forty-cdk 0.2.0 → 0.3.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/accordion/README.md +122 -0
- package/aspect-ratio/README.md +76 -0
- package/avatar/README.md +100 -0
- package/breadcrumbs/README.md +49 -0
- package/breakpoints/README.md +81 -0
- package/button/README.md +49 -0
- package/calendar/README.md +458 -0
- package/carousel/README.md +358 -0
- package/checkbox/README.md +146 -0
- package/combobox/README.md +535 -0
- package/context-menu/README.md +139 -0
- package/date-field/README.md +184 -0
- package/date-picker/README.md +338 -0
- package/dialog/README.md +388 -0
- package/disclosure/README.md +114 -0
- package/drag-drop/README.md +359 -0
- package/drawer/README.md +560 -0
- package/dropdown-menu/README.md +176 -0
- package/fesm2022/forty-cdk-accordion.mjs +348 -0
- package/fesm2022/forty-cdk-accordion.mjs.map +1 -0
- package/fesm2022/forty-cdk-aspect-ratio.mjs +74 -0
- package/fesm2022/forty-cdk-aspect-ratio.mjs.map +1 -0
- package/fesm2022/forty-cdk-avatar.mjs +308 -0
- package/fesm2022/forty-cdk-avatar.mjs.map +1 -0
- package/fesm2022/forty-cdk-breadcrumbs.mjs +125 -0
- package/fesm2022/forty-cdk-breadcrumbs.mjs.map +1 -0
- package/fesm2022/forty-cdk-breakpoints.mjs +117 -0
- package/fesm2022/forty-cdk-breakpoints.mjs.map +1 -0
- package/fesm2022/forty-cdk-button.mjs +134 -0
- package/fesm2022/forty-cdk-button.mjs.map +1 -0
- package/fesm2022/forty-cdk-calendar.mjs +2034 -0
- package/fesm2022/forty-cdk-calendar.mjs.map +1 -0
- package/fesm2022/forty-cdk-carousel.mjs +968 -0
- package/fesm2022/forty-cdk-carousel.mjs.map +1 -0
- package/fesm2022/forty-cdk-checkbox.mjs +226 -0
- package/fesm2022/forty-cdk-checkbox.mjs.map +1 -0
- package/fesm2022/forty-cdk-combobox.mjs +2596 -0
- package/fesm2022/forty-cdk-combobox.mjs.map +1 -0
- package/fesm2022/forty-cdk-context-menu.mjs +413 -0
- package/fesm2022/forty-cdk-context-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-core.mjs +9022 -0
- package/fesm2022/forty-cdk-core.mjs.map +1 -0
- package/fesm2022/forty-cdk-date-field.mjs +744 -0
- package/fesm2022/forty-cdk-date-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-date-picker.mjs +1011 -0
- package/fesm2022/forty-cdk-date-picker.mjs.map +1 -0
- package/fesm2022/forty-cdk-dialog.mjs +707 -0
- package/fesm2022/forty-cdk-dialog.mjs.map +1 -0
- package/fesm2022/forty-cdk-disclosure.mjs +190 -0
- package/fesm2022/forty-cdk-disclosure.mjs.map +1 -0
- package/fesm2022/forty-cdk-drag-drop.mjs +1180 -0
- package/fesm2022/forty-cdk-drag-drop.mjs.map +1 -0
- package/fesm2022/forty-cdk-drawer.mjs +1641 -0
- package/fesm2022/forty-cdk-drawer.mjs.map +1 -0
- package/fesm2022/forty-cdk-dropdown-menu.mjs +350 -0
- package/fesm2022/forty-cdk-dropdown-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-field.mjs +425 -0
- package/fesm2022/forty-cdk-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-fieldset.mjs +164 -0
- package/fesm2022/forty-cdk-fieldset.mjs.map +1 -0
- package/fesm2022/forty-cdk-file-upload.mjs +221 -0
- package/fesm2022/forty-cdk-file-upload.mjs.map +1 -0
- package/fesm2022/forty-cdk-hover-card.mjs +496 -0
- package/fesm2022/forty-cdk-hover-card.mjs.map +1 -0
- package/fesm2022/forty-cdk-input.mjs +274 -0
- package/fesm2022/forty-cdk-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-internationalized-date.mjs +1 -1
- package/fesm2022/forty-cdk-internationalized-date.mjs.map +1 -1
- package/fesm2022/forty-cdk-listbox.mjs +1279 -0
- package/fesm2022/forty-cdk-listbox.mjs.map +1 -0
- package/fesm2022/forty-cdk-menu.mjs +1439 -0
- package/fesm2022/forty-cdk-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-menubar.mjs +787 -0
- package/fesm2022/forty-cdk-menubar.mjs.map +1 -0
- package/fesm2022/forty-cdk-meter.mjs +211 -0
- package/fesm2022/forty-cdk-meter.mjs.map +1 -0
- package/fesm2022/forty-cdk-navigation-menu.mjs +1145 -0
- package/fesm2022/forty-cdk-navigation-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-number-input.mjs +559 -0
- package/fesm2022/forty-cdk-number-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-otp-input.mjs +527 -0
- package/fesm2022/forty-cdk-otp-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-pagination.mjs +323 -0
- package/fesm2022/forty-cdk-pagination.mjs.map +1 -0
- package/fesm2022/forty-cdk-pane-resizer.mjs +297 -0
- package/fesm2022/forty-cdk-pane-resizer.mjs.map +1 -0
- package/fesm2022/forty-cdk-popover.mjs +698 -0
- package/fesm2022/forty-cdk-popover.mjs.map +1 -0
- package/fesm2022/forty-cdk-progress.mjs +226 -0
- package/fesm2022/forty-cdk-progress.mjs.map +1 -0
- package/fesm2022/forty-cdk-radio-group.mjs +378 -0
- package/fesm2022/forty-cdk-radio-group.mjs.map +1 -0
- package/fesm2022/forty-cdk-scroll-area.mjs +640 -0
- package/fesm2022/forty-cdk-scroll-area.mjs.map +1 -0
- package/fesm2022/forty-cdk-search.mjs +205 -0
- package/fesm2022/forty-cdk-search.mjs.map +1 -0
- package/fesm2022/forty-cdk-select.mjs +1661 -0
- package/fesm2022/forty-cdk-select.mjs.map +1 -0
- package/fesm2022/forty-cdk-separator.mjs +82 -0
- package/fesm2022/forty-cdk-separator.mjs.map +1 -0
- package/fesm2022/forty-cdk-signal-forms.mjs +97 -0
- package/fesm2022/forty-cdk-signal-forms.mjs.map +1 -0
- package/fesm2022/forty-cdk-slider.mjs +803 -0
- package/fesm2022/forty-cdk-slider.mjs.map +1 -0
- package/fesm2022/forty-cdk-stepper.mjs +886 -0
- package/fesm2022/forty-cdk-stepper.mjs.map +1 -0
- package/fesm2022/forty-cdk-switch.mjs +137 -0
- package/fesm2022/forty-cdk-switch.mjs.map +1 -0
- package/fesm2022/forty-cdk-table.mjs +1518 -0
- package/fesm2022/forty-cdk-table.mjs.map +1 -0
- package/fesm2022/forty-cdk-tabs.mjs +400 -0
- package/fesm2022/forty-cdk-tabs.mjs.map +1 -0
- package/fesm2022/forty-cdk-time-field.mjs +593 -0
- package/fesm2022/forty-cdk-time-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-time-picker.mjs +1013 -0
- package/fesm2022/forty-cdk-time-picker.mjs.map +1 -0
- package/fesm2022/forty-cdk-toast.mjs +1153 -0
- package/fesm2022/forty-cdk-toast.mjs.map +1 -0
- package/fesm2022/forty-cdk-toggle.mjs +516 -0
- package/fesm2022/forty-cdk-toggle.mjs.map +1 -0
- package/fesm2022/forty-cdk-toolbar.mjs +374 -0
- package/fesm2022/forty-cdk-toolbar.mjs.map +1 -0
- package/fesm2022/forty-cdk-tooltip.mjs +672 -0
- package/fesm2022/forty-cdk-tooltip.mjs.map +1 -0
- package/fesm2022/forty-cdk-tree.mjs +2007 -0
- package/fesm2022/forty-cdk-tree.mjs.map +1 -0
- package/fesm2022/forty-cdk-virtualization.mjs +1 -1
- package/fesm2022/forty-cdk-virtualization.mjs.map +1 -1
- package/fesm2022/forty-cdk.mjs +0 -43310
- package/fesm2022/forty-cdk.mjs.map +1 -1
- package/field/README.md +97 -0
- package/fieldset/README.md +86 -0
- package/file-upload/README.md +73 -0
- package/hover-card/README.md +171 -0
- package/input/README.md +156 -0
- package/listbox/README.md +424 -0
- package/menu/README.md +181 -0
- package/menubar/README.md +140 -0
- package/meter/README.md +128 -0
- package/navigation-menu/README.md +253 -0
- package/number-input/README.md +171 -0
- package/otp-input/README.md +198 -0
- package/package.json +213 -1
- package/pagination/README.md +61 -0
- package/pane-resizer/README.md +136 -0
- package/popover/README.md +262 -0
- package/progress/README.md +115 -0
- package/radio-group/README.md +129 -0
- package/scroll-area/README.md +184 -0
- package/search/README.md +42 -0
- package/select/README.md +488 -0
- package/separator/README.md +84 -0
- package/signal-forms/README.md +72 -0
- package/slider/README.md +152 -0
- package/stepper/README.md +292 -0
- package/switch/README.md +116 -0
- package/table/README.md +769 -0
- package/tabs/README.md +130 -0
- package/time-field/README.md +157 -0
- package/time-picker/README.md +172 -0
- package/toast/README.md +398 -0
- package/toggle/README.md +224 -0
- package/toolbar/README.md +109 -0
- package/tooltip/README.md +274 -0
- package/tree/README.md +708 -0
- package/types/forty-cdk-accordion.d.ts +242 -0
- package/types/forty-cdk-aspect-ratio.d.ts +59 -0
- package/types/forty-cdk-avatar.d.ts +133 -0
- package/types/forty-cdk-breadcrumbs.d.ts +92 -0
- package/types/forty-cdk-breakpoints.d.ts +141 -0
- package/types/forty-cdk-button.d.ts +80 -0
- package/types/forty-cdk-calendar.d.ts +914 -0
- package/types/forty-cdk-carousel.d.ts +530 -0
- package/types/forty-cdk-checkbox.d.ts +141 -0
- package/types/forty-cdk-combobox.d.ts +1259 -0
- package/types/forty-cdk-context-menu.d.ts +313 -0
- package/types/forty-cdk-core.d.ts +5774 -0
- package/types/forty-cdk-date-field.d.ts +307 -0
- package/types/forty-cdk-date-picker.d.ts +622 -0
- package/types/forty-cdk-dialog.d.ts +546 -0
- package/types/forty-cdk-disclosure.d.ts +127 -0
- package/types/forty-cdk-drag-drop.d.ts +456 -0
- package/types/forty-cdk-drawer.d.ts +871 -0
- package/types/forty-cdk-dropdown-menu.d.ts +242 -0
- package/types/forty-cdk-field.d.ts +236 -0
- package/types/forty-cdk-fieldset.d.ts +119 -0
- package/types/forty-cdk-file-upload.d.ts +124 -0
- package/types/forty-cdk-hover-card.d.ts +320 -0
- package/types/forty-cdk-input.d.ts +169 -0
- package/types/forty-cdk-internationalized-date.d.ts +1 -1
- package/types/forty-cdk-listbox.d.ts +513 -0
- package/types/forty-cdk-menu.d.ts +629 -0
- package/types/forty-cdk-menubar.d.ts +451 -0
- package/types/forty-cdk-meter.d.ts +122 -0
- package/types/forty-cdk-navigation-menu.d.ts +514 -0
- package/types/forty-cdk-number-input.d.ts +319 -0
- package/types/forty-cdk-otp-input.d.ts +248 -0
- package/types/forty-cdk-pagination.d.ts +214 -0
- package/types/forty-cdk-pane-resizer.d.ts +145 -0
- package/types/forty-cdk-popover.d.ts +509 -0
- package/types/forty-cdk-progress.d.ts +143 -0
- package/types/forty-cdk-radio-group.d.ts +222 -0
- package/types/forty-cdk-scroll-area.d.ts +258 -0
- package/types/forty-cdk-search.d.ts +142 -0
- package/types/forty-cdk-select.d.ts +899 -0
- package/types/forty-cdk-separator.d.ts +59 -0
- package/types/forty-cdk-signal-forms.d.ts +58 -0
- package/types/forty-cdk-slider.d.ts +379 -0
- package/types/forty-cdk-stepper.d.ts +650 -0
- package/types/forty-cdk-switch.d.ts +87 -0
- package/types/forty-cdk-table.d.ts +723 -0
- package/types/forty-cdk-tabs.d.ts +235 -0
- package/types/forty-cdk-time-field.d.ts +307 -0
- package/types/forty-cdk-time-picker.d.ts +578 -0
- package/types/forty-cdk-toast.d.ts +598 -0
- package/types/forty-cdk-toggle.d.ts +310 -0
- package/types/forty-cdk-toolbar.d.ts +217 -0
- package/types/forty-cdk-tooltip.d.ts +436 -0
- package/types/forty-cdk-tree.d.ts +688 -0
- package/types/forty-cdk.d.ts +1 -19743
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, model, input, booleanAttribute, computed, Directive, ElementRef } from '@angular/core';
|
|
3
|
+
import { createDefaults, injectTextDirection, RovingTabindex, Collection, firstEnabledHost, reconcileRovingActive, moveIndex, hostId, registerHandle, resolveListNavigation, injectHasFocusableContent } from 'forty-cdk/core';
|
|
4
|
+
|
|
5
|
+
const FOR_TABS_CONTEXT = new InjectionToken('FOR_TABS_CONTEXT');
|
|
6
|
+
function injectTabsContext(piece) {
|
|
7
|
+
const ctx = inject(FOR_TABS_CONTEXT, { optional: true });
|
|
8
|
+
if (!ctx) {
|
|
9
|
+
throw new Error(`[forty-cdk/tabs] ${piece} must be used inside a [forTabs] element.`);
|
|
10
|
+
}
|
|
11
|
+
return ctx;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Library fallback for tabs defaults, read at the root injector when no
|
|
16
|
+
* consumer has called `provideForTabsDefaults`. Exported for the shared
|
|
17
|
+
* defaults contract spec; not re-exported from the primitive's public entry.
|
|
18
|
+
*/
|
|
19
|
+
const FOR_TABS_FALLBACK_DEFAULTS = {
|
|
20
|
+
activationMode: 'automatic',
|
|
21
|
+
loop: true,
|
|
22
|
+
};
|
|
23
|
+
const { token, provideDefaults } = createDefaults('FOR_TABS_DEFAULTS', FOR_TABS_FALLBACK_DEFAULTS);
|
|
24
|
+
/** Token holding the resolved tabs defaults for the current scope. */
|
|
25
|
+
const FOR_TABS_DEFAULTS = token;
|
|
26
|
+
/**
|
|
27
|
+
* Configures forty-cdk tabs defaults for this injector scope. Partial
|
|
28
|
+
* overrides inherit unspecified keys from the parent scope (or library
|
|
29
|
+
* defaults at the root).
|
|
30
|
+
*/
|
|
31
|
+
function provideForTabsDefaults(defaults = {}) {
|
|
32
|
+
return provideDefaults(defaults);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Root of the Tabs primitive. Owns the selected value, activation mode,
|
|
37
|
+
* orientation, and disabled state. Provides the shared context to descendant
|
|
38
|
+
* `ForTabsList` / `ForTabsTrigger` / `ForTabsContent` directives.
|
|
39
|
+
*
|
|
40
|
+
* Implements the [WAI-ARIA Tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/).
|
|
41
|
+
*
|
|
42
|
+
* `activationMode='automatic'` (default): arrow nav moves focus AND selects
|
|
43
|
+
* the new tab. Use when panel content is cheap to render.
|
|
44
|
+
* `activationMode='manual'`: arrow nav only moves focus; the user must press
|
|
45
|
+
* Space / Enter to activate. Use when panel content is expensive.
|
|
46
|
+
*/
|
|
47
|
+
class ForTabs {
|
|
48
|
+
#defaults = inject(FOR_TABS_DEFAULTS);
|
|
49
|
+
/**
|
|
50
|
+
* Two-way bindable. The selected tab's value, or `null` when nothing is
|
|
51
|
+
* selected. `null` is the canonical unset state — distinct from a tab whose
|
|
52
|
+
* `value` is the empty string `''`, which is a legal, selectable value. The
|
|
53
|
+
* `model()` change emitter (`(valueChange)`) fires only on internal
|
|
54
|
+
* selection changes (trigger click or automatic-mode arrow nav), never on
|
|
55
|
+
* consumer writes via `[(value)]` — observe transitions without binding back.
|
|
56
|
+
*/
|
|
57
|
+
value = model(null, /* @ts-ignore */
|
|
58
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
59
|
+
activationMode = input(this.#defaults.activationMode, /* @ts-ignore */
|
|
60
|
+
...(ngDevMode ? [{ debugName: "activationMode" }] : /* istanbul ignore next */ []));
|
|
61
|
+
orientation = input('horizontal', /* @ts-ignore */
|
|
62
|
+
...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
|
|
63
|
+
/**
|
|
64
|
+
* Writing direction. When unset (default `null`), the inherited ambient
|
|
65
|
+
* direction is resolved from the nearest ancestor carrying a `dir` attribute
|
|
66
|
+
* (or `<html dir>`), defaulting to `'ltr'`. An explicit `[dir]` always wins.
|
|
67
|
+
* The resolved value is reflected to the host `dir` attribute and swaps
|
|
68
|
+
* ArrowLeft / ArrowRight semantics in RTL.
|
|
69
|
+
*/
|
|
70
|
+
_dirInput = input(null, { ...(ngDevMode ? { debugName: "_dirInput" } : /* istanbul ignore next */ {}), alias: 'dir' });
|
|
71
|
+
dir = injectTextDirection(this._dirInput);
|
|
72
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
73
|
+
/**
|
|
74
|
+
* Whether arrow navigation wraps around past the first / last enabled
|
|
75
|
+
* trigger. Default `true` — matches the WAI-ARIA Tabs APG. Set to `false`
|
|
76
|
+
* for a non-wrapping tablist. The default is read from
|
|
77
|
+
* `provideForTabsDefaults` for the surrounding scope.
|
|
78
|
+
*/
|
|
79
|
+
loop = input(this.#defaults.loop, { ...(ngDevMode ? { debugName: "loop" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
80
|
+
roving = new RovingTabindex();
|
|
81
|
+
#triggers = new Collection();
|
|
82
|
+
#contents = new Collection();
|
|
83
|
+
#firstEnabledTriggerHost = computed(() => firstEnabledHost(this.#triggers.items()), /* @ts-ignore */
|
|
84
|
+
...(ngDevMode ? [{ debugName: "#firstEnabledTriggerHost" }] : /* istanbul ignore next */ []));
|
|
85
|
+
constructor() {
|
|
86
|
+
reconcileRovingActive(this.roving, this.#triggers.items);
|
|
87
|
+
}
|
|
88
|
+
isSelected(v) {
|
|
89
|
+
return this.value() === v;
|
|
90
|
+
}
|
|
91
|
+
select(v) {
|
|
92
|
+
if (this.disabled()) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
this.value.set(v);
|
|
96
|
+
}
|
|
97
|
+
navigate(currentTrigger, action) {
|
|
98
|
+
if (this.disabled()) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const triggers = this.#triggers.items();
|
|
102
|
+
if (triggers.length === 0) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const currentIndex = triggers.findIndex((t) => t.host === currentTrigger);
|
|
106
|
+
const next = moveIndex(currentIndex < 0 ? 0 : currentIndex, triggers.length, action, {
|
|
107
|
+
loop: this.loop(),
|
|
108
|
+
isDisabled: (i) => triggers[i].disabled(),
|
|
109
|
+
});
|
|
110
|
+
if (next === null) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const target = triggers[next];
|
|
114
|
+
if (!target) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
target.host.focus();
|
|
118
|
+
if (this.activationMode() === 'automatic') {
|
|
119
|
+
this.value.set(target.value());
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
registerTrigger(handle) {
|
|
123
|
+
this.#triggers.register(handle);
|
|
124
|
+
}
|
|
125
|
+
unregisterTrigger(handle) {
|
|
126
|
+
this.#triggers.unregister(handle);
|
|
127
|
+
this.roving.unregister(handle.host);
|
|
128
|
+
}
|
|
129
|
+
registerContent(handle) {
|
|
130
|
+
this.#contents.register(handle);
|
|
131
|
+
}
|
|
132
|
+
unregisterContent(handle) {
|
|
133
|
+
this.#contents.unregister(handle);
|
|
134
|
+
}
|
|
135
|
+
triggerIdFor(value) {
|
|
136
|
+
for (const t of this.#triggers.items()) {
|
|
137
|
+
if (t.value() === value) {
|
|
138
|
+
return t.id();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
contentIdFor(value) {
|
|
144
|
+
for (const c of this.#contents.items()) {
|
|
145
|
+
if (c.value() === value) {
|
|
146
|
+
return c.id();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
isFirstEnabledTrigger(el) {
|
|
152
|
+
return this.#firstEnabledTriggerHost() === el;
|
|
153
|
+
}
|
|
154
|
+
hasSelectedTrigger() {
|
|
155
|
+
const value = this.value();
|
|
156
|
+
if (value === null) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
return this.#triggers.items().some((t) => !t.disabled() && t.value() === value);
|
|
160
|
+
}
|
|
161
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForTabs, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
162
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: ForTabs, isStandalone: true, selector: "[forTabs]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, activationMode: { classPropertyName: "activationMode", publicName: "activationMode", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, _dirInput: { classPropertyName: "_dirInput", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { properties: { "attr.data-orientation": "orientation()", "attr.data-disabled": "disabled() ? \"\" : null", "attr.dir": "dir()" } }, providers: [{ provide: FOR_TABS_CONTEXT, useExisting: ForTabs }], exportAs: ["forTabs"], ngImport: i0 });
|
|
163
|
+
}
|
|
164
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForTabs, decorators: [{
|
|
165
|
+
type: Directive,
|
|
166
|
+
args: [{
|
|
167
|
+
selector: '[forTabs]',
|
|
168
|
+
exportAs: 'forTabs',
|
|
169
|
+
host: {
|
|
170
|
+
'[attr.data-orientation]': 'orientation()',
|
|
171
|
+
'[attr.data-disabled]': 'disabled() ? "" : null',
|
|
172
|
+
'[attr.dir]': 'dir()',
|
|
173
|
+
},
|
|
174
|
+
providers: [{ provide: FOR_TABS_CONTEXT, useExisting: ForTabs }],
|
|
175
|
+
}]
|
|
176
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], activationMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "activationMode", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], _dirInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loop: [{ type: i0.Input, args: [{ isSignal: true, alias: "loop", required: false }] }] } });
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The `role="tablist"` container — wraps the `ForTabsTrigger` elements (and
|
|
180
|
+
* only those — panels live as siblings of the list). Reflects the parent's
|
|
181
|
+
* orientation as `aria-orientation`.
|
|
182
|
+
*/
|
|
183
|
+
class ForTabsList {
|
|
184
|
+
group = injectTabsContext('ForTabsList');
|
|
185
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForTabsList, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
186
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: ForTabsList, isStandalone: true, selector: "[forTabsList]", host: { attributes: { "role": "tablist" }, properties: { "attr.aria-orientation": "group.orientation()", "attr.data-orientation": "group.orientation()" } }, exportAs: ["forTabsList"], ngImport: i0 });
|
|
187
|
+
}
|
|
188
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForTabsList, decorators: [{
|
|
189
|
+
type: Directive,
|
|
190
|
+
args: [{
|
|
191
|
+
selector: '[forTabsList]',
|
|
192
|
+
exportAs: 'forTabsList',
|
|
193
|
+
host: {
|
|
194
|
+
role: 'tablist',
|
|
195
|
+
'[attr.aria-orientation]': 'group.orientation()',
|
|
196
|
+
'[attr.data-orientation]': 'group.orientation()',
|
|
197
|
+
},
|
|
198
|
+
}]
|
|
199
|
+
}] });
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Header button for one tab. Apply on a `<button type="button">` so Enter /
|
|
203
|
+
* Space activation come from native button behavior.
|
|
204
|
+
*
|
|
205
|
+
* Tabindex follows APG: the user-focused trigger owns `tabindex=0` (tracked
|
|
206
|
+
* by `RovingTabindex`); before any interaction, the selected trigger (or
|
|
207
|
+
* first enabled, when nothing is selected) is the tab entry.
|
|
208
|
+
*
|
|
209
|
+
* `aria-controls` is emitted only while the tab is selected — mirroring the
|
|
210
|
+
* overlay triggers' open-only gating — so the reference never dangles at an
|
|
211
|
+
* unmounted panel under the `@if (selected())` mount pattern.
|
|
212
|
+
*/
|
|
213
|
+
class ForTabsTrigger {
|
|
214
|
+
group = injectTabsContext('ForTabsTrigger');
|
|
215
|
+
#host = inject(ElementRef);
|
|
216
|
+
value = input.required(/* @ts-ignore */
|
|
217
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
218
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
219
|
+
id = hostId('for-tabs-trigger');
|
|
220
|
+
selected = computed(() => this.group.isSelected(this.value()), /* @ts-ignore */
|
|
221
|
+
...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
|
|
222
|
+
effectiveDisabled = computed(() => this.disabled() || this.group.disabled(), /* @ts-ignore */
|
|
223
|
+
...(ngDevMode ? [{ debugName: "effectiveDisabled" }] : /* istanbul ignore next */ []));
|
|
224
|
+
controlsId = computed(() => this.group.contentIdFor(this.value()), /* @ts-ignore */
|
|
225
|
+
...(ngDevMode ? [{ debugName: "controlsId" }] : /* istanbul ignore next */ []));
|
|
226
|
+
/**
|
|
227
|
+
* APG tabindex: user-driven roving owns it once any trigger has been
|
|
228
|
+
* focused. Before that, fall back to "selected, else first enabled".
|
|
229
|
+
*/
|
|
230
|
+
tabindex = computed(() => {
|
|
231
|
+
if (this.effectiveDisabled()) {
|
|
232
|
+
return -1;
|
|
233
|
+
}
|
|
234
|
+
if (this.group.roving.hasActive()) {
|
|
235
|
+
return this.group.roving.tabindexFor(this.#host.nativeElement);
|
|
236
|
+
}
|
|
237
|
+
if (this.selected()) {
|
|
238
|
+
return 0;
|
|
239
|
+
}
|
|
240
|
+
if (this.group.hasSelectedTrigger()) {
|
|
241
|
+
return -1;
|
|
242
|
+
}
|
|
243
|
+
return this.group.isFirstEnabledTrigger(this.#host.nativeElement) ? 0 : -1;
|
|
244
|
+
}, /* @ts-ignore */
|
|
245
|
+
...(ngDevMode ? [{ debugName: "tabindex" }] : /* istanbul ignore next */ []));
|
|
246
|
+
constructor() {
|
|
247
|
+
const handle = {
|
|
248
|
+
host: this.#host.nativeElement,
|
|
249
|
+
id: this.id,
|
|
250
|
+
value: this.value,
|
|
251
|
+
disabled: this.effectiveDisabled,
|
|
252
|
+
};
|
|
253
|
+
// Defer registration so `input.required` is bound by the time the parent
|
|
254
|
+
// ever reads `handle.value()` from `triggerIdFor` / `contentIdFor` — both
|
|
255
|
+
// are evaluated during host-binding CD passes that can interleave with
|
|
256
|
+
// sibling triggers' input-binding step. Eager registration in the
|
|
257
|
+
// constructor used to hit the not-yet-bound throw, papered over by a
|
|
258
|
+
// `try/catch` in the parent. `afterNextRender` runs after every directive
|
|
259
|
+
// in the current pass has had its inputs bound, which makes the lookup
|
|
260
|
+
// deterministic. `unregisterTrigger` is reference-based, so it's a no-op
|
|
261
|
+
// when destroy fires before the deferred register did.
|
|
262
|
+
registerHandle(handle, (h) => this.group.registerTrigger(h), (h) => this.group.unregisterTrigger(h), 'afterNextRender');
|
|
263
|
+
}
|
|
264
|
+
onClick() {
|
|
265
|
+
if (this.effectiveDisabled()) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
this.group.select(this.value());
|
|
269
|
+
}
|
|
270
|
+
onFocus() {
|
|
271
|
+
if (this.effectiveDisabled()) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
this.group.roving.setActive(this.#host.nativeElement);
|
|
275
|
+
}
|
|
276
|
+
onKeyDown(event) {
|
|
277
|
+
if (this.effectiveDisabled()) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const action = resolveListNavigation(event, {
|
|
281
|
+
orientation: this.group.orientation(),
|
|
282
|
+
dir: this.group.dir(),
|
|
283
|
+
});
|
|
284
|
+
if (!action) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
event.preventDefault();
|
|
288
|
+
this.group.navigate(this.#host.nativeElement, action);
|
|
289
|
+
}
|
|
290
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForTabsTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
291
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: ForTabsTrigger, isStandalone: true, selector: "[forTabsTrigger]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "tab", "type": "button" }, listeners: { "click": "onClick()", "focus": "onFocus()", "keydown": "onKeyDown($event)" }, properties: { "id": "id()", "attr.aria-selected": "selected() ? \"true\" : \"false\"", "attr.aria-controls": "selected() ? controlsId() : null", "attr.aria-disabled": "effectiveDisabled() ? \"true\" : null", "attr.tabindex": "tabindex()", "attr.data-state": "selected() ? \"active\" : \"inactive\"", "attr.data-disabled": "effectiveDisabled() ? \"\" : null", "attr.data-orientation": "group.orientation()" } }, exportAs: ["forTabsTrigger"], ngImport: i0 });
|
|
292
|
+
}
|
|
293
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForTabsTrigger, decorators: [{
|
|
294
|
+
type: Directive,
|
|
295
|
+
args: [{
|
|
296
|
+
selector: '[forTabsTrigger]',
|
|
297
|
+
exportAs: 'forTabsTrigger',
|
|
298
|
+
host: {
|
|
299
|
+
role: 'tab',
|
|
300
|
+
type: 'button',
|
|
301
|
+
'[id]': 'id()',
|
|
302
|
+
'[attr.aria-selected]': 'selected() ? "true" : "false"',
|
|
303
|
+
'[attr.aria-controls]': 'selected() ? controlsId() : null',
|
|
304
|
+
'[attr.aria-disabled]': 'effectiveDisabled() ? "true" : null',
|
|
305
|
+
'[attr.tabindex]': 'tabindex()',
|
|
306
|
+
'[attr.data-state]': 'selected() ? "active" : "inactive"',
|
|
307
|
+
'[attr.data-disabled]': 'effectiveDisabled() ? "" : null',
|
|
308
|
+
'[attr.data-orientation]': 'group.orientation()',
|
|
309
|
+
'(click)': 'onClick()',
|
|
310
|
+
'(focus)': 'onFocus()',
|
|
311
|
+
'(keydown)': 'onKeyDown($event)',
|
|
312
|
+
},
|
|
313
|
+
}]
|
|
314
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Panel for one tab. The directive does not manage DOM presence — leave the
|
|
318
|
+
* panel mounted (idiomatic for tabs, preserves scroll/input state across
|
|
319
|
+
* activations) and either toggle visibility in CSS via
|
|
320
|
+
* `[data-state="inactive"]` or wrap with `@if (selected())` to unmount it.
|
|
321
|
+
* While inactive, the directive reflects `aria-hidden="true"` and `inert`
|
|
322
|
+
* so the mounted-but-inactive panel is removed from the accessibility tree
|
|
323
|
+
* and focus order automatically.
|
|
324
|
+
*
|
|
325
|
+
* APG: a `tabpanel` is a tab stop (`tabindex="0"`) **only** when it has no
|
|
326
|
+
* focusable content of its own — that lets screen-reader users reach an
|
|
327
|
+
* otherwise-unreachable panel, while a panel that already contains a form,
|
|
328
|
+
* links, or buttons does not add a redundant tab stop. The directive detects
|
|
329
|
+
* focusable descendants automatically (reactive to subtree changes); set
|
|
330
|
+
* `[interactiveContent]` to override the detection in either direction.
|
|
331
|
+
*/
|
|
332
|
+
class ForTabsContent {
|
|
333
|
+
group = injectTabsContext('ForTabsContent');
|
|
334
|
+
value = input.required(/* @ts-ignore */
|
|
335
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
336
|
+
/**
|
|
337
|
+
* Overrides the automatic focusable-content detection that drives the
|
|
338
|
+
* panel's `tabindex`. Leave unset (default `null`) to let the directive
|
|
339
|
+
* decide: a panel with no focusable descendants gets `tabindex="0"` so it
|
|
340
|
+
* is reachable by Tab, a panel with focusable descendants gets none. Set
|
|
341
|
+
* `true` when the panel always holds its own focusable content (skip the
|
|
342
|
+
* extra tab stop without paying for detection); set `false` to force the
|
|
343
|
+
* panel to be a tab stop regardless of its content.
|
|
344
|
+
*/
|
|
345
|
+
interactiveContent = input(null, { ...(ngDevMode ? { debugName: "interactiveContent" } : /* istanbul ignore next */ {}), transform: (value) => (value == null ? null : booleanAttribute(value)) });
|
|
346
|
+
id = hostId('for-tabs-content');
|
|
347
|
+
#hasFocusableContent = injectHasFocusableContent();
|
|
348
|
+
selected = computed(() => this.group.isSelected(this.value()), /* @ts-ignore */
|
|
349
|
+
...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
|
|
350
|
+
labelledBy = computed(() => this.group.triggerIdFor(this.value()), /* @ts-ignore */
|
|
351
|
+
...(ngDevMode ? [{ debugName: "labelledBy" }] : /* istanbul ignore next */ []));
|
|
352
|
+
/**
|
|
353
|
+
* APG tabindex: `0` only when the panel has no focusable content of its
|
|
354
|
+
* own, so SR users can focus the panel itself; otherwise no `tabindex`
|
|
355
|
+
* attribute, so the panel does not add a redundant tab stop. An explicit
|
|
356
|
+
* `interactiveContent` wins over the automatic detection.
|
|
357
|
+
*/
|
|
358
|
+
tabindex = computed(() => {
|
|
359
|
+
const override = this.interactiveContent();
|
|
360
|
+
const interactive = override ?? this.#hasFocusableContent();
|
|
361
|
+
return interactive ? null : '0';
|
|
362
|
+
}, /* @ts-ignore */
|
|
363
|
+
...(ngDevMode ? [{ debugName: "tabindex" }] : /* istanbul ignore next */ []));
|
|
364
|
+
constructor() {
|
|
365
|
+
const host = inject(ElementRef).nativeElement;
|
|
366
|
+
const handle = { host, id: this.id, value: this.value };
|
|
367
|
+
// Mirror of the registration ordering in `ForTabsTrigger`. Defer until
|
|
368
|
+
// input bindings have settled so the parent's `triggerIdFor` /
|
|
369
|
+
// `contentIdFor` can read `handle.value()` without the not-yet-bound
|
|
370
|
+
// throw. `unregisterContent` is reference-based and tolerant of being
|
|
371
|
+
// called before the deferred register.
|
|
372
|
+
registerHandle(handle, (h) => this.group.registerContent(h), (h) => this.group.unregisterContent(h), 'afterNextRender');
|
|
373
|
+
}
|
|
374
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForTabsContent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
375
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: ForTabsContent, isStandalone: true, selector: "[forTabsContent]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, interactiveContent: { classPropertyName: "interactiveContent", publicName: "interactiveContent", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "tabpanel" }, properties: { "attr.tabindex": "tabindex()", "id": "id()", "attr.aria-labelledby": "labelledBy()", "attr.aria-hidden": "selected() ? null : \"true\"", "attr.inert": "selected() ? null : \"\"", "attr.data-state": "selected() ? \"active\" : \"inactive\"", "attr.data-orientation": "group.orientation()" } }, exportAs: ["forTabsContent"], ngImport: i0 });
|
|
376
|
+
}
|
|
377
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForTabsContent, decorators: [{
|
|
378
|
+
type: Directive,
|
|
379
|
+
args: [{
|
|
380
|
+
selector: '[forTabsContent]',
|
|
381
|
+
exportAs: 'forTabsContent',
|
|
382
|
+
host: {
|
|
383
|
+
role: 'tabpanel',
|
|
384
|
+
'[attr.tabindex]': 'tabindex()',
|
|
385
|
+
'[id]': 'id()',
|
|
386
|
+
'[attr.aria-labelledby]': 'labelledBy()',
|
|
387
|
+
'[attr.aria-hidden]': 'selected() ? null : "true"',
|
|
388
|
+
'[attr.inert]': 'selected() ? null : ""',
|
|
389
|
+
'[attr.data-state]': 'selected() ? "active" : "inactive"',
|
|
390
|
+
'[attr.data-orientation]': 'group.orientation()',
|
|
391
|
+
},
|
|
392
|
+
}]
|
|
393
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], interactiveContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactiveContent", required: false }] }] } });
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Generated bundle index. Do not edit.
|
|
397
|
+
*/
|
|
398
|
+
|
|
399
|
+
export { FOR_TABS_CONTEXT, FOR_TABS_DEFAULTS, ForTabs, ForTabsContent, ForTabsList, ForTabsTrigger, provideForTabsDefaults };
|
|
400
|
+
//# sourceMappingURL=forty-cdk-tabs.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forty-cdk-tabs.mjs","sources":["../../../projects/forty-cdk/tabs/src/tabs-context.ts","../../../projects/forty-cdk/tabs/src/tabs-defaults.ts","../../../projects/forty-cdk/tabs/src/tabs.ts","../../../projects/forty-cdk/tabs/src/tabs-list.ts","../../../projects/forty-cdk/tabs/src/tabs-trigger.ts","../../../projects/forty-cdk/tabs/src/tabs-content.ts","../../../projects/forty-cdk/tabs/src/forty-cdk-tabs.ts"],"sourcesContent":["import { inject, InjectionToken, type Signal } from '@angular/core';\n\nimport {\n type ListNavigationAction,\n type WritingDirection,\n type RovingTabindex,\n} from 'forty-cdk/core';\n\nexport type TabsActivationMode = 'automatic' | 'manual';\n\nexport interface ForTabsTriggerHandle {\n readonly host: HTMLElement;\n readonly id: Signal<string>;\n readonly value: Signal<string>;\n readonly disabled: Signal<boolean>;\n}\n\nexport interface ForTabsContentHandle {\n readonly host: HTMLElement;\n readonly id: Signal<string>;\n readonly value: Signal<string>;\n}\n\n/**\n * Coordination contract owned by `ForTabs`. Triggers and contents register\n * with the root so each side can look up its pair (for `aria-controls` and\n * `aria-labelledby` wiring), and the root drives keyboard navigation.\n */\nexport interface ForTabsContext {\n readonly value: Signal<string | null>;\n readonly disabled: Signal<boolean>;\n readonly orientation: Signal<'horizontal' | 'vertical'>;\n readonly dir: Signal<WritingDirection>;\n readonly activationMode: Signal<TabsActivationMode>;\n readonly roving: RovingTabindex;\n\n isSelected(value: string): boolean;\n /** Selects `value` if the tabs widget is interactive. */\n select(value: string): void;\n /** Moves focus from `currentTrigger`. In automatic mode also selects the new tab. */\n navigate(currentTrigger: HTMLElement, action: ListNavigationAction): void;\n\n registerTrigger(handle: ForTabsTriggerHandle): void;\n unregisterTrigger(handle: ForTabsTriggerHandle): void;\n registerContent(handle: ForTabsContentHandle): void;\n unregisterContent(handle: ForTabsContentHandle): void;\n\n /** Looks up the trigger id for a given tab value. Reactive. */\n triggerIdFor(value: string): string | null;\n /** Looks up the content id for a given tab value. Reactive. */\n contentIdFor(value: string): string | null;\n /** True when `el` is the first enabled trigger in registration order. */\n isFirstEnabledTrigger(el: HTMLElement): boolean;\n /**\n * True when some registered, enabled trigger matches the current `value`.\n * Distinguishes \"another trigger owns the tab stop\" from \"the selected\n * value points at a removed / disabled trigger\" so the per-trigger\n * tabindex fallback can re-engage the first-enabled entry point instead of\n * stranding the tablist. Reactive.\n */\n hasSelectedTrigger(): boolean;\n}\n\nexport const FOR_TABS_CONTEXT = new InjectionToken<ForTabsContext>('FOR_TABS_CONTEXT');\n\nexport function injectTabsContext(piece: string): ForTabsContext {\n const ctx = inject(FOR_TABS_CONTEXT, { optional: true });\n if (!ctx) {\n throw new Error(`[forty-cdk/tabs] ${piece} must be used inside a [forTabs] element.`);\n }\n return ctx;\n}\n","import { type Provider } from '@angular/core';\n\nimport { createDefaults } from 'forty-cdk/core';\nimport { type TabsActivationMode } from './tabs-context';\n\n/**\n * Defaults inherited by descendant tabs in the surrounding injector scope.\n * Configure with `provideForTabsDefaults` either at the application root\n * or in any component's `providers` array; partial overrides merge with\n * the parent scope.\n */\nexport interface ForTabsDefaults {\n /**\n * `'automatic'` (default): arrow navigation moves focus AND selects the\n * new tab. Use when panel content is cheap to render. `'manual'`: arrow\n * navigation only moves focus; the user must press Space / Enter to\n * activate. Use when panel content is expensive.\n */\n activationMode: TabsActivationMode;\n /**\n * Whether arrow navigation wraps around past the first / last enabled\n * trigger. Matches the WAI-ARIA Tabs APG default.\n */\n loop: boolean;\n}\n\n/**\n * Library fallback for tabs defaults, read at the root injector when no\n * consumer has called `provideForTabsDefaults`. Exported for the shared\n * defaults contract spec; not re-exported from the primitive's public entry.\n */\nexport const FOR_TABS_FALLBACK_DEFAULTS: ForTabsDefaults = {\n activationMode: 'automatic',\n loop: true,\n};\n\nconst { token, provideDefaults } = createDefaults<ForTabsDefaults>(\n 'FOR_TABS_DEFAULTS',\n FOR_TABS_FALLBACK_DEFAULTS,\n);\n\n/** Token holding the resolved tabs defaults for the current scope. */\nexport const FOR_TABS_DEFAULTS = token;\n\n/**\n * Configures forty-cdk tabs defaults for this injector scope. Partial\n * overrides inherit unspecified keys from the parent scope (or library\n * defaults at the root).\n */\nexport function provideForTabsDefaults(defaults: Partial<ForTabsDefaults> = {}): Provider[] {\n return provideDefaults(defaults);\n}\n","import { booleanAttribute, computed, Directive, inject, input, model } from '@angular/core';\n\nimport {\n Collection,\n firstEnabledHost,\n type ListNavigationAction,\n moveIndex,\n type WritingDirection,\n reconcileRovingActive,\n RovingTabindex,\n injectTextDirection,\n} from 'forty-cdk/core';\nimport {\n FOR_TABS_CONTEXT,\n type ForTabsContentHandle,\n type ForTabsContext,\n type ForTabsTriggerHandle,\n type TabsActivationMode,\n} from './tabs-context';\nimport { FOR_TABS_DEFAULTS } from './tabs-defaults';\n\n/**\n * Root of the Tabs primitive. Owns the selected value, activation mode,\n * orientation, and disabled state. Provides the shared context to descendant\n * `ForTabsList` / `ForTabsTrigger` / `ForTabsContent` directives.\n *\n * Implements the [WAI-ARIA Tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/).\n *\n * `activationMode='automatic'` (default): arrow nav moves focus AND selects\n * the new tab. Use when panel content is cheap to render.\n * `activationMode='manual'`: arrow nav only moves focus; the user must press\n * Space / Enter to activate. Use when panel content is expensive.\n */\n@Directive({\n selector: '[forTabs]',\n exportAs: 'forTabs',\n host: {\n '[attr.data-orientation]': 'orientation()',\n '[attr.data-disabled]': 'disabled() ? \"\" : null',\n '[attr.dir]': 'dir()',\n },\n providers: [{ provide: FOR_TABS_CONTEXT, useExisting: ForTabs }],\n})\nexport class ForTabs implements ForTabsContext {\n readonly #defaults = inject(FOR_TABS_DEFAULTS);\n\n /**\n * Two-way bindable. The selected tab's value, or `null` when nothing is\n * selected. `null` is the canonical unset state — distinct from a tab whose\n * `value` is the empty string `''`, which is a legal, selectable value. The\n * `model()` change emitter (`(valueChange)`) fires only on internal\n * selection changes (trigger click or automatic-mode arrow nav), never on\n * consumer writes via `[(value)]` — observe transitions without binding back.\n */\n readonly value = model<string | null>(null);\n\n readonly activationMode = input<TabsActivationMode>(this.#defaults.activationMode);\n readonly orientation = input<'horizontal' | 'vertical'>('horizontal');\n\n /**\n * Writing direction. When unset (default `null`), the inherited ambient\n * direction is resolved from the nearest ancestor carrying a `dir` attribute\n * (or `<html dir>`), defaulting to `'ltr'`. An explicit `[dir]` always wins.\n * The resolved value is reflected to the host `dir` attribute and swaps\n * ArrowLeft / ArrowRight semantics in RTL.\n */\n readonly _dirInput = input<WritingDirection | null>(null, { alias: 'dir' });\n readonly dir = injectTextDirection(this._dirInput);\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /**\n * Whether arrow navigation wraps around past the first / last enabled\n * trigger. Default `true` — matches the WAI-ARIA Tabs APG. Set to `false`\n * for a non-wrapping tablist. The default is read from\n * `provideForTabsDefaults` for the surrounding scope.\n */\n readonly loop = input(this.#defaults.loop, { transform: booleanAttribute });\n\n readonly roving = new RovingTabindex();\n\n readonly #triggers = new Collection<ForTabsTriggerHandle>();\n readonly #contents = new Collection<ForTabsContentHandle>();\n\n readonly #firstEnabledTriggerHost = computed(() => firstEnabledHost(this.#triggers.items()));\n\n constructor() {\n reconcileRovingActive(this.roving, this.#triggers.items);\n }\n\n isSelected(v: string): boolean {\n return this.value() === v;\n }\n\n select(v: string): void {\n if (this.disabled()) {\n return;\n }\n this.value.set(v);\n }\n\n navigate(currentTrigger: HTMLElement, action: ListNavigationAction): void {\n if (this.disabled()) {\n return;\n }\n const triggers = this.#triggers.items();\n if (triggers.length === 0) {\n return;\n }\n const currentIndex = triggers.findIndex((t) => t.host === currentTrigger);\n const next = moveIndex(currentIndex < 0 ? 0 : currentIndex, triggers.length, action, {\n loop: this.loop(),\n isDisabled: (i) => triggers[i]!.disabled(),\n });\n if (next === null) {\n return;\n }\n const target = triggers[next];\n if (!target) {\n return;\n }\n target.host.focus();\n if (this.activationMode() === 'automatic') {\n this.value.set(target.value());\n }\n }\n\n registerTrigger(handle: ForTabsTriggerHandle): void {\n this.#triggers.register(handle);\n }\n\n unregisterTrigger(handle: ForTabsTriggerHandle): void {\n this.#triggers.unregister(handle);\n this.roving.unregister(handle.host);\n }\n\n registerContent(handle: ForTabsContentHandle): void {\n this.#contents.register(handle);\n }\n\n unregisterContent(handle: ForTabsContentHandle): void {\n this.#contents.unregister(handle);\n }\n\n triggerIdFor(value: string): string | null {\n for (const t of this.#triggers.items()) {\n if (t.value() === value) {\n return t.id();\n }\n }\n return null;\n }\n\n contentIdFor(value: string): string | null {\n for (const c of this.#contents.items()) {\n if (c.value() === value) {\n return c.id();\n }\n }\n return null;\n }\n\n isFirstEnabledTrigger(el: HTMLElement): boolean {\n return this.#firstEnabledTriggerHost() === el;\n }\n\n hasSelectedTrigger(): boolean {\n const value = this.value();\n if (value === null) {\n return false;\n }\n return this.#triggers.items().some((t) => !t.disabled() && t.value() === value);\n }\n}\n","import { Directive } from '@angular/core';\n\nimport { injectTabsContext } from './tabs-context';\n\n/**\n * The `role=\"tablist\"` container — wraps the `ForTabsTrigger` elements (and\n * only those — panels live as siblings of the list). Reflects the parent's\n * orientation as `aria-orientation`.\n */\n@Directive({\n selector: '[forTabsList]',\n exportAs: 'forTabsList',\n host: {\n role: 'tablist',\n '[attr.aria-orientation]': 'group.orientation()',\n '[attr.data-orientation]': 'group.orientation()',\n },\n})\nexport class ForTabsList {\n protected readonly group = injectTabsContext('ForTabsList');\n}\n","import { booleanAttribute, computed, Directive, ElementRef, inject, input } from '@angular/core';\n\nimport { registerHandle, hostId, resolveListNavigation } from 'forty-cdk/core';\nimport { injectTabsContext } from './tabs-context';\n\n/**\n * Header button for one tab. Apply on a `<button type=\"button\">` so Enter /\n * Space activation come from native button behavior.\n *\n * Tabindex follows APG: the user-focused trigger owns `tabindex=0` (tracked\n * by `RovingTabindex`); before any interaction, the selected trigger (or\n * first enabled, when nothing is selected) is the tab entry.\n *\n * `aria-controls` is emitted only while the tab is selected — mirroring the\n * overlay triggers' open-only gating — so the reference never dangles at an\n * unmounted panel under the `@if (selected())` mount pattern.\n */\n@Directive({\n selector: '[forTabsTrigger]',\n exportAs: 'forTabsTrigger',\n host: {\n role: 'tab',\n type: 'button',\n '[id]': 'id()',\n '[attr.aria-selected]': 'selected() ? \"true\" : \"false\"',\n '[attr.aria-controls]': 'selected() ? controlsId() : null',\n '[attr.aria-disabled]': 'effectiveDisabled() ? \"true\" : null',\n '[attr.tabindex]': 'tabindex()',\n '[attr.data-state]': 'selected() ? \"active\" : \"inactive\"',\n '[attr.data-disabled]': 'effectiveDisabled() ? \"\" : null',\n '[attr.data-orientation]': 'group.orientation()',\n '(click)': 'onClick()',\n '(focus)': 'onFocus()',\n '(keydown)': 'onKeyDown($event)',\n },\n})\nexport class ForTabsTrigger {\n protected readonly group = injectTabsContext('ForTabsTrigger');\n readonly #host = inject<ElementRef<HTMLElement>>(ElementRef);\n\n readonly value = input.required<string>();\n readonly disabled = input(false, { transform: booleanAttribute });\n\n readonly id = hostId('for-tabs-trigger');\n\n readonly selected = computed(() => this.group.isSelected(this.value()));\n readonly effectiveDisabled = computed(() => this.disabled() || this.group.disabled());\n\n protected readonly controlsId = computed(() => this.group.contentIdFor(this.value()));\n\n /**\n * APG tabindex: user-driven roving owns it once any trigger has been\n * focused. Before that, fall back to \"selected, else first enabled\".\n */\n protected readonly tabindex = computed<-1 | 0>(() => {\n if (this.effectiveDisabled()) {\n return -1;\n }\n if (this.group.roving.hasActive()) {\n return this.group.roving.tabindexFor(this.#host.nativeElement);\n }\n if (this.selected()) {\n return 0;\n }\n if (this.group.hasSelectedTrigger()) {\n return -1;\n }\n return this.group.isFirstEnabledTrigger(this.#host.nativeElement) ? 0 : -1;\n });\n\n constructor() {\n const handle = {\n host: this.#host.nativeElement,\n id: this.id,\n value: this.value,\n disabled: this.effectiveDisabled,\n };\n // Defer registration so `input.required` is bound by the time the parent\n // ever reads `handle.value()` from `triggerIdFor` / `contentIdFor` — both\n // are evaluated during host-binding CD passes that can interleave with\n // sibling triggers' input-binding step. Eager registration in the\n // constructor used to hit the not-yet-bound throw, papered over by a\n // `try/catch` in the parent. `afterNextRender` runs after every directive\n // in the current pass has had its inputs bound, which makes the lookup\n // deterministic. `unregisterTrigger` is reference-based, so it's a no-op\n // when destroy fires before the deferred register did.\n registerHandle(\n handle,\n (h) => this.group.registerTrigger(h),\n (h) => this.group.unregisterTrigger(h),\n 'afterNextRender',\n );\n }\n\n protected onClick(): void {\n if (this.effectiveDisabled()) {\n return;\n }\n this.group.select(this.value());\n }\n\n protected onFocus(): void {\n if (this.effectiveDisabled()) {\n return;\n }\n this.group.roving.setActive(this.#host.nativeElement);\n }\n\n protected onKeyDown(event: KeyboardEvent): void {\n if (this.effectiveDisabled()) {\n return;\n }\n const action = resolveListNavigation(event, {\n orientation: this.group.orientation(),\n dir: this.group.dir(),\n });\n if (!action) {\n return;\n }\n event.preventDefault();\n this.group.navigate(this.#host.nativeElement, action);\n }\n}\n","import { booleanAttribute, computed, Directive, ElementRef, inject, input } from '@angular/core';\n\nimport { registerHandle, injectHasFocusableContent, hostId } from 'forty-cdk/core';\nimport { injectTabsContext } from './tabs-context';\n\n/**\n * Panel for one tab. The directive does not manage DOM presence — leave the\n * panel mounted (idiomatic for tabs, preserves scroll/input state across\n * activations) and either toggle visibility in CSS via\n * `[data-state=\"inactive\"]` or wrap with `@if (selected())` to unmount it.\n * While inactive, the directive reflects `aria-hidden=\"true\"` and `inert`\n * so the mounted-but-inactive panel is removed from the accessibility tree\n * and focus order automatically.\n *\n * APG: a `tabpanel` is a tab stop (`tabindex=\"0\"`) **only** when it has no\n * focusable content of its own — that lets screen-reader users reach an\n * otherwise-unreachable panel, while a panel that already contains a form,\n * links, or buttons does not add a redundant tab stop. The directive detects\n * focusable descendants automatically (reactive to subtree changes); set\n * `[interactiveContent]` to override the detection in either direction.\n */\n@Directive({\n selector: '[forTabsContent]',\n exportAs: 'forTabsContent',\n host: {\n role: 'tabpanel',\n '[attr.tabindex]': 'tabindex()',\n '[id]': 'id()',\n '[attr.aria-labelledby]': 'labelledBy()',\n '[attr.aria-hidden]': 'selected() ? null : \"true\"',\n '[attr.inert]': 'selected() ? null : \"\"',\n '[attr.data-state]': 'selected() ? \"active\" : \"inactive\"',\n '[attr.data-orientation]': 'group.orientation()',\n },\n})\nexport class ForTabsContent {\n protected readonly group = injectTabsContext('ForTabsContent');\n\n readonly value = input.required<string>();\n\n /**\n * Overrides the automatic focusable-content detection that drives the\n * panel's `tabindex`. Leave unset (default `null`) to let the directive\n * decide: a panel with no focusable descendants gets `tabindex=\"0\"` so it\n * is reachable by Tab, a panel with focusable descendants gets none. Set\n * `true` when the panel always holds its own focusable content (skip the\n * extra tab stop without paying for detection); set `false` to force the\n * panel to be a tab stop regardless of its content.\n */\n readonly interactiveContent = input<boolean | null, unknown>(null, {\n transform: (value: unknown) => (value == null ? null : booleanAttribute(value)),\n });\n\n readonly id = hostId('for-tabs-content');\n\n readonly #hasFocusableContent = injectHasFocusableContent();\n\n readonly selected = computed(() => this.group.isSelected(this.value()));\n protected readonly labelledBy = computed(() => this.group.triggerIdFor(this.value()));\n\n /**\n * APG tabindex: `0` only when the panel has no focusable content of its\n * own, so SR users can focus the panel itself; otherwise no `tabindex`\n * attribute, so the panel does not add a redundant tab stop. An explicit\n * `interactiveContent` wins over the automatic detection.\n */\n protected readonly tabindex = computed<'0' | null>(() => {\n const override = this.interactiveContent();\n const interactive = override ?? this.#hasFocusableContent();\n return interactive ? null : '0';\n });\n\n constructor() {\n const host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n const handle = { host, id: this.id, value: this.value };\n // Mirror of the registration ordering in `ForTabsTrigger`. Defer until\n // input bindings have settled so the parent's `triggerIdFor` /\n // `contentIdFor` can read `handle.value()` without the not-yet-bound\n // throw. `unregisterContent` is reference-based and tolerant of being\n // called before the deferred register.\n registerHandle(\n handle,\n (h) => this.group.registerContent(h),\n (h) => this.group.unregisterContent(h),\n 'afterNextRender',\n );\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|