From 254b4294473fdcb495ea5e7a81a81e4331e50fc2 Mon Sep 17 00:00:00 2001
From: bqy_fe <1743369777@qq.com>
Date: Mon, 25 Jul 2022 19:01:59 +0800
Subject: [PATCH] feat(module:anchor): sync new properties (#7494)
---
components/anchor/anchor-link.component.ts | 10 ++++-
components/anchor/anchor.component.ts | 37 +++++++++++++---
components/anchor/anchor.spec.ts | 43 +++++++++++++++++++
components/anchor/demo/customize-highlight.md | 14 ++++++
components/anchor/demo/customize-highlight.ts | 16 +++++++
components/anchor/demo/on-change.md | 14 ++++++
components/anchor/demo/on-change.ts | 20 +++++++++
components/anchor/demo/on-click.md | 14 ++++++
components/anchor/demo/on-click.ts | 20 +++++++++
components/anchor/demo/target-offset.md | 14 ++++++
components/anchor/demo/target-offset.ts | 22 ++++++++++
components/anchor/doc/index.en-US.md | 4 ++
components/anchor/doc/index.zh-CN.md | 4 ++
13 files changed, 225 insertions(+), 7 deletions(-)
create mode 100644 components/anchor/demo/customize-highlight.md
create mode 100644 components/anchor/demo/customize-highlight.ts
create mode 100644 components/anchor/demo/on-change.md
create mode 100644 components/anchor/demo/on-change.ts
create mode 100644 components/anchor/demo/on-click.md
create mode 100644 components/anchor/demo/on-click.ts
create mode 100644 components/anchor/demo/target-offset.md
create mode 100644 components/anchor/demo/target-offset.ts
diff --git a/components/anchor/anchor-link.component.ts b/components/anchor/anchor-link.component.ts
index a0b7b02678..8a778cb9c2 100644
--- a/components/anchor/anchor-link.component.ts
+++ b/components/anchor/anchor-link.component.ts
@@ -27,7 +27,14 @@ import { NzAnchorComponent } from './anchor.component';
exportAs: 'nzLink',
preserveWhitespaces: false,
template: `
-
+
{{ titleStr }}
@@ -37,6 +44,7 @@ import { NzAnchorComponent } from './anchor.component';
})
export class NzAnchorLinkComponent implements OnInit, OnDestroy {
@Input() nzHref = '#';
+ @Input() nzTarget?: string;
titleStr: string | null = '';
titleTpl?: TemplateRef;
diff --git a/components/anchor/anchor.component.ts b/components/anchor/anchor.component.ts
index 295e7f42a9..f9a7a8cd64 100644
--- a/components/anchor/anchor.component.ts
+++ b/components/anchor/anchor.component.ts
@@ -92,15 +92,23 @@ export class NzAnchorComponent implements OnDestroy, AfterViewInit, OnChanges {
@WithConfig()
nzOffsetTop?: number = undefined;
+ @Input()
+ @InputNumber(undefined)
+ @WithConfig()
+ nzTargetOffset?: number = undefined;
+
@Input() nzContainer?: string | HTMLElement;
+ @Input() nzCurrentAnchor?: string;
@Output() readonly nzClick = new EventEmitter();
+ @Output() readonly nzChange = new EventEmitter();
@Output() readonly nzScroll = new EventEmitter();
visible = false;
wrapperStyle: NgStyleInterface = { 'max-height': '100vh' };
container?: HTMLElement | Window;
+ activeLink?: string;
private links: NzAnchorLinkComponent[] = [];
private animating = false;
@@ -160,7 +168,8 @@ export class NzAnchorComponent implements OnDestroy, AfterViewInit, OnChanges {
}
const sections: Section[] = [];
- const scope = (this.nzOffsetTop || 0) + this.nzBounds;
+ const offsetTop = this.nzTargetOffset ? this.nzTargetOffset : this.nzOffsetTop || 0;
+ const scope = offsetTop + this.nzBounds;
this.links.forEach(comp => {
const sharpLinkMatch = sharpMatcherRegx.exec(comp.nzHref.toString());
if (!sharpLinkMatch) {
@@ -195,11 +204,23 @@ export class NzAnchorComponent implements OnDestroy, AfterViewInit, OnChanges {
});
}
+ private setActive(comp?: NzAnchorLinkComponent): void {
+ const originalActiveLink = this.activeLink;
+ const targetComp = (this.nzCurrentAnchor && this.links.find(n => n.nzHref === this.nzCurrentAnchor)) || comp;
+ if (!targetComp) return;
+
+ targetComp.setActive();
+ const linkNode = targetComp.getLinkTitleElement();
+ this.ink.nativeElement.style.top = `${linkNode.offsetTop + linkNode.clientHeight / 2 - 4.5}px`;
+ this.activeLink = (comp || targetComp).nzHref;
+ if (originalActiveLink !== this.activeLink) {
+ this.nzChange.emit(this.activeLink);
+ }
+ }
+
private handleActive(comp: NzAnchorLinkComponent): void {
this.clearActive();
- comp.setActive();
- const linkNode = comp.getLinkTitleElement();
- this.ink.nativeElement.style.top = `${linkNode.offsetTop + linkNode.clientHeight / 2 - 4.5}px`;
+ this.setActive(comp);
this.visible = true;
this.setVisible();
this.nzScroll.emit(comp);
@@ -226,7 +247,8 @@ export class NzAnchorComponent implements OnDestroy, AfterViewInit, OnChanges {
this.animating = true;
const containerScrollTop = this.scrollSrv.getScroll(this.getContainer());
const elOffsetTop = getOffsetTop(el, this.getContainer());
- const targetScrollTop = containerScrollTop + elOffsetTop - (this.nzOffsetTop || 0);
+ let targetScrollTop = containerScrollTop + elOffsetTop;
+ targetScrollTop -= this.nzTargetOffset !== undefined ? this.nzTargetOffset : this.nzOffsetTop || 0;
this.scrollSrv.scrollTo(this.getContainer(), targetScrollTop, {
callback: () => {
this.animating = false;
@@ -237,7 +259,7 @@ export class NzAnchorComponent implements OnDestroy, AfterViewInit, OnChanges {
}
ngOnChanges(changes: SimpleChanges): void {
- const { nzOffsetTop, nzContainer } = changes;
+ const { nzOffsetTop, nzContainer, nzCurrentAnchor } = changes;
if (nzOffsetTop) {
this.wrapperStyle = {
'max-height': `calc(100vh - ${this.nzOffsetTop}px)`
@@ -248,5 +270,8 @@ export class NzAnchorComponent implements OnDestroy, AfterViewInit, OnChanges {
this.container = typeof container === 'string' ? this.doc.querySelector(container) : container;
this.registerScrollEvent();
}
+ if (nzCurrentAnchor) {
+ this.setActive();
+ }
}
}
diff --git a/components/anchor/anchor.spec.ts b/components/anchor/anchor.spec.ts
index 8388a2a76b..a62ac99a4e 100644
--- a/components/anchor/anchor.spec.ts
+++ b/components/anchor/anchor.spec.ts
@@ -26,6 +26,7 @@ describe('anchor', () => {
fixture.detectChanges();
page = new PageObject();
spyOn(context, '_scroll');
+ spyOn(context, '_change');
srv = TestBed.inject(NzScrollService);
});
afterEach(() => context.comp.ngOnDestroy());
@@ -131,6 +132,18 @@ describe('anchor', () => {
});
});
+ describe('[nzCurrentAnchor]', () => {
+ it('customize the anchor highlight', () => {
+ context.nzCurrentAnchor = '#basic';
+ fixture.detectChanges();
+ const linkList = dl.queryAll(By.css('.ant-anchor-link'));
+ expect(linkList.length).toBeGreaterThan(0);
+ const activeLink = linkList.find(n => (n.nativeElement as HTMLDivElement).getAttribute('nzhref') === '#basic')!;
+ expect(activeLink).toBeTruthy();
+ expect((activeLink.nativeElement as HTMLDivElement).classList).toContain('ant-anchor-link-active');
+ });
+ });
+
describe('[nzShowInkInFixed]', () => {
beforeEach(() => {
context.nzAffix = false;
@@ -169,6 +182,30 @@ describe('anchor', () => {
});
});
+ describe('(nzChange)', () => {
+ it('should emit nzChange when click a link', fakeAsync(() => {
+ spyOn(srv, 'scrollTo').and.callFake((_containerEl, _targetTopValue = 0, options = {}) => {
+ if (options.callback) {
+ options.callback();
+ }
+ });
+ expect(context._change).not.toHaveBeenCalled();
+ page.to('#basic-target');
+ expect(context._change).toHaveBeenCalled();
+ }));
+ it('should emit nzChange when scrolling to the anchor', (done: () => void) => {
+ spyOn(context, '_change');
+ expect(context._change).not.toHaveBeenCalled();
+ page.scrollTo();
+ setTimeout(() => {
+ const inkNode = page.getEl('.ant-anchor-ink-ball');
+ expect(+inkNode.style.top!.replace('px', '')).toBeGreaterThan(0);
+ expect(context._change).toHaveBeenCalled();
+ done();
+ }, throttleTime);
+ });
+ });
+
it('(nzClick)', () => {
spyOn(context, '_click');
expect(context._click).not.toHaveBeenCalled();
@@ -233,9 +270,12 @@ describe('anchor', () => {
[nzBounds]="nzBounds"
[nzShowInkInFixed]="nzShowInkInFixed"
[nzOffsetTop]="nzOffsetTop"
+ [nzTargetOffset]="nzTargetOffset"
[nzContainer]="nzContainer"
+ [nzCurrentAnchor]="nzCurrentAnchor"
(nzClick)="_click($event)"
(nzScroll)="_scroll($event)"
+ (nzChange)="_change($event)"
>
@@ -288,8 +328,11 @@ export class TestComponent {
nzAffix = true;
nzBounds = 5;
nzOffsetTop = 0;
+ nzTargetOffset?: number;
nzShowInkInFixed = false;
nzContainer: any = null;
+ nzCurrentAnchor?: string;
_click() {}
+ _change() {}
_scroll() {}
}
diff --git a/components/anchor/demo/customize-highlight.md b/components/anchor/demo/customize-highlight.md
new file mode 100644
index 0000000000..e93025cea5
--- /dev/null
+++ b/components/anchor/demo/customize-highlight.md
@@ -0,0 +1,14 @@
+---
+order: 4
+title:
+ zh-CN: 自定义锚点高亮
+ en-US: Customize the anchor highlight
+---
+
+## zh-CN
+
+自定义锚点高亮。
+
+## en-US
+
+Customize the anchor highlight.
\ No newline at end of file
diff --git a/components/anchor/demo/customize-highlight.ts b/components/anchor/demo/customize-highlight.ts
new file mode 100644
index 0000000000..a4a06c5e1c
--- /dev/null
+++ b/components/anchor/demo/customize-highlight.ts
@@ -0,0 +1,16 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'nz-demo-anchor-customize-highlight',
+ template: `
+
+
+
+
+
+
+
+
+ `
+})
+export class NzDemoAnchorCustomizeHighlightComponent {}
diff --git a/components/anchor/demo/on-change.md b/components/anchor/demo/on-change.md
new file mode 100644
index 0000000000..29cbbd1bcb
--- /dev/null
+++ b/components/anchor/demo/on-change.md
@@ -0,0 +1,14 @@
+---
+order: 6
+title:
+ zh-CN: 监听锚点链接改变
+ en-US: Listening for anchor link change
+---
+
+## zh-CN
+
+监听锚点链接改变
+
+## en-US
+
+Listening for anchor link change.
\ No newline at end of file
diff --git a/components/anchor/demo/on-change.ts b/components/anchor/demo/on-change.ts
new file mode 100644
index 0000000000..a4841169e1
--- /dev/null
+++ b/components/anchor/demo/on-change.ts
@@ -0,0 +1,20 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'nz-demo-anchor-on-change',
+ template: `
+
+
+
+
+
+
+
+
+ `
+})
+export class NzDemoAnchorOnChangeComponent {
+ handleChange(link: string): void {
+ console.log('Anchor:OnChange', link);
+ }
+}
diff --git a/components/anchor/demo/on-click.md b/components/anchor/demo/on-click.md
new file mode 100644
index 0000000000..8437252fd3
--- /dev/null
+++ b/components/anchor/demo/on-click.md
@@ -0,0 +1,14 @@
+---
+order: 3
+title:
+ zh-CN: 自定义 onClick 事件
+ en-US: Customize the onClick event
+---
+
+## zh-CN
+
+点击锚点不记录历史。
+
+## en-US
+
+Clicking on an anchor does not record history.
\ No newline at end of file
diff --git a/components/anchor/demo/on-click.ts b/components/anchor/demo/on-click.ts
new file mode 100644
index 0000000000..66d1505071
--- /dev/null
+++ b/components/anchor/demo/on-click.ts
@@ -0,0 +1,20 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'nz-demo-anchor-on-click',
+ template: `
+
+
+
+
+
+
+
+
+ `
+})
+export class NzDemoAnchorOnClickComponent {
+ handleClick(e: string): void {
+ console.log(e);
+ }
+}
diff --git a/components/anchor/demo/target-offset.md b/components/anchor/demo/target-offset.md
new file mode 100644
index 0000000000..965bf6319d
--- /dev/null
+++ b/components/anchor/demo/target-offset.md
@@ -0,0 +1,14 @@
+---
+order: 5
+title:
+ zh-CN: 设置锚点滚动偏移量
+ en-US: Set Anchor scroll offset
+---
+
+## zh-CN
+
+锚点目标滚动到屏幕正中间。
+
+## en-US
+
+Anchor target scroll to screen center.
\ No newline at end of file
diff --git a/components/anchor/demo/target-offset.ts b/components/anchor/demo/target-offset.ts
new file mode 100644
index 0000000000..6789d98512
--- /dev/null
+++ b/components/anchor/demo/target-offset.ts
@@ -0,0 +1,22 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'nz-demo-anchor-target-offset',
+ template: `
+
+
+
+
+
+
+
+
+ `
+})
+export class NzDemoAnchorTargetOffsetComponent implements OnInit {
+ targetOffset?: number;
+
+ ngOnInit(): void {
+ this.targetOffset = window.innerHeight / 2;
+ }
+}
diff --git a/components/anchor/doc/index.en-US.md b/components/anchor/doc/index.en-US.md
index 4b9c311039..41a8dd6270 100755
--- a/components/anchor/doc/index.en-US.md
+++ b/components/anchor/doc/index.en-US.md
@@ -25,8 +25,11 @@ import { NzAnchorModule } from 'ng-zorro-antd/anchor';
| `[nzBounds]` | Bounding distance of anchor area, unit: px | `number` | `5` | ✅ |
| `[nzOffsetTop]` | Pixels to offset from top when calculating position of scroll | `number` | `0` | ✅ |
| `[nzShowInkInFixed]` | Whether show ink-balls in Fixed mode | `boolean` | `false` | ✅ |
+| `[nzTargetOffset]` | Anchor scroll offset, default as `offsetTop`, [example](#components-anchor-demo-targetOffset) | number | - | |
| `[nzContainer]` | Scrolling container | `string \| HTMLElement` | `window` |
+| `[nzCurrentAnchor]` | Customize the anchor highlight | string | - | |
| `(nzClick)` | Click of Anchor item | `EventEmitter` | - |
+| `(nzChange)` | Listening for anchor link change | `EventEmitter` | - | |
| `(nzScroll)` | The scroll function that is triggered when scrolling to an anchor. | `EventEmitter` | - |
### nz-link
@@ -34,4 +37,5 @@ import { NzAnchorModule } from 'ng-zorro-antd/anchor';
| Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
| `[nzHref]` | target of hyperlink | `string` | - |
+| `[nzTarget]` | Specifies where to display the linked URL | string | - | |
| `[nzTitle]` | content of hyperlink | `string \| TemplateRef` | - |
diff --git a/components/anchor/doc/index.zh-CN.md b/components/anchor/doc/index.zh-CN.md
index b7539e7102..36ee5debd4 100755
--- a/components/anchor/doc/index.zh-CN.md
+++ b/components/anchor/doc/index.zh-CN.md
@@ -27,8 +27,11 @@ import { NzAnchorModule } from 'ng-zorro-antd/anchor';
| `[nzBounds]` | 锚点区域边界,单位:px | `number` | `5` | ✅ |
| `[nzOffsetTop]` | 距离窗口顶部达到指定偏移量后触发 | `number` | - | ✅ |
| `[nzShowInkInFixed]` | 固定模式是否显示小圆点 | `boolean` | `false` | ✅ |
+| `[nzTargetOffset]` | 锚点滚动偏移量,默认与 offsetTop 相同,[例子](#components-anchor-demo-targetOffset) | number | - | |
| `[nzContainer]` | 指定滚动的容器 | `string \| HTMLElement` | `window` |
+| `[nzCurrentAnchor]` | 自定义高亮的锚点 | string | - | |
| `(nzClick)` | 点击项触发 | `EventEmitter` | - |
+| `(nzChange)` | 监听锚点链接改变 | `EventEmitter` | - | |
| `(nzScroll)` | 滚动至某锚点时触发 | `EventEmitter` | - |
### nz-link
@@ -36,4 +39,5 @@ import { NzAnchorModule } from 'ng-zorro-antd/anchor';
| 成员 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| `[nzHref]` | 锚点链接 | `string` | - |
+| `[nzTarget]` | 该属性指定在何处显示链接的资源。 | string | - | |
| `[nzTitle]` | 文字内容 | `string \| TemplateRef` | - |