Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Anchor): add onChange prop #18715

Merged
merged 3 commits into from Sep 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 18 additions & 7 deletions components/anchor/Anchor.tsx
Expand Up @@ -62,6 +62,8 @@ export interface AnchorProps {
) => void;
/** Scroll to target offset value, if none, it's offsetTop prop value or 0. */
targetOffset?: number;
/** Listening event when scrolling change active link */
onChange?: (currentActiveLink: string) => void;
}

export interface AnchorState {
Expand Down Expand Up @@ -205,7 +207,7 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState> {
handleScrollTo = (link: string) => {
const { offsetTop, getContainer, targetOffset } = this.props as AnchorDefaultProps;

this.setState({ activeLink: link });
this.setCurrentActiveLink(link);
const container = getContainer();
const scrollTop = getScroll(container, true);
const sharpLinkMatch = sharpMatcherRegx.exec(link);
Expand Down Expand Up @@ -234,21 +236,30 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState> {
this.inkNode = node;
};

setCurrentActiveLink = (link: string) => {
const { activeLink } = this.state;
const { onChange } = this.props;

if (activeLink !== link) {
this.setState({
activeLink: link,
});
if (onChange) {
onChange(link);
}
}
};

handleScroll = () => {
if (this.animating) {
return;
}
const { activeLink } = this.state;
const { offsetTop, bounds, targetOffset } = this.props;
const currentActiveLink = this.getCurrentAnchor(
targetOffset !== undefined ? targetOffset : offsetTop || 0,
bounds,
);
if (activeLink !== currentActiveLink) {
this.setState({
activeLink: currentActiveLink,
});
}
this.setCurrentActiveLink(currentActiveLink);
};

updateInk = () => {
Expand Down
14 changes: 14 additions & 0 deletions components/anchor/__tests__/Anchor.test.js
Expand Up @@ -319,4 +319,18 @@ describe('Anchor Render', () => {
dateNowMock.mockRestore();
jest.useRealTimers();
});

it('Anchor onChange prop', async () => {
const onChange = jest.fn();
const wrapper = mount(
<Anchor onChange={onChange}>
<Link href="#API1" title="API1" />
<Link href="#API2" title="API2" />
</Anchor>,
);
expect(onChange).toHaveBeenCalledTimes(1);
wrapper.instance().handleScrollTo('#API2');
expect(onChange).toHaveBeenCalledTimes(2);
expect(onChange).toHaveBeenCalledWith('#API2');
});
});
74 changes: 74 additions & 0 deletions components/anchor/__tests__/__snapshots__/demo.test.js.snap
Expand Up @@ -166,6 +166,80 @@ exports[`renders ./components/anchor/demo/customizeHighlight.md correctly 1`] =
</div>
`;

exports[`renders ./components/anchor/demo/onChange.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"
Expand Down
36 changes: 36 additions & 0 deletions components/anchor/demo/onChange.md
@@ -0,0 +1,36 @@
---
order: 6
title:
zh-CN: 监听锚点链接改变
en-US: Listening for anchor link change
---

## zh-CN

监听锚点链接改变

## en-US

Listening for anchor link change.

```jsx
import { Anchor } from 'antd';

const { Link } = Anchor;

const onChange = link => {
console.log('Anchor:OnChange', link);
};

ReactDOM.render(
<Anchor affix={false} onChange={onChange}>
<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,
);
```
2 changes: 1 addition & 1 deletion components/anchor/demo/targetOffset.md
@@ -1,5 +1,5 @@
---
order: 4
order: 5
title:
zh-CN: 设置锚点滚动偏移量
en-US: Set Anchor scroll offset
Expand Down
1 change: 1 addition & 0 deletions components/anchor/index.en-US.md
Expand Up @@ -26,6 +26,7 @@ For displaying anchor hyperlinks on page and jumping between them.
| onClick | set the handler to handle `click` event | Function(e: Event, link: Object) | - | 3.9.0 |
| getCurrentAnchor | Customize the anchor highlight | () => string | - | 3.22.0 |
| targetOffset | Anchor scroll offset, default as `offsetTop`, [example](#components-anchor-demo-targetOffset) | number | `offsetTop` | 3.22.0 |
| onChange | Listening for anchor link change | (currentActiveLink: string) => void | | 3.24.0 |

### Link Props

Expand Down
1 change: 1 addition & 0 deletions components/anchor/index.zh-CN.md
Expand Up @@ -27,6 +27,7 @@ title: Anchor
| onClick | `click` 事件的 handler | Function(e: Event, link: Object) | - | 3.9.0 |
| getCurrentAnchor | 自定义高亮的锚点 | () => string | - | 3.22.0 |
| targetOffset | 锚点滚动偏移量,默认与 offsetTop 相同,[例子](#components-anchor-demo-targetOffset) | number | `offsetTop` | 3.22.0 |
| onChange | 监听锚点链接改变 | (currentActiveLink: string) => void | | 3.24.0 |

### Link Props

Expand Down