@ngxsmk/cdk 2.0.0 → 3.0.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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Low-level, zoneless-friendly Angular behaviors that power NGXSMK components. Each behavior is its own secondary entry point, so you only bundle what you import.
4
4
 
5
- Part of the [NGXSMK UI kit](https://ngxsmk.github.io/ngxsmk-ui-kit).
5
+ Part of the [NGXSMK UI kit](https://ngxsmk.github.io/ngxsmk-ui-kit) ([WhatsApp Channel](https://whatsapp.com/channel/0029Vb8PWpz1XquUOnGPUM2p)).
6
6
 
7
7
  ## Compatibility
8
8
 
@@ -0,0 +1,2 @@
1
+ export * from './roving-focus';
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jZGsvcm92aW5nLWZvY3VzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsZ0JBQWdCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL3JvdmluZy1mb2N1cyc7XG4iXX0=
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './index';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4c21rLWNkay1yb3ZpbmctZm9jdXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jZGsvcm92aW5nLWZvY3VzL25neHNtay1jZGstcm92aW5nLWZvY3VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vaW5kZXgnO1xuIl19
@@ -0,0 +1,176 @@
1
+ import { Directive, ElementRef, InjectionToken, booleanAttribute, computed, inject, input, output, signal, } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export const NGXSMK_ROVING_FOCUS_GROUP = new InjectionToken('NGXSMK_ROVING_FOCUS_GROUP');
4
+ /**
5
+ * Universal signals-native Roving Focus container directive.
6
+ * Manages keyboard navigation (Arrow keys, Home, End) across a set of items,
7
+ * keeping only the currently active item focusable via Tab (`tabindex="0"` vs `"-1"`).
8
+ *
9
+ * ```html
10
+ * <div ngxsmkRovingFocusGroup orientation="horizontal" [loop]="true">
11
+ * <button ngxsmkRovingFocusItem>Tab 1</button>
12
+ * <button ngxsmkRovingFocusItem>Tab 2</button>
13
+ * </div>
14
+ * ```
15
+ */
16
+ export class NgxsmkRovingFocusGroup {
17
+ constructor() {
18
+ this.orientation = input('horizontal');
19
+ this.loop = input(true, { transform: booleanAttribute });
20
+ this.items = signal([]);
21
+ this.activeItem = signal(null);
22
+ }
23
+ register(item) {
24
+ this.items.update((list) => [...list, item]);
25
+ if (this.activeItem() === null && !item.disabled()) {
26
+ this.activeItem.set(item);
27
+ }
28
+ }
29
+ unregister(item) {
30
+ this.items.update((list) => list.filter((i) => i !== item));
31
+ if (this.activeItem() === item) {
32
+ const remaining = this.items().filter((i) => !i.disabled());
33
+ this.activeItem.set(remaining.length > 0 ? remaining[0] : null);
34
+ }
35
+ }
36
+ focusNext(current) {
37
+ const list = this.items().filter((i) => !i.disabled());
38
+ const idx = list.indexOf(current);
39
+ if (idx === -1)
40
+ return;
41
+ if (idx < list.length - 1) {
42
+ const next = list[idx + 1];
43
+ this.setActiveAndFocus(next);
44
+ }
45
+ else if (this.loop()) {
46
+ const first = list[0];
47
+ this.setActiveAndFocus(first);
48
+ }
49
+ }
50
+ focusPrev(current) {
51
+ const list = this.items().filter((i) => !i.disabled());
52
+ const idx = list.indexOf(current);
53
+ if (idx === -1)
54
+ return;
55
+ if (idx > 0) {
56
+ const prev = list[idx - 1];
57
+ this.setActiveAndFocus(prev);
58
+ }
59
+ else if (this.loop()) {
60
+ const last = list[list.length - 1];
61
+ this.setActiveAndFocus(last);
62
+ }
63
+ }
64
+ focusFirst() {
65
+ const list = this.items().filter((i) => !i.disabled());
66
+ if (list.length > 0) {
67
+ this.setActiveAndFocus(list[0]);
68
+ }
69
+ }
70
+ focusLast() {
71
+ const list = this.items().filter((i) => !i.disabled());
72
+ if (list.length > 0) {
73
+ this.setActiveAndFocus(list[list.length - 1]);
74
+ }
75
+ }
76
+ setActiveAndFocus(item) {
77
+ this.activeItem.set(item);
78
+ item.focus();
79
+ }
80
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkRovingFocusGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
81
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.0", type: NgxsmkRovingFocusGroup, isStandalone: true, selector: "[ngxsmkRovingFocusGroup]", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
82
+ {
83
+ provide: NGXSMK_ROVING_FOCUS_GROUP,
84
+ useExisting: NgxsmkRovingFocusGroup,
85
+ },
86
+ ], ngImport: i0 }); }
87
+ }
88
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkRovingFocusGroup, decorators: [{
89
+ type: Directive,
90
+ args: [{
91
+ standalone: true,
92
+ selector: '[ngxsmkRovingFocusGroup]',
93
+ providers: [
94
+ {
95
+ provide: NGXSMK_ROVING_FOCUS_GROUP,
96
+ useExisting: NgxsmkRovingFocusGroup,
97
+ },
98
+ ],
99
+ }]
100
+ }] });
101
+ /**
102
+ * Item in a Roving Focus group. Binds `[tabindex]` dynamically based on active state.
103
+ */
104
+ export class NgxsmkRovingFocusItem {
105
+ constructor() {
106
+ this.group = inject(NGXSMK_ROVING_FOCUS_GROUP);
107
+ this.elRef = inject((ElementRef));
108
+ this.disabled = input(false, { transform: booleanAttribute });
109
+ this.focused = output();
110
+ this.isActive = computed(() => this.group.activeItem() === this);
111
+ this.tabIndex = computed(() => {
112
+ if (this.disabled())
113
+ return -1;
114
+ return this.isActive() ? 0 : -1;
115
+ });
116
+ this.group.register(this);
117
+ }
118
+ ngOnDestroy() {
119
+ this.group.unregister(this);
120
+ }
121
+ focus() {
122
+ this.elRef.nativeElement.focus();
123
+ }
124
+ handleFocus() {
125
+ if (!this.disabled()) {
126
+ this.group.activeItem.set(this);
127
+ this.focused.emit();
128
+ }
129
+ }
130
+ handleKeydown(event) {
131
+ if (this.disabled())
132
+ return;
133
+ const orient = this.group.orientation();
134
+ const isHoriz = orient === 'horizontal' || orient === 'both';
135
+ const isVert = orient === 'vertical' || orient === 'both';
136
+ switch (event.key) {
137
+ case 'ArrowRight':
138
+ case 'ArrowDown':
139
+ if ((event.key === 'ArrowRight' && isHoriz) || (event.key === 'ArrowDown' && isVert)) {
140
+ event.preventDefault();
141
+ this.group.focusNext(this);
142
+ }
143
+ break;
144
+ case 'ArrowLeft':
145
+ case 'ArrowUp':
146
+ if ((event.key === 'ArrowLeft' && isHoriz) || (event.key === 'ArrowUp' && isVert)) {
147
+ event.preventDefault();
148
+ this.group.focusPrev(this);
149
+ }
150
+ break;
151
+ case 'Home':
152
+ event.preventDefault();
153
+ this.group.focusFirst();
154
+ break;
155
+ case 'End':
156
+ event.preventDefault();
157
+ this.group.focusLast();
158
+ break;
159
+ }
160
+ }
161
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkRovingFocusItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
162
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.0", type: NgxsmkRovingFocusItem, isStandalone: true, selector: "[ngxsmkRovingFocusItem]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { focused: "focused" }, host: { listeners: { "keydown": "handleKeydown($event)", "focus": "handleFocus()" }, properties: { "attr.tabindex": "tabIndex()" } }, ngImport: i0 }); }
163
+ }
164
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkRovingFocusItem, decorators: [{
165
+ type: Directive,
166
+ args: [{
167
+ standalone: true,
168
+ selector: '[ngxsmkRovingFocusItem]',
169
+ host: {
170
+ '[attr.tabindex]': 'tabIndex()',
171
+ '(keydown)': 'handleKeydown($event)',
172
+ '(focus)': 'handleFocus()',
173
+ },
174
+ }]
175
+ }], ctorParameters: () => [] });
176
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm92aW5nLWZvY3VzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY2RrL3JvdmluZy1mb2N1cy9yb3ZpbmctZm9jdXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxVQUFVLEVBQ1YsY0FBYyxFQUdkLGdCQUFnQixFQUNoQixRQUFRLEVBQ1IsTUFBTSxFQUNOLEtBQUssRUFDTCxNQUFNLEVBQ04sTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDOztBQWdCdkIsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQUcsSUFBSSxjQUFjLENBQ3pELDJCQUEyQixDQUM1QixDQUFDO0FBRUY7Ozs7Ozs7Ozs7O0dBV0c7QUFXSCxNQUFNLE9BQU8sc0JBQXNCO0lBVm5DO1FBV1csZ0JBQVcsR0FBRyxLQUFLLENBQTBCLFlBQVksQ0FBQyxDQUFDO1FBQzNELFNBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLENBQUMsQ0FBQztRQUU1QyxVQUFLLEdBQUcsTUFBTSxDQUEwQixFQUFFLENBQUMsQ0FBQztRQUNwRCxlQUFVLEdBQUcsTUFBTSxDQUErQixJQUFJLENBQUMsQ0FBQztLQStEbEU7SUE3REMsUUFBUSxDQUFDLElBQTJCO1FBQ2xDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDN0MsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLEtBQUssSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUM7WUFDbkQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUIsQ0FBQztJQUNILENBQUM7SUFFRCxVQUFVLENBQUMsSUFBMkI7UUFDcEMsSUFB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QVk7d0JBQy9CLFdBQVcsRUFBRSx1QkFBdUI7d0JBQ3BDLFNBQVMsRUFBRSxlQUFlO3FCQUMzQjtpQkFDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgSW5qZWN0aW9uVG9rZW4sXG4gIE9uRGVzdHJveSxcbiAgV3JpdGFibGVTaWduYWwsXG4gIGJvb2xlYW5BdHRyaWJ1dGUsXG4gIGNvbXB1dGVkLFxuICBpbmplY3QsXG4gIGlucHV0LFxuICBvdXRwdXQsXG4gIHNpZ25hbCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmV4cG9ydCB0eXBlIE5neHNta1JvdmluZ09yaWVudGF0aW9uID0gJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJyB8ICdib3RoJztcblxuZXhwb3J0IGludGVyZmFjZSBOZ3hzbWtSb3ZpbmdGb2N1c0NvbnRleHQge1xuICByZWdpc3RlcihpdGVtOiBOZ3hzbWtSb3ZpbmdGb2N1c0l0ZW0pOiB2b2lkO1xuICB1bnJlZ2lzdGVyKGl0ZW06IE5neHNta1JvdmluZ0ZvY3VzSXRlbSk6IHZvaWQ7XG4gIGZvY3VzTmV4dChjdXJyZW50OiBOZ3hzbWtSb3ZpbmdGb2N1c0l0ZW0pOiB2b2lkO1xuICBmb2N1c1ByZXYoY3VycmVudDogTmd4c21rUm92aW5nRm9jdXNJdGVtKTogdm9pZDtcbiAgZm9jdXNGaXJzdCgpOiB2b2lkO1xuICBmb2N1c0xhc3QoKTogdm9pZDtcbiAgYWN0aXZlSXRlbTogV3JpdGFibGVTaWduYWw8Tmd4c21rUm92aW5nRm9jdXNJdGVtIHwgbnVsbD47XG4gIG9yaWVudGF0aW9uOiAoKSA9PiBOZ3hzbWtSb3ZpbmdPcmllbnRhdGlvbjtcbiAgbG9vcDogKCkgPT4gYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNvbnN0IE5HWFNNS19ST1ZJTkdfRk9DVVNfR1JPVVAgPSBuZXcgSW5qZWN0aW9uVG9rZW48Tmd4c21rUm92aW5nRm9jdXNDb250ZXh0PihcbiAgJ05HWFNNS19ST1ZJTkdfRk9DVVNfR1JPVVAnLFxuKTtcblxuLyoqXG4gKiBVbml2ZXJzYWwgc2lnbmFscy1uYXRpdmUgUm92aW5nIEZvY3VzIGNvbnRhaW5lciBkaXJlY3RpdmUuXG4gKiBNYW5hZ2VzIGtleWJvYXJkIG5hdmlnYXRpb24gKEFycm93IGtleXMsIEhvbWUsIEVuZCkgYWNyb3NzIGEgc2V0IG9mIGl0ZW1zLFxuICoga2VlcGluZyBvbmx5IHRoZSBjdXJyZW50bHkgYWN0aXZlIGl0ZW0gZm9jdXNhYmxlIHZpYSBUYWIgKGB0YWJpbmRleD1cIjBcImAgdnMgYFwiLTFcImApLlxuICpcbiAqIGBgYGh0bWxcbiAqIDxkaXYgbmd4c21rUm92aW5nRm9jdXNHcm91cCBvcmllbnRhdGlvbj1cImhvcml6b250YWxcIiBbbG9vcF09XCJ0cnVlXCI+XG4gKiAgIDxidXR0b24gbmd4c21rUm92aW5nRm9jdXNJdGVtPlRhYiAxPC9idXR0b24+XG4gKiAgIDxidXR0b24gbmd4c21rUm92aW5nRm9jdXNJdGVtPlRhYiAyPC9idXR0b24+XG4gKiA8L2Rpdj5cbiAqIGBgYFxuICovXG5ARGlyZWN0aXZlKHtcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgc2VsZWN0b3I6ICdbbmd4c21rUm92aW5nRm9jdXNHcm91cF0nLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR1hTTUtfUk9WSU5HX0ZPQ1VTX0dST1VQLFxuICAgICAgdXNlRXhpc3Rpbmc6IE5neHNta1JvdmluZ0ZvY3VzR3JvdXAsXG4gICAgfSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgTmd4c21rUm92aW5nRm9jdXNHcm91cCBpbXBsZW1lbnRzIE5neHNta1JvdmluZ0ZvY3VzQ29udGV4dCB7XG4gIHJlYWRvbmx5IG9yaWVudGF0aW9uID0gaW5wdXQ8Tmd4c21rUm92aW5nT3JpZW50YXRpb24+KCdob3Jpem9udGFsJyk7XG4gIHJlYWRvbmx5IGxvb3AgPSBpbnB1dCh0cnVlLCB7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGl0ZW1zID0gc2lnbmFsPE5neHNta1JvdmluZ0ZvY3VzSXRlbVtdPihbXSk7XG4gIHJlYWRvbmx5IGFjdGl2ZUl0ZW0gPSBzaWduYWw8Tmd4c21rUm92aW5nRm9jdXNJdGVtIHwgbnVsbD4obnVsbCk7XG5cbiAgcmVnaXN0ZXIoaXRlbTogTmd4c21rUm92aW5nRm9jdXNJdGVtKTogdm9pZCB7XG4gICAgdGhpcy5pdGVtcy51cGRhdGUoKGxpc3QpID0+IFsuLi5saXN0LCBpdGVtXSk7XG4gICAgaWYgKHRoaXMuYWN0aXZlSXRlbSgpID09PSBudWxsICYmICFpdGVtLmRpc2FibGVkKCkpIHtcbiAgICAgIHRoaXMuYWN0aXZlSXRlbS5zZXQoaXRlbSk7XG4gICAgfVxuICB9XG5cbiAgdW5yZWdpc3RlcihpdGVtOiBOZ3hzbWtSb3ZpbmdGb2N1c0l0ZW0pOiB2b2lkIHtcbiAgICB0aGlzLml0ZW1zLnVwZGF0ZSgobGlzdCkgPT4gbGlzdC5maWx0ZXIoKGkpID0+IGkgIT09IGl0ZW0pKTtcbiAgICBpZiAodGhpcy5hY3RpdmVJdGVtKCkgPT09IGl0ZW0pIHtcbiAgICAgIGNvbnN0IHJlbWFpbmluZyA9IHRoaXMuaXRlbXMoKS5maWx0ZXIoKGkpID0+ICFpLmRpc2FibGVkKCkpO1xuICAgICAgdGhpcy5hY3RpdmVJdGVtLnNldChyZW1haW5pbmcubGVuZ3RoID4gMCA/IHJlbWFpbmluZ1swXSA6IG51bGwpO1xuICAgIH1cbiAgfVxuXG4gIGZvY3VzTmV4dChjdXJyZW50OiBOZ3hzbWtSb3ZpbmdGb2N1c0l0ZW0pOiB2b2lkIHtcbiAgICBjb25zdCBsaXN0ID0gdGhpcy5pdGVtcygpLmZpbHRlcigoaSkgPT4gIWkuZGlzYWJsZWQoKSk7XG4gICAgY29uc3QgaWR4ID0gbGlzdC5pbmRleE9mKGN1cnJlbnQpO1xuICAgIGlmIChpZHggPT09IC0xKSByZXR1cm47XG5cbiAgICBpZiAoaWR4IDwgbGlzdC5sZW5ndGggLSAxKSB7XG4gICAgICBjb25zdCBuZXh0ID0gbGlzdFtpZHggKyAxXTtcbiAgICAgIHRoaXMuc2V0QWN0aXZlQW5kRm9jdXMobmV4dCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmxvb3AoKSkge1xuICAgICAgY29uc3QgZmlyc3QgPSBsaXN0WzBdO1xuICAgICAgdGhpcy5zZXRBY3RpdmVBbmRGb2N1cyhmaXJzdCk7XG4gICAgfVxuICB9XG5cbiAgZm9jdXNQcmV2KGN1cnJlbnQ6IE5neHNta1JvdmluZ0ZvY3VzSXRlbSk6IHZvaWQge1xuICAgIGNvbnN0IGxpc3QgPSB0aGlzLml0ZW1zKCkuZmlsdGVyKChpKSA9PiAhaS5kaXNhYmxlZCgpKTtcbiAgICBjb25zdCBpZHggPSBsaXN0LmluZGV4T2YoY3VycmVudCk7XG4gICAgaWYgKGlkeCA9PT0gLTEpIHJldHVybjtcblxuICAgIGlmIChpZHggPiAwKSB7XG4gICAgICBjb25zdCBwcmV2ID0gbGlzdFtpZHggLSAxXTtcbiAgICAgIHRoaXMuc2V0QWN0aXZlQW5kRm9jdXMocHJldik7XG4gICAgfSBlbHNlIGlmICh0aGlzLmxvb3AoKSkge1xuICAgICAgY29uc3QgbGFzdCA9IGxpc3RbbGlzdC5sZW5ndGggLSAxXTtcbiAgICAgIHRoaXMuc2V0QWN0aXZlQW5kRm9jdXMobGFzdCk7XG4gICAgfVxuICB9XG5cbiAgZm9jdXNGaXJzdCgpOiB2b2lkIHtcbiAgICBjb25zdCBsaXN0ID0gdGhpcy5pdGVtcygpLmZpbHRlcigoaSkgPT4gIWkuZGlzYWJsZWQoKSk7XG4gICAgaWYgKGxpc3QubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5zZXRBY3RpdmVBbmRGb2N1cyhsaXN0WzBdKTtcbiAgICB9XG4gIH1cblxuICBmb2N1c0xhc3QoKTogdm9pZCB7XG4gICAgY29uc3QgbGlzdCA9IHRoaXMuaXRlbXMoKS5maWx0ZXIoKGkpID0+ICFpLmRpc2FibGVkKCkpO1xuICAgIGlmIChsaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuc2V0QWN0aXZlQW5kRm9jdXMobGlzdFtsaXN0Lmxlbmd0aCAtIDFdKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldEFjdGl2ZUFuZEZvY3VzKGl0ZW06IE5neHNta1JvdmluZ0ZvY3VzSXRlbSk6IHZvaWQge1xuICAgIHRoaXMuYWN0aXZlSXRlbS5zZXQoaXRlbSk7XG4gICAgaXRlbS5mb2N1cygpO1xuICB9XG59XG5cbi8qKlxuICogSXRlbSBpbiBhIFJvdmluZyBGb2N1cyBncm91cC4gQmluZHMgYFt0YWJpbmRleF1gIGR5bmFtaWNhbGx5IGJhc2VkIG9uIGFjdGl2ZSBzdGF0ZS5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHNlbGVjdG9yOiAnW25neHNta1JvdmluZ0ZvY3VzSXRlbV0nLFxuICBob3N0OiB7XG4gICAgJ1thdHRyLnRhYmluZGV4XSc6ICd0YWJJbmRleCgpJyxcbiAgICAnKGtleWRvd24pJzogJ2hhbmRsZUtleWRvd24oJGV2ZW50KScsXG4gICAgJyhmb2N1cyknOiAnaGFuZGxlRm9jdXMoKScsXG4gIH0sXG59KVxuZXhwb3J0IGNsYXNzIE5neHNta1JvdmluZ0ZvY3VzSXRlbSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZ3JvdXAgPSBpbmplY3QoTkdYU01LX1JPVklOR19GT0NVU19HUk9VUCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZWxSZWYgPSBpbmplY3QoRWxlbWVudFJlZjxIVE1MRWxlbWVudD4pO1xuXG4gIHJlYWRvbmx5IGRpc2FibGVkID0gaW5wdXQoZmFsc2UsIHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pO1xuICByZWFkb25seSBmb2N1c2VkID0gb3V0cHV0PHZvaWQ+KCk7XG5cbiAgcmVhZG9ubHkgaXNBY3RpdmUgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmdyb3VwLmFjdGl2ZUl0ZW0oKSA9PT0gdGhpcyk7XG4gIHJlYWRvbmx5IHRhYkluZGV4ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKCkpIHJldHVybiAtMTtcbiAgICByZXR1cm4gdGhpcy5pc0FjdGl2ZSgpID8gMCA6IC0xO1xuICB9KTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmdyb3VwLnJlZ2lzdGVyKHRoaXMpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5ncm91cC51bnJlZ2lzdGVyKHRoaXMpO1xuICB9XG5cbiAgZm9jdXMoKTogdm9pZCB7XG4gICAgdGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlRm9jdXMoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmRpc2FibGVkKCkpIHtcbiAgICAgIHRoaXMuZ3JvdXAuYWN0aXZlSXRlbS5zZXQodGhpcyk7XG4gICAgICB0aGlzLmZvY3VzZWQuZW1pdCgpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQoKSkgcmV0dXJuO1xuXG4gICAgY29uc3Qgb3JpZW50ID0gdGhpcy5ncm91cC5vcmllbnRhdGlvbigpO1xuICAgIGNvbnN0IGlzSG9yaXogPSBvcmllbnQgPT09ICdob3Jpem9udGFsJyB8fCBvcmllbnQgPT09ICdib3RoJztcbiAgICBjb25zdCBpc1ZlcnQgPSBvcmllbnQgPT09ICd2ZXJ0aWNhbCcgfHwgb3JpZW50ID09PSAnYm90aCc7XG5cbiAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuICAgICAgY2FzZSAnQXJyb3dSaWdodCc6XG4gICAgICBjYXNlICdBcnJvd0Rvd24nOlxuICAgICAgICBpZiAoKGV2ZW50LmtleSA9PT0gJ0Fycm93UmlnaHQnICYmIGlzSG9yaXopIHx8IChldmVudC5rZXkgPT09ICdBcnJvd0Rvd24nICYmIGlzVmVydCkpIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIHRoaXMuZ3JvdXAuZm9jdXNOZXh0KHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdBcnJvd0xlZnQnOlxuICAgICAgY2FzZSAnQXJyb3dVcCc6XG4gICAgICAgIGlmICgoZXZlbnQua2V5ID09PSAnQXJyb3dMZWZ0JyAmJiBpc0hvcml6KSB8fCAoZXZlbnQua2V5ID09PSAnQXJyb3dVcCcgJiYgaXNWZXJ0KSkge1xuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgdGhpcy5ncm91cC5mb2N1c1ByZXYodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ0hvbWUnOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmdyb3VwLmZvY3VzRmlyc3QoKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ0VuZCc6XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuZ3JvdXAuZm9jdXNMYXN0KCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -1,5 +1,5 @@
1
- import { Injectable, inject } from '@angular/core';
2
- import { DOCUMENT } from '@angular/common';
1
+ import { Injectable, inject, PLATFORM_ID } from '@angular/core';
2
+ import { DOCUMENT, isPlatformBrowser } from '@angular/common';
3
3
  import * as i0 from "@angular/core";
4
4
  /**
5
5
  * Locks body scrolling (for dialogs, drawers, sheets). Reference-counted so
@@ -9,31 +9,48 @@ import * as i0 from "@angular/core";
9
9
  export class NgxsmkScrollLock {
10
10
  constructor() {
11
11
  this.document = inject(DOCUMENT);
12
+ this.platformId = inject(PLATFORM_ID);
12
13
  this.locks = 0;
13
14
  this.previousOverflow = '';
14
15
  this.previousPaddingRight = '';
16
+ this.previousOverscroll = '';
15
17
  }
16
18
  lock() {
19
+ if (!isPlatformBrowser(this.platformId)) {
20
+ return;
21
+ }
17
22
  if (this.locks++ > 0) {
18
23
  return;
19
24
  }
20
- const body = this.document.body;
25
+ const body = this.document?.body;
26
+ if (!body) {
27
+ return;
28
+ }
21
29
  const window = this.document.defaultView;
22
30
  const scrollbar = window ? window.innerWidth - this.document.documentElement.clientWidth : 0;
23
31
  this.previousOverflow = body.style.overflow;
24
32
  this.previousPaddingRight = body.style.paddingRight;
33
+ this.previousOverscroll = body.style.overscrollBehavior;
25
34
  body.style.overflow = 'hidden';
35
+ body.style.overscrollBehavior = 'none';
26
36
  if (scrollbar > 0) {
27
37
  body.style.paddingRight = `${scrollbar}px`;
28
38
  }
29
39
  }
30
40
  unlock() {
41
+ if (!isPlatformBrowser(this.platformId)) {
42
+ return;
43
+ }
31
44
  if (this.locks === 0 || --this.locks > 0) {
32
45
  return;
33
46
  }
34
- const body = this.document.body;
47
+ const body = this.document?.body;
48
+ if (!body) {
49
+ return;
50
+ }
35
51
  body.style.overflow = this.previousOverflow;
36
52
  body.style.paddingRight = this.previousPaddingRight;
53
+ body.style.overscrollBehavior = this.previousOverscroll;
37
54
  }
38
55
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkScrollLock, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
39
56
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkScrollLock, providedIn: 'root' }); }
@@ -42,4 +59,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImpor
42
59
  type: Injectable,
43
60
  args: [{ providedIn: 'root' }]
44
61
  }] });
45
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xsLWxvY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jZGsvc2Nyb2xsLWxvY2svc2Nyb2xsLWxvY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDOztBQUUzQzs7OztHQUlHO0FBRUgsTUFBTSxPQUFPLGdCQUFnQjtJQUQ3QjtRQUVtQixhQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3JDLFVBQUssR0FBRyxDQUFDLENBQUM7UUFDVixxQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFDdEIseUJBQW9CLEdBQUcsRUFBRSxDQUFDO0tBMEJuQztJQXhCQyxJQUFJO1FBQ0YsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDckIsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztRQUNoQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQztRQUN6QyxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFN0YsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDO1FBQzVDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQztRQUNwRCxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDL0IsSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDbEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEdBQUcsR0FBRyxTQUFTLElBQUksQ0FBQztRQUM3QyxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU07UUFDSixJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN6QyxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztRQUM1QyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUM7SUFDdEQsQ0FBQzs4R0E3QlUsZ0JBQWdCO2tIQUFoQixnQkFBZ0IsY0FESCxNQUFNOzsyRkFDbkIsZ0JBQWdCO2tCQUQ1QixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG4vKipcbiAqIExvY2tzIGJvZHkgc2Nyb2xsaW5nIChmb3IgZGlhbG9ncywgZHJhd2Vycywgc2hlZXRzKS4gUmVmZXJlbmNlLWNvdW50ZWQgc29cbiAqIG5lc3RlZCBvdmVybGF5cyBjYW4gbG9jayBpbmRlcGVuZGVudGx5OyBjb21wZW5zYXRlcyBmb3Igc2Nyb2xsYmFyIHdpZHRoIHRvXG4gKiBwcmV2ZW50IGxheW91dCBzaGlmdC5cbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBOZ3hzbWtTY3JvbGxMb2NrIHtcbiAgcHJpdmF0ZSByZWFkb25seSBkb2N1bWVudCA9IGluamVjdChET0NVTUVOVCk7XG4gIHByaXZhdGUgbG9ja3MgPSAwO1xuICBwcml2YXRlIHByZXZpb3VzT3ZlcmZsb3cgPSAnJztcbiAgcHJpdmF0ZSBwcmV2aW91c1BhZGRpbmdSaWdodCA9ICcnO1xuXG4gIGxvY2soKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubG9ja3MrKyA+IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgYm9keSA9IHRoaXMuZG9jdW1lbnQuYm9keTtcbiAgICBjb25zdCB3aW5kb3cgPSB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3O1xuICAgIGNvbnN0IHNjcm9sbGJhciA9IHdpbmRvdyA/IHdpbmRvdy5pbm5lcldpZHRoIC0gdGhpcy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGggOiAwO1xuXG4gICAgdGhpcy5wcmV2aW91c092ZXJmbG93ID0gYm9keS5zdHlsZS5vdmVyZmxvdztcbiAgICB0aGlzLnByZXZpb3VzUGFkZGluZ1JpZ2h0ID0gYm9keS5zdHlsZS5wYWRkaW5nUmlnaHQ7XG4gICAgYm9keS5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nO1xuICAgIGlmIChzY3JvbGxiYXIgPiAwKSB7XG4gICAgICBib2R5LnN0eWxlLnBhZGRpbmdSaWdodCA9IGAke3Njcm9sbGJhcn1weGA7XG4gICAgfVxuICB9XG5cbiAgdW5sb2NrKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmxvY2tzID09PSAwIHx8IC0tdGhpcy5sb2NrcyA+IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgYm9keSA9IHRoaXMuZG9jdW1lbnQuYm9keTtcbiAgICBib2R5LnN0eWxlLm92ZXJmbG93ID0gdGhpcy5wcmV2aW91c092ZXJmbG93O1xuICAgIGJvZHkuc3R5bGUucGFkZGluZ1JpZ2h0ID0gdGhpcy5wcmV2aW91c1BhZGRpbmdSaWdodDtcbiAgfVxufVxuIl19
62
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xsLWxvY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jZGsvc2Nyb2xsLWxvY2svc2Nyb2xsLWxvY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hFLE9BQU8sRUFBRSxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7QUFFOUQ7Ozs7R0FJRztBQUVILE1BQU0sT0FBTyxnQkFBZ0I7SUFEN0I7UUFFbUIsYUFBUSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM1QixlQUFVLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzFDLFVBQUssR0FBRyxDQUFDLENBQUM7UUFDVixxQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFDdEIseUJBQW9CLEdBQUcsRUFBRSxDQUFDO1FBQzFCLHVCQUFrQixHQUFHLEVBQUUsQ0FBQztLQTBDakM7SUF4Q0MsSUFBSTtRQUNGLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUN4QyxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3JCLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUM7UUFDakMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ1YsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQztRQUN6QyxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFN0YsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDO1FBQzVDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQztRQUNwRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztRQUV4RCxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDL0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsR0FBRyxNQUFNLENBQUM7UUFDdkMsSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDbEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEdBQUcsR0FBRyxTQUFTLElBQUksQ0FBQztRQUM3QyxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU07UUFDSixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDeEMsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN6QyxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNWLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBQzVDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQztRQUNwRCxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztJQUMxRCxDQUFDOzhHQS9DVSxnQkFBZ0I7a0hBQWhCLGdCQUFnQixjQURILE1BQU07OzJGQUNuQixnQkFBZ0I7a0JBRDVCLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0LCBQTEFURk9STV9JRCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRE9DVU1FTlQsIGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuLyoqXG4gKiBMb2NrcyBib2R5IHNjcm9sbGluZyAoZm9yIGRpYWxvZ3MsIGRyYXdlcnMsIHNoZWV0cykuIFJlZmVyZW5jZS1jb3VudGVkIHNvXG4gKiBuZXN0ZWQgb3ZlcmxheXMgY2FuIGxvY2sgaW5kZXBlbmRlbnRseTsgY29tcGVuc2F0ZXMgZm9yIHNjcm9sbGJhciB3aWR0aCB0b1xuICogcHJldmVudCBsYXlvdXQgc2hpZnQuXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgTmd4c21rU2Nyb2xsTG9jayB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZG9jdW1lbnQgPSBpbmplY3QoRE9DVU1FTlQpO1xuICBwcml2YXRlIHJlYWRvbmx5IHBsYXRmb3JtSWQgPSBpbmplY3QoUExBVEZPUk1fSUQpO1xuICBwcml2YXRlIGxvY2tzID0gMDtcbiAgcHJpdmF0ZSBwcmV2aW91c092ZXJmbG93ID0gJyc7XG4gIHByaXZhdGUgcHJldmlvdXNQYWRkaW5nUmlnaHQgPSAnJztcbiAgcHJpdmF0ZSBwcmV2aW91c092ZXJzY3JvbGwgPSAnJztcblxuICBsb2NrKCk6IHZvaWQge1xuICAgIGlmICghaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5sb2NrcysrID4gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBib2R5ID0gdGhpcy5kb2N1bWVudD8uYm9keTtcbiAgICBpZiAoIWJvZHkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgd2luZG93ID0gdGhpcy5kb2N1bWVudC5kZWZhdWx0VmlldztcbiAgICBjb25zdCBzY3JvbGxiYXIgPSB3aW5kb3cgPyB3aW5kb3cuaW5uZXJXaWR0aCAtIHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoIDogMDtcblxuICAgIHRoaXMucHJldmlvdXNPdmVyZmxvdyA9IGJvZHkuc3R5bGUub3ZlcmZsb3c7XG4gICAgdGhpcy5wcmV2aW91c1BhZGRpbmdSaWdodCA9IGJvZHkuc3R5bGUucGFkZGluZ1JpZ2h0O1xuICAgIHRoaXMucHJldmlvdXNPdmVyc2Nyb2xsID0gYm9keS5zdHlsZS5vdmVyc2Nyb2xsQmVoYXZpb3I7XG5cbiAgICBib2R5LnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbic7XG4gICAgYm9keS5zdHlsZS5vdmVyc2Nyb2xsQmVoYXZpb3IgPSAnbm9uZSc7XG4gICAgaWYgKHNjcm9sbGJhciA+IDApIHtcbiAgICAgIGJvZHkuc3R5bGUucGFkZGluZ1JpZ2h0ID0gYCR7c2Nyb2xsYmFyfXB4YDtcbiAgICB9XG4gIH1cblxuICB1bmxvY2soKTogdm9pZCB7XG4gICAgaWYgKCFpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmxvY2tzID09PSAwIHx8IC0tdGhpcy5sb2NrcyA+IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgYm9keSA9IHRoaXMuZG9jdW1lbnQ/LmJvZHk7XG4gICAgaWYgKCFib2R5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGJvZHkuc3R5bGUub3ZlcmZsb3cgPSB0aGlzLnByZXZpb3VzT3ZlcmZsb3c7XG4gICAgYm9keS5zdHlsZS5wYWRkaW5nUmlnaHQgPSB0aGlzLnByZXZpb3VzUGFkZGluZ1JpZ2h0O1xuICAgIGJvZHkuc3R5bGUub3ZlcnNjcm9sbEJlaGF2aW9yID0gdGhpcy5wcmV2aW91c092ZXJzY3JvbGw7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,2 @@
1
+ export * from './skip-link';
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jZGsvc2tpcC1saW5rL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsYUFBYSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9za2lwLWxpbmsnO1xuIl19
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './index';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4c21rLWNkay1za2lwLWxpbmsuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jZGsvc2tpcC1saW5rL25neHNtay1jZGstc2tpcC1saW5rLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vaW5kZXgnO1xuIl19
@@ -0,0 +1,33 @@
1
+ import { ChangeDetectionStrategy, Component, input } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Accessible skip navigation link for keyboard users to bypass repetitive header navigation.
5
+ * Renders off-screen by default, sliding into view when focused via Tab.
6
+ *
7
+ * ```html
8
+ * <ngxsmk-skip-link targetId="main-content" label="Skip to main content" />
9
+ * ```
10
+ */
11
+ export class NgxsmkSkipLink {
12
+ constructor() {
13
+ /** Target HTML ID anchor to scroll/focus to. Default: 'main-content'. */
14
+ this.targetId = input('main-content');
15
+ /** Label text rendered inside the skip link. Default: 'Skip to content'. */
16
+ this.label = input('Skip to content');
17
+ }
18
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkSkipLink, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
19
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.0", type: NgxsmkSkipLink, isStandalone: true, selector: "ngxsmk-skip-link", inputs: { targetId: { classPropertyName: "targetId", publicName: "targetId", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
20
+ <a [href]="'#' + targetId()" class="ngxsmk-skip-link">
21
+ {{ label() }}
22
+ </a>
23
+ `, isInline: true, styles: [".ngxsmk-skip-link{position:absolute;top:-9999px;inset-inline-start:var(--ngxsmk-space-4, 1rem);z-index:var(--ngxsmk-z-popover, 1000);padding:var(--ngxsmk-space-3, .75rem) var(--ngxsmk-space-4, 1rem);background:var(--ngxsmk-color-primary, #7c3aed);color:var(--ngxsmk-color-on-primary, #ffffff);font-family:var(--ngxsmk-font-sans, system-ui);font-size:var(--ngxsmk-text-body-sm-size, .875rem);font-weight:600;text-decoration:none;border-radius:var(--ngxsmk-radius-md, .375rem);box-shadow:var(--ngxsmk-shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, .1));outline:none;transition:top .15s ease-out}.ngxsmk-skip-link:focus{top:var(--ngxsmk-space-4, 1rem);box-shadow:var(--ngxsmk-focus-ring)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
24
+ }
25
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkSkipLink, decorators: [{
26
+ type: Component,
27
+ args: [{ standalone: true, selector: 'ngxsmk-skip-link', template: `
28
+ <a [href]="'#' + targetId()" class="ngxsmk-skip-link">
29
+ {{ label() }}
30
+ </a>
31
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".ngxsmk-skip-link{position:absolute;top:-9999px;inset-inline-start:var(--ngxsmk-space-4, 1rem);z-index:var(--ngxsmk-z-popover, 1000);padding:var(--ngxsmk-space-3, .75rem) var(--ngxsmk-space-4, 1rem);background:var(--ngxsmk-color-primary, #7c3aed);color:var(--ngxsmk-color-on-primary, #ffffff);font-family:var(--ngxsmk-font-sans, system-ui);font-size:var(--ngxsmk-text-body-sm-size, .875rem);font-weight:600;text-decoration:none;border-radius:var(--ngxsmk-radius-md, .375rem);box-shadow:var(--ngxsmk-shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, .1));outline:none;transition:top .15s ease-out}.ngxsmk-skip-link:focus{top:var(--ngxsmk-space-4, 1rem);box-shadow:var(--ngxsmk-focus-ring)}\n"] }]
32
+ }] });
33
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2tpcC1saW5rLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY2RrL3NraXAtbGluay9za2lwLWxpbmsudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBRTFFOzs7Ozs7O0dBT0c7QUFtQ0gsTUFBTSxPQUFPLGNBQWM7SUFsQzNCO1FBbUNFLHlFQUF5RTtRQUNoRSxhQUFRLEdBQUcsS0FBSyxDQUFTLGNBQWMsQ0FBQyxDQUFDO1FBRWxELDRFQUE0RTtRQUNuRSxVQUFLLEdBQUcsS0FBSyxDQUFTLGlCQUFpQixDQUFDLENBQUM7S0FDbkQ7OEdBTlksY0FBYztrR0FBZCxjQUFjLGlWQS9CZjs7OztHQUlUOzsyRkEyQlUsY0FBYztrQkFsQzFCLFNBQVM7aUNBQ0ksSUFBSSxZQUNOLGtCQUFrQixZQUNsQjs7OztHQUlULG1CQXlCZ0IsdUJBQXVCLENBQUMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIGlucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8qKlxuICogQWNjZXNzaWJsZSBza2lwIG5hdmlnYXRpb24gbGluayBmb3Iga2V5Ym9hcmQgdXNlcnMgdG8gYnlwYXNzIHJlcGV0aXRpdmUgaGVhZGVyIG5hdmlnYXRpb24uXG4gKiBSZW5kZXJzIG9mZi1zY3JlZW4gYnkgZGVmYXVsdCwgc2xpZGluZyBpbnRvIHZpZXcgd2hlbiBmb2N1c2VkIHZpYSBUYWIuXG4gKlxuICogYGBgaHRtbFxuICogPG5neHNtay1za2lwLWxpbmsgdGFyZ2V0SWQ9XCJtYWluLWNvbnRlbnRcIiBsYWJlbD1cIlNraXAgdG8gbWFpbiBjb250ZW50XCIgLz5cbiAqIGBgYFxuICovXG5AQ29tcG9uZW50KHtcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgc2VsZWN0b3I6ICduZ3hzbWstc2tpcC1saW5rJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8YSBbaHJlZl09XCInIycgKyB0YXJnZXRJZCgpXCIgY2xhc3M9XCJuZ3hzbWstc2tpcC1saW5rXCI+XG4gICAgICB7eyBsYWJlbCgpIH19XG4gICAgPC9hPlxuICBgLFxuICBzdHlsZXM6IGBcbiAgICAubmd4c21rLXNraXAtbGluayB7XG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICB0b3A6IC05OTk5cHg7XG4gICAgICBpbnNldC1pbmxpbmUtc3RhcnQ6IHZhcigtLW5neHNtay1zcGFjZS00LCAxcmVtKTtcbiAgICAgIHotaW5kZXg6IHZhcigtLW5neHNtay16LXBvcG92ZXIsIDEwMDApO1xuICAgICAgcGFkZGluZzogdmFyKC0tbmd4c21rLXNwYWNlLTMsIDAuNzVyZW0pIHZhcigtLW5neHNtay1zcGFjZS00LCAxcmVtKTtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLW5neHNtay1jb2xvci1wcmltYXJ5LCAjN2MzYWVkKTtcbiAgICAgIGNvbG9yOiB2YXIoLS1uZ3hzbWstY29sb3Itb24tcHJpbWFyeSwgI2ZmZmZmZik7XG4gICAgICBmb250LWZhbWlseTogdmFyKC0tbmd4c21rLWZvbnQtc2Fucywgc3lzdGVtLXVpKTtcbiAgICAgIGZvbnQtc2l6ZTogdmFyKC0tbmd4c21rLXRleHQtYm9keS1zbS1zaXplLCAwLjg3NXJlbSk7XG4gICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICAgICAgYm9yZGVyLXJhZGl1czogdmFyKC0tbmd4c21rLXJhZGl1cy1tZCwgMC4zNzVyZW0pO1xuICAgICAgYm94LXNoYWRvdzogdmFyKC0tbmd4c21rLXNoYWRvdy1sZywgMCAxMHB4IDE1cHggLTNweCByZ2JhKDAsIDAsIDAsIDAuMSkpO1xuICAgICAgb3V0bGluZTogbm9uZTtcbiAgICAgIHRyYW5zaXRpb246IHRvcCAwLjE1cyBlYXNlLW91dDtcbiAgICB9XG5cbiAgICAubmd4c21rLXNraXAtbGluazpmb2N1cyB7XG4gICAgICB0b3A6IHZhcigtLW5neHNtay1zcGFjZS00LCAxcmVtKTtcbiAgICAgIGJveC1zaGFkb3c6IHZhcigtLW5neHNtay1mb2N1cy1yaW5nKTtcbiAgICB9XG4gIGAsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBOZ3hzbWtTa2lwTGluayB7XG4gIC8qKiBUYXJnZXQgSFRNTCBJRCBhbmNob3IgdG8gc2Nyb2xsL2ZvY3VzIHRvLiBEZWZhdWx0OiAnbWFpbi1jb250ZW50Jy4gKi9cbiAgcmVhZG9ubHkgdGFyZ2V0SWQgPSBpbnB1dDxzdHJpbmc+KCdtYWluLWNvbnRlbnQnKTtcblxuICAvKiogTGFiZWwgdGV4dCByZW5kZXJlZCBpbnNpZGUgdGhlIHNraXAgbGluay4gRGVmYXVsdDogJ1NraXAgdG8gY29udGVudCcuICovXG4gIHJlYWRvbmx5IGxhYmVsID0gaW5wdXQ8c3RyaW5nPignU2tpcCB0byBjb250ZW50Jyk7XG59XG4iXX0=
@@ -0,0 +1,183 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, input, booleanAttribute, signal, Directive, inject, ElementRef, output, computed } from '@angular/core';
3
+
4
+ const NGXSMK_ROVING_FOCUS_GROUP = new InjectionToken('NGXSMK_ROVING_FOCUS_GROUP');
5
+ /**
6
+ * Universal signals-native Roving Focus container directive.
7
+ * Manages keyboard navigation (Arrow keys, Home, End) across a set of items,
8
+ * keeping only the currently active item focusable via Tab (`tabindex="0"` vs `"-1"`).
9
+ *
10
+ * ```html
11
+ * <div ngxsmkRovingFocusGroup orientation="horizontal" [loop]="true">
12
+ * <button ngxsmkRovingFocusItem>Tab 1</button>
13
+ * <button ngxsmkRovingFocusItem>Tab 2</button>
14
+ * </div>
15
+ * ```
16
+ */
17
+ class NgxsmkRovingFocusGroup {
18
+ constructor() {
19
+ this.orientation = input('horizontal');
20
+ this.loop = input(true, { transform: booleanAttribute });
21
+ this.items = signal([]);
22
+ this.activeItem = signal(null);
23
+ }
24
+ register(item) {
25
+ this.items.update((list) => [...list, item]);
26
+ if (this.activeItem() === null && !item.disabled()) {
27
+ this.activeItem.set(item);
28
+ }
29
+ }
30
+ unregister(item) {
31
+ this.items.update((list) => list.filter((i) => i !== item));
32
+ if (this.activeItem() === item) {
33
+ const remaining = this.items().filter((i) => !i.disabled());
34
+ this.activeItem.set(remaining.length > 0 ? remaining[0] : null);
35
+ }
36
+ }
37
+ focusNext(current) {
38
+ const list = this.items().filter((i) => !i.disabled());
39
+ const idx = list.indexOf(current);
40
+ if (idx === -1)
41
+ return;
42
+ if (idx < list.length - 1) {
43
+ const next = list[idx + 1];
44
+ this.setActiveAndFocus(next);
45
+ }
46
+ else if (this.loop()) {
47
+ const first = list[0];
48
+ this.setActiveAndFocus(first);
49
+ }
50
+ }
51
+ focusPrev(current) {
52
+ const list = this.items().filter((i) => !i.disabled());
53
+ const idx = list.indexOf(current);
54
+ if (idx === -1)
55
+ return;
56
+ if (idx > 0) {
57
+ const prev = list[idx - 1];
58
+ this.setActiveAndFocus(prev);
59
+ }
60
+ else if (this.loop()) {
61
+ const last = list[list.length - 1];
62
+ this.setActiveAndFocus(last);
63
+ }
64
+ }
65
+ focusFirst() {
66
+ const list = this.items().filter((i) => !i.disabled());
67
+ if (list.length > 0) {
68
+ this.setActiveAndFocus(list[0]);
69
+ }
70
+ }
71
+ focusLast() {
72
+ const list = this.items().filter((i) => !i.disabled());
73
+ if (list.length > 0) {
74
+ this.setActiveAndFocus(list[list.length - 1]);
75
+ }
76
+ }
77
+ setActiveAndFocus(item) {
78
+ this.activeItem.set(item);
79
+ item.focus();
80
+ }
81
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkRovingFocusGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
82
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.0", type: NgxsmkRovingFocusGroup, isStandalone: true, selector: "[ngxsmkRovingFocusGroup]", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
83
+ {
84
+ provide: NGXSMK_ROVING_FOCUS_GROUP,
85
+ useExisting: NgxsmkRovingFocusGroup,
86
+ },
87
+ ], ngImport: i0 }); }
88
+ }
89
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkRovingFocusGroup, decorators: [{
90
+ type: Directive,
91
+ args: [{
92
+ standalone: true,
93
+ selector: '[ngxsmkRovingFocusGroup]',
94
+ providers: [
95
+ {
96
+ provide: NGXSMK_ROVING_FOCUS_GROUP,
97
+ useExisting: NgxsmkRovingFocusGroup,
98
+ },
99
+ ],
100
+ }]
101
+ }] });
102
+ /**
103
+ * Item in a Roving Focus group. Binds `[tabindex]` dynamically based on active state.
104
+ */
105
+ class NgxsmkRovingFocusItem {
106
+ constructor() {
107
+ this.group = inject(NGXSMK_ROVING_FOCUS_GROUP);
108
+ this.elRef = inject((ElementRef));
109
+ this.disabled = input(false, { transform: booleanAttribute });
110
+ this.focused = output();
111
+ this.isActive = computed(() => this.group.activeItem() === this);
112
+ this.tabIndex = computed(() => {
113
+ if (this.disabled())
114
+ return -1;
115
+ return this.isActive() ? 0 : -1;
116
+ });
117
+ this.group.register(this);
118
+ }
119
+ ngOnDestroy() {
120
+ this.group.unregister(this);
121
+ }
122
+ focus() {
123
+ this.elRef.nativeElement.focus();
124
+ }
125
+ handleFocus() {
126
+ if (!this.disabled()) {
127
+ this.group.activeItem.set(this);
128
+ this.focused.emit();
129
+ }
130
+ }
131
+ handleKeydown(event) {
132
+ if (this.disabled())
133
+ return;
134
+ const orient = this.group.orientation();
135
+ const isHoriz = orient === 'horizontal' || orient === 'both';
136
+ const isVert = orient === 'vertical' || orient === 'both';
137
+ switch (event.key) {
138
+ case 'ArrowRight':
139
+ case 'ArrowDown':
140
+ if ((event.key === 'ArrowRight' && isHoriz) || (event.key === 'ArrowDown' && isVert)) {
141
+ event.preventDefault();
142
+ this.group.focusNext(this);
143
+ }
144
+ break;
145
+ case 'ArrowLeft':
146
+ case 'ArrowUp':
147
+ if ((event.key === 'ArrowLeft' && isHoriz) || (event.key === 'ArrowUp' && isVert)) {
148
+ event.preventDefault();
149
+ this.group.focusPrev(this);
150
+ }
151
+ break;
152
+ case 'Home':
153
+ event.preventDefault();
154
+ this.group.focusFirst();
155
+ break;
156
+ case 'End':
157
+ event.preventDefault();
158
+ this.group.focusLast();
159
+ break;
160
+ }
161
+ }
162
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkRovingFocusItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
163
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.0", type: NgxsmkRovingFocusItem, isStandalone: true, selector: "[ngxsmkRovingFocusItem]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { focused: "focused" }, host: { listeners: { "keydown": "handleKeydown($event)", "focus": "handleFocus()" }, properties: { "attr.tabindex": "tabIndex()" } }, ngImport: i0 }); }
164
+ }
165
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkRovingFocusItem, decorators: [{
166
+ type: Directive,
167
+ args: [{
168
+ standalone: true,
169
+ selector: '[ngxsmkRovingFocusItem]',
170
+ host: {
171
+ '[attr.tabindex]': 'tabIndex()',
172
+ '(keydown)': 'handleKeydown($event)',
173
+ '(focus)': 'handleFocus()',
174
+ },
175
+ }]
176
+ }], ctorParameters: () => [] });
177
+
178
+ /**
179
+ * Generated bundle index. Do not edit.
180
+ */
181
+
182
+ export { NGXSMK_ROVING_FOCUS_GROUP, NgxsmkRovingFocusGroup, NgxsmkRovingFocusItem };
183
+ //# sourceMappingURL=ngxsmk-cdk-roving-focus.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngxsmk-cdk-roving-focus.mjs","sources":["../../../../packages/cdk/roving-focus/roving-focus.ts","../../../../packages/cdk/roving-focus/ngxsmk-cdk-roving-focus.ts"],"sourcesContent":["import {\n Directive,\n ElementRef,\n InjectionToken,\n OnDestroy,\n WritableSignal,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\n\nexport type NgxsmkRovingOrientation = 'horizontal' | 'vertical' | 'both';\n\nexport interface NgxsmkRovingFocusContext {\n register(item: NgxsmkRovingFocusItem): void;\n unregister(item: NgxsmkRovingFocusItem): void;\n focusNext(current: NgxsmkRovingFocusItem): void;\n focusPrev(current: NgxsmkRovingFocusItem): void;\n focusFirst(): void;\n focusLast(): void;\n activeItem: WritableSignal<NgxsmkRovingFocusItem | null>;\n orientation: () => NgxsmkRovingOrientation;\n loop: () => boolean;\n}\n\nexport const NGXSMK_ROVING_FOCUS_GROUP = new InjectionToken<NgxsmkRovingFocusContext>(\n 'NGXSMK_ROVING_FOCUS_GROUP',\n);\n\n/**\n * Universal signals-native Roving Focus container directive.\n * Manages keyboard navigation (Arrow keys, Home, End) across a set of items,\n * keeping only the currently active item focusable via Tab (`tabindex=\"0\"` vs `\"-1\"`).\n *\n * ```html\n * <div ngxsmkRovingFocusGroup orientation=\"horizontal\" [loop]=\"true\">\n * <button ngxsmkRovingFocusItem>Tab 1</button>\n * <button ngxsmkRovingFocusItem>Tab 2</button>\n * </div>\n * ```\n */\n@Directive({\n standalone: true,\n selector: '[ngxsmkRovingFocusGroup]',\n providers: [\n {\n provide: NGXSMK_ROVING_FOCUS_GROUP,\n useExisting: NgxsmkRovingFocusGroup,\n },\n ],\n})\nexport class NgxsmkRovingFocusGroup implements NgxsmkRovingFocusContext {\n readonly orientation = input<NgxsmkRovingOrientation>('horizontal');\n readonly loop = input(true, { transform: booleanAttribute });\n\n private readonly items = signal<NgxsmkRovingFocusItem[]>([]);\n readonly activeItem = signal<NgxsmkRovingFocusItem | null>(null);\n\n register(item: NgxsmkRovingFocusItem): void {\n this.items.update((list) => [...list, item]);\n if (this.activeItem() === null && !item.disabled()) {\n this.activeItem.set(item);\n }\n }\n\n unregister(item: NgxsmkRovingFocusItem): void {\n this.items.update((list) => list.filter((i) => i !== item));\n if (this.activeItem() === item) {\n const remaining = this.items().filter((i) => !i.disabled());\n this.activeItem.set(remaining.length > 0 ? remaining[0] : null);\n }\n }\n\n focusNext(current: NgxsmkRovingFocusItem): void {\n const list = this.items().filter((i) => !i.disabled());\n const idx = list.indexOf(current);\n if (idx === -1) return;\n\n if (idx < list.length - 1) {\n const next = list[idx + 1];\n this.setActiveAndFocus(next);\n } else if (this.loop()) {\n const first = list[0];\n this.setActiveAndFocus(first);\n }\n }\n\n focusPrev(current: NgxsmkRovingFocusItem): void {\n const list = this.items().filter((i) => !i.disabled());\n const idx = list.indexOf(current);\n if (idx === -1) return;\n\n if (idx > 0) {\n const prev = list[idx - 1];\n this.setActiveAndFocus(prev);\n } else if (this.loop()) {\n const last = list[list.length - 1];\n this.setActiveAndFocus(last);\n }\n }\n\n focusFirst(): void {\n const list = this.items().filter((i) => !i.disabled());\n if (list.length > 0) {\n this.setActiveAndFocus(list[0]);\n }\n }\n\n focusLast(): void {\n const list = this.items().filter((i) => !i.disabled());\n if (list.length > 0) {\n this.setActiveAndFocus(list[list.length - 1]);\n }\n }\n\n private setActiveAndFocus(item: NgxsmkRovingFocusItem): void {\n this.activeItem.set(item);\n item.focus();\n }\n}\n\n/**\n * Item in a Roving Focus group. Binds `[tabindex]` dynamically based on active state.\n */\n@Directive({\n standalone: true,\n selector: '[ngxsmkRovingFocusItem]',\n host: {\n '[attr.tabindex]': 'tabIndex()',\n '(keydown)': 'handleKeydown($event)',\n '(focus)': 'handleFocus()',\n },\n})\nexport class NgxsmkRovingFocusItem implements OnDestroy {\n private readonly group = inject(NGXSMK_ROVING_FOCUS_GROUP);\n private readonly elRef = inject(ElementRef<HTMLElement>);\n\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly focused = output<void>();\n\n readonly isActive = computed(() => this.group.activeItem() === this);\n readonly tabIndex = computed(() => {\n if (this.disabled()) return -1;\n return this.isActive() ? 0 : -1;\n });\n\n constructor() {\n this.group.register(this);\n }\n\n ngOnDestroy(): void {\n this.group.unregister(this);\n }\n\n focus(): void {\n this.elRef.nativeElement.focus();\n }\n\n protected handleFocus(): void {\n if (!this.disabled()) {\n this.group.activeItem.set(this);\n this.focused.emit();\n }\n }\n\n protected handleKeydown(event: KeyboardEvent): void {\n if (this.disabled()) return;\n\n const orient = this.group.orientation();\n const isHoriz = orient === 'horizontal' || orient === 'both';\n const isVert = orient === 'vertical' || orient === 'both';\n\n switch (event.key) {\n case 'ArrowRight':\n case 'ArrowDown':\n if ((event.key === 'ArrowRight' && isHoriz) || (event.key === 'ArrowDown' && isVert)) {\n event.preventDefault();\n this.group.focusNext(this);\n }\n break;\n\n case 'ArrowLeft':\n case 'ArrowUp':\n if ((event.key === 'ArrowLeft' && isHoriz) || (event.key === 'ArrowUp' && isVert)) {\n event.preventDefault();\n this.group.focusPrev(this);\n }\n break;\n\n case 'Home':\n event.preventDefault();\n this.group.focusFirst();\n break;\n\n case 'End':\n event.preventDefault();\n this.group.focusLast();\n break;\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;MA4Ba,yBAAyB,GAAG,IAAI,cAAc,CACzD,2BAA2B;AAG7B;;;;;;;;;;;AAWG;MAWU,sBAAsB,CAAA;AAVnC,IAAA,WAAA,GAAA;AAWW,QAAA,IAAA,CAAA,WAAW,GAAG,KAAK,CAA0B,YAAY,CAAC;QAC1D,IAAA,CAAA,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC;AAE3C,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAA0B,EAAE,CAAC;AACnD,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAA+B,IAAI,CAAC;AA+DjE,IAAA;AA7DC,IAAA,QAAQ,CAAC,IAA2B,EAAA;AAClC,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC;AAC5C,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE;AAClD,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;QAC3B;IACF;AAEA,IAAA,UAAU,CAAC,IAA2B,EAAA;QACpC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;AAC3D,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;YAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC3D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QACjE;IACF;AAEA,IAAA,SAAS,CAAC,OAA8B,EAAA;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QACjC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE;QAEhB,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;AAC1B,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;QAC9B;AAAO,aAAA,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE;AACtB,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;AACrB,YAAA,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC;QAC/B;IACF;AAEA,IAAA,SAAS,CAAC,OAA8B,EAAA;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QACjC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE;AAEhB,QAAA,IAAI,GAAG,GAAG,CAAC,EAAE;YACX,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;AAC1B,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;QAC9B;AAAO,aAAA,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;AAClC,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;QAC9B;IACF;IAEA,UAAU,GAAA;QACR,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AACtD,QAAA,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;YACnB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC;IACF;IAEA,SAAS,GAAA;QACP,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AACtD,QAAA,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;AACnB,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC/C;IACF;AAEQ,IAAA,iBAAiB,CAAC,IAA2B,EAAA;AACnD,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,KAAK,EAAE;IACd;8GAnEW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAtB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,0BAAA,EAAA,MAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,SAAA,EAPtB;AACT,YAAA;AACE,gBAAA,OAAO,EAAE,yBAAyB;AAClC,gBAAA,WAAW,EAAE,sBAAsB;AACpC,aAAA;AACF,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA,CAAA;;2FAEU,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBAVlC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,UAAU,EAAE,IAAI;AAChB,oBAAA,QAAQ,EAAE,0BAA0B;AACpC,oBAAA,SAAS,EAAE;AACT,wBAAA;AACE,4BAAA,OAAO,EAAE,yBAAyB;AAClC,4BAAA,WAAW,EAAA,sBAAwB;AACpC,yBAAA;AACF,qBAAA;AACF,iBAAA;;AAuED;;AAEG;MAUU,qBAAqB,CAAA;AAahC,IAAA,WAAA,GAAA;AAZiB,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,yBAAyB,CAAC;AACzC,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,EAAC,UAAuB,EAAC;QAE/C,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC;QACxD,IAAA,CAAA,OAAO,GAAG,MAAM,EAAQ;AAExB,QAAA,IAAA,CAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,IAAI,CAAC;AAC3D,QAAA,IAAA,CAAA,QAAQ,GAAG,QAAQ,CAAC,MAAK;YAChC,IAAI,IAAI,CAAC,QAAQ,EAAE;gBAAE,OAAO,CAAC,CAAC;AAC9B,YAAA,OAAO,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;AACjC,QAAA,CAAC,CAAC;AAGA,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC3B;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;IAC7B;IAEA,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE;IAClC;IAEU,WAAW,GAAA;AACnB,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE;YACpB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;AAC/B,YAAA,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;QACrB;IACF;AAEU,IAAA,aAAa,CAAC,KAAoB,EAAA;QAC1C,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE;QAErB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;QACvC,MAAM,OAAO,GAAG,MAAM,KAAK,YAAY,IAAI,MAAM,KAAK,MAAM;QAC5D,MAAM,MAAM,GAAG,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,MAAM;AAEzD,QAAA,QAAQ,KAAK,CAAC,GAAG;AACf,YAAA,KAAK,YAAY;AACjB,YAAA,KAAK,WAAW;gBACd,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,YAAY,IAAI,OAAO,MAAM,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,MAAM,CAAC,EAAE;oBACpF,KAAK,CAAC,cAAc,EAAE;AACtB,oBAAA,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC5B;gBACA;AAEF,YAAA,KAAK,WAAW;AAChB,YAAA,KAAK,SAAS;gBACZ,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,OAAO,MAAM,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,MAAM,CAAC,EAAE;oBACjF,KAAK,CAAC,cAAc,EAAE;AACtB,oBAAA,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC5B;gBACA;AAEF,YAAA,KAAK,MAAM;gBACT,KAAK,CAAC,cAAc,EAAE;AACtB,gBAAA,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE;gBACvB;AAEF,YAAA,KAAK,KAAK;gBACR,KAAK,CAAC,cAAc,EAAE;AACtB,gBAAA,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;gBACtB;;IAEN;8GAlEW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAArB,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,yBAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,OAAA,EAAA,SAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,SAAA,EAAA,uBAAA,EAAA,OAAA,EAAA,eAAA,EAAA,EAAA,UAAA,EAAA,EAAA,eAAA,EAAA,YAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA,CAAA;;2FAArB,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBATjC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,UAAU,EAAE,IAAI;AAChB,oBAAA,QAAQ,EAAE,yBAAyB;AACnC,oBAAA,IAAI,EAAE;AACJ,wBAAA,iBAAiB,EAAE,YAAY;AAC/B,wBAAA,WAAW,EAAE,uBAAuB;AACpC,wBAAA,SAAS,EAAE,eAAe;AAC3B,qBAAA;AACF,iBAAA;;;ACvID;;AAEG;;;;"}
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Injectable } from '@angular/core';
3
- import { DOCUMENT } from '@angular/common';
2
+ import { inject, PLATFORM_ID, Injectable } from '@angular/core';
3
+ import { DOCUMENT, isPlatformBrowser } from '@angular/common';
4
4
 
5
5
  /**
6
6
  * Locks body scrolling (for dialogs, drawers, sheets). Reference-counted so
@@ -10,31 +10,48 @@ import { DOCUMENT } from '@angular/common';
10
10
  class NgxsmkScrollLock {
11
11
  constructor() {
12
12
  this.document = inject(DOCUMENT);
13
+ this.platformId = inject(PLATFORM_ID);
13
14
  this.locks = 0;
14
15
  this.previousOverflow = '';
15
16
  this.previousPaddingRight = '';
17
+ this.previousOverscroll = '';
16
18
  }
17
19
  lock() {
20
+ if (!isPlatformBrowser(this.platformId)) {
21
+ return;
22
+ }
18
23
  if (this.locks++ > 0) {
19
24
  return;
20
25
  }
21
- const body = this.document.body;
26
+ const body = this.document?.body;
27
+ if (!body) {
28
+ return;
29
+ }
22
30
  const window = this.document.defaultView;
23
31
  const scrollbar = window ? window.innerWidth - this.document.documentElement.clientWidth : 0;
24
32
  this.previousOverflow = body.style.overflow;
25
33
  this.previousPaddingRight = body.style.paddingRight;
34
+ this.previousOverscroll = body.style.overscrollBehavior;
26
35
  body.style.overflow = 'hidden';
36
+ body.style.overscrollBehavior = 'none';
27
37
  if (scrollbar > 0) {
28
38
  body.style.paddingRight = `${scrollbar}px`;
29
39
  }
30
40
  }
31
41
  unlock() {
42
+ if (!isPlatformBrowser(this.platformId)) {
43
+ return;
44
+ }
32
45
  if (this.locks === 0 || --this.locks > 0) {
33
46
  return;
34
47
  }
35
- const body = this.document.body;
48
+ const body = this.document?.body;
49
+ if (!body) {
50
+ return;
51
+ }
36
52
  body.style.overflow = this.previousOverflow;
37
53
  body.style.paddingRight = this.previousPaddingRight;
54
+ body.style.overscrollBehavior = this.previousOverscroll;
38
55
  }
39
56
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkScrollLock, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
40
57
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkScrollLock, providedIn: 'root' }); }
@@ -1 +1 @@
1
- {"version":3,"file":"ngxsmk-cdk-scroll-lock.mjs","sources":["../../../../packages/cdk/scroll-lock/scroll-lock.ts","../../../../packages/cdk/scroll-lock/ngxsmk-cdk-scroll-lock.ts"],"sourcesContent":["import { Injectable, inject } from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\n\n/**\n * Locks body scrolling (for dialogs, drawers, sheets). Reference-counted so\n * nested overlays can lock independently; compensates for scrollbar width to\n * prevent layout shift.\n */\n@Injectable({ providedIn: 'root' })\nexport class NgxsmkScrollLock {\n private readonly document = inject(DOCUMENT);\n private locks = 0;\n private previousOverflow = '';\n private previousPaddingRight = '';\n\n lock(): void {\n if (this.locks++ > 0) {\n return;\n }\n const body = this.document.body;\n const window = this.document.defaultView;\n const scrollbar = window ? window.innerWidth - this.document.documentElement.clientWidth : 0;\n\n this.previousOverflow = body.style.overflow;\n this.previousPaddingRight = body.style.paddingRight;\n body.style.overflow = 'hidden';\n if (scrollbar > 0) {\n body.style.paddingRight = `${scrollbar}px`;\n }\n }\n\n unlock(): void {\n if (this.locks === 0 || --this.locks > 0) {\n return;\n }\n const body = this.document.body;\n body.style.overflow = this.previousOverflow;\n body.style.paddingRight = this.previousPaddingRight;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAGA;;;;AAIG;MAEU,gBAAgB,CAAA;AAD7B,IAAA,WAAA,GAAA;AAEmB,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QACpC,IAAA,CAAA,KAAK,GAAG,CAAC;QACT,IAAA,CAAA,gBAAgB,GAAG,EAAE;QACrB,IAAA,CAAA,oBAAoB,GAAG,EAAE;AA0BlC,IAAA;IAxBC,IAAI,GAAA;AACF,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;YACpB;QACF;AACA,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI;AAC/B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW;QACxC,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,WAAW,GAAG,CAAC;QAE5F,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ;QAC3C,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY;AACnD,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ;AAC9B,QAAA,IAAI,SAAS,GAAG,CAAC,EAAE;YACjB,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAA,EAAG,SAAS,IAAI;QAC5C;IACF;IAEA,MAAM,GAAA;AACJ,QAAA,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE;YACxC;QACF;AACA,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI;QAC/B,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,gBAAgB;QAC3C,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,oBAAoB;IACrD;8GA7BW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAhB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,cADH,MAAM,EAAA,CAAA,CAAA;;2FACnB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACRlC;;AAEG;;;;"}
1
+ {"version":3,"file":"ngxsmk-cdk-scroll-lock.mjs","sources":["../../../../packages/cdk/scroll-lock/scroll-lock.ts","../../../../packages/cdk/scroll-lock/ngxsmk-cdk-scroll-lock.ts"],"sourcesContent":["import { Injectable, inject, PLATFORM_ID } from '@angular/core';\nimport { DOCUMENT, isPlatformBrowser } from '@angular/common';\n\n/**\n * Locks body scrolling (for dialogs, drawers, sheets). Reference-counted so\n * nested overlays can lock independently; compensates for scrollbar width to\n * prevent layout shift.\n */\n@Injectable({ providedIn: 'root' })\nexport class NgxsmkScrollLock {\n private readonly document = inject(DOCUMENT);\n private readonly platformId = inject(PLATFORM_ID);\n private locks = 0;\n private previousOverflow = '';\n private previousPaddingRight = '';\n private previousOverscroll = '';\n\n lock(): void {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n if (this.locks++ > 0) {\n return;\n }\n const body = this.document?.body;\n if (!body) {\n return;\n }\n const window = this.document.defaultView;\n const scrollbar = window ? window.innerWidth - this.document.documentElement.clientWidth : 0;\n\n this.previousOverflow = body.style.overflow;\n this.previousPaddingRight = body.style.paddingRight;\n this.previousOverscroll = body.style.overscrollBehavior;\n\n body.style.overflow = 'hidden';\n body.style.overscrollBehavior = 'none';\n if (scrollbar > 0) {\n body.style.paddingRight = `${scrollbar}px`;\n }\n }\n\n unlock(): void {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n if (this.locks === 0 || --this.locks > 0) {\n return;\n }\n const body = this.document?.body;\n if (!body) {\n return;\n }\n body.style.overflow = this.previousOverflow;\n body.style.paddingRight = this.previousPaddingRight;\n body.style.overscrollBehavior = this.previousOverscroll;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAGA;;;;AAIG;MAEU,gBAAgB,CAAA;AAD7B,IAAA,WAAA,GAAA;AAEmB,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;AAC3B,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC;QACzC,IAAA,CAAA,KAAK,GAAG,CAAC;QACT,IAAA,CAAA,gBAAgB,GAAG,EAAE;QACrB,IAAA,CAAA,oBAAoB,GAAG,EAAE;QACzB,IAAA,CAAA,kBAAkB,GAAG,EAAE;AA0ChC,IAAA;IAxCC,IAAI,GAAA;QACF,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;YACvC;QACF;AACA,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;YACpB;QACF;AACA,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI;QAChC,IAAI,CAAC,IAAI,EAAE;YACT;QACF;AACA,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW;QACxC,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,WAAW,GAAG,CAAC;QAE5F,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ;QAC3C,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY;QACnD,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB;AAEvD,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ;AAC9B,QAAA,IAAI,CAAC,KAAK,CAAC,kBAAkB,GAAG,MAAM;AACtC,QAAA,IAAI,SAAS,GAAG,CAAC,EAAE;YACjB,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAA,EAAG,SAAS,IAAI;QAC5C;IACF;IAEA,MAAM,GAAA;QACJ,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;YACvC;QACF;AACA,QAAA,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE;YACxC;QACF;AACA,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI;QAChC,IAAI,CAAC,IAAI,EAAE;YACT;QACF;QACA,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,gBAAgB;QAC3C,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,oBAAoB;QACnD,IAAI,CAAC,KAAK,CAAC,kBAAkB,GAAG,IAAI,CAAC,kBAAkB;IACzD;8GA/CW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAhB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,cADH,MAAM,EAAA,CAAA,CAAA;;2FACnB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACRlC;;AAEG;;;;"}
@@ -0,0 +1,40 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, ChangeDetectionStrategy, Component } from '@angular/core';
3
+
4
+ /**
5
+ * Accessible skip navigation link for keyboard users to bypass repetitive header navigation.
6
+ * Renders off-screen by default, sliding into view when focused via Tab.
7
+ *
8
+ * ```html
9
+ * <ngxsmk-skip-link targetId="main-content" label="Skip to main content" />
10
+ * ```
11
+ */
12
+ class NgxsmkSkipLink {
13
+ constructor() {
14
+ /** Target HTML ID anchor to scroll/focus to. Default: 'main-content'. */
15
+ this.targetId = input('main-content');
16
+ /** Label text rendered inside the skip link. Default: 'Skip to content'. */
17
+ this.label = input('Skip to content');
18
+ }
19
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkSkipLink, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
20
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.0", type: NgxsmkSkipLink, isStandalone: true, selector: "ngxsmk-skip-link", inputs: { targetId: { classPropertyName: "targetId", publicName: "targetId", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
21
+ <a [href]="'#' + targetId()" class="ngxsmk-skip-link">
22
+ {{ label() }}
23
+ </a>
24
+ `, isInline: true, styles: [".ngxsmk-skip-link{position:absolute;top:-9999px;inset-inline-start:var(--ngxsmk-space-4, 1rem);z-index:var(--ngxsmk-z-popover, 1000);padding:var(--ngxsmk-space-3, .75rem) var(--ngxsmk-space-4, 1rem);background:var(--ngxsmk-color-primary, #7c3aed);color:var(--ngxsmk-color-on-primary, #ffffff);font-family:var(--ngxsmk-font-sans, system-ui);font-size:var(--ngxsmk-text-body-sm-size, .875rem);font-weight:600;text-decoration:none;border-radius:var(--ngxsmk-radius-md, .375rem);box-shadow:var(--ngxsmk-shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, .1));outline:none;transition:top .15s ease-out}.ngxsmk-skip-link:focus{top:var(--ngxsmk-space-4, 1rem);box-shadow:var(--ngxsmk-focus-ring)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
25
+ }
26
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: NgxsmkSkipLink, decorators: [{
27
+ type: Component,
28
+ args: [{ standalone: true, selector: 'ngxsmk-skip-link', template: `
29
+ <a [href]="'#' + targetId()" class="ngxsmk-skip-link">
30
+ {{ label() }}
31
+ </a>
32
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".ngxsmk-skip-link{position:absolute;top:-9999px;inset-inline-start:var(--ngxsmk-space-4, 1rem);z-index:var(--ngxsmk-z-popover, 1000);padding:var(--ngxsmk-space-3, .75rem) var(--ngxsmk-space-4, 1rem);background:var(--ngxsmk-color-primary, #7c3aed);color:var(--ngxsmk-color-on-primary, #ffffff);font-family:var(--ngxsmk-font-sans, system-ui);font-size:var(--ngxsmk-text-body-sm-size, .875rem);font-weight:600;text-decoration:none;border-radius:var(--ngxsmk-radius-md, .375rem);box-shadow:var(--ngxsmk-shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, .1));outline:none;transition:top .15s ease-out}.ngxsmk-skip-link:focus{top:var(--ngxsmk-space-4, 1rem);box-shadow:var(--ngxsmk-focus-ring)}\n"] }]
33
+ }] });
34
+
35
+ /**
36
+ * Generated bundle index. Do not edit.
37
+ */
38
+
39
+ export { NgxsmkSkipLink };
40
+ //# sourceMappingURL=ngxsmk-cdk-skip-link.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngxsmk-cdk-skip-link.mjs","sources":["../../../../packages/cdk/skip-link/skip-link.ts","../../../../packages/cdk/skip-link/ngxsmk-cdk-skip-link.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\n/**\n * Accessible skip navigation link for keyboard users to bypass repetitive header navigation.\n * Renders off-screen by default, sliding into view when focused via Tab.\n *\n * ```html\n * <ngxsmk-skip-link targetId=\"main-content\" label=\"Skip to main content\" />\n * ```\n */\n@Component({\n standalone: true,\n selector: 'ngxsmk-skip-link',\n template: `\n <a [href]=\"'#' + targetId()\" class=\"ngxsmk-skip-link\">\n {{ label() }}\n </a>\n `,\n styles: `\n .ngxsmk-skip-link {\n position: absolute;\n top: -9999px;\n inset-inline-start: var(--ngxsmk-space-4, 1rem);\n z-index: var(--ngxsmk-z-popover, 1000);\n padding: var(--ngxsmk-space-3, 0.75rem) var(--ngxsmk-space-4, 1rem);\n background: var(--ngxsmk-color-primary, #7c3aed);\n color: var(--ngxsmk-color-on-primary, #ffffff);\n font-family: var(--ngxsmk-font-sans, system-ui);\n font-size: var(--ngxsmk-text-body-sm-size, 0.875rem);\n font-weight: 600;\n text-decoration: none;\n border-radius: var(--ngxsmk-radius-md, 0.375rem);\n box-shadow: var(--ngxsmk-shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, 0.1));\n outline: none;\n transition: top 0.15s ease-out;\n }\n\n .ngxsmk-skip-link:focus {\n top: var(--ngxsmk-space-4, 1rem);\n box-shadow: var(--ngxsmk-focus-ring);\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class NgxsmkSkipLink {\n /** Target HTML ID anchor to scroll/focus to. Default: 'main-content'. */\n readonly targetId = input<string>('main-content');\n\n /** Label text rendered inside the skip link. Default: 'Skip to content'. */\n readonly label = input<string>('Skip to content');\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;AAEA;;;;;;;AAOG;MAmCU,cAAc,CAAA;AAlC3B,IAAA,WAAA,GAAA;;AAoCW,QAAA,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAS,cAAc,CAAC;;AAGxC,QAAA,IAAA,CAAA,KAAK,GAAG,KAAK,CAAS,iBAAiB,CAAC;AAClD,IAAA;8GANY,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAd,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,cAAc,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA/Bf;;;;AAIT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,4qBAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FA2BU,cAAc,EAAA,UAAA,EAAA,CAAA;kBAlC1B,SAAS;iCACI,IAAI,EAAA,QAAA,EACN,kBAAkB,EAAA,QAAA,EAClB;;;;GAIT,EAAA,eAAA,EAyBgB,uBAAuB,CAAC,MAAM,EAAA,MAAA,EAAA,CAAA,4qBAAA,CAAA,EAAA;;;AC1CjD;;AAEG;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ngxsmk/cdk",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Low-level Angular directives and utilities (click-outside, focus-trap, media-query, scroll-lock) for @ngxsmk.",
5
5
  "keywords": [
6
6
  "angular",
@@ -62,23 +62,17 @@
62
62
  "esm": "./esm2022/cva-base/ngxsmk-cdk-cva-base.mjs",
63
63
  "default": "./fesm2022/ngxsmk-cdk-cva-base.mjs"
64
64
  },
65
- "./focus-trap": {
66
- "types": "./focus-trap/index.d.ts",
67
- "esm2022": "./esm2022/focus-trap/ngxsmk-cdk-focus-trap.mjs",
68
- "esm": "./esm2022/focus-trap/ngxsmk-cdk-focus-trap.mjs",
69
- "default": "./fesm2022/ngxsmk-cdk-focus-trap.mjs"
70
- },
71
65
  "./input-group": {
72
66
  "types": "./input-group/index.d.ts",
73
67
  "esm2022": "./esm2022/input-group/ngxsmk-cdk-input-group.mjs",
74
68
  "esm": "./esm2022/input-group/ngxsmk-cdk-input-group.mjs",
75
69
  "default": "./fesm2022/ngxsmk-cdk-input-group.mjs"
76
70
  },
77
- "./focusable": {
78
- "types": "./focusable/index.d.ts",
79
- "esm2022": "./esm2022/focusable/ngxsmk-cdk-focusable.mjs",
80
- "esm": "./esm2022/focusable/ngxsmk-cdk-focusable.mjs",
81
- "default": "./fesm2022/ngxsmk-cdk-focusable.mjs"
71
+ "./focus-trap": {
72
+ "types": "./focus-trap/index.d.ts",
73
+ "esm2022": "./esm2022/focus-trap/ngxsmk-cdk-focus-trap.mjs",
74
+ "esm": "./esm2022/focus-trap/ngxsmk-cdk-focus-trap.mjs",
75
+ "default": "./fesm2022/ngxsmk-cdk-focus-trap.mjs"
82
76
  },
83
77
  "./listbox-keyboard": {
84
78
  "types": "./listbox-keyboard/index.d.ts",
@@ -86,6 +80,12 @@
86
80
  "esm": "./esm2022/listbox-keyboard/ngxsmk-cdk-listbox-keyboard.mjs",
87
81
  "default": "./fesm2022/ngxsmk-cdk-listbox-keyboard.mjs"
88
82
  },
83
+ "./focusable": {
84
+ "types": "./focusable/index.d.ts",
85
+ "esm2022": "./esm2022/focusable/ngxsmk-cdk-focusable.mjs",
86
+ "esm": "./esm2022/focusable/ngxsmk-cdk-focusable.mjs",
87
+ "default": "./fesm2022/ngxsmk-cdk-focusable.mjs"
88
+ },
89
89
  "./intersection-observer": {
90
90
  "types": "./intersection-observer/index.d.ts",
91
91
  "esm2022": "./esm2022/intersection-observer/ngxsmk-cdk-intersection-observer.mjs",
@@ -110,11 +110,11 @@
110
110
  "esm": "./esm2022/resize-observer/ngxsmk-cdk-resize-observer.mjs",
111
111
  "default": "./fesm2022/ngxsmk-cdk-resize-observer.mjs"
112
112
  },
113
- "./scheduler": {
114
- "types": "./scheduler/index.d.ts",
115
- "esm2022": "./esm2022/scheduler/ngxsmk-cdk-scheduler.mjs",
116
- "esm": "./esm2022/scheduler/ngxsmk-cdk-scheduler.mjs",
117
- "default": "./fesm2022/ngxsmk-cdk-scheduler.mjs"
113
+ "./roving-focus": {
114
+ "types": "./roving-focus/index.d.ts",
115
+ "esm2022": "./esm2022/roving-focus/ngxsmk-cdk-roving-focus.mjs",
116
+ "esm": "./esm2022/roving-focus/ngxsmk-cdk-roving-focus.mjs",
117
+ "default": "./fesm2022/ngxsmk-cdk-roving-focus.mjs"
118
118
  },
119
119
  "./scroll-lock": {
120
120
  "types": "./scroll-lock/index.d.ts",
@@ -122,23 +122,35 @@
122
122
  "esm": "./esm2022/scroll-lock/ngxsmk-cdk-scroll-lock.mjs",
123
123
  "default": "./fesm2022/ngxsmk-cdk-scroll-lock.mjs"
124
124
  },
125
+ "./scheduler": {
126
+ "types": "./scheduler/index.d.ts",
127
+ "esm2022": "./esm2022/scheduler/ngxsmk-cdk-scheduler.mjs",
128
+ "esm": "./esm2022/scheduler/ngxsmk-cdk-scheduler.mjs",
129
+ "default": "./fesm2022/ngxsmk-cdk-scheduler.mjs"
130
+ },
131
+ "./skip-link": {
132
+ "types": "./skip-link/index.d.ts",
133
+ "esm2022": "./esm2022/skip-link/ngxsmk-cdk-skip-link.mjs",
134
+ "esm": "./esm2022/skip-link/ngxsmk-cdk-skip-link.mjs",
135
+ "default": "./fesm2022/ngxsmk-cdk-skip-link.mjs"
136
+ },
125
137
  "./spreadsheet": {
126
138
  "types": "./spreadsheet/index.d.ts",
127
139
  "esm2022": "./esm2022/spreadsheet/ngxsmk-cdk-spreadsheet.mjs",
128
140
  "esm": "./esm2022/spreadsheet/ngxsmk-cdk-spreadsheet.mjs",
129
141
  "default": "./fesm2022/ngxsmk-cdk-spreadsheet.mjs"
130
142
  },
131
- "./testing": {
132
- "types": "./testing/index.d.ts",
133
- "esm2022": "./esm2022/testing/ngxsmk-cdk-testing.mjs",
134
- "esm": "./esm2022/testing/ngxsmk-cdk-testing.mjs",
135
- "default": "./fesm2022/ngxsmk-cdk-testing.mjs"
136
- },
137
143
  "./visually-hidden": {
138
144
  "types": "./visually-hidden/index.d.ts",
139
145
  "esm2022": "./esm2022/visually-hidden/ngxsmk-cdk-visually-hidden.mjs",
140
146
  "esm": "./esm2022/visually-hidden/ngxsmk-cdk-visually-hidden.mjs",
141
147
  "default": "./fesm2022/ngxsmk-cdk-visually-hidden.mjs"
148
+ },
149
+ "./testing": {
150
+ "types": "./testing/index.d.ts",
151
+ "esm2022": "./esm2022/testing/ngxsmk-cdk-testing.mjs",
152
+ "esm": "./esm2022/testing/ngxsmk-cdk-testing.mjs",
153
+ "default": "./fesm2022/ngxsmk-cdk-testing.mjs"
142
154
  }
143
155
  }
144
156
  }
@@ -0,0 +1,2 @@
1
+ export * from './roving-focus';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../packages/cdk/roving-focus/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngxsmk-cdk-roving-focus.d.ts","sourceRoot":"","sources":["../../../../packages/cdk/roving-focus/ngxsmk-cdk-roving-focus.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,cAAc,SAAS,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { InjectionToken, OnDestroy, WritableSignal } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export type NgxsmkRovingOrientation = 'horizontal' | 'vertical' | 'both';
4
+ export interface NgxsmkRovingFocusContext {
5
+ register(item: NgxsmkRovingFocusItem): void;
6
+ unregister(item: NgxsmkRovingFocusItem): void;
7
+ focusNext(current: NgxsmkRovingFocusItem): void;
8
+ focusPrev(current: NgxsmkRovingFocusItem): void;
9
+ focusFirst(): void;
10
+ focusLast(): void;
11
+ activeItem: WritableSignal<NgxsmkRovingFocusItem | null>;
12
+ orientation: () => NgxsmkRovingOrientation;
13
+ loop: () => boolean;
14
+ }
15
+ export declare const NGXSMK_ROVING_FOCUS_GROUP: InjectionToken<NgxsmkRovingFocusContext>;
16
+ /**
17
+ * Universal signals-native Roving Focus container directive.
18
+ * Manages keyboard navigation (Arrow keys, Home, End) across a set of items,
19
+ * keeping only the currently active item focusable via Tab (`tabindex="0"` vs `"-1"`).
20
+ *
21
+ * ```html
22
+ * <div ngxsmkRovingFocusGroup orientation="horizontal" [loop]="true">
23
+ * <button ngxsmkRovingFocusItem>Tab 1</button>
24
+ * <button ngxsmkRovingFocusItem>Tab 2</button>
25
+ * </div>
26
+ * ```
27
+ */
28
+ export declare class NgxsmkRovingFocusGroup implements NgxsmkRovingFocusContext {
29
+ readonly orientation: import("@angular/core").InputSignal<NgxsmkRovingOrientation>;
30
+ readonly loop: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
31
+ private readonly items;
32
+ readonly activeItem: WritableSignal<NgxsmkRovingFocusItem>;
33
+ register(item: NgxsmkRovingFocusItem): void;
34
+ unregister(item: NgxsmkRovingFocusItem): void;
35
+ focusNext(current: NgxsmkRovingFocusItem): void;
36
+ focusPrev(current: NgxsmkRovingFocusItem): void;
37
+ focusFirst(): void;
38
+ focusLast(): void;
39
+ private setActiveAndFocus;
40
+ static ɵfac: i0.ɵɵFactoryDeclaration<NgxsmkRovingFocusGroup, never>;
41
+ static ɵdir: i0.ɵɵDirectiveDeclaration<NgxsmkRovingFocusGroup, "[ngxsmkRovingFocusGroup]", never, { "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "loop": { "alias": "loop"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
42
+ }
43
+ /**
44
+ * Item in a Roving Focus group. Binds `[tabindex]` dynamically based on active state.
45
+ */
46
+ export declare class NgxsmkRovingFocusItem implements OnDestroy {
47
+ private readonly group;
48
+ private readonly elRef;
49
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
50
+ readonly focused: import("@angular/core").OutputEmitterRef<void>;
51
+ readonly isActive: import("@angular/core").Signal<boolean>;
52
+ readonly tabIndex: import("@angular/core").Signal<0 | -1>;
53
+ constructor();
54
+ ngOnDestroy(): void;
55
+ focus(): void;
56
+ protected handleFocus(): void;
57
+ protected handleKeydown(event: KeyboardEvent): void;
58
+ static ɵfac: i0.ɵɵFactoryDeclaration<NgxsmkRovingFocusItem, never>;
59
+ static ɵdir: i0.ɵɵDirectiveDeclaration<NgxsmkRovingFocusItem, "[ngxsmkRovingFocusItem]", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "focused": "focused"; }, never, never, true, never>;
60
+ }
61
+ //# sourceMappingURL=roving-focus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roving-focus.d.ts","sourceRoot":"","sources":["../../../../packages/cdk/roving-focus/roving-focus.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,cAAc,EACd,SAAS,EACT,cAAc,EAOf,MAAM,eAAe,CAAC;;AAEvB,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG,UAAU,GAAG,MAAM,CAAC;AAEzE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC5C,UAAU,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC9C,SAAS,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAChD,SAAS,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAChD,UAAU,IAAI,IAAI,CAAC;IACnB,SAAS,IAAI,IAAI,CAAC;IAClB,UAAU,EAAE,cAAc,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;IACzD,WAAW,EAAE,MAAM,uBAAuB,CAAC;IAC3C,IAAI,EAAE,MAAM,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,yBAAyB,0CAErC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,qBAUa,sBAAuB,YAAW,wBAAwB;IACrE,QAAQ,CAAC,WAAW,+DAAgD;IACpE,QAAQ,CAAC,IAAI,qEAAgD;IAE7D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuC;IAC7D,QAAQ,CAAC,UAAU,wCAA8C;IAEjE,QAAQ,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI;IAO3C,UAAU,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI;IAQ7C,SAAS,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAc/C,SAAS,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAc/C,UAAU,IAAI,IAAI;IAOlB,SAAS,IAAI,IAAI;IAOjB,OAAO,CAAC,iBAAiB;yCAhEd,sBAAsB;2CAAtB,sBAAsB;CAoElC;AAED;;GAEG;AACH,qBASa,qBAAsB,YAAW,SAAS;IACrD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAC3D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmC;IAEzD,QAAQ,CAAC,QAAQ,qEAAiD;IAClE,QAAQ,CAAC,OAAO,iDAAkB;IAElC,QAAQ,CAAC,QAAQ,0CAAoD;IACrE,QAAQ,CAAC,QAAQ,yCAGd;;IAMH,WAAW,IAAI,IAAI;IAInB,KAAK,IAAI,IAAI;IAIb,SAAS,CAAC,WAAW,IAAI,IAAI;IAO7B,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;yCAhCxC,qBAAqB;2CAArB,qBAAqB;CAmEjC"}
@@ -6,9 +6,11 @@ import * as i0 from "@angular/core";
6
6
  */
7
7
  export declare class NgxsmkScrollLock {
8
8
  private readonly document;
9
+ private readonly platformId;
9
10
  private locks;
10
11
  private previousOverflow;
11
12
  private previousPaddingRight;
13
+ private previousOverscroll;
12
14
  lock(): void;
13
15
  unlock(): void;
14
16
  static ɵfac: i0.ɵɵFactoryDeclaration<NgxsmkScrollLock, never>;
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-lock.d.ts","sourceRoot":"","sources":["../../../../packages/cdk/scroll-lock/scroll-lock.ts"],"names":[],"mappings":";AAGA;;;;GAIG;AACH,qBACa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,oBAAoB,CAAM;IAElC,IAAI,IAAI,IAAI;IAgBZ,MAAM,IAAI,IAAI;yCAtBH,gBAAgB;6CAAhB,gBAAgB;CA8B5B"}
1
+ {"version":3,"file":"scroll-lock.d.ts","sourceRoot":"","sources":["../../../../packages/cdk/scroll-lock/scroll-lock.ts"],"names":[],"mappings":";AAGA;;;;GAIG;AACH,qBACa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuB;IAClD,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,oBAAoB,CAAM;IAClC,OAAO,CAAC,kBAAkB,CAAM;IAEhC,IAAI,IAAI,IAAI;IAyBZ,MAAM,IAAI,IAAI;yCAjCH,gBAAgB;6CAAhB,gBAAgB;CAgD5B"}
@@ -0,0 +1,2 @@
1
+ export * from './skip-link';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../packages/cdk/skip-link/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngxsmk-cdk-skip-link.d.ts","sourceRoot":"","sources":["../../../../packages/cdk/skip-link/ngxsmk-cdk-skip-link.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,cAAc,SAAS,CAAC"}
@@ -0,0 +1,18 @@
1
+ import * as i0 from "@angular/core";
2
+ /**
3
+ * Accessible skip navigation link for keyboard users to bypass repetitive header navigation.
4
+ * Renders off-screen by default, sliding into view when focused via Tab.
5
+ *
6
+ * ```html
7
+ * <ngxsmk-skip-link targetId="main-content" label="Skip to main content" />
8
+ * ```
9
+ */
10
+ export declare class NgxsmkSkipLink {
11
+ /** Target HTML ID anchor to scroll/focus to. Default: 'main-content'. */
12
+ readonly targetId: import("@angular/core").InputSignal<string>;
13
+ /** Label text rendered inside the skip link. Default: 'Skip to content'. */
14
+ readonly label: import("@angular/core").InputSignal<string>;
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<NgxsmkSkipLink, never>;
16
+ static ɵcmp: i0.ɵɵComponentDeclaration<NgxsmkSkipLink, "ngxsmk-skip-link", never, { "targetId": { "alias": "targetId"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
17
+ }
18
+ //# sourceMappingURL=skip-link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skip-link.d.ts","sourceRoot":"","sources":["../../../../packages/cdk/skip-link/skip-link.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AACH,qBAkCa,cAAc;IACzB,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,8CAAiC;IAElD,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,8CAAoC;yCALvC,cAAc;2CAAd,cAAc;CAM1B"}