mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-27 12:39:49 +08:00
Merge branch 'feature' into feat/button-color
This commit is contained in:
commit
a4262b7ff9
@ -8,9 +8,6 @@ import SiteContext from '../SiteContext';
|
||||
import ContributorAvatar from './ContributorAvatar';
|
||||
|
||||
const useStyle = createStyles(({ token, css }) => ({
|
||||
contributorsList: css`
|
||||
margin-top: 120px !important;
|
||||
`,
|
||||
listMobile: css`
|
||||
margin: 1em 0 !important;
|
||||
`,
|
||||
@ -50,7 +47,7 @@ const Contributors: React.FC<ContributorsProps> = ({ filename }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classNames(styles.contributorsList, { [styles.listMobile]: isMobile })}>
|
||||
<div className={classNames({ [styles.listMobile]: isMobile })}>
|
||||
<div className={styles.title}>{formatMessage({ id: 'app.content.contributors' })}</div>
|
||||
<ContributorsList
|
||||
cache
|
||||
|
@ -94,9 +94,11 @@ const Content: React.FC<React.PropsWithChildren> = ({ children }) => {
|
||||
juejinLink={meta.frontmatter.juejin_url}
|
||||
/>
|
||||
</InViewSuspense>
|
||||
<InViewSuspense fallback={<div style={{ height: 50, marginTop: 120 }} />}>
|
||||
<Contributors filename={meta.frontmatter.filename} />
|
||||
</InViewSuspense>
|
||||
<div style={{ marginTop: 120 }}>
|
||||
<InViewSuspense fallback={<div style={{ height: 50 }} />}>
|
||||
<Contributors filename={meta.frontmatter.filename} />
|
||||
</InViewSuspense>
|
||||
</div>
|
||||
</article>
|
||||
<InViewSuspense fallback={null}>
|
||||
<PrevAndNext rtl={isRTL} />
|
||||
|
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -133,7 +133,7 @@ jobs:
|
||||
bunx nyc report --reporter text -t coverage --report-dir coverage
|
||||
rm -rf persist-coverage
|
||||
- name: Upload coverage to codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
# use own token to upload coverage reports
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
@ -77,15 +77,26 @@ jobs:
|
||||
const mergedStatus = diffPassed ? 'success' : hasDiffFailed ? 'failure' : 'pending';
|
||||
console.log('Status:', mergedStatus);
|
||||
|
||||
await github.rest.repos.createCommitStatus({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
sha: prHeadSha,
|
||||
state: mergedStatus,
|
||||
context: 'Visual Regression Diff Wait Approve',
|
||||
description: diffPassed ? 'Visual diff is acceptable' : 'Visual diff is not pass',
|
||||
const { data: currentStatuses } = await github.rest.repos.listCommitStatusesForRef({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
ref: prHeadSha,
|
||||
});
|
||||
|
||||
const currentStatus = currentStatuses.find(status => status.context === 'Visual Regression Diff Wait Approve');
|
||||
if (currentStatus && currentStatus.state === mergedStatus) {
|
||||
console.log('Status has not changed, no need to update:', currentStatus.state);
|
||||
} else {
|
||||
await github.rest.repos.createCommitStatus({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
sha: prHeadSha,
|
||||
state: mergedStatus,
|
||||
context: 'Visual Regression Diff Wait Approve',
|
||||
description: diffPassed ? 'Visual diff is acceptable' : 'Visual diff is not pass',
|
||||
});
|
||||
}
|
||||
|
||||
if (hasDiffSuccess || (hasDiffFailed && hasMemberApprove)) {
|
||||
return 'success';
|
||||
} else if (hasDiffFailed) {
|
||||
|
@ -62,5 +62,17 @@
|
||||
"https://github.com/ant-design/ant-design/issues/50960",
|
||||
"https://github.com/ant-design/ant-design/issues/50969"
|
||||
],
|
||||
"5.22.0": ["https://github.com/ant-design/ant-design/issues/51601"]
|
||||
"5.21.6": [
|
||||
"https://github.com/ant-design/ant-design/issues/51420",
|
||||
"https://github.com/ant-design/ant-design/issues/51430"
|
||||
],
|
||||
"5.22.0": [
|
||||
"https://github.com/ant-design/ant-design/issues/51601",
|
||||
"https://github.com/ant-design/ant-design/issues/51420",
|
||||
"https://github.com/ant-design/ant-design/issues/51430"
|
||||
],
|
||||
"5.22.1": [
|
||||
"https://github.com/ant-design/ant-design/issues/51420",
|
||||
"https://github.com/ant-design/ant-design/issues/51430"
|
||||
]
|
||||
}
|
||||
|
@ -15,6 +15,23 @@ tag: vVERSION
|
||||
|
||||
---
|
||||
|
||||
## 5.22.2
|
||||
|
||||
`2024-11-21`
|
||||
|
||||
- 🐞 Fix Input.OTP focus from advancing when previous input is empty. [#51664](https://github.com/ant-design/ant-design/pull/51664) [@thecodesalim](https://github.com/thecodesalim)
|
||||
- 🐞 Adjust Modal function call not to scroll the confirm button when it get auto focused. [#51647](https://github.com/ant-design/ant-design/pull/51647) [@zombieJ](https://github.com/zombieJ)
|
||||
- 🐞 Fix Form `rules` with same error content will cause React render warning. [#51636](https://github.com/ant-design/ant-design/pull/51636) [@zombieJ](https://github.com/zombieJ)
|
||||
- 🐞 Refactor Button `focus` logic trigger with `useEffect` to resolve some async load case not get `autoFocus`. [#51624](https://github.com/ant-design/ant-design/pull/51624) [@zombieJ](https://github.com/zombieJ)
|
||||
- 🐞 Fix Button custom icon not center-aligned. [#51652](https://github.com/ant-design/ant-design/pull/51652) [@afc163](https://github.com/afc163)
|
||||
- 🐞 Fix Table `getCheckboxProps` event handlers being overridden by internal selection logic. [#51661](https://github.com/ant-design/ant-design/pull/51661) [@Zyf665](https://github.com/Zyf665)
|
||||
- 🐞 Fix Tree that `onCheck` and `onSelect` were not properly triggered. [#51448](https://github.com/ant-design/ant-design/pull/51448) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- 🐞 Fix vertical alignment of clear icon in Input component. [#51700](https://github.com/ant-design/ant-design/pull/51700) [@jynxio](https://github.com/jynxio)
|
||||
- 🐞 Fix Select with `prefix` style issue with color, line break, status error. [#51694](https://github.com/ant-design/ant-design/pull/51694) [@zombieJ](https://github.com/zombieJ)
|
||||
- 🌐 Localization
|
||||
- 🇷🇺 Add support for Russian translation. [#51619](https://github.com/ant-design/ant-design/pull/51619) [@avvakumovid](https://github.com/avvakumovid)
|
||||
- 🇮🇹 Add support for Italian translation in TimePicker. [#51685](https://github.com/ant-design/ant-design/pull/51685) [@LorenzoCardinali](https://github.com/LorenzoCardinali)
|
||||
|
||||
## 5.22.1
|
||||
|
||||
`2024-11-13`
|
||||
|
@ -15,6 +15,23 @@ tag: vVERSION
|
||||
|
||||
---
|
||||
|
||||
## 5.22.2
|
||||
|
||||
`2024-11-21`
|
||||
|
||||
- 🐞 修复 Input.OTP 组件在有非法输入时仍会切换到下一个输入框的问题。[#51664](https://github.com/ant-design/ant-design/pull/51664) [@thecodesalim](https://github.com/thecodesalim)
|
||||
- 🐞 调整 Modal 确认函数,使其在弹出后聚焦确认按钮时不要滚动窗体。[#51647](https://github.com/ant-design/ant-design/pull/51647) [@zombieJ](https://github.com/zombieJ)
|
||||
- 🐞 修复 Form `rules` 生成多条相同错误时会报 React 渲染错误的问题。[#51636](https://github.com/ant-design/ant-design/pull/51636) [@zombieJ](https://github.com/zombieJ)
|
||||
- 🐞 调整 Button 使用 `useEffect` 来触发 `autoFocus` 逻辑,以解决一些异步渲染场景下 Button 无法自动聚焦的问题。[#51624](https://github.com/ant-design/ant-design/pull/51624) [@zombieJ](https://github.com/zombieJ)
|
||||
- 🐞 修复 Button 中使用自定义三方图标库时图标未居中的问题。[#51652](https://github.com/ant-design/ant-design/pull/51652) [@afc163](https://github.com/afc163)
|
||||
- 🐞 修复 Table 组件 `getCheckboxProps` 中的事件处理器被内部选择逻辑覆盖的问题。[#51661](https://github.com/ant-design/ant-design/pull/51661) [@Zyf665](https://github.com/Zyf665)
|
||||
- 🐞 修复 Tree 组件的 `onCheck` 和 `onSelect` 事件没有被正确触发的问题。[#51448](https://github.com/ant-design/ant-design/pull/51448) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- 🐞 修复 Input 组件的清除按钮未能垂直居中的问题。[#51700](https://github.com/ant-design/ant-design/pull/51700) [@jynxio](https://github.com/jynxio)
|
||||
- 🐞 修复 Select 组件的 `prefix` 组合导致的颜色、折行、状态等一系列样式问题。[#51694](https://github.com/ant-design/ant-design/pull/51694) [@zombieJ](https://github.com/zombieJ)
|
||||
- 🌐 本地化
|
||||
- 🇷🇺 添加了俄语翻译支持。[#51619](https://github.com/ant-design/ant-design/pull/51619) [@avvakumovid](https://github.com/avvakumovid)
|
||||
- 🇮🇹 为 TimePicker 添加了意大利语翻译。[#51685](https://github.com/ant-design/ant-design/pull/51685) [@LorenzoCardinali](https://github.com/LorenzoCardinali)
|
||||
|
||||
## 5.22.1
|
||||
|
||||
`2024-11-13`
|
||||
|
@ -52,7 +52,9 @@ const ActionButton: React.FC<ActionButtonProps> = (props) => {
|
||||
let timeoutId: ReturnType<typeof setTimeout> | null = null;
|
||||
if (autoFocus) {
|
||||
timeoutId = setTimeout(() => {
|
||||
buttonRef.current?.focus();
|
||||
buttonRef.current?.focus({
|
||||
preventScroll: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
return () => {
|
||||
|
@ -22,7 +22,7 @@ import { isTwoCNChar, isUnBorderedButtonVariant, spaceChildren } from './buttonH
|
||||
import IconWrapper from './IconWrapper';
|
||||
import LoadingIcon from './LoadingIcon';
|
||||
import useStyle from './style';
|
||||
import CompactCmp from './style/compactCmp';
|
||||
import Compact from './style/compact';
|
||||
|
||||
export type LegacyButtonType = ButtonType | 'danger';
|
||||
|
||||
@ -337,8 +337,7 @@ const InternalCompoundedButton = React.forwardRef<
|
||||
>
|
||||
{iconNode}
|
||||
{kids}
|
||||
{/* Styles: compact */}
|
||||
{!!compactItemClassnames && <CompactCmp key="compact" prefixCls={prefixCls} />}
|
||||
{compactItemClassnames && <Compact prefixCls={prefixCls} />}
|
||||
</button>
|
||||
);
|
||||
|
||||
|
50
components/button/style/compact.ts
Normal file
50
components/button/style/compact.ts
Normal file
@ -0,0 +1,50 @@
|
||||
// Style as inline component
|
||||
import type { CSSObject } from '@ant-design/cssinjs';
|
||||
|
||||
import { genCompactItemStyle } from '../../style/compact-item';
|
||||
import { genCompactItemVerticalStyle } from '../../style/compact-item-vertical';
|
||||
import type { GenerateStyle } from '../../theme/internal';
|
||||
import { genSubStyleComponent } from '../../theme/internal';
|
||||
import type { ButtonToken } from './token';
|
||||
import { prepareComponentToken, prepareToken } from './token';
|
||||
|
||||
const genButtonCompactStyle: GenerateStyle<ButtonToken> = (token) => {
|
||||
const { componentCls, colorPrimaryHover, lineWidth, calc } = token;
|
||||
const insetOffset = calc(lineWidth).mul(-1).equal();
|
||||
const getCompactBorderStyle = (vertical?: boolean) =>
|
||||
({
|
||||
[`${componentCls}-compact${vertical ? '-vertical' : ''}-item${componentCls}-primary:not([disabled])`]:
|
||||
{
|
||||
'& + &::before': {
|
||||
position: 'absolute',
|
||||
top: vertical ? insetOffset : 0,
|
||||
insetInlineStart: vertical ? 0 : insetOffset,
|
||||
backgroundColor: colorPrimaryHover,
|
||||
content: '""',
|
||||
width: vertical ? '100%' : lineWidth,
|
||||
height: vertical ? lineWidth : '100%',
|
||||
},
|
||||
},
|
||||
}) as CSSObject;
|
||||
// Special styles for Primary Button
|
||||
return {
|
||||
...getCompactBorderStyle(),
|
||||
...getCompactBorderStyle(true),
|
||||
};
|
||||
};
|
||||
|
||||
// ============================== Export ==============================
|
||||
export default genSubStyleComponent(
|
||||
['Button', 'compact'],
|
||||
(token) => {
|
||||
const buttonToken = prepareToken(token);
|
||||
|
||||
return [
|
||||
// Space Compact
|
||||
genCompactItemStyle(buttonToken),
|
||||
genCompactItemVerticalStyle(buttonToken),
|
||||
genButtonCompactStyle(buttonToken),
|
||||
];
|
||||
},
|
||||
prepareComponentToken,
|
||||
);
|
@ -1,72 +0,0 @@
|
||||
// Style as inline component
|
||||
import { unit } from '@ant-design/cssinjs';
|
||||
|
||||
import { genCompactItemStyle } from '../../style/compact-item';
|
||||
import { genCompactItemVerticalStyle } from '../../style/compact-item-vertical';
|
||||
import type { GenerateStyle } from '../../theme/internal';
|
||||
import { genSubStyleComponent } from '../../theme/internal';
|
||||
import type { ButtonToken } from './token';
|
||||
import { prepareComponentToken, prepareToken } from './token';
|
||||
|
||||
const genButtonCompactStyle: GenerateStyle<ButtonToken> = (token) => {
|
||||
const { componentCls, calc } = token;
|
||||
|
||||
return {
|
||||
[componentCls]: {
|
||||
// Special styles for Primary Button
|
||||
[`&-compact-item${componentCls}-primary`]: {
|
||||
[`&:not([disabled]) + ${componentCls}-compact-item${componentCls}-primary:not([disabled])`]:
|
||||
{
|
||||
position: 'relative',
|
||||
|
||||
'&:before': {
|
||||
position: 'absolute',
|
||||
top: calc(token.lineWidth).mul(-1).equal(),
|
||||
insetInlineStart: calc(token.lineWidth).mul(-1).equal(),
|
||||
display: 'inline-block',
|
||||
width: token.lineWidth,
|
||||
height: `calc(100% + ${unit(token.lineWidth)} * 2)`,
|
||||
backgroundColor: token.colorPrimaryHover,
|
||||
content: '""',
|
||||
},
|
||||
},
|
||||
},
|
||||
// Special styles for Primary Button
|
||||
'&-compact-vertical-item': {
|
||||
[`&${componentCls}-primary`]: {
|
||||
[`&:not([disabled]) + ${componentCls}-compact-vertical-item${componentCls}-primary:not([disabled])`]:
|
||||
{
|
||||
position: 'relative',
|
||||
|
||||
'&:before': {
|
||||
position: 'absolute',
|
||||
top: calc(token.lineWidth).mul(-1).equal(),
|
||||
insetInlineStart: calc(token.lineWidth).mul(-1).equal(),
|
||||
display: 'inline-block',
|
||||
width: `calc(100% + ${unit(token.lineWidth)} * 2)`,
|
||||
height: token.lineWidth,
|
||||
backgroundColor: token.colorPrimaryHover,
|
||||
content: '""',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
// ============================== Export ==============================
|
||||
export default genSubStyleComponent(
|
||||
['Button', 'compact'],
|
||||
(token) => {
|
||||
const buttonToken = prepareToken(token);
|
||||
|
||||
return [
|
||||
// Space Compact
|
||||
genCompactItemStyle(buttonToken),
|
||||
genCompactItemVerticalStyle(buttonToken),
|
||||
genButtonCompactStyle(buttonToken),
|
||||
];
|
||||
},
|
||||
prepareComponentToken,
|
||||
);
|
@ -40,12 +40,8 @@ const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSS
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
|
||||
'> span': {
|
||||
display: 'inline-block',
|
||||
},
|
||||
|
||||
[`${componentCls}-icon`]: {
|
||||
lineHeight: 1,
|
||||
[`> span, ${componentCls}-icon`]: {
|
||||
display: 'inline-flex',
|
||||
},
|
||||
|
||||
'> a': {
|
||||
@ -622,10 +618,11 @@ const genButtonStyle = (token: ButtonToken, prefixCls = ''): CSSInterpolation =>
|
||||
buttonPaddingHorizontal,
|
||||
iconCls,
|
||||
buttonPaddingVertical,
|
||||
motionDurationSlow,
|
||||
motionEaseInOut,
|
||||
buttonIconOnlyFontSize,
|
||||
opacityLoading,
|
||||
} = token;
|
||||
|
||||
const iconOnlyCls = `${componentCls}-icon-only`;
|
||||
|
||||
return [
|
||||
{
|
||||
[prefixCls]: {
|
||||
@ -635,7 +632,7 @@ const genButtonStyle = (token: ButtonToken, prefixCls = ''): CSSInterpolation =>
|
||||
padding: `${unit(buttonPaddingVertical!)} ${unit(buttonPaddingHorizontal!)}`,
|
||||
borderRadius,
|
||||
|
||||
[`&${iconOnlyCls}`]: {
|
||||
[`&${componentCls}-icon-only`]: {
|
||||
width: controlHeight,
|
||||
paddingInline: 0,
|
||||
|
||||
@ -649,22 +646,21 @@ const genButtonStyle = (token: ButtonToken, prefixCls = ''): CSSInterpolation =>
|
||||
},
|
||||
|
||||
[iconCls]: {
|
||||
fontSize: token.buttonIconOnlyFontSize,
|
||||
fontSize: buttonIconOnlyFontSize,
|
||||
},
|
||||
},
|
||||
|
||||
// Loading
|
||||
[`&${componentCls}-loading`]: {
|
||||
opacity: token.opacityLoading,
|
||||
opacity: opacityLoading,
|
||||
cursor: 'default',
|
||||
},
|
||||
|
||||
[`${componentCls}-loading-icon`]: {
|
||||
transition: `width ${token.motionDurationSlow} ${token.motionEaseInOut}, opacity ${token.motionDurationSlow} ${token.motionEaseInOut}`,
|
||||
transition: `width ${motionDurationSlow} ${motionEaseInOut}, opacity ${motionDurationSlow} ${motionEaseInOut}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Shape - patch prefixCls again to override solid border radius style
|
||||
{
|
||||
[`${componentCls}${componentCls}-circle${prefixCls}`]: genCircleButtonStyle(token),
|
||||
|
@ -31,7 +31,7 @@ demo:
|
||||
<code src="./demo/search.tsx">Search</code>
|
||||
<code src="./demo/lazy.tsx">Load Options Lazily</code>
|
||||
<code src="./demo/fields-name.tsx">Custom Field Names</code>
|
||||
<code src="./demo/suffix.tsx" debug>Prefix and Suffix</code>
|
||||
<code src="./demo/suffix.tsx" version="5.22.0">Prefix and Suffix</code>
|
||||
<code src="./demo/custom-dropdown.tsx">Custom dropdown</code>
|
||||
<code src="./demo/placement.tsx">Placement</code>
|
||||
<code src="./demo/status.tsx">Status</code>
|
||||
@ -67,7 +67,7 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
| maxTagCount | Max tag count to show. `responsive` will cost render performance | number \| `responsive` | - | 4.17.0 |
|
||||
| maxTagPlaceholder | Placeholder for not showing tags | ReactNode \| function(omittedValues) | - | 4.17.0 |
|
||||
| maxTagTextLength | Max tag text length to show | number | - | 4.17.0 |
|
||||
| notFoundContent | Specify content to show when no result matches | string | `Not Found` | |
|
||||
| notFoundContent | Specify content to show when no result matches | ReactNode | `Not Found` | |
|
||||
| open | Set visible of cascader popup | boolean | - | 4.17.0 |
|
||||
| options | The data options of cascade | [Option](#option)\[] | - | |
|
||||
| placeholder | The input placeholder | string | - | |
|
||||
|
@ -32,7 +32,7 @@ demo:
|
||||
<code src="./demo/search.tsx">搜索</code>
|
||||
<code src="./demo/lazy.tsx">动态加载选项</code>
|
||||
<code src="./demo/fields-name.tsx">自定义字段名</code>
|
||||
<code src="./demo/suffix.tsx" debug>前后缀</code>
|
||||
<code src="./demo/suffix.tsx" version="5.22.0">前后缀</code>
|
||||
<code src="./demo/custom-dropdown.tsx">扩展菜单</code>
|
||||
<code src="./demo/placement.tsx">弹出位置</code>
|
||||
<code src="./demo/status.tsx">自定义状态</code>
|
||||
@ -68,7 +68,7 @@ demo:
|
||||
| maxTagCount | 最多显示多少个 tag,响应式模式会对性能产生损耗 | number \| `responsive` | - | 4.17.0 |
|
||||
| maxTagPlaceholder | 隐藏 tag 时显示的内容 | ReactNode \| function(omittedValues) | - | 4.17.0 |
|
||||
| maxTagTextLength | 最大显示的 tag 文本长度 | number | - | 4.17.0 |
|
||||
| notFoundContent | 当下拉列表为空时显示的内容 | string | `Not Found` | |
|
||||
| notFoundContent | 当下拉列表为空时显示的内容 | ReactNode | `Not Found` | |
|
||||
| open | 控制浮层显隐 | boolean | - | 4.17.0 |
|
||||
| options | 可选项数据源 | [Option](#option)\[] | - | |
|
||||
| placeholder | 输入框占位文本 | string | - | |
|
||||
|
@ -208,7 +208,7 @@ const OTP = React.forwardRef<OTPRef, OTPProps>((props, ref) => {
|
||||
const nextCells = patchValue(index, txt);
|
||||
|
||||
const nextIndex = Math.min(index + txt.length, length - 1);
|
||||
if (nextIndex !== index) {
|
||||
if (nextIndex !== index && nextCells[index] !== undefined) {
|
||||
refs.current[nextIndex]?.focus();
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import type { TextAreaRef as RcTextAreaRef } from 'rc-textarea';
|
||||
import type { TextAreaRef as RcTextAreaRef, TextAreaProps as RcTextAreaProps } from 'rc-textarea';
|
||||
import RcTextArea from 'rc-textarea';
|
||||
import type { TextAreaProps as RcTextAreaProps } from 'rc-textarea/lib/interface';
|
||||
|
||||
import getAllowClear from '../_util/getAllowClear';
|
||||
import type { InputStatus } from '../_util/statusUtils';
|
||||
import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils';
|
||||
|
@ -421,6 +421,7 @@ const genAllowClearStyle = (token: InputToken): CSSObject => {
|
||||
// ========================= Input =========================
|
||||
[`${componentCls}-clear-icon`]: {
|
||||
margin: 0,
|
||||
lineHeight: 0,
|
||||
color: token.colorTextQuaternary,
|
||||
fontSize: token.fontSizeIcon,
|
||||
verticalAlign: -1,
|
||||
|
@ -25,17 +25,17 @@ const ContainerHeight = 400;
|
||||
const App: React.FC = () => {
|
||||
const [data, setData] = useState<UserItem[]>([]);
|
||||
|
||||
const appendData = () => {
|
||||
const appendData = (showMessage = true) => {
|
||||
fetch(fakeDataUrl)
|
||||
.then((res) => res.json())
|
||||
.then((body) => {
|
||||
setData(data.concat(body.results));
|
||||
message.success(`${body.results.length} more items loaded!`);
|
||||
showMessage && message.success(`${body.results.length} more items loaded!`);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
appendData();
|
||||
appendData(false);
|
||||
}, []);
|
||||
|
||||
const onScroll = (e: React.UIEvent<HTMLElement, UIEvent>) => {
|
||||
|
@ -34,7 +34,7 @@ export const sortGradient = (gradients: StringGradients) => {
|
||||
let tempArr: { key: number; value?: string }[] = [];
|
||||
Object.keys(gradients).forEach((key) => {
|
||||
const formattedKey = parseFloat(key.replace(/%/g, ''));
|
||||
if (!isNaN(formattedKey)) {
|
||||
if (!Number.isNaN(formattedKey)) {
|
||||
tempArr.push({ key: formattedKey, value: gradients[key] });
|
||||
}
|
||||
});
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,15 @@
|
||||
import React from 'react';
|
||||
import { Cascader, Select, Space, TreeSelect, Typography } from 'antd';
|
||||
import {
|
||||
AutoComplete,
|
||||
Cascader,
|
||||
Flex,
|
||||
Form,
|
||||
Input,
|
||||
Select,
|
||||
Space,
|
||||
TreeSelect,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
|
||||
const options = [
|
||||
{ value: 'long', label: <Typography>long, long, long piece of text</Typography> },
|
||||
@ -8,69 +18,172 @@ const options = [
|
||||
];
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Space wrap>
|
||||
<Select
|
||||
defaultValue="long, long, long piece of text"
|
||||
style={{ width: 120 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
<>
|
||||
<Space wrap>
|
||||
<Select
|
||||
defaultValue="long, long, long piece of text"
|
||||
style={{ width: 120 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
|
||||
<Select
|
||||
placeholder="Select a option"
|
||||
style={{ width: 120, height: 60 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
<Select
|
||||
placeholder="Select a option"
|
||||
style={{ width: 120, height: 60 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
|
||||
<Select
|
||||
defaultValue="normal"
|
||||
placeholder="Select a option"
|
||||
style={{ width: 120 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
<Select
|
||||
defaultValue="normal"
|
||||
placeholder="Select a option"
|
||||
style={{ width: 120 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
|
||||
<Select
|
||||
defaultValue={['normal']}
|
||||
mode="multiple"
|
||||
placeholder="Select a option"
|
||||
style={{ width: 120 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
<Select
|
||||
defaultValue={['normal']}
|
||||
mode="multiple"
|
||||
placeholder="Select a option"
|
||||
style={{ width: 120 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
|
||||
<Select
|
||||
mode="multiple"
|
||||
placeholder="Select a option"
|
||||
style={{ width: 120, height: 60 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
<Select
|
||||
mode="multiple"
|
||||
placeholder="Select a option"
|
||||
style={{ width: 120, height: 60 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
|
||||
<Cascader
|
||||
placeholder="Select a option"
|
||||
style={{ width: 120, height: 60 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
<Cascader
|
||||
placeholder="Select a option"
|
||||
style={{ width: 120, height: 60 }}
|
||||
allowClear
|
||||
options={options}
|
||||
/>
|
||||
|
||||
<TreeSelect
|
||||
showSearch
|
||||
style={{ width: 120, height: 60 }}
|
||||
placeholder="Please select"
|
||||
allowClear
|
||||
popupMatchSelectWidth={false}
|
||||
treeDefaultExpandAll
|
||||
treeData={[
|
||||
{
|
||||
value: 'parent 1',
|
||||
title: 'parent 1',
|
||||
children: options,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Space>
|
||||
<TreeSelect
|
||||
showSearch
|
||||
style={{ width: 120, height: 60 }}
|
||||
placeholder="Please select"
|
||||
allowClear
|
||||
popupMatchSelectWidth={false}
|
||||
treeDefaultExpandAll
|
||||
treeData={[
|
||||
{
|
||||
value: 'parent 1',
|
||||
title: 'parent 1',
|
||||
children: options,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Select
|
||||
prefix="Hello World"
|
||||
mode="multiple"
|
||||
allowClear
|
||||
placeholder="Select"
|
||||
style={{ minWidth: 200, height: 200 }}
|
||||
defaultValue={['long']}
|
||||
options={options}
|
||||
/>
|
||||
<Select
|
||||
mode="multiple"
|
||||
style={{ width: 200 }}
|
||||
placeholder="请选择"
|
||||
maxTagCount="responsive"
|
||||
prefix="城市"
|
||||
options={options}
|
||||
/>
|
||||
<Select
|
||||
style={{ width: 200 }}
|
||||
placeholder="请选择"
|
||||
prefix="城市"
|
||||
options={options}
|
||||
showSearch
|
||||
allowClear
|
||||
status="error"
|
||||
/>
|
||||
<Select
|
||||
style={{ width: 100 }}
|
||||
prefix="Hi"
|
||||
options={options}
|
||||
showSearch
|
||||
allowClear
|
||||
status="warning"
|
||||
variant="filled"
|
||||
defaultValue="Bamboo"
|
||||
/>
|
||||
<Select
|
||||
style={{ width: 100 }}
|
||||
prefix="Hi"
|
||||
options={options}
|
||||
showSearch
|
||||
allowClear
|
||||
status="error"
|
||||
variant="borderless"
|
||||
defaultValue="Bamboo"
|
||||
/>
|
||||
<Form style={{ width: 200 }} layout="vertical">
|
||||
<Form.Item
|
||||
label="Label"
|
||||
name="bamboo"
|
||||
initialValue="Bamboo"
|
||||
style={{
|
||||
boxShadow: '0 0 0 1px red',
|
||||
}}
|
||||
>
|
||||
<Select options={options} allowClear placeholder="bamboo" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="Label"
|
||||
name="bamboo"
|
||||
initialValue="Bamboo"
|
||||
style={{
|
||||
boxShadow: '0 0 0 1px red',
|
||||
}}
|
||||
>
|
||||
<AutoComplete options={options} allowClear placeholder="bamboo" />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Space>
|
||||
|
||||
{/* Test for align */}
|
||||
<Flex vertical style={{ width: 200 }}>
|
||||
{/* Single */}
|
||||
<Input prefix="Hi" placeholder="Input" allowClear />
|
||||
<Select prefix="Hi" placeholder="Single" options={options} allowClear showSearch />
|
||||
<Select
|
||||
prefix="Hi"
|
||||
placeholder="Single"
|
||||
options={options}
|
||||
allowClear
|
||||
showSearch
|
||||
defaultValue="Bamboo"
|
||||
/>
|
||||
{/* Multiple */}
|
||||
<Select placeholder="Multiple" options={options} allowClear mode="multiple" />
|
||||
<Select prefix="Hi" placeholder="Multiple" options={options} allowClear mode="multiple" />
|
||||
<Select
|
||||
prefix="Hi"
|
||||
placeholder="Multiple"
|
||||
options={options}
|
||||
allowClear
|
||||
mode="multiple"
|
||||
defaultValue={['Bamboo']}
|
||||
/>
|
||||
<Select
|
||||
placeholder="Multiple"
|
||||
options={options}
|
||||
allowClear
|
||||
mode="multiple"
|
||||
defaultValue={['Bamboo']}
|
||||
/>
|
||||
</Flex>
|
||||
</>
|
||||
);
|
||||
|
||||
export default App;
|
||||
|
@ -52,7 +52,7 @@ return (
|
||||
<code src="./demo/label-in-value.tsx">Get value of selected item</code>
|
||||
<code src="./demo/automatic-tokenization.tsx">Automatic tokenization</code>
|
||||
<code src="./demo/select-users.tsx">Search and Select Users</code>
|
||||
<code src="./demo/suffix.tsx" debug>Prefix and Suffix</code>
|
||||
<code src="./demo/suffix.tsx" version="5.22.0">Prefix and Suffix</code>
|
||||
<code src="./demo/custom-dropdown-menu.tsx">Custom dropdown</code>
|
||||
<code src="./demo/hide-selected.tsx">Hide Already Selected</code>
|
||||
<code src="./demo/variant.tsx" version="5.13.0">Variants</code>
|
||||
|
@ -53,7 +53,7 @@ return (
|
||||
<code src="./demo/label-in-value.tsx">获得选项的文本</code>
|
||||
<code src="./demo/automatic-tokenization.tsx">自动分词</code>
|
||||
<code src="./demo/select-users.tsx">搜索用户</code>
|
||||
<code src="./demo/suffix.tsx" debug>前后缀</code>
|
||||
<code src="./demo/suffix.tsx" version="5.22.0">前后缀</code>
|
||||
<code src="./demo/custom-dropdown-menu.tsx">扩展菜单</code>
|
||||
<code src="./demo/hide-selected.tsx">隐藏已选择选项</code>
|
||||
<code src="./demo/variant.tsx" version="5.13.0">多种形态</code>
|
||||
|
@ -146,6 +146,26 @@ const genBaseStyle: GenerateStyle<SelectToken> = (token) => {
|
||||
},
|
||||
},
|
||||
|
||||
// ========================== Wrap ===========================
|
||||
[`${componentCls}-selection-wrap`]: {
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
position: 'relative',
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/51669
|
||||
'&:after': {
|
||||
content: '"\\a0"',
|
||||
width: 0,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
},
|
||||
|
||||
// ========================= Prefix ==========================
|
||||
[`${componentCls}-prefix`]: {
|
||||
flex: 'none',
|
||||
marginInlineEnd: token.selectAffixPadding,
|
||||
},
|
||||
|
||||
// ========================== Clear ==========================
|
||||
[`${componentCls}-clear`]: {
|
||||
position: 'absolute',
|
||||
|
@ -232,27 +232,46 @@ const genSelectionStyle = (
|
||||
},
|
||||
},
|
||||
|
||||
[`${componentCls}-selection-wrap`]: {
|
||||
width: '100%',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
|
||||
// ======================== Selections ========================
|
||||
[`${componentCls}-selection-item`]: {
|
||||
height: multipleSelectorUnit.itemHeight,
|
||||
lineHeight: unit(multipleSelectorUnit.itemLineHeight),
|
||||
},
|
||||
|
||||
// ========================== Wrap ===========================
|
||||
[`${componentCls}-selection-wrap`]: {
|
||||
alignSelf: 'flex-start',
|
||||
|
||||
'&:after': {
|
||||
lineHeight: unit(selectItemHeight),
|
||||
marginBlock: INTERNAL_FIXED_ITEM_MARGIN,
|
||||
},
|
||||
},
|
||||
|
||||
// ========================== Input ==========================
|
||||
[`${selectOverflowPrefixCls}-item + ${selectOverflowPrefixCls}-item`]: {
|
||||
[`${componentCls}-prefix`]: {
|
||||
marginInlineStart: token
|
||||
.calc(token.inputPaddingHorizontalBase)
|
||||
.sub(multipleSelectorUnit.basePadding)
|
||||
.equal(),
|
||||
},
|
||||
|
||||
[`${selectOverflowPrefixCls}-item + ${selectOverflowPrefixCls}-item,
|
||||
${componentCls}-prefix + ${componentCls}-selection-wrap
|
||||
`]: {
|
||||
[`${componentCls}-selection-search`]: {
|
||||
marginInlineStart: 0,
|
||||
},
|
||||
[`${componentCls}-selection-placeholder`]: {
|
||||
insetInlineStart: 0,
|
||||
},
|
||||
},
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/44754
|
||||
// Same as `wrap:after`
|
||||
[`${selectOverflowPrefixCls}-item-suffix`]: {
|
||||
height: '100%',
|
||||
minHeight: multipleSelectorUnit.itemHeight,
|
||||
marginBlock: INTERNAL_FIXED_ITEM_MARGIN,
|
||||
},
|
||||
|
||||
[`${componentCls}-selection-search`]: {
|
||||
@ -291,18 +310,14 @@ const genSelectionStyle = (
|
||||
[`${componentCls}-selection-placeholder`]: {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
insetInlineStart: token.inputPaddingHorizontalBase,
|
||||
insetInlineStart: token
|
||||
.calc(token.inputPaddingHorizontalBase)
|
||||
.sub(multipleSelectorUnit.basePadding)
|
||||
.equal(),
|
||||
insetInlineEnd: token.inputPaddingHorizontalBase,
|
||||
transform: 'translateY(-50%)',
|
||||
transition: `all ${token.motionDurationSlow}`,
|
||||
},
|
||||
|
||||
[`${componentCls}-prefix`]: {
|
||||
height: multipleSelectorUnit.itemHeight,
|
||||
lineHeight: unit(multipleSelectorUnit.itemLineHeight),
|
||||
marginInlineStart: `calc(${unit(token.inputPaddingHorizontalBase)} - ${unit(multipleSelectorUnit.basePadding)})`,
|
||||
marginInlineEnd: token.selectAffixPadding,
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -6,7 +6,7 @@ import { mergeToken } from '../../theme/internal';
|
||||
import type { SelectToken } from './token';
|
||||
|
||||
function genSizeStyle(token: SelectToken, suffix?: string): CSSObject {
|
||||
const { componentCls, inputPaddingHorizontalBase, borderRadius, selectAffixPadding } = token;
|
||||
const { componentCls, inputPaddingHorizontalBase, borderRadius } = token;
|
||||
|
||||
const selectHeightWithoutBorder = token
|
||||
.calc(token.controlHeight)
|
||||
@ -28,12 +28,6 @@ function genSizeStyle(token: SelectToken, suffix?: string): CSSObject {
|
||||
borderRadius,
|
||||
flex: '1 1 auto',
|
||||
|
||||
[`${componentCls}-selection-wrap`]: {
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
position: 'relative',
|
||||
},
|
||||
|
||||
[`${componentCls}-selection-search`]: {
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
@ -47,8 +41,7 @@ function genSizeStyle(token: SelectToken, suffix?: string): CSSObject {
|
||||
|
||||
[`
|
||||
${componentCls}-selection-item,
|
||||
${componentCls}-selection-placeholder,
|
||||
${componentCls}-prefix
|
||||
${componentCls}-selection-placeholder
|
||||
`]: {
|
||||
display: 'block',
|
||||
padding: 0,
|
||||
@ -62,10 +55,6 @@ function genSizeStyle(token: SelectToken, suffix?: string): CSSObject {
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
|
||||
[`${componentCls}-prefix`]: {
|
||||
marginInlineEnd: selectAffixPadding,
|
||||
},
|
||||
|
||||
// For common baseline align
|
||||
[[
|
||||
'&:after',
|
||||
@ -101,6 +90,7 @@ function genSizeStyle(token: SelectToken, suffix?: string): CSSObject {
|
||||
[`${componentCls}-selector`]: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
padding: `0 ${unit(inputPaddingHorizontalBase)}`,
|
||||
|
||||
[`${componentCls}-selection-search-input`]: {
|
||||
|
@ -13,6 +13,7 @@ const genBaseOutlinedStyle = (
|
||||
hoverBorderHover: string;
|
||||
activeBorderColor: string;
|
||||
activeOutlineColor: string;
|
||||
color: string;
|
||||
},
|
||||
): CSSObject => {
|
||||
const { componentCls, antCls, controlOutlineWidth } = token;
|
||||
@ -33,6 +34,9 @@ const genBaseOutlinedStyle = (
|
||||
boxShadow: `0 0 0 ${unit(controlOutlineWidth)} ${options.activeOutlineColor}`,
|
||||
outline: 0,
|
||||
},
|
||||
[`${componentCls}-prefix`]: {
|
||||
color: options.color,
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
@ -45,6 +49,7 @@ const genOutlinedStatusStyle = (
|
||||
hoverBorderHover: string;
|
||||
activeBorderColor: string;
|
||||
activeOutlineColor: string;
|
||||
color: string;
|
||||
},
|
||||
): CSSObject => ({
|
||||
[`&${token.componentCls}-status-${options.status}`]: {
|
||||
@ -59,6 +64,7 @@ const genOutlinedStyle = (token: SelectToken): CSSObject => ({
|
||||
hoverBorderHover: token.hoverBorderColor,
|
||||
activeBorderColor: token.activeBorderColor,
|
||||
activeOutlineColor: token.activeOutlineColor,
|
||||
color: token.colorText,
|
||||
}),
|
||||
|
||||
...genOutlinedStatusStyle(token, {
|
||||
@ -67,6 +73,7 @@ const genOutlinedStyle = (token: SelectToken): CSSObject => ({
|
||||
hoverBorderHover: token.colorErrorHover,
|
||||
activeBorderColor: token.colorError,
|
||||
activeOutlineColor: token.colorErrorOutline,
|
||||
color: token.colorError,
|
||||
}),
|
||||
|
||||
...genOutlinedStatusStyle(token, {
|
||||
@ -75,6 +82,7 @@ const genOutlinedStyle = (token: SelectToken): CSSObject => ({
|
||||
hoverBorderHover: token.colorWarningHover,
|
||||
activeBorderColor: token.colorWarning,
|
||||
activeOutlineColor: token.colorWarningOutline,
|
||||
color: token.colorWarning,
|
||||
}),
|
||||
|
||||
[`&${token.componentCls}-disabled`]: {
|
||||
@ -188,7 +196,7 @@ const genBorderlessStyle = (token: SelectToken): CSSObject => ({
|
||||
'&-borderless': {
|
||||
[`${token.componentCls}-selector`]: {
|
||||
background: 'transparent',
|
||||
borderColor: 'transparent',
|
||||
border: `${unit(token.lineWidth)} ${token.lineType} transparent`,
|
||||
},
|
||||
|
||||
[`&${token.componentCls}-disabled`]: {
|
||||
@ -204,13 +212,13 @@ const genBorderlessStyle = (token: SelectToken): CSSObject => ({
|
||||
|
||||
// Status
|
||||
[`&${token.componentCls}-status-error`]: {
|
||||
[`${token.componentCls}-selection-item`]: {
|
||||
[`${token.componentCls}-prefix, ${token.componentCls}-selection-item`]: {
|
||||
color: token.colorError,
|
||||
},
|
||||
},
|
||||
|
||||
[`&${token.componentCls}-status-warning`]: {
|
||||
[`${token.componentCls}-selection-item`]: {
|
||||
[`${token.componentCls}-prefix, ${token.componentCls}-selection-item`]: {
|
||||
color: token.colorWarning,
|
||||
},
|
||||
},
|
||||
|
@ -1905,4 +1905,76 @@ describe('Table.rowSelection', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should trigger both custom and internal checkbox events', () => {
|
||||
const onClickMock = jest.fn();
|
||||
const onChangeMock = jest.fn();
|
||||
|
||||
const getCheckboxProps = () => ({
|
||||
onClick: onClickMock,
|
||||
onChange: onChangeMock,
|
||||
});
|
||||
|
||||
const { container } = render(
|
||||
<Table
|
||||
rowSelection={{
|
||||
type: 'checkbox',
|
||||
getCheckboxProps,
|
||||
}}
|
||||
columns={columns}
|
||||
dataSource={data}
|
||||
/>,
|
||||
);
|
||||
|
||||
const firstRowCheckbox = container.querySelector('tbody tr:first-child input[type="checkbox"]');
|
||||
expect(firstRowCheckbox).toBeTruthy();
|
||||
|
||||
fireEvent.click(firstRowCheckbox!);
|
||||
|
||||
expect(onClickMock).toHaveBeenCalled();
|
||||
expect(onClickMock.mock.calls.length).toBe(1);
|
||||
|
||||
expect(onChangeMock).toHaveBeenCalled();
|
||||
expect(onChangeMock.mock.calls.length).toBe(1);
|
||||
|
||||
const changeEvent = onChangeMock.mock.calls[0][0];
|
||||
expect(changeEvent).toHaveProperty('target');
|
||||
expect(changeEvent.target).toHaveProperty('checked');
|
||||
});
|
||||
|
||||
it('should trigger both custom and internal radio events', () => {
|
||||
const onClickMock = jest.fn();
|
||||
const onChangeMock = jest.fn();
|
||||
|
||||
const getCheckboxProps = () => ({
|
||||
onClick: onClickMock,
|
||||
onChange: onChangeMock,
|
||||
});
|
||||
|
||||
const { container } = render(
|
||||
<Table
|
||||
rowSelection={{
|
||||
type: 'radio',
|
||||
getCheckboxProps,
|
||||
}}
|
||||
columns={columns}
|
||||
dataSource={data}
|
||||
/>,
|
||||
);
|
||||
|
||||
const firstRowRadio = container.querySelector('tbody tr:first-child input[type="radio"]');
|
||||
expect(firstRowRadio).toBeTruthy();
|
||||
|
||||
fireEvent.click(firstRowRadio!);
|
||||
|
||||
expect(onClickMock).toHaveBeenCalled();
|
||||
expect(onClickMock.mock.calls.length).toBe(1);
|
||||
|
||||
expect(onChangeMock).toHaveBeenCalled();
|
||||
expect(onChangeMock.mock.calls.length).toBe(1);
|
||||
|
||||
const changeEvent = onChangeMock.mock.calls[0][0];
|
||||
expect(changeEvent).toHaveProperty('target');
|
||||
expect(changeEvent.target).toHaveProperty('checked');
|
||||
});
|
||||
});
|
||||
|
@ -496,17 +496,21 @@ const useSelection = <RecordType extends AnyObject = AnyObject>(
|
||||
renderCell = (_, record, index) => {
|
||||
const key = getRowKey(record, index);
|
||||
const checked = keySet.has(key);
|
||||
|
||||
const checkboxProps = checkboxPropsMap.get(key);
|
||||
return {
|
||||
node: (
|
||||
<Radio
|
||||
{...checkboxPropsMap.get(key)}
|
||||
{...checkboxProps}
|
||||
checked={checked}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
checkboxProps?.onClick?.(e);
|
||||
}}
|
||||
onChange={(event) => {
|
||||
if (!keySet.has(key)) {
|
||||
triggerSingleSelection(key, true, [key], event.nativeEvent);
|
||||
}
|
||||
checkboxProps?.onChange?.(event);
|
||||
}}
|
||||
/>
|
||||
),
|
||||
@ -538,8 +542,12 @@ const useSelection = <RecordType extends AnyObject = AnyObject>(
|
||||
indeterminate={mergedIndeterminate}
|
||||
checked={checked}
|
||||
skipGroup
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onChange={({ nativeEvent }) => {
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
checkboxProps?.onClick?.(e);
|
||||
}}
|
||||
onChange={(event) => {
|
||||
const { nativeEvent } = event;
|
||||
const { shiftKey } = nativeEvent;
|
||||
const currentSelectedIndex = recordKeys.findIndex((item) => item === key);
|
||||
const isMultiple = derivedSelectedKeys.some((item) => recordKeys.includes(item));
|
||||
@ -595,6 +603,7 @@ const useSelection = <RecordType extends AnyObject = AnyObject>(
|
||||
} else {
|
||||
updatePrevSelectedIndex(currentSelectedIndex);
|
||||
}
|
||||
checkboxProps?.onChange?.(event);
|
||||
}}
|
||||
/>
|
||||
),
|
||||
|
@ -2,6 +2,7 @@ import type { TimePickerLocale } from '../index';
|
||||
|
||||
const locale: TimePickerLocale = {
|
||||
placeholder: "Selezionare l'orario",
|
||||
rangePlaceholder: ['Inizio orario', 'Fine orario'],
|
||||
};
|
||||
|
||||
export default locale;
|
||||
|
@ -24,7 +24,7 @@ demo:
|
||||
<code src="./demo/treeLine.tsx">Show Tree Line</code>
|
||||
<code src="./demo/placement.tsx">Placement</code>
|
||||
<code src="./demo/status.tsx">Status</code>
|
||||
<code src="./demo/suffix.tsx" debug>Prefix and Suffix</code>
|
||||
<code src="./demo/suffix.tsx" version="5.22.0">Prefix and Suffix</code>
|
||||
<code src="./demo/render-panel.tsx" debug>_InternalPanelDoNotUseOrYouWillBeFired</code>
|
||||
<code src="./demo/component-token.tsx" debug>Component Token</code>
|
||||
|
||||
|
@ -25,7 +25,7 @@ demo:
|
||||
<code src="./demo/treeLine.tsx">线性样式</code>
|
||||
<code src="./demo/placement.tsx">弹出位置</code>
|
||||
<code src="./demo/status.tsx">自定义状态</code>
|
||||
<code src="./demo/suffix.tsx" debug>前后缀</code>
|
||||
<code src="./demo/suffix.tsx" version="5.22.0">前后缀</code>
|
||||
<code src="./demo/render-panel.tsx" debug>\_InternalPanelDoNotUseOrYouWillBeFired</code>
|
||||
<code src="./demo/component-token.tsx" debug>组件 Token</code>
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { extendTest } from '../../../tests/shared/demoTest';
|
||||
|
||||
extendTest('tree', { skip: ['big-data.tsx', 'virtual-scroll.tsx', 'component-token.tsx'] });
|
||||
extendTest('tree', {
|
||||
skip: ['big-data.tsx', 'virtual-scroll.tsx', 'component-token.tsx', 'directory-debug.tsx'],
|
||||
});
|
||||
|
@ -1,3 +1,5 @@
|
||||
import demoTest from '../../../tests/shared/demoTest';
|
||||
|
||||
demoTest('tree', { skip: ['big-data.tsx', 'virtual-scroll.tsx', 'component-token.tsx'] });
|
||||
demoTest('tree', {
|
||||
skip: ['big-data.tsx', 'virtual-scroll.tsx', 'component-token.tsx', 'directory-debug.tsx'],
|
||||
});
|
||||
|
7
components/tree/demo/directory-debug.md
Normal file
7
components/tree/demo/directory-debug.md
Normal file
@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
调试 [#51210](https://github.com/ant-design/ant-design/pull/51210), [#51448](https://github.com/ant-design/ant-design/pull/51448#issuecomment-2449144872)
|
||||
|
||||
## en-US
|
||||
|
||||
Debugging [#51210](https://github.com/ant-design/ant-design/pull/51210), [#51448](https://github.com/ant-design/ant-design/pull/51448#issuecomment-2449144872)
|
65
components/tree/demo/directory-debug.tsx
Normal file
65
components/tree/demo/directory-debug.tsx
Normal file
@ -0,0 +1,65 @@
|
||||
import React from 'react';
|
||||
import { Flex, Tree } from 'antd';
|
||||
import type { GetProps, TreeDataNode } from 'antd';
|
||||
|
||||
const { DirectoryTree } = Tree;
|
||||
|
||||
const treeData: TreeDataNode[] = [
|
||||
{
|
||||
title: 'parent 0',
|
||||
key: '0-0',
|
||||
children: [
|
||||
{ title: 'leaf 0-0', key: '0-0-0', isLeaf: true },
|
||||
{ title: 'leaf 0-1', key: '0-0-1', isLeaf: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'parent 1',
|
||||
key: '0-1',
|
||||
children: [
|
||||
{ title: 'leaf 1-0', key: '0-1-0', isLeaf: true },
|
||||
{ title: 'leaf 1-1', key: '0-1-1', isLeaf: true },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const sharedProps: GetProps<typeof DirectoryTree> = {
|
||||
treeData,
|
||||
defaultExpandAll: true,
|
||||
onSelect: (keys, info) => {
|
||||
console.log('Trigger Select', keys, info);
|
||||
},
|
||||
onExpand: (keys, info) => {
|
||||
console.log('Trigger Expand', keys, info);
|
||||
},
|
||||
};
|
||||
|
||||
const DemoOne = () => <DirectoryTree draggable defaultSelectedKeys={['0-0-0']} />;
|
||||
|
||||
const DemoTwo = () => <DirectoryTree {...sharedProps} checkable defaultSelectedKeys={['0-1-0']} />;
|
||||
|
||||
const DemoThree = () => (
|
||||
<DirectoryTree {...sharedProps} draggable checkable defaultSelectedKeys={['0-1']} />
|
||||
);
|
||||
|
||||
const BasicDemo = () => <DirectoryTree {...sharedProps} multiple treeData={treeData} />;
|
||||
|
||||
const NormalDemo = () => <Tree {...sharedProps} defaultSelectedKeys={['0-1']} />;
|
||||
|
||||
const NormalCheckDemo = () => <Tree {...sharedProps} checkable defaultSelectedKeys={['0-1']} />;
|
||||
|
||||
const NormalDragDemo = () => <Tree {...sharedProps} draggable defaultSelectedKeys={['0-1-0']} />;
|
||||
|
||||
const App = () => (
|
||||
<Flex wrap gap="large">
|
||||
<DemoOne />
|
||||
<DemoTwo />
|
||||
<DemoThree />
|
||||
<BasicDemo />
|
||||
<NormalDemo />
|
||||
<NormalCheckDemo />
|
||||
<NormalDragDemo />
|
||||
</Flex>
|
||||
);
|
||||
|
||||
export default App;
|
@ -24,6 +24,7 @@ Almost anything can be represented in a tree structure. Examples include directo
|
||||
<code src="./demo/line.tsx">Tree with line</code>
|
||||
<code src="./demo/customized-icon.tsx">Customize Icon</code>
|
||||
<code src="./demo/directory.tsx">directory</code>
|
||||
<code src="./demo/directory-debug.tsx" debug>Directory Debug</code>
|
||||
<code src="./demo/switcher-icon.tsx">Customize collapse/expand icon</code>
|
||||
<code src="./demo/virtual-scroll.tsx">Virtual scroll</code>
|
||||
<code src="./demo/drag-debug.tsx" debug>Drag Debug</code>
|
||||
|
@ -25,6 +25,7 @@ demo:
|
||||
<code src="./demo/line.tsx">连接线</code>
|
||||
<code src="./demo/customized-icon.tsx">自定义图标</code>
|
||||
<code src="./demo/directory.tsx">目录</code>
|
||||
<code src="./demo/directory-debug.tsx" debug>目录 Debug</code>
|
||||
<code src="./demo/switcher-icon.tsx">自定义展开/折叠图标</code>
|
||||
<code src="./demo/virtual-scroll.tsx">虚拟滚动</code>
|
||||
<code src="./demo/drag-debug.tsx" debug>Drag Debug</code>
|
||||
|
@ -38,15 +38,14 @@ export const genDirectoryStyle = ({
|
||||
},
|
||||
},
|
||||
|
||||
[`${treeCls}-switcher`]: {
|
||||
marginInlineEnd: 0,
|
||||
[`${treeCls}-switcher, ${treeCls}-checkbox, ${treeCls}-draggable-icon`]: {
|
||||
zIndex: 1,
|
||||
},
|
||||
|
||||
// ============= Selected =============
|
||||
'&-selected': {
|
||||
[`${treeCls}-switcher, ${treeCls}-draggable-icon`]: {
|
||||
color: directoryNodeSelectedColor,
|
||||
zIndex: 1,
|
||||
},
|
||||
|
||||
// >>> Title
|
||||
|
@ -120,7 +120,6 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken): CSSObject =>
|
||||
nodeHoverBg,
|
||||
colorTextQuaternary,
|
||||
} = token;
|
||||
const treeCheckBoxMarginHorizontal = token.marginXXS;
|
||||
|
||||
return {
|
||||
[treeCls]: {
|
||||
@ -253,6 +252,14 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken): CSSObject =>
|
||||
visibility: 'hidden',
|
||||
},
|
||||
|
||||
// Switcher / Checkbox
|
||||
[`${treeCls}-switcher, ${treeCls}-checkbox`]: {
|
||||
marginInlineEnd: token
|
||||
.calc(token.calc(titleHeight).sub(token.controlInteractiveSize))
|
||||
.div(2)
|
||||
.equal(),
|
||||
},
|
||||
|
||||
// >>> Switcher
|
||||
[`${treeCls}-switcher`]: {
|
||||
...getSwitchStyle(prefixCls, token),
|
||||
@ -260,15 +267,10 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken): CSSObject =>
|
||||
flex: 'none',
|
||||
alignSelf: 'stretch',
|
||||
width: titleHeight,
|
||||
margin: 0,
|
||||
textAlign: 'center',
|
||||
cursor: 'pointer',
|
||||
userSelect: 'none',
|
||||
transition: `all ${token.motionDurationSlow}`,
|
||||
marginInlineEnd: token
|
||||
.calc(token.calc(titleHeight).sub(token.controlInteractiveSize))
|
||||
.div(2)
|
||||
.equal(),
|
||||
|
||||
'&-noop': {
|
||||
cursor: 'unset',
|
||||
@ -329,14 +331,6 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken): CSSObject =>
|
||||
},
|
||||
},
|
||||
|
||||
// >>> Checkbox
|
||||
[`${treeCls}-checkbox`]: {
|
||||
top: 'initial',
|
||||
marginInlineEnd: treeCheckBoxMarginHorizontal,
|
||||
alignSelf: 'flex-start',
|
||||
marginTop: token.marginXXS,
|
||||
},
|
||||
|
||||
// >>> Title
|
||||
// add `${treeCls}-checkbox + span` to cover checkbox `${checkboxCls} + span`
|
||||
[`${treeCls}-node-content-wrapper`]: {
|
||||
|
@ -5,11 +5,10 @@ import { clearFix, textEllipsis } from '../../style';
|
||||
import type { GenerateStyle } from '../../theme/internal';
|
||||
|
||||
const genListStyle: GenerateStyle<UploadToken> = (token) => {
|
||||
const { componentCls, antCls, iconCls, fontSize, lineHeight, calc } = token;
|
||||
const { componentCls, iconCls, fontSize, lineHeight, calc } = token;
|
||||
const itemCls = `${componentCls}-list-item`;
|
||||
const actionsCls = `${itemCls}-actions`;
|
||||
const actionCls = `${itemCls}-action`;
|
||||
const listItemHeightSM = token.fontHeightSM;
|
||||
|
||||
return {
|
||||
[`${componentCls}-wrapper`]: {
|
||||
@ -25,6 +24,7 @@ const genListStyle: GenerateStyle<UploadToken> = (token) => {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
transition: `background-color ${token.motionDurationSlow}`,
|
||||
borderRadius: token.borderRadiusSM,
|
||||
|
||||
'&:hover': {
|
||||
backgroundColor: token.controlItemBgHover,
|
||||
@ -56,12 +56,6 @@ const genListStyle: GenerateStyle<UploadToken> = (token) => {
|
||||
`]: {
|
||||
opacity: 1,
|
||||
},
|
||||
|
||||
[`${actionCls}${antCls}-btn`]: {
|
||||
height: listItemHeightSM,
|
||||
border: 0,
|
||||
lineHeight: 1,
|
||||
},
|
||||
},
|
||||
|
||||
[`${componentCls}-icon ${iconCls}`]: {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "5.22.1",
|
||||
"version": "5.22.2",
|
||||
"description": "An enterprise-class UI design language and React components implementation",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
@ -149,7 +149,7 @@
|
||||
"rc-textarea": "~1.8.2",
|
||||
"rc-tooltip": "~6.2.1",
|
||||
"rc-tree": "~5.10.1",
|
||||
"rc-tree-select": "~5.24.4",
|
||||
"rc-tree-select": "~5.24.5",
|
||||
"rc-upload": "~4.8.1",
|
||||
"rc-util": "^5.43.0",
|
||||
"scroll-into-view-if-needed": "^3.1.0",
|
||||
|
@ -18,6 +18,8 @@ const blockStatus = ['failure', 'cancelled', 'timed_out'] as const;
|
||||
const spinner = { interval: 80, frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'] };
|
||||
const spinnies = new Spinnies({ spinner });
|
||||
|
||||
const IGNORE_ACTIONS = ['Check Virtual Regression Approval', 'issue-remove-inactive'];
|
||||
|
||||
let spinniesId = 0;
|
||||
|
||||
// `spinnies` 为按条目进度,需要做简单的封装变成接近 `ora` 的形态
|
||||
@ -142,14 +144,18 @@ const runPrePublish = async () => {
|
||||
showMessage(`开始检查远程分支 ${currentBranch} 的 CI 状态`, true);
|
||||
|
||||
const failureUrlList: string[] = [];
|
||||
const {
|
||||
let {
|
||||
data: { check_runs },
|
||||
} = await octokit.checks.listForRef({
|
||||
owner,
|
||||
repo,
|
||||
ref: sha,
|
||||
filter: 'all',
|
||||
});
|
||||
showMessage(`远程分支 CI 状态(${check_runs.length}):`, 'succeed');
|
||||
check_runs = check_runs.filter((run) =>
|
||||
IGNORE_ACTIONS.every((action) => !run.name.includes(action)),
|
||||
);
|
||||
check_runs.forEach((run) => {
|
||||
showMessage(` ${run.name.padEnd(36)} ${emojify(run.status)} ${emojify(run.conclusion || '')}`);
|
||||
if (blockStatus.some((status) => run.conclusion === status)) {
|
||||
|
@ -29,6 +29,11 @@
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table > thead {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 8px;
|
||||
@ -61,13 +66,22 @@
|
||||
border: 0;
|
||||
}
|
||||
|
||||
table > thead {
|
||||
position: unset;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
width: 100%;
|
||||
display: block;
|
||||
padding: 6px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
td:last-child {
|
||||
border-bottom: 3px dashed darkgray;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
background-color: transparent;
|
||||
|
Loading…
Reference in New Issue
Block a user