mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 01:13:58 +08:00
Merge pull request #48573 from ant-design/master
chore: merge master into feature
This commit is contained in:
commit
5c2e6e3651
@ -53,5 +53,6 @@
|
||||
"5.13.0": ["https://github.com/ant-design/ant-design/pull/46962"],
|
||||
"5.14.0": ["https://github.com/ant-design/ant-design/issues/47354"],
|
||||
"5.15.0": ["https://github.com/ant-design/ant-design/pull/47504#issuecomment-1980459433"],
|
||||
">= 5.16.0 <= 5.16.1": ["https://github.com/ant-design/ant-design/issues/48200"]
|
||||
">= 5.16.0 <= 5.16.1": ["https://github.com/ant-design/ant-design/issues/48200"],
|
||||
"5.16.3": ["https://github.com/ant-design/ant-design/issues/48568"]
|
||||
}
|
||||
|
@ -16,6 +16,36 @@ tag: vVERSION
|
||||
|
||||
---
|
||||
|
||||
## 5.16.4
|
||||
|
||||
`2024-04-22`
|
||||
|
||||
- 🐞 Fix Select with `multiple` and `paddingXXS=0` will break the height align of `controlHeight` token. [#48574](https://github.com/ant-design/ant-design/pull/48574)
|
||||
- 🐞 Fix Upload miss style when enable CSS Variable. [#48569](https://github.com/ant-design/ant-design/pull/48569) [@nova1751](https://github.com/nova1751)
|
||||
- 🐞 Fix Slider in `range` tooltip blink when drag the handle over another one. [#48536](https://github.com/ant-design/ant-design/pull/48536)
|
||||
- Input
|
||||
- 🐞 Fix the text of the button is not the large size when Input.Search is set to a large size. [#48527](https://github.com/ant-design/ant-design/pull/48527)
|
||||
- 🐞 Fix abnormal text display in Input.TextArea. [#48489](https://github.com/ant-design/ant-design/pull/48489) [@korkt-kim](https://github.com/korkt-kim)
|
||||
- 🐞 Fix the stuck animation effect of the Upload component image. [#48522](https://github.com/ant-design/ant-design/pull/48522) [@nova1751](https://github.com/nova1751)
|
||||
- 🐞 Fix the issue where the Switch component using `checkedChildren` and `unCheckedChildren` did not add a default height. [#48513](https://github.com/ant-design/ant-design/pull/48513) [@wanpan11](https://github.com/wanpan11)
|
||||
- 🐞 Fix the warning reminder when Form.Item uses noStyle with no value. [#48508](https://github.com/ant-design/ant-design/pull/48508)
|
||||
- 🐞 Fix Popover `defaultOpen` setting failed. [#48481](https://github.com/ant-design/ant-design/pull/48481) [@linhf123](https://github.com/linhf123)
|
||||
- 🐞 Fix where `placeholder` is not displayed when DatePicker is configured with `multiple`. [#48387](https://github.com/ant-design/ant-design/pull/48387) [@nova1751](https://github.com/nova1751)
|
||||
- 🐞 Fix where ColorPicker clear color could not be changed when controlled in strict mode. [#48450](https://github.com/ant-design/ant-design/pull/48450)
|
||||
- 💄 Fix the arrow style issue when Collapse uses third-party icons. [#48417](https://github.com/ant-design/ant-design/pull/48417) [@guoyunhe](https://github.com/guoyunhe)
|
||||
- 💄 Optimize the animation effect of the embedded Menu Sider when it is expanded. [#48127](https://github.com/ant-design/ant-design/pull/48127) [@metouch](https://github.com/metouch)
|
||||
- 💄 Optimize Steps process style. [#48464](https://github.com/ant-design/ant-design/pull/48464)
|
||||
- Locales
|
||||
- 🇨🇳 Add zh_CN zh_HK zh_TW Table licales. [#48543](https://github.com/ant-design/ant-design/pull/48543) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🇮🇩 Add id_ID DatePicker Form Table etc. locales. [#48537](https://github.com/ant-design/ant-design/pull/48537) [#48287](https://github.com/ant-design/ant-design/pull/48287) [@edikurniawan-dev](https://github.com/edikurniawan-dev)
|
||||
- 🌐 Optimize Transfer localization to use `deselectAll` locale when need deselect all. [#48553](https://github.com/ant-design/ant-design/pull/48553) [@coderz-w](https://github.com/coderz-w)
|
||||
|
||||
## 5.16.3
|
||||
|
||||
`2024-04-21`
|
||||
|
||||
- 🛠 Script failed to publish an empty package. Do not use this version.
|
||||
|
||||
## 5.16.2
|
||||
|
||||
`2024-04-15`
|
||||
|
@ -15,6 +15,36 @@ tag: vVERSION
|
||||
|
||||
---
|
||||
|
||||
## 5.16.4
|
||||
|
||||
`2024-04-22`
|
||||
|
||||
- 🐞 修复 Select 配置 `paddingXXS=0` 时,多选下超出设定的 `controlHeight` token 的问题。[#48574](https://github.com/ant-design/ant-design/pull/48574)
|
||||
- 🐞 修复 Upload 在开启 CSS Variable 时样式丢失的问题。[#48569](https://github.com/ant-design/ant-design/pull/48569) [@nova1751](https://github.com/nova1751)
|
||||
- 🐞 修复 Slider 在范围选择下,拖动滑块越过另一个滑块时提示框闪动的问题。[#48536](https://github.com/ant-design/ant-design/pull/48536)
|
||||
- Input
|
||||
- 🐞 修复 Input.Search 设置大尺寸时,按钮的文字不是大尺寸的问题。[#48527](https://github.com/ant-design/ant-design/pull/48527)
|
||||
- 🐞 修复 Input.TextArea 的文字显示异常问题。[#48489](https://github.com/ant-design/ant-design/pull/48489) [@korkt-kim](https://github.com/korkt-kim)
|
||||
- 🐞 修复 Upload 组件图片卡顿的动画效果。[#48522](https://github.com/ant-design/ant-design/pull/48522) [@nova1751](https://github.com/nova1751)
|
||||
- 🐞 修复 Switch 组件使用 `checkedChildren` `unCheckedChildren` 未添加默认高度的问题。[#48513](https://github.com/ant-design/ant-design/pull/48513) [@wanpan11](https://github.com/wanpan11)
|
||||
- 🐞 修复 Form.Item 使用 noStyle 无值时的警告提醒。[#48508](https://github.com/ant-design/ant-design/pull/48508)
|
||||
- 🐞 修复 Popover `defaultOpen` 设置失效的问题。[#48481](https://github.com/ant-design/ant-design/pull/48481) [@linhf123](https://github.com/linhf123)
|
||||
- 🐞 修复 DatePicker 配置 `multiple` 时 `placeholder` 不展示的问题。[#48387](https://github.com/ant-design/ant-design/pull/48387) [@nova1751](https://github.com/nova1751)
|
||||
- 🐞 修复 ColorPicker 在严格模式下受控时清除颜色无法改变的问题。[#48450](https://github.com/ant-design/ant-design/pull/48450)
|
||||
- 💄 修复 Collapse 使用第三方图标时的 arrow 样式问题。[#48417](https://github.com/ant-design/ant-design/pull/48417) [@guoyunhe](https://github.com/guoyunhe)
|
||||
- 💄 优化内嵌 Menu 的 Sider 在展开时的动画效果。[#48127](https://github.com/ant-design/ant-design/pull/48127) [@metouch](https://github.com/metouch)
|
||||
- 💄 优化 Steps process 样式。[#48464](https://github.com/ant-design/ant-design/pull/48464)
|
||||
- 国际化
|
||||
- 🇨🇳 补充 zh_CN zh_HK zh_TW Table 文案。[#48543](https://github.com/ant-design/ant-design/pull/48543) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🇮🇩 补充 id_ID DatePicker Form Table 等文案。[#48537](https://github.com/ant-design/ant-design/pull/48537) [#48287](https://github.com/ant-design/ant-design/pull/48287) [@edikurniawan-dev](https://github.com/edikurniawan-dev)
|
||||
- 🌐 优化 Transfer 本地化,现在反选会使用 `deselectAll` locale 配置。[#48553](https://github.com/ant-design/ant-design/pull/48553) [@coderz-w](https://github.com/coderz-w)
|
||||
|
||||
## 5.16.3
|
||||
|
||||
`2024-04-21`
|
||||
|
||||
- 🛠 脚本错误发布空包,请勿使用。
|
||||
|
||||
## 5.16.2
|
||||
|
||||
`2024-04-15`
|
||||
|
@ -7,7 +7,15 @@ import type { PickerLocale } from '../generatePicker';
|
||||
const locale: PickerLocale = {
|
||||
lang: {
|
||||
placeholder: 'Pilih tanggal',
|
||||
rangePlaceholder: ['Mulai tanggal', 'Tanggal akhir'],
|
||||
yearPlaceholder: 'Pilih tahun',
|
||||
quarterPlaceholder: 'Pilih kuartal',
|
||||
monthPlaceholder: 'Pilih bulan',
|
||||
weekPlaceholder: 'Pilih minggu',
|
||||
rangePlaceholder: ['Tanggal awal', 'Tanggal akhir'],
|
||||
rangeYearPlaceholder: ['Tahun awal', 'Tahun akhir'],
|
||||
rangeQuarterPlaceholder: ['Kuartal awal', 'Kuartal akhir'],
|
||||
rangeMonthPlaceholder: ['Bulan awal', 'Bulan akhir'],
|
||||
rangeWeekPlaceholder: ['Minggu awal', 'Minggu akhir'],
|
||||
...CalendarLocale,
|
||||
},
|
||||
timePickerLocale: {
|
||||
|
@ -109,10 +109,14 @@ export type PickerPanelToken = {
|
||||
pickerControlIconBorderWidth: number;
|
||||
};
|
||||
|
||||
export type PickerToken = FullToken<'DatePicker'> &
|
||||
PickerPanelToken &
|
||||
SharedInputToken &
|
||||
SelectorToken;
|
||||
export interface PickerToken
|
||||
extends FullToken<'DatePicker'>,
|
||||
PickerPanelToken,
|
||||
SharedInputToken,
|
||||
SelectorToken {
|
||||
/** @private Used for internal calculation */
|
||||
INTERNAL_FIXED_ITEM_MARGIN: number;
|
||||
}
|
||||
|
||||
export type SharedPickerToken = TokenWithCommonCls<GlobalToken> &
|
||||
PickerPanelToken &
|
||||
@ -139,10 +143,36 @@ export const initPickerPanelToken = (token: TokenWithCommonCls<GlobalToken>): Pi
|
||||
};
|
||||
|
||||
export const initPanelComponentToken = (token: GlobalToken): PanelComponentToken => {
|
||||
const { colorBgContainerDisabled, controlHeight, controlHeightSM, controlHeightLG, paddingXXS } =
|
||||
token;
|
||||
const {
|
||||
colorBgContainerDisabled,
|
||||
controlHeight,
|
||||
controlHeightSM,
|
||||
controlHeightLG,
|
||||
paddingXXS,
|
||||
lineWidth,
|
||||
} = token;
|
||||
|
||||
return {
|
||||
// Item height default use `controlHeight - 2 * paddingXXS`,
|
||||
// but some case `paddingXXS=0`.
|
||||
// Let's fallback it.
|
||||
const dblPaddingXXS = paddingXXS * 2;
|
||||
const dblLineWidth = lineWidth * 2;
|
||||
|
||||
const multipleItemHeight = Math.min(controlHeight - dblPaddingXXS, controlHeight - dblLineWidth);
|
||||
const multipleItemHeightSM = Math.min(
|
||||
controlHeightSM - dblPaddingXXS,
|
||||
controlHeightSM - dblLineWidth,
|
||||
);
|
||||
const multipleItemHeightLG = Math.min(
|
||||
controlHeightLG - dblPaddingXXS,
|
||||
controlHeightLG - dblLineWidth,
|
||||
);
|
||||
|
||||
// FIXED_ITEM_MARGIN is a hardcode calculation since calc not support rounding
|
||||
const INTERNAL_FIXED_ITEM_MARGIN = Math.floor(paddingXXS / 2);
|
||||
|
||||
const filledToken = {
|
||||
INTERNAL_FIXED_ITEM_MARGIN,
|
||||
cellHoverBg: token.controlItemBgHover,
|
||||
cellActiveWithRangeBg: token.controlItemBgActive,
|
||||
cellHoverWithRangeBg: new TinyColor(token.colorPrimary).lighten(35).toHexString(),
|
||||
@ -157,13 +187,15 @@ export const initPanelComponentToken = (token: GlobalToken): PanelComponentToken
|
||||
withoutTimeCellHeight: controlHeightLG * 1.65,
|
||||
multipleItemBg: token.colorFillSecondary,
|
||||
multipleItemBorderColor: 'transparent',
|
||||
multipleItemHeight: controlHeight - paddingXXS * 2,
|
||||
multipleItemHeightSM: controlHeightSM - paddingXXS * 2,
|
||||
multipleItemHeightLG: controlHeightLG - paddingXXS * 2,
|
||||
multipleItemHeight,
|
||||
multipleItemHeightSM,
|
||||
multipleItemHeightLG,
|
||||
multipleSelectorBgDisabled: colorBgContainerDisabled,
|
||||
multipleItemColorDisabled: token.colorTextDisabled,
|
||||
multipleItemBorderColorDisabled: 'transparent',
|
||||
};
|
||||
|
||||
return filledToken;
|
||||
};
|
||||
|
||||
export const prepareComponentToken: GetDefaultToken<'DatePicker'> = (token) => ({
|
||||
|
@ -1310,7 +1310,7 @@ describe('Form', () => {
|
||||
mark: 'pro_table_render',
|
||||
render: (_: any, doms: any) => (
|
||||
<div>
|
||||
<h1>warning title</h1>
|
||||
<div className="bamboo">warning title</div>
|
||||
{doms.input}
|
||||
{doms.errorList}
|
||||
{doms.extra}
|
||||
@ -1323,7 +1323,7 @@ describe('Form', () => {
|
||||
</Form>,
|
||||
);
|
||||
|
||||
expect(container.querySelector('h1')!).toHaveTextContent(/warning title/i);
|
||||
expect(container.querySelector('.bamboo')!).toHaveTextContent(/warning title/i);
|
||||
});
|
||||
|
||||
it('Form Item element id will auto add form_item prefix if form name is empty and item name is in the black list', async () => {
|
||||
|
@ -881,4 +881,7 @@ export default genStyleHooks(
|
||||
];
|
||||
},
|
||||
initComponentToken,
|
||||
{
|
||||
resetFont: false,
|
||||
},
|
||||
);
|
||||
|
@ -146780,7 +146780,7 @@ exports[`Locale Provider should display the text as id 1`] = `
|
||||
aria-invalid="false"
|
||||
autocomplete="off"
|
||||
date-range="start"
|
||||
placeholder="Mulai tanggal"
|
||||
placeholder="Tanggal awal"
|
||||
size="12"
|
||||
value=""
|
||||
/>
|
||||
|
@ -59,6 +59,7 @@ const localeValues: Locale = {
|
||||
selectCurrent: 'Select current page',
|
||||
removeCurrent: 'Remove current page',
|
||||
selectAll: 'Select all data',
|
||||
deselectAll: 'Deselect all data',
|
||||
removeAll: 'Remove all data',
|
||||
selectInvert: 'Invert current page',
|
||||
},
|
||||
|
@ -25,6 +25,7 @@ const localeValues: Locale = {
|
||||
filterEmptyText: '无筛选项',
|
||||
filterCheckall: '全选',
|
||||
filterSearchPlaceholder: '在筛选项中搜索',
|
||||
emptyText: '暂无数据',
|
||||
selectAll: '全选当页',
|
||||
selectInvert: '反选当页',
|
||||
selectNone: '清空所有',
|
||||
@ -59,6 +60,7 @@ const localeValues: Locale = {
|
||||
selectCurrent: '全选当页',
|
||||
removeCurrent: '删除当页',
|
||||
selectAll: '全选所有',
|
||||
deselectAll: '取消全选',
|
||||
removeAll: '删除全部',
|
||||
selectInvert: '反选当页',
|
||||
},
|
||||
|
@ -22,6 +22,9 @@ const localeValues: Locale = {
|
||||
filterConfirm: '確定',
|
||||
filterReset: '重置',
|
||||
filterEmptyText: '無篩選項',
|
||||
filterCheckall: '全選',
|
||||
filterSearchPlaceholder: '在篩選項中搜尋',
|
||||
emptyText: '暫無數據',
|
||||
selectAll: '全部選取',
|
||||
selectInvert: '反向選取',
|
||||
selectNone: '清空所有',
|
||||
|
@ -22,6 +22,9 @@ const localeValues: Locale = {
|
||||
filterConfirm: '確定',
|
||||
filterReset: '重置',
|
||||
filterEmptyText: '無篩選項',
|
||||
filterCheckall: '全選',
|
||||
filterSearchPlaceholder: '在篩選項中搜尋',
|
||||
emptyText: '暫無數據',
|
||||
selectAll: '全部選取',
|
||||
selectInvert: '反向選取',
|
||||
selectNone: '清空所有',
|
||||
|
@ -387,7 +387,7 @@ describe('notification', () => {
|
||||
expect(document.querySelectorAll('.with-false .ant-notification-notice-close').length).toBe(0);
|
||||
});
|
||||
|
||||
it('style.width could be overrided', async () => {
|
||||
it('style.width could be override', async () => {
|
||||
act(() => {
|
||||
notification.open({
|
||||
message: 'Notification Title',
|
||||
@ -400,8 +400,5 @@ describe('notification', () => {
|
||||
});
|
||||
await awaitPromise();
|
||||
expect(document.querySelector('.with-style')).toHaveStyle({ width: '600px' });
|
||||
expect(
|
||||
document.querySelector('.ant-notification-notice-wrapper:has(.width-style)'),
|
||||
).toHaveStyle({ width: '' });
|
||||
});
|
||||
});
|
||||
|
@ -59,9 +59,11 @@ exports[`Segmented render label with ReactNode 1`] = `
|
||||
<div
|
||||
class="ant-segmented-item-label"
|
||||
>
|
||||
<h2>
|
||||
<div
|
||||
class="little"
|
||||
>
|
||||
Monthly
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -61,7 +61,7 @@ describe('Segmented', () => {
|
||||
options={[
|
||||
{ label: 'Daily', value: 'Daily' },
|
||||
{ label: <div id="weekly">Weekly</div>, value: 'Weekly' },
|
||||
{ label: <h2>Monthly</h2>, value: 'Monthly' },
|
||||
{ label: <div className="little">Monthly</div>, value: 'Monthly' },
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
@ -71,7 +71,7 @@ describe('Segmented', () => {
|
||||
expectMatchChecked(container, [true, false, false]);
|
||||
|
||||
expect(container.querySelector('#weekly')?.textContent).toContain('Weekly');
|
||||
expect(container.querySelectorAll('h2')[0].textContent).toContain('Monthly');
|
||||
expect(container.querySelector('.little')?.textContent).toContain('Monthly');
|
||||
});
|
||||
|
||||
it('render segmented with defaultValue', () => {
|
||||
|
@ -11,10 +11,6 @@ for (let i = 10; i < 36; i++) {
|
||||
});
|
||||
}
|
||||
|
||||
const handleChange = (value: string[]) => {
|
||||
console.log(`selected ${value}`);
|
||||
};
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Space direction="vertical">
|
||||
<ConfigProvider
|
||||
@ -35,7 +31,6 @@ const App: React.FC = () => (
|
||||
style={{ width: '100%' }}
|
||||
placeholder="Please select"
|
||||
defaultValue={['a10', 'c12']}
|
||||
onChange={handleChange}
|
||||
options={options}
|
||||
/>
|
||||
<Select
|
||||
@ -44,7 +39,6 @@ const App: React.FC = () => (
|
||||
style={{ width: '100%' }}
|
||||
placeholder="Please select"
|
||||
defaultValue={['a10', 'c12']}
|
||||
onChange={handleChange}
|
||||
options={options}
|
||||
/>
|
||||
</Space>
|
||||
@ -64,7 +58,6 @@ const App: React.FC = () => (
|
||||
style={{ width: '100%' }}
|
||||
placeholder="Please select"
|
||||
defaultValue={['a10', 'c12']}
|
||||
onChange={handleChange}
|
||||
options={options}
|
||||
/>
|
||||
<Select
|
||||
@ -73,7 +66,26 @@ const App: React.FC = () => (
|
||||
style={{ width: '100%' }}
|
||||
placeholder="Please select"
|
||||
defaultValue={['a10', 'c12']}
|
||||
onChange={handleChange}
|
||||
options={options}
|
||||
/>
|
||||
</Space>
|
||||
</ConfigProvider>
|
||||
<ConfigProvider
|
||||
theme={{
|
||||
components: {
|
||||
Select: {
|
||||
paddingXXS: 0,
|
||||
controlHeight: 28,
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Space style={{ width: '100%' }} direction="vertical">
|
||||
<Select style={{ width: '100%' }} defaultValue="a10" options={options} />
|
||||
<Select
|
||||
mode="multiple"
|
||||
style={{ width: '100%' }}
|
||||
defaultValue={['a10', 'c12']}
|
||||
options={options}
|
||||
/>
|
||||
</Space>
|
||||
|
@ -7,8 +7,6 @@ import type { AliasToken } from '../../theme/internal';
|
||||
import type { TokenWithCommonCls } from '../../theme/util/genComponentStyleHook';
|
||||
import type { SelectToken } from './token';
|
||||
|
||||
export const FIXED_ITEM_MARGIN = 2;
|
||||
|
||||
type SelectItemToken = Pick<
|
||||
SelectToken,
|
||||
| 'multipleSelectItemHeight'
|
||||
@ -19,6 +17,7 @@ type SelectItemToken = Pick<
|
||||
| 'lineWidth'
|
||||
| 'calc'
|
||||
| 'inputPaddingHorizontalBase'
|
||||
| 'INTERNAL_FIXED_ITEM_MARGIN'
|
||||
>;
|
||||
|
||||
/**
|
||||
@ -41,13 +40,21 @@ type SelectItemToken = Pick<
|
||||
export const getMultipleSelectorUnit = (
|
||||
token: Pick<
|
||||
SelectToken,
|
||||
'max' | 'calc' | 'multipleSelectItemHeight' | 'paddingXXS' | 'lineWidth'
|
||||
| 'max'
|
||||
| 'calc'
|
||||
| 'multipleSelectItemHeight'
|
||||
| 'paddingXXS'
|
||||
| 'lineWidth'
|
||||
| 'INTERNAL_FIXED_ITEM_MARGIN'
|
||||
>,
|
||||
) => {
|
||||
const { multipleSelectItemHeight, paddingXXS, lineWidth } = token;
|
||||
const { multipleSelectItemHeight, paddingXXS, lineWidth, INTERNAL_FIXED_ITEM_MARGIN } = token;
|
||||
|
||||
const basePadding = token.max(token.calc(paddingXXS).sub(lineWidth).equal(), 0);
|
||||
const containerPadding = token.max(token.calc(basePadding).sub(FIXED_ITEM_MARGIN).equal(), 0);
|
||||
const containerPadding = token.max(
|
||||
token.calc(basePadding).sub(INTERNAL_FIXED_ITEM_MARGIN).equal(),
|
||||
0,
|
||||
);
|
||||
|
||||
return {
|
||||
basePadding,
|
||||
@ -87,6 +94,7 @@ export const genOverflowStyle = (
|
||||
| 'multipleItemBorderColorDisabled'
|
||||
| 'colorIcon'
|
||||
| 'colorIconHover'
|
||||
| 'INTERNAL_FIXED_ITEM_MARGIN'
|
||||
>,
|
||||
): CSSObject => {
|
||||
const {
|
||||
@ -99,6 +107,7 @@ export const genOverflowStyle = (
|
||||
multipleItemBorderColorDisabled,
|
||||
colorIcon,
|
||||
colorIconHover,
|
||||
INTERNAL_FIXED_ITEM_MARGIN,
|
||||
} = token;
|
||||
|
||||
const selectOverflowPrefixCls = `${componentCls}-selection-overflow`;
|
||||
@ -130,11 +139,11 @@ export const genOverflowStyle = (
|
||||
flex: 'none',
|
||||
boxSizing: 'border-box',
|
||||
maxWidth: '100%',
|
||||
marginBlock: FIXED_ITEM_MARGIN,
|
||||
marginBlock: INTERNAL_FIXED_ITEM_MARGIN,
|
||||
borderRadius: borderRadiusSM,
|
||||
cursor: 'default',
|
||||
transition: `font-size ${motionDurationSlow}, line-height ${motionDurationSlow}, height ${motionDurationSlow}`,
|
||||
marginInlineEnd: token.calc(FIXED_ITEM_MARGIN).mul(2).equal(),
|
||||
marginInlineEnd: token.calc(INTERNAL_FIXED_ITEM_MARGIN).mul(2).equal(),
|
||||
paddingInlineStart: paddingXS,
|
||||
paddingInlineEnd: token.calc(paddingXS).div(2).equal(),
|
||||
|
||||
@ -181,7 +190,7 @@ const genSelectionStyle = (
|
||||
token: TokenWithCommonCls<AliasToken> & SelectItemToken,
|
||||
suffix?: string,
|
||||
): CSSObject => {
|
||||
const { componentCls } = token;
|
||||
const { componentCls, INTERNAL_FIXED_ITEM_MARGIN } = token;
|
||||
|
||||
const selectOverflowPrefixCls = `${componentCls}-selection-overflow`;
|
||||
|
||||
@ -216,7 +225,7 @@ const genSelectionStyle = (
|
||||
'&:after': {
|
||||
display: 'inline-block',
|
||||
width: 0,
|
||||
margin: `${unit(FIXED_ITEM_MARGIN)} 0`,
|
||||
margin: `${unit(INTERNAL_FIXED_ITEM_MARGIN)} 0`,
|
||||
lineHeight: unit(selectItemHeight),
|
||||
visibility: 'hidden',
|
||||
content: '"\\a0"',
|
||||
|
@ -120,12 +120,16 @@ export interface SelectorToken {
|
||||
|
||||
export interface SelectToken extends FullToken<'Select'>, SelectorToken {
|
||||
rootPrefixCls: string;
|
||||
|
||||
/** @private Used for internal calculation */
|
||||
INTERNAL_FIXED_ITEM_MARGIN: number;
|
||||
}
|
||||
|
||||
export const prepareComponentToken: GetDefaultToken<'Select'> = (token) => {
|
||||
const {
|
||||
fontSize,
|
||||
lineHeight,
|
||||
lineWidth,
|
||||
|
||||
controlHeight,
|
||||
controlHeightSM,
|
||||
@ -146,11 +150,28 @@ export const prepareComponentToken: GetDefaultToken<'Select'> = (token) => {
|
||||
colorTextDisabled,
|
||||
} = token;
|
||||
|
||||
const multipleItemHeight = controlHeight - paddingXXS * 2;
|
||||
const multipleItemHeightSM = controlHeightSM - paddingXXS * 2;
|
||||
const multipleItemHeightLG = controlHeightLG - paddingXXS * 2;
|
||||
// Item height default use `controlHeight - 2 * paddingXXS`,
|
||||
// but some case `paddingXXS=0`.
|
||||
// Let's fallback it.
|
||||
const dblPaddingXXS = paddingXXS * 2;
|
||||
const dblLineWidth = lineWidth * 2;
|
||||
|
||||
const multipleItemHeight = Math.min(controlHeight - dblPaddingXXS, controlHeight - dblLineWidth);
|
||||
const multipleItemHeightSM = Math.min(
|
||||
controlHeightSM - dblPaddingXXS,
|
||||
controlHeightSM - dblLineWidth,
|
||||
);
|
||||
const multipleItemHeightLG = Math.min(
|
||||
controlHeightLG - dblPaddingXXS,
|
||||
controlHeightLG - dblLineWidth,
|
||||
);
|
||||
|
||||
// FIXED_ITEM_MARGIN is a hardcode calculation since calc not support rounding
|
||||
const INTERNAL_FIXED_ITEM_MARGIN = Math.floor(paddingXXS / 2);
|
||||
|
||||
return {
|
||||
INTERNAL_FIXED_ITEM_MARGIN,
|
||||
|
||||
zIndexPopup: zIndexPopupBase + 50,
|
||||
optionSelectedColor: colorText,
|
||||
optionSelectedFontWeight: fontWeightStrong,
|
||||
|
@ -70,25 +70,6 @@ Array [
|
||||
style="left: 20%; transform: translateX(-50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
style="position: absolute; bottom: 0px; left: 0px;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
20
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation="horizontal"
|
||||
@ -100,6 +81,11 @@ Array [
|
||||
style="left: 50%; transform: translateX(-50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="transform: translateX(-50%); pointer-events: none; visibility: hidden;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
@ -114,9 +100,7 @@ Array [
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
50
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
@ -215,25 +199,6 @@ Array [
|
||||
style="left: 20%; transform: translateX(-50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
style="position: absolute; bottom: 0px; left: 0px;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
20
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation="horizontal"
|
||||
@ -245,6 +210,11 @@ Array [
|
||||
style="left: 50%; transform: translateX(-50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="transform: translateX(-50%); pointer-events: none; visibility: hidden;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
@ -259,9 +229,7 @@ Array [
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
50
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
@ -340,25 +308,6 @@ Array [
|
||||
style="bottom: 20%; transform: translateY(50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-right"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
style="position: absolute; top: 0px; left: 0px;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
20
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation="vertical"
|
||||
@ -370,6 +319,11 @@ Array [
|
||||
style="bottom: 50%; transform: translateY(50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="transform: translateY(50%); pointer-events: none; visibility: hidden;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-right"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
@ -384,9 +338,7 @@ Array [
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
50
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -435,25 +387,6 @@ Array [
|
||||
style="bottom: 26%; transform: translateY(50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-right"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
style="position: absolute; top: 0px; left: 0px;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
26
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation="vertical"
|
||||
@ -465,6 +398,11 @@ Array [
|
||||
style="bottom: 37%; transform: translateY(50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="transform: translateY(50%); pointer-events: none; visibility: hidden;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-right"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
@ -479,9 +417,7 @@ Array [
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
37
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@ -546,25 +482,6 @@ exports[`renders components/slider/demo/draggableTrack.tsx extend context correc
|
||||
style="left: 20%; transform: translateX(-50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
style="position: absolute; bottom: 0px; left: 0px;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
20
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation="horizontal"
|
||||
@ -576,6 +493,11 @@ exports[`renders components/slider/demo/draggableTrack.tsx extend context correc
|
||||
style="left: 50%; transform: translateX(-50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="transform: translateX(-50%); pointer-events: none; visibility: hidden;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
@ -590,9 +512,7 @@ exports[`renders components/slider/demo/draggableTrack.tsx extend context correc
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
50
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -670,25 +590,6 @@ Array [
|
||||
style="left: 20%; transform: translateX(-50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
style="position: absolute; bottom: 0px; left: 0px;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
20
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation="horizontal"
|
||||
@ -700,6 +601,11 @@ Array [
|
||||
style="left: 50%; transform: translateX(-50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="transform: translateX(-50%); pointer-events: none; visibility: hidden;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
@ -714,9 +620,7 @@ Array [
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
50
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
@ -1237,25 +1141,6 @@ Array [
|
||||
style="left: 26%; transform: translateX(-50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
style="position: absolute; bottom: 0px; left: 0px;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
26
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation="horizontal"
|
||||
@ -1267,6 +1152,11 @@ Array [
|
||||
style="left: 37%; transform: translateX(-50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="transform: translateX(-50%); pointer-events: none; visibility: hidden;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
@ -1281,9 +1171,7 @@ Array [
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
37
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@ -1633,25 +1521,6 @@ exports[`renders components/slider/demo/multiple.tsx extend context correctly 1`
|
||||
style="left: 0%; transform: translateX(-50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
style="position: absolute; bottom: 0px; left: 0px;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
0
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation="horizontal"
|
||||
@ -1663,25 +1532,6 @@ exports[`renders components/slider/demo/multiple.tsx extend context correctly 1`
|
||||
style="left: 10%; transform: translateX(-50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
style="position: absolute; bottom: 0px; left: 0px;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
10
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation="horizontal"
|
||||
@ -1693,6 +1543,11 @@ exports[`renders components/slider/demo/multiple.tsx extend context correctly 1`
|
||||
style="left: 20%; transform: translateX(-50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="transform: translateX(-50%); pointer-events: none; visibility: hidden;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
@ -1707,9 +1562,7 @@ exports[`renders components/slider/demo/multiple.tsx extend context correctly 1`
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
20
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -1787,25 +1640,6 @@ Array [
|
||||
style="right: 20%; transform: translateX(50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
style="position: absolute; bottom: 0px; left: 0px;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
20
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation="horizontal"
|
||||
@ -1817,6 +1651,11 @@ Array [
|
||||
style="right: 50%; transform: translateX(50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="transform: translateX(50%); pointer-events: none; visibility: hidden;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-top"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
@ -1831,9 +1670,7 @@ Array [
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
50
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
@ -2082,25 +1919,6 @@ Array [
|
||||
style="bottom: 20%; transform: translateY(50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-right"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
style="position: absolute; top: 0px; left: 0px;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
20
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation="vertical"
|
||||
@ -2112,6 +1930,11 @@ Array [
|
||||
style="bottom: 50%; transform: translateY(50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="transform: translateY(50%); pointer-events: none; visibility: hidden;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-right"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
@ -2126,9 +1949,7 @@ Array [
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
50
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -2177,25 +1998,6 @@ Array [
|
||||
style="bottom: 26%; transform: translateY(50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-right"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
style="position: absolute; top: 0px; left: 0px;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
26
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation="vertical"
|
||||
@ -2207,6 +2009,11 @@ Array [
|
||||
style="bottom: 37%; transform: translateY(50%);"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="transform: translateY(50%); pointer-events: none; visibility: hidden;"
|
||||
/>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-placement-right"
|
||||
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
|
||||
@ -2221,9 +2028,7 @@ Array [
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
37
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
@ -62,6 +62,11 @@ Array [
|
||||
style="left:50%;transform:translateX(-50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="left:NaN%;transform:translateX(-50%);pointer-events:none;visibility:hidden"
|
||||
/>
|
||||
</div>,
|
||||
Disabled: ,
|
||||
<button
|
||||
@ -148,6 +153,11 @@ Array [
|
||||
style="left:50%;transform:translateX(-50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="left:NaN%;transform:translateX(-50%);pointer-events:none;visibility:hidden"
|
||||
/>
|
||||
</div>,
|
||||
<div
|
||||
style="display:inline-block;height:300px;margin-left:70px"
|
||||
@ -216,6 +226,11 @@ Array [
|
||||
style="bottom:50%;transform:translateY(50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="bottom:NaN%;transform:translateY(50%);pointer-events:none;visibility:hidden"
|
||||
/>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
@ -273,6 +288,11 @@ Array [
|
||||
style="bottom:37%;transform:translateY(50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="bottom:NaN%;transform:translateY(50%);pointer-events:none;visibility:hidden"
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-mark"
|
||||
>
|
||||
@ -344,6 +364,11 @@ exports[`renders components/slider/demo/draggableTrack.tsx correctly 1`] = `
|
||||
style="left:50%;transform:translateX(-50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="left:NaN%;transform:translateX(-50%);pointer-events:none;visibility:hidden"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@ -409,6 +434,11 @@ Array [
|
||||
style="left:50%;transform:translateX(-50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="left:NaN%;transform:translateX(-50%);pointer-events:none;visibility:hidden"
|
||||
/>
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
@ -856,6 +886,11 @@ Array [
|
||||
style="left:37%;transform:translateX(-50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="left:NaN%;transform:translateX(-50%);pointer-events:none;visibility:hidden"
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-mark"
|
||||
>
|
||||
@ -1166,6 +1201,11 @@ exports[`renders components/slider/demo/multiple.tsx correctly 1`] = `
|
||||
style="left:20%;transform:translateX(-50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="left:NaN%;transform:translateX(-50%);pointer-events:none;visibility:hidden"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@ -1231,6 +1271,11 @@ Array [
|
||||
style="right:50%;transform:translateX(50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="right:NaN%;transform:translateX(50%);pointer-events:none;visibility:hidden"
|
||||
/>
|
||||
</div>,
|
||||
Reversed: ,
|
||||
<button
|
||||
@ -1380,6 +1425,11 @@ Array [
|
||||
style="bottom:50%;transform:translateY(50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="bottom:NaN%;transform:translateY(50%);pointer-events:none;visibility:hidden"
|
||||
/>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
@ -1437,6 +1487,11 @@ Array [
|
||||
style="bottom:37%;transform:translateY(50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-slider-handle"
|
||||
style="bottom:NaN%;transform:translateY(50%);pointer-events:none;visibility:hidden"
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-mark"
|
||||
>
|
||||
|
56
components/slider/__tests__/tooltip.test.tsx
Normal file
56
components/slider/__tests__/tooltip.test.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
import React from 'react';
|
||||
|
||||
import Slider from '..';
|
||||
import { fireEvent, render, waitFakeTimer } from '../../../tests/utils';
|
||||
import type { TooltipProps, TooltipRef } from '../../tooltip';
|
||||
|
||||
function tooltipProps(): TooltipProps {
|
||||
return (global as any).tooltipProps;
|
||||
}
|
||||
|
||||
jest.mock('../../tooltip', () => {
|
||||
const ReactReal: typeof React = jest.requireActual('react');
|
||||
const Tooltip = jest.requireActual('../../tooltip');
|
||||
const TooltipComponent = Tooltip.default;
|
||||
return ReactReal.forwardRef<TooltipRef, TooltipProps>((props, ref) => {
|
||||
(global as any).tooltipProps = props;
|
||||
return <TooltipComponent {...props} ref={ref} />;
|
||||
});
|
||||
});
|
||||
|
||||
describe('Slider.Tooltip', () => {
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllTimers();
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('Correct show the tooltip', async () => {
|
||||
const { container } = render(<Slider defaultValue={30} />);
|
||||
|
||||
const handleEle = container.querySelector('.ant-slider-handle')!;
|
||||
|
||||
// Enter
|
||||
fireEvent.mouseEnter(handleEle);
|
||||
await waitFakeTimer();
|
||||
expect(tooltipProps().open).toBeTruthy();
|
||||
|
||||
// Down
|
||||
fireEvent.mouseDown(handleEle);
|
||||
await waitFakeTimer();
|
||||
expect(tooltipProps().open).toBeTruthy();
|
||||
|
||||
// Move(Leave)
|
||||
fireEvent.mouseLeave(handleEle);
|
||||
await waitFakeTimer();
|
||||
expect(tooltipProps().open).toBeTruthy();
|
||||
|
||||
// Up
|
||||
fireEvent.mouseUp(handleEle);
|
||||
await waitFakeTimer();
|
||||
expect(tooltipProps().open).toBeFalsy();
|
||||
});
|
||||
});
|
@ -2,7 +2,8 @@ import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import type { SliderProps as RcSliderProps } from 'rc-slider';
|
||||
import RcSlider from 'rc-slider';
|
||||
import type { SliderRef } from 'rc-slider/lib/Slider';
|
||||
import type { SliderProps, SliderRef } from 'rc-slider/lib/Slider';
|
||||
import raf from 'rc-util/lib/raf';
|
||||
|
||||
import { devUseWarning } from '../_util/warning';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
@ -10,6 +11,7 @@ import DisabledContext from '../config-provider/DisabledContext';
|
||||
import type { AbstractTooltipProps, TooltipPlacement } from '../tooltip';
|
||||
import SliderTooltip from './SliderTooltip';
|
||||
import useStyle from './style';
|
||||
import useRafLock from './useRafLock';
|
||||
|
||||
export type SliderMarks = RcSliderProps['marks'];
|
||||
|
||||
@ -138,28 +140,57 @@ const Slider = React.forwardRef<SliderRef, SliderSingleProps | SliderRangeProps>
|
||||
tooltipVisible: legacyTooltipVisible,
|
||||
getTooltipPopupContainer: legacyGetTooltipPopupContainer,
|
||||
tooltipPlacement: legacyTooltipPlacement,
|
||||
tooltip = {},
|
||||
onChangeComplete,
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
const { vertical } = props;
|
||||
|
||||
const { direction, slider, getPrefixCls, getPopupContainer } = React.useContext(ConfigContext);
|
||||
const contextDisabled = React.useContext(DisabledContext);
|
||||
const mergedDisabled = disabled ?? contextDisabled;
|
||||
const [opens, setOpens] = React.useState<Opens>({});
|
||||
|
||||
const toggleTooltipOpen = (index: number, open: boolean) => {
|
||||
setOpens((prev: Opens) => ({ ...prev, [index]: open }));
|
||||
// =============================== Open ===============================
|
||||
const [hoverOpen, setHoverOpen] = useRafLock();
|
||||
const [focusOpen, setFocusOpen] = useRafLock();
|
||||
const activeOpen = hoverOpen || focusOpen;
|
||||
|
||||
const tooltipProps: SliderTooltipProps = {
|
||||
...tooltip,
|
||||
};
|
||||
const {
|
||||
open: tooltipOpen,
|
||||
placement: tooltipPlacement,
|
||||
getPopupContainer: getTooltipPopupContainer,
|
||||
prefixCls: customizeTooltipPrefixCls,
|
||||
formatter: tipFormatter,
|
||||
} = tooltipProps;
|
||||
|
||||
const lockOpen = tooltipOpen ?? legacyTooltipVisible;
|
||||
|
||||
const mergedTipFormatter = getTipFormatter(tipFormatter, legacyTipFormatter);
|
||||
|
||||
// ============================= Change ==============================
|
||||
const [dragging, setDragging] = useRafLock();
|
||||
|
||||
const onInternalChangeComplete: RcSliderProps['onChangeComplete'] = (nextValues) => {
|
||||
onChangeComplete?.(nextValues as any);
|
||||
setDragging(false);
|
||||
};
|
||||
|
||||
const getTooltipPlacement = (placement?: TooltipPlacement, vertical?: boolean) => {
|
||||
// ============================ Placement ============================
|
||||
const getTooltipPlacement = (placement?: TooltipPlacement, vert?: boolean) => {
|
||||
if (placement) {
|
||||
return placement;
|
||||
}
|
||||
if (!vertical) {
|
||||
if (!vert) {
|
||||
return 'top';
|
||||
}
|
||||
return direction === 'rtl' ? 'left' : 'right';
|
||||
};
|
||||
|
||||
// ============================== Style ===============================
|
||||
const prefixCls = getPrefixCls('slider', customizePrefixCls);
|
||||
|
||||
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
|
||||
@ -170,6 +201,7 @@ const Slider = React.forwardRef<SliderRef, SliderSingleProps | SliderRangeProps>
|
||||
rootClassName,
|
||||
{
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
[`${prefixCls}-lock`]: dragging,
|
||||
},
|
||||
hashId,
|
||||
cssVarCls,
|
||||
@ -180,6 +212,7 @@ const Slider = React.forwardRef<SliderRef, SliderSingleProps | SliderRangeProps>
|
||||
restProps.reverse = !restProps.reverse;
|
||||
}
|
||||
|
||||
// ============================= Multiple =============================
|
||||
// Range config
|
||||
const [mergedRange, draggableTrack] = React.useMemo(() => {
|
||||
if (!range) {
|
||||
@ -189,6 +222,7 @@ const Slider = React.forwardRef<SliderRef, SliderSingleProps | SliderRangeProps>
|
||||
return typeof range === 'object' ? [true, range.draggableTrack] : [true, false];
|
||||
}, [range]);
|
||||
|
||||
// ============================= Warning ==============================
|
||||
// Warning for deprecated usage
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const warning = devUseWarning('Slider');
|
||||
@ -204,60 +238,112 @@ const Slider = React.forwardRef<SliderRef, SliderSingleProps | SliderRangeProps>
|
||||
});
|
||||
}
|
||||
|
||||
// ============================== Handle ==============================
|
||||
|
||||
React.useEffect(() => {
|
||||
const onMouseUp = () => {
|
||||
// Delay for 1 frame to make the click to enable hide tooltip
|
||||
// even when the handle is focused
|
||||
raf(() => {
|
||||
setFocusOpen(false);
|
||||
}, 1);
|
||||
};
|
||||
document.addEventListener('mouseup', onMouseUp);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('mouseup', onMouseUp);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const useActiveTooltipHandle = mergedRange && !lockOpen;
|
||||
|
||||
const handleRender: RcSliderProps['handleRender'] = (node, info) => {
|
||||
const { index, dragging } = info;
|
||||
const { index } = info;
|
||||
|
||||
const { tooltip = {}, vertical } = props;
|
||||
const nodeProps = node.props;
|
||||
|
||||
const tooltipProps: SliderTooltipProps = {
|
||||
...tooltip,
|
||||
};
|
||||
const {
|
||||
open: tooltipOpen,
|
||||
placement: tooltipPlacement,
|
||||
getPopupContainer: getTooltipPopupContainer,
|
||||
prefixCls: customizeTooltipPrefixCls,
|
||||
formatter: tipFormatter,
|
||||
} = tooltipProps;
|
||||
|
||||
const mergedTipFormatter = getTipFormatter(tipFormatter, legacyTipFormatter);
|
||||
|
||||
const isTipFormatter = mergedTipFormatter ? opens[index] || dragging : false;
|
||||
const open =
|
||||
tooltipOpen ?? legacyTooltipVisible ?? (tooltipOpen === undefined && isTipFormatter);
|
||||
|
||||
const passedProps = {
|
||||
...node.props,
|
||||
onMouseEnter: () => toggleTooltipOpen(index, true),
|
||||
onMouseLeave: () => toggleTooltipOpen(index, false),
|
||||
onFocus: (e: React.FocusEvent<HTMLDivElement>) => {
|
||||
toggleTooltipOpen(index, true);
|
||||
const passedProps: typeof nodeProps = {
|
||||
...nodeProps,
|
||||
onMouseEnter: (e) => {
|
||||
setHoverOpen(true);
|
||||
nodeProps.onMouseEnter?.(e);
|
||||
},
|
||||
onMouseLeave: (e) => {
|
||||
setHoverOpen(false);
|
||||
nodeProps.onMouseLeave?.(e);
|
||||
},
|
||||
onMouseDown: (e) => {
|
||||
setFocusOpen(true);
|
||||
setDragging(true);
|
||||
nodeProps.onMouseDown?.(e);
|
||||
},
|
||||
onFocus: (e) => {
|
||||
setFocusOpen(true);
|
||||
restProps.onFocus?.(e);
|
||||
nodeProps.onFocus?.(e);
|
||||
},
|
||||
onBlur: (e: React.FocusEvent<HTMLDivElement>) => {
|
||||
toggleTooltipOpen(index, false);
|
||||
onBlur: (e) => {
|
||||
setFocusOpen(false);
|
||||
restProps.onBlur?.(e);
|
||||
nodeProps.onBlur?.(e);
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<SliderTooltip
|
||||
{...tooltipProps}
|
||||
prefixCls={getPrefixCls('tooltip', customizeTooltipPrefixCls ?? legacyTooltipPrefixCls)}
|
||||
title={mergedTipFormatter ? mergedTipFormatter(info.value) : ''}
|
||||
open={open}
|
||||
placement={getTooltipPlacement(tooltipPlacement ?? legacyTooltipPlacement, vertical)}
|
||||
key={index}
|
||||
overlayClassName={`${prefixCls}-tooltip`}
|
||||
getPopupContainer={
|
||||
getTooltipPopupContainer || legacyGetTooltipPopupContainer || getPopupContainer
|
||||
}
|
||||
>
|
||||
{React.cloneElement(node, passedProps)}
|
||||
</SliderTooltip>
|
||||
);
|
||||
const cloneNode = React.cloneElement(node, passedProps);
|
||||
|
||||
// Wrap on handle with Tooltip when is single mode or multiple with all show tooltip
|
||||
if (!useActiveTooltipHandle) {
|
||||
return (
|
||||
<SliderTooltip
|
||||
{...tooltipProps}
|
||||
prefixCls={getPrefixCls('tooltip', customizeTooltipPrefixCls ?? legacyTooltipPrefixCls)}
|
||||
title={mergedTipFormatter ? mergedTipFormatter(info.value) : ''}
|
||||
open={!!lockOpen || activeOpen}
|
||||
placement={getTooltipPlacement(tooltipPlacement ?? legacyTooltipPlacement, vertical)}
|
||||
key={index}
|
||||
overlayClassName={`${prefixCls}-tooltip`}
|
||||
getPopupContainer={
|
||||
getTooltipPopupContainer || legacyGetTooltipPopupContainer || getPopupContainer
|
||||
}
|
||||
>
|
||||
{cloneNode}
|
||||
</SliderTooltip>
|
||||
);
|
||||
}
|
||||
|
||||
return cloneNode;
|
||||
};
|
||||
|
||||
// ========================== Active Handle ===========================
|
||||
const activeHandleRender: SliderProps['activeHandleRender'] = useActiveTooltipHandle
|
||||
? (handle, info) => {
|
||||
const cloneNode = React.cloneElement(handle, {
|
||||
style: {
|
||||
...handle.props.style,
|
||||
visibility: 'hidden',
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<SliderTooltip
|
||||
{...tooltipProps}
|
||||
prefixCls={getPrefixCls('tooltip', customizeTooltipPrefixCls ?? legacyTooltipPrefixCls)}
|
||||
title={mergedTipFormatter ? mergedTipFormatter(info.value) : ''}
|
||||
open={activeOpen}
|
||||
placement={getTooltipPlacement(tooltipPlacement ?? legacyTooltipPlacement, vertical)}
|
||||
key="tooltip"
|
||||
overlayClassName={`${prefixCls}-tooltip`}
|
||||
getPopupContainer={
|
||||
getTooltipPopupContainer || legacyGetTooltipPopupContainer || getPopupContainer
|
||||
}
|
||||
>
|
||||
{cloneNode}
|
||||
</SliderTooltip>
|
||||
);
|
||||
}
|
||||
: undefined;
|
||||
|
||||
// ============================== Render ==============================
|
||||
const mergedStyle: React.CSSProperties = { ...slider?.style, ...style };
|
||||
|
||||
return wrapCSSVar(
|
||||
@ -273,6 +359,8 @@ const Slider = React.forwardRef<SliderRef, SliderSingleProps | SliderRangeProps>
|
||||
ref={ref}
|
||||
prefixCls={prefixCls}
|
||||
handleRender={handleRender}
|
||||
activeHandleRender={activeHandleRender}
|
||||
onChangeComplete={onInternalChangeComplete}
|
||||
/>,
|
||||
);
|
||||
});
|
||||
|
@ -256,6 +256,12 @@ const genBaseStyle: GenerateStyle<SliderToken> = (token) => {
|
||||
},
|
||||
},
|
||||
|
||||
[`&-lock ${componentCls}-handle`]: {
|
||||
[`&::before, &::after`]: {
|
||||
transition: 'none',
|
||||
},
|
||||
},
|
||||
|
||||
[`${componentCls}-mark`]: {
|
||||
position: 'absolute',
|
||||
fontSize: token.fontSize,
|
||||
|
27
components/slider/useRafLock.ts
Normal file
27
components/slider/useRafLock.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import * as React from 'react';
|
||||
import raf from 'rc-util/lib/raf';
|
||||
|
||||
export default function useRafLock(): [state: boolean, setState: (nextState: boolean) => void] {
|
||||
const [state, setState] = React.useState(false);
|
||||
|
||||
const rafRef = React.useRef<number>();
|
||||
const cleanup = () => {
|
||||
raf.cancel(rafRef.current!);
|
||||
};
|
||||
|
||||
const setDelayState = (nextState: boolean) => {
|
||||
cleanup();
|
||||
|
||||
if (nextState) {
|
||||
setState(nextState);
|
||||
} else {
|
||||
rafRef.current = raf(() => {
|
||||
setState(nextState);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
React.useEffect(() => cleanup, []);
|
||||
|
||||
return [state, setDelayState];
|
||||
}
|
@ -107,29 +107,34 @@ export const genCommonStyle = (
|
||||
token: DerivativeToken,
|
||||
componentPrefixCls: string,
|
||||
rootCls?: string,
|
||||
resetFont?: boolean,
|
||||
): CSSObject => {
|
||||
const { fontFamily, fontSize } = token;
|
||||
|
||||
const prefixSelector = `[class^="${componentPrefixCls}"], [class*=" ${componentPrefixCls}"]`;
|
||||
const rootPrefixSelector = rootCls ? `.${rootCls}` : prefixSelector;
|
||||
|
||||
const resetStyle: CSSObject = {
|
||||
boxSizing: 'border-box',
|
||||
|
||||
'&::before, &::after': {
|
||||
boxSizing: 'border-box',
|
||||
},
|
||||
};
|
||||
|
||||
let resetFontStyle: CSSObject = {};
|
||||
|
||||
if (resetFont !== false) {
|
||||
resetFontStyle = {
|
||||
fontFamily: token.fontFamily,
|
||||
fontSize: token.fontSize,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
[rootPrefixSelector]: {
|
||||
fontFamily,
|
||||
fontSize,
|
||||
boxSizing: 'border-box',
|
||||
...resetFontStyle,
|
||||
...resetStyle,
|
||||
|
||||
'&::before, &::after': {
|
||||
boxSizing: 'border-box',
|
||||
},
|
||||
|
||||
[prefixSelector]: {
|
||||
boxSizing: 'border-box',
|
||||
|
||||
'&::before, &::after': {
|
||||
boxSizing: 'border-box',
|
||||
},
|
||||
},
|
||||
[prefixSelector]: resetStyle,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -85,7 +85,7 @@ const App: React.FC = () => {
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, [JSON.stringify(tableParams)]);
|
||||
}, [tableParams.pagination?.current, tableParams.pagination?.pageSize]);
|
||||
|
||||
const handleTableChange: TableProps['onChange'] = (pagination, filters, sorter) => {
|
||||
setTableParams({
|
||||
|
@ -1,12 +1,12 @@
|
||||
import * as React from 'react';
|
||||
import { Theme } from '@ant-design/cssinjs';
|
||||
import { Input } from 'antd';
|
||||
|
||||
import theme from '..';
|
||||
import { render, renderHook } from '../../../tests/utils';
|
||||
import ConfigProvider from '../../config-provider';
|
||||
import type { ThemeConfig } from '../../config-provider/context';
|
||||
import Row from '../../row';
|
||||
import Slider from '../../slider';
|
||||
import genRadius from '../themes/shared/genRadius';
|
||||
|
||||
const { useToken } = theme;
|
||||
@ -314,24 +314,30 @@ describe('Theme', () => {
|
||||
<ConfigProvider
|
||||
theme={{
|
||||
components: {
|
||||
Input: {
|
||||
Slider: {
|
||||
colorPrimary: '#00B96B',
|
||||
algorithm,
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Input />
|
||||
<Slider value={5} />
|
||||
</ConfigProvider>
|
||||
);
|
||||
|
||||
const { container, rerender } = render(<Demo />);
|
||||
expect(container.querySelector('input')).toHaveStyle({ 'border-color': '#4096ff' });
|
||||
expect(container.querySelector('.ant-slider-track')).toHaveStyle({
|
||||
'background-color': '#91caff',
|
||||
});
|
||||
|
||||
rerender(<Demo algorithm />);
|
||||
expect(container.querySelector('input')).toHaveStyle({ 'border-color': '#20c77c' });
|
||||
expect(container.querySelector('.ant-slider-track')).toHaveStyle({
|
||||
'background-color': '#6ce0a4',
|
||||
});
|
||||
|
||||
rerender(<Demo algorithm={theme.darkAlgorithm} />);
|
||||
expect(container.querySelector('input')).toHaveStyle({ 'border-color': '#1fb572' });
|
||||
expect(container.querySelector('.ant-slider-track')).toHaveStyle({
|
||||
'background-color': '#0e462e',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -133,6 +133,7 @@ export default function genComponentStyleHook<C extends OverrideComponent>(
|
||||
getDefaultToken?: GetDefaultToken<C>,
|
||||
options: {
|
||||
resetStyle?: boolean;
|
||||
resetFont?: boolean;
|
||||
// Deprecated token key map [["oldTokenKey", "newTokenKey"], ["oldTokenKey", "newTokenKey"]]
|
||||
deprecatedTokens?: [ComponentTokenKey<C>, ComponentTokenKey<C>][];
|
||||
/**
|
||||
@ -246,7 +247,9 @@ export default function genComponentStyleHook<C extends OverrideComponent>(
|
||||
});
|
||||
flush(component, componentToken);
|
||||
return [
|
||||
options.resetStyle === false ? null : genCommonStyle(mergedToken, prefixCls, rootCls),
|
||||
options.resetStyle === false
|
||||
? null
|
||||
: genCommonStyle(mergedToken, prefixCls, rootCls, options.resetFont),
|
||||
styleInterpolation,
|
||||
];
|
||||
},
|
||||
@ -381,6 +384,7 @@ export const genStyleHooks = <C extends OverrideComponent>(
|
||||
getDefaultToken?: GetDefaultToken<C>,
|
||||
options?: {
|
||||
resetStyle?: boolean;
|
||||
resetFont?: boolean;
|
||||
deprecatedTokens?: [ComponentTokenKey<C>, ComponentTokenKey<C>][];
|
||||
/**
|
||||
* Component tokens that do not need unit.
|
||||
|
@ -2,6 +2,7 @@ import type { TimePickerLocale } from '../index';
|
||||
|
||||
const locale: TimePickerLocale = {
|
||||
placeholder: 'Pilih waktu',
|
||||
rangePlaceholder: ['Waktu awal', 'Waktu akhir'],
|
||||
};
|
||||
|
||||
export default locale;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,6 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Space, Switch, Table, Tag, Transfer } from 'antd';
|
||||
import type { GetProp, TableColumnsType, TableProps, TransferProps } from 'antd';
|
||||
import difference from 'lodash/difference';
|
||||
|
||||
type TransferItem = GetProp<TransferProps, 'dataSource'>[number];
|
||||
type TableRowSelection<T extends object> = TableProps<T>['rowSelection'];
|
||||
@ -10,7 +9,6 @@ interface RecordType {
|
||||
key: string;
|
||||
title: string;
|
||||
description: string;
|
||||
disabled: boolean;
|
||||
tag: string;
|
||||
}
|
||||
|
||||
@ -18,7 +16,6 @@ interface DataType {
|
||||
key: string;
|
||||
title: string;
|
||||
description: string;
|
||||
disabled: boolean;
|
||||
tag: string;
|
||||
}
|
||||
|
||||
@ -34,28 +31,20 @@ const TableTransfer = ({ leftColumns, rightColumns, ...restProps }: TableTransfe
|
||||
{({
|
||||
direction,
|
||||
filteredItems,
|
||||
onItemSelectAll,
|
||||
onItemSelect,
|
||||
onItemSelectAll,
|
||||
selectedKeys: listSelectedKeys,
|
||||
disabled: listDisabled,
|
||||
}) => {
|
||||
const columns = direction === 'left' ? leftColumns : rightColumns;
|
||||
|
||||
const rowSelection: TableRowSelection<TransferItem> = {
|
||||
getCheckboxProps: (item) => ({ disabled: listDisabled || item.disabled }),
|
||||
onSelectAll(selected, selectedRows) {
|
||||
const treeSelectedKeys = selectedRows
|
||||
.filter((item) => !item.disabled)
|
||||
.map(({ key }) => key);
|
||||
const diffKeys = selected
|
||||
? difference(treeSelectedKeys, listSelectedKeys)
|
||||
: difference(listSelectedKeys, treeSelectedKeys);
|
||||
onItemSelectAll(diffKeys as string[], selected);
|
||||
},
|
||||
onSelect({ key }, selected) {
|
||||
onItemSelect(key as string, selected);
|
||||
getCheckboxProps: () => ({ disabled: listDisabled }),
|
||||
onChange(selectedRowKeys) {
|
||||
onItemSelectAll(selectedRowKeys, 'replace');
|
||||
},
|
||||
selectedRowKeys: listSelectedKeys,
|
||||
selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT, Table.SELECTION_NONE],
|
||||
};
|
||||
|
||||
return (
|
||||
@ -70,7 +59,7 @@ const TableTransfer = ({ leftColumns, rightColumns, ...restProps }: TableTransfe
|
||||
if (itemDisabled || listDisabled) {
|
||||
return;
|
||||
}
|
||||
onItemSelect(key as string, !listSelectedKeys.includes(key as string));
|
||||
onItemSelect(key, !listSelectedKeys.includes(key));
|
||||
},
|
||||
})}
|
||||
/>
|
||||
@ -85,15 +74,10 @@ const mockData: RecordType[] = Array.from({ length: 20 }).map((_, i) => ({
|
||||
key: i.toString(),
|
||||
title: `content${i + 1}`,
|
||||
description: `description of content${i + 1}`,
|
||||
disabled: i % 4 === 0,
|
||||
tag: mockTags[i % 3],
|
||||
}));
|
||||
|
||||
const originTargetKeys = mockData
|
||||
.filter((item) => Number(item.key) % 3 > 1)
|
||||
.map((item) => item.key);
|
||||
|
||||
const leftTableColumns: TableColumnsType<DataType> = [
|
||||
const columns: TableColumnsType<DataType> = [
|
||||
{
|
||||
dataIndex: 'title',
|
||||
title: 'Name',
|
||||
@ -101,7 +85,11 @@ const leftTableColumns: TableColumnsType<DataType> = [
|
||||
{
|
||||
dataIndex: 'tag',
|
||||
title: 'Tag',
|
||||
render: (tag: string) => <Tag style={{ marginInlineEnd: 0 }}>{tag.toUpperCase()}</Tag>,
|
||||
render: (tag: string) => (
|
||||
<Tag style={{ marginInlineEnd: 0 }} color="cyan">
|
||||
{tag.toUpperCase()}
|
||||
</Tag>
|
||||
),
|
||||
},
|
||||
{
|
||||
dataIndex: 'description',
|
||||
@ -109,56 +97,39 @@ const leftTableColumns: TableColumnsType<DataType> = [
|
||||
},
|
||||
];
|
||||
|
||||
const rightTableColumns: TableColumnsType<DataType> = [
|
||||
{
|
||||
dataIndex: 'title',
|
||||
title: 'Name',
|
||||
},
|
||||
];
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [targetKeys, setTargetKeys] = useState<TransferProps['targetKeys']>(originTargetKeys);
|
||||
const [targetKeys, setTargetKeys] = useState<TransferProps['targetKeys']>([]);
|
||||
const [disabled, setDisabled] = useState(false);
|
||||
const [showSearch, setShowSearch] = useState(false);
|
||||
|
||||
const onChange: TableTransferProps['onChange'] = (nextTargetKeys) => {
|
||||
setTargetKeys(nextTargetKeys);
|
||||
};
|
||||
|
||||
const triggerDisable = (checked: boolean) => {
|
||||
const toggleDisabled = (checked: boolean) => {
|
||||
setDisabled(checked);
|
||||
};
|
||||
|
||||
const triggerShowSearch = (checked: boolean) => {
|
||||
setShowSearch(checked);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableTransfer
|
||||
dataSource={mockData}
|
||||
targetKeys={targetKeys}
|
||||
disabled={disabled}
|
||||
showSearch={showSearch}
|
||||
showSearch
|
||||
showSelectAll={false}
|
||||
onChange={onChange}
|
||||
filterOption={(inputValue, item) =>
|
||||
item.title!.indexOf(inputValue) !== -1 || item.tag.indexOf(inputValue) !== -1
|
||||
}
|
||||
leftColumns={leftTableColumns}
|
||||
rightColumns={rightTableColumns}
|
||||
leftColumns={columns}
|
||||
rightColumns={columns}
|
||||
/>
|
||||
<Space style={{ marginTop: 16 }}>
|
||||
<Switch
|
||||
unCheckedChildren="disabled"
|
||||
checkedChildren="disabled"
|
||||
checked={disabled}
|
||||
onChange={triggerDisable}
|
||||
/>
|
||||
<Switch
|
||||
unCheckedChildren="showSearch"
|
||||
checkedChildren="showSearch"
|
||||
checked={showSearch}
|
||||
onChange={triggerShowSearch}
|
||||
onChange={toggleDisabled}
|
||||
/>
|
||||
</Space>
|
||||
</>
|
||||
|
@ -67,6 +67,7 @@ export interface TransferLocale {
|
||||
itemsUnit: string;
|
||||
remove?: string;
|
||||
selectAll?: string;
|
||||
deselectAll?: string;
|
||||
selectCurrent?: string;
|
||||
selectInvert?: string;
|
||||
removeAll?: string;
|
||||
|
@ -97,6 +97,7 @@ const TransferList = <RecordType extends KeyWiseTransferItem>(
|
||||
searchPlaceholder,
|
||||
notFoundContent,
|
||||
selectAll,
|
||||
deselectAll,
|
||||
selectCurrent,
|
||||
selectInvert,
|
||||
removeAll,
|
||||
@ -325,7 +326,7 @@ const TransferList = <RecordType extends KeyWiseTransferItem>(
|
||||
items = [
|
||||
{
|
||||
key: 'selectAll',
|
||||
label: selectAll,
|
||||
label: checkStatus === 'all' ? deselectAll : selectAll,
|
||||
onClick() {
|
||||
const keys = getEnabledItemKeys(filteredItems);
|
||||
onItemSelectAll?.(keys, keys.length !== checkedKeys.length);
|
||||
@ -362,7 +363,6 @@ const TransferList = <RecordType extends KeyWiseTransferItem>(
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const dropdown: React.ReactNode = (
|
||||
<Dropdown className={`${prefixCls}-header-dropdown`} menu={{ items }} disabled={disabled}>
|
||||
{isValidIcon(selectionsIcon) ? selectionsIcon : <DownOutlined />}
|
||||
|
@ -14,7 +14,7 @@ const genMotionStyle: GenerateStyle<UploadToken> = (token) => {
|
||||
height: 0,
|
||||
padding: 0,
|
||||
opacity: 0,
|
||||
margin: `calc(${token.marginXS} / -2)`,
|
||||
margin: token.calc(token.marginXS).div(-2).equal(),
|
||||
},
|
||||
});
|
||||
|
||||
@ -24,7 +24,7 @@ const genMotionStyle: GenerateStyle<UploadToken> = (token) => {
|
||||
height: 0,
|
||||
padding: 0,
|
||||
opacity: 0,
|
||||
margin: `calc(${token.marginXS} / -2)`,
|
||||
margin: token.calc(token.marginXS).div(-2).equal(),
|
||||
},
|
||||
});
|
||||
|
||||
|
10
package.json
10
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "5.16.2",
|
||||
"version": "5.16.4",
|
||||
"description": "An enterprise-class UI design language and React components implementation",
|
||||
"keywords": [
|
||||
"ant",
|
||||
@ -151,7 +151,7 @@
|
||||
"rc-resize-observer": "^1.4.0",
|
||||
"rc-segmented": "~2.3.0",
|
||||
"rc-select": "~14.13.1",
|
||||
"rc-slider": "~10.5.0",
|
||||
"rc-slider": "~10.6.1",
|
||||
"rc-steps": "~6.0.1",
|
||||
"rc-switch": "~4.1.0",
|
||||
"rc-table": "~7.45.4",
|
||||
@ -222,7 +222,7 @@
|
||||
"@types/react-resizable": "^3.0.7",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@types/spinnies": "^0.5.3",
|
||||
"@types/tar": "^6.1.12",
|
||||
"@types/tar": "^6.1.13",
|
||||
"@types/throttle-debounce": "^5.0.2",
|
||||
"@types/warning": "^3.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^7.7.0",
|
||||
@ -302,7 +302,7 @@
|
||||
"qs": "^6.12.1",
|
||||
"rc-footer": "^0.6.8",
|
||||
"rc-tween-one": "^3.0.6",
|
||||
"rc-virtual-list": "^3.11.4",
|
||||
"rc-virtual-list": "^3.11.5",
|
||||
"react": "^18.2.0",
|
||||
"react-copy-to-clipboard": "^5.1.0",
|
||||
"react-countup": "^6.5.3",
|
||||
@ -341,7 +341,7 @@
|
||||
"tsx": "^4.7.2",
|
||||
"typedoc": "^0.25.13",
|
||||
"typescript": "~5.4.5",
|
||||
"vanilla-jsoneditor": "^0.23.1",
|
||||
"vanilla-jsoneditor": "^0.23.2",
|
||||
"vanilla-tilt": "^1.8.1",
|
||||
"webpack": "^5.91.0",
|
||||
"webpack-bundle-analyzer": "^4.10.2",
|
||||
|
Loading…
Reference in New Issue
Block a user