@odx/angular 12.14.2 → 12.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/components/anchor-navigation/README.md +3 -0
- package/components/anchor-navigation/anchor-navigation.component.d.ts +31 -0
- package/components/anchor-navigation/anchor-navigation.module.d.ts +8 -0
- package/components/anchor-navigation/anchor-navigation.service.d.ts +43 -0
- package/components/anchor-navigation/components/anchor-navigation-item.component.d.ts +10 -0
- package/components/anchor-navigation/components/index.d.ts +1 -0
- package/components/anchor-navigation/index.d.ts +4 -0
- package/esm2022/components/anchor-navigation/anchor-navigation.component.mjs +60 -0
- package/esm2022/components/anchor-navigation/anchor-navigation.module.mjs +18 -0
- package/esm2022/components/anchor-navigation/anchor-navigation.service.mjs +119 -0
- package/esm2022/components/anchor-navigation/components/anchor-navigation-item.component.mjs +32 -0
- package/esm2022/components/anchor-navigation/components/index.mjs +2 -0
- package/esm2022/components/anchor-navigation/index.mjs +5 -0
- package/esm2022/components/anchor-navigation/odx-angular-components-anchor-navigation.mjs +5 -0
- package/fesm2022/odx-angular-components-anchor-navigation.mjs +220 -0
- package/fesm2022/odx-angular-components-anchor-navigation.mjs.map +1 -0
- package/package.json +7 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @odx/angular
|
|
2
2
|
|
|
3
|
+
## 12.15.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 16a5991: New component: Anchor Navigation
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- b20f2f7: fix: update active anchor link handling and improve styles for anchor navigation
|
|
12
|
+
|
|
3
13
|
## 12.14.2
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { AnchorNavigationItemComponent } from './components';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare class AnchorNavigationComponent {
|
|
4
|
+
private readonly service;
|
|
5
|
+
readonly element: import("@angular/core").ElementRef<HTMLElement>;
|
|
6
|
+
/**
|
|
7
|
+
* A Signal with list of `AnchorLinkDirective` instances projected into this component.
|
|
8
|
+
* These are the anchor links that this navigation component will manage.
|
|
9
|
+
*/
|
|
10
|
+
readonly projectedAnchorLinks: import("@angular/core").Signal<readonly AnchorNavigationItemComponent[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Input to determine if the anchor navigation should be displayed vertically.
|
|
13
|
+
* Defaults to `false` (horizontal).
|
|
14
|
+
*/
|
|
15
|
+
vertical: import("@angular/core").InputSignalWithTransform<boolean, boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Input to specify the scrollable container element or document whose scroll position
|
|
18
|
+
* is used to determine the active anchor link. If not provided, defaults to the
|
|
19
|
+
* `document` of the current window.
|
|
20
|
+
*/
|
|
21
|
+
scrollableContainer: import("@angular/core").InputSignal<HTMLElement | Document | undefined>;
|
|
22
|
+
readonly activeAnchorLink: import("@angular/core").WritableSignal<AnchorNavigationItemComponent | null>;
|
|
23
|
+
constructor();
|
|
24
|
+
/**
|
|
25
|
+
* Scrolls the view to the section associated with the given `AnchorLinkDirective`.
|
|
26
|
+
* @param anchor The `AnchorLinkDirective` instance representing the target anchor/section.
|
|
27
|
+
*/
|
|
28
|
+
scrollToAnchor(anchor: AnchorNavigationItemComponent): void;
|
|
29
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AnchorNavigationComponent, never>;
|
|
30
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AnchorNavigationComponent, "odx-anchor-navigation", never, { "vertical": { "alias": "vertical"; "required": false; "isSignal": true; }; "scrollableContainer": { "alias": "root"; "required": false; "isSignal": true; }; }, {}, ["projectedAnchorLinks"], ["odx-anchor-navigation-item"], true, never>;
|
|
31
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import * as i1 from "./anchor-navigation.component";
|
|
3
|
+
import * as i2 from "./components/anchor-navigation-item.component";
|
|
4
|
+
export declare class AnchorNavigationModule {
|
|
5
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AnchorNavigationModule, never>;
|
|
6
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<AnchorNavigationModule, never, [typeof i1.AnchorNavigationComponent, typeof i2.AnchorNavigationItemComponent], [typeof i1.AnchorNavigationComponent, typeof i2.AnchorNavigationItemComponent]>;
|
|
7
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<AnchorNavigationModule>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { OnDestroy, WritableSignal } from '@angular/core';
|
|
2
|
+
import { AnchorNavigationItemComponent } from './components/anchor-navigation-item.component';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export declare class AnchorNavigationService implements OnDestroy {
|
|
5
|
+
private readonly windowRef;
|
|
6
|
+
private intersectionObserver?;
|
|
7
|
+
private readonly intersectionStates;
|
|
8
|
+
private readonly targetScrollSections;
|
|
9
|
+
/**
|
|
10
|
+
* A WritableSignal holding the scrollable container element or document.
|
|
11
|
+
* This is set by the AnchorNavigationComponent.
|
|
12
|
+
* Defaults to the window's document.
|
|
13
|
+
*/
|
|
14
|
+
scrollableContainer: WritableSignal<HTMLElement | Document>;
|
|
15
|
+
/**
|
|
16
|
+
* A WritableSignal holding an array of `AnchorLinkDirective` instances.
|
|
17
|
+
* These are the links managed by the service, typically set by the `AnchorNavigationComponent`
|
|
18
|
+
* based on its projected content.
|
|
19
|
+
*/
|
|
20
|
+
projectedAnchorLinks: WritableSignal<readonly AnchorNavigationItemComponent[]>;
|
|
21
|
+
/**
|
|
22
|
+
* A readonly Signal indicating the currently active AnchorLinkDirective.
|
|
23
|
+
* This is updated by the service based on scroll position and intersection.
|
|
24
|
+
*/
|
|
25
|
+
readonly activeAnchorLink: WritableSignal<AnchorNavigationItemComponent | null>;
|
|
26
|
+
constructor();
|
|
27
|
+
ngOnDestroy(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Scrolls the view to the section associated with the given `AnchorLinkDirective`
|
|
30
|
+
* and sets it as the active link.
|
|
31
|
+
*
|
|
32
|
+
* @param anchor The `AnchorLinkDirective` instance representing the target anchor/section.
|
|
33
|
+
* If null or if the anchor's ID is not found, a warning is logged and the method returns.
|
|
34
|
+
*/
|
|
35
|
+
scrollToAnchor(anchor: AnchorNavigationItemComponent | null): void;
|
|
36
|
+
private initIntersectionObserver;
|
|
37
|
+
private updateObservedElements;
|
|
38
|
+
private onIntersectionUpdate;
|
|
39
|
+
private findTargetScrollSections;
|
|
40
|
+
private disconnectObserver;
|
|
41
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AnchorNavigationService, never>;
|
|
42
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AnchorNavigationService>;
|
|
43
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
export declare class AnchorNavigationItemComponent {
|
|
3
|
+
private readonly navigationService;
|
|
4
|
+
readonly element: import("@angular/core").ElementRef<HTMLElement>;
|
|
5
|
+
href: import("@angular/core").InputSignal<string>;
|
|
6
|
+
isActive: import("@angular/core").Signal<boolean>;
|
|
7
|
+
protected handleClick(e: Event): void;
|
|
8
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AnchorNavigationItemComponent, never>;
|
|
9
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AnchorNavigationItemComponent, "odx-anchor-navigation-item", never, { "href": { "alias": "href"; "required": true; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './anchor-navigation-item.component';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { __decorate, __metadata } from "tslib";
|
|
2
|
+
import { booleanAttribute, ChangeDetectionStrategy, Component, contentChildren, effect, inject, input, ViewEncapsulation } from '@angular/core';
|
|
3
|
+
import { CSSComponent } from '@odx/angular/internal';
|
|
4
|
+
import { injectElement } from '@odx/angular/utils';
|
|
5
|
+
import { AnchorNavigationService } from './anchor-navigation.service';
|
|
6
|
+
import { AnchorNavigationItemComponent } from './components';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
let AnchorNavigationComponent = class AnchorNavigationComponent {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.service = inject(AnchorNavigationService);
|
|
11
|
+
this.element = injectElement();
|
|
12
|
+
/**
|
|
13
|
+
* A Signal with list of `AnchorLinkDirective` instances projected into this component.
|
|
14
|
+
* These are the anchor links that this navigation component will manage.
|
|
15
|
+
*/
|
|
16
|
+
this.projectedAnchorLinks = contentChildren(AnchorNavigationItemComponent);
|
|
17
|
+
/**
|
|
18
|
+
* Input to determine if the anchor navigation should be displayed vertically.
|
|
19
|
+
* Defaults to `false` (horizontal).
|
|
20
|
+
*/
|
|
21
|
+
this.vertical = input(false, { transform: booleanAttribute });
|
|
22
|
+
/**
|
|
23
|
+
* Input to specify the scrollable container element or document whose scroll position
|
|
24
|
+
* is used to determine the active anchor link. If not provided, defaults to the
|
|
25
|
+
* `document` of the current window.
|
|
26
|
+
*/
|
|
27
|
+
// eslint-disable-next-line @angular-eslint/no-input-rename
|
|
28
|
+
this.scrollableContainer = input(undefined, { alias: 'root' });
|
|
29
|
+
this.activeAnchorLink = this.service.activeAnchorLink;
|
|
30
|
+
effect(() => {
|
|
31
|
+
this.service.projectedAnchorLinks.set(this.projectedAnchorLinks());
|
|
32
|
+
const rcInput = this.scrollableContainer();
|
|
33
|
+
if (rcInput !== undefined) {
|
|
34
|
+
this.service.scrollableContainer.set(rcInput);
|
|
35
|
+
}
|
|
36
|
+
}, { allowSignalWrites: true });
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Scrolls the view to the section associated with the given `AnchorLinkDirective`.
|
|
40
|
+
* @param anchor The `AnchorLinkDirective` instance representing the target anchor/section.
|
|
41
|
+
*/
|
|
42
|
+
scrollToAnchor(anchor) {
|
|
43
|
+
this.service.scrollToAnchor(anchor);
|
|
44
|
+
}
|
|
45
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
46
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.13", type: AnchorNavigationComponent, isStandalone: true, selector: "odx-anchor-navigation", inputs: { vertical: { classPropertyName: "vertical", publicName: "vertical", isSignal: true, isRequired: false, transformFunction: null }, scrollableContainer: { classPropertyName: "scrollableContainer", publicName: "root", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.odx-anchor-navigation--vertical": "vertical()", "attr.role": "\"navigation\"" } }, providers: [AnchorNavigationService], queries: [{ propertyName: "projectedAnchorLinks", predicate: AnchorNavigationItemComponent, isSignal: true }], ngImport: i0, template: "<ng-content select=\"odx-anchor-navigation-item\" />\n", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
47
|
+
};
|
|
48
|
+
AnchorNavigationComponent = __decorate([
|
|
49
|
+
CSSComponent('anchor-navigation'),
|
|
50
|
+
__metadata("design:paramtypes", [])
|
|
51
|
+
], AnchorNavigationComponent);
|
|
52
|
+
export { AnchorNavigationComponent };
|
|
53
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationComponent, decorators: [{
|
|
54
|
+
type: Component,
|
|
55
|
+
args: [{ selector: 'odx-anchor-navigation', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, encapsulation: ViewEncapsulation.None, providers: [AnchorNavigationService], host: {
|
|
56
|
+
'[class.odx-anchor-navigation--vertical]': 'vertical()',
|
|
57
|
+
'[attr.role]': '"navigation"',
|
|
58
|
+
}, template: "<ng-content select=\"odx-anchor-navigation-item\" />\n" }]
|
|
59
|
+
}], ctorParameters: () => [] });
|
|
60
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5jaG9yLW5hdmlnYXRpb24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9hbmd1bGFyL2NvbXBvbmVudHMvYW5jaG9yLW5hdmlnYXRpb24vc3JjL2FuY2hvci1uYXZpZ2F0aW9uLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvYW5ndWxhci9jb21wb25lbnRzL2FuY2hvci1uYXZpZ2F0aW9uL3NyYy9hbmNob3ItbmF2aWdhdGlvbi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLGdCQUFnQixFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEosT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxjQUFjLENBQUM7O0FBZXRELElBQU0seUJBQXlCLEdBQS9CLE1BQU0seUJBQXlCO0lBMEJwQztRQXpCaUIsWUFBTyxHQUFHLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQzNDLFlBQU8sR0FBRyxhQUFhLEVBQUUsQ0FBQztRQUUxQzs7O1dBR0c7UUFDYSx5QkFBb0IsR0FBRyxlQUFlLENBQUMsNkJBQTZCLENBQUMsQ0FBQztRQUV0Rjs7O1dBR0c7UUFDSSxhQUFRLEdBQUcsS0FBSyxDQUFtQixLQUFLLEVBQUUsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO1FBRWxGOzs7O1dBSUc7UUFDSCwyREFBMkQ7UUFDcEQsd0JBQW1CLEdBQUcsS0FBSyxDQUFxQyxTQUFTLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUVyRixxQkFBZ0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDO1FBRy9ELE1BQU0sQ0FDSixHQUFHLEVBQUU7WUFDSCxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1lBQ25FLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBRTNDLElBQUksT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUMxQixJQUFJLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNoRCxDQUFDO1FBQ0gsQ0FBQyxFQUNELEVBQUUsaUJBQWlCLEVBQUUsSUFBSSxFQUFFLENBQzVCLENBQUM7SUFDSixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksY0FBYyxDQUFDLE1BQXFDO1FBQ3pELElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RDLENBQUM7K0dBOUNVLHlCQUF5QjttR0FBekIseUJBQXlCLG9kQU56QixDQUFDLHVCQUF1QixDQUFDLCtEQWNtQiw2QkFBNkIsNkNDM0J0Rix3REFDQTs7QURrQmEseUJBQXlCO0lBYnJDLFlBQVksQ0FBQyxtQkFBbUIsQ0FBQzs7R0FhckIseUJBQXlCLENBK0NyQzs7NEZBL0NZLHlCQUF5QjtrQkFackMsU0FBUzsrQkFDRSx1QkFBdUIsbUJBRWhCLHVCQUF1QixDQUFDLE1BQU0sY0FDbkMsSUFBSSxpQkFDRCxpQkFBaUIsQ0FBQyxJQUFJLGFBQzFCLENBQUMsdUJBQXVCLENBQUMsUUFDOUI7d0JBQ0oseUNBQXlDLEVBQUUsWUFBWTt3QkFDdkQsYUFBYSxFQUFFLGNBQWM7cUJBQzlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYm9vbGVhbkF0dHJpYnV0ZSwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgY29udGVudENoaWxkcmVuLCBlZmZlY3QsIGluamVjdCwgaW5wdXQsIFZpZXdFbmNhcHN1bGF0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDU1NDb21wb25lbnQgfSBmcm9tICdAb2R4L2FuZ3VsYXIvaW50ZXJuYWwnO1xuaW1wb3J0IHsgaW5qZWN0RWxlbWVudCB9IGZyb20gJ0BvZHgvYW5ndWxhci91dGlscyc7XG5pbXBvcnQgeyBBbmNob3JOYXZpZ2F0aW9uU2VydmljZSB9IGZyb20gJy4vYW5jaG9yLW5hdmlnYXRpb24uc2VydmljZSc7XG5pbXBvcnQgeyBBbmNob3JOYXZpZ2F0aW9uSXRlbUNvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cyc7XG5cbkBDU1NDb21wb25lbnQoJ2FuY2hvci1uYXZpZ2F0aW9uJylcbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ29keC1hbmNob3ItbmF2aWdhdGlvbicsXG4gIHRlbXBsYXRlVXJsOiAnLi9hbmNob3ItbmF2aWdhdGlvbi5jb21wb25lbnQuaHRtbCcsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBwcm92aWRlcnM6IFtBbmNob3JOYXZpZ2F0aW9uU2VydmljZV0sXG4gIGhvc3Q6IHtcbiAgICAnW2NsYXNzLm9keC1hbmNob3ItbmF2aWdhdGlvbi0tdmVydGljYWxdJzogJ3ZlcnRpY2FsKCknLFxuICAgICdbYXR0ci5yb2xlXSc6ICdcIm5hdmlnYXRpb25cIicsXG4gIH0sXG59KVxuZXhwb3J0IGNsYXNzIEFuY2hvck5hdmlnYXRpb25Db21wb25lbnQge1xuICBwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2UgPSBpbmplY3QoQW5jaG9yTmF2aWdhdGlvblNlcnZpY2UpO1xuICBwdWJsaWMgcmVhZG9ubHkgZWxlbWVudCA9IGluamVjdEVsZW1lbnQoKTtcblxuICAvKipcbiAgICogQSBTaWduYWwgd2l0aCBsaXN0IG9mIGBBbmNob3JMaW5rRGlyZWN0aXZlYCBpbnN0YW5jZXMgcHJvamVjdGVkIGludG8gdGhpcyBjb21wb25lbnQuXG4gICAqIFRoZXNlIGFyZSB0aGUgYW5jaG9yIGxpbmtzIHRoYXQgdGhpcyBuYXZpZ2F0aW9uIGNvbXBvbmVudCB3aWxsIG1hbmFnZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBwcm9qZWN0ZWRBbmNob3JMaW5rcyA9IGNvbnRlbnRDaGlsZHJlbihBbmNob3JOYXZpZ2F0aW9uSXRlbUNvbXBvbmVudCk7XG5cbiAgLyoqXG4gICAqIElucHV0IHRvIGRldGVybWluZSBpZiB0aGUgYW5jaG9yIG5hdmlnYXRpb24gc2hvdWxkIGJlIGRpc3BsYXllZCB2ZXJ0aWNhbGx5LlxuICAgKiBEZWZhdWx0cyB0byBgZmFsc2VgIChob3Jpem9udGFsKS5cbiAgICovXG4gIHB1YmxpYyB2ZXJ0aWNhbCA9IGlucHV0PGJvb2xlYW4sIGJvb2xlYW4+KGZhbHNlLCB7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KTtcblxuICAvKipcbiAgICogSW5wdXQgdG8gc3BlY2lmeSB0aGUgc2Nyb2xsYWJsZSBjb250YWluZXIgZWxlbWVudCBvciBkb2N1bWVudCB3aG9zZSBzY3JvbGwgcG9zaXRpb25cbiAgICogaXMgdXNlZCB0byBkZXRlcm1pbmUgdGhlIGFjdGl2ZSBhbmNob3IgbGluay4gSWYgbm90IHByb3ZpZGVkLCBkZWZhdWx0cyB0byB0aGVcbiAgICogYGRvY3VtZW50YCBvZiB0aGUgY3VycmVudCB3aW5kb3cuXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L25vLWlucHV0LXJlbmFtZVxuICBwdWJsaWMgc2Nyb2xsYWJsZUNvbnRhaW5lciA9IGlucHV0PEhUTUxFbGVtZW50IHwgRG9jdW1lbnQgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCwgeyBhbGlhczogJ3Jvb3QnIH0pO1xuXG4gIHB1YmxpYyByZWFkb25seSBhY3RpdmVBbmNob3JMaW5rID0gdGhpcy5zZXJ2aWNlLmFjdGl2ZUFuY2hvckxpbms7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgZWZmZWN0KFxuICAgICAgKCkgPT4ge1xuICAgICAgICB0aGlzLnNlcnZpY2UucHJvamVjdGVkQW5jaG9yTGlua3Muc2V0KHRoaXMucHJvamVjdGVkQW5jaG9yTGlua3MoKSk7XG4gICAgICAgIGNvbnN0IHJjSW5wdXQgPSB0aGlzLnNjcm9sbGFibGVDb250YWluZXIoKTtcblxuICAgICAgICBpZiAocmNJbnB1dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhpcy5zZXJ2aWNlLnNjcm9sbGFibGVDb250YWluZXIuc2V0KHJjSW5wdXQpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgeyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9LFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogU2Nyb2xscyB0aGUgdmlldyB0byB0aGUgc2VjdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIGBBbmNob3JMaW5rRGlyZWN0aXZlYC5cbiAgICogQHBhcmFtIGFuY2hvciBUaGUgYEFuY2hvckxpbmtEaXJlY3RpdmVgIGluc3RhbmNlIHJlcHJlc2VudGluZyB0aGUgdGFyZ2V0IGFuY2hvci9zZWN0aW9uLlxuICAgKi9cbiAgcHVibGljIHNjcm9sbFRvQW5jaG9yKGFuY2hvcjogQW5jaG9yTmF2aWdhdGlvbkl0ZW1Db21wb25lbnQpOiB2b2lkIHtcbiAgICB0aGlzLnNlcnZpY2Uuc2Nyb2xsVG9BbmNob3IoYW5jaG9yKTtcbiAgfVxufVxuIiwiPG5nLWNvbnRlbnQgc2VsZWN0PVwib2R4LWFuY2hvci1uYXZpZ2F0aW9uLWl0ZW1cIiAvPlxuIl19
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { AnchorNavigationComponent } from './anchor-navigation.component';
|
|
3
|
+
import { AnchorNavigationItemComponent } from './components';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
const modules = [AnchorNavigationComponent, AnchorNavigationItemComponent];
|
|
6
|
+
export class AnchorNavigationModule {
|
|
7
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
8
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationModule, imports: [AnchorNavigationComponent, AnchorNavigationItemComponent], exports: [AnchorNavigationComponent, AnchorNavigationItemComponent] }); }
|
|
9
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationModule }); }
|
|
10
|
+
}
|
|
11
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationModule, decorators: [{
|
|
12
|
+
type: NgModule,
|
|
13
|
+
args: [{
|
|
14
|
+
imports: modules,
|
|
15
|
+
exports: modules,
|
|
16
|
+
}]
|
|
17
|
+
}] });
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5jaG9yLW5hdmlnYXRpb24ubW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9hbmd1bGFyL2NvbXBvbmVudHMvYW5jaG9yLW5hdmlnYXRpb24vc3JjL2FuY2hvci1uYXZpZ2F0aW9uLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzFFLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7QUFFN0QsTUFBTSxPQUFPLEdBQUcsQ0FBQyx5QkFBeUIsRUFBRSw2QkFBNkIsQ0FBQyxDQUFDO0FBTTNFLE1BQU0sT0FBTyxzQkFBc0I7K0dBQXRCLHNCQUFzQjtnSEFBdEIsc0JBQXNCLFlBTmxCLHlCQUF5QixFQUFFLDZCQUE2QixhQUF4RCx5QkFBeUIsRUFBRSw2QkFBNkI7Z0hBTTVELHNCQUFzQjs7NEZBQXRCLHNCQUFzQjtrQkFKbEMsUUFBUTttQkFBQztvQkFDUixPQUFPLEVBQUUsT0FBTztvQkFDaEIsT0FBTyxFQUFFLE9BQU87aUJBQ2pCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFuY2hvck5hdmlnYXRpb25Db21wb25lbnQgfSBmcm9tICcuL2FuY2hvci1uYXZpZ2F0aW9uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBBbmNob3JOYXZpZ2F0aW9uSXRlbUNvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cyc7XG5cbmNvbnN0IG1vZHVsZXMgPSBbQW5jaG9yTmF2aWdhdGlvbkNvbXBvbmVudCwgQW5jaG9yTmF2aWdhdGlvbkl0ZW1Db21wb25lbnRdO1xuXG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBtb2R1bGVzLFxuICBleHBvcnRzOiBtb2R1bGVzLFxufSlcbmV4cG9ydCBjbGFzcyBBbmNob3JOYXZpZ2F0aW9uTW9kdWxlIHt9XG4iXX0=
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { computed, effect, inject, Injectable, signal } from '@angular/core';
|
|
2
|
+
import { WindowRef } from '@odx/angular';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export class AnchorNavigationService {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.windowRef = inject(WindowRef);
|
|
7
|
+
this.intersectionStates = new Map();
|
|
8
|
+
this.targetScrollSections = computed(() => this.findTargetScrollSections());
|
|
9
|
+
/**
|
|
10
|
+
* A WritableSignal holding the scrollable container element or document.
|
|
11
|
+
* This is set by the AnchorNavigationComponent.
|
|
12
|
+
* Defaults to the window's document.
|
|
13
|
+
*/
|
|
14
|
+
this.scrollableContainer = signal(this.windowRef.document);
|
|
15
|
+
/**
|
|
16
|
+
* A WritableSignal holding an array of `AnchorLinkDirective` instances.
|
|
17
|
+
* These are the links managed by the service, typically set by the `AnchorNavigationComponent`
|
|
18
|
+
* based on its projected content.
|
|
19
|
+
*/
|
|
20
|
+
this.projectedAnchorLinks = signal([]);
|
|
21
|
+
/**
|
|
22
|
+
* A readonly Signal indicating the currently active AnchorLinkDirective.
|
|
23
|
+
* This is updated by the service based on scroll position and intersection.
|
|
24
|
+
*/
|
|
25
|
+
this.activeAnchorLink = signal(null);
|
|
26
|
+
effect((onCleanup) => {
|
|
27
|
+
const currentRoot = this.scrollableContainer();
|
|
28
|
+
const currentLinks = this.projectedAnchorLinks();
|
|
29
|
+
if (!currentLinks.length) {
|
|
30
|
+
this.disconnectObserver();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
this.initIntersectionObserver(currentRoot);
|
|
34
|
+
this.updateObservedElements();
|
|
35
|
+
onCleanup(() => {
|
|
36
|
+
this.disconnectObserver();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
ngOnDestroy() {
|
|
41
|
+
this.disconnectObserver();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Scrolls the view to the section associated with the given `AnchorLinkDirective`
|
|
45
|
+
* and sets it as the active link.
|
|
46
|
+
*
|
|
47
|
+
* @param anchor The `AnchorLinkDirective` instance representing the target anchor/section.
|
|
48
|
+
* If null or if the anchor's ID is not found, a warning is logged and the method returns.
|
|
49
|
+
*/
|
|
50
|
+
scrollToAnchor(anchor) {
|
|
51
|
+
const anchorId = anchor?.href();
|
|
52
|
+
if (!anchorId) {
|
|
53
|
+
console.warn(`[AnchorNavigationService] Attempted to scroll to an anchor without an ID.`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const anchorElement = this.scrollableContainer().querySelector(`#${CSS.escape(anchorId)}`);
|
|
57
|
+
if (!anchorElement) {
|
|
58
|
+
console.warn(`[AnchorNavigationService] Anchor with ID "${anchorId}" not found in the root container.`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
anchorElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
62
|
+
}
|
|
63
|
+
initIntersectionObserver(root) {
|
|
64
|
+
if (this.intersectionObserver) {
|
|
65
|
+
this.intersectionObserver.disconnect();
|
|
66
|
+
}
|
|
67
|
+
this.intersectionObserver = new IntersectionObserver((entries) => this.onIntersectionUpdate(entries), {
|
|
68
|
+
root: root === this.windowRef.document ? null : root,
|
|
69
|
+
threshold: 0.1,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
updateObservedElements() {
|
|
73
|
+
if (!this.intersectionObserver)
|
|
74
|
+
return;
|
|
75
|
+
this.intersectionObserver.disconnect();
|
|
76
|
+
this.intersectionStates.clear();
|
|
77
|
+
const sections = this.targetScrollSections();
|
|
78
|
+
sections.forEach((section) => {
|
|
79
|
+
if (section) {
|
|
80
|
+
this.intersectionStates.set(section, false);
|
|
81
|
+
this.intersectionObserver.observe(section);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
onIntersectionUpdate(entries) {
|
|
86
|
+
entries.forEach((entry) => this.intersectionStates.set(entry.target, entry.isIntersecting));
|
|
87
|
+
let newActiveCandidate = null;
|
|
88
|
+
const currentSections = this.targetScrollSections();
|
|
89
|
+
for (const section of currentSections) {
|
|
90
|
+
if (this.intersectionStates.get(section) === true) {
|
|
91
|
+
newActiveCandidate = this.projectedAnchorLinks().find((link) => link.href() === section.id) || null;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (this.activeAnchorLink() !== newActiveCandidate)
|
|
96
|
+
this.activeAnchorLink.set(newActiveCandidate);
|
|
97
|
+
}
|
|
98
|
+
findTargetScrollSections() {
|
|
99
|
+
const currentLinks = this.projectedAnchorLinks();
|
|
100
|
+
if (!currentLinks.length)
|
|
101
|
+
return [];
|
|
102
|
+
const selectors = currentLinks
|
|
103
|
+
.map((link) => link.href())
|
|
104
|
+
.filter(Boolean)
|
|
105
|
+
.map((id) => `#${CSS.escape(id)}`)
|
|
106
|
+
.join(',');
|
|
107
|
+
return selectors ? Array.from(this.scrollableContainer().querySelectorAll(selectors)) : [];
|
|
108
|
+
}
|
|
109
|
+
disconnectObserver() {
|
|
110
|
+
this.intersectionObserver?.disconnect();
|
|
111
|
+
this.intersectionObserver = undefined;
|
|
112
|
+
}
|
|
113
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
114
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationService }); }
|
|
115
|
+
}
|
|
116
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationService, decorators: [{
|
|
117
|
+
type: Injectable
|
|
118
|
+
}], ctorParameters: () => [] });
|
|
119
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5jaG9yLW5hdmlnYXRpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvYW5ndWxhci9jb21wb25lbnRzL2FuY2hvci1uYXZpZ2F0aW9uL3NyYy9hbmNob3ItbmF2aWdhdGlvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQWEsTUFBTSxFQUFrQixNQUFNLGVBQWUsQ0FBQztBQUN4RyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDOztBQUl6QyxNQUFNLE9BQU8sdUJBQXVCO0lBMkJsQztRQTFCaUIsY0FBUyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUU5Qix1QkFBa0IsR0FBRyxJQUFJLEdBQUcsRUFBb0IsQ0FBQztRQUVqRCx5QkFBb0IsR0FBRyxRQUFRLENBQWdCLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDLENBQUM7UUFFdkc7Ozs7V0FJRztRQUNJLHdCQUFtQixHQUEyQyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUVyRzs7OztXQUlHO1FBQ0kseUJBQW9CLEdBQTZELE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUVuRzs7O1dBR0c7UUFDYSxxQkFBZ0IsR0FBRyxNQUFNLENBQXVDLElBQUksQ0FBQyxDQUFDO1FBR3BGLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFO1lBQ25CLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQy9DLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBRWpELElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ3pCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxD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QUN4QyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsU0FBUyxDQUFDO0lBQ3hDLENBQUM7K0dBL0hVLHVCQUF1QjttSEFBdkIsdUJBQXVCOzs0RkFBdkIsdUJBQXVCO2tCQURuQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29tcHV0ZWQsIGVmZmVjdCwgaW5qZWN0LCBJbmplY3RhYmxlLCBPbkRlc3Ryb3ksIHNpZ25hbCwgV3JpdGFibGVTaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFdpbmRvd1JlZiB9IGZyb20gJ0BvZHgvYW5ndWxhcic7XG5pbXBvcnQgeyBBbmNob3JOYXZpZ2F0aW9uSXRlbUNvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy9hbmNob3ItbmF2aWdhdGlvbi1pdGVtLmNvbXBvbmVudCc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBBbmNob3JOYXZpZ2F0aW9uU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgd2luZG93UmVmID0gaW5qZWN0KFdpbmRvd1JlZik7XG4gIHByaXZhdGUgaW50ZXJzZWN0aW9uT2JzZXJ2ZXI/OiBJbnRlcnNlY3Rpb25PYnNlcnZlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBpbnRlcnNlY3Rpb25TdGF0ZXMgPSBuZXcgTWFwPEVsZW1lbnQsIGJvb2xlYW4+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB0YXJnZXRTY3JvbGxTZWN0aW9ucyA9IGNvbXB1dGVkPEhUTUxFbGVtZW50W10+KCgpID0+IHRoaXMuZmluZFRhcmdldFNjcm9sbFNlY3Rpb25zKCkpO1xuXG4gIC8qKlxuICAgKiBBIFdyaXRhYmxlU2lnbmFsIGhvbGRpbmcgdGhlIHNjcm9sbGFibGUgY29udGFpbmVyIGVsZW1lbnQgb3IgZG9jdW1lbnQuXG4gICAqIFRoaXMgaXMgc2V0IGJ5IHRoZSBBbmNob3JOYXZpZ2F0aW9uQ29tcG9uZW50LlxuICAgKiBEZWZhdWx0cyB0byB0aGUgd2luZG93J3MgZG9jdW1lbnQuXG4gICAqL1xuICBwdWJsaWMgc2Nyb2xsYWJsZUNvbnRhaW5lcjogV3JpdGFibGVTaWduYWw8SFRNTEVsZW1lbnQgfCBEb2N1bWVudD4gPSBzaWduYWwodGhpcy53aW5kb3dSZWYuZG9jdW1lbnQpO1xuXG4gIC8qKlxuICAgKiBBIFdyaXRhYmxlU2lnbmFsIGhvbGRpbmcgYW4gYXJyYXkgb2YgYEFuY2hvckxpbmtEaXJlY3RpdmVgIGluc3RhbmNlcy5cbiAgICogVGhlc2UgYXJlIHRoZSBsaW5rcyBtYW5hZ2VkIGJ5IHRoZSBzZXJ2aWNlLCB0eXBpY2FsbHkgc2V0IGJ5IHRoZSBgQW5jaG9yTmF2aWdhdGlvbkNvbXBvbmVudGBcbiAgICogYmFzZWQgb24gaXRzIHByb2plY3RlZCBjb250ZW50LlxuICAgKi9cbiAgcHVibGljIHByb2plY3RlZEFuY2hvckxpbmtzOiBXcml0YWJsZVNpZ25hbDxyZWFkb25seSBBbmNob3JOYXZpZ2F0aW9uSXRlbUNvbXBvbmVudFtdPiA9IHNpZ25hbChbXSk7XG5cbiAgLyoqXG4gICAqIEEgcmVhZG9ubHkgU2lnbmFsIGluZGljYXRpbmcgdGhlIGN1cnJlbnRseSBhY3RpdmUgQW5jaG9yTGlua0RpcmVjdGl2ZS5cbiAgICogVGhpcyBpcyB1cGRhdGVkIGJ5IHRoZSBzZXJ2aWNlIGJhc2VkIG9uIHNjcm9sbCBwb3NpdGlvbiBhbmQgaW50ZXJzZWN0aW9uLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFjdGl2ZUFuY2hvckxpbmsgPSBzaWduYWw8QW5jaG9yTmF2aWdhdGlvbkl0ZW1Db21wb25lbnQgfCBudWxsPihudWxsKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBlZmZlY3QoKG9uQ2xlYW51cCkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudFJvb3QgPSB0aGlzLnNjcm9sbGFibGVDb250YWluZXIoKTtcbiAgICAgIGNvbnN0IGN1cnJlbnRMaW5rcyA9IHRoaXMucHJvamVjdGVkQW5jaG9yTGlua3MoKTtcblxuICAgICAgaWYgKCFjdXJyZW50TGlua3MubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuZGlzY29ubmVjdE9ic2VydmVyKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pbml0SW50ZXJzZWN0aW9uT2JzZXJ2ZXIoY3VycmVudFJvb3QpO1xuICAgICAgdGhpcy51cGRhdGVPYnNlcnZlZEVsZW1lbnRzKCk7XG5cbiAgICAgIG9uQ2xlYW51cCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGlzY29ubmVjdE9ic2VydmVyKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRpc2Nvbm5lY3RPYnNlcnZlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNjcm9sbHMgdGhlIHZpZXcgdG8gdGhlIHNlY3Rpb24gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBgQW5jaG9yTGlua0RpcmVjdGl2ZWBcbiAgICogYW5kIHNldHMgaXQgYXMgdGhlIGFjdGl2ZSBsaW5rLlxuICAgKlxuICAgKiBAcGFyYW0gYW5jaG9yIFRoZSBgQW5jaG9yTGlua0RpcmVjdGl2ZWAgaW5zdGFuY2UgcmVwcmVzZW50aW5nIHRoZSB0YXJnZXQgYW5jaG9yL3NlY3Rpb24uXG4gICAqICAgICAgICAgICAgICAgSWYgbnVsbCBvciBpZiB0aGUgYW5jaG9yJ3MgSUQgaXMgbm90IGZvdW5kLCBhIHdhcm5pbmcgaXMgbG9nZ2VkIGFuZCB0aGUgbWV0aG9kIHJldHVybnMuXG4gICAqL1xuICBwdWJsaWMgc2Nyb2xsVG9BbmNob3IoYW5jaG9yOiBBbmNob3JOYXZpZ2F0aW9uSXRlbUNvbXBvbmVudCB8IG51bGwpOiB2b2lkIHtcbiAgICBjb25zdCBhbmNob3JJZCA9IGFuY2hvcj8uaHJlZigpO1xuICAgIGlmICghYW5jaG9ySWQpIHtcbiAgICAgIGNvbnNvbGUud2FybihgW0FuY2hvck5hdmlnYXRpb25TZXJ2aWNlXSBBdHRlbXB0ZWQgdG8gc2Nyb2xsIHRvIGFuIGFuY2hvciB3aXRob3V0IGFuIElELmApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBhbmNob3JFbGVtZW50ID0gdGhpcy5zY3JvbGxhYmxlQ29udGFpbmVyKCkucXVlcnlTZWxlY3RvcihgIyR7Q1NTLmVzY2FwZShhbmNob3JJZCl9YCkgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuXG4gICAgaWYgKCFhbmNob3JFbGVtZW50KSB7XG4gICAgICBjb25zb2xlLndhcm4oYFtBbmNob3JOYXZpZ2F0aW9uU2VydmljZV0gQW5jaG9yIHdpdGggSUQgXCIke2FuY2hvcklkfVwiIG5vdCBmb3VuZCBpbiB0aGUgcm9vdCBjb250YWluZXIuYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgYW5jaG9yRWxlbWVudC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdzdGFydCcgfSk7XG4gIH1cblxuICBwcml2YXRlIGluaXRJbnRlcnNlY3Rpb25PYnNlcnZlcihyb290OiBIVE1MRWxlbWVudCB8IERvY3VtZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaW50ZXJzZWN0aW9uT2JzZXJ2ZXIpIHtcbiAgICAgIHRoaXMuaW50ZXJzZWN0aW9uT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgIH1cbiAgICB0aGlzLmludGVyc2VjdGlvbk9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbnRyaWVzOiBJbnRlcnNlY3Rpb25PYnNlcnZlckVudHJ5W10pID0+IHRoaXMub25JbnRlcnNlY3Rpb25VcGRhdGUoZW50cmllcyksIHtcbiAgICAgIHJvb3Q6IHJvb3QgPT09IHRoaXMud2luZG93UmVmLmRvY3VtZW50ID8gbnVsbCA6IHJvb3QsXG4gICAgICB0aHJlc2hvbGQ6IDAuMSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlT2JzZXJ2ZWRFbGVtZW50cygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaW50ZXJzZWN0aW9uT2JzZXJ2ZXIpIHJldHVybjtcbiAgICB0aGlzLmludGVyc2VjdGlvbk9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB0aGlzLmludGVyc2VjdGlvblN0YXRlcy5jbGVhcigpO1xuXG4gICAgY29uc3Qgc2VjdGlvbnMgPSB0aGlzLnRhcmdldFNjcm9sbFNlY3Rpb25zKCk7XG4gICAgc2VjdGlvbnMuZm9yRWFjaCgoc2VjdGlvbikgPT4ge1xuICAgICAgaWYgKHNlY3Rpb24pIHtcbiAgICAgICAgdGhpcy5pbnRlcnNlY3Rpb25TdGF0ZXMuc2V0KHNlY3Rpb24sIGZhbHNlKTtcbiAgICAgICAgdGhpcy5pbnRlcnNlY3Rpb25PYnNlcnZlciEub2JzZXJ2ZShzZWN0aW9uKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgb25JbnRlcnNlY3Rpb25VcGRhdGUoZW50cmllczogSW50ZXJzZWN0aW9uT2JzZXJ2ZXJFbnRyeVtdKTogdm9pZCB7XG4gICAgZW50cmllcy5mb3JFYWNoKChlbnRyeSkgPT4gdGhpcy5pbnRlcnNlY3Rpb25TdGF0ZXMuc2V0KGVudHJ5LnRhcmdldCwgZW50cnkuaXNJbnRlcnNlY3RpbmcpKTtcblxuICAgIGxldCBuZXdBY3RpdmVDYW5kaWRhdGU6IEFuY2hvck5hdmlnYXRpb25JdGVtQ29tcG9uZW50IHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3QgY3VycmVudFNlY3Rpb25zID0gdGhpcy50YXJnZXRTY3JvbGxTZWN0aW9ucygpO1xuICAgIGZvciAoY29uc3Qgc2VjdGlvbiBvZiBjdXJyZW50U2VjdGlvbnMpIHtcbiAgICAgIGlmICh0aGlzLmludGVyc2VjdGlvblN0YXRlcy5nZXQoc2VjdGlvbikgPT09IHRydWUpIHtcbiAgICAgICAgbmV3QWN0aXZlQ2FuZGlkYXRlID0gdGhpcy5wcm9qZWN0ZWRBbmNob3JMaW5rcygpLmZpbmQoKGxpbmspID0+IGxpbmsuaHJlZigpID09PSBzZWN0aW9uLmlkKSB8fCBudWxsO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5hY3RpdmVBbmNob3JMaW5rKCkgIT09IG5ld0FjdGl2ZUNhbmRpZGF0ZSkgdGhpcy5hY3RpdmVBbmNob3JMaW5rLnNldChuZXdBY3RpdmVDYW5kaWRhdGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kVGFyZ2V0U2Nyb2xsU2VjdGlvbnMoKTogSFRNTEVsZW1lbnRbXSB7XG4gICAgY29uc3QgY3VycmVudExpbmtzID0gdGhpcy5wcm9qZWN0ZWRBbmNob3JMaW5rcygpO1xuICAgIGlmICghY3VycmVudExpbmtzLmxlbmd0aCkgcmV0dXJuIFtdO1xuXG4gICAgY29uc3Qgc2VsZWN0b3JzID0gY3VycmVudExpbmtzXG4gICAgICAubWFwKChsaW5rKSA9PiBsaW5rLmhyZWYoKSlcbiAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgIC5tYXAoKGlkKSA9PiBgIyR7Q1NTLmVzY2FwZShpZCl9YClcbiAgICAgIC5qb2luKCcsJyk7XG4gICAgcmV0dXJuIHNlbGVjdG9ycyA/IEFycmF5LmZyb20odGhpcy5zY3JvbGxhYmxlQ29udGFpbmVyKCkucXVlcnlTZWxlY3RvckFsbDxIVE1MRWxlbWVudD4oc2VsZWN0b3JzKSkgOiBbXTtcbiAgfVxuXG4gIHByaXZhdGUgZGlzY29ubmVjdE9ic2VydmVyKCk6IHZvaWQge1xuICAgIHRoaXMuaW50ZXJzZWN0aW9uT2JzZXJ2ZXI/LmRpc2Nvbm5lY3QoKTtcbiAgICB0aGlzLmludGVyc2VjdGlvbk9ic2VydmVyID0gdW5kZWZpbmVkO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { ChangeDetectionStrategy, Component, computed, inject, input, ViewEncapsulation } from '@angular/core';
|
|
3
|
+
import { LinkDirective } from '@odx/angular/components/link';
|
|
4
|
+
import { CSSComponent } from '@odx/angular/internal';
|
|
5
|
+
import { injectElement } from '@odx/angular/utils';
|
|
6
|
+
import { AnchorNavigationService } from '../anchor-navigation.service';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
let AnchorNavigationItemComponent = class AnchorNavigationItemComponent {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.navigationService = inject(AnchorNavigationService);
|
|
11
|
+
this.element = injectElement();
|
|
12
|
+
this.href = input.required();
|
|
13
|
+
this.isActive = computed(() => this.navigationService.activeAnchorLink() === this);
|
|
14
|
+
}
|
|
15
|
+
handleClick(e) {
|
|
16
|
+
e.preventDefault();
|
|
17
|
+
this.navigationService.scrollToAnchor(this);
|
|
18
|
+
}
|
|
19
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
20
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AnchorNavigationItemComponent, isStandalone: true, selector: "odx-anchor-navigation-item", inputs: { href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.is-active": "isActive()" } }, ngImport: i0, template: "<a odxLink [href]=\"'#' + href()\" (click)=\"handleClick($event)\" (keydown.space)=\"handleClick($event)\" [attr.aria-current]=\"isActive() ? 'page' : null\">\n <ng-content />\n</a>\n", dependencies: [{ kind: "directive", type: LinkDirective, selector: "a[odxLink]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
21
|
+
};
|
|
22
|
+
AnchorNavigationItemComponent = __decorate([
|
|
23
|
+
CSSComponent('anchor-navigation-item')
|
|
24
|
+
], AnchorNavigationItemComponent);
|
|
25
|
+
export { AnchorNavigationItemComponent };
|
|
26
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationItemComponent, decorators: [{
|
|
27
|
+
type: Component,
|
|
28
|
+
args: [{ selector: 'odx-anchor-navigation-item', standalone: true, imports: [LinkDirective], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
29
|
+
'[class.is-active]': 'isActive()',
|
|
30
|
+
}, template: "<a odxLink [href]=\"'#' + href()\" (click)=\"handleClick($event)\" (keydown.space)=\"handleClick($event)\" [attr.aria-current]=\"isActive() ? 'page' : null\">\n <ng-content />\n</a>\n" }]
|
|
31
|
+
}] });
|
|
32
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5jaG9yLW5hdmlnYXRpb24taXRlbS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2FuZ3VsYXIvY29tcG9uZW50cy9hbmNob3ItbmF2aWdhdGlvbi9zcmMvY29tcG9uZW50cy9hbmNob3ItbmF2aWdhdGlvbi1pdGVtLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvYW5ndWxhci9jb21wb25lbnRzL2FuY2hvci1uYXZpZ2F0aW9uL3NyYy9jb21wb25lbnRzL2FuY2hvci1uYXZpZ2F0aW9uLWl0ZW0uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0csT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzdELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOEJBQThCLENBQUM7O0FBY2hFLElBQU0sNkJBQTZCLEdBQW5DLE1BQU0sNkJBQTZCO0lBQW5DO1FBQ1ksc0JBQWlCLEdBQUcsTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUM7UUFDckQsWUFBTyxHQUFHLGFBQWEsRUFBRSxDQUFDO1FBRW5DLFNBQUksR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFVLENBQUM7UUFDaEMsYUFBUSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQztLQU10RjtJQUpXLFdBQVcsQ0FBQyxDQUFRO1FBQzVCLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsaUJBQWlCLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzlDLENBQUM7K0dBVlUsNkJBQTZCO21HQUE3Qiw2QkFBNkIsaVJDbEIxQywwTEFHQSw0Q0RRWSxhQUFhOztBQU9aLDZCQUE2QjtJQVp6QyxZQUFZLENBQUMsd0JBQXdCLENBQUM7R0FZMUIsNkJBQTZCLENBV3pDOzs0RkFYWSw2QkFBNkI7a0JBWHpDLFNBQVM7K0JBQ0UsNEJBQTRCLGNBRTFCLElBQUksV0FDUCxDQUFDLGFBQWEsQ0FBQyxpQkFDVCxpQkFBaUIsQ0FBQyxJQUFJLG1CQUNwQix1QkFBdUIsQ0FBQyxNQUFNLFFBQ3pDO3dCQUNKLG1CQUFtQixFQUFFLFlBQVk7cUJBQ2xDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgY29tcHV0ZWQsIGluamVjdCwgaW5wdXQsIFZpZXdFbmNhcHN1bGF0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBMaW5rRGlyZWN0aXZlIH0gZnJvbSAnQG9keC9hbmd1bGFyL2NvbXBvbmVudHMvbGluayc7XG5pbXBvcnQgeyBDU1NDb21wb25lbnQgfSBmcm9tICdAb2R4L2FuZ3VsYXIvaW50ZXJuYWwnO1xuaW1wb3J0IHsgaW5qZWN0RWxlbWVudCB9IGZyb20gJ0BvZHgvYW5ndWxhci91dGlscyc7XG5pbXBvcnQgeyBBbmNob3JOYXZpZ2F0aW9uU2VydmljZSB9IGZyb20gJy4uL2FuY2hvci1uYXZpZ2F0aW9uLnNlcnZpY2UnO1xuXG5AQ1NTQ29tcG9uZW50KCdhbmNob3ItbmF2aWdhdGlvbi1pdGVtJylcbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ29keC1hbmNob3ItbmF2aWdhdGlvbi1pdGVtJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2FuY2hvci1uYXZpZ2F0aW9uLWl0ZW0uY29tcG9uZW50Lmh0bWwnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbTGlua0RpcmVjdGl2ZV0sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBob3N0OiB7XG4gICAgJ1tjbGFzcy5pcy1hY3RpdmVdJzogJ2lzQWN0aXZlKCknLFxuICB9LFxufSlcbmV4cG9ydCBjbGFzcyBBbmNob3JOYXZpZ2F0aW9uSXRlbUNvbXBvbmVudCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgbmF2aWdhdGlvblNlcnZpY2UgPSBpbmplY3QoQW5jaG9yTmF2aWdhdGlvblNlcnZpY2UpO1xuICBwdWJsaWMgcmVhZG9ubHkgZWxlbWVudCA9IGluamVjdEVsZW1lbnQoKTtcblxuICBwdWJsaWMgaHJlZiA9IGlucHV0LnJlcXVpcmVkPHN0cmluZz4oKTtcbiAgcHVibGljIGlzQWN0aXZlID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5hY3RpdmVBbmNob3JMaW5rKCkgPT09IHRoaXMpO1xuXG4gIHByb3RlY3RlZCBoYW5kbGVDbGljayhlOiBFdmVudCk6IHZvaWQge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLm5hdmlnYXRpb25TZXJ2aWNlLnNjcm9sbFRvQW5jaG9yKHRoaXMpO1xuICB9XG59XG4iLCI8YSBvZHhMaW5rIFtocmVmXT1cIicjJyArIGhyZWYoKVwiIChjbGljayk9XCJoYW5kbGVDbGljaygkZXZlbnQpXCIgKGtleWRvd24uc3BhY2UpPVwiaGFuZGxlQ2xpY2soJGV2ZW50KVwiIFthdHRyLmFyaWEtY3VycmVudF09XCJpc0FjdGl2ZSgpID8gJ3BhZ2UnIDogbnVsbFwiPlxuICA8bmctY29udGVudCAvPlxuPC9hPlxuIl19
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export * from './anchor-navigation-item.component';
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2FuZ3VsYXIvY29tcG9uZW50cy9hbmNob3ItbmF2aWdhdGlvbi9zcmMvY29tcG9uZW50cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLG9DQUFvQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9hbmNob3ItbmF2aWdhdGlvbi1pdGVtLmNvbXBvbmVudCc7XG4iXX0=
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from './anchor-navigation.component';
|
|
2
|
+
export * from './anchor-navigation.module';
|
|
3
|
+
export * from './anchor-navigation.service';
|
|
4
|
+
export * from './components';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL2FuZ3VsYXIvY29tcG9uZW50cy9hbmNob3ItbmF2aWdhdGlvbi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYywrQkFBK0IsQ0FBQztBQUM5QyxjQUFjLDRCQUE0QixDQUFDO0FBQzNDLGNBQWMsNkJBQTZCLENBQUM7QUFDNUMsY0FBYyxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2FuY2hvci1uYXZpZ2F0aW9uLmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL2FuY2hvci1uYXZpZ2F0aW9uLm1vZHVsZSc7XG5leHBvcnQgKiBmcm9tICcuL2FuY2hvci1uYXZpZ2F0aW9uLnNlcnZpY2UnO1xuZXhwb3J0ICogZnJvbSAnLi9jb21wb25lbnRzJztcbiJdfQ==
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated bundle index. Do not edit.
|
|
3
|
+
*/
|
|
4
|
+
export * from './index';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2R4LWFuZ3VsYXItY29tcG9uZW50cy1hbmNob3ItbmF2aWdhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvYW5ndWxhci9jb21wb25lbnRzL2FuY2hvci1uYXZpZ2F0aW9uL3NyYy9vZHgtYW5ndWxhci1jb21wb25lbnRzLWFuY2hvci1uYXZpZ2F0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vaW5kZXgnO1xuIl19
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { __decorate, __metadata } from 'tslib';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { inject, computed, signal, effect, Injectable, input, Component, ViewEncapsulation, ChangeDetectionStrategy, contentChildren, booleanAttribute, NgModule } from '@angular/core';
|
|
4
|
+
import { CSSComponent } from '@odx/angular/internal';
|
|
5
|
+
import { injectElement } from '@odx/angular/utils';
|
|
6
|
+
import { WindowRef } from '@odx/angular';
|
|
7
|
+
import { LinkDirective } from '@odx/angular/components/link';
|
|
8
|
+
|
|
9
|
+
class AnchorNavigationService {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.windowRef = inject(WindowRef);
|
|
12
|
+
this.intersectionStates = new Map();
|
|
13
|
+
this.targetScrollSections = computed(() => this.findTargetScrollSections());
|
|
14
|
+
/**
|
|
15
|
+
* A WritableSignal holding the scrollable container element or document.
|
|
16
|
+
* This is set by the AnchorNavigationComponent.
|
|
17
|
+
* Defaults to the window's document.
|
|
18
|
+
*/
|
|
19
|
+
this.scrollableContainer = signal(this.windowRef.document);
|
|
20
|
+
/**
|
|
21
|
+
* A WritableSignal holding an array of `AnchorLinkDirective` instances.
|
|
22
|
+
* These are the links managed by the service, typically set by the `AnchorNavigationComponent`
|
|
23
|
+
* based on its projected content.
|
|
24
|
+
*/
|
|
25
|
+
this.projectedAnchorLinks = signal([]);
|
|
26
|
+
/**
|
|
27
|
+
* A readonly Signal indicating the currently active AnchorLinkDirective.
|
|
28
|
+
* This is updated by the service based on scroll position and intersection.
|
|
29
|
+
*/
|
|
30
|
+
this.activeAnchorLink = signal(null);
|
|
31
|
+
effect((onCleanup) => {
|
|
32
|
+
const currentRoot = this.scrollableContainer();
|
|
33
|
+
const currentLinks = this.projectedAnchorLinks();
|
|
34
|
+
if (!currentLinks.length) {
|
|
35
|
+
this.disconnectObserver();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.initIntersectionObserver(currentRoot);
|
|
39
|
+
this.updateObservedElements();
|
|
40
|
+
onCleanup(() => {
|
|
41
|
+
this.disconnectObserver();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
ngOnDestroy() {
|
|
46
|
+
this.disconnectObserver();
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Scrolls the view to the section associated with the given `AnchorLinkDirective`
|
|
50
|
+
* and sets it as the active link.
|
|
51
|
+
*
|
|
52
|
+
* @param anchor The `AnchorLinkDirective` instance representing the target anchor/section.
|
|
53
|
+
* If null or if the anchor's ID is not found, a warning is logged and the method returns.
|
|
54
|
+
*/
|
|
55
|
+
scrollToAnchor(anchor) {
|
|
56
|
+
const anchorId = anchor?.href();
|
|
57
|
+
if (!anchorId) {
|
|
58
|
+
console.warn(`[AnchorNavigationService] Attempted to scroll to an anchor without an ID.`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const anchorElement = this.scrollableContainer().querySelector(`#${CSS.escape(anchorId)}`);
|
|
62
|
+
if (!anchorElement) {
|
|
63
|
+
console.warn(`[AnchorNavigationService] Anchor with ID "${anchorId}" not found in the root container.`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
anchorElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
67
|
+
}
|
|
68
|
+
initIntersectionObserver(root) {
|
|
69
|
+
if (this.intersectionObserver) {
|
|
70
|
+
this.intersectionObserver.disconnect();
|
|
71
|
+
}
|
|
72
|
+
this.intersectionObserver = new IntersectionObserver((entries) => this.onIntersectionUpdate(entries), {
|
|
73
|
+
root: root === this.windowRef.document ? null : root,
|
|
74
|
+
threshold: 0.1,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
updateObservedElements() {
|
|
78
|
+
if (!this.intersectionObserver)
|
|
79
|
+
return;
|
|
80
|
+
this.intersectionObserver.disconnect();
|
|
81
|
+
this.intersectionStates.clear();
|
|
82
|
+
const sections = this.targetScrollSections();
|
|
83
|
+
sections.forEach((section) => {
|
|
84
|
+
if (section) {
|
|
85
|
+
this.intersectionStates.set(section, false);
|
|
86
|
+
this.intersectionObserver.observe(section);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
onIntersectionUpdate(entries) {
|
|
91
|
+
entries.forEach((entry) => this.intersectionStates.set(entry.target, entry.isIntersecting));
|
|
92
|
+
let newActiveCandidate = null;
|
|
93
|
+
const currentSections = this.targetScrollSections();
|
|
94
|
+
for (const section of currentSections) {
|
|
95
|
+
if (this.intersectionStates.get(section) === true) {
|
|
96
|
+
newActiveCandidate = this.projectedAnchorLinks().find((link) => link.href() === section.id) || null;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (this.activeAnchorLink() !== newActiveCandidate)
|
|
101
|
+
this.activeAnchorLink.set(newActiveCandidate);
|
|
102
|
+
}
|
|
103
|
+
findTargetScrollSections() {
|
|
104
|
+
const currentLinks = this.projectedAnchorLinks();
|
|
105
|
+
if (!currentLinks.length)
|
|
106
|
+
return [];
|
|
107
|
+
const selectors = currentLinks
|
|
108
|
+
.map((link) => link.href())
|
|
109
|
+
.filter(Boolean)
|
|
110
|
+
.map((id) => `#${CSS.escape(id)}`)
|
|
111
|
+
.join(',');
|
|
112
|
+
return selectors ? Array.from(this.scrollableContainer().querySelectorAll(selectors)) : [];
|
|
113
|
+
}
|
|
114
|
+
disconnectObserver() {
|
|
115
|
+
this.intersectionObserver?.disconnect();
|
|
116
|
+
this.intersectionObserver = undefined;
|
|
117
|
+
}
|
|
118
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
119
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationService }); }
|
|
120
|
+
}
|
|
121
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationService, decorators: [{
|
|
122
|
+
type: Injectable
|
|
123
|
+
}], ctorParameters: () => [] });
|
|
124
|
+
|
|
125
|
+
let AnchorNavigationItemComponent = class AnchorNavigationItemComponent {
|
|
126
|
+
constructor() {
|
|
127
|
+
this.navigationService = inject(AnchorNavigationService);
|
|
128
|
+
this.element = injectElement();
|
|
129
|
+
this.href = input.required();
|
|
130
|
+
this.isActive = computed(() => this.navigationService.activeAnchorLink() === this);
|
|
131
|
+
}
|
|
132
|
+
handleClick(e) {
|
|
133
|
+
e.preventDefault();
|
|
134
|
+
this.navigationService.scrollToAnchor(this);
|
|
135
|
+
}
|
|
136
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
137
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AnchorNavigationItemComponent, isStandalone: true, selector: "odx-anchor-navigation-item", inputs: { href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.is-active": "isActive()" } }, ngImport: i0, template: "<a odxLink [href]=\"'#' + href()\" (click)=\"handleClick($event)\" (keydown.space)=\"handleClick($event)\" [attr.aria-current]=\"isActive() ? 'page' : null\">\n <ng-content />\n</a>\n", dependencies: [{ kind: "directive", type: LinkDirective, selector: "a[odxLink]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
138
|
+
};
|
|
139
|
+
AnchorNavigationItemComponent = __decorate([
|
|
140
|
+
CSSComponent('anchor-navigation-item')
|
|
141
|
+
], AnchorNavigationItemComponent);
|
|
142
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationItemComponent, decorators: [{
|
|
143
|
+
type: Component,
|
|
144
|
+
args: [{ selector: 'odx-anchor-navigation-item', standalone: true, imports: [LinkDirective], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
145
|
+
'[class.is-active]': 'isActive()',
|
|
146
|
+
}, template: "<a odxLink [href]=\"'#' + href()\" (click)=\"handleClick($event)\" (keydown.space)=\"handleClick($event)\" [attr.aria-current]=\"isActive() ? 'page' : null\">\n <ng-content />\n</a>\n" }]
|
|
147
|
+
}] });
|
|
148
|
+
|
|
149
|
+
let AnchorNavigationComponent = class AnchorNavigationComponent {
|
|
150
|
+
constructor() {
|
|
151
|
+
this.service = inject(AnchorNavigationService);
|
|
152
|
+
this.element = injectElement();
|
|
153
|
+
/**
|
|
154
|
+
* A Signal with list of `AnchorLinkDirective` instances projected into this component.
|
|
155
|
+
* These are the anchor links that this navigation component will manage.
|
|
156
|
+
*/
|
|
157
|
+
this.projectedAnchorLinks = contentChildren(AnchorNavigationItemComponent);
|
|
158
|
+
/**
|
|
159
|
+
* Input to determine if the anchor navigation should be displayed vertically.
|
|
160
|
+
* Defaults to `false` (horizontal).
|
|
161
|
+
*/
|
|
162
|
+
this.vertical = input(false, { transform: booleanAttribute });
|
|
163
|
+
/**
|
|
164
|
+
* Input to specify the scrollable container element or document whose scroll position
|
|
165
|
+
* is used to determine the active anchor link. If not provided, defaults to the
|
|
166
|
+
* `document` of the current window.
|
|
167
|
+
*/
|
|
168
|
+
// eslint-disable-next-line @angular-eslint/no-input-rename
|
|
169
|
+
this.scrollableContainer = input(undefined, { alias: 'root' });
|
|
170
|
+
this.activeAnchorLink = this.service.activeAnchorLink;
|
|
171
|
+
effect(() => {
|
|
172
|
+
this.service.projectedAnchorLinks.set(this.projectedAnchorLinks());
|
|
173
|
+
const rcInput = this.scrollableContainer();
|
|
174
|
+
if (rcInput !== undefined) {
|
|
175
|
+
this.service.scrollableContainer.set(rcInput);
|
|
176
|
+
}
|
|
177
|
+
}, { allowSignalWrites: true });
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Scrolls the view to the section associated with the given `AnchorLinkDirective`.
|
|
181
|
+
* @param anchor The `AnchorLinkDirective` instance representing the target anchor/section.
|
|
182
|
+
*/
|
|
183
|
+
scrollToAnchor(anchor) {
|
|
184
|
+
this.service.scrollToAnchor(anchor);
|
|
185
|
+
}
|
|
186
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
187
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.13", type: AnchorNavigationComponent, isStandalone: true, selector: "odx-anchor-navigation", inputs: { vertical: { classPropertyName: "vertical", publicName: "vertical", isSignal: true, isRequired: false, transformFunction: null }, scrollableContainer: { classPropertyName: "scrollableContainer", publicName: "root", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.odx-anchor-navigation--vertical": "vertical()", "attr.role": "\"navigation\"" } }, providers: [AnchorNavigationService], queries: [{ propertyName: "projectedAnchorLinks", predicate: AnchorNavigationItemComponent, isSignal: true }], ngImport: i0, template: "<ng-content select=\"odx-anchor-navigation-item\" />\n", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
188
|
+
};
|
|
189
|
+
AnchorNavigationComponent = __decorate([
|
|
190
|
+
CSSComponent('anchor-navigation'),
|
|
191
|
+
__metadata("design:paramtypes", [])
|
|
192
|
+
], AnchorNavigationComponent);
|
|
193
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationComponent, decorators: [{
|
|
194
|
+
type: Component,
|
|
195
|
+
args: [{ selector: 'odx-anchor-navigation', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, encapsulation: ViewEncapsulation.None, providers: [AnchorNavigationService], host: {
|
|
196
|
+
'[class.odx-anchor-navigation--vertical]': 'vertical()',
|
|
197
|
+
'[attr.role]': '"navigation"',
|
|
198
|
+
}, template: "<ng-content select=\"odx-anchor-navigation-item\" />\n" }]
|
|
199
|
+
}], ctorParameters: () => [] });
|
|
200
|
+
|
|
201
|
+
const modules = [AnchorNavigationComponent, AnchorNavigationItemComponent];
|
|
202
|
+
class AnchorNavigationModule {
|
|
203
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
204
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationModule, imports: [AnchorNavigationComponent, AnchorNavigationItemComponent], exports: [AnchorNavigationComponent, AnchorNavigationItemComponent] }); }
|
|
205
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationModule }); }
|
|
206
|
+
}
|
|
207
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnchorNavigationModule, decorators: [{
|
|
208
|
+
type: NgModule,
|
|
209
|
+
args: [{
|
|
210
|
+
imports: modules,
|
|
211
|
+
exports: modules,
|
|
212
|
+
}]
|
|
213
|
+
}] });
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Generated bundle index. Do not edit.
|
|
217
|
+
*/
|
|
218
|
+
|
|
219
|
+
export { AnchorNavigationComponent, AnchorNavigationItemComponent, AnchorNavigationModule, AnchorNavigationService };
|
|
220
|
+
//# sourceMappingURL=odx-angular-components-anchor-navigation.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"odx-angular-components-anchor-navigation.mjs","sources":["../../../../libs/angular/components/anchor-navigation/src/anchor-navigation.service.ts","../../../../libs/angular/components/anchor-navigation/src/components/anchor-navigation-item.component.ts","../../../../libs/angular/components/anchor-navigation/src/components/anchor-navigation-item.component.html","../../../../libs/angular/components/anchor-navigation/src/anchor-navigation.component.ts","../../../../libs/angular/components/anchor-navigation/src/anchor-navigation.component.html","../../../../libs/angular/components/anchor-navigation/src/anchor-navigation.module.ts","../../../../libs/angular/components/anchor-navigation/src/odx-angular-components-anchor-navigation.ts"],"sourcesContent":["import { computed, effect, inject, Injectable, OnDestroy, signal, WritableSignal } from '@angular/core';\nimport { WindowRef } from '@odx/angular';\nimport { AnchorNavigationItemComponent } from './components/anchor-navigation-item.component';\n\n@Injectable()\nexport class AnchorNavigationService implements OnDestroy {\n private readonly windowRef = inject(WindowRef);\n private intersectionObserver?: IntersectionObserver;\n private readonly intersectionStates = new Map<Element, boolean>();\n\n private readonly targetScrollSections = computed<HTMLElement[]>(() => this.findTargetScrollSections());\n\n /**\n * A WritableSignal holding the scrollable container element or document.\n * This is set by the AnchorNavigationComponent.\n * Defaults to the window's document.\n */\n public scrollableContainer: WritableSignal<HTMLElement | Document> = signal(this.windowRef.document);\n\n /**\n * A WritableSignal holding an array of `AnchorLinkDirective` instances.\n * These are the links managed by the service, typically set by the `AnchorNavigationComponent`\n * based on its projected content.\n */\n public projectedAnchorLinks: WritableSignal<readonly AnchorNavigationItemComponent[]> = signal([]);\n\n /**\n * A readonly Signal indicating the currently active AnchorLinkDirective.\n * This is updated by the service based on scroll position and intersection.\n */\n public readonly activeAnchorLink = signal<AnchorNavigationItemComponent | null>(null);\n\n constructor() {\n effect((onCleanup) => {\n const currentRoot = this.scrollableContainer();\n const currentLinks = this.projectedAnchorLinks();\n\n if (!currentLinks.length) {\n this.disconnectObserver();\n return;\n }\n\n this.initIntersectionObserver(currentRoot);\n this.updateObservedElements();\n\n onCleanup(() => {\n this.disconnectObserver();\n });\n });\n }\n\n public ngOnDestroy(): void {\n this.disconnectObserver();\n }\n\n /**\n * Scrolls the view to the section associated with the given `AnchorLinkDirective`\n * and sets it as the active link.\n *\n * @param anchor The `AnchorLinkDirective` instance representing the target anchor/section.\n * If null or if the anchor's ID is not found, a warning is logged and the method returns.\n */\n public scrollToAnchor(anchor: AnchorNavigationItemComponent | null): void {\n const anchorId = anchor?.href();\n if (!anchorId) {\n console.warn(`[AnchorNavigationService] Attempted to scroll to an anchor without an ID.`);\n return;\n }\n const anchorElement = this.scrollableContainer().querySelector(`#${CSS.escape(anchorId)}`) as HTMLElement | null;\n\n if (!anchorElement) {\n console.warn(`[AnchorNavigationService] Anchor with ID \"${anchorId}\" not found in the root container.`);\n return;\n }\n\n anchorElement.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n\n private initIntersectionObserver(root: HTMLElement | Document): void {\n if (this.intersectionObserver) {\n this.intersectionObserver.disconnect();\n }\n this.intersectionObserver = new IntersectionObserver((entries: IntersectionObserverEntry[]) => this.onIntersectionUpdate(entries), {\n root: root === this.windowRef.document ? null : root,\n threshold: 0.1,\n });\n }\n\n private updateObservedElements(): void {\n if (!this.intersectionObserver) return;\n this.intersectionObserver.disconnect();\n this.intersectionStates.clear();\n\n const sections = this.targetScrollSections();\n sections.forEach((section) => {\n if (section) {\n this.intersectionStates.set(section, false);\n this.intersectionObserver!.observe(section);\n }\n });\n }\n\n private onIntersectionUpdate(entries: IntersectionObserverEntry[]): void {\n entries.forEach((entry) => this.intersectionStates.set(entry.target, entry.isIntersecting));\n\n let newActiveCandidate: AnchorNavigationItemComponent | null = null;\n const currentSections = this.targetScrollSections();\n for (const section of currentSections) {\n if (this.intersectionStates.get(section) === true) {\n newActiveCandidate = this.projectedAnchorLinks().find((link) => link.href() === section.id) || null;\n break;\n }\n }\n\n if (this.activeAnchorLink() !== newActiveCandidate) this.activeAnchorLink.set(newActiveCandidate);\n }\n\n private findTargetScrollSections(): HTMLElement[] {\n const currentLinks = this.projectedAnchorLinks();\n if (!currentLinks.length) return [];\n\n const selectors = currentLinks\n .map((link) => link.href())\n .filter(Boolean)\n .map((id) => `#${CSS.escape(id)}`)\n .join(',');\n return selectors ? Array.from(this.scrollableContainer().querySelectorAll<HTMLElement>(selectors)) : [];\n }\n\n private disconnectObserver(): void {\n this.intersectionObserver?.disconnect();\n this.intersectionObserver = undefined;\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input, ViewEncapsulation } from '@angular/core';\nimport { LinkDirective } from '@odx/angular/components/link';\nimport { CSSComponent } from '@odx/angular/internal';\nimport { injectElement } from '@odx/angular/utils';\nimport { AnchorNavigationService } from '../anchor-navigation.service';\n\n@CSSComponent('anchor-navigation-item')\n@Component({\n selector: 'odx-anchor-navigation-item',\n templateUrl: './anchor-navigation-item.component.html',\n standalone: true,\n imports: [LinkDirective],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.is-active]': 'isActive()',\n },\n})\nexport class AnchorNavigationItemComponent {\n private readonly navigationService = inject(AnchorNavigationService);\n public readonly element = injectElement();\n\n public href = input.required<string>();\n public isActive = computed(() => this.navigationService.activeAnchorLink() === this);\n\n protected handleClick(e: Event): void {\n e.preventDefault();\n this.navigationService.scrollToAnchor(this);\n }\n}\n","<a odxLink [href]=\"'#' + href()\" (click)=\"handleClick($event)\" (keydown.space)=\"handleClick($event)\" [attr.aria-current]=\"isActive() ? 'page' : null\">\n <ng-content />\n</a>\n","import { booleanAttribute, ChangeDetectionStrategy, Component, contentChildren, effect, inject, input, ViewEncapsulation } from '@angular/core';\nimport { CSSComponent } from '@odx/angular/internal';\nimport { injectElement } from '@odx/angular/utils';\nimport { AnchorNavigationService } from './anchor-navigation.service';\nimport { AnchorNavigationItemComponent } from './components';\n\n@CSSComponent('anchor-navigation')\n@Component({\n selector: 'odx-anchor-navigation',\n templateUrl: './anchor-navigation.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n encapsulation: ViewEncapsulation.None,\n providers: [AnchorNavigationService],\n host: {\n '[class.odx-anchor-navigation--vertical]': 'vertical()',\n '[attr.role]': '\"navigation\"',\n },\n})\nexport class AnchorNavigationComponent {\n private readonly service = inject(AnchorNavigationService);\n public readonly element = injectElement();\n\n /**\n * A Signal with list of `AnchorLinkDirective` instances projected into this component.\n * These are the anchor links that this navigation component will manage.\n */\n public readonly projectedAnchorLinks = contentChildren(AnchorNavigationItemComponent);\n\n /**\n * Input to determine if the anchor navigation should be displayed vertically.\n * Defaults to `false` (horizontal).\n */\n public vertical = input<boolean, boolean>(false, { transform: booleanAttribute });\n\n /**\n * Input to specify the scrollable container element or document whose scroll position\n * is used to determine the active anchor link. If not provided, defaults to the\n * `document` of the current window.\n */\n // eslint-disable-next-line @angular-eslint/no-input-rename\n public scrollableContainer = input<HTMLElement | Document | undefined>(undefined, { alias: 'root' });\n\n public readonly activeAnchorLink = this.service.activeAnchorLink;\n\n constructor() {\n effect(\n () => {\n this.service.projectedAnchorLinks.set(this.projectedAnchorLinks());\n const rcInput = this.scrollableContainer();\n\n if (rcInput !== undefined) {\n this.service.scrollableContainer.set(rcInput);\n }\n },\n { allowSignalWrites: true },\n );\n }\n\n /**\n * Scrolls the view to the section associated with the given `AnchorLinkDirective`.\n * @param anchor The `AnchorLinkDirective` instance representing the target anchor/section.\n */\n public scrollToAnchor(anchor: AnchorNavigationItemComponent): void {\n this.service.scrollToAnchor(anchor);\n }\n}\n","<ng-content select=\"odx-anchor-navigation-item\" />\n","import { NgModule } from '@angular/core';\nimport { AnchorNavigationComponent } from './anchor-navigation.component';\nimport { AnchorNavigationItemComponent } from './components';\n\nconst modules = [AnchorNavigationComponent, AnchorNavigationItemComponent];\n\n@NgModule({\n imports: modules,\n exports: modules,\n})\nexport class AnchorNavigationModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@odx/angular",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.15.0",
|
|
4
4
|
"author": "Drägerwerk AG & Co.KGaA",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"peerDependencies": {
|
|
@@ -166,6 +166,12 @@
|
|
|
166
166
|
"esm": "./esm2022/components/action-group/odx-angular-components-action-group.mjs",
|
|
167
167
|
"default": "./fesm2022/odx-angular-components-action-group.mjs"
|
|
168
168
|
},
|
|
169
|
+
"./components/anchor-navigation": {
|
|
170
|
+
"types": "./components/anchor-navigation/index.d.ts",
|
|
171
|
+
"esm2022": "./esm2022/components/anchor-navigation/odx-angular-components-anchor-navigation.mjs",
|
|
172
|
+
"esm": "./esm2022/components/anchor-navigation/odx-angular-components-anchor-navigation.mjs",
|
|
173
|
+
"default": "./fesm2022/odx-angular-components-anchor-navigation.mjs"
|
|
174
|
+
},
|
|
169
175
|
"./components/area-header": {
|
|
170
176
|
"types": "./components/area-header/index.d.ts",
|
|
171
177
|
"esm2022": "./esm2022/components/area-header/odx-angular-components-area-header.mjs",
|