mirror of
https://github.com/ant-design/ant-design.git
synced 2025-01-19 14:53:16 +08:00
Merge pull request #18327 from ant-design/feature
Merge feature into master
This commit is contained in:
commit
cfa73249db
13
components/_util/__tests__/easings.test.js
Normal file
13
components/_util/__tests__/easings.test.js
Normal file
@ -0,0 +1,13 @@
|
||||
import { easeInOutCubic } from '../easings';
|
||||
|
||||
describe('Test easings', () => {
|
||||
it('easeInOutCubic return value', () => {
|
||||
const nums = [];
|
||||
// eslint-disable-next-line no-plusplus
|
||||
for (let index = 0; index < 5; index++) {
|
||||
nums.push(easeInOutCubic(index, 1, 5, 4));
|
||||
}
|
||||
|
||||
expect(nums).toEqual([1, 1.25, 3, 4.75, 5]);
|
||||
});
|
||||
});
|
56
components/_util/__tests__/scrollTo.test.js
Normal file
56
components/_util/__tests__/scrollTo.test.js
Normal file
@ -0,0 +1,56 @@
|
||||
import scrollTo from '../scrollTo';
|
||||
|
||||
describe('Test ScrollTo function', () => {
|
||||
let dateNowMock;
|
||||
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
dateNowMock = jest
|
||||
.spyOn(Date, 'now')
|
||||
.mockImplementationOnce(() => 0)
|
||||
.mockImplementationOnce(() => 1000);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
dateNowMock.mockRestore();
|
||||
});
|
||||
|
||||
it('test scrollTo', async () => {
|
||||
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
|
||||
window.scrollY = y;
|
||||
window.pageYOffset = y;
|
||||
});
|
||||
|
||||
scrollTo(1000);
|
||||
|
||||
jest.runAllTimers();
|
||||
expect(window.pageYOffset).toBe(1000);
|
||||
|
||||
scrollToSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('test callback - option', async () => {
|
||||
const cbMock = jest.fn();
|
||||
scrollTo(1000, {
|
||||
callback: cbMock,
|
||||
});
|
||||
jest.runAllTimers();
|
||||
expect(cbMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('test getContainer - option', async () => {
|
||||
const div = document.createElement('div');
|
||||
scrollTo(1000, {
|
||||
getContainer: () => div,
|
||||
});
|
||||
jest.runAllTimers();
|
||||
expect(div.scrollTop).toBe(1000);
|
||||
});
|
||||
});
|
9
components/_util/easings.ts
Normal file
9
components/_util/easings.ts
Normal file
@ -0,0 +1,9 @@
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export function easeInOutCubic(t: number, b: number, c: number, d: number) {
|
||||
const cc = c - b;
|
||||
t /= d / 2;
|
||||
if (t < 1) {
|
||||
return (cc / 2) * t * t * t + b;
|
||||
}
|
||||
return (cc / 2) * ((t -= 2) * t * t + 2) + b;
|
||||
}
|
37
components/_util/scrollTo.ts
Normal file
37
components/_util/scrollTo.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import raf from 'raf';
|
||||
import getScroll from './getScroll';
|
||||
import { easeInOutCubic } from './easings';
|
||||
|
||||
interface ScrollToOptions {
|
||||
/** Scroll container, default as window */
|
||||
getContainer?: () => HTMLElement | Window;
|
||||
/** Scroll end callback */
|
||||
callback?: () => any;
|
||||
/** Animation duration, default as 450 */
|
||||
duration?: number;
|
||||
}
|
||||
|
||||
export default function scrollTo(y: number, options: ScrollToOptions = {}) {
|
||||
const { getContainer = () => window, callback, duration = 450 } = options;
|
||||
|
||||
const container = getContainer();
|
||||
const scrollTop = getScroll(container, true);
|
||||
const startTime = Date.now();
|
||||
|
||||
const frameFunc = () => {
|
||||
const timestamp = Date.now();
|
||||
const time = timestamp - startTime;
|
||||
const nextScrollTop = easeInOutCubic(time > duration ? duration : time, scrollTop, y, duration);
|
||||
if (container === window) {
|
||||
window.scrollTo(window.pageXOffset, nextScrollTop);
|
||||
} else {
|
||||
(container as HTMLElement).scrollTop = nextScrollTop;
|
||||
}
|
||||
if (time < duration) {
|
||||
raf(frameFunc);
|
||||
} else if (typeof callback === 'function') {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
raf(frameFunc);
|
||||
}
|
@ -3,10 +3,10 @@ import * as ReactDOM from 'react-dom';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
import raf from 'raf';
|
||||
import Affix from '../affix';
|
||||
import AnchorLink from './AnchorLink';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import scrollTo from '../_util/scrollTo';
|
||||
import getScroll from '../_util/getScroll';
|
||||
|
||||
function getDefaultContainer() {
|
||||
@ -35,52 +35,7 @@ function getOffsetTop(element: HTMLElement, container: AnchorContainer): number
|
||||
return rect.top;
|
||||
}
|
||||
|
||||
function easeInOutCubic(t: number, b: number, c: number, d: number) {
|
||||
const cc = c - b;
|
||||
t /= d / 2;
|
||||
if (t < 1) {
|
||||
return (cc / 2) * t * t * t + b;
|
||||
}
|
||||
return (cc / 2) * ((t -= 2) * t * t + 2) + b;
|
||||
}
|
||||
|
||||
const sharpMatcherRegx = /#([^#]+)$/;
|
||||
function scrollTo(
|
||||
href: string,
|
||||
offsetTop = 0,
|
||||
getContainer: () => AnchorContainer,
|
||||
callback = () => {},
|
||||
) {
|
||||
const container = getContainer();
|
||||
const scrollTop = getScroll(container, true);
|
||||
const sharpLinkMatch = sharpMatcherRegx.exec(href);
|
||||
if (!sharpLinkMatch) {
|
||||
return;
|
||||
}
|
||||
const targetElement = document.getElementById(sharpLinkMatch[1]);
|
||||
if (!targetElement) {
|
||||
return;
|
||||
}
|
||||
const eleOffsetTop = getOffsetTop(targetElement, container);
|
||||
const targetScrollTop = scrollTop + eleOffsetTop - offsetTop;
|
||||
const startTime = Date.now();
|
||||
const frameFunc = () => {
|
||||
const timestamp = Date.now();
|
||||
const time = timestamp - startTime;
|
||||
const nextScrollTop = easeInOutCubic(time, scrollTop, targetScrollTop, 450);
|
||||
if (container === window) {
|
||||
window.scrollTo(window.pageXOffset, nextScrollTop);
|
||||
} else {
|
||||
(container as HTMLElement).scrollTop = nextScrollTop;
|
||||
}
|
||||
if (time < 450) {
|
||||
raf(frameFunc);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
raf(frameFunc);
|
||||
}
|
||||
|
||||
type Section = {
|
||||
link: string;
|
||||
@ -99,10 +54,14 @@ export interface AnchorProps {
|
||||
affix?: boolean;
|
||||
showInkInFixed?: boolean;
|
||||
getContainer?: () => AnchorContainer;
|
||||
/** Return customize highlight anchor */
|
||||
getCurrentAnchor?: () => string;
|
||||
onClick?: (
|
||||
e: React.MouseEvent<HTMLElement>,
|
||||
link: { title: React.ReactNode; href: string },
|
||||
) => void;
|
||||
/** Scroll to target offset value, if none, it's offsetTop prop value or 0. */
|
||||
targetOffset?: number;
|
||||
}
|
||||
|
||||
export interface AnchorState {
|
||||
@ -205,6 +164,12 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState> {
|
||||
}
|
||||
|
||||
getCurrentAnchor(offsetTop = 0, bounds = 5): string {
|
||||
const { getCurrentAnchor } = this.props;
|
||||
|
||||
if (typeof getCurrentAnchor === 'function') {
|
||||
return getCurrentAnchor();
|
||||
}
|
||||
|
||||
const activeLink = '';
|
||||
if (typeof document === 'undefined') {
|
||||
return activeLink;
|
||||
@ -237,6 +202,34 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState> {
|
||||
return '';
|
||||
}
|
||||
|
||||
handleScrollTo = (link: string) => {
|
||||
const { offsetTop, getContainer, targetOffset } = this.props as AnchorDefaultProps;
|
||||
|
||||
this.setState({ activeLink: link });
|
||||
const container = getContainer();
|
||||
const scrollTop = getScroll(container, true);
|
||||
const sharpLinkMatch = sharpMatcherRegx.exec(link);
|
||||
if (!sharpLinkMatch) {
|
||||
return;
|
||||
}
|
||||
const targetElement = document.getElementById(sharpLinkMatch[1]);
|
||||
if (!targetElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
const eleOffsetTop = getOffsetTop(targetElement, container);
|
||||
let y = scrollTop + eleOffsetTop;
|
||||
y -= targetOffset !== undefined ? targetOffset : offsetTop || 0;
|
||||
this.animating = true;
|
||||
|
||||
scrollTo(y, {
|
||||
callback: () => {
|
||||
this.animating = false;
|
||||
},
|
||||
getContainer,
|
||||
});
|
||||
};
|
||||
|
||||
saveInkNode = (node: HTMLSpanElement) => {
|
||||
this.inkNode = node;
|
||||
};
|
||||
@ -246,8 +239,11 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState> {
|
||||
return;
|
||||
}
|
||||
const { activeLink } = this.state;
|
||||
const { offsetTop, bounds } = this.props;
|
||||
const currentActiveLink = this.getCurrentAnchor(offsetTop, bounds);
|
||||
const { offsetTop, bounds, targetOffset } = this.props;
|
||||
const currentActiveLink = this.getCurrentAnchor(
|
||||
targetOffset !== undefined ? targetOffset : offsetTop || 0,
|
||||
bounds,
|
||||
);
|
||||
if (activeLink !== currentActiveLink) {
|
||||
this.setState({
|
||||
activeLink: currentActiveLink,
|
||||
@ -255,15 +251,6 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState> {
|
||||
}
|
||||
};
|
||||
|
||||
handleScrollTo = (link: string) => {
|
||||
const { offsetTop, getContainer } = this.props as AnchorDefaultProps;
|
||||
this.animating = true;
|
||||
this.setState({ activeLink: link });
|
||||
scrollTo(link, offsetTop, getContainer, () => {
|
||||
this.animating = false;
|
||||
});
|
||||
};
|
||||
|
||||
updateInk = () => {
|
||||
if (typeof document === 'undefined') {
|
||||
return;
|
||||
|
@ -1,12 +1,29 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import Anchor from '..';
|
||||
import { spyElementPrototypes } from '../../__tests__/util/domHook';
|
||||
import { sleep } from '../../../tests/utils';
|
||||
|
||||
const { Link } = Anchor;
|
||||
|
||||
const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));
|
||||
|
||||
describe('Anchor Render', () => {
|
||||
const getBoundingClientRectMock = jest.fn(() => ({
|
||||
width: 100,
|
||||
height: 100,
|
||||
top: 1000,
|
||||
}));
|
||||
const getClientRectsMock = jest.fn(() => ({
|
||||
length: 1,
|
||||
}));
|
||||
const headingSpy = spyElementPrototypes(HTMLHeadingElement, {
|
||||
getBoundingClientRect: getBoundingClientRectMock,
|
||||
getClientRects: getClientRectsMock,
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
headingSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('Anchor render perfectly', () => {
|
||||
const wrapper = mount(
|
||||
<Anchor>
|
||||
@ -64,7 +81,7 @@ describe('Anchor Render', () => {
|
||||
wrapper.instance().handleScrollTo('##API');
|
||||
expect(wrapper.instance().state.activeLink).toBe('##API');
|
||||
expect(scrollToSpy).not.toHaveBeenCalled();
|
||||
await delay(1000);
|
||||
await sleep(1000);
|
||||
expect(scrollToSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -154,7 +171,7 @@ describe('Anchor Render', () => {
|
||||
</Anchor>,
|
||||
);
|
||||
const removeListenerSpy = jest.spyOn(wrapper.instance().scrollEvent, 'remove');
|
||||
await delay(1000);
|
||||
await sleep(1000);
|
||||
wrapper.setProps({ getContainer: getContainerB });
|
||||
expect(removeListenerSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
@ -187,7 +204,7 @@ describe('Anchor Render', () => {
|
||||
);
|
||||
const removeListenerSpy = jest.spyOn(wrapper.instance().scrollEvent, 'remove');
|
||||
expect(removeListenerSpy).not.toHaveBeenCalled();
|
||||
await delay(1000);
|
||||
await sleep(1000);
|
||||
wrapper.setProps({ getContainer: getContainerB });
|
||||
expect(removeListenerSpy).toHaveBeenCalled();
|
||||
});
|
||||
@ -239,9 +256,67 @@ describe('Anchor Render', () => {
|
||||
);
|
||||
const removeListenerSpy = jest.spyOn(wrapper.instance().scrollEvent, 'remove');
|
||||
expect(removeListenerSpy).not.toHaveBeenCalled();
|
||||
await delay(1000);
|
||||
await sleep(1000);
|
||||
holdContainer.container = document.getElementById('API2');
|
||||
wrapper.setProps({ 'data-only-trigger-re-render': true });
|
||||
expect(removeListenerSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Anchor getCurrentAnchor prop', () => {
|
||||
const getCurrentAnchor = () => '#API2';
|
||||
const wrapper = mount(
|
||||
<Anchor getCurrentAnchor={getCurrentAnchor}>
|
||||
<Link href="#API1" title="API1" />
|
||||
<Link href="#API2" title="API2" />
|
||||
</Anchor>,
|
||||
);
|
||||
expect(wrapper.instance().state.activeLink).toBe('#API2');
|
||||
});
|
||||
|
||||
it('Anchor targetOffset prop', async () => {
|
||||
jest.useFakeTimers();
|
||||
|
||||
let dateNowMock;
|
||||
|
||||
function dataNowMockFn() {
|
||||
return jest
|
||||
.spyOn(Date, 'now')
|
||||
.mockImplementationOnce(() => 0)
|
||||
.mockImplementationOnce(() => 1000);
|
||||
}
|
||||
|
||||
dateNowMock = dataNowMockFn();
|
||||
|
||||
const scrollToSpy = jest.spyOn(window, 'scrollTo');
|
||||
let root = document.getElementById('root');
|
||||
if (!root) {
|
||||
root = document.createElement('div', { id: 'root' });
|
||||
root.id = 'root';
|
||||
document.body.appendChild(root);
|
||||
}
|
||||
mount(<h1 id="API">Hello</h1>, { attachTo: root });
|
||||
const wrapper = mount(
|
||||
<Anchor>
|
||||
<Link href="#API" title="API" />
|
||||
</Anchor>,
|
||||
);
|
||||
wrapper.instance().handleScrollTo('#API');
|
||||
jest.runAllTimers();
|
||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 1000);
|
||||
dateNowMock = dataNowMockFn();
|
||||
|
||||
wrapper.setProps({ offsetTop: 100 });
|
||||
wrapper.instance().handleScrollTo('#API');
|
||||
jest.runAllTimers();
|
||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 900);
|
||||
dateNowMock = dataNowMockFn();
|
||||
|
||||
wrapper.setProps({ targetOffset: 200 });
|
||||
wrapper.instance().handleScrollTo('#API');
|
||||
jest.runAllTimers();
|
||||
expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800);
|
||||
|
||||
dateNowMock.mockRestore();
|
||||
jest.useRealTimers();
|
||||
});
|
||||
});
|
||||
|
@ -80,6 +80,80 @@ exports[`renders ./components/anchor/demo/basic.md correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/anchor/demo/customizeHighlight.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-anchor-wrapper"
|
||||
style="max-height:100vh"
|
||||
>
|
||||
<div
|
||||
class="ant-anchor fixed"
|
||||
>
|
||||
<div
|
||||
class="ant-anchor-ink"
|
||||
>
|
||||
<span
|
||||
class="ant-anchor-ink-ball"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#components-anchor-demo-basic"
|
||||
title="Basic demo"
|
||||
>
|
||||
Basic demo
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#components-anchor-demo-static"
|
||||
title="Static demo"
|
||||
>
|
||||
Static demo
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#API"
|
||||
title="API"
|
||||
>
|
||||
API
|
||||
</a>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#Anchor-Props"
|
||||
title="Anchor Props"
|
||||
>
|
||||
Anchor Props
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#Link-Props"
|
||||
title="Link Props"
|
||||
>
|
||||
Link Props
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/anchor/demo/onClick.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-anchor-wrapper"
|
||||
@ -227,3 +301,83 @@ exports[`renders ./components/anchor/demo/static.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/anchor/demo/targetOffset.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="ant-anchor-wrapper"
|
||||
style="max-height:100vh"
|
||||
>
|
||||
<div
|
||||
class="ant-anchor"
|
||||
>
|
||||
<div
|
||||
class="ant-anchor-ink"
|
||||
>
|
||||
<span
|
||||
class="ant-anchor-ink-ball"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#components-anchor-demo-basic"
|
||||
title="Basic demo"
|
||||
>
|
||||
Basic demo
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#components-anchor-demo-static"
|
||||
title="Static demo"
|
||||
>
|
||||
Static demo
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#API"
|
||||
title="API"
|
||||
>
|
||||
API
|
||||
</a>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#Anchor-Props"
|
||||
title="Anchor Props"
|
||||
>
|
||||
Anchor Props
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#Link-Props"
|
||||
title="Link Props"
|
||||
>
|
||||
Link Props
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
36
components/anchor/demo/customizeHighlight.md
Normal file
36
components/anchor/demo/customizeHighlight.md
Normal file
@ -0,0 +1,36 @@
|
||||
---
|
||||
order: 4
|
||||
title:
|
||||
zh-CN: 自定义锚点高亮
|
||||
en-US: Customize the anchor highlight
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
自定义锚点高亮。
|
||||
|
||||
## en-US
|
||||
|
||||
Customize the anchor highlight.
|
||||
|
||||
```jsx
|
||||
import { Anchor } from 'antd';
|
||||
|
||||
const { Link } = Anchor;
|
||||
|
||||
const getCurrentAnchor = () => {
|
||||
return '#components-anchor-demo-static';
|
||||
};
|
||||
|
||||
ReactDOM.render(
|
||||
<Anchor affix={false} getCurrentAnchor={getCurrentAnchor}>
|
||||
<Link href="#components-anchor-demo-basic" title="Basic demo" />
|
||||
<Link href="#components-anchor-demo-static" title="Static demo" />
|
||||
<Link href="#API" title="API">
|
||||
<Link href="#Anchor-Props" title="Anchor Props" />
|
||||
<Link href="#Link-Props" title="Link Props" />
|
||||
</Link>
|
||||
</Anchor>,
|
||||
mountNode,
|
||||
);
|
||||
```
|
47
components/anchor/demo/targetOffset.md
Normal file
47
components/anchor/demo/targetOffset.md
Normal file
@ -0,0 +1,47 @@
|
||||
---
|
||||
order: 4
|
||||
title:
|
||||
zh-CN: 设置锚点滚动偏移量
|
||||
en-US: Set Anchor scroll offset
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
锚点目标滚动到屏幕正中间。
|
||||
|
||||
## en-US
|
||||
|
||||
Anchor target scroll to screen center.
|
||||
|
||||
```jsx
|
||||
import { Anchor } from 'antd';
|
||||
|
||||
const { Link } = Anchor;
|
||||
|
||||
class AnchorExample extends React.Component {
|
||||
state = {
|
||||
targetOffset: undefined,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
targetOffset: window.innerHeight / 2,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Anchor targetOffset={this.state.targetOffset}>
|
||||
<Link href="#components-anchor-demo-basic" title="Basic demo" />
|
||||
<Link href="#components-anchor-demo-static" title="Static demo" />
|
||||
<Link href="#API" title="API">
|
||||
<Link href="#Anchor-Props" title="Anchor Props" />
|
||||
<Link href="#Link-Props" title="Link Props" />
|
||||
</Link>
|
||||
</Anchor>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<AnchorExample />, mountNode);
|
||||
```
|
@ -24,6 +24,8 @@ For displaying anchor hyperlinks on page and jumping between them.
|
||||
| offsetTop | Pixels to offset from top when calculating position of scroll | number | 0 | |
|
||||
| showInkInFixed | Whether show ink-balls in Fixed mode | boolean | false | |
|
||||
| onClick | set the handler to handle `click` event | Function(e: Event, link: Object) | - | 3.9.0 |
|
||||
| getCurrentAnchor | Customize the anchor highlight | () => string | - | 3.21.0 |
|
||||
| targetOffset | Anchor scroll offset, default as `offsetTop`, [example](#components-anchor-demo-targetOffset) | number | `offsetTop` | 3.22.0 |
|
||||
|
||||
### Link Props
|
||||
|
||||
|
@ -25,6 +25,8 @@ title: Anchor
|
||||
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | | |
|
||||
| showInkInFixed | 固定模式是否显示小圆点 | boolean | false | |
|
||||
| onClick | `click` 事件的 handler | Function(e: Event, link: Object) | - | 3.9.0 |
|
||||
| getCurrentAnchor | 自定义高亮的锚点 | () => string | - | 3.21.0 |
|
||||
| targetOffset | 锚点滚动偏移量,默认与 offsetTop 相同,[例子](#components-anchor-demo-targetOffset) | number | `offsetTop` | 3.22.0 |
|
||||
|
||||
### Link Props
|
||||
|
||||
|
@ -1,16 +1,22 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { sleep } from '../../../tests/utils';
|
||||
import BackTop from '..';
|
||||
|
||||
describe('BackTop', () => {
|
||||
it('should scroll to top after click it', async () => {
|
||||
const wrapper = mount(<BackTop visibilityHeight={-1} />);
|
||||
document.documentElement.scrollTop = 400;
|
||||
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
|
||||
window.scrollY = y;
|
||||
window.pageYOffset = y;
|
||||
});
|
||||
window.scrollTo(0, 400);
|
||||
// trigger scroll manually
|
||||
wrapper.instance().handleScroll();
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
await sleep();
|
||||
wrapper.find('.ant-back-top').simulate('click');
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
expect(Math.abs(Math.round(document.documentElement.scrollTop))).toBe(0);
|
||||
await sleep(500);
|
||||
expect(window.pageYOffset).toBe(0);
|
||||
scrollToSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
@ -3,20 +3,9 @@ import Animate from 'rc-animate';
|
||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'omit.js';
|
||||
import raf from 'raf';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import getScroll from '../_util/getScroll';
|
||||
|
||||
const easeInOutCubic = (t: number, b: number, c: number, d: number) => {
|
||||
const cc = c - b;
|
||||
t /= d / 2;
|
||||
if (t < 1) {
|
||||
return (cc / 2) * t * t * t + b;
|
||||
}
|
||||
return (cc / 2) * ((t -= 2) * t * t + 2) + b;
|
||||
};
|
||||
|
||||
function noop() {}
|
||||
import scrollTo from '../_util/scrollTo';
|
||||
|
||||
function getDefaultTarget() {
|
||||
return window;
|
||||
@ -79,21 +68,14 @@ export default class BackTop extends React.Component<BackTopProps, any> {
|
||||
};
|
||||
|
||||
scrollToTop = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
const scrollTop = this.getCurrentScrollTop();
|
||||
const startTime = Date.now();
|
||||
const frameFunc = () => {
|
||||
const timestamp = Date.now();
|
||||
const time = timestamp - startTime;
|
||||
this.setScrollTop(easeInOutCubic(time, scrollTop, 0, 450));
|
||||
if (time < 450) {
|
||||
raf(frameFunc);
|
||||
} else {
|
||||
this.setScrollTop(0);
|
||||
const { target = getDefaultTarget } = this.props;
|
||||
scrollTo(0, {
|
||||
getContainer: target,
|
||||
});
|
||||
if (typeof this.props.onClick === 'function') {
|
||||
this.props.onClick(e);
|
||||
}
|
||||
};
|
||||
raf(frameFunc);
|
||||
(this.props.onClick || noop)(e);
|
||||
};
|
||||
|
||||
handleScroll = () => {
|
||||
const { visibilityHeight, target = getDefaultTarget } = this.props;
|
||||
|
3
components/calendar/locale/ro_RO.tsx
Normal file
3
components/calendar/locale/ro_RO.tsx
Normal file
@ -0,0 +1,3 @@
|
||||
import ro_RO from '../../date-picker/locale/ro_RO';
|
||||
|
||||
export default ro_RO;
|
@ -11357,7 +11357,10 @@ exports[`ConfigProvider components Steps configProvider 1`] = `
|
||||
class="config-steps config-steps-horizontal config-steps-label-horizontal"
|
||||
>
|
||||
<div
|
||||
class="config-steps-item config-steps-item-process"
|
||||
class="config-steps-item config-steps-item-process config-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="config-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="config-steps-item-tail"
|
||||
@ -11387,6 +11390,7 @@ exports[`ConfigProvider components Steps configProvider 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ConfigProvider components Steps normal 1`] = `
|
||||
@ -11394,7 +11398,10 @@ exports[`ConfigProvider components Steps normal 1`] = `
|
||||
class="ant-steps ant-steps-horizontal ant-steps-label-horizontal"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process"
|
||||
class="ant-steps-item ant-steps-item-process ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -11424,6 +11431,7 @@ exports[`ConfigProvider components Steps normal 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ConfigProvider components Steps prefixCls 1`] = `
|
||||
@ -11431,7 +11439,10 @@ exports[`ConfigProvider components Steps prefixCls 1`] = `
|
||||
class="prefix-Steps prefix-Steps-horizontal prefix-Steps-label-horizontal"
|
||||
>
|
||||
<div
|
||||
class="prefix-Steps-item prefix-Steps-item-process"
|
||||
class="prefix-Steps-item prefix-Steps-item-process prefix-Steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="prefix-Steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="prefix-Steps-item-tail"
|
||||
@ -11461,6 +11472,7 @@ exports[`ConfigProvider components Steps prefixCls 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ConfigProvider components Switch configProvider 1`] = `
|
||||
|
19
components/date-picker/locale/ro_RO.tsx
Normal file
19
components/date-picker/locale/ro_RO.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import CalendarLocale from 'rc-calendar/lib/locale/ro_RO';
|
||||
import TimePickerLocale from '../../time-picker/locale/ro_RO';
|
||||
|
||||
// Merge into a locale object
|
||||
const locale = {
|
||||
lang: {
|
||||
placeholder: 'Selectează data',
|
||||
rangePlaceholder: ['Data start', 'Data sfârșit'],
|
||||
...CalendarLocale,
|
||||
},
|
||||
timePickerLocale: {
|
||||
...TimePickerLocale,
|
||||
},
|
||||
};
|
||||
|
||||
// All settings at:
|
||||
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||
|
||||
export default locale;
|
@ -579,6 +579,123 @@ exports[`renders ./components/descriptions/demo/size.md correctly 1`] = `
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<div
|
||||
class="ant-descriptions"
|
||||
>
|
||||
<div
|
||||
class="ant-descriptions-title"
|
||||
>
|
||||
Custom Size
|
||||
</div>
|
||||
<div
|
||||
class="ant-descriptions-view"
|
||||
>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Product
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
Cloud Database
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Billing
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
Prepaid
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
time
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
18:00:00
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Amount
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
$80.00
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Discount
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
$20.00
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Official
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
$60.00
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
@ -59,6 +59,16 @@ class Demo extends React.Component {
|
||||
Region: East China 1<br />
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<br />
|
||||
<br />
|
||||
<Descriptions title="Custom Size" border size={this.state.size}>
|
||||
<Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
|
||||
<Descriptions.Item label="Billing">Prepaid</Descriptions.Item>
|
||||
<Descriptions.Item label="time">18:00:00</Descriptions.Item>
|
||||
<Descriptions.Item label="Amount">$80.00</Descriptions.Item>
|
||||
<Descriptions.Item label="Discount">$20.00</Descriptions.Item>
|
||||
<Descriptions.Item label="Official">$60.00</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -30,3 +30,5 @@ Commonly displayed on the details page.
|
||||
| -------- | ------------------------------ | --------- | ------- | ------- |
|
||||
| label | description of the content | ReactNode | - | 3.19.0 |
|
||||
| span | The number of columns included | number | 1 | 3.19.0 |
|
||||
|
||||
> The number of span Description.Item. Span={2} takes up the width of two DescriptionItems.
|
||||
|
@ -31,3 +31,5 @@ cols: 1
|
||||
| ----- | ------------ | --------- | ------ | ------ |
|
||||
| label | 内容的描述 | ReactNode | - | 3.19.0 |
|
||||
| span | 包含列的数量 | number | 1 | 3.19.0 |
|
||||
|
||||
> span Description.Item 的数量。 span={2} 会占用两个 DescriptionItem 的宽度。
|
||||
|
@ -78,6 +78,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-middle {
|
||||
.@{descriptions-prefix-cls}-row {
|
||||
> th,
|
||||
> td {
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-small {
|
||||
.@{descriptions-prefix-cls}-row {
|
||||
> th,
|
||||
> td {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-bordered {
|
||||
.@{descriptions-prefix-cls}-view {
|
||||
border: 1px solid @border-color-split;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -50,6 +50,7 @@ import nlNL from '../nl_NL';
|
||||
import plPL from '../pl_PL';
|
||||
import ptBR from '../pt_BR';
|
||||
import ptPT from '../pt_PT';
|
||||
import roRO from '../ro_RO';
|
||||
import ruRU from '../ru_RU';
|
||||
import skSK from '../sk_SK';
|
||||
import slSI from '../sl_SI';
|
||||
@ -99,6 +100,7 @@ const locales = [
|
||||
plPL,
|
||||
ptBR,
|
||||
ptPT,
|
||||
roRO,
|
||||
ruRU,
|
||||
skSK,
|
||||
slSI,
|
||||
|
3
components/locale-provider/ro_RO.tsx
Normal file
3
components/locale-provider/ro_RO.tsx
Normal file
@ -0,0 +1,3 @@
|
||||
import locale from '../locale/ro_RO';
|
||||
|
||||
export default locale;
|
61
components/locale/ro_RO.tsx
Normal file
61
components/locale/ro_RO.tsx
Normal file
@ -0,0 +1,61 @@
|
||||
import Pagination from 'rc-pagination/lib/locale/ro_RO';
|
||||
import DatePicker from '../date-picker/locale/ro_RO';
|
||||
import TimePicker from '../time-picker/locale/ro_RO';
|
||||
import Calendar from '../calendar/locale/ro_RO';
|
||||
|
||||
export default {
|
||||
locale: 'ro',
|
||||
Pagination,
|
||||
DatePicker,
|
||||
TimePicker,
|
||||
Calendar,
|
||||
global: {
|
||||
placeholder: 'Selectează',
|
||||
},
|
||||
Table: {
|
||||
filterTitle: 'Filtrează',
|
||||
filterConfirm: 'OK',
|
||||
filterReset: 'Resetează',
|
||||
selectAll: 'Selectează pagina curentă',
|
||||
selectInvert: 'Inversează pagina curentă',
|
||||
sortTitle: 'Ordonează',
|
||||
expand: 'Extinde rândul',
|
||||
collapse: 'Micșorează rândul',
|
||||
},
|
||||
Modal: {
|
||||
okText: 'OK',
|
||||
cancelText: 'Anulare',
|
||||
justOkText: 'OK',
|
||||
},
|
||||
Popconfirm: {
|
||||
okText: 'OK',
|
||||
cancelText: 'Anulare',
|
||||
},
|
||||
Transfer: {
|
||||
titles: ['', ''],
|
||||
searchPlaceholder: 'Căutare',
|
||||
itemUnit: 'element',
|
||||
itemsUnit: 'elemente',
|
||||
},
|
||||
Upload: {
|
||||
uploading: 'Se transferă...',
|
||||
removeFile: 'Înlătură fișierul',
|
||||
uploadError: 'Eroare la upload',
|
||||
previewFile: 'Previzualizare fișier',
|
||||
},
|
||||
Empty: {
|
||||
description: 'Fără date',
|
||||
},
|
||||
Icon: {
|
||||
icon: 'icon',
|
||||
},
|
||||
Text: {
|
||||
edit: 'editează',
|
||||
copy: 'copiază',
|
||||
copied: 'copiat',
|
||||
expand: 'extinde',
|
||||
},
|
||||
PageHeader: {
|
||||
back: 'înapoi',
|
||||
},
|
||||
};
|
@ -38,6 +38,7 @@ When need to mention someone or something.
|
||||
| onSearch | Trigger when prefix hit | (text: string, prefix: string) => void | - | 3.19.0 |
|
||||
| onFocus | Trigger when mentions get focus | () => void | - | 3.19.0 |
|
||||
| onBlur | Trigger when mentions lose focus | () => void | - | 3.19.0 |
|
||||
| getPopupContainer | Set the mount HTML node for suggestions | () => HTMLElement | - | 3.22.0 |
|
||||
|
||||
### Mention methods
|
||||
|
||||
|
@ -48,6 +48,7 @@ title: Mentions
|
||||
| onSearch | 搜索时触发 | (text: string, prefix: string) => void | - | 3.19.0 |
|
||||
| onFocus | 获得焦点时触发 | () => void | - | 3.19.0 |
|
||||
| onBlur | 失去焦点时触发 | () => void | - | 3.19.0 |
|
||||
| getPopupContainer | 指定建议框挂载的 HTML 节点 | () => HTMLElement | - | 3.22.0 |
|
||||
|
||||
### Mention 方法
|
||||
|
||||
|
@ -76,6 +76,7 @@ export interface ModalProps {
|
||||
keyboard?: boolean;
|
||||
wrapProps?: any;
|
||||
prefixCls?: string;
|
||||
closeIcon?: React.ReactNode;
|
||||
}
|
||||
|
||||
type getContainerFunc = () => HTMLElement;
|
||||
@ -164,6 +165,7 @@ export default class Modal extends React.Component<ModalProps, {}> {
|
||||
footer: PropTypes.node,
|
||||
title: PropTypes.node,
|
||||
closable: PropTypes.bool,
|
||||
closeIcon: PropTypes.node,
|
||||
};
|
||||
|
||||
handleCancel = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
@ -210,6 +212,7 @@ export default class Modal extends React.Component<ModalProps, {}> {
|
||||
wrapClassName,
|
||||
centered,
|
||||
getContainer,
|
||||
closeIcon,
|
||||
...restProps
|
||||
} = this.props;
|
||||
|
||||
@ -220,9 +223,9 @@ export default class Modal extends React.Component<ModalProps, {}> {
|
||||
</LocaleReceiver>
|
||||
);
|
||||
|
||||
const closeIcon = (
|
||||
const closeIconToRender = (
|
||||
<span className={`${prefixCls}-close-x`}>
|
||||
<Icon className={`${prefixCls}-close-icon`} type="close" />
|
||||
{closeIcon || <Icon className={`${prefixCls}-close-icon`} type="close" />}
|
||||
</span>
|
||||
);
|
||||
|
||||
@ -236,7 +239,7 @@ export default class Modal extends React.Component<ModalProps, {}> {
|
||||
visible={visible}
|
||||
mousePosition={mousePosition}
|
||||
onClose={this.handleCancel}
|
||||
closeIcon={closeIcon}
|
||||
closeIcon={closeIconToRender}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -57,4 +57,9 @@ describe('Modal', () => {
|
||||
wrapper.handleOk();
|
||||
expect(onOk).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('support closeIcon', () => {
|
||||
const wrapper = mount(<Modal closeIcon={<a>closeIcon</a>} visible />);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -169,3 +169,75 @@ exports[`Modal render without footer 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Modal support closeIcon 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-modal-mask fade-appear"
|
||||
/>
|
||||
<div
|
||||
class="ant-modal-wrap "
|
||||
role="dialog"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-modal zoom-appear"
|
||||
role="document"
|
||||
style="width: 520px;"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style="width: 0px; height: 0px; overflow: hidden;"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-modal-content"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="ant-modal-close"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-modal-close-x"
|
||||
>
|
||||
<a>
|
||||
closeIcon
|
||||
</a>
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="ant-modal-body"
|
||||
/>
|
||||
<div
|
||||
class="ant-modal-footer"
|
||||
>
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Cancel
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
OK
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style="width: 0px; height: 0px; overflow: hidden;"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -19,6 +19,7 @@ When requiring users to interact with the application, but without jumping to a
|
||||
| cancelText | Text of the Cancel button | string\|ReactNode | `Cancel` | |
|
||||
| centered | Centered Modal | Boolean | `false` | 3.8.0 |
|
||||
| closable | Whether a close (x) button is visible on top right of the modal dialog or not | boolean | true | |
|
||||
| closeIcon | custom close icon | ReactNode | - | 3.22.0 |
|
||||
| confirmLoading | Whether to apply loading visual effect for OK button or not | boolean | false | |
|
||||
| destroyOnClose | Whether to unmount child components on onClose | boolean | false | 3.1.0 |
|
||||
| footer | Footer content, set as `footer={null}` when you don't need default buttons | string\|ReactNode | OK and Cancel buttons | |
|
||||
|
@ -22,6 +22,7 @@ title: Modal
|
||||
| cancelText | 取消按钮文字 | string\|ReactNode | 取消 | |
|
||||
| centered | 垂直居中展示 Modal | Boolean | `false` | 3.8.0 |
|
||||
| closable | 是否显示右上角的关闭按钮 | boolean | true | |
|
||||
| closeIcon | 自定义关闭图标 | ReactNode | - | 3.22.0 |
|
||||
| confirmLoading | 确定按钮 loading | boolean | 无 | |
|
||||
| destroyOnClose | 关闭时销毁 Modal 里的子元素 | boolean | false | 3.1.0 |
|
||||
| footer | 底部内容,当不需要默认底部按钮时,可以设为 `footer={null}` | string\|ReactNode | 确定取消按钮 | |
|
||||
|
@ -4,8 +4,7 @@ import moment from 'moment';
|
||||
import { mount } from 'enzyme';
|
||||
import Statistic from '..';
|
||||
import { formatTimeStr } from '../utils';
|
||||
|
||||
const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));
|
||||
import { sleep } from '../../../tests/utils';
|
||||
|
||||
describe('Statistic', () => {
|
||||
beforeAll(() => {
|
||||
@ -70,7 +69,7 @@ describe('Statistic', () => {
|
||||
const instance = wrapper.instance();
|
||||
expect(instance.countdownId).not.toBe(undefined);
|
||||
|
||||
await delay(10);
|
||||
await sleep(10);
|
||||
|
||||
wrapper.unmount();
|
||||
expect(instance.countdownId).toBe(undefined);
|
||||
|
@ -6,7 +6,10 @@ exports[`renders ./components/steps/demo/clickable.md correctly 1`] = `
|
||||
class="ant-steps ant-steps-horizontal ant-steps-label-horizontal"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process"
|
||||
class="ant-steps-item ant-steps-item-process ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -37,8 +40,12 @@ exports[`renders ./components/steps/demo/clickable.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -69,8 +76,12 @@ exports[`renders ./components/steps/demo/clickable.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -102,6 +113,7 @@ exports[`renders ./components/steps/demo/clickable.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-divider ant-divider-horizontal"
|
||||
role="separator"
|
||||
@ -110,7 +122,10 @@ exports[`renders ./components/steps/demo/clickable.md correctly 1`] = `
|
||||
class="ant-steps ant-steps-vertical"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process"
|
||||
class="ant-steps-item ant-steps-item-process ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -141,8 +156,12 @@ exports[`renders ./components/steps/demo/clickable.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -173,8 +192,12 @@ exports[`renders ./components/steps/demo/clickable.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -207,6 +230,7 @@ exports[`renders ./components/steps/demo/clickable.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/steps/demo/customized-progress-dot.md correctly 1`] = `
|
||||
@ -215,6 +239,9 @@ exports[`renders ./components/steps/demo/customized-progress-dot.md correctly 1`
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -245,8 +272,12 @@ exports[`renders ./components/steps/demo/customized-progress-dot.md correctly 1`
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process"
|
||||
class="ant-steps-item ant-steps-item-process ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -277,8 +308,12 @@ exports[`renders ./components/steps/demo/customized-progress-dot.md correctly 1`
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -309,8 +344,12 @@ exports[`renders ./components/steps/demo/customized-progress-dot.md correctly 1`
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -342,6 +381,7 @@ exports[`renders ./components/steps/demo/customized-progress-dot.md correctly 1`
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/steps/demo/error.md correctly 1`] = `
|
||||
@ -350,6 +390,9 @@ exports[`renders ./components/steps/demo/error.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish ant-steps-next-error"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -396,8 +439,12 @@ exports[`renders ./components/steps/demo/error.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-error"
|
||||
class="ant-steps-item ant-steps-item-error ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -444,8 +491,12 @@ exports[`renders ./components/steps/demo/error.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -475,6 +526,7 @@ exports[`renders ./components/steps/demo/error.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/steps/demo/icon.md correctly 1`] = `
|
||||
@ -482,7 +534,10 @@ exports[`renders ./components/steps/demo/icon.md correctly 1`] = `
|
||||
class="ant-steps ant-steps-horizontal ant-steps-label-horizontal"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish ant-steps-item-custom"
|
||||
class="ant-steps-item ant-steps-item-finish ant-steps-item-custom ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -524,8 +579,12 @@ exports[`renders ./components/steps/demo/icon.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish ant-steps-item-custom"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -567,8 +626,12 @@ exports[`renders ./components/steps/demo/icon.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process ant-steps-item-custom"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -610,8 +673,12 @@ exports[`renders ./components/steps/demo/icon.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait ant-steps-item-custom"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -654,6 +721,480 @@ exports[`renders ./components/steps/demo/icon.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/steps/demo/nav.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
style="border:1px solid rgb(235, 237, 240);margin-bottom:24px"
|
||||
>
|
||||
<div
|
||||
class="ant-steps ant-steps-horizontal ant-steps-small ant-steps-label-horizontal ant-steps-navigation"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: check"
|
||||
class="anticon anticon-check ant-steps-finish-icon"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="check"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
Step 1
|
||||
<div
|
||||
class="ant-steps-item-subtitle"
|
||||
title="00:00:05"
|
||||
>
|
||||
00:00:05
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-description"
|
||||
>
|
||||
This is a description.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
2
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
Step 2
|
||||
<div
|
||||
class="ant-steps-item-subtitle"
|
||||
title="00:01:02"
|
||||
>
|
||||
00:01:02
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-description"
|
||||
>
|
||||
This is a description.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
3
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
Step 3
|
||||
<div
|
||||
class="ant-steps-item-subtitle"
|
||||
title="waiting for longlong time"
|
||||
>
|
||||
waiting for longlong time
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-description"
|
||||
>
|
||||
This is a description.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="border:1px solid rgb(235, 237, 240);margin-bottom:24px"
|
||||
>
|
||||
<div
|
||||
class="ant-steps ant-steps-horizontal ant-steps-label-horizontal ant-steps-navigation"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: check"
|
||||
class="anticon anticon-check ant-steps-finish-icon"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="check"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
Step 1
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
2
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
Step 2
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
3
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
Step 3
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
4
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
Step 4
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="border:1px solid rgb(235, 237, 240);margin-bottom:24px"
|
||||
>
|
||||
<div
|
||||
class="ant-steps ant-steps-horizontal ant-steps-small ant-steps-label-horizontal ant-steps-navigation"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: check"
|
||||
class="anticon anticon-check ant-steps-finish-icon"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="check"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
finish 1
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: check"
|
||||
class="anticon anticon-check ant-steps-finish-icon"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="check"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
finish 2
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
3
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
current process
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait ant-steps-item-disabled"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
4
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
wait
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/steps/demo/progress-dot.md correctly 1`] = `
|
||||
@ -662,6 +1203,9 @@ exports[`renders ./components/steps/demo/progress-dot.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -692,8 +1236,12 @@ exports[`renders ./components/steps/demo/progress-dot.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process"
|
||||
class="ant-steps-item ant-steps-item-process ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -724,8 +1272,12 @@ exports[`renders ./components/steps/demo/progress-dot.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -757,6 +1309,7 @@ exports[`renders ./components/steps/demo/progress-dot.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/steps/demo/simple.md correctly 1`] = `
|
||||
@ -765,6 +1318,9 @@ exports[`renders ./components/steps/demo/simple.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -811,8 +1367,12 @@ exports[`renders ./components/steps/demo/simple.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process"
|
||||
class="ant-steps-item ant-steps-item-process ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -833,6 +1393,12 @@ exports[`renders ./components/steps/demo/simple.md correctly 1`] = `
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
In Progress
|
||||
<div
|
||||
class="ant-steps-item-subtitle"
|
||||
title="Left 00:00:08"
|
||||
>
|
||||
Left 00:00:08
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-description"
|
||||
@ -841,8 +1407,12 @@ exports[`renders ./components/steps/demo/simple.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -872,6 +1442,7 @@ exports[`renders ./components/steps/demo/simple.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/steps/demo/small-size.md correctly 1`] = `
|
||||
@ -880,6 +1451,9 @@ exports[`renders ./components/steps/demo/small-size.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -921,8 +1495,12 @@ exports[`renders ./components/steps/demo/small-size.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process"
|
||||
class="ant-steps-item ant-steps-item-process ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -946,8 +1524,12 @@ exports[`renders ./components/steps/demo/small-size.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -972,6 +1554,7 @@ exports[`renders ./components/steps/demo/small-size.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/steps/demo/step-next.md correctly 1`] = `
|
||||
@ -980,7 +1563,10 @@ exports[`renders ./components/steps/demo/step-next.md correctly 1`] = `
|
||||
class="ant-steps ant-steps-horizontal ant-steps-label-horizontal"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process"
|
||||
class="ant-steps-item ant-steps-item-process ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -1004,8 +1590,12 @@ exports[`renders ./components/steps/demo/step-next.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -1029,8 +1619,12 @@ exports[`renders ./components/steps/demo/step-next.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -1055,6 +1649,7 @@ exports[`renders ./components/steps/demo/step-next.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="steps-content"
|
||||
>
|
||||
@ -1081,6 +1676,9 @@ exports[`renders ./components/steps/demo/vertical.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -1127,8 +1725,12 @@ exports[`renders ./components/steps/demo/vertical.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process"
|
||||
class="ant-steps-item ant-steps-item-process ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -1157,8 +1759,12 @@ exports[`renders ./components/steps/demo/vertical.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -1188,6 +1794,7 @@ exports[`renders ./components/steps/demo/vertical.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/steps/demo/vertical-small.md correctly 1`] = `
|
||||
@ -1196,6 +1803,9 @@ exports[`renders ./components/steps/demo/vertical-small.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -1242,8 +1852,12 @@ exports[`renders ./components/steps/demo/vertical-small.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process"
|
||||
class="ant-steps-item ant-steps-item-process ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -1272,8 +1886,12 @@ exports[`renders ./components/steps/demo/vertical-small.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
@ -1303,4 +1921,5 @@ exports[`renders ./components/steps/demo/vertical-small.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
84
components/steps/demo/nav.md
Normal file
84
components/steps/demo/nav.md
Normal file
@ -0,0 +1,84 @@
|
||||
---
|
||||
order: 11
|
||||
title:
|
||||
zh-CN: 导航步骤
|
||||
en-US: Navgation Steps
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
导航类型的步骤条。
|
||||
|
||||
## en-US
|
||||
|
||||
Navgation steps.
|
||||
|
||||
```jsx
|
||||
import { Steps } from 'antd';
|
||||
|
||||
const { Step } = Steps;
|
||||
|
||||
class Demo extends React.Component {
|
||||
state = {
|
||||
current: 0,
|
||||
};
|
||||
|
||||
onChange = current => {
|
||||
console.log('onChange:', current);
|
||||
this.setState({ current });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { current } = this.state;
|
||||
const containerStyle = {
|
||||
border: '1px solid rgb(235, 237, 240)',
|
||||
marginBottom: 24,
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={containerStyle}>
|
||||
<Steps type="navigation" size="small" current={current} onChange={this.onChange}>
|
||||
<Step
|
||||
title="Step 1"
|
||||
subTitle="00:00:05"
|
||||
status="finish"
|
||||
description="This is a description."
|
||||
/>
|
||||
<Step
|
||||
title="Step 2"
|
||||
subTitle="00:01:02"
|
||||
status="process"
|
||||
description="This is a description."
|
||||
/>
|
||||
<Step
|
||||
title="Step 3"
|
||||
subTitle="waiting for longlong time"
|
||||
status="wait"
|
||||
description="This is a description."
|
||||
/>
|
||||
</Steps>
|
||||
</div>
|
||||
<div style={containerStyle}>
|
||||
<Steps type="navigation" current={current} onChange={this.onChange}>
|
||||
<Step status="finish" title="Step 1" />
|
||||
<Step status="process" title="Step 2" />
|
||||
<Step status="wait" title="Step 3" />
|
||||
<Step status="wait" title="Step 4" />
|
||||
</Steps>
|
||||
</div>
|
||||
<div style={containerStyle}>
|
||||
<Steps type="navigation" size="small" current={current} onChange={this.onChange}>
|
||||
<Step status="finish" title="finish 1" />
|
||||
<Step status="finish" title="finish 2" />
|
||||
<Step status="process" title="current process" />
|
||||
<Step status="wait" title="wait" disabled />
|
||||
</Steps>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<Demo />, mountNode);
|
||||
```
|
@ -21,7 +21,7 @@ const { Step } = Steps;
|
||||
ReactDOM.render(
|
||||
<Steps current={1}>
|
||||
<Step title="Finished" description="This is a description." />
|
||||
<Step title="In Progress" description="This is a description." />
|
||||
<Step title="In Progress" subTitle="Left 00:00:08" description="This is a description." />
|
||||
<Step title="Waiting" description="This is a description." />
|
||||
</Steps>,
|
||||
mountNode,
|
||||
|
@ -28,6 +28,7 @@ The whole of the step bar.
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| className | additional class to Steps | string | - | 3.11.3 |
|
||||
| type | type of steps, can be set to one of the following values: `default`, `navigation` | string | `default` | 3.22.0 |
|
||||
| current | to set the current step, counting from 0. You can overwrite this state by using `status` of `Step` | number | 0 | |
|
||||
| direction | to specify the direction of the step bar, `horizontal` or `vertical` | string | `horizontal` | |
|
||||
| labelPlacement | place title and description with `horizontal` or `vertical` direction | string | `horizontal` | 3.7.3 |
|
||||
@ -47,3 +48,5 @@ A single step in the step bar.
|
||||
| icon | icon of the step, optional property | string\|ReactNode | - | |
|
||||
| status | to specify the status. It will be automatically set by `current` of `Steps` if not configured. Optional values are: `wait` `process` `finish` `error` | string | `wait` | |
|
||||
| title | title of the step | string\|ReactNode | - | |
|
||||
| subTitle | subTitle of the step | string\|ReactNode | - | 3.22.0 |
|
||||
| disabled | disable click | boolean | false | 3.22.0 |
|
||||
|
@ -5,6 +5,7 @@ import Icon from '../icon';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
|
||||
export interface StepsProps {
|
||||
type?: 'default' | 'navigation';
|
||||
className?: string;
|
||||
current?: number;
|
||||
direction?: 'horizontal' | 'vertical';
|
||||
@ -25,6 +26,7 @@ export interface StepProps {
|
||||
icon?: React.ReactNode;
|
||||
onClick?: React.MouseEventHandler<HTMLElement>;
|
||||
status?: 'wait' | 'process' | 'finish' | 'error';
|
||||
disabled?: boolean;
|
||||
title?: React.ReactNode;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ title: Steps
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| className | 步骤条类名 | string | - | 3.11.3 |
|
||||
| type | 步骤条类型,有 `default` 和 `navigation` 两种 | string | `default` | 3.22.0 |
|
||||
| current | 指定当前步骤,从 0 开始记数。在子 Step 元素中,可以通过 `status` 属性覆盖状态 | number | 0 | |
|
||||
| direction | 指定步骤条方向。目前支持水平(`horizontal`)和竖直(`vertical`)两种方向 | string | horizontal | |
|
||||
| labelPlacement | 指定标签放置位置,默认水平放图标右侧,可选 `vertical` 放图标下方 | string | `horizontal` | 3.7.3 |
|
||||
@ -48,3 +49,5 @@ title: Steps
|
||||
| icon | 步骤图标的类型,可选 | string\|ReactNode | - | |
|
||||
| status | 指定状态。当不配置该属性时,会使用 Steps 的 `current` 来自动指定状态。可选:`wait` `process` `finish` `error` | string | wait | |
|
||||
| title | 标题 | string\|ReactNode | - | |
|
||||
| subTitle | 子标题 | string\|ReactNode | - | 3.22.0 |
|
||||
| disabled | 禁用点击 | boolean | false | 3.22.0 |
|
||||
|
@ -20,12 +20,15 @@
|
||||
@error-description-color: @error-color;
|
||||
@error-tail-color: @wait-tail-color;
|
||||
@steps-background: @component-background;
|
||||
@steps-nav-arrow-color: fade(@black, 25%);
|
||||
@steps-nav-active-color: @primary-color;
|
||||
|
||||
@steps-icon-size: 32px;
|
||||
@steps-small-icon-size: 24px;
|
||||
@steps-dot-size: 8px;
|
||||
@steps-current-dot-size: 10px;
|
||||
@steps-desciption-max-width: 140px;
|
||||
@steps-nav-content-max-width: @steps-desciption-max-width;
|
||||
|
||||
.@{steps-prefix-cls} {
|
||||
.reset-component;
|
||||
@ -42,12 +45,16 @@
|
||||
overflow: hidden;
|
||||
vertical-align: top;
|
||||
|
||||
&-container {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
&:last-child > &-tail,
|
||||
&:last-child > &-content > &-title::after {
|
||||
&:last-child > &-container > &-tail,
|
||||
&:last-child > &-container > &-content > &-title::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@ -110,6 +117,13 @@
|
||||
content: '';
|
||||
}
|
||||
}
|
||||
&-subtitle {
|
||||
display: inline;
|
||||
color: @text-color-secondary;
|
||||
font-size: @font-size-base;
|
||||
margin-left: 8px;
|
||||
font-weight: normal;
|
||||
}
|
||||
&-description {
|
||||
color: @text-color-secondary;
|
||||
font-size: @font-size-base;
|
||||
@ -131,12 +145,12 @@
|
||||
&.@{steps-prefix-cls}-next-error .@{steps-prefix-cls}-item-title::after {
|
||||
background: @error-icon-color;
|
||||
}
|
||||
}
|
||||
|
||||
// ===================== Clickable =====================
|
||||
&[role='button'] {
|
||||
outline: none;
|
||||
|
||||
&:not(.@{steps-prefix-cls}-item-process) {
|
||||
.@{steps-prefix-cls}:not(.@{steps-prefix-cls}-navigation) .@{steps-prefix-cls}-item {
|
||||
&:not(.@{steps-prefix-cls}-item-active) {
|
||||
& > .@{steps-prefix-cls}-item-container[role='button'] {
|
||||
cursor: pointer;
|
||||
|
||||
.@{steps-prefix-cls}-item {
|
||||
@ -150,10 +164,17 @@
|
||||
&:hover {
|
||||
.@{steps-prefix-cls}-item {
|
||||
&-title,
|
||||
&-subtitle,
|
||||
&-description {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.@{steps-prefix-cls}-item-process) {
|
||||
& > .@{steps-prefix-cls}-item-container[role='button']:hover {
|
||||
.@{steps-prefix-cls}-item {
|
||||
&-icon {
|
||||
border-color: @primary-color;
|
||||
|
||||
@ -202,16 +223,16 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
&-@{status} > &-content > &-title {
|
||||
&-@{status} > &-container > &-content > &-title {
|
||||
color: @@title-color;
|
||||
&::after {
|
||||
background-color: @@tail-color;
|
||||
}
|
||||
}
|
||||
&-@{status} > &-content > &-description {
|
||||
&-@{status} > &-container > &-content > &-description {
|
||||
color: @@description-color;
|
||||
}
|
||||
&-@{status} > &-tail::after {
|
||||
&-@{status} > &-container > &-tail::after {
|
||||
background-color: @@tail-color;
|
||||
}
|
||||
}
|
||||
@ -221,4 +242,5 @@
|
||||
@import 'vertical';
|
||||
@import 'label-placement';
|
||||
@import 'progress-dot';
|
||||
@import 'nav';
|
||||
@import 'compatibility';
|
||||
|
91
components/steps/style/nav.less
Normal file
91
components/steps/style/nav.less
Normal file
@ -0,0 +1,91 @@
|
||||
.@{steps-prefix-cls}-navigation {
|
||||
padding-top: 12px;
|
||||
|
||||
&.@{steps-prefix-cls}-small {
|
||||
.@{steps-prefix-cls}-item {
|
||||
&-container {
|
||||
margin-left: -12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.@{steps-prefix-cls}-item {
|
||||
text-align: center;
|
||||
overflow: visible;
|
||||
|
||||
&-container {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
height: 100%;
|
||||
padding-bottom: 12px;
|
||||
margin-left: -16px;
|
||||
transition: opacity 0.3s;
|
||||
|
||||
.@{steps-prefix-cls}-item-content {
|
||||
max-width: @steps-nav-content-max-width;
|
||||
}
|
||||
|
||||
.@{steps-prefix-cls}-item-title {
|
||||
padding-right: 0;
|
||||
max-width: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.@{steps-prefix-cls}-item-active) {
|
||||
.@{steps-prefix-cls}-item-container[role='button'] {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
flex: 1;
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border: 1px solid @steps-nav-arrow-color;
|
||||
border-bottom: none;
|
||||
border-left: none;
|
||||
transform: rotate(45deg);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 100%;
|
||||
margin-top: -14px;
|
||||
margin-left: -2px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
height: 3px;
|
||||
width: 0;
|
||||
background-color: @steps-nav-active-color;
|
||||
transition: width 0.3s, left 0.3s;
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.@{steps-prefix-cls}-item.@{steps-prefix-cls}-item-active::before {
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
.@{steps-prefix-cls}-small {
|
||||
.@{steps-prefix-cls}-small .@{steps-prefix-cls}-item-container {
|
||||
&.@{steps-prefix-cls}-horizontal:not(.@{steps-prefix-cls}-label-vertical)
|
||||
.@{steps-prefix-cls}-item {
|
||||
margin-right: 12px;
|
||||
|
@ -20,7 +20,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
> .@{steps-prefix-cls}-item > .@{steps-prefix-cls}-item-tail {
|
||||
> .@{steps-prefix-cls}-item
|
||||
> .@{steps-prefix-cls}-item-container
|
||||
> .@{steps-prefix-cls}-item-tail {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 16px;
|
||||
@ -33,11 +35,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
> .@{steps-prefix-cls}-item:not(:last-child) > .@{steps-prefix-cls}-item-tail {
|
||||
> .@{steps-prefix-cls}-item:not(:last-child)
|
||||
> .@{steps-prefix-cls}-item-container
|
||||
> .@{steps-prefix-cls}-item-tail {
|
||||
display: block;
|
||||
}
|
||||
|
||||
> .@{steps-prefix-cls}-item
|
||||
> .@{steps-prefix-cls}-item-container
|
||||
> .@{steps-prefix-cls}-item-content
|
||||
> .@{steps-prefix-cls}-item-title {
|
||||
&::after {
|
||||
@ -45,7 +50,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.@{steps-prefix-cls}-small {
|
||||
&.@{steps-prefix-cls}-small .@{steps-prefix-cls}-item-container {
|
||||
.@{steps-prefix-cls}-item-tail {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
5
components/time-picker/locale/ro_RO.tsx
Normal file
5
components/time-picker/locale/ro_RO.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
const locale = {
|
||||
placeholder: 'Selectează ora',
|
||||
};
|
||||
|
||||
export default locale;
|
@ -7,8 +7,7 @@ import Checkbox from '../../checkbox';
|
||||
import DatePicker from '../../date-picker';
|
||||
import Input from '../../input';
|
||||
import Group from '../../input/Group';
|
||||
|
||||
const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));
|
||||
import { sleep } from '../../../tests/utils';
|
||||
|
||||
describe('Tooltip', () => {
|
||||
it('check `onVisibleChange` arguments', () => {
|
||||
@ -205,12 +204,12 @@ describe('Tooltip', () => {
|
||||
expect(wrapper.find('span.ant-calendar-picker')).toHaveLength(1);
|
||||
const picker = wrapper.find('span.ant-calendar-picker').at(0);
|
||||
picker.simulate('mouseenter');
|
||||
await delay(100);
|
||||
await sleep(100);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(true);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(true);
|
||||
|
||||
picker.simulate('mouseleave');
|
||||
await delay(100);
|
||||
await sleep(100);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(false);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
});
|
||||
@ -230,12 +229,12 @@ describe('Tooltip', () => {
|
||||
expect(wrapper.find('Group')).toHaveLength(1);
|
||||
const picker = wrapper.find('Group').at(0);
|
||||
picker.simulate('mouseenter');
|
||||
await delay(100);
|
||||
await sleep(100);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(true);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(true);
|
||||
|
||||
picker.simulate('mouseleave');
|
||||
await delay(100);
|
||||
await sleep(100);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(false);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
});
|
||||
|
@ -6,8 +6,7 @@ import Form from '../../form';
|
||||
import { spyElementPrototypes } from '../../__tests__/util/domHook';
|
||||
import { errorRequest, successRequest } from './requests';
|
||||
import { setup, teardown } from './mock';
|
||||
|
||||
const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));
|
||||
import { sleep } from '../../../tests/utils';
|
||||
|
||||
const fileList = [
|
||||
{
|
||||
@ -124,7 +123,7 @@ describe('Upload List', () => {
|
||||
.at(0)
|
||||
.find('.anticon-close')
|
||||
.simulate('click');
|
||||
await delay(400);
|
||||
await sleep(400);
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-upload-list-item').hostNodes().length).toBe(1);
|
||||
});
|
||||
@ -245,7 +244,7 @@ describe('Upload List', () => {
|
||||
.at(1)
|
||||
.simulate('click');
|
||||
expect(handleRemove).toHaveBeenCalledWith(fileList[1]);
|
||||
await delay(0);
|
||||
await sleep();
|
||||
expect(handleChange.mock.calls.length).toBe(2);
|
||||
});
|
||||
|
||||
@ -274,7 +273,7 @@ describe('Upload List', () => {
|
||||
</Upload>,
|
||||
);
|
||||
wrapper.setState({});
|
||||
await delay(0);
|
||||
await sleep();
|
||||
|
||||
expect(wrapper.state().fileList[2].thumbUrl).not.toBe(undefined);
|
||||
expect(onDrawImage).toHaveBeenCalled();
|
||||
@ -525,7 +524,7 @@ describe('Upload List', () => {
|
||||
</Upload>,
|
||||
);
|
||||
wrapper.setState({});
|
||||
await delay(0);
|
||||
await sleep();
|
||||
|
||||
expect(previewFile).toHaveBeenCalledWith(file.originFileObj);
|
||||
wrapper.update();
|
||||
|
@ -66,6 +66,7 @@ Supported languages:
|
||||
| Tamil | ta_IN |
|
||||
| Thai | th_TH |
|
||||
| Turkish | tr_TR |
|
||||
| Romanian | ro_RO |
|
||||
| Russian | ru_RU |
|
||||
| Ukrainian | uk_UA |
|
||||
| Vietnamese | vi_VN |
|
||||
|
@ -65,6 +65,7 @@ return (
|
||||
| 泰米尔语 | ta_IN |
|
||||
| 泰语 | th_TH |
|
||||
| 土耳其语 | tr_TR |
|
||||
| 罗马尼亚语 | ro_RO |
|
||||
| 俄罗斯语 | ru_RU |
|
||||
| 乌克兰语 | uk_UA |
|
||||
| 越南语 | vi_VN |
|
||||
|
@ -69,7 +69,7 @@
|
||||
"rc-editor-mention": "^1.1.13",
|
||||
"rc-form": "^2.4.5",
|
||||
"rc-input-number": "~4.4.5",
|
||||
"rc-mentions": "~0.3.1",
|
||||
"rc-mentions": "~0.4.0",
|
||||
"rc-menu": "~7.4.23",
|
||||
"rc-notification": "~3.3.1",
|
||||
"rc-pagination": "~1.20.5",
|
||||
@ -77,7 +77,7 @@
|
||||
"rc-rate": "~2.5.0",
|
||||
"rc-select": "~9.2.0",
|
||||
"rc-slider": "~8.6.11",
|
||||
"rc-steps": "~3.4.1",
|
||||
"rc-steps": "~3.5.0",
|
||||
"rc-switch": "~1.9.0",
|
||||
"rc-table": "~6.7.0",
|
||||
"rc-tabs": "~9.6.4",
|
||||
|
@ -8,3 +8,5 @@ export function setMockDate(dateString = '2017-09-18T03:30:07.795') {
|
||||
export function resetMockDate() {
|
||||
MockDate.reset();
|
||||
}
|
||||
|
||||
export const sleep = (timeout = 0) => new Promise(resolve => setTimeout(resolve, timeout));
|
||||
|
Loading…
Reference in New Issue
Block a user