mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-02 03:59:01 +08:00
megre Feature into master (#29141)
* feat: Allow user to configure the Tooltip in the Table header (#29002) * feat: Table header supports tooltipPlacement * docs: add Table tooltipPlacement * feat: Allow user to configure the Tooltip in the Table header * fix: fix jsx and use old code style * fix: replace if blocks with ternary operator * docs: fix url Co-authored-by: 偏右 <afc163@gmail.com> * docs: fix url Co-authored-by: harrisoff <john@smith.kyon> Co-authored-by: 偏右 <afc163@gmail.com> * fix: Row with gutter has additional gap (#29059) * chore: init gutter * feat: col support gap * chore: Update playground * fix: Safari padding * test: fix test case * test: More test case * docs: Update demo * test: Update coverage * test: Update test hack * feat(input-number): add keyboard prop to support disable keyboard (#29110) Co-authored-by: Ant Design GitHub Bot <yesmeck+ant-design-bot@gmail.com> Co-authored-by: Harrison <stlebea@foxmail.com> Co-authored-by: harrisoff <john@smith.kyon> Co-authored-by: 偏右 <afc163@gmail.com> Co-authored-by: 二货机器人 <smith3816@gmail.com> Co-authored-by: Kermit <kermitlx@outlook.com>
This commit is contained in:
parent
be08d23bad
commit
40f9be9417
@ -1,5 +1,9 @@
|
||||
import canUseDom from 'rc-util/lib/Dom/canUseDom';
|
||||
|
||||
export const canUseDocElement = () => canUseDom() && window.document.documentElement;
|
||||
|
||||
export const isStyleSupport = (styleName: string | Array<string>): boolean => {
|
||||
if (typeof window !== 'undefined' && window.document && window.document.documentElement) {
|
||||
if (canUseDocElement()) {
|
||||
const styleNameList = Array.isArray(styleName) ? styleName : [styleName];
|
||||
const { documentElement } = window.document;
|
||||
|
||||
@ -9,3 +13,26 @@ export const isStyleSupport = (styleName: string | Array<string>): boolean => {
|
||||
};
|
||||
|
||||
export const isFlexSupported = isStyleSupport(['flex', 'webkitFlex', 'Flex', 'msFlex']);
|
||||
|
||||
export const isFlexGapSupported = (() => {
|
||||
if (!canUseDocElement()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// create flex container with row-gap set
|
||||
const flex = document.createElement('div');
|
||||
flex.style.display = 'flex';
|
||||
flex.style.flexDirection = 'column';
|
||||
flex.style.rowGap = '1px';
|
||||
|
||||
// create two, elements inside it
|
||||
flex.appendChild(document.createElement('div'));
|
||||
flex.appendChild(document.createElement('div'));
|
||||
|
||||
// append to the DOM (needed to obtain scrollHeight)
|
||||
document.body.appendChild(flex);
|
||||
const isSupported = flex.scrollHeight === 1; // flex container should be 1px high from the row-gap
|
||||
document.body.removeChild(flex);
|
||||
|
||||
return isSupported;
|
||||
})();
|
||||
|
@ -701,7 +701,7 @@ Array [
|
||||
</div>,
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left:-8px;margin-right:-8px;margin-top:-12px;margin-bottom:12px"
|
||||
style="margin-left:-8px;margin-right:-8px;margin-top:-12px;margin-bottom:-12px"
|
||||
>
|
||||
<div
|
||||
class="ant-col ant-col-6 gutter-row"
|
||||
@ -1121,7 +1121,7 @@ Array [
|
||||
</div>,
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left:-8px;margin-right:-8px;margin-top:-8px;margin-bottom:8px"
|
||||
style="margin-left:-8px;margin-right:-8px;margin-top:-8px;margin-bottom:-8px"
|
||||
>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
@ -1155,10 +1155,43 @@ Array [
|
||||
Column
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
style="padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px"
|
||||
>
|
||||
<div>
|
||||
Column
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
style="padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px"
|
||||
>
|
||||
<div>
|
||||
Column
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
style="padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px"
|
||||
>
|
||||
<div>
|
||||
Column
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
style="padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px"
|
||||
>
|
||||
<div>
|
||||
Column
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
"Another Row:",
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left:-8px;margin-right:-8px;margin-top:-8px;margin-bottom:8px"
|
||||
style="margin-left:-8px;margin-right:-8px;margin-top:-8px;margin-bottom:-8px"
|
||||
>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
@ -1201,6 +1234,11 @@ Array [
|
||||
<Col span={6} />
|
||||
<Col span={6} />
|
||||
<Col span={6} />
|
||||
|
||||
<Col span={6} />
|
||||
<Col span={6} />
|
||||
<Col span={6} />
|
||||
<Col span={6} />
|
||||
</Row>
|
||||
</pre>,
|
||||
<pre
|
||||
|
@ -45,6 +45,6 @@ exports[`Grid should render Row 1`] = `
|
||||
exports[`Grid when typeof gutter is object array in large screen 1`] = `
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left:-20px;margin-right:-20px;margin-top:-200px;margin-bottom:200px"
|
||||
style="margin-left:-20px;margin-right:-20px;margin-top:-200px;margin-bottom:-200px"
|
||||
/>
|
||||
`;
|
||||
|
28
components/grid/__tests__/gap.test.js
Normal file
28
components/grid/__tests__/gap.test.js
Normal file
@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { Col, Row } from '..';
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import * as styleChecker from '../../_util/styleChecker';
|
||||
|
||||
jest.mock('../../_util/styleChecker', () => ({
|
||||
canUseDocElement: () => true,
|
||||
isStyleSupport: () => true,
|
||||
isFlexGapSupported: true,
|
||||
}));
|
||||
|
||||
describe('Grid.Gap', () => {
|
||||
it('should use gap', () => {
|
||||
const wrapper = mount(
|
||||
<Row gutter={[16, 8]}>
|
||||
<Col />
|
||||
</Row>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('.ant-row').props().style).toEqual(
|
||||
expect.objectContaining({
|
||||
'--column-gap': '16px',
|
||||
'--row-gap': '8px',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
@ -93,13 +93,13 @@ describe('Grid', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should work currect when gutter is array', () => {
|
||||
it('should work current when gutter is array', () => {
|
||||
const wrapper = mount(<Row gutter={[16, 20]} />);
|
||||
expect(wrapper.find('div').prop('style')).toEqual({
|
||||
marginLeft: -8,
|
||||
marginRight: -8,
|
||||
marginTop: -10,
|
||||
marginBottom: 10,
|
||||
marginBottom: -10,
|
||||
});
|
||||
});
|
||||
|
||||
|
35
components/grid/__tests__/server.test.js
Normal file
35
components/grid/__tests__/server.test.js
Normal file
@ -0,0 +1,35 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import canUseDom from 'rc-util/lib/Dom/canUseDom';
|
||||
import { Col, Row } from '..';
|
||||
|
||||
jest.mock('rc-util/lib/Dom/canUseDom', () => () => false);
|
||||
|
||||
describe('Grid.Server', () => {
|
||||
it('use compatible gap logic', () => {
|
||||
const wrapper = mount(
|
||||
<Row gutter={[8, 16]}>
|
||||
<Col />
|
||||
</Row>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('.ant-row').props().style).toEqual(
|
||||
expect.objectContaining({
|
||||
marginLeft: -4,
|
||||
marginRight: -4,
|
||||
marginTop: -8,
|
||||
marginBottom: -8,
|
||||
}),
|
||||
);
|
||||
|
||||
expect(wrapper.find('.ant-col').props().style).toEqual(
|
||||
expect.objectContaining({
|
||||
paddingLeft: 4,
|
||||
paddingRight: 4,
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
@ -2,6 +2,7 @@ import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import RowContext from './RowContext';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import { isFlexGapSupported } from '../_util/styleChecker';
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/14324
|
||||
type ColSpanType = number | string;
|
||||
@ -103,7 +104,7 @@ const Col = React.forwardRef<HTMLDivElement, ColProps>((props, ref) => {
|
||||
);
|
||||
|
||||
let mergedStyle: React.CSSProperties = { ...style };
|
||||
if (gutter) {
|
||||
if (gutter && !isFlexGapSupported) {
|
||||
mergedStyle = {
|
||||
...(gutter[0]! > 0
|
||||
? {
|
||||
|
@ -100,9 +100,13 @@ class App extends React.Component {
|
||||
tipFormatter={value => colCounts[value]}
|
||||
/>
|
||||
</div>
|
||||
<Row gutter={[gutters[gutterKey], vgutters[vgutterKey]]}>
|
||||
{cols}
|
||||
{cols}
|
||||
</Row>
|
||||
Another Row:
|
||||
<Row gutter={[gutters[gutterKey], vgutters[vgutterKey]]}>{cols}</Row>
|
||||
<Row gutter={[gutters[gutterKey], vgutters[vgutterKey]]}>{cols}</Row>
|
||||
<pre className="demo-code">{`<Row gutter={[${gutters[gutterKey]}, ${vgutters[vgutterKey]}]}>\n${colCode}</Row>`}</pre>
|
||||
<pre className="demo-code">{`<Row gutter={[${gutters[gutterKey]}, ${vgutters[vgutterKey]}]}>\n${colCode}\n${colCode}</Row>`}</pre>
|
||||
<pre className="demo-code">{`<Row gutter={[${gutters[gutterKey]}, ${vgutters[vgutterKey]}]}>\n${colCode}</Row>`}</pre>
|
||||
</>
|
||||
);
|
||||
@ -133,6 +137,9 @@ ReactDOM.render(<App />, mountNode);
|
||||
#components-grid-demo-playground pre.demo-code {
|
||||
direction: ltr;
|
||||
}
|
||||
#components-grid-demo-playground .ant-col {
|
||||
padding: 0;
|
||||
}
|
||||
```
|
||||
|
||||
<style>
|
||||
|
@ -8,6 +8,7 @@ import ResponsiveObserve, {
|
||||
ScreenMap,
|
||||
responsiveArray,
|
||||
} from '../_util/responsiveObserve';
|
||||
import { isFlexGapSupported } from '../_util/styleChecker';
|
||||
|
||||
const RowAligns = tuple('top', 'middle', 'bottom', 'stretch');
|
||||
const RowJustify = tuple('start', 'end', 'center', 'space-around', 'space-between');
|
||||
@ -92,25 +93,44 @@ const Row = React.forwardRef<HTMLDivElement, RowProps>((props, ref) => {
|
||||
},
|
||||
className,
|
||||
);
|
||||
const rowStyle = {
|
||||
...(gutters[0]! > 0
|
||||
? {
|
||||
marginLeft: gutters[0]! / -2,
|
||||
marginRight: gutters[0]! / -2,
|
||||
}
|
||||
: {}),
|
||||
...(gutters[1]! > 0
|
||||
? {
|
||||
marginTop: gutters[1]! / -2,
|
||||
marginBottom: gutters[1]! / 2,
|
||||
}
|
||||
: {}),
|
||||
...style,
|
||||
};
|
||||
|
||||
// Add gutter related style
|
||||
let rowStyle: React.CSSProperties & {
|
||||
'--column-gap'?: string | number;
|
||||
'--row-gap'?: string | number;
|
||||
} = {};
|
||||
|
||||
if (isFlexGapSupported) {
|
||||
rowStyle = {
|
||||
'--column-gap': 0,
|
||||
'--row-gap': 0,
|
||||
};
|
||||
|
||||
if (gutters[0]! > 0) {
|
||||
const gap = gutters[0];
|
||||
rowStyle.columnGap = gap;
|
||||
rowStyle['--column-gap'] = `${gap}px`;
|
||||
}
|
||||
if (gutters[1]! > 0) {
|
||||
const gap = gutters[1];
|
||||
rowStyle.rowGap = gap;
|
||||
rowStyle['--row-gap'] = `${gap}px`;
|
||||
}
|
||||
} else {
|
||||
const horizontalGutter = gutters[0]! > 0 ? gutters[0] / -2 : undefined;
|
||||
const verticalGutter = gutters[1]! > 0 ? gutters[1] / -2 : undefined;
|
||||
|
||||
rowStyle = {
|
||||
marginLeft: horizontalGutter,
|
||||
marginRight: horizontalGutter,
|
||||
marginTop: verticalGutter,
|
||||
marginBottom: verticalGutter,
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<RowContext.Provider value={{ gutter: gutters, wrap }}>
|
||||
<div {...others} className={classes} style={rowStyle} ref={ref}>
|
||||
<div {...others} className={classes} style={{ ...rowStyle, ...style }} ref={ref}>
|
||||
{children}
|
||||
</div>
|
||||
</RowContext.Provider>
|
||||
|
@ -8,6 +8,7 @@
|
||||
display: block;
|
||||
flex: 0 0 percentage((@index / @grid-columns));
|
||||
max-width: percentage((@index / @grid-columns));
|
||||
max-width: calc(percentage((@index / @grid-columns)) - ~'var(--column-gap)');
|
||||
}
|
||||
.@{ant-prefix}-col@{class}-push-@{index} {
|
||||
left: percentage((@index / @grid-columns));
|
||||
|
@ -411,6 +411,99 @@ Array [
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders ./components/input-number/demo/keyboard.md correctly 1`] = `
|
||||
Array [
|
||||
<div
|
||||
class="ant-input-number"
|
||||
>
|
||||
<div
|
||||
class="ant-input-number-handler-wrap"
|
||||
>
|
||||
<span
|
||||
aria-label="Increase Value"
|
||||
class="ant-input-number-handler ant-input-number-handler-up"
|
||||
role="button"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="up"
|
||||
class="anticon anticon-up ant-input-number-handler-up-inner"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="up"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
aria-label="Decrease Value"
|
||||
class="ant-input-number-handler ant-input-number-handler-down"
|
||||
role="button"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down ant-input-number-handler-down-inner"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-input-number-input-wrap"
|
||||
>
|
||||
<input
|
||||
aria-valuemax="10"
|
||||
aria-valuemin="1"
|
||||
aria-valuenow="3"
|
||||
autocomplete="off"
|
||||
class="ant-input-number-input"
|
||||
max="10"
|
||||
min="1"
|
||||
role="spinbutton"
|
||||
step="1"
|
||||
value="3"
|
||||
/>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
style="margin-top:20px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Toggle keyboard
|
||||
</span>
|
||||
</button>
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders ./components/input-number/demo/size.md correctly 1`] = `
|
||||
<div
|
||||
class="site-input-number-wrapper"
|
||||
|
45
components/input-number/demo/keyboard.md
Normal file
45
components/input-number/demo/keyboard.md
Normal file
@ -0,0 +1,45 @@
|
||||
---
|
||||
order: 5
|
||||
title:
|
||||
zh-CN: 键盘行为
|
||||
en-US: Keyboard
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
使用 `keyboard` 属性可以控制键盘行为。
|
||||
|
||||
## en-US
|
||||
|
||||
Control keyboard behavior by `keyboard`.
|
||||
|
||||
```jsx
|
||||
import { InputNumber, Button } from 'antd';
|
||||
|
||||
class App extends React.Component {
|
||||
state = {
|
||||
keyboard: true,
|
||||
};
|
||||
|
||||
toggle = () => {
|
||||
this.setState({
|
||||
keyboard: !this.state.keyboard,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<InputNumber min={1} max={10} keyboard={this.state.keyboard} defaultValue={3} />
|
||||
<div style={{ marginTop: 20 }}>
|
||||
<Button onClick={this.toggle} type="primary">
|
||||
Toggle keyboard
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<App />, mountNode);
|
||||
```
|
@ -20,6 +20,7 @@ When a numeric value needs to be provided.
|
||||
| defaultValue | The initial value | number | - | - |
|
||||
| disabled | If disable the input | boolean | false | - |
|
||||
| formatter | Specifies the format of the value presented | function(value: number \| string): string | - | - |
|
||||
| keyboard | If enable keyboard behavior | boolean | true | 4.12.0 |
|
||||
| max | The max value | number | [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) | - |
|
||||
| min | The min value | number | [Number.MIN_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER) | - |
|
||||
| parser | Specifies the value extracted from formatter | function(string): number | - | - |
|
||||
|
@ -23,6 +23,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/XOS8qZ0kU/InputNumber.svg
|
||||
| defaultValue | 初始值 | number | - | - |
|
||||
| disabled | 禁用 | boolean | false | - |
|
||||
| formatter | 指定输入框展示值的格式 | function(value: number \| string): string | - | - |
|
||||
| keyboard | 是否启用键盘快捷行为 | boolean | true | 4.12.0 |
|
||||
| max | 最大值 | number | [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) | - |
|
||||
| min | 最小值 | number | [Number.MIN_SAFE_INTEGER](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER) | - |
|
||||
| parser | 指定从 `formatter` 里转换回数字的方式,和 `formatter` 搭配使用 | function(string): number | - | - |
|
||||
|
@ -9,6 +9,7 @@ import Button from '../button';
|
||||
import { LegacyButtonType, ButtonProps, convertLegacyProps } from '../button/button';
|
||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||
import { ConfigContext, DirectionType } from '../config-provider';
|
||||
import { canUseDocElement } from '../_util/styleChecker';
|
||||
|
||||
let mousePosition: { x: number; y: number } | null;
|
||||
export const destroyFns: Array<() => void> = [];
|
||||
@ -28,7 +29,7 @@ const getClickPosition = (e: MouseEvent) => {
|
||||
};
|
||||
|
||||
// 只有点击事件支持从鼠标位置动画展开
|
||||
if (typeof window !== 'undefined' && window.document && window.document.documentElement) {
|
||||
if (canUseDocElement()) {
|
||||
document.documentElement.addEventListener('click', getClickPosition, true);
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import { TableProps as RcTableProps, INTERNAL_HOOKS } from 'rc-table/lib/Table';
|
||||
import { convertChildrenToColumns } from 'rc-table/lib/hooks/useColumns';
|
||||
import Spin, { SpinProps } from '../spin';
|
||||
import Pagination from '../pagination';
|
||||
import { TooltipProps } from '../tooltip';
|
||||
import { ConfigContext } from '../config-provider/context';
|
||||
import usePagination, { DEFAULT_PAGE_SIZE, getPaginationParam } from './hooks/usePagination';
|
||||
import useLazyKVMap from './hooks/useLazyKVMap';
|
||||
@ -95,7 +96,7 @@ export interface TableProps<RecordType>
|
||||
scrollToFirstRowOnChange?: boolean;
|
||||
};
|
||||
sortDirections?: SortOrder[];
|
||||
showSorterTooltip?: boolean;
|
||||
showSorterTooltip?: boolean | TooltipProps;
|
||||
}
|
||||
|
||||
function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
|
||||
|
@ -215,6 +215,42 @@ describe('Table.sorter', () => {
|
||||
expect(wrapper.find('.ant-tooltip-open')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should show correct tooltip when showSorterTooltip is an object', () => {
|
||||
// basically copied from 'hover header show sorter tooltip'
|
||||
jest.useFakeTimers();
|
||||
const wrapper = mount(
|
||||
createTable({ showSorterTooltip: { placement: 'bottom', title: 'static title' } }),
|
||||
);
|
||||
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseenter');
|
||||
jest.runAllTimers();
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy();
|
||||
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseout');
|
||||
|
||||
wrapper.setProps({ showSorterTooltip: false });
|
||||
expect(wrapper.find('.ant-table-column-sorters-with-tooltip')).toHaveLength(0);
|
||||
jest.runAllTimers();
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-tooltip-open')).toHaveLength(0);
|
||||
wrapper.setProps({
|
||||
showSorterTooltip: false,
|
||||
columns: [{ ...column, showSorterTooltip: true }],
|
||||
});
|
||||
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseenter');
|
||||
jest.runAllTimers();
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy();
|
||||
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseout');
|
||||
wrapper.setProps({
|
||||
showSorterTooltip: true,
|
||||
columns: [{ ...column, showSorterTooltip: false }],
|
||||
});
|
||||
expect(wrapper.find('.ant-table-column-sorters-with-tooltip')).toHaveLength(0);
|
||||
jest.runAllTimers();
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-tooltip-open')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('works with grouping columns in controlled mode', () => {
|
||||
const columns = [
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
ColumnGroupType,
|
||||
TableLocale,
|
||||
} from '../interface';
|
||||
import Tooltip from '../../tooltip';
|
||||
import Tooltip, { TooltipProps } from '../../tooltip';
|
||||
import { getColumnKey, getColumnPos, renderColumnTitle } from '../util';
|
||||
|
||||
const ASCEND = 'ascend';
|
||||
@ -108,7 +108,7 @@ function injectSorter<RecordType>(
|
||||
triggerSorter: (sorterSates: SortState<RecordType>) => void,
|
||||
defaultSortDirections: SortOrder[],
|
||||
tableLocale?: TableLocale,
|
||||
tableShowSorterTooltip?: boolean,
|
||||
tableShowSorterTooltip?: boolean | TooltipProps,
|
||||
pos?: string,
|
||||
): ColumnsType<RecordType> {
|
||||
return (columns || []).map((column, index) => {
|
||||
@ -146,6 +146,7 @@ function injectSorter<RecordType>(
|
||||
} else if (nextSortOrder === ASCEND) {
|
||||
sortTip = triggerAsc;
|
||||
}
|
||||
const tooltipProps: TooltipProps = typeof showSorterTooltip === 'object' ? showSorterTooltip : { title: sortTip };
|
||||
newColumn = {
|
||||
...newColumn,
|
||||
className: classNames(newColumn.className, { [`${prefixCls}-column-sort`]: sorterOrder }),
|
||||
@ -166,7 +167,7 @@ function injectSorter<RecordType>(
|
||||
</div>
|
||||
);
|
||||
return showSorterTooltip ? (
|
||||
<Tooltip title={sortTip}>
|
||||
<Tooltip {...tooltipProps}>
|
||||
<div className={`${prefixCls}-column-sorters-with-tooltip`}>{renderSortTitle}</div>
|
||||
</Tooltip>
|
||||
) : (
|
||||
@ -306,7 +307,7 @@ interface SorterConfig<RecordType> {
|
||||
) => void;
|
||||
sortDirections: SortOrder[];
|
||||
tableLocale?: TableLocale;
|
||||
showSorterTooltip?: boolean;
|
||||
showSorterTooltip?: boolean | TooltipProps;
|
||||
}
|
||||
|
||||
export default function useFilterSorter<RecordType>({
|
||||
|
@ -75,7 +75,7 @@ const columns = [
|
||||
| rowSelection | Row selection [config](#rowSelection) | object | - | |
|
||||
| scroll | Whether the table can be scrollable, [config](#scroll) | object | - | |
|
||||
| showHeader | Whether to show table header | boolean | true | |
|
||||
| showSorterTooltip | The header show next sorter direction tooltip | boolean | true | |
|
||||
| showSorterTooltip | The header show next sorter direction tooltip. It will be set as the property of Tooltip if its type is object | boolean \| [Tooltip props](/components/tooltip/#API) | true | |
|
||||
| size | Size of table | `default` \| `middle` \| `small` | `default` | |
|
||||
| sortDirections | Supported sort way, could be `ascend`, `descend` | Array | \[`ascend`, `descend`] | |
|
||||
| sticky | Set sticky header and scroll bar | boolean \| `{offsetHeader?: number, offsetScroll?: number, getContainer?: () => HTMLElement}` | - | 4.6.0 (getContainer: 4.7.0) |
|
||||
@ -134,7 +134,7 @@ One of the Table `columns` prop for describing the table's columns, Column has t
|
||||
| render | Renderer of the table cell. The return value should be a ReactNode, or an object for [colSpan/rowSpan config](#components-table-demo-colspan-rowspan) | function(text, record, index) {} | - | | |
|
||||
| responsive | The list of breakpoints at which to display this column. Always visible if not set. | [Breakpoint](https://github.com/ant-design/ant-design/blob/015109b42b85c63146371b4e32b883cf97b088e8/components/_util/responsiveObserve.ts#L1)\[] | - | 4.2.0 | |
|
||||
| shouldCellUpdate | Control cell render logic | (record, prevRecord) => boolean | - | 4.3.0 | |
|
||||
| showSorterTooltip | If header show next sorter direction tooltip, override `showSorterTooltip` in table | boolean | true | | |
|
||||
| showSorterTooltip | If header show next sorter direction tooltip, override `showSorterTooltip` in table | boolean \| [Tooltip props](/components/tooltip/) | true | | |
|
||||
| sortDirections | Supported sort way, override `sortDirections` in `Table`, could be `ascend`, `descend` | Array | \[`ascend`, `descend`] | | |
|
||||
| sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set to `true` | function \| boolean | - | | |
|
||||
| sortOrder | Order of sorted values: `'ascend'` `'descend'` `false` | boolean \| string | - | | |
|
||||
|
@ -82,7 +82,7 @@ const columns = [
|
||||
| rowSelection | 表格行是否可选择,[配置项](#rowSelection) | object | - | |
|
||||
| scroll | 表格是否可滚动,也可以指定滚动区域的宽、高,[配置项](#scroll) | object | - | |
|
||||
| showHeader | 是否显示表头 | boolean | true | |
|
||||
| showSorterTooltip | 表头是否显示下一次排序的 tooltip 提示 | boolean | true | |
|
||||
| showSorterTooltip | 表头是否显示下一次排序的 tooltip 提示。当参数类型为对象时,将被设置为 Tooltip 的属性 | boolean \| [Tooltip props](/components/tooltip/) | true | |
|
||||
| size | 表格大小 | `default` \| `middle` \| `small` | default | |
|
||||
| sortDirections | 支持的排序方式,取值为 `ascend` `descend` | Array | \[`ascend`, `descend`] | |
|
||||
| sticky | 设置粘性头部和滚动条 | boolean \| `{offsetHeader?: number, offsetScroll?: number, getContainer?: () => HTMLElement}` | - | 4.6.0 (getContainer: 4.7.0) |
|
||||
@ -141,7 +141,7 @@ const columns = [
|
||||
| render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return 里面可以设置表格[行/列合并](#components-table-demo-colspan-rowspan) | function(text, record, index) {} | - | |
|
||||
| responsive | 响应式 breakpoint 配置列表。未设置则始终可见。 | [Breakpoint](https://github.com/ant-design/ant-design/blob/015109b42b85c63146371b4e32b883cf97b088e8/components/_util/responsiveObserve.ts#L1)\[] | - | 4.2.0 |
|
||||
| shouldCellUpdate | 自定义单元格渲染时机 | (record, prevRecord) => boolean | - | 4.3.0 |
|
||||
| showSorterTooltip | 表头显示下一次排序的 tooltip 提示, 覆盖 table 中 `showSorterTooltip` | boolean | true | |
|
||||
| showSorterTooltip | 表头显示下一次排序的 tooltip 提示, 覆盖 table 中 `showSorterTooltip` | boolean \| [Tooltip props](/components/tooltip/#API) | true | |
|
||||
| sortDirections | 支持的排序方式,覆盖 `Table` 中 `sortDirections`, 取值为 `ascend` `descend` | Array | \[`ascend`, `descend`] | |
|
||||
| sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | function \| boolean | - | |
|
||||
| sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `ascend` `descend` false | boolean \| string | - | |
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
RenderedCell as RcRenderedCell,
|
||||
ExpandableConfig,
|
||||
} from 'rc-table/lib/interface';
|
||||
import { TooltipProps } from '../tooltip';
|
||||
import { CheckboxProps } from '../checkbox';
|
||||
import { PaginationProps } from '../pagination';
|
||||
import { Breakpoint } from '../_util/responsiveObserve';
|
||||
@ -95,7 +96,7 @@ export interface ColumnType<RecordType> extends RcColumnType<RecordType> {
|
||||
sortOrder?: SortOrder;
|
||||
defaultSortOrder?: SortOrder;
|
||||
sortDirections?: SortOrder[];
|
||||
showSorterTooltip?: boolean;
|
||||
showSorterTooltip?: boolean | TooltipProps;
|
||||
|
||||
// Filter
|
||||
filtered?: boolean;
|
||||
|
@ -126,7 +126,7 @@
|
||||
"rc-dropdown": "~3.2.0",
|
||||
"rc-field-form": "~1.18.0",
|
||||
"rc-image": "~5.1.1",
|
||||
"rc-input-number": "~6.1.0",
|
||||
"rc-input-number": "~6.2.0",
|
||||
"rc-mentions": "~1.5.0",
|
||||
"rc-menu": "~8.10.0",
|
||||
"rc-motion": "^2.4.0",
|
||||
|
Loading…
Reference in New Issue
Block a user