mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-11-29 18:50:00 +08:00
commit
96722dbcd5
@ -181,6 +181,7 @@ export function isLocalStorageNameSupported() {
|
||||
storage.removeItem(testKey);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Your web browser does not support storing settings locally.', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ jobs:
|
||||
EVENT_NUMBER: ${{ github.event.number }}
|
||||
BASE_REF: ${{ github.base_ref }}
|
||||
run: |
|
||||
npm run test:visual-regression -- --pr-id=$EVENT_NUMBER --base-ref=$BASE_REF
|
||||
npm run test:visual-regression -- --pr-id=$EVENT_NUMBER --base-ref=$BASE_REF --max-workers=2
|
||||
|
||||
# Upload report in `visualRegressionReport`
|
||||
- name: upload report artifact
|
||||
@ -153,4 +153,4 @@ jobs:
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: visual-regression-diff-ref
|
||||
path: ./visual-regression-pr-id.txt
|
||||
path: ./visual-regression-pr-id.txt
|
||||
|
@ -16,6 +16,36 @@ tag: vVERSION
|
||||
|
||||
---
|
||||
|
||||
## 5.20.0
|
||||
|
||||
`2024-08-03`
|
||||
|
||||
- 🛠 Replace ColorPicker internal `@ctrl/tiny-color` with `@ant-design/fast-color`. [#49846](https://github.com/ant-design/ant-design/pull/49846)
|
||||
- 🆕 ConfigProvider support indicator property for Spin. [#50183](https://github.com/ant-design/ant-design/pull/50183) [@coding-ice](https://github.com/coding-ice)
|
||||
- 🆕 Upload `showUploadList` support `extra` for additional content. [#50098](https://github.com/ant-design/ant-design/pull/50098) [@guoyunhe](https://github.com/guoyunhe)
|
||||
- 🆕 Tree support custom loading icon for tree nodes with new prop `switcherLoadingIcon`. [#49716](https://github.com/ant-design/ant-design/pull/49716) [@coding-ice](https://github.com/coding-ice)
|
||||
- 🆕 Slider support `range.editable` to dynamic add/remove handles. [#49923](https://github.com/ant-design/ant-design/pull/49923)
|
||||
- 🆕 Slider `range.editable` support `minCount` and `maxCount`. [#49987](https://github.com/ant-design/ant-design/pull/49987)
|
||||
- 🆕 Support custom status render in QRCode. [#49563](https://github.com/ant-design/ant-design/pull/49563) [@kiner-tang](https://github.com/kiner-tang)
|
||||
- 🆕 Table component supports custom Filter dropdown box empty status. [#49613](https://github.com/ant-design/ant-design/pull/49613) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- 🆕 Allow user to add the Divider style of `dashed`, `dotted` or `solid`. [#49654](https://github.com/ant-design/ant-design/pull/49654) [@pinaki-08](https://github.com/pinaki-08)
|
||||
- 🆕 InputNumber supports `suffix` prop. [#49674](https://github.com/ant-design/ant-design/pull/49674) [@coding-ice](https://github.com/coding-ice)
|
||||
- 🆕 ColorPicker support gradient color type and fix controlled mode not working. [#50050](https://github.com/ant-design/ant-design/pull/50050)
|
||||
- 🆕 Input/TextArea/Mentions support `onClear` prop. [#49905](https://github.com/ant-design/ant-design/pull/49905) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- ⌨️ Optimize Input be changed repeatedly when hold the enter key in multi-mode. [rc-input#72](https://github.com/react-component/input/pull/72/files) [@crazyair](https://github.com/crazyair)
|
||||
- 🐞 Fix the issue where line-height is not effective in cssinjs mode for ColorPicker. [#50220](https://github.com/ant-design/ant-design/pull/50220) [@vagusX](https://github.com/vagusX)
|
||||
- 🐞 Fix cursor disabled state for ColorPicker. [#50217](https://github.com/ant-design/ant-design/pull/50217) [@coding-ice](https://github.com/coding-ice)
|
||||
- 🐞 Fix grouping columns does not apply sorting for Table. [#50086](https://github.com/ant-design/ant-design/pull/50086) [@Zyf665](https://github.com/Zyf665)
|
||||
- 🐞 Fix Popover/PopConfirm/Tooltip with `topLeft`, `topRight`, `bottomLeft`, `bottomRight` zoom in transform origin not correct when target element width is too large. [#50134](https://github.com/ant-design/ant-design/pull/50134)
|
||||
- 💄 Fix Tree filter node style lost. [#49773](https://github.com/ant-design/ant-design/pull/49773) [@wanpan11](https://github.com/wanpan11)
|
||||
- 💄 Optimize ColorPicker when selecting a color from the `transparent` state, it defaults to using a bright color instead of black color to enhance the user interaction experience. [#50148](https://github.com/ant-design/ant-design/pull/50148)
|
||||
- TypeScript
|
||||
- 🤖 Component Token support string and number. [#49837](https://github.com/ant-design/ant-design/pull/49837) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🤖 Improve Radio export types. [#50203](https://github.com/ant-design/ant-design/pull/50203) [@baicie](https://github.com/baicie)
|
||||
- 🌐 Locales
|
||||
- 🇪🇸 Improve Spanish translation. [#50179](https://github.com/ant-design/ant-design/pull/50179) [@sergioalmela](https://github.com/sergioalmela)
|
||||
- 🇺🇦 Add missed translation in uk_UA. [#50178](https://github.com/ant-design/ant-design/pull/50178) [@Andrik264](https://github.com/Andrik264)
|
||||
|
||||
## 5.19.4
|
||||
|
||||
`2024-07-30`
|
||||
|
@ -15,6 +15,36 @@ tag: vVERSION
|
||||
|
||||
---
|
||||
|
||||
## 5.20.0
|
||||
|
||||
`2024-08-03`
|
||||
|
||||
- 🛠 替换 ColorPicker 内部使用的 `@ctrl/tiny-color` 为 `@ant-design/fast-color`。[#49846](https://github.com/ant-design/ant-design/pull/49846)
|
||||
- 🆕 ConfigProvider 支持配置 Spin 的 indicator 属性。[#50183](https://github.com/ant-design/ant-design/pull/50183) [@coding-ice](https://github.com/coding-ice)
|
||||
- 🆕 Upload `showUploadList` 添加 `extra` 以支持渲染额外信息。[#50098](https://github.com/ant-design/ant-design/pull/50098) [@guoyunhe](https://github.com/guoyunhe)
|
||||
- 🆕 Tree 新增 `switcherLoadingIcon` 属性以支持自定义树节点的加载图标[#49716](https://github.com/ant-design/ant-design/pull/49716) [@coding-ice](https://github.com/coding-ice)
|
||||
- 🆕 Slider 支持 `range.editable` 以动态添加/删除节点。[#49923](https://github.com/ant-design/ant-design/pull/49923)
|
||||
- 🆕 Slider `range.editable` 支持 `minCount` 与 `maxCount` 以配置可编辑节点树。[#49987](https://github.com/ant-design/ant-design/pull/49987)
|
||||
- 🆕 在 QRCode 中支持自定义状态渲染。[#49563](https://github.com/ant-design/ant-design/pull/49563) [@kiner-tang](https://github.com/kiner-tang)
|
||||
- 🆕 Table 组件支持自定义过滤器下拉框空状态。 [#49613](https://github.com/ant-design/ant-design/pull/49613) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- 🆕 Divider 支持添加 `dashed`(虚线)、`dotted`(点线)或 `solid`(实线)的样式。[#49654](https://github.com/ant-design/ant-design/pull/49654) [@pinaki-08](https://github.com/pinaki-08)
|
||||
- 🆕 InputNumber 支持 `suffix` 属性。[#49674](https://github.com/ant-design/ant-design/pull/49674) [@coding-ice](https://github.com/coding-ice)
|
||||
- 🆕 ColorPicker 支持渐变色选择,并修复受控模式不生效的问题。[#50050](https://github.com/ant-design/ant-design/pull/50050)
|
||||
- 🆕 Input/TextArea/Mentions 组件支持 `onClear` 回调,便于区分点击 x 清除和手动清除这两个行为。[#49905](https://github.com/ant-design/ant-design/pull/49905) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- ⌨️ 优化 Input 下长按回车会不断触发变更的问题。[rc-input#72](https://github.com/react-component/input/pull/72/files) [@crazyair](https://github.com/crazyair)
|
||||
- 🐞 修复 ColorPicker 在 cssinjs 模式下 line-height 失效的问题。[#50220](https://github.com/ant-design/ant-design/pull/50220) [@vagusX](https://github.com/vagusX)
|
||||
- 🐞 修复 ColorPicker 在 disabled 状态下的光标问题. [#50217](https://github.com/ant-design/ant-design/pull/50217) [@coding-ice](https://github.com/coding-ice)
|
||||
- 🐞 修复 Table 中列存在分组时,排序不生效的问题。[#50086](https://github.com/ant-design/ant-design/pull/50086) [@Zyf665](https://github.com/Zyf665)
|
||||
- 🐞 修复 Popover/PopConfirm/Tooltip 在目标元素宽度过大时,使用 `topLeft`, `topRight`, `bottomLeft`, `bottomRight` 的弹出动画起始缩放中心有所偏移的问题。[#50134](https://github.com/ant-design/ant-design/pull/50134)
|
||||
- 💄 修复 Tree 组件 filter-node 节点高亮样式丢失。[#49773](https://github.com/ant-design/ant-design/pull/49773) [@wanpan11](https://github.com/wanpan11)
|
||||
- 💄 优化 ColorPicker 当从 `transparent` 状态进行颜色选取时,默认使用亮色以代替原本的纯黑色以提升用户交互体验。[#50148](https://github.com/ant-design/ant-design/pull/50148)
|
||||
- TypeScript
|
||||
- 🤖 Component Token 支持 string 或 number。[#49837](https://github.com/ant-design/ant-design/pull/49837) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🤖 改进 Radio 类型导出。[#50203](https://github.com/ant-design/ant-design/pull/50203) [@baicie](https://github.com/baicie)
|
||||
- 🌐 Locales
|
||||
- 🇪🇸 改进西班牙语本地化文案。[#50179](https://github.com/ant-design/ant-design/pull/50179) [@sergioalmela](https://github.com/sergioalmela)
|
||||
- 🇺🇦 补全 `uk_UA` 本地化文案。[#50178](https://github.com/ant-design/ant-design/pull/50178) [@Andrik264](https://github.com/Andrik264)
|
||||
|
||||
## 5.19.4
|
||||
|
||||
`2024-07-30`
|
||||
|
@ -33,6 +33,7 @@ describe('type', () => {
|
||||
type Props = GetProps<typeof FC>;
|
||||
const props: Props = { bamboo: 123 };
|
||||
|
||||
expect(FC).toBeTruthy();
|
||||
expect(props).toBeTruthy();
|
||||
});
|
||||
|
||||
@ -89,6 +90,7 @@ describe('type', () => {
|
||||
type ListItemType = GetProp<typeof Optional, 'list'>[number];
|
||||
|
||||
const item: ListItemType = { bamboo: '123' };
|
||||
expect(Optional).toBeTruthy();
|
||||
expect(item).toBeTruthy();
|
||||
});
|
||||
|
||||
|
@ -40,7 +40,7 @@ type CheckboxGroupType = GetProps<typeof Checkbox.Group>;
|
||||
|
||||
## GetProp
|
||||
|
||||
获取组件的单个 `props` 属性定义。它已经将 `NonNullable` 进行了封装,所以不用在考虑为空的情况:
|
||||
获取组件的单个 `props` 属性定义。它已经将 `NonNullable` 进行了封装,所以不用再考虑为空的情况:
|
||||
|
||||
```tsx
|
||||
import { Select } from 'antd';
|
||||
|
@ -27,6 +27,7 @@ const initCollapseMotion = (rootCls = defaultPrefixCls): CSSMotionProps => ({
|
||||
motionDeadline: 500,
|
||||
});
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const SelectPlacements = ['bottomLeft', 'bottomRight', 'topLeft', 'topRight'] as const;
|
||||
|
||||
export type SelectCommonPlacement = (typeof SelectPlacements)[number];
|
||||
|
@ -2,6 +2,7 @@ import classNames from 'classnames';
|
||||
|
||||
import type { ValidateStatus } from '../form/FormItem';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const InputStatuses = ['warning', 'error', ''] as const;
|
||||
|
||||
export type InputStatus = (typeof InputStatuses)[number];
|
||||
|
@ -147,7 +147,7 @@ const genGroupStyle: GenerateStyle<AvatarToken> = (token) => {
|
||||
[`${componentCls}-group`]: {
|
||||
display: 'inline-flex',
|
||||
|
||||
[`${componentCls}`]: {
|
||||
[componentCls]: {
|
||||
borderColor: groupBorderColor,
|
||||
},
|
||||
|
||||
|
@ -75,11 +75,14 @@ export function spaceChildren(children: React.ReactNode, needInserted: boolean)
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const ButtonTypes = ['default', 'primary', 'dashed', 'link', 'text'] as const;
|
||||
export type ButtonType = (typeof ButtonTypes)[number];
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const ButtonShapes = ['default', 'circle', 'round'] as const;
|
||||
export type ButtonShape = (typeof ButtonShapes)[number];
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const ButtonHTMLTypes = ['submit', 'button', 'reset'] as const;
|
||||
export type ButtonHTMLType = (typeof ButtonHTMLTypes)[number];
|
||||
|
@ -1,7 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
点击添加,拖拽或者删除。
|
||||
通过 `mode` 设置颜色为单一颜色还是渐变色。
|
||||
|
||||
## en-US
|
||||
|
||||
Click to add, drag out or keyboard delete.
|
||||
Set the color to a single or a gradient color via `mode`.
|
||||
|
@ -68,7 +68,7 @@ const genClearStyle = (
|
||||
border: `${unit(lineWidth)} solid ${colorSplit}`,
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
cursor: 'pointer',
|
||||
cursor: 'inherit',
|
||||
transition: `all ${token.motionDurationFast}`,
|
||||
|
||||
...extraStyle,
|
||||
@ -161,7 +161,7 @@ const genSizeStyle = (token: ColorPickerToken): CSSObject => {
|
||||
},
|
||||
|
||||
[`${componentCls}-trigger-text`]: {
|
||||
lineHeight: controlHeightXS,
|
||||
lineHeight: unit(controlHeightXS),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -53,7 +53,7 @@ describe('ConfigProvider.Form', () => {
|
||||
await act(async () => {
|
||||
try {
|
||||
await formRef.current?.validateFields();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
// Do nothing
|
||||
}
|
||||
});
|
||||
@ -76,7 +76,7 @@ describe('ConfigProvider.Form', () => {
|
||||
await act(async () => {
|
||||
try {
|
||||
await formRef.current?.validateFields();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
// Do nothing
|
||||
}
|
||||
});
|
||||
@ -126,7 +126,7 @@ describe('ConfigProvider.Form', () => {
|
||||
await act(async () => {
|
||||
try {
|
||||
await formRef.current?.validateFields();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
// Do nothing
|
||||
}
|
||||
});
|
||||
|
@ -11,6 +11,7 @@ import type { SizeType } from '../../config-provider/SizeContext';
|
||||
import type { Variant } from '../../config-provider';
|
||||
import type { TimePickerLocale } from '../../time-picker';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const DataPickerPlacements = ['bottomLeft', 'bottomRight', 'topLeft', 'topRight'] as const;
|
||||
|
||||
type DataPickerPlacement = (typeof DataPickerPlacements)[number];
|
||||
|
@ -7,15 +7,35 @@ import type { PickerLocale } from '../generatePicker';
|
||||
const locale: PickerLocale = {
|
||||
lang: {
|
||||
placeholder: 'Оберіть дату',
|
||||
yearPlaceholder: 'Оберіть рік',
|
||||
quarterPlaceholder: 'Оберіть квартал',
|
||||
monthPlaceholder: 'Оберіть місяць',
|
||||
weekPlaceholder: 'Оберіть тиждень',
|
||||
rangePlaceholder: ['Початкова дата', 'Кінцева дата'],
|
||||
rangeYearPlaceholder: ['Початковий рік', 'Кінцевий рік'],
|
||||
rangeMonthPlaceholder: ['Початковий місяць', 'Кінцевий місяць'],
|
||||
rangeWeekPlaceholder: ['Початковий тиждень', 'Кінцевий тиждень'],
|
||||
shortWeekDays: ['Нд', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
|
||||
shortMonths: [
|
||||
'Січ',
|
||||
'Лют',
|
||||
'Бер',
|
||||
'Кві',
|
||||
'Тра',
|
||||
'Чер',
|
||||
'Лип',
|
||||
'Сер',
|
||||
'Вер',
|
||||
'Жов',
|
||||
'Лис',
|
||||
'Гру',
|
||||
],
|
||||
...CalendarLocale,
|
||||
},
|
||||
timePickerLocale: {
|
||||
...TimePickerLocale,
|
||||
},
|
||||
};
|
||||
|
||||
// All settings at:
|
||||
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||
|
||||
export default locale;
|
||||
|
@ -16,6 +16,7 @@ import type { DrawerClassNames, DrawerPanelProps, DrawerStyles } from './DrawerP
|
||||
import DrawerPanel from './DrawerPanel';
|
||||
import useStyle from './style';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const SizeTypes = ['default', 'large'] as const;
|
||||
type sizeType = (typeof SizeTypes)[number];
|
||||
|
||||
|
@ -22,6 +22,7 @@ import { OverrideProvider } from '../menu/OverrideContext';
|
||||
import { useToken } from '../theme/internal';
|
||||
import useStyle from './style';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const Placements = [
|
||||
'topLeft',
|
||||
'topCenter',
|
||||
|
@ -31,6 +31,7 @@ interface FieldError {
|
||||
warnings: string[];
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const ValidateStatuses = ['success', 'warning', 'error', 'validating', ''] as const;
|
||||
export type ValidateStatus = (typeof ValidateStatuses)[number];
|
||||
|
||||
|
@ -92,6 +92,8 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
| onValuesChange | Trigger when value updated | function(changedValues, allValues) | - | |
|
||||
| clearOnDestroy | Clear form values when the form is uninstalled | boolean | false | 5.18.0 |
|
||||
|
||||
> It accepts all props which native forms support but `onSubmit`.
|
||||
|
||||
### validateMessages
|
||||
|
||||
Form provides [default verification error messages](https://github.com/ant-design/ant-design/blob/6234509d18bac1ac60fbb3f92a5b2c6a6361295a/components/locale/en_US.ts#L88-L134). You can modify the template by configuring `validateMessages` property. A common usage is to configure localization:
|
||||
|
@ -93,6 +93,8 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*ylFATY6w-ygAAA
|
||||
| onValuesChange | 字段值更新时触发回调事件 | function(changedValues, allValues) | - | |
|
||||
| clearOnDestroy | 当表单被卸载时清空表单值 | boolean | false | 5.18.0 |
|
||||
|
||||
> 支持原生 form 除 `onSubmit` 外的所有属性。
|
||||
|
||||
### validateMessages
|
||||
|
||||
Form 为验证提供了[默认的错误提示信息](https://github.com/ant-design/ant-design/blob/6234509d18bac1ac60fbb3f92a5b2c6a6361295a/components/locale/en_US.ts#L88-L134),你可以通过配置 `validateMessages` 属性,修改对应的提示模板。一种常见的使用方式,是配置国际化提示信息:
|
||||
|
@ -8,7 +8,9 @@ import RowContext from './RowContext';
|
||||
import type { RowContextState } from './RowContext';
|
||||
import { useRowStyle } from './style';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const RowAligns = ['top', 'middle', 'bottom', 'stretch'] as const;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const RowJustify = [
|
||||
'start',
|
||||
'end',
|
||||
|
@ -120,7 +120,7 @@ const Sider = React.forwardRef<HTMLDivElement, SiderProps>((props, ref) => {
|
||||
mql = matchMedia(`screen and (max-width: ${dimensionMaxMap[breakpoint]})`);
|
||||
try {
|
||||
mql.addEventListener('change', responsiveHandler);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
mql.addListener(responsiveHandler);
|
||||
}
|
||||
responsiveHandler(mql);
|
||||
@ -129,7 +129,7 @@ const Sider = React.forwardRef<HTMLDivElement, SiderProps>((props, ref) => {
|
||||
return () => {
|
||||
try {
|
||||
mql?.removeEventListener('change', responsiveHandler);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
mql?.removeListener(responsiveHandler);
|
||||
}
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@ import Calendar from '../calendar/locale/az_AZ';
|
||||
import DatePicker from '../date-picker/locale/az_AZ';
|
||||
import TimePicker from '../time-picker/locale/az_AZ';
|
||||
|
||||
const typeTemplate = '${label}Hökmlü deyil${type}';
|
||||
const typeTemplate = '${label} Hökmlü deyil ${type}';
|
||||
|
||||
const localeValues: Locale = {
|
||||
locale: 'az',
|
||||
@ -87,14 +87,14 @@ const localeValues: Locale = {
|
||||
Form: {
|
||||
optional: '(Seçimli)',
|
||||
defaultValidateMessages: {
|
||||
default: 'Sahə təsdiq xətası${label}',
|
||||
required: 'Xahiş edirik daxil olun${label}',
|
||||
enum: '${label}Onlardan biri olmalıdır[${enum}]',
|
||||
whitespace: '${label}Null xarakter ola bilməz',
|
||||
default: 'Sahə təsdiq xətası ${label}',
|
||||
required: 'Xahiş edirik daxil olun ${label}',
|
||||
enum: '${label} Onlardan biri olmalıdır[${enum}]',
|
||||
whitespace: '${label} Null xarakter ola bilməz',
|
||||
date: {
|
||||
format: '${label}Tarix formatı hökmlü deyil',
|
||||
parse: '${label}Tarixi döndərmək mümkün deyil',
|
||||
invalid: '${label}səhv tarixdir',
|
||||
format: '${label} Tarix formatı hökmlü deyil',
|
||||
parse: '${label} Tarixi döndərmək mümkün deyil',
|
||||
invalid: '${label} səhv tarixdir',
|
||||
},
|
||||
types: {
|
||||
string: typeTemplate,
|
||||
@ -112,25 +112,25 @@ const localeValues: Locale = {
|
||||
hex: typeTemplate,
|
||||
},
|
||||
string: {
|
||||
len: '${label}Olmalıdır${len}işarələr',
|
||||
min: '${label}ən az${min}işarələr',
|
||||
max: '${label}ən çox${max}işarələr',
|
||||
range: '${label}Olmalıdır${min}-${max}hərflər arasında',
|
||||
len: '${label} Olmalıdır ${len} işarələr',
|
||||
min: '${label} ən az ${min} işarələr',
|
||||
max: '${label} ən çox ${max} işarələr',
|
||||
range: '${label} Olmalıdır ${min}-${max} hərflər arasında',
|
||||
},
|
||||
number: {
|
||||
len: '${label}Bərabər olmalıdır${len}',
|
||||
min: '${label}Minimal dəyəri${min}',
|
||||
max: '${label}Maksimal qiymət:${max}',
|
||||
range: '${label}Olmalıdır${min}-${max}aralarında',
|
||||
len: '${label} Bərabər olmalıdır ${len}',
|
||||
min: '${label} Minimal dəyəri ${min}',
|
||||
max: '${label} Maksimal qiymət: ${max}',
|
||||
range: '${label} Olmalıdır ${min}-${max} aralarında',
|
||||
},
|
||||
array: {
|
||||
len: 'Olmalıdır${len}parça${label}',
|
||||
min: 'ən az${min}parça${label}',
|
||||
max: 'ən çox${max}parça${label}',
|
||||
range: '${label}miqdarıOlmalıdır${min}-${max}aralarında',
|
||||
len: 'Olmalıdır ${len} parça ${label}',
|
||||
min: 'ən az ${min} parça ${label}',
|
||||
max: 'ən çox ${max} parça ${label}',
|
||||
range: '${label} miqdarıOlmalıdır ${min}-${max} aralarında',
|
||||
},
|
||||
pattern: {
|
||||
mismatch: '${label}Şablona uyğun gəlmir${pattern}',
|
||||
mismatch: '${label} Şablona uyğun gəlmir ${pattern}',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -6,7 +6,7 @@ import Calendar from '../calendar/locale/uk_UA';
|
||||
import DatePicker from '../date-picker/locale/uk_UA';
|
||||
import TimePicker from '../time-picker/locale/uk_UA';
|
||||
|
||||
const typeTemplate = '${label} не є типом ${type}';
|
||||
const typeTemplate: string = '${label} не є типом ${type}';
|
||||
|
||||
const localeValues: Locale = {
|
||||
locale: 'uk',
|
||||
|
@ -44,10 +44,20 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
| defaultValue | Default selected value | string \| number | | |
|
||||
| disabled | Disable all segments | boolean | false | |
|
||||
| onChange | The callback function that is triggered when the state changes | function(value: string \| number) | | |
|
||||
| options | Set children optional | string\[] \| number\[] \| Array<{ label: ReactNode value: string icon? ReactNode disabled?: boolean className?: string }> | [] | |
|
||||
| options | Set children optional | string\[] \| number\[] \| SegmentedItemType\[] | [] | |
|
||||
| size | The size of the Segmented. | `large` \| `middle` \| `small` | `middle` | |
|
||||
| value | Currently selected value | string \| number | | |
|
||||
|
||||
### SegmentedItemType
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| label | Display text for Segmented item | ReactNode | - | |
|
||||
| value | Value for Segmented item | string \| number | - | |
|
||||
| icon | Display icon for Segmented item | ReactNode | - | |
|
||||
| disabled | Disabled state of segmented item | boolean | false | |
|
||||
| className | The additional css class | string | - | |
|
||||
|
||||
## Design Token
|
||||
|
||||
<ComponentTokenTable component="Segmented"></ComponentTokenTable>
|
||||
|
@ -47,10 +47,20 @@ demo:
|
||||
| defaultValue | 默认选中的值 | string \| number | | |
|
||||
| disabled | 是否禁用 | boolean | false | |
|
||||
| onChange | 选项变化时的回调函数 | function(value: string \| number) | | |
|
||||
| options | 数据化配置选项内容 | string\[] \| number\[] \| Array<{ label: ReactNode value: string icon? ReactNode disabled?: boolean className?: string }> | [] | |
|
||||
| options | 数据化配置选项内容 | string\[] \| number\[] \| SegmentedItemType\[] | [] | |
|
||||
| size | 控件尺寸 | `large` \| `middle` \| `small` | `middle` | |
|
||||
| value | 当前选中的值 | string \| number | | |
|
||||
|
||||
### SegmentedItemType
|
||||
|
||||
| 属性 | 描述 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| label | 分段项的显示文本 | ReactNode | - | |
|
||||
| value | 分段项的值 | string \| number | - | |
|
||||
| icon | 分段项的显示图标 | ReactNode | - | |
|
||||
| disabled | 分段项的禁用状态 | boolean | false | |
|
||||
| className | 自定义类名 | string | - | |
|
||||
|
||||
## 主题变量(Design Token)
|
||||
|
||||
<ComponentTokenTable component="Segmented"></ComponentTokenTable>
|
||||
|
@ -8,6 +8,7 @@ import Indicator from './Indicator';
|
||||
import useStyle from './style/index';
|
||||
import usePercent from './usePercent';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const SpinSizes = ['small', 'default', 'large'] as const;
|
||||
export type SpinSize = (typeof SpinSizes)[number];
|
||||
export type SpinIndicator = React.ReactElement<HTMLElement>;
|
||||
|
@ -64,6 +64,7 @@ export type SorterTooltipProps = TooltipProps & {
|
||||
target?: SorterTooltipTarget;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const TableActions = ['paginate', 'sort', 'filter'] as const;
|
||||
export type TableAction = (typeof TableActions)[number];
|
||||
|
||||
|
@ -2,6 +2,7 @@ import type { TimePickerLocale } from '../index';
|
||||
|
||||
const locale: TimePickerLocale = {
|
||||
placeholder: 'Оберіть час',
|
||||
rangePlaceholder: ['Початковий час', 'Кінцевий час'],
|
||||
};
|
||||
|
||||
export default locale;
|
||||
|
@ -220,7 +220,7 @@ const InternalUpload: React.ForwardRefRenderFunction<UploadRef, UploadProps> = (
|
||||
clone = new File([originFileObj], originFileObj.name, {
|
||||
type: originFileObj.type,
|
||||
}) as any as UploadFile;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
clone = new Blob([originFileObj], {
|
||||
type: originFileObj.type,
|
||||
}) as any as UploadFile;
|
||||
@ -246,7 +246,7 @@ const InternalUpload: React.ForwardRefRenderFunction<UploadRef, UploadProps> = (
|
||||
// biome-ignore lint/style/noParameterAssign: we need to modify response
|
||||
response = JSON.parse(response);
|
||||
}
|
||||
} catch (e) {
|
||||
} catch {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "5.19.4",
|
||||
"version": "5.20.0",
|
||||
"description": "An enterprise-class UI design language and React components implementation",
|
||||
"keywords": [
|
||||
"ant",
|
||||
@ -135,7 +135,7 @@
|
||||
"rc-resize-observer": "^1.4.0",
|
||||
"rc-segmented": "~2.3.0",
|
||||
"rc-select": "~14.15.1",
|
||||
"rc-slider": "~11.1.3",
|
||||
"rc-slider": "~11.1.5",
|
||||
"rc-steps": "~6.0.1",
|
||||
"rc-switch": "~4.1.0",
|
||||
"rc-table": "~7.45.7",
|
||||
@ -209,8 +209,8 @@
|
||||
"@types/tar": "^6.1.13",
|
||||
"@types/throttle-debounce": "^5.0.2",
|
||||
"@types/warning": "^3.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^7.16.1",
|
||||
"@typescript-eslint/parser": "^7.16.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||
"@typescript-eslint/parser": "^8.0.0",
|
||||
"adm-zip": "^0.5.14",
|
||||
"ali-oss": "^6.20.0",
|
||||
"antd-img-crop": "^4.22.0",
|
||||
@ -275,6 +275,7 @@
|
||||
"nprogress": "^0.2.0",
|
||||
"open": "^10.1.0",
|
||||
"ora": "^8.0.1",
|
||||
"p-all": "^5.0.0",
|
||||
"pixelmatch": "^6.0.0",
|
||||
"pngjs": "^7.0.0",
|
||||
"prettier": "^3.3.3",
|
||||
|
@ -184,9 +184,9 @@ exports[`site test Component components/result en Page 1`] = `1`;
|
||||
|
||||
exports[`site test Component components/result zh Page 1`] = `1`;
|
||||
|
||||
exports[`site test Component components/segmented en Page 1`] = `1`;
|
||||
exports[`site test Component components/segmented en Page 1`] = `2`;
|
||||
|
||||
exports[`site test Component components/segmented zh Page 1`] = `1`;
|
||||
exports[`site test Component components/segmented zh Page 1`] = `2`;
|
||||
|
||||
exports[`site test Component components/select en Page 1`] = `4`;
|
||||
|
||||
|
@ -78,6 +78,7 @@ const miscKeys = [
|
||||
'🇲🇳',
|
||||
'🇳🇵',
|
||||
'🇪🇬',
|
||||
'🇪🇸',
|
||||
];
|
||||
|
||||
(() => {
|
||||
|
@ -258,7 +258,7 @@ const runPrePublish = async () => {
|
||||
firstArtifactFile = await Promise.any([downloadArtifactPromise, downloadOSSPromise]);
|
||||
} catch (error) {
|
||||
showMessage(
|
||||
chalk.bgRedBright(`下载失败,请确认你当前 ${sha.slice(0, 6)} 位于 master 分支中`),
|
||||
chalk.bgRedBright(`下载失败 ${error},请确认你当前 ${sha.slice(0, 6)} 位于 master 分支中`),
|
||||
'fail',
|
||||
);
|
||||
process.exit(1);
|
||||
|
@ -150,19 +150,22 @@ interface IBadCase {
|
||||
const git = simpleGit();
|
||||
|
||||
async function parseArgs() {
|
||||
// parse args from -- --pr-id=123 --base_ref=feature
|
||||
// parse args from -- --pr-id=123 --base_ref=feature --max-workers=2
|
||||
const argv = minimist(process.argv.slice(2));
|
||||
const prId = argv['pr-id'];
|
||||
assert(prId, 'Missing --pr-id');
|
||||
const baseRef = argv['base-ref'];
|
||||
assert(baseRef, 'Missing --base-ref');
|
||||
|
||||
const maxWorkers = argv['max-workers'] ? parseInt(argv['max-workers'], 10) : 1;
|
||||
|
||||
const { latest } = await git.log();
|
||||
|
||||
return {
|
||||
prId,
|
||||
baseRef,
|
||||
currentRef: latest?.hash.slice(0, 8) || '',
|
||||
maxWorkers,
|
||||
};
|
||||
}
|
||||
|
||||
@ -311,7 +314,10 @@ If you think the visual diff is acceptable, please check:
|
||||
}
|
||||
|
||||
async function boot() {
|
||||
const { prId, baseRef: targetBranch = 'master', currentRef } = await parseArgs();
|
||||
const args = await parseArgs();
|
||||
console.log(`Args: ${JSON.stringify(args)}`);
|
||||
|
||||
const { prId, baseRef: targetBranch = 'master', currentRef, maxWorkers } = args;
|
||||
|
||||
const baseImgSourceDir = path.resolve(ROOT_DIR, `./imageSnapshots-${targetBranch}`);
|
||||
|
||||
@ -365,8 +371,8 @@ async function boot() {
|
||||
.map((n) => path.basename(n, path.extname(n)));
|
||||
|
||||
// compare to target branch
|
||||
for (const basename of cssInJsImgNames) {
|
||||
for (const extname of ['.png', '.css-var.png']) {
|
||||
const compareTasks = cssInJsImgNames.map((basename) =>
|
||||
['.png', '.css-var.png'].map((extname) => async () => {
|
||||
// baseImg always use cssinjs png
|
||||
const baseImgName = `${basename}.png`;
|
||||
const baseImgPath = path.join(baseImgSourceDir, baseImgName);
|
||||
@ -379,13 +385,13 @@ async function boot() {
|
||||
const currentImgExists = await fse.exists(currentImgPath);
|
||||
if (!currentImgExists) {
|
||||
console.log(chalk.red(`⛔️ Missing image: ${compareImgName}\n`));
|
||||
badCases.push({
|
||||
// base img would use twice so we cannot move it
|
||||
await fse.copy(baseImgPath, path.join(baseImgReportDir, compareImgName));
|
||||
return {
|
||||
type: 'removed',
|
||||
filename: compareImgName,
|
||||
weight: 1,
|
||||
});
|
||||
await fse.copy(baseImgPath, path.join(baseImgReportDir, compareImgName));
|
||||
continue;
|
||||
} as IBadCase;
|
||||
}
|
||||
|
||||
const mismatchedPxPercent = await compareScreenshots(
|
||||
@ -400,19 +406,28 @@ async function boot() {
|
||||
chalk.yellow(compareImgName),
|
||||
`${(mismatchedPxPercent * 100).toFixed(2)}%\n`,
|
||||
);
|
||||
// copy compare imgs(x2) to report dir
|
||||
// copy/move compare imgs(x2) to report dir
|
||||
// base img would use twice so we cannot move it
|
||||
await fse.copy(baseImgPath, path.join(baseImgReportDir, compareImgName));
|
||||
await fse.copy(currentImgPath, path.join(currentImgReportDir, compareImgName));
|
||||
await fse.move(currentImgPath, path.join(currentImgReportDir, compareImgName));
|
||||
|
||||
badCases.push({
|
||||
return {
|
||||
type: 'changed',
|
||||
filename: compareImgName,
|
||||
targetFilename: baseImgName,
|
||||
weight: mismatchedPxPercent,
|
||||
});
|
||||
} else {
|
||||
console.log('Passed for: %s\n', chalk.green(compareImgName));
|
||||
} as IBadCase;
|
||||
}
|
||||
console.log('Passed for: %s\n', chalk.green(compareImgName));
|
||||
}),
|
||||
);
|
||||
|
||||
const { default: pAll } = await import('p-all');
|
||||
|
||||
const compareResults = await pAll(compareTasks.flat(), { concurrency: maxWorkers });
|
||||
for (const compareResult of compareResults) {
|
||||
if (compareResult) {
|
||||
badCases.push(compareResult);
|
||||
}
|
||||
}
|
||||
|
||||
@ -431,16 +446,23 @@ async function boot() {
|
||||
console.log('\n');
|
||||
}
|
||||
|
||||
for (const newImg of newImgs) {
|
||||
badCases.push({
|
||||
type: 'added',
|
||||
filename: newImg,
|
||||
weight: 0,
|
||||
});
|
||||
await fse.copy(
|
||||
const newImgTask = newImgs.map((newImg) => async () => {
|
||||
await fse.move(
|
||||
path.join(currentImgSourceDir, newImg),
|
||||
path.resolve(currentImgReportDir, newImg),
|
||||
);
|
||||
return {
|
||||
type: 'added',
|
||||
filename: newImg,
|
||||
weight: 0,
|
||||
} as IBadCase;
|
||||
});
|
||||
|
||||
const newTaskResults = await pAll(newImgTask, { concurrency: maxWorkers });
|
||||
for (const newTaskResult of newTaskResults) {
|
||||
if (newTaskResult) {
|
||||
badCases.push(newTaskResult);
|
||||
}
|
||||
}
|
||||
|
||||
/* --- generate report stage --- */
|
||||
|
Loading…
Reference in New Issue
Block a user