mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-02 12:09:14 +08:00
commit
493b66b641
@ -15,6 +15,50 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 5.7.0
|
||||
|
||||
`2023-07-11`
|
||||
|
||||
- 🆕 ConfigProvider now supports `className` and `style` properties for all components. Thanks to [@Yuiai01](https://github.com/Yuiai01), [@li-jia-nan](https://github.com/li-jia-nan), [@MuxinFeng](https://github.com/MuxinFeng) for their contributions.
|
||||
- 🆕 Badge now supports `classNames` and `styles` properties. [#43245](https://github.com/ant-design/ant-design/pull/43245) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🆕 ColorPicker now supports new features such as `showText`, `destroyTooltipOnHide`, `onChangeComplete`, `panelRender` and `size`.
|
||||
- [#42865](https://github.com/ant-design/ant-design/pull/42865) [@RedJue](https://github.com/RedJue)
|
||||
- [#42645](https://github.com/ant-design/ant-design/pull/42645) [@linxianxi](https://github.com/linxianxi)
|
||||
- [#43370](https://github.com/ant-design/ant-design/pull/43370) [@RedJue](https://github.com/RedJue)
|
||||
- [#43134](https://github.com/ant-design/ant-design/pull/43134) [@RedJue](https://github.com/RedJue)
|
||||
- [#43116](https://github.com/ant-design/ant-design/pull/43116) [@RedJue](https://github.com/RedJue)
|
||||
- 🆕 Alert, Drawer, Modal, Notifaction, Tag, Tabs now support hiding the close button by setting `closeIcon` to null or false. [#42828](https://github.com/ant-design/ant-design/discussions/42828) [@kiner-tang](https://github.com/kiner-tang)
|
||||
- 🆕 Image supports `imageRender`, `toolbarRender` attributes to support custom rendering of preview images and toolbars, also supports new props such as `onTransform`, `minScale`, `maxScale`. Image.PreviewGroup supports `items` attribute to pass in list data, and fixes that the native attributes of the img tag are not passed to preview images The problem. [#43075](https://github.com/ant-design/ant-design/pull/43075) [@linxianxi](https://github.com/linxianxi)
|
||||
- 🆕 Modify the layout style of the Image preview, the `preview` attribute supports `closeIcon`, Image.PreviewGroup supports the `fallback` attribute, and fixes the problem of loading preview resources in advance. [#43167](https://github.com/ant-design/ant-design/pull/43167) [@linxianxi](https://github.com/linxianxi)
|
||||
- 🆕 Changed the layout style, Preview now supports `closeIcon`, PreviewGroup now supports `fallback`, and fixed an issue where preview resources would be loaded at the beginning.[#43167](https://github.com/ant-design/ant-design/pull/43167) [@linxianxi](https://github.com/linxianxi)
|
||||
- 🛠 InputNumber was refactored to use rc-input. (#42762)。[#42762](https://github.com/ant-design/ant-design/pull/42762) [@muxin](https://github.com/muxin)
|
||||
- 🛠 Resolved Circular dependency issue in vite, rollup, meteor and microbundle. [#42750](https://github.com/ant-design/ant-design/pull/42750). Thanks to [@jrr997](https://github.com/jrr997), [@kiner-tang](https://github.com/kiner-tang) and [@MuxinFeng](https://github.com/MuxinFeng) for their contributions.
|
||||
- 🐞 Remove default values (empty string) of `className` prop in Anchor, CollapsePanel, and Input.Group. [#43481](https://github.com/ant-design/ant-design/pull/43481) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🐞 Fix Upload progress bar missing fade motion. [#43471](https://github.com/ant-design/ant-design/pull/43471)
|
||||
- 🐞 Added warning for deprecated Token `colorItemBgSelected` in Menu.[#43461](https://github.com/ant-design/ant-design/pull/43461) [@MadCcc](https://github.com/MadCcc)
|
||||
- 🐞 Fixed an issue where some browsers had scroll bars that were not redrawn when style feature support was detected.[#43358](https://github.com/ant-design/ant-design/pull/43358) [@LeeeeeeM](https://github.com/LeeeeeeM)
|
||||
- 🐞 Fixed an issue where the Tab component of Card would not be displayed at all when tabList is empty.[#43416](https://github.com/ant-design/ant-design/pull/43416) [@linxianxi](https://github.com/linxianxi)
|
||||
- 🐞 Fixed an issue where the `form.validateMessages`` configuration would be lost when using ConfigProvider nestedly.[#43239](https://github.com/ant-design/ant-design/pull/43239) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- 🐞 Fixed an issue where the ripple effect of Tag click would sometimes be offset from the Tag element.[#43402](https://github.com/ant-design/ant-design/pull/43402)
|
||||
- 🐞 Fixed an issue where clicking "now" in DatePicker when switching to the year-month panel would not work.[#43367](https://github.com/ant-design/ant-design/pull/43367) [@Yuiai01](https://github.com/Yuiai01)
|
||||
- 🐞 Fixed an issue where the height set for the TextArea component would become invalid when the screen size changed.[#43169](https://github.com/ant-design/ant-design/pull/43169) [@MadCcc](https://github.com/MadCcc)
|
||||
- 💄 In Slider, the `tooltip` should be centered when there is little content. [#43430](https://github.com/ant-design/ant-design/pull/43430) [@Jomorx](https://github.com/Jomorx)
|
||||
- 💄 Added `colorLink` to the seed token, and `colorLinkHover` and `colorLinkActive` will be calculated from colorLink.[#43183](https://github.com/ant-design/ant-design/pull/43183) [@MadCcc](https://github.com/MadCcc)
|
||||
- 💄 Adjusted some tokens in Slider to component tokens. [#42428](https://github.com/ant-design/ant-design/pull/42428) [@heiyu4585](https://github.com/heiyu4585) RTL[#42428](https://github.com/ant-design/ant-design/pull/42428) [@heiyu4585](https://github.com/heiyu4585)
|
||||
- RTL
|
||||
- 🤖 Progress now supports animations in rtl direction.[#43316](https://github.com/ant-design/ant-design/pull/43316) [@Yuiai01](https://github.com/Yuiai01)
|
||||
- TypeScript
|
||||
- 🤖 Added `RawPurePanelProps` interface description for Popover.[#43453](https://github.com/ant-design/ant-design/pull/43453) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🤖 Replaced `ref` type with `TooltipRef` instead of `unknown` for `Popconfirm`.[#43452](https://github.com/ant-design/ant-design/pull/43452) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🤖 Replaced `ref` type with `TooltipRef` instead of `unknown` for Popover.[#43450](https://github.com/ant-design/ant-design/pull/43450) [@Negentropy247](https://github.com/Negentropy247)
|
||||
- 🤖 Improved type declaration of `GroupSizeContext` in ButtonGroup.[#43439](https://github.com/ant-design/ant-design/pull/43439) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🤖 Improved type declaration of `mode` property in Select.[#43413](https://github.com/ant-design/ant-design/pull/43413) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🤖 Replaced `ref` type with `CheckboxRef` instead of `unknown` for Checkbox.[#43424](https://github.com/ant-design/ant-design/pull/43424) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🤖 Improved internal type implementation for Table/Tag/Notification.
|
||||
- [#43366](https://github.com/ant-design/ant-design/pull/43366) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- [#43357](https://github.com/ant-design/ant-design/pull/43357) [@thinkasany](https://github.com/thinkasany)
|
||||
- [#43351](https://github.com/ant-design/ant-design/pull/43351) [@thinkasany](https://github.com/thinkasany)
|
||||
|
||||
## 5.6.4
|
||||
|
||||
`2023-07-03`
|
||||
|
@ -15,6 +15,50 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 5.7.0
|
||||
|
||||
`2023-07-11`
|
||||
|
||||
- 🆕 ConfigProvider 支持所有组件的 `className` 和 `style` 属性控制。感谢 [@Yuiai01](https://github.com/Yuiai01)、[@li-jia-nan](https://github.com/li-jia-nan) 和 [@MuxinFeng](https://github.com/MuxinFeng) 的贡献。
|
||||
- 🆕 Badge 支持 `classNames` 属性和 `styles` 属性。[#43245](https://github.com/ant-design/ant-design/pull/43245) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🆕 ColorPicker 支持 `showText`、`destroyTooltipOnHide`、`onChangeComplete`、`panelRender`、`size` 等新特性。
|
||||
- [#42865](https://github.com/ant-design/ant-design/pull/42865) [@RedJue](https://github.com/RedJue)
|
||||
- [#42645](https://github.com/ant-design/ant-design/pull/42645) [@linxianxi](https://github.com/linxianxi)
|
||||
- [#43370](https://github.com/ant-design/ant-design/pull/43370) [@RedJue](https://github.com/RedJue)
|
||||
- [#43134](https://github.com/ant-design/ant-design/pull/43134) [@RedJue](https://github.com/RedJue)
|
||||
- [#43116](https://github.com/ant-design/ant-design/pull/43116) [@RedJue](https://github.com/RedJue)
|
||||
- 🆕 Alert、Drawer、Modal、Notifaction、Tag、Tabs 均已支持通过设置 `closeIcon` 为 null 或 false 隐藏关闭按钮。 [#42828](https://github.com/ant-design/ant-design/discussions/42828) [@kiner-tang](https://github.com/kiner-tang)
|
||||
- 🆕 Anchor 添加 `replace` 属性。[#43006](https://github.com/ant-design/ant-design/pull/43006) [@ds1371dani](https://github.com/ds1371dani)
|
||||
- 🆕 Image 支持 `imageRender`、`toolbarRender` 属性以支持预览图和工具栏的自定义渲染,还支持了 `onTransform`、`minScale`、`maxScale` 等新属性,Image.PreviewGroup 支持 `items` 属性传入列表数据,并修复了 img 标签的原生属性没有传递给预览图的问题。[#43075](https://github.com/ant-design/ant-design/pull/43075) [@linxianxi](https://github.com/linxianxi)
|
||||
- 🆕 修改 Image 预览图的布局风格,`preview` 属性支持 `closeIcon`,Image.PreviewGroup 支持 `fallback` 属性,修复加载预览资源提前加载的问题。[#43167](https://github.com/ant-design/ant-design/pull/43167) [@linxianxi](https://github.com/linxianxi)
|
||||
- 🛠 InputNumber 使用 rc-input 进行重构。[#42762](https://github.com/ant-design/ant-design/pull/42762) [@muxin](https://github.com/muxin)
|
||||
- 🛠 解决 vite、rollup、meteor、microbundle 等构建工具中遇到的循环依赖问题,并增加相关的检测。[#42750](https://github.com/ant-design/ant-design/pull/42750),感谢 [@jrr997](https://github.com/jrr997)、[@kiner-tang](https://github.com/kiner-tang) 和 [@MuxinFeng](https://github.com/MuxinFeng) 的贡献。
|
||||
- 🐞 移除 Anchor/CollapsePanel/Input.Group 组件中 `className` 属性的默认值(空字符串)。 [#43481](https://github.com/ant-design/ant-design/pull/43481) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🐞 修复 Upload 上传进度条延迟消失且丢失动画效果的问题。[#43471](https://github.com/ant-design/ant-design/pull/43471)
|
||||
- 🐞 为 Menu 中组件 Token `colorItemBgSelected` 添加废弃警告。[#43461](https://github.com/ant-design/ant-design/pull/43461) [@MadCcc](https://github.com/MadCcc)
|
||||
- 🐞 修复样式特性支持检测时部分浏览器因为未重绘导致出现滚动条的问题。[#43358](https://github.com/ant-design/ant-design/pull/43358) [@LeeeeeeM](https://github.com/LeeeeeeM)
|
||||
- 🐞 修复 Card `tabList` 为空时 Tab 完全不展示的问题。[#43416](https://github.com/ant-design/ant-design/pull/43416) [@linxianxi](https://github.com/linxianxi)
|
||||
- 🐞 修复 ConfigProvider 嵌套使用时,`form.validateMessages` 配置会丢失的问题。[#43239](https://github.com/ant-design/ant-design/pull/43239) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- 🐞 修复 Tag 点击的水波纹效果有时候会和 Tag 元素产生偏移的问题。[#43402](https://github.com/ant-design/ant-design/pull/43402)
|
||||
- 🐞 修复 DatePicker 切换到年月面板时,`此刻` 点击无效的问题。[#43367](https://github.com/ant-design/ant-design/pull/43367) [@Yuiai01](https://github.com/Yuiai01)
|
||||
- 🐞 修复 TextArea 组件在屏幕大小变化时设置的高度失效的问题。[#43169](https://github.com/ant-design/ant-design/pull/43169) [@MadCcc](https://github.com/MadCcc)
|
||||
- 💄 Slider 中 `tooltip` 在内容很少时应该居中。[#43430](https://github.com/ant-design/ant-design/pull/43430) [@Jomorx](https://github.com/Jomorx)
|
||||
- 💄 将 `colorLink` 添加至 seed token 中, `colorLinkHover` 和 `colorLinkActive` 将会由 `colorLink` 计算得出。[#43183](https://github.com/ant-design/ant-design/pull/43183) [@MadCcc](https://github.com/MadCcc)
|
||||
- 💄 调整 Slider 中部分 token 为 component token。[#42428](https://github.com/ant-design/ant-design/pull/42428) [@heiyu4585](https://github.com/heiyu4585)
|
||||
- RTL
|
||||
- 🤖 Progress 支持 rtl 方向的动画。[#43316](https://github.com/ant-design/ant-design/pull/43316) [@Yuiai01](https://github.com/Yuiai01)
|
||||
- TypeScript
|
||||
- 🤖 Popover 增加 `RawPurePanelProps` 接口描述。[#43453](https://github.com/ant-design/ant-design/pull/43453) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🤖 Popconfirm 替换 `ref` 类型 `unknown` 为 `TooltipRef`。[#43452](https://github.com/ant-design/ant-design/pull/43452) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🤖 Popover 替换 `ref` 类型 `unknown` 为 `TooltipRef`。[#43450](https://github.com/ant-design/ant-design/pull/43450) [@Negentropy247](https://github.com/Negentropy247)
|
||||
- 🤖 改进 ButtonGroup 中 `GroupSizeContext` 的类型声明。[#43439](https://github.com/ant-design/ant-design/pull/43439) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🤖 改进 Select 的 `mode` 属性的类型声明。[#43413](https://github.com/ant-design/ant-design/pull/43413) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🤖 Checkbox 替换 `ref` 类型 `unknown` 为 `CheckboxRef`。[#43424](https://github.com/ant-design/ant-design/pull/43424) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🤖 改进 Table/Tag/Notification 内部类型实现。
|
||||
- [#43366](https://github.com/ant-design/ant-design/pull/43366) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- [#43357](https://github.com/ant-design/ant-design/pull/43357) [@thinkasany](https://github.com/thinkasany)
|
||||
- [#43351](https://github.com/ant-design/ant-design/pull/43351) [@thinkasany](https://github.com/thinkasany)
|
||||
|
||||
## 5.6.4
|
||||
|
||||
`2023-07-03`
|
||||
|
@ -96,25 +96,27 @@ const CloseIcon: React.FC<CloseIconProps> = (props) => {
|
||||
) : null;
|
||||
};
|
||||
|
||||
const Alert: React.FC<AlertProps> = ({
|
||||
description,
|
||||
prefixCls: customizePrefixCls,
|
||||
message,
|
||||
banner,
|
||||
className,
|
||||
rootClassName,
|
||||
style,
|
||||
onMouseEnter,
|
||||
onMouseLeave,
|
||||
onClick,
|
||||
afterClose,
|
||||
showIcon,
|
||||
closable,
|
||||
closeText,
|
||||
closeIcon,
|
||||
action,
|
||||
...props
|
||||
}) => {
|
||||
const Alert: React.FC<AlertProps> = (props) => {
|
||||
const {
|
||||
description,
|
||||
prefixCls: customizePrefixCls,
|
||||
message,
|
||||
banner,
|
||||
className,
|
||||
rootClassName,
|
||||
style,
|
||||
onMouseEnter,
|
||||
onMouseLeave,
|
||||
onClick,
|
||||
afterClose,
|
||||
showIcon,
|
||||
closable,
|
||||
closeText,
|
||||
closeIcon,
|
||||
action,
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
const [closed, setClosed] = React.useState(false);
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warning(!closeText, 'Alert', '`closeText` is deprecated. Please use `closeIcon` instead.');
|
||||
@ -129,14 +131,13 @@ const Alert: React.FC<AlertProps> = ({
|
||||
props.onClose?.(e);
|
||||
};
|
||||
|
||||
const getType = () => {
|
||||
const { type } = props;
|
||||
if (type !== undefined) {
|
||||
return type;
|
||||
const type = React.useMemo<AlertProps['type']>(() => {
|
||||
if (props.type !== undefined) {
|
||||
return props.type;
|
||||
}
|
||||
// banner mode defaults to 'warning'
|
||||
return banner ? 'warning' : 'info';
|
||||
};
|
||||
}, [props.type, banner]);
|
||||
|
||||
// closeable when closeText or closeIcon is assigned
|
||||
const isClosable = React.useMemo(() => {
|
||||
@ -150,8 +151,6 @@ const Alert: React.FC<AlertProps> = ({
|
||||
return closeIcon !== false && closeIcon !== null && closeIcon !== undefined;
|
||||
}, [closeText, closeIcon, closable]);
|
||||
|
||||
const type = getType();
|
||||
|
||||
// banner mode defaults to Icon
|
||||
const isShowIcon = banner && showIcon === undefined ? true : showIcon;
|
||||
|
||||
@ -170,10 +169,7 @@ const Alert: React.FC<AlertProps> = ({
|
||||
hashId,
|
||||
);
|
||||
|
||||
const dataOrAriaProps = pickAttrs(props, {
|
||||
aria: true,
|
||||
data: true,
|
||||
});
|
||||
const restProps = pickAttrs(otherProps, { aria: true, data: true });
|
||||
|
||||
return wrapSSR(
|
||||
<CSSMotion
|
||||
@ -181,9 +177,7 @@ const Alert: React.FC<AlertProps> = ({
|
||||
motionName={`${prefixCls}-motion`}
|
||||
motionAppear={false}
|
||||
motionEnter={false}
|
||||
onLeaveStart={(node) => ({
|
||||
maxHeight: node.offsetHeight,
|
||||
})}
|
||||
onLeaveStart={(node) => ({ maxHeight: node.offsetHeight })}
|
||||
onLeaveEnd={afterClose}
|
||||
>
|
||||
{({ className: motionClassName, style: motionStyle }) => (
|
||||
@ -196,7 +190,7 @@ const Alert: React.FC<AlertProps> = ({
|
||||
onMouseLeave={onMouseLeave}
|
||||
onClick={onClick}
|
||||
role="alert"
|
||||
{...dataOrAriaProps}
|
||||
{...restProps}
|
||||
>
|
||||
{isShowIcon ? (
|
||||
<IconNode
|
||||
|
@ -114,7 +114,7 @@ const AnchorContent: React.FC<InternalAnchorProps> = (props) => {
|
||||
const {
|
||||
rootClassName,
|
||||
anchorPrefixCls: prefixCls,
|
||||
className = '',
|
||||
className,
|
||||
style,
|
||||
offsetTop,
|
||||
affix = true,
|
||||
|
@ -29,98 +29,94 @@ export interface CarouselRef {
|
||||
innerSlider: any;
|
||||
}
|
||||
|
||||
const Carousel = React.forwardRef<CarouselRef, CarouselProps>(
|
||||
(
|
||||
{
|
||||
dots = true,
|
||||
arrows = false,
|
||||
draggable = false,
|
||||
waitForAnimate = false,
|
||||
dotPosition = 'bottom',
|
||||
vertical = dotPosition === 'left' || dotPosition === 'right',
|
||||
rootClassName,
|
||||
className: customClassName,
|
||||
style,
|
||||
...props
|
||||
},
|
||||
const Carousel = React.forwardRef<CarouselRef, CarouselProps>((props, ref) => {
|
||||
const {
|
||||
dots = true,
|
||||
arrows = false,
|
||||
draggable = false,
|
||||
waitForAnimate = false,
|
||||
dotPosition = 'bottom',
|
||||
vertical = dotPosition === 'left' || dotPosition === 'right',
|
||||
rootClassName,
|
||||
className: customClassName,
|
||||
style,
|
||||
...otherProps
|
||||
} = props;
|
||||
const { getPrefixCls, direction, carousel } = React.useContext(ConfigContext);
|
||||
const slickRef = React.useRef<any>();
|
||||
|
||||
const goTo = (slide: number, dontAnimate = false) => {
|
||||
slickRef.current.slickGoTo(slide, dontAnimate);
|
||||
};
|
||||
|
||||
React.useImperativeHandle(
|
||||
ref,
|
||||
) => {
|
||||
const { getPrefixCls, direction, carousel } = React.useContext(ConfigContext);
|
||||
const slickRef = React.useRef<any>();
|
||||
() => ({
|
||||
goTo,
|
||||
autoPlay: slickRef.current.innerSlider.autoPlay,
|
||||
innerSlider: slickRef.current.innerSlider,
|
||||
prev: slickRef.current.slickPrev,
|
||||
next: slickRef.current.slickNext,
|
||||
}),
|
||||
[slickRef.current],
|
||||
);
|
||||
|
||||
const goTo = (slide: number, dontAnimate = false) => {
|
||||
slickRef.current.slickGoTo(slide, dontAnimate);
|
||||
};
|
||||
const prevCount = React.useRef(React.Children.count(props.children));
|
||||
|
||||
React.useImperativeHandle(
|
||||
ref,
|
||||
() => ({
|
||||
goTo,
|
||||
autoPlay: slickRef.current.innerSlider.autoPlay,
|
||||
innerSlider: slickRef.current.innerSlider,
|
||||
prev: slickRef.current.slickPrev,
|
||||
next: slickRef.current.slickNext,
|
||||
}),
|
||||
[slickRef.current],
|
||||
);
|
||||
|
||||
const prevCount = React.useRef(React.Children.count(props.children));
|
||||
|
||||
React.useEffect(() => {
|
||||
if (prevCount.current !== React.Children.count(props.children)) {
|
||||
goTo(props.initialSlide || 0, false);
|
||||
prevCount.current = React.Children.count(props.children);
|
||||
}
|
||||
}, [props.children]);
|
||||
|
||||
const newProps = {
|
||||
vertical,
|
||||
className: classNames(customClassName, carousel?.className),
|
||||
style: { ...carousel?.style, ...style },
|
||||
...props,
|
||||
};
|
||||
|
||||
if (newProps.effect === 'fade') {
|
||||
newProps.fade = true;
|
||||
React.useEffect(() => {
|
||||
if (prevCount.current !== React.Children.count(props.children)) {
|
||||
goTo(props.initialSlide || 0, false);
|
||||
prevCount.current = React.Children.count(props.children);
|
||||
}
|
||||
}, [props.children]);
|
||||
|
||||
const prefixCls = getPrefixCls('carousel', newProps.prefixCls);
|
||||
const dotsClass = 'slick-dots';
|
||||
const newProps = {
|
||||
vertical,
|
||||
className: classNames(customClassName, carousel?.className),
|
||||
style: { ...carousel?.style, ...style },
|
||||
...otherProps,
|
||||
};
|
||||
|
||||
const enableDots = !!dots;
|
||||
const dsClass = classNames(
|
||||
dotsClass,
|
||||
`${dotsClass}-${dotPosition}`,
|
||||
typeof dots === 'boolean' ? false : dots?.className,
|
||||
);
|
||||
if (newProps.effect === 'fade') {
|
||||
newProps.fade = true;
|
||||
}
|
||||
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
const prefixCls = getPrefixCls('carousel', newProps.prefixCls);
|
||||
const dotsClass = 'slick-dots';
|
||||
|
||||
const className = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
[`${prefixCls}-vertical`]: newProps.vertical,
|
||||
},
|
||||
hashId,
|
||||
rootClassName,
|
||||
);
|
||||
const enableDots = !!dots;
|
||||
const dsClass = classNames(
|
||||
dotsClass,
|
||||
`${dotsClass}-${dotPosition}`,
|
||||
typeof dots === 'boolean' ? false : dots?.className,
|
||||
);
|
||||
|
||||
return wrapSSR(
|
||||
<div className={className}>
|
||||
<SlickCarousel
|
||||
ref={slickRef}
|
||||
{...newProps}
|
||||
dots={enableDots}
|
||||
dotsClass={dsClass}
|
||||
arrows={arrows}
|
||||
draggable={draggable}
|
||||
waitForAnimate={waitForAnimate}
|
||||
/>
|
||||
</div>,
|
||||
);
|
||||
},
|
||||
);
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
|
||||
const className = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
[`${prefixCls}-vertical`]: newProps.vertical,
|
||||
},
|
||||
hashId,
|
||||
rootClassName,
|
||||
);
|
||||
|
||||
return wrapSSR(
|
||||
<div className={className}>
|
||||
<SlickCarousel
|
||||
ref={slickRef}
|
||||
{...newProps}
|
||||
dots={enableDots}
|
||||
dotsClass={dsClass}
|
||||
arrows={arrows}
|
||||
draggable={draggable}
|
||||
waitForAnimate={waitForAnimate}
|
||||
/>
|
||||
</div>,
|
||||
);
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
Carousel.displayName = 'Carousel';
|
||||
|
@ -51,7 +51,10 @@ export interface CheckboxProps extends AbstractCheckboxProps<CheckboxChangeEvent
|
||||
}
|
||||
|
||||
const InternalCheckbox: React.ForwardRefRenderFunction<CheckboxRef, CheckboxProps> = (
|
||||
{
|
||||
props,
|
||||
ref,
|
||||
) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
className,
|
||||
rootClassName,
|
||||
@ -63,9 +66,7 @@ const InternalCheckbox: React.ForwardRefRenderFunction<CheckboxRef, CheckboxProp
|
||||
skipGroup = false,
|
||||
disabled,
|
||||
...restProps
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
} = props;
|
||||
const { getPrefixCls, direction, checkbox } = React.useContext(ConfigContext);
|
||||
const checkboxGroup = React.useContext(GroupContext);
|
||||
const { isFormItemInput } = React.useContext(FormItemInputContext);
|
||||
|
@ -36,8 +36,11 @@ export interface CheckboxGroupProps extends AbstractCheckboxGroupProps {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const InternalCheckboxGroup: React.ForwardRefRenderFunction<HTMLDivElement, CheckboxGroupProps> = (
|
||||
{
|
||||
const InternalGroup: React.ForwardRefRenderFunction<HTMLDivElement, CheckboxGroupProps> = (
|
||||
props,
|
||||
ref,
|
||||
) => {
|
||||
const {
|
||||
defaultValue,
|
||||
children,
|
||||
options = [],
|
||||
@ -47,9 +50,7 @@ const InternalCheckboxGroup: React.ForwardRefRenderFunction<HTMLDivElement, Chec
|
||||
style,
|
||||
onChange,
|
||||
...restProps
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
} = props;
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
|
||||
const [value, setValue] = React.useState<CheckboxValueType[]>(
|
||||
@ -63,16 +64,16 @@ const InternalCheckboxGroup: React.ForwardRefRenderFunction<HTMLDivElement, Chec
|
||||
}
|
||||
}, [restProps.value]);
|
||||
|
||||
const getOptions = () =>
|
||||
options.map((option) => {
|
||||
if (typeof option === 'string' || typeof option === 'number') {
|
||||
return {
|
||||
label: option,
|
||||
value: option,
|
||||
};
|
||||
}
|
||||
return option;
|
||||
});
|
||||
const memoOptions = React.useMemo(
|
||||
() =>
|
||||
options.map<CheckboxOptionType>((option) => {
|
||||
if (typeof option === 'string' || typeof option === 'number') {
|
||||
return { label: option, value: option };
|
||||
}
|
||||
return option;
|
||||
}),
|
||||
[options],
|
||||
);
|
||||
|
||||
const cancelValue = (val: string) => {
|
||||
setRegisteredValues((prevValues) => prevValues.filter((v) => v !== val));
|
||||
@ -93,13 +94,12 @@ const InternalCheckboxGroup: React.ForwardRefRenderFunction<HTMLDivElement, Chec
|
||||
if (!('value' in restProps)) {
|
||||
setValue(newValue);
|
||||
}
|
||||
const opts = getOptions();
|
||||
onChange?.(
|
||||
newValue
|
||||
.filter((val) => registeredValues.includes(val))
|
||||
.sort((a, b) => {
|
||||
const indexA = opts.findIndex((opt) => opt.value === a);
|
||||
const indexB = opts.findIndex((opt) => opt.value === b);
|
||||
const indexA = memoOptions.findIndex((opt) => opt.value === a);
|
||||
const indexB = memoOptions.findIndex((opt) => opt.value === b);
|
||||
return indexA - indexB;
|
||||
}),
|
||||
);
|
||||
@ -112,23 +112,23 @@ const InternalCheckboxGroup: React.ForwardRefRenderFunction<HTMLDivElement, Chec
|
||||
|
||||
const domProps = omit(restProps, ['value', 'disabled']);
|
||||
|
||||
if (options && options.length > 0) {
|
||||
children = getOptions().map((option) => (
|
||||
<Checkbox
|
||||
prefixCls={prefixCls}
|
||||
key={option.value.toString()}
|
||||
disabled={'disabled' in option ? option.disabled : restProps.disabled}
|
||||
value={option.value}
|
||||
checked={value.includes(option.value)}
|
||||
onChange={option.onChange}
|
||||
className={`${groupPrefixCls}-item`}
|
||||
style={option.style}
|
||||
title={option.title}
|
||||
>
|
||||
{option.label}
|
||||
</Checkbox>
|
||||
));
|
||||
}
|
||||
const childrenNode = options.length
|
||||
? memoOptions.map<React.ReactNode>((option) => (
|
||||
<Checkbox
|
||||
prefixCls={prefixCls}
|
||||
key={option.value.toString()}
|
||||
disabled={'disabled' in option ? option.disabled : restProps.disabled}
|
||||
value={option.value}
|
||||
checked={value.includes(option.value)}
|
||||
onChange={option.onChange}
|
||||
className={`${groupPrefixCls}-item`}
|
||||
style={option.style}
|
||||
title={option.title}
|
||||
>
|
||||
{option.label}
|
||||
</Checkbox>
|
||||
))
|
||||
: children;
|
||||
|
||||
// eslint-disable-next-line react/jsx-no-constructed-context-values
|
||||
const context = {
|
||||
@ -151,7 +151,7 @@ const InternalCheckboxGroup: React.ForwardRefRenderFunction<HTMLDivElement, Chec
|
||||
);
|
||||
return wrapSSR(
|
||||
<div className={classString} style={style} {...domProps} ref={ref}>
|
||||
<GroupContext.Provider value={context}>{children}</GroupContext.Provider>
|
||||
<GroupContext.Provider value={context}>{childrenNode}</GroupContext.Provider>
|
||||
</div>,
|
||||
);
|
||||
};
|
||||
@ -159,6 +159,6 @@ const InternalCheckboxGroup: React.ForwardRefRenderFunction<HTMLDivElement, Chec
|
||||
export type { CheckboxGroupContext } from './GroupContext';
|
||||
export { GroupContext };
|
||||
|
||||
const CheckboxGroup = React.forwardRef<HTMLDivElement, CheckboxGroupProps>(InternalCheckboxGroup);
|
||||
const CheckboxGroup = React.forwardRef<HTMLDivElement, CheckboxGroupProps>(InternalGroup);
|
||||
|
||||
export default React.memo(CheckboxGroup);
|
||||
|
@ -30,7 +30,7 @@ const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((prop
|
||||
);
|
||||
|
||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||
const { prefixCls: customizePrefixCls, className = '', showArrow = true } = props;
|
||||
const { prefixCls: customizePrefixCls, className, showArrow = true } = props;
|
||||
const prefixCls = getPrefixCls('collapse', customizePrefixCls);
|
||||
const collapsePanelClassName = classNames(
|
||||
{
|
||||
|
@ -7,10 +7,12 @@ import useMergedState from 'rc-util/lib/hooks/useMergedState';
|
||||
import type { CSSProperties, FC } from 'react';
|
||||
import React, { useContext, useRef, useState } from 'react';
|
||||
import genPurePanel from '../_util/PurePanel';
|
||||
import { getStatusClassNames } from '../_util/statusUtils';
|
||||
import type { SizeType } from '../config-provider/SizeContext';
|
||||
import type { ConfigConsumerProps } from '../config-provider/context';
|
||||
import { ConfigContext } from '../config-provider/context';
|
||||
import useSize from '../config-provider/hooks/useSize';
|
||||
import { FormItemInputContext, NoFormStyle } from '../form/context';
|
||||
import type { PopoverProps } from '../popover';
|
||||
import Popover from '../popover';
|
||||
import theme from '../theme';
|
||||
@ -21,6 +23,7 @@ import useColorState from './hooks/useColorState';
|
||||
import type {
|
||||
ColorFormat,
|
||||
ColorPickerBaseProps,
|
||||
ColorValueType,
|
||||
PresetsItem,
|
||||
TriggerPlacement,
|
||||
TriggerType,
|
||||
@ -32,8 +35,8 @@ export type ColorPickerProps = Omit<
|
||||
RcColorPickerProps,
|
||||
'onChange' | 'value' | 'defaultValue' | 'panelRender' | 'onChangeComplete'
|
||||
> & {
|
||||
value?: Color | string;
|
||||
defaultValue?: Color | string;
|
||||
value?: ColorValueType;
|
||||
defaultValue?: ColorValueType;
|
||||
children?: React.ReactNode;
|
||||
open?: boolean;
|
||||
disabled?: boolean;
|
||||
@ -114,12 +117,16 @@ const ColorPicker: CompoundedComponent = (props) => {
|
||||
|
||||
const prefixCls = getPrefixCls('color-picker', customizePrefixCls);
|
||||
|
||||
// ===================== Form Status =====================
|
||||
const { status: contextStatus } = React.useContext(FormItemInputContext);
|
||||
|
||||
// ===================== Style =====================
|
||||
const mergedSize = useSize(customizeSize);
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
const rtlCls = { [`${prefixCls}-rtl`]: direction };
|
||||
const mergeRootCls = classNames(rootClassName, rtlCls);
|
||||
const mergeCls = classNames(
|
||||
getStatusClassNames(prefixCls, contextStatus),
|
||||
{
|
||||
[`${prefixCls}-sm`]: mergedSize === 'small',
|
||||
[`${prefixCls}-lg`]: mergedSize === 'large',
|
||||
@ -135,7 +142,8 @@ const ColorPicker: CompoundedComponent = (props) => {
|
||||
|
||||
const handleChange = (data: Color, type?: HsbaColorType, pickColor?: boolean) => {
|
||||
let color: Color = generateColor(data);
|
||||
if (colorCleared) {
|
||||
const isNull = value === null || (!value && defaultValue === null);
|
||||
if (colorCleared || isNull) {
|
||||
setColorCleared(false);
|
||||
const hsba = color.toHsb();
|
||||
// ignore alpha slider
|
||||
@ -199,7 +207,14 @@ const ColorPicker: CompoundedComponent = (props) => {
|
||||
}
|
||||
}}
|
||||
content={
|
||||
<ColorPickerPanel {...colorBaseProps} onChange={handleChange} onClear={handleClear} />
|
||||
<NoFormStyle override status>
|
||||
<ColorPickerPanel
|
||||
{...colorBaseProps}
|
||||
onChange={handleChange}
|
||||
onChangeComplete={handleChangeComplete}
|
||||
onClear={handleClear}
|
||||
/>
|
||||
</NoFormStyle>
|
||||
}
|
||||
overlayClassName={mergePopupCls}
|
||||
{...popoverProps}
|
||||
|
@ -5,6 +5,7 @@ import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import { waitFakeTimer } from '../../../tests/utils';
|
||||
import ConfigProvider from '../../config-provider';
|
||||
import Form from '../../form';
|
||||
import theme from '../../theme';
|
||||
import ColorPicker from '../ColorPicker';
|
||||
import type { Color } from '../color';
|
||||
@ -398,7 +399,7 @@ describe('ColorPicker', () => {
|
||||
expect(componentContainer).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('Should onChangeComplete work', async () => {
|
||||
it('Should null work as expect', async () => {
|
||||
spyElementPrototypes(HTMLElement, {
|
||||
getBoundingClientRect: () => ({
|
||||
x: 0,
|
||||
@ -407,6 +408,51 @@ describe('ColorPicker', () => {
|
||||
height: 100,
|
||||
}),
|
||||
});
|
||||
const { container } = render(<ColorPicker value={null} open />);
|
||||
expect(
|
||||
container.querySelector('.ant-color-picker-alpha-input input')?.getAttribute('value'),
|
||||
).toEqual('0%');
|
||||
expect(
|
||||
container.querySelector('.ant-color-picker-hex-input input')?.getAttribute('value'),
|
||||
).toEqual('000000');
|
||||
doMouseMove(container, 0, 999);
|
||||
expect(
|
||||
container.querySelector('.ant-color-picker-alpha-input input')?.getAttribute('value'),
|
||||
).toEqual('100%');
|
||||
});
|
||||
|
||||
it('should support valid in form', async () => {
|
||||
const Demo = () => {
|
||||
const [form] = Form.useForm();
|
||||
const submit = () => {
|
||||
form.validateFields();
|
||||
};
|
||||
return (
|
||||
<Form form={form} initialValues={{ 'color-picker': null }}>
|
||||
<Form.Item
|
||||
name="color-picker"
|
||||
label="ColorPicker"
|
||||
rules={[{ required: true, message: 'color is required!' }]}
|
||||
>
|
||||
<ColorPicker />
|
||||
</Form.Item>
|
||||
<button type="button" onClick={submit}>
|
||||
submit
|
||||
</button>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
const { container } = render(<Demo />);
|
||||
expect(container.querySelector('.ant-color-picker-status-error')).toBeFalsy();
|
||||
fireEvent.click(container.querySelector('button')!);
|
||||
await waitFakeTimer();
|
||||
expect(container.querySelector('.ant-color-picker-status-error')).toBeTruthy();
|
||||
expect(container.querySelector('.ant-form-item-explain-error')?.innerHTML).toEqual(
|
||||
'color is required!',
|
||||
);
|
||||
});
|
||||
|
||||
it('Should onChangeComplete work', async () => {
|
||||
const handleChangeComplete = jest.fn();
|
||||
const { container } = render(<ColorPicker open onChangeComplete={handleChangeComplete} />);
|
||||
doMouseMove(container, 0, 999);
|
||||
|
@ -19,6 +19,9 @@ export class ColorFactory {
|
||||
|
||||
constructor(color: ColorGenInput<Color>) {
|
||||
this.metaColor = new RcColor(color as ColorGenInput);
|
||||
if (!color) {
|
||||
this.metaColor.setAlpha(0);
|
||||
}
|
||||
}
|
||||
|
||||
toHsb() {
|
||||
|
@ -12,11 +12,9 @@ export interface PanelPresetsProps extends Pick<ColorPickerBaseProps, 'prefixCls
|
||||
|
||||
const PanelPresets: FC = () => {
|
||||
const { prefixCls, value, presets, onChange } = useContext(PanelPresetsContext);
|
||||
return (
|
||||
Array.isArray(presets) && (
|
||||
<ColorPresets value={value} presets={presets} prefixCls={prefixCls} onChange={onChange} />
|
||||
)
|
||||
);
|
||||
return Array.isArray(presets) ? (
|
||||
<ColorPresets value={value} presets={presets} prefixCls={prefixCls} onChange={onChange} />
|
||||
) : null;
|
||||
};
|
||||
|
||||
export default PanelPresets;
|
||||
|
@ -1,18 +1,19 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import type { Color } from '../color';
|
||||
import type { ColorValueType } from '../interface';
|
||||
import { generateColor } from '../util';
|
||||
|
||||
function hasValue(value?: Color | string) {
|
||||
function hasValue(value?: ColorValueType) {
|
||||
return value !== undefined;
|
||||
}
|
||||
|
||||
const useColorState = (
|
||||
defaultStateValue: Color | string,
|
||||
option: { defaultValue?: Color | string; value?: Color | string },
|
||||
defaultStateValue: ColorValueType,
|
||||
option: { defaultValue?: ColorValueType; value?: ColorValueType },
|
||||
): readonly [Color, React.Dispatch<React.SetStateAction<Color>>] => {
|
||||
const { defaultValue, value } = option;
|
||||
const [colorValue, setColorValue] = useState<Color>(() => {
|
||||
let mergeState: string | Color | undefined;
|
||||
let mergeState: ColorValueType | undefined;
|
||||
if (hasValue(value)) {
|
||||
mergeState = value;
|
||||
} else if (hasValue(defaultValue)) {
|
||||
|
@ -33,3 +33,5 @@ export interface ColorPickerBaseProps {
|
||||
onFormatChange?: ColorPickerProps['onFormatChange'];
|
||||
onChangeComplete?: ColorPickerProps['onChangeComplete'];
|
||||
}
|
||||
|
||||
export type ColorValueType = Color | string | null;
|
||||
|
@ -77,6 +77,45 @@ const genClearStyle = (
|
||||
};
|
||||
};
|
||||
|
||||
const genStatusStyle = (token: ColorPickerToken): CSSObject => {
|
||||
const {
|
||||
componentCls,
|
||||
colorError,
|
||||
colorWarning,
|
||||
colorErrorBorderHover,
|
||||
colorWarningBorderHover,
|
||||
colorErrorOutline,
|
||||
colorWarningOutline,
|
||||
} = token;
|
||||
return {
|
||||
[`&${componentCls}-status-error`]: {
|
||||
borderColor: colorError,
|
||||
'&:hover': {
|
||||
borderColor: colorErrorBorderHover,
|
||||
},
|
||||
[`&${componentCls}-trigger-active`]: {
|
||||
...genActiveStyle(
|
||||
mergeToken<ColorPickerToken>(token, {
|
||||
controlOutline: colorErrorOutline,
|
||||
}),
|
||||
),
|
||||
},
|
||||
},
|
||||
[`&${componentCls}-status-warning`]: {
|
||||
borderColor: colorWarning,
|
||||
'&:hover': {
|
||||
borderColor: colorWarningBorderHover,
|
||||
},
|
||||
[`&${componentCls}-trigger-active`]: {
|
||||
...genActiveStyle(
|
||||
mergeToken<ColorPickerToken>(token, {
|
||||
controlOutline: colorWarningOutline,
|
||||
}),
|
||||
),
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
const genSizeStyle = (token: ColorPickerToken): CSSObject => {
|
||||
const {
|
||||
componentCls,
|
||||
@ -202,6 +241,7 @@ const genColorPickerStyle: GenerateStyle<ColorPickerToken> = (token) => {
|
||||
},
|
||||
...genClearStyle(token, controlHeightSM),
|
||||
...genColorBlockStyle(token, controlHeightSM),
|
||||
...genStatusStyle(token),
|
||||
...genSizeStyle(token),
|
||||
},
|
||||
...genRtlStyle(token),
|
||||
|
@ -156,7 +156,7 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
|
||||
[`${prefixCls}-borderless`]: !bordered,
|
||||
},
|
||||
getStatusClassNames(
|
||||
prefixCls as string,
|
||||
prefixCls,
|
||||
getMergedStatus(contextStatus, customStatus),
|
||||
hasFeedback,
|
||||
),
|
||||
|
@ -318,7 +318,7 @@ function postPureProps(props: DropdownProps) {
|
||||
const PurePanel = genPurePanel(Dropdown, 'dropdown', (prefixCls) => prefixCls, postPureProps);
|
||||
|
||||
/* istanbul ignore next */
|
||||
const WrapPurePanel = (props: DropdownProps) => (
|
||||
const WrapPurePanel: React.FC<DropdownProps> = (props) => (
|
||||
<PurePanel {...props}>
|
||||
<span />
|
||||
</PurePanel>
|
||||
|
@ -20842,6 +20842,414 @@ exports[`renders components/form/demo/validate-other.tsx extend context correctl
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-form-item"
|
||||
>
|
||||
<div
|
||||
class="ant-row ant-form-item-row"
|
||||
>
|
||||
<div
|
||||
class="ant-col ant-col-6 ant-form-item-label"
|
||||
>
|
||||
<label
|
||||
class="ant-form-item-required"
|
||||
for="validate_other_color-picker"
|
||||
title="ColorPicker"
|
||||
>
|
||||
ColorPicker
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-14 ant-form-item-control"
|
||||
>
|
||||
<div
|
||||
class="ant-form-item-control-input"
|
||||
>
|
||||
<div
|
||||
class="ant-form-item-control-input-content"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-trigger"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-color-block"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-color-block-inner"
|
||||
style="background: rgba(0, 0, 0, 0);"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover ant-zoom-big-appear ant-zoom-big-appear-prepare ant-zoom-big ant-color-picker ant-popover-placement-bottomLeft"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-arrow"
|
||||
style="position: absolute;"
|
||||
/>
|
||||
<div
|
||||
class="ant-popover-content"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-inner-content"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-panel"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-select"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-palette"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
style="position: absolute; left: 0px; top: 0px; z-index: 1;"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-handler"
|
||||
style="background-color: rgba(0, 0, 0, 0);"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-color-picker-saturation"
|
||||
style="background-color: rgb(255, 0, 0);"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-color-picker-slider-container"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-slider-group"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-slider ant-color-picker-slider-hue"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-palette"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
style="position: absolute; left: 0px; top: 0px; z-index: 1;"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-handler ant-color-picker-handler-sm"
|
||||
style="background-color: rgb(255, 0, 0);"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-color-picker-gradient"
|
||||
style="position: absolute; inset: 0;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-color-picker-slider ant-color-picker-slider-alpha"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-palette"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
style="position: absolute; left: 0px; top: 0px; z-index: 1;"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-handler ant-color-picker-handler-sm"
|
||||
style="background-color: rgba(0, 0, 0, 0);"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-color-picker-gradient"
|
||||
style="position: absolute; inset: 0;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-color-picker-color-block"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-color-block-inner"
|
||||
style="background: rgba(0, 0, 0, 0);"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-color-picker-input-container"
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-sm ant-select-borderless ant-color-picker-format-select ant-select-single ant-select-show-arrow"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
>
|
||||
<span
|
||||
class="ant-select-selection-search"
|
||||
>
|
||||
<input
|
||||
aria-activedescendant="rc_select_TEST_OR_SSR_list_0"
|
||||
aria-autocomplete="list"
|
||||
aria-controls="rc_select_TEST_OR_SSR_list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
aria-owns="rc_select_TEST_OR_SSR_list"
|
||||
autocomplete="off"
|
||||
class="ant-select-selection-search-input"
|
||||
id="rc_select_TEST_OR_SSR"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
style="opacity: 0;"
|
||||
type="search"
|
||||
unselectable="on"
|
||||
value=""
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-select-selection-item"
|
||||
title="HEX"
|
||||
>
|
||||
HEX
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up ant-select-dropdown-placement-bottomRight"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box; width: 68px;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
id="rc_select_TEST_OR_SSR_list"
|
||||
role="listbox"
|
||||
style="height: 0px; width: 0px; overflow: hidden;"
|
||||
>
|
||||
<div
|
||||
aria-label="HEX"
|
||||
aria-selected="true"
|
||||
id="rc_select_TEST_OR_SSR_list_0"
|
||||
role="option"
|
||||
>
|
||||
hex
|
||||
</div>
|
||||
<div
|
||||
aria-label="HSB"
|
||||
aria-selected="false"
|
||||
id="rc_select_TEST_OR_SSR_list_1"
|
||||
role="option"
|
||||
>
|
||||
hsb
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="rc-virtual-list"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
class="rc-virtual-list-holder"
|
||||
style="max-height: 256px; overflow-y: auto;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="rc-virtual-list-holder-inner"
|
||||
style="display: flex; flex-direction: column;"
|
||||
>
|
||||
<div
|
||||
aria-selected="true"
|
||||
class="ant-select-item ant-select-item-option ant-select-item-option-active ant-select-item-option-selected"
|
||||
title="HEX"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
HEX
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option"
|
||||
title="HSB"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
HSB
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option"
|
||||
title="RGB"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
RGB
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-arrow"
|
||||
style="user-select: none;"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down ant-select-suffix"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-color-picker-input"
|
||||
>
|
||||
<span
|
||||
class="ant-input-affix-wrapper ant-color-picker-hex-input ant-input-affix-wrapper-sm"
|
||||
>
|
||||
<span
|
||||
class="ant-input-prefix"
|
||||
>
|
||||
#
|
||||
</span>
|
||||
<input
|
||||
class="ant-input ant-input-sm"
|
||||
type="text"
|
||||
value="000000"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-input-number ant-input-number-sm ant-color-picker-steppers ant-color-picker-alpha-input"
|
||||
>
|
||||
<div
|
||||
class="ant-input-number-handler-wrap"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
aria-label="Increase Value"
|
||||
class="ant-input-number-handler ant-input-number-handler-up"
|
||||
role="button"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="up"
|
||||
class="anticon anticon-up ant-input-number-handler-up-inner"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="up"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
aria-disabled="true"
|
||||
aria-label="Decrease Value"
|
||||
class="ant-input-number-handler ant-input-number-handler-down ant-input-number-handler-down-disabled"
|
||||
role="button"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down ant-input-number-handler-down-inner"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-input-number-input-wrap"
|
||||
>
|
||||
<input
|
||||
aria-valuemax="100"
|
||||
aria-valuemin="0"
|
||||
aria-valuenow="0"
|
||||
autocomplete="off"
|
||||
class="ant-input-number-input"
|
||||
role="spinbutton"
|
||||
step="1"
|
||||
value="0%"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-form-item"
|
||||
>
|
||||
|
@ -9703,6 +9703,49 @@ exports[`renders components/form/demo/validate-other.tsx correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-form-item"
|
||||
>
|
||||
<div
|
||||
class="ant-row ant-form-item-row"
|
||||
>
|
||||
<div
|
||||
class="ant-col ant-col-6 ant-form-item-label"
|
||||
>
|
||||
<label
|
||||
class="ant-form-item-required"
|
||||
for="validate_other_color-picker"
|
||||
title="ColorPicker"
|
||||
>
|
||||
ColorPicker
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-14 ant-form-item-control"
|
||||
>
|
||||
<div
|
||||
class="ant-form-item-control-input"
|
||||
>
|
||||
<div
|
||||
class="ant-form-item-control-input-content"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-trigger"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-color-block"
|
||||
>
|
||||
<div
|
||||
class="ant-color-picker-color-block-inner"
|
||||
style="background:rgba(0, 0, 0, 0)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-form-item"
|
||||
>
|
||||
|
@ -3,6 +3,7 @@ import {
|
||||
Button,
|
||||
Checkbox,
|
||||
Col,
|
||||
ColorPicker,
|
||||
Form,
|
||||
InputNumber,
|
||||
Radio,
|
||||
@ -40,7 +41,12 @@ const App: React.FC = () => (
|
||||
name="validate_other"
|
||||
{...formItemLayout}
|
||||
onFinish={onFinish}
|
||||
initialValues={{ 'input-number': 3, 'checkbox-group': ['A', 'B'], rate: 3.5 }}
|
||||
initialValues={{
|
||||
'input-number': 3,
|
||||
'checkbox-group': ['A', 'B'],
|
||||
rate: 3.5,
|
||||
'color-picker': null,
|
||||
}}
|
||||
style={{ maxWidth: 600 }}
|
||||
>
|
||||
<Form.Item label="Plain Text">
|
||||
@ -168,7 +174,6 @@ const App: React.FC = () => (
|
||||
<Button icon={<UploadOutlined />}>Click to upload</Button>
|
||||
</Upload>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="Dragger">
|
||||
<Form.Item name="dragger" valuePropName="fileList" getValueFromEvent={normFile} noStyle>
|
||||
<Upload.Dragger name="files" action="/upload.do">
|
||||
@ -180,6 +185,13 @@ const App: React.FC = () => (
|
||||
</Upload.Dragger>
|
||||
</Form.Item>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="color-picker"
|
||||
label="ColorPicker"
|
||||
rules={[{ required: true, message: 'color is required!' }]}
|
||||
>
|
||||
<ColorPicker />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item wrapperCol={{ span: 12, offset: 6 }}>
|
||||
<Space>
|
||||
|
@ -13,6 +13,7 @@ const App: React.FC = () => (
|
||||
src="https://mdn.alipayobjects.com/huamei_iwk9zp/afts/file/A*uYT7SZwhJnUAAAAAAAAAAAAADgCCAQ"
|
||||
/>
|
||||
),
|
||||
toolbarRender: () => null,
|
||||
}}
|
||||
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
|
||||
/>
|
||||
|
@ -1,10 +1,10 @@
|
||||
## zh-CN
|
||||
|
||||
可以自定义工具栏并添加下载图片按钮。
|
||||
可以自定义工具栏并添加下载原图或翻转旋转后图片的按钮。
|
||||
|
||||
## en-US
|
||||
|
||||
You can customize the toolbar and add a button for downloading the image.
|
||||
You can customize the toolbar and add a button for downloading the original image or downloading the flipped and rotated image.
|
||||
|
||||
```css
|
||||
.toolbar-wrapper {
|
||||
|
@ -12,6 +12,8 @@ import React from 'react';
|
||||
const src = 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png';
|
||||
|
||||
const App: React.FC = () => {
|
||||
// or you can download flipped and rotated image
|
||||
// https://codesandbox.io/s/zi-ding-yi-gong-ju-lan-antd-5-7-0-forked-c9jvmp
|
||||
const onDownload = () => {
|
||||
fetch(src)
|
||||
.then((response) => response.blob())
|
||||
|
@ -13,14 +13,15 @@ export interface CompositionImage<P> extends React.FC<P> {
|
||||
PreviewGroup: typeof PreviewGroup;
|
||||
}
|
||||
|
||||
const Image: CompositionImage<ImageProps> = ({
|
||||
prefixCls: customizePrefixCls,
|
||||
preview,
|
||||
className,
|
||||
rootClassName,
|
||||
style,
|
||||
...otherProps
|
||||
}) => {
|
||||
const Image: CompositionImage<ImageProps> = (props) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
preview,
|
||||
className,
|
||||
rootClassName,
|
||||
style,
|
||||
...otherProps
|
||||
} = props;
|
||||
const {
|
||||
getPrefixCls,
|
||||
locale: contextLocale = defaultLocale,
|
||||
|
@ -1,10 +1,10 @@
|
||||
import classNames from 'classnames';
|
||||
import * as React from 'react';
|
||||
import { useContext, useMemo } from 'react';
|
||||
import warning from '../_util/warning';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import type { FormItemStatusContextProps } from '../form/context';
|
||||
import { FormItemInputContext } from '../form/context';
|
||||
import warning from '../_util/warning';
|
||||
import useStyle from './style';
|
||||
|
||||
export interface GroupProps {
|
||||
@ -22,7 +22,7 @@ export interface GroupProps {
|
||||
|
||||
const Group: React.FC<GroupProps> = (props) => {
|
||||
const { getPrefixCls, direction } = useContext(ConfigContext);
|
||||
const { prefixCls: customizePrefixCls, className = '' } = props;
|
||||
const { prefixCls: customizePrefixCls, className } = props;
|
||||
const prefixCls = getPrefixCls('input-group', customizePrefixCls);
|
||||
const inputPrefixCls = getPrefixCls('input');
|
||||
const [wrapSSR, hashId] = useStyle(inputPrefixCls);
|
||||
|
@ -6,8 +6,8 @@ import omit from 'rc-util/lib/omit';
|
||||
import * as React from 'react';
|
||||
import { useContext, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import isNumeric from '../_util/isNumeric';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import { LayoutContext } from './layout';
|
||||
|
||||
const dimensionMaxMap = {
|
||||
@ -58,172 +58,161 @@ const generateId = (() => {
|
||||
};
|
||||
})();
|
||||
|
||||
const Sider = React.forwardRef<HTMLDivElement, SiderProps>(
|
||||
(
|
||||
{
|
||||
prefixCls: customizePrefixCls,
|
||||
className,
|
||||
trigger,
|
||||
children,
|
||||
defaultCollapsed = false,
|
||||
theme = 'dark',
|
||||
style = {},
|
||||
collapsible = false,
|
||||
reverseArrow = false,
|
||||
width = 200,
|
||||
collapsedWidth = 80,
|
||||
zeroWidthTriggerStyle,
|
||||
breakpoint,
|
||||
onCollapse,
|
||||
onBreakpoint,
|
||||
...props
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const { siderHook } = useContext(LayoutContext);
|
||||
const Sider = React.forwardRef<HTMLDivElement, SiderProps>((props, ref) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
className,
|
||||
trigger,
|
||||
children,
|
||||
defaultCollapsed = false,
|
||||
theme = 'dark',
|
||||
style = {},
|
||||
collapsible = false,
|
||||
reverseArrow = false,
|
||||
width = 200,
|
||||
collapsedWidth = 80,
|
||||
zeroWidthTriggerStyle,
|
||||
breakpoint,
|
||||
onCollapse,
|
||||
onBreakpoint,
|
||||
...otherProps
|
||||
} = props;
|
||||
const { siderHook } = useContext(LayoutContext);
|
||||
|
||||
const [collapsed, setCollapsed] = useState(
|
||||
'collapsed' in props ? props.collapsed : defaultCollapsed,
|
||||
);
|
||||
const [below, setBelow] = useState(false);
|
||||
const [collapsed, setCollapsed] = useState(
|
||||
'collapsed' in props ? props.collapsed : defaultCollapsed,
|
||||
);
|
||||
const [below, setBelow] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if ('collapsed' in props) {
|
||||
setCollapsed(props.collapsed);
|
||||
}
|
||||
}, [props.collapsed]);
|
||||
useEffect(() => {
|
||||
if ('collapsed' in props) {
|
||||
setCollapsed(props.collapsed);
|
||||
}
|
||||
}, [props.collapsed]);
|
||||
|
||||
const handleSetCollapsed = (value: boolean, type: CollapseType) => {
|
||||
if (!('collapsed' in props)) {
|
||||
setCollapsed(value);
|
||||
}
|
||||
onCollapse?.(value, type);
|
||||
};
|
||||
const handleSetCollapsed = (value: boolean, type: CollapseType) => {
|
||||
if (!('collapsed' in props)) {
|
||||
setCollapsed(value);
|
||||
}
|
||||
onCollapse?.(value, type);
|
||||
};
|
||||
|
||||
// ========================= Responsive =========================
|
||||
const responsiveHandlerRef = useRef<(mql: MediaQueryListEvent | MediaQueryList) => void>();
|
||||
responsiveHandlerRef.current = (mql: MediaQueryListEvent | MediaQueryList) => {
|
||||
setBelow(mql.matches);
|
||||
onBreakpoint?.(mql.matches);
|
||||
// ========================= Responsive =========================
|
||||
const responsiveHandlerRef = useRef<(mql: MediaQueryListEvent | MediaQueryList) => void>();
|
||||
responsiveHandlerRef.current = (mql: MediaQueryListEvent | MediaQueryList) => {
|
||||
setBelow(mql.matches);
|
||||
onBreakpoint?.(mql.matches);
|
||||
|
||||
if (collapsed !== mql.matches) {
|
||||
handleSetCollapsed(mql.matches, 'responsive');
|
||||
}
|
||||
};
|
||||
if (collapsed !== mql.matches) {
|
||||
handleSetCollapsed(mql.matches, 'responsive');
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
function responsiveHandler(mql: MediaQueryListEvent | MediaQueryList) {
|
||||
return responsiveHandlerRef.current!(mql);
|
||||
}
|
||||
useEffect(() => {
|
||||
function responsiveHandler(mql: MediaQueryListEvent | MediaQueryList) {
|
||||
return responsiveHandlerRef.current!(mql);
|
||||
}
|
||||
|
||||
let mql: MediaQueryList;
|
||||
if (typeof window !== 'undefined') {
|
||||
const { matchMedia } = window;
|
||||
if (matchMedia! && breakpoint && breakpoint in dimensionMaxMap) {
|
||||
mql = matchMedia(`(max-width: ${dimensionMaxMap[breakpoint]})`);
|
||||
try {
|
||||
mql.addEventListener('change', responsiveHandler);
|
||||
} catch (error) {
|
||||
mql.addListener(responsiveHandler);
|
||||
}
|
||||
responsiveHandler(mql);
|
||||
}
|
||||
}
|
||||
return () => {
|
||||
let mql: MediaQueryList;
|
||||
if (typeof window !== 'undefined') {
|
||||
const { matchMedia } = window;
|
||||
if (matchMedia! && breakpoint && breakpoint in dimensionMaxMap) {
|
||||
mql = matchMedia(`(max-width: ${dimensionMaxMap[breakpoint]})`);
|
||||
try {
|
||||
mql?.removeEventListener('change', responsiveHandler);
|
||||
mql.addEventListener('change', responsiveHandler);
|
||||
} catch (error) {
|
||||
mql?.removeListener(responsiveHandler);
|
||||
mql.addListener(responsiveHandler);
|
||||
}
|
||||
};
|
||||
}, [breakpoint]); // in order to accept dynamic 'breakpoint' property, we need to add 'breakpoint' into dependency array.
|
||||
responsiveHandler(mql);
|
||||
}
|
||||
}
|
||||
return () => {
|
||||
try {
|
||||
mql?.removeEventListener('change', responsiveHandler);
|
||||
} catch (error) {
|
||||
mql?.removeListener(responsiveHandler);
|
||||
}
|
||||
};
|
||||
}, [breakpoint]); // in order to accept dynamic 'breakpoint' property, we need to add 'breakpoint' into dependency array.
|
||||
|
||||
useEffect(() => {
|
||||
const uniqueId = generateId('ant-sider-');
|
||||
siderHook.addSider(uniqueId);
|
||||
return () => siderHook.removeSider(uniqueId);
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
const uniqueId = generateId('ant-sider-');
|
||||
siderHook.addSider(uniqueId);
|
||||
return () => siderHook.removeSider(uniqueId);
|
||||
}, []);
|
||||
|
||||
const toggle = () => {
|
||||
handleSetCollapsed(!collapsed, 'clickTrigger');
|
||||
const toggle = () => {
|
||||
handleSetCollapsed(!collapsed, 'clickTrigger');
|
||||
};
|
||||
|
||||
const { getPrefixCls } = useContext(ConfigContext);
|
||||
|
||||
const renderSider = () => {
|
||||
const prefixCls = getPrefixCls('layout-sider', customizePrefixCls);
|
||||
const divProps = omit(otherProps, ['collapsed']);
|
||||
const rawWidth = collapsed ? collapsedWidth : width;
|
||||
// use "px" as fallback unit for width
|
||||
const siderWidth = isNumeric(rawWidth) ? `${rawWidth}px` : String(rawWidth);
|
||||
// special trigger when collapsedWidth == 0
|
||||
const zeroWidthTrigger =
|
||||
parseFloat(String(collapsedWidth || 0)) === 0 ? (
|
||||
<span
|
||||
onClick={toggle}
|
||||
className={classNames(
|
||||
`${prefixCls}-zero-width-trigger`,
|
||||
`${prefixCls}-zero-width-trigger-${reverseArrow ? 'right' : 'left'}`,
|
||||
)}
|
||||
style={zeroWidthTriggerStyle}
|
||||
>
|
||||
{trigger || <BarsOutlined />}
|
||||
</span>
|
||||
) : null;
|
||||
const iconObj = {
|
||||
expanded: reverseArrow ? <RightOutlined /> : <LeftOutlined />,
|
||||
collapsed: reverseArrow ? <LeftOutlined /> : <RightOutlined />,
|
||||
};
|
||||
const status = collapsed ? 'collapsed' : 'expanded';
|
||||
const defaultTrigger = iconObj[status];
|
||||
const triggerDom =
|
||||
trigger !== null
|
||||
? zeroWidthTrigger || (
|
||||
<div className={`${prefixCls}-trigger`} onClick={toggle} style={{ width: siderWidth }}>
|
||||
{trigger || defaultTrigger}
|
||||
</div>
|
||||
)
|
||||
: null;
|
||||
|
||||
const divStyle: React.CSSProperties = {
|
||||
...style,
|
||||
flex: `0 0 ${siderWidth}`,
|
||||
maxWidth: siderWidth, // Fix width transition bug in IE11
|
||||
minWidth: siderWidth, // https://github.com/ant-design/ant-design/issues/6349
|
||||
width: siderWidth,
|
||||
};
|
||||
|
||||
const { getPrefixCls } = useContext(ConfigContext);
|
||||
|
||||
const renderSider = () => {
|
||||
const prefixCls = getPrefixCls('layout-sider', customizePrefixCls);
|
||||
const divProps = omit(props, ['collapsed']);
|
||||
const rawWidth = collapsed ? collapsedWidth : width;
|
||||
// use "px" as fallback unit for width
|
||||
const siderWidth = isNumeric(rawWidth) ? `${rawWidth}px` : String(rawWidth);
|
||||
// special trigger when collapsedWidth == 0
|
||||
const zeroWidthTrigger =
|
||||
parseFloat(String(collapsedWidth || 0)) === 0 ? (
|
||||
<span
|
||||
onClick={toggle}
|
||||
className={classNames(
|
||||
`${prefixCls}-zero-width-trigger`,
|
||||
`${prefixCls}-zero-width-trigger-${reverseArrow ? 'right' : 'left'}`,
|
||||
)}
|
||||
style={zeroWidthTriggerStyle}
|
||||
>
|
||||
{trigger || <BarsOutlined />}
|
||||
</span>
|
||||
) : null;
|
||||
const iconObj = {
|
||||
expanded: reverseArrow ? <RightOutlined /> : <LeftOutlined />,
|
||||
collapsed: reverseArrow ? <LeftOutlined /> : <RightOutlined />,
|
||||
};
|
||||
const status = collapsed ? 'collapsed' : 'expanded';
|
||||
const defaultTrigger = iconObj[status];
|
||||
const triggerDom =
|
||||
trigger !== null
|
||||
? zeroWidthTrigger || (
|
||||
<div
|
||||
className={`${prefixCls}-trigger`}
|
||||
onClick={toggle}
|
||||
style={{ width: siderWidth }}
|
||||
>
|
||||
{trigger || defaultTrigger}
|
||||
</div>
|
||||
)
|
||||
: null;
|
||||
const divStyle = {
|
||||
...style,
|
||||
flex: `0 0 ${siderWidth}`,
|
||||
maxWidth: siderWidth, // Fix width transition bug in IE11
|
||||
minWidth: siderWidth, // https://github.com/ant-design/ant-design/issues/6349
|
||||
width: siderWidth,
|
||||
};
|
||||
const siderCls = classNames(
|
||||
prefixCls,
|
||||
`${prefixCls}-${theme}`,
|
||||
{
|
||||
[`${prefixCls}-collapsed`]: !!collapsed,
|
||||
[`${prefixCls}-has-trigger`]: collapsible && trigger !== null && !zeroWidthTrigger,
|
||||
[`${prefixCls}-below`]: !!below,
|
||||
[`${prefixCls}-zero-width`]: parseFloat(siderWidth) === 0,
|
||||
},
|
||||
className,
|
||||
);
|
||||
return (
|
||||
<aside className={siderCls} {...divProps} style={divStyle} ref={ref}>
|
||||
<div className={`${prefixCls}-children`}>{children}</div>
|
||||
{collapsible || (below && zeroWidthTrigger) ? triggerDom : null}
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
|
||||
const contextValue = React.useMemo(
|
||||
() => ({
|
||||
siderCollapsed: collapsed,
|
||||
}),
|
||||
[collapsed],
|
||||
const siderCls = classNames(
|
||||
prefixCls,
|
||||
`${prefixCls}-${theme}`,
|
||||
{
|
||||
[`${prefixCls}-collapsed`]: !!collapsed,
|
||||
[`${prefixCls}-has-trigger`]: collapsible && trigger !== null && !zeroWidthTrigger,
|
||||
[`${prefixCls}-below`]: !!below,
|
||||
[`${prefixCls}-zero-width`]: parseFloat(siderWidth) === 0,
|
||||
},
|
||||
className,
|
||||
);
|
||||
return (
|
||||
<aside className={siderCls} {...divProps} style={divStyle} ref={ref}>
|
||||
<div className={`${prefixCls}-children`}>{children}</div>
|
||||
{collapsible || (below && zeroWidthTrigger) ? triggerDom : null}
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
|
||||
return <SiderContext.Provider value={contextValue}>{renderSider()}</SiderContext.Provider>;
|
||||
},
|
||||
);
|
||||
const contextValue = React.useMemo(() => ({ siderCollapsed: collapsed }), [collapsed]);
|
||||
|
||||
return <SiderContext.Provider value={contextValue}>{renderSider()}</SiderContext.Provider>;
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
Sider.displayName = 'Sider';
|
||||
|
@ -57,7 +57,7 @@ const Basic = React.forwardRef<HTMLElement, BasicPropsWithTagName>((props, ref)
|
||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||
const prefixCls = getPrefixCls('layout', customizePrefixCls);
|
||||
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls as string);
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
|
||||
const prefixWithSuffixCls = suffixCls ? `${prefixCls}-${suffixCls}` : prefixCls;
|
||||
|
||||
@ -91,7 +91,7 @@ const BasicLayout = React.forwardRef<HTMLElement, BasicPropsWithTagName>((props,
|
||||
const { getPrefixCls, layout } = React.useContext(ConfigContext);
|
||||
const prefixCls = getPrefixCls('layout', customizePrefixCls);
|
||||
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls as string);
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
const classString = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
|
@ -64,7 +64,10 @@ type CompoundedComponent = React.ForwardRefExoticComponent<
|
||||
};
|
||||
|
||||
const InternalMentions: React.ForwardRefRenderFunction<MentionsRef, MentionProps> = (
|
||||
{
|
||||
props,
|
||||
ref,
|
||||
) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
className,
|
||||
rootClassName,
|
||||
@ -78,9 +81,7 @@ const InternalMentions: React.ForwardRefRenderFunction<MentionsRef, MentionProps
|
||||
popupClassName,
|
||||
style,
|
||||
...restProps
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
} = props;
|
||||
const [focused, setFocused] = React.useState(false);
|
||||
const innerRef = React.useRef<MentionsRef>(null);
|
||||
const mergedRef = composeRef(ref, innerRef);
|
||||
|
@ -34,19 +34,20 @@ export interface PaginationConfig extends Omit<PaginationProps, 'rootClassName'>
|
||||
|
||||
export type { PaginationLocale };
|
||||
|
||||
const Pagination: React.FC<PaginationProps> = ({
|
||||
prefixCls: customizePrefixCls,
|
||||
selectPrefixCls: customizeSelectPrefixCls,
|
||||
className,
|
||||
rootClassName,
|
||||
style,
|
||||
size: customizeSize,
|
||||
locale: customLocale,
|
||||
selectComponentClass,
|
||||
responsive,
|
||||
showSizeChanger,
|
||||
...restProps
|
||||
}) => {
|
||||
const Pagination: React.FC<PaginationProps> = (props) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
selectPrefixCls: customizeSelectPrefixCls,
|
||||
className,
|
||||
rootClassName,
|
||||
style,
|
||||
size: customizeSize,
|
||||
locale: customLocale,
|
||||
selectComponentClass,
|
||||
responsive,
|
||||
showSizeChanger,
|
||||
...restProps
|
||||
} = props;
|
||||
const { xs } = useBreakpoint(responsive);
|
||||
|
||||
const { getPrefixCls, direction, pagination = {} } = React.useContext(ConfigContext);
|
||||
|
@ -10,7 +10,6 @@ import { ConfigContext } from '../config-provider';
|
||||
import { useLocale } from '../locale';
|
||||
import defaultLocale from '../locale/en_US';
|
||||
import PopoverPurePanel from '../popover/PurePanel';
|
||||
|
||||
import useStyle from './style';
|
||||
|
||||
export interface PopconfirmLocale {
|
||||
@ -100,7 +99,7 @@ export interface PurePanelProps
|
||||
prefixCls?: string;
|
||||
}
|
||||
|
||||
export default function PurePanel(props: PurePanelProps) {
|
||||
const PurePanel: React.FC<PurePanelProps> = (props) => {
|
||||
const { prefixCls: customizePrefixCls, placement, className, style, ...restProps } = props;
|
||||
|
||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||
@ -115,4 +114,6 @@ export default function PurePanel(props: PurePanelProps) {
|
||||
content={<Overlay prefixCls={prefixCls} {...restProps} />}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default PurePanel;
|
||||
|
@ -34,6 +34,7 @@ demo:
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| autoFocus | 自动获取焦点 | boolean | false | |
|
||||
| allowClear | 支持清除, 单选模式有效 | boolean | false | |
|
||||
| defaultValue | 设置初始取值。当 `range` 为 false 时,使用 number,否则用 \[number, number] | number \| \[number, number] | 0 \| \[0, 0] | |
|
||||
| disabled | 值为 true 时,滑块为禁用状态 | boolean | false | |
|
||||
@ -51,6 +52,9 @@ demo:
|
||||
| vertical | 值为 true 时,Slider 为垂直方向 | boolean | false | |
|
||||
| onAfterChange | 与 `onmouseup` 触发时机一致,把当前值作为参数传入 | (value) => void | - | |
|
||||
| onChange | 当 Slider 的值发生改变时,会触发 onChange 事件,并把改变后的值作为参数传入 | (value) => void | - | |
|
||||
| trackStyle | Slider 滑动条轨道样式 (选中范围内) | CSSProperties | - | |
|
||||
| railStyle | Slider 滑动条轨道样式 (背景) | CSSProperties | - | |
|
||||
| handleStyle | Slider 滑动滑块样式 | CSSProperties | - | |
|
||||
|
||||
### range
|
||||
|
||||
|
@ -2,10 +2,10 @@ import DeleteOutlined from '@ant-design/icons/DeleteOutlined';
|
||||
import classNames from 'classnames';
|
||||
import * as React from 'react';
|
||||
import type { KeyWiseTransferItem } from '.';
|
||||
import Checkbox from '../checkbox';
|
||||
import defaultLocale from '../locale/en_US';
|
||||
import { useLocale } from '../locale';
|
||||
import TransButton from '../_util/transButton';
|
||||
import Checkbox from '../checkbox';
|
||||
import { useLocale } from '../locale';
|
||||
import defaultLocale from '../locale/en_US';
|
||||
|
||||
type ListItemProps<RecordType> = {
|
||||
renderedText?: string | number;
|
||||
@ -32,8 +32,7 @@ const ListItem = <RecordType extends KeyWiseTransferItem>(props: ListItemProps<R
|
||||
showRemove,
|
||||
} = props;
|
||||
|
||||
const className = classNames({
|
||||
[`${prefixCls}-content-item`]: true,
|
||||
const className = classNames(`${prefixCls}-content-item`, {
|
||||
[`${prefixCls}-content-item-disabled`]: disabled || item.disabled,
|
||||
[`${prefixCls}-content-item-checked`]: checked,
|
||||
});
|
||||
|
@ -3,10 +3,10 @@ import classNames from 'classnames';
|
||||
import type { AutoSizeType } from 'rc-textarea';
|
||||
import KeyCode from 'rc-util/lib/KeyCode';
|
||||
import * as React from 'react';
|
||||
import type { DirectionType } from '../config-provider';
|
||||
import TextArea from '../input/TextArea';
|
||||
import type { TextAreaRef } from '../input/TextArea';
|
||||
import { cloneElement } from '../_util/reactNode';
|
||||
import type { DirectionType } from '../config-provider';
|
||||
import type { TextAreaRef } from '../input/TextArea';
|
||||
import TextArea from '../input/TextArea';
|
||||
import useStyle from './style';
|
||||
|
||||
interface EditableProps {
|
||||
@ -25,21 +25,22 @@ interface EditableProps {
|
||||
component?: string;
|
||||
}
|
||||
|
||||
const Editable: React.FC<EditableProps> = ({
|
||||
prefixCls,
|
||||
'aria-label': ariaLabel,
|
||||
className,
|
||||
style,
|
||||
direction,
|
||||
maxLength,
|
||||
autoSize = true,
|
||||
value,
|
||||
onSave,
|
||||
onCancel,
|
||||
onEnd,
|
||||
component,
|
||||
enterIcon = <EnterOutlined />,
|
||||
}) => {
|
||||
const Editable: React.FC<EditableProps> = (props) => {
|
||||
const {
|
||||
prefixCls,
|
||||
'aria-label': ariaLabel,
|
||||
className,
|
||||
style,
|
||||
direction,
|
||||
maxLength,
|
||||
autoSize = true,
|
||||
value,
|
||||
onSave,
|
||||
onCancel,
|
||||
onEnd,
|
||||
component,
|
||||
enterIcon = <EnterOutlined />,
|
||||
} = props;
|
||||
const ref = React.useRef<TextAreaRef>(null);
|
||||
|
||||
const inComposition = React.useRef(false);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Keyframes } from '@ant-design/cssinjs';
|
||||
import type { UploadToken } from '.';
|
||||
import type { GenerateStyle } from '../../theme/internal';
|
||||
import { initFadeMotion } from '../../style/motion';
|
||||
|
||||
const uploadAnimateInlineIn = new Keyframes('uploadAnimateInlineIn', {
|
||||
from: {
|
||||
@ -44,6 +45,9 @@ const genMotionStyle: GenerateStyle<UploadToken> = (token) => {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
[`${componentCls}-wrapper`]: initFadeMotion(token),
|
||||
},
|
||||
uploadAnimateInlineIn,
|
||||
uploadAnimateInlineOut,
|
||||
];
|
||||
|
@ -238,7 +238,7 @@ exports[`renders components/watermark/demo/custom.tsx extend context correctly 1
|
||||
class="ant-color-picker-input-container"
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-sm ant-select-borderless ant-select-in-form-item ant-color-picker-format-select ant-select-single ant-select-show-arrow"
|
||||
class="ant-select ant-select-sm ant-select-borderless ant-color-picker-format-select ant-select-single ant-select-show-arrow"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
@ -414,7 +414,7 @@ exports[`renders components/watermark/demo/custom.tsx extend context correctly 1
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-input-number ant-input-number-sm ant-input-number-in-form-item ant-color-picker-steppers ant-color-picker-alpha-input"
|
||||
class="ant-input-number ant-input-number-sm ant-color-picker-steppers ant-color-picker-alpha-input"
|
||||
>
|
||||
<div
|
||||
class="ant-input-number-handler-wrap"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "5.6.4",
|
||||
"version": "5.7.0",
|
||||
"packageManager": "^npm@9.0.0",
|
||||
"description": "An enterprise-class UI design language and React components implementation",
|
||||
"title": "Ant Design",
|
||||
@ -242,7 +242,7 @@
|
||||
"inquirer": "^9.1.2",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"jest": "^29.4.1",
|
||||
"jest-axe": "^7.0.0",
|
||||
"jest-axe": "^8.0.0",
|
||||
"jest-canvas-mock": "^2.4.0",
|
||||
"jest-environment-jsdom": "^29.0.1",
|
||||
"jest-environment-node": "^29.0.0",
|
||||
@ -325,4 +325,4 @@
|
||||
"*.{ts,tsx,js,jsx}": "prettier --ignore-unknown --write",
|
||||
"*.{json,less,md}": "prettier --ignore-unknown --write"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,11 +57,16 @@ async function checkCommit({ files }: StatusResult) {
|
||||
async function checkRemote() {
|
||||
try {
|
||||
const { remote } = await git.fetch('origin', 'master');
|
||||
console.log(chalk.blue('⛳ Checking origin master with `git fetch origin master`'));
|
||||
if (!remote?.includes('ant-design/ant-design')) {
|
||||
console.log(
|
||||
chalk.yellow('😓 Your remote origin is not ant-design/ant-design, did you fork it?'),
|
||||
);
|
||||
exitProcess();
|
||||
console.log(chalk.blue('⛳ Checking locally with `git config --get remote.origin.url`'));
|
||||
const { value } = await git.getConfig('remote.origin.url');
|
||||
if (!value?.includes('ant-design/ant-design')) {
|
||||
console.log(
|
||||
chalk.yellow('🧐 Your remote origin is not ant-design/ant-design, did you fork it?'),
|
||||
);
|
||||
exitProcess();
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
console.log(chalk.red('🚨 Check remote failed. Skip...'));
|
||||
|
Loading…
Reference in New Issue
Block a user