@cdevhub/ngx-tw 0.5.0 → 0.6.1
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 +78 -15
- package/fesm2022/cdevhub-ngx-tw-accordion.mjs +16 -5
- package/fesm2022/cdevhub-ngx-tw-accordion.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-avatar.mjs +26 -15
- package/fesm2022/cdevhub-ngx-tw-avatar.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-badge.mjs +17 -5
- package/fesm2022/cdevhub-ngx-tw-badge.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs +27 -6
- package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-button.mjs +23 -11
- package/fesm2022/cdevhub-ngx-tw-button.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs +5 -5
- package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs +3 -3
- package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-calendar.mjs +427 -122
- package/fesm2022/cdevhub-ngx-tw-calendar.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-card.mjs +21 -11
- package/fesm2022/cdevhub-ngx-tw-card.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-carousel.mjs +215 -96
- package/fesm2022/cdevhub-ngx-tw-carousel.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-checkbox.mjs +108 -64
- package/fesm2022/cdevhub-ngx-tw-checkbox.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-code-block.mjs +18 -6
- package/fesm2022/cdevhub-ngx-tw-code-block.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-collapsible.mjs +55 -30
- package/fesm2022/cdevhub-ngx-tw-collapsible.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-combobox-testing.mjs +218 -0
- package/fesm2022/cdevhub-ngx-tw-combobox-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-combobox.mjs +236 -211
- package/fesm2022/cdevhub-ngx-tw-combobox.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-command-palette-testing.mjs +200 -0
- package/fesm2022/cdevhub-ngx-tw-command-palette-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-command-palette.mjs +34 -7
- package/fesm2022/cdevhub-ngx-tw-command-palette.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-core.mjs +135 -15
- package/fesm2022/cdevhub-ngx-tw-core.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-date-picker-testing.mjs +203 -0
- package/fesm2022/cdevhub-ngx-tw-date-picker-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-date-picker.mjs +160 -102
- package/fesm2022/cdevhub-ngx-tw-date-picker.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-date-range-picker-testing.mjs +209 -0
- package/fesm2022/cdevhub-ngx-tw-date-range-picker-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs +182 -107
- package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-dialog-testing.mjs +122 -0
- package/fesm2022/cdevhub-ngx-tw-dialog-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-dialog.mjs +11 -2
- package/fesm2022/cdevhub-ngx-tw-dialog.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-empty-state.mjs +1 -1
- package/fesm2022/cdevhub-ngx-tw-empty-state.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-file-upload-testing.mjs +149 -0
- package/fesm2022/cdevhub-ngx-tw-file-upload-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-file-upload.mjs +57 -67
- package/fesm2022/cdevhub-ngx-tw-file-upload.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-flip-card.mjs +42 -24
- package/fesm2022/cdevhub-ngx-tw-flip-card.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-form-field.mjs +114 -21
- package/fesm2022/cdevhub-ngx-tw-form-field.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-icon.mjs +16 -6
- package/fesm2022/cdevhub-ngx-tw-icon.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-input.mjs +52 -61
- package/fesm2022/cdevhub-ngx-tw-input.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-item.mjs +28 -4
- package/fesm2022/cdevhub-ngx-tw-item.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-menu-testing.mjs +168 -0
- package/fesm2022/cdevhub-ngx-tw-menu-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-menu.mjs +58 -21
- package/fesm2022/cdevhub-ngx-tw-menu.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-number-input.mjs +34 -1
- package/fesm2022/cdevhub-ngx-tw-number-input.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-paginator.mjs +95 -45
- package/fesm2022/cdevhub-ngx-tw-paginator.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-popover.mjs +81 -32
- package/fesm2022/cdevhub-ngx-tw-popover.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs +1 -1
- package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-radio.mjs +131 -98
- package/fesm2022/cdevhub-ngx-tw-radio.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs +207 -42
- package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-select-testing.mjs +165 -0
- package/fesm2022/cdevhub-ngx-tw-select-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-select.mjs +386 -210
- package/fesm2022/cdevhub-ngx-tw-select.mjs.map +1 -1
- package/fesm2022/{cdevhub-ngx-tw-sheet-sheet-renderer-ByyNluUd.mjs → cdevhub-ngx-tw-sheet-sheet-renderer-CqVJwgmp.mjs} +3 -3
- package/fesm2022/cdevhub-ngx-tw-sheet-sheet-renderer-CqVJwgmp.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-sheet-testing.mjs +129 -0
- package/fesm2022/cdevhub-ngx-tw-sheet-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-sheet.mjs +23 -7
- package/fesm2022/cdevhub-ngx-tw-sheet.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-slider.mjs +89 -54
- package/fesm2022/cdevhub-ngx-tw-slider.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-sort.mjs +122 -17
- package/fesm2022/cdevhub-ngx-tw-sort.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-split.mjs +72 -19
- package/fesm2022/cdevhub-ngx-tw-split.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-stat.mjs +63 -25
- package/fesm2022/cdevhub-ngx-tw-stat.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-stepper.mjs +35 -8
- package/fesm2022/cdevhub-ngx-tw-stepper.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-switch.mjs +54 -48
- package/fesm2022/cdevhub-ngx-tw-switch.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs +12 -15
- package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-table.mjs +74 -13
- package/fesm2022/cdevhub-ngx-tw-table.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-tabs.mjs +84 -30
- package/fesm2022/cdevhub-ngx-tw-tabs.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-tags-input-testing.mjs +172 -0
- package/fesm2022/cdevhub-ngx-tw-tags-input-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-tags-input.mjs +107 -71
- package/fesm2022/cdevhub-ngx-tw-tags-input.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-textarea.mjs +41 -9
- package/fesm2022/cdevhub-ngx-tw-textarea.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-theme.mjs +257 -45
- package/fesm2022/cdevhub-ngx-tw-theme.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-time-picker-testing.mjs +201 -0
- package/fesm2022/cdevhub-ngx-tw-time-picker-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-time-picker.mjs +184 -77
- package/fesm2022/cdevhub-ngx-tw-time-picker.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-timeline.mjs +110 -27
- package/fesm2022/cdevhub-ngx-tw-timeline.mjs.map +1 -1
- package/fesm2022/{cdevhub-ngx-tw-toast-toast-renderer-DSu4YoTy.mjs → cdevhub-ngx-tw-toast-toast-renderer-BlDxemsU.mjs} +107 -19
- package/fesm2022/cdevhub-ngx-tw-toast-toast-renderer-BlDxemsU.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-toast.mjs +21 -13
- package/fesm2022/cdevhub-ngx-tw-toast.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-tooltip.mjs +102 -15
- package/fesm2022/cdevhub-ngx-tw-tooltip.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-transfer-testing.mjs +219 -0
- package/fesm2022/cdevhub-ngx-tw-transfer-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-transfer.mjs +88 -69
- package/fesm2022/cdevhub-ngx-tw-transfer.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-tree.mjs +68 -19
- package/fesm2022/cdevhub-ngx-tw-tree.mjs.map +1 -1
- package/index.json +1 -1
- package/package.json +63 -2
- package/theme/_base.css +13 -0
- package/theme/_dark.css +111 -36
- package/theme/_high-contrast-dark.css +367 -0
- package/theme/_high-contrast.css +13 -2
- package/theme/_light.css +332 -0
- package/theme/_semantic.css +60 -26
- package/theme/_typography.css +17 -0
- package/theme/index.css +86 -7
- package/types/cdevhub-ngx-tw-accordion.d.ts +12 -4
- package/types/cdevhub-ngx-tw-avatar.d.ts +10 -3
- package/types/cdevhub-ngx-tw-button.d.ts +1 -0
- package/types/cdevhub-ngx-tw-calendar-luxon.d.ts +2 -2
- package/types/cdevhub-ngx-tw-calendar-testing.d.ts +1 -1
- package/types/cdevhub-ngx-tw-calendar.d.ts +179 -73
- package/types/cdevhub-ngx-tw-card.d.ts +11 -3
- package/types/cdevhub-ngx-tw-carousel.d.ts +89 -20
- package/types/cdevhub-ngx-tw-checkbox.d.ts +40 -12
- package/types/cdevhub-ngx-tw-code-block.d.ts +11 -2
- package/types/cdevhub-ngx-tw-collapsible.d.ts +32 -5
- package/types/cdevhub-ngx-tw-combobox-testing.d.ts +157 -0
- package/types/cdevhub-ngx-tw-combobox.d.ts +94 -53
- package/types/cdevhub-ngx-tw-command-palette-testing.d.ts +136 -0
- package/types/cdevhub-ngx-tw-command-palette.d.ts +33 -5
- package/types/cdevhub-ngx-tw-core.d.ts +152 -21
- package/types/cdevhub-ngx-tw-date-picker-testing.d.ts +141 -0
- package/types/cdevhub-ngx-tw-date-picker.d.ts +37 -29
- package/types/cdevhub-ngx-tw-date-range-picker-testing.d.ts +148 -0
- package/types/cdevhub-ngx-tw-date-range-picker.d.ts +36 -29
- package/types/cdevhub-ngx-tw-dialog-testing.d.ts +98 -0
- package/types/cdevhub-ngx-tw-dialog.d.ts +12 -3
- package/types/cdevhub-ngx-tw-file-upload-testing.d.ts +120 -0
- package/types/cdevhub-ngx-tw-file-upload.d.ts +8 -10
- package/types/cdevhub-ngx-tw-flip-card.d.ts +18 -11
- package/types/cdevhub-ngx-tw-form-field.d.ts +19 -2
- package/types/cdevhub-ngx-tw-icon.d.ts +3 -3
- package/types/cdevhub-ngx-tw-input.d.ts +5 -8
- package/types/cdevhub-ngx-tw-item.d.ts +2 -0
- package/types/cdevhub-ngx-tw-menu-testing.d.ts +131 -0
- package/types/cdevhub-ngx-tw-menu.d.ts +2 -2
- package/types/cdevhub-ngx-tw-number-input.d.ts +20 -0
- package/types/cdevhub-ngx-tw-paginator.d.ts +58 -24
- package/types/cdevhub-ngx-tw-popover.d.ts +41 -10
- package/types/cdevhub-ngx-tw-progress-bar.d.ts +1 -1
- package/types/cdevhub-ngx-tw-radio.d.ts +68 -25
- package/types/cdevhub-ngx-tw-segmented-control.d.ts +79 -16
- package/types/cdevhub-ngx-tw-select-testing.d.ts +114 -0
- package/types/cdevhub-ngx-tw-select.d.ts +104 -33
- package/types/cdevhub-ngx-tw-sheet-testing.d.ts +104 -0
- package/types/cdevhub-ngx-tw-sheet.d.ts +19 -3
- package/types/cdevhub-ngx-tw-slider.d.ts +79 -25
- package/types/cdevhub-ngx-tw-sort.d.ts +45 -4
- package/types/cdevhub-ngx-tw-split.d.ts +32 -2
- package/types/cdevhub-ngx-tw-stat.d.ts +14 -4
- package/types/cdevhub-ngx-tw-stepper.d.ts +16 -2
- package/types/cdevhub-ngx-tw-switch.d.ts +35 -13
- package/types/cdevhub-ngx-tw-tab-nav.d.ts +7 -6
- package/types/cdevhub-ngx-tw-table.d.ts +53 -10
- package/types/cdevhub-ngx-tw-tabs.d.ts +41 -10
- package/types/cdevhub-ngx-tw-tags-input-testing.d.ts +135 -0
- package/types/cdevhub-ngx-tw-tags-input.d.ts +26 -11
- package/types/cdevhub-ngx-tw-textarea.d.ts +3 -2
- package/types/cdevhub-ngx-tw-theme.d.ts +245 -39
- package/types/cdevhub-ngx-tw-time-picker-testing.d.ts +129 -0
- package/types/cdevhub-ngx-tw-time-picker.d.ts +76 -19
- package/types/cdevhub-ngx-tw-timeline.d.ts +36 -12
- package/types/cdevhub-ngx-tw-toast.d.ts +20 -6
- package/types/cdevhub-ngx-tw-tooltip.d.ts +28 -6
- package/types/cdevhub-ngx-tw-transfer-testing.d.ts +152 -0
- package/types/cdevhub-ngx-tw-transfer.d.ts +21 -8
- package/types/cdevhub-ngx-tw-tree.d.ts +6 -1
- package/fesm2022/cdevhub-ngx-tw-sheet-sheet-renderer-ByyNluUd.mjs.map +0 -1
- package/fesm2022/cdevhub-ngx-tw-toast-toast-renderer-DSu4YoTy.mjs.map +0 -1
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { input, model, output, inject, ElementRef, DestroyRef, signal, afterNextRender, isDevMode, computed, linkedSignal, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
-
import {
|
|
3
|
+
import { Validators, NgControl } from '@angular/forms';
|
|
4
4
|
import { FocusMonitor } from '@angular/cdk/a11y';
|
|
5
|
-
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
6
|
-
import { merge } from 'rxjs';
|
|
7
5
|
import { tv } from 'tailwind-variants';
|
|
8
|
-
import {
|
|
6
|
+
import { wireErrorState } from '@cdevhub/ngx-tw/core';
|
|
9
7
|
|
|
10
8
|
// ── tv() config ──────────────────────────────────────────────────
|
|
11
9
|
const switchVariants = tv({
|
|
@@ -120,9 +118,25 @@ class SwitchComponent {
|
|
|
120
118
|
/** When true, prevents interaction and applies muted styling. Defaults to `false`. */
|
|
121
119
|
disabled = input(false, /* @ts-ignore */
|
|
122
120
|
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
123
|
-
/** When true, sets `aria-required="true"` so assistive tech announces the control as required. Defaults to `false`. */
|
|
124
|
-
|
|
125
|
-
|
|
121
|
+
/** When true, sets `aria-required="true"` so assistive tech announces the control as required. Also inferred from `Validators.required` / `Validators.requiredTrue` on a bound control, so a reactive/template-driven form does not have to state it twice. Defaults to `false`. */
|
|
122
|
+
requiredInput = input(false, { ...(ngDevMode ? { debugName: "requiredInput" } : /* istanbul ignore next */ {}), alias: 'required' });
|
|
123
|
+
/**
|
|
124
|
+
* @internal Shared `errorState` / `required` / `errors` derivation — see
|
|
125
|
+
* `wireErrorState`. Declared here, above `required`, because class field
|
|
126
|
+
* initializers run in declaration order.
|
|
127
|
+
*/
|
|
128
|
+
errorWiring = wireErrorState({
|
|
129
|
+
ngControl: () => this.ngControl,
|
|
130
|
+
matcher: () => this.errorStateMatcher(),
|
|
131
|
+
required: () => this.requiredInput(),
|
|
132
|
+
// A switch bound with `Validators.requiredTrue` is required too.
|
|
133
|
+
requiredValidators: [Validators.required, Validators.requiredTrue],
|
|
134
|
+
});
|
|
135
|
+
/**
|
|
136
|
+
* @internal Resolved required state: the `required` input OR'd with
|
|
137
|
+
* `Validators.required` / `Validators.requiredTrue` on a bound `NgControl`.
|
|
138
|
+
*/
|
|
139
|
+
required = this.errorWiring.required;
|
|
126
140
|
/** Optional inline label rendered next to the switch. Use default content projection for rich label content instead. */
|
|
127
141
|
label = input(undefined, /* @ts-ignore */
|
|
128
142
|
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
@@ -135,35 +149,44 @@ class SwitchComponent {
|
|
|
135
149
|
/** Optional name attribute, mirrored to the host for form association. */
|
|
136
150
|
name = input(undefined, /* @ts-ignore */
|
|
137
151
|
...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
138
|
-
/** Accessible name when no visible label is provided. Mirrored to `aria-label`. */
|
|
152
|
+
/** Accessible name when no visible label is provided. Mirrored to `aria-label`. Defaults to `undefined`. */
|
|
139
153
|
ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
|
|
140
|
-
/** ID of an external element that labels the switch. Mirrored to `aria-labelledby`. */
|
|
154
|
+
/** ID of an external element that labels the switch. Mirrored to `aria-labelledby`. Defaults to `undefined`. */
|
|
141
155
|
ariaLabelledby = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabelledby" } : /* istanbul ignore next */ {}), alias: 'aria-labelledby' });
|
|
142
|
-
/** ID of an external element that describes the switch. Mirrored to `aria-describedby`. */
|
|
156
|
+
/** ID of an external element that describes the switch. Mirrored to `aria-describedby`. Defaults to `undefined`. */
|
|
143
157
|
ariaDescribedby = input(undefined, { ...(ngDevMode ? { debugName: "ariaDescribedby" } : /* istanbul ignore next */ {}), alias: 'aria-describedby' });
|
|
144
|
-
/**
|
|
158
|
+
/**
|
|
159
|
+
* Two-way bound checked state. Updates when the user toggles via click or
|
|
160
|
+
* Space, **and** when a bound form writes into the control
|
|
161
|
+
* (`FormControl.setValue`, `ngModel`, `writeValue`). Defaults to `false`.
|
|
162
|
+
*
|
|
163
|
+
* The two-way binding mints a `checkedChange` output. That output is the
|
|
164
|
+
* *any-change* channel: it fires on programmatic writes as well as user
|
|
165
|
+
* gestures. `(change)` is the *user-gesture-only* channel. Bind
|
|
166
|
+
* `(checkedChange)` to mirror state; bind `(change)` for analytics or a
|
|
167
|
+
* confirmation prompt, where a programmatic write must not count as a click.
|
|
168
|
+
* Writing back into the same form from a `(checkedChange)` handler will echo.
|
|
169
|
+
*/
|
|
145
170
|
checked = model(false, /* @ts-ignore */
|
|
146
171
|
...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
|
|
147
172
|
/** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the switch uses the `TW_ERROR_STATE_MATCHER` token's value. */
|
|
148
173
|
errorStateMatcher = input(undefined, /* @ts-ignore */
|
|
149
174
|
...(ngDevMode ? [{ debugName: "errorStateMatcher" }] : /* istanbul ignore next */ []));
|
|
150
|
-
/**
|
|
175
|
+
/**
|
|
176
|
+
* Fires after the checked state changes from a user interaction (click or
|
|
177
|
+
* Space). Does **not** fire when the value is updated programmatically via
|
|
178
|
+
* `writeValue` / `FormControl.setValue` / `ngModel` — for those, bind the
|
|
179
|
+
* two-way binding's `(checkedChange)` instead, which fires on any change.
|
|
180
|
+
*/
|
|
151
181
|
change = output();
|
|
152
182
|
focusMonitor = inject(FocusMonitor);
|
|
153
183
|
elementRef = inject((ElementRef));
|
|
154
184
|
destroyRef = inject(DestroyRef);
|
|
155
185
|
ngControl = inject(NgControl, { optional: true, self: true });
|
|
156
|
-
parentForm = inject(NgForm, { optional: true });
|
|
157
|
-
parentFormGroup = inject(FormGroupDirective, { optional: true });
|
|
158
|
-
defaultMatcher = inject(TW_ERROR_STATE_MATCHER);
|
|
159
186
|
onChange = () => { };
|
|
160
187
|
onTouched = () => { };
|
|
161
188
|
cvaDisabled = signal(false, /* @ts-ignore */
|
|
162
189
|
...(ngDevMode ? [{ debugName: "cvaDisabled" }] : /* istanbul ignore next */ []));
|
|
163
|
-
_ngControlRev = signal(0, /* @ts-ignore */
|
|
164
|
-
...(ngDevMode ? [{ debugName: "_ngControlRev" }] : /* istanbul ignore next */ []));
|
|
165
|
-
_formSubmitRev = signal(0, /* @ts-ignore */
|
|
166
|
-
...(ngDevMode ? [{ debugName: "_formSubmitRev" }] : /* istanbul ignore next */ []));
|
|
167
190
|
uid = nextId++;
|
|
168
191
|
hostId = `tw-switch-${this.uid}`;
|
|
169
192
|
labelId = `${this.hostId}-label`;
|
|
@@ -185,15 +208,7 @@ class SwitchComponent {
|
|
|
185
208
|
isDisabled = computed(() => this.disabled() || this.cvaDisabled(), /* @ts-ignore */
|
|
186
209
|
...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
187
210
|
/** Whether the switch is in an error state per the configured `ErrorStateMatcher`. Reads the bound `NgControl.invalid` through the matcher. */
|
|
188
|
-
errorState =
|
|
189
|
-
this._ngControlRev();
|
|
190
|
-
this._formSubmitRev();
|
|
191
|
-
const matcher = this.errorStateMatcher() ?? this.defaultMatcher;
|
|
192
|
-
const form = this.parentFormGroup ??
|
|
193
|
-
this.parentForm;
|
|
194
|
-
return matcher.isErrorState(this.ngControl?.control ?? null, form);
|
|
195
|
-
}, /* @ts-ignore */
|
|
196
|
-
...(ngDevMode ? [{ debugName: "errorState" }] : /* istanbul ignore next */ []));
|
|
211
|
+
errorState = this.errorWiring.errorState;
|
|
197
212
|
internalChecked = linkedSignal(() => this.checked(), /* @ts-ignore */
|
|
198
213
|
...(ngDevMode ? [{ debugName: "internalChecked" }] : /* istanbul ignore next */ []));
|
|
199
214
|
effectiveAriaLabelledby = computed(() => {
|
|
@@ -261,7 +276,12 @@ class SwitchComponent {
|
|
|
261
276
|
this.internalChecked.set(next);
|
|
262
277
|
this.checked.set(next);
|
|
263
278
|
this.onChange(next);
|
|
264
|
-
|
|
279
|
+
// Deliberately NOT `onTouched()`. Angular's CVA contract registers
|
|
280
|
+
// `onTouched` as the BLUR notification; calling it here flipped `touched`
|
|
281
|
+
// the instant the value changed, so a consumer staging error display on
|
|
282
|
+
// `touched` ("only once they leave the field") got different behaviour from
|
|
283
|
+
// `tw-switch` than from `tw-slider` / `tw-input`. `onBlur()` below is the
|
|
284
|
+
// only place that fires it.
|
|
265
285
|
this.change.emit(next);
|
|
266
286
|
}
|
|
267
287
|
/** Handles keyboard activation. Space toggles the switch — matches the ARIA `switch` role pattern (Enter is intentionally NOT handled, mirroring `<tw-checkbox>`). */
|
|
@@ -276,7 +296,7 @@ class SwitchComponent {
|
|
|
276
296
|
/** @internal Called on host blur to notify forms the control has been touched and recompute errorState. */
|
|
277
297
|
onBlur() {
|
|
278
298
|
this.onTouched();
|
|
279
|
-
this.
|
|
299
|
+
this.errorWiring.bump();
|
|
280
300
|
}
|
|
281
301
|
// ── ControlValueAccessor ──────────────────────────────────
|
|
282
302
|
writeValue(value) {
|
|
@@ -300,23 +320,9 @@ class SwitchComponent {
|
|
|
300
320
|
this.focusMonitor.stopMonitoring(this.elementRef);
|
|
301
321
|
});
|
|
302
322
|
// NgControl's `control` is set by the parent FormControl* directive before
|
|
303
|
-
// children's `ngOnInit`.
|
|
323
|
+
// children's `ngOnInit`. Connect here so errorState reacts to status/value
|
|
304
324
|
// changes on the bound control.
|
|
305
|
-
|
|
306
|
-
if (ctrl) {
|
|
307
|
-
const streams = [ctrl.statusChanges, ctrl.valueChanges].filter((s) => !!s);
|
|
308
|
-
if (streams.length) {
|
|
309
|
-
merge(...streams)
|
|
310
|
-
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
311
|
-
.subscribe(() => this._ngControlRev.update((n) => n + 1));
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
const submit = this.parentFormGroup?.ngSubmit ?? this.parentForm?.ngSubmit;
|
|
315
|
-
if (submit) {
|
|
316
|
-
submit
|
|
317
|
-
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
318
|
-
.subscribe(() => this._formSubmitRev.update((n) => n + 1));
|
|
319
|
-
}
|
|
325
|
+
this.errorWiring.connect();
|
|
320
326
|
}
|
|
321
327
|
hasAccessibleNameHint() {
|
|
322
328
|
if (this.label() || this.ariaLabel() || this.ariaLabelledby())
|
|
@@ -325,7 +331,7 @@ class SwitchComponent {
|
|
|
325
331
|
return host.textContent !== null && host.textContent.trim().length > 0;
|
|
326
332
|
}
|
|
327
333
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SwitchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
328
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: SwitchComponent, isStandalone: true, selector: "tw-switch", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null },
|
|
334
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: SwitchComponent, isStandalone: true, selector: "tw-switch", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, requiredInput: { classPropertyName: "requiredInput", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, errorStateMatcher: { classPropertyName: "errorStateMatcher", publicName: "errorStateMatcher", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", change: "change" }, host: { attributes: { "role": "switch" }, listeners: { "click": "toggle()", "keydown": "onKeydown($event)", "blur": "onBlur()" }, properties: { "id": "hostId", "class": "rootClasses()", "attr.data-checked": "internalChecked()", "attr.aria-checked": "internalChecked()", "attr.aria-disabled": "isDisabled() || null", "attr.aria-invalid": "errorState() || null", "attr.aria-required": "required() || null", "attr.aria-label": "ariaLabel() || null", "attr.aria-labelledby": "effectiveAriaLabelledby() || null", "attr.aria-describedby": "effectiveAriaDescribedby() || null", "attr.tabindex": "isDisabled() ? -1 : 0", "attr.name": "name() || null" } }, ngImport: i0, template: `
|
|
329
335
|
<span [class]="switchClasses()">
|
|
330
336
|
<span [class]="trackClasses()">
|
|
331
337
|
<span [class]="iconWrapClasses()">
|
|
@@ -410,7 +416,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
410
416
|
'(blur)': 'onBlur()',
|
|
411
417
|
},
|
|
412
418
|
}]
|
|
413
|
-
}], ctorParameters: () => [], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }],
|
|
419
|
+
}], ctorParameters: () => [], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], requiredInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], labelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPosition", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-describedby", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], errorStateMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorStateMatcher", required: false }] }], change: [{ type: i0.Output, args: ["change"] }] } });
|
|
414
420
|
|
|
415
421
|
/**
|
|
416
422
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cdevhub-ngx-tw-switch.mjs","sources":["../../../projects/ngx-tw/switch/switch.ts","../../../projects/ngx-tw/switch/cdevhub-ngx-tw-switch.ts"],"sourcesContent":["import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n inject,\n input,\n isDevMode,\n linkedSignal,\n model,\n type OnInit,\n output,\n signal,\n type Signal,\n} from '@angular/core';\nimport {\n type ControlValueAccessor,\n FormGroupDirective,\n NgControl,\n NgForm,\n} from '@angular/forms';\nimport { FocusMonitor } from '@angular/cdk/a11y';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { merge } from 'rxjs';\nimport { tv } from 'tailwind-variants';\nimport {\n type ErrorStateMatcher,\n TW_ERROR_STATE_MATCHER,\n type TwColor,\n type TwFormSubmitted,\n type TwSize,\n} from '@cdevhub/ngx-tw/core';\n\n/** Position of the label relative to the switch control. */\nexport type SwitchLabelPosition = 'before' | 'after';\n\n// ── tv() config ──────────────────────────────────────────────────\n\nconst switchVariants = tv(\n {\n slots: {\n root: 'inline-flex items-center gap-3 cursor-pointer select-none rounded-md focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n switchEl: 'relative inline-flex items-center shrink-0',\n track:\n 'relative inline-flex items-center rounded-full border border-transparent transition-colors duration-normal motion-reduce:transition-none',\n thumb:\n 'absolute left-0.5 inline-flex items-center justify-center bg-surface rounded-full shadow-sm transition-transform duration-normal motion-reduce:transition-none',\n iconWrap:\n 'absolute inset-0 flex items-center justify-between px-1 pointer-events-none empty:hidden',\n labelWrap: 'flex flex-col min-w-0 empty:hidden',\n label: 'font-medium text-fg empty:hidden',\n description: 'text-fg-muted empty:hidden',\n },\n variants: {\n size: {\n xs: {\n track: 'h-4 w-7',\n thumb: 'size-3 data-[checked=true]:translate-x-3',\n label: 'text-xs',\n description: 'text-2xs',\n },\n sm: {\n track: 'h-5 w-9',\n thumb: 'size-4 data-[checked=true]:translate-x-4',\n label: 'text-sm',\n description: 'text-xs',\n },\n md: {\n track: 'h-6 w-11',\n thumb: 'size-5 data-[checked=true]:translate-x-5',\n label: 'text-sm',\n description: 'text-xs',\n },\n lg: {\n track: 'h-7 w-12',\n thumb: 'size-6 data-[checked=true]:translate-x-5',\n label: 'text-base',\n description: 'text-sm',\n },\n xl: {\n track: 'h-8 w-14',\n thumb: 'size-7 data-[checked=true]:translate-x-6',\n label: 'text-base',\n description: 'text-sm',\n },\n },\n labelPosition: {\n before: { root: 'flex-row-reverse' },\n after: { root: 'flex-row' },\n },\n checked: {\n true: { track: '' },\n false: { track: 'bg-surface-muted' },\n },\n disabled: {\n true: { root: 'opacity-50 pointer-events-none cursor-not-allowed' },\n false: { root: '' },\n },\n errorState: {\n true: { label: 'text-error-700', description: 'text-error-600' },\n false: { label: '', description: '' },\n },\n },\n compoundVariants: [\n // Error state on an off (unchecked) switch repaints the rail with the error color.\n // The on (checked) track is dominated by CHECKED_TRACK[color]; consumers wanting an\n // error appearance on a checked switch should set `color=\"error\"` directly.\n {\n errorState: true,\n checked: false,\n class: { track: 'bg-error-100 ring-1 ring-inset ring-error-300' },\n },\n ],\n defaultVariants: {\n size: 'md',\n labelPosition: 'after',\n checked: false,\n disabled: false,\n errorState: false,\n },\n },\n { twMerge: true },\n);\n\n// ── Static checked-state color lookups (statically written for Tailwind v4 scanning) ──\n\nconst CHECKED_TRACK: Record<TwColor, string> = {\n primary: 'bg-primary-600',\n secondary: 'bg-secondary-600',\n accent: 'bg-accent-600',\n neutral: 'bg-fg',\n info: 'bg-info-600',\n success: 'bg-success-600',\n warning: 'bg-warning-500',\n error: 'bg-error-600',\n};\n\nconst CHECKED_ICON_COLOR: Record<TwColor, string> = {\n primary: 'text-on-primary',\n secondary: 'text-on-secondary',\n accent: 'text-on-accent',\n neutral: 'text-on-neutral',\n info: 'text-on-info',\n success: 'text-on-success',\n warning: 'text-on-warning',\n error: 'text-on-error',\n};\n\nlet nextId = 0;\n\n// ── SwitchComponent ──────────────────────────────────────────────\n\n@Component({\n selector: 'tw-switch',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <span [class]=\"switchClasses()\">\n <span [class]=\"trackClasses()\">\n <span [class]=\"iconWrapClasses()\">\n <span [class]=\"offIconClasses()\">\n <ng-content select=\"[slot='off-icon']\" />\n </span>\n <span [class]=\"onIconClasses()\">\n <ng-content select=\"[slot='on-icon']\" />\n </span>\n </span>\n <span [class]=\"thumbClasses()\" [attr.data-checked]=\"internalChecked()\"></span>\n </span>\n </span>\n\n <span [class]=\"labelWrapClasses()\">\n <span [id]=\"labelId\" [class]=\"labelClasses()\">\n <ng-content />\n @if (label()) {\n {{ label() }}\n }\n </span>\n <span [id]=\"descriptionId\" [class]=\"descriptionClasses()\">\n <ng-content select=\"[slot='description']\" />\n @if (description()) {\n {{ description() }}\n }\n </span>\n </span>\n `,\n host: {\n 'role': 'switch',\n '[id]': 'hostId',\n '[class]': 'rootClasses()',\n '[attr.data-checked]': 'internalChecked()',\n '[attr.aria-checked]': 'internalChecked()',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.aria-required]': 'required() || null',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'effectiveAriaLabelledby() || null',\n '[attr.aria-describedby]': 'effectiveAriaDescribedby() || null',\n '[attr.tabindex]': 'isDisabled() ? -1 : 0',\n '[attr.name]': 'name() || null',\n '(click)': 'toggle()',\n '(keydown)': 'onKeydown($event)',\n '(blur)': 'onBlur()',\n },\n})\nexport class SwitchComponent implements ControlValueAccessor, OnInit {\n /** Sets the semantic color for the active (checked) track. Defaults to `'primary'`. */\n readonly color = input<TwColor>('primary');\n\n /** Controls the overall scale of the track, thumb, and label typography. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** When true, prevents interaction and applies muted styling. Defaults to `false`. */\n readonly disabled = input(false);\n\n /** When true, sets `aria-required=\"true\"` so assistive tech announces the control as required. Defaults to `false`. */\n readonly required = input(false);\n\n /** Optional inline label rendered next to the switch. Use default content projection for rich label content instead. */\n readonly label = input<string | undefined>(undefined);\n\n /** Optional secondary description rendered under the label. Use `[slot=\"description\"]` content projection for rich content instead. */\n readonly description = input<string | undefined>(undefined);\n\n /** Position of the label/description relative to the switch. Defaults to `'after'`. */\n readonly labelPosition = input<SwitchLabelPosition>('after');\n\n /** Optional name attribute, mirrored to the host for form association. */\n readonly name = input<string | undefined>(undefined);\n\n /** Accessible name when no visible label is provided. Mirrored to `aria-label`. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** ID of an external element that labels the switch. Mirrored to `aria-labelledby`. */\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n /** ID of an external element that describes the switch. Mirrored to `aria-describedby`. */\n readonly ariaDescribedby = input<string | undefined>(undefined, { alias: 'aria-describedby' });\n\n /** Two-way bound checked state. Updates when the user toggles via click or Space. */\n readonly checked = model(false);\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the switch uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n /** Fires after the checked state changes from a user interaction. Does not fire when the value is updated programmatically via `writeValue`. */\n readonly change = output<boolean>();\n\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly destroyRef = inject(DestroyRef);\n private readonly ngControl = inject(NgControl, { optional: true, self: true });\n private readonly parentForm = inject(NgForm, { optional: true });\n private readonly parentFormGroup = inject(FormGroupDirective, { optional: true });\n private readonly defaultMatcher = inject(TW_ERROR_STATE_MATCHER);\n\n private onChange: (value: boolean) => void = () => {};\n private onTouched: () => void = () => {};\n private readonly cvaDisabled = signal(false);\n private readonly _ngControlRev = signal(0);\n private readonly _formSubmitRev = signal(0);\n\n private readonly uid = nextId++;\n readonly hostId = `tw-switch-${this.uid}`;\n readonly labelId = `${this.hostId}-label`;\n readonly descriptionId = `${this.hostId}-description`;\n\n constructor() {\n // Material-style CVA wiring: declare ourselves as the value accessor on any\n // host-level `NgControl` (FormControlDirective, NgModel, etc.). This avoids\n // the circular-DI that a static `NG_VALUE_ACCESSOR` provider would create\n // because `NgControl` is injected with `self: true` on the same element.\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n afterNextRender(() => {\n if (isDevMode() && !this.hasAccessibleNameHint()) {\n console.warn(\n '[tw-switch] The switch has no accessible name. Provide a `label` input, project label content, or set `aria-label` / `aria-labelledby`.',\n );\n }\n });\n }\n\n readonly isDisabled = computed(() => this.disabled() || this.cvaDisabled());\n\n /** Whether the switch is in an error state per the configured `ErrorStateMatcher`. Reads the bound `NgControl.invalid` through the matcher. */\n readonly errorState: Signal<boolean> = computed(() => {\n this._ngControlRev();\n this._formSubmitRev();\n const matcher = this.errorStateMatcher() ?? this.defaultMatcher;\n const form: TwFormSubmitted | null =\n (this.parentFormGroup as TwFormSubmitted | null) ??\n (this.parentForm as TwFormSubmitted | null);\n return matcher.isErrorState(this.ngControl?.control ?? null, form);\n });\n\n readonly internalChecked = linkedSignal(() => this.checked());\n\n readonly effectiveAriaLabelledby = computed(() => {\n const external = this.ariaLabelledby();\n if (external) return external;\n if (this.ariaLabel()) return undefined;\n return this.labelId;\n });\n\n readonly effectiveAriaDescribedby = computed(() => {\n const external = this.ariaDescribedby();\n if (external) return external;\n return this.descriptionId;\n });\n\n private readonly variantResult = computed(() =>\n switchVariants({\n size: this.size(),\n labelPosition: this.labelPosition(),\n checked: this.internalChecked(),\n disabled: this.isDisabled(),\n errorState: this.errorState(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly switchClasses = computed(() => this.variantResult().switchEl());\n readonly labelWrapClasses = computed(() => this.variantResult().labelWrap());\n readonly labelClasses = computed(() => this.variantResult().label());\n readonly descriptionClasses = computed(() => this.variantResult().description());\n readonly iconWrapClasses = computed(() => this.variantResult().iconWrap());\n readonly thumbClasses = computed(() => this.variantResult().thumb());\n\n readonly trackClasses = computed(() => {\n const base = this.variantResult().track();\n return this.internalChecked() ? `${base} ${CHECKED_TRACK[this.color()]}` : base;\n });\n\n readonly onIconClasses = computed(() => {\n const base =\n 'inline-flex items-center justify-center transition-opacity duration-normal motion-reduce:transition-none empty:hidden';\n const visibility = this.internalChecked() ? 'opacity-100' : 'opacity-0';\n const color = this.internalChecked() ? CHECKED_ICON_COLOR[this.color()] : 'text-fg-muted';\n return `${base} ${visibility} ${color}`;\n });\n\n readonly offIconClasses = computed(() => {\n const base =\n 'inline-flex items-center justify-center transition-opacity duration-normal motion-reduce:transition-none text-fg-muted empty:hidden';\n const visibility = this.internalChecked() ? 'opacity-0' : 'opacity-100';\n return `${base} ${visibility}`;\n });\n\n // ── Interactions ──────────────────────────────────────────\n\n /** Toggles the checked state. No-op when disabled. */\n toggle(): void {\n if (this.isDisabled()) return;\n const next = !this.internalChecked();\n this.internalChecked.set(next);\n this.checked.set(next);\n this.onChange(next);\n this.onTouched();\n this.change.emit(next);\n }\n\n /** Handles keyboard activation. Space toggles the switch — matches the ARIA `switch` role pattern (Enter is intentionally NOT handled, mirroring `<tw-checkbox>`). */\n onKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) return;\n if (event.key === ' ' || event.key === 'Spacebar') {\n event.preventDefault();\n this.toggle();\n }\n }\n\n /** @internal Called on host blur to notify forms the control has been touched and recompute errorState. */\n onBlur(): void {\n this.onTouched();\n this._ngControlRev.update((n) => n + 1);\n }\n\n // ── ControlValueAccessor ──────────────────────────────────\n\n writeValue(value: boolean | null | undefined): void {\n const next = !!value;\n this.internalChecked.set(next);\n this.checked.set(next);\n }\n\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n // ── Lifecycle ─────────────────────────────────────────────\n\n ngOnInit(): void {\n this.focusMonitor.monitor(this.elementRef);\n this.destroyRef.onDestroy(() => {\n this.focusMonitor.stopMonitoring(this.elementRef);\n });\n\n // NgControl's `control` is set by the parent FormControl* directive before\n // children's `ngOnInit`. Subscribe here so errorState reacts to status/value\n // changes on the bound control.\n const ctrl = this.ngControl?.control;\n if (ctrl) {\n const streams = [ctrl.statusChanges, ctrl.valueChanges].filter(\n (s): s is NonNullable<typeof s> => !!s,\n );\n if (streams.length) {\n merge(...streams)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._ngControlRev.update((n) => n + 1));\n }\n }\n\n const submit = this.parentFormGroup?.ngSubmit ?? this.parentForm?.ngSubmit;\n if (submit) {\n submit\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._formSubmitRev.update((n) => n + 1));\n }\n }\n\n private hasAccessibleNameHint(): boolean {\n if (this.label() || this.ariaLabel() || this.ariaLabelledby()) return true;\n const host = this.elementRef.nativeElement;\n return host.textContent !== null && host.textContent.trim().length > 0;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cdevhub-ngx-tw-switch.mjs","sources":["../../../projects/ngx-tw/switch/switch.ts","../../../projects/ngx-tw/switch/cdevhub-ngx-tw-switch.ts"],"sourcesContent":["import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n inject,\n input,\n isDevMode,\n linkedSignal,\n model,\n type OnInit,\n output,\n signal,\n type Signal,\n} from '@angular/core';\nimport {\n type ControlValueAccessor,\n NgControl,\n Validators,\n} from '@angular/forms';\nimport { FocusMonitor } from '@angular/cdk/a11y';\nimport { tv } from 'tailwind-variants';\nimport {\n type ErrorStateMatcher,\n type TwColor,\n type TwSize,\n wireErrorState,\n} from '@cdevhub/ngx-tw/core';\n\n/** Position of the label relative to the switch control. */\nexport type SwitchLabelPosition = 'before' | 'after';\n\n// ── tv() config ──────────────────────────────────────────────────\n\nconst switchVariants = tv(\n {\n slots: {\n root: 'inline-flex items-center gap-3 cursor-pointer select-none rounded-md focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n switchEl: 'relative inline-flex items-center shrink-0',\n track:\n 'relative inline-flex items-center rounded-full border border-transparent transition-colors duration-normal motion-reduce:transition-none',\n thumb:\n 'absolute left-0.5 inline-flex items-center justify-center bg-surface rounded-full shadow-sm transition-transform duration-normal motion-reduce:transition-none',\n iconWrap:\n 'absolute inset-0 flex items-center justify-between px-1 pointer-events-none empty:hidden',\n labelWrap: 'flex flex-col min-w-0 empty:hidden',\n label: 'font-medium text-fg empty:hidden',\n description: 'text-fg-muted empty:hidden',\n },\n variants: {\n size: {\n xs: {\n track: 'h-4 w-7',\n thumb: 'size-3 data-[checked=true]:translate-x-3',\n label: 'text-xs',\n description: 'text-2xs',\n },\n sm: {\n track: 'h-5 w-9',\n thumb: 'size-4 data-[checked=true]:translate-x-4',\n label: 'text-sm',\n description: 'text-xs',\n },\n md: {\n track: 'h-6 w-11',\n thumb: 'size-5 data-[checked=true]:translate-x-5',\n label: 'text-sm',\n description: 'text-xs',\n },\n lg: {\n track: 'h-7 w-12',\n thumb: 'size-6 data-[checked=true]:translate-x-5',\n label: 'text-base',\n description: 'text-sm',\n },\n xl: {\n track: 'h-8 w-14',\n thumb: 'size-7 data-[checked=true]:translate-x-6',\n label: 'text-base',\n description: 'text-sm',\n },\n },\n labelPosition: {\n before: { root: 'flex-row-reverse' },\n after: { root: 'flex-row' },\n },\n checked: {\n true: { track: '' },\n false: { track: 'bg-surface-muted' },\n },\n disabled: {\n true: { root: 'opacity-50 pointer-events-none cursor-not-allowed' },\n false: { root: '' },\n },\n errorState: {\n true: { label: 'text-error-700', description: 'text-error-600' },\n false: { label: '', description: '' },\n },\n },\n compoundVariants: [\n // Error state on an off (unchecked) switch repaints the rail with the error color.\n // The on (checked) track is dominated by CHECKED_TRACK[color]; consumers wanting an\n // error appearance on a checked switch should set `color=\"error\"` directly.\n {\n errorState: true,\n checked: false,\n class: { track: 'bg-error-100 ring-1 ring-inset ring-error-300' },\n },\n ],\n defaultVariants: {\n size: 'md',\n labelPosition: 'after',\n checked: false,\n disabled: false,\n errorState: false,\n },\n },\n { twMerge: true },\n);\n\n// ── Static checked-state color lookups (statically written for Tailwind v4 scanning) ──\n\nconst CHECKED_TRACK: Record<TwColor, string> = {\n primary: 'bg-primary-600',\n secondary: 'bg-secondary-600',\n accent: 'bg-accent-600',\n neutral: 'bg-fg',\n info: 'bg-info-600',\n success: 'bg-success-600',\n warning: 'bg-warning-500',\n error: 'bg-error-600',\n};\n\nconst CHECKED_ICON_COLOR: Record<TwColor, string> = {\n primary: 'text-on-primary',\n secondary: 'text-on-secondary',\n accent: 'text-on-accent',\n neutral: 'text-on-neutral',\n info: 'text-on-info',\n success: 'text-on-success',\n warning: 'text-on-warning',\n error: 'text-on-error',\n};\n\nlet nextId = 0;\n\n// ── SwitchComponent ──────────────────────────────────────────────\n\n@Component({\n selector: 'tw-switch',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <span [class]=\"switchClasses()\">\n <span [class]=\"trackClasses()\">\n <span [class]=\"iconWrapClasses()\">\n <span [class]=\"offIconClasses()\">\n <ng-content select=\"[slot='off-icon']\" />\n </span>\n <span [class]=\"onIconClasses()\">\n <ng-content select=\"[slot='on-icon']\" />\n </span>\n </span>\n <span [class]=\"thumbClasses()\" [attr.data-checked]=\"internalChecked()\"></span>\n </span>\n </span>\n\n <span [class]=\"labelWrapClasses()\">\n <span [id]=\"labelId\" [class]=\"labelClasses()\">\n <ng-content />\n @if (label()) {\n {{ label() }}\n }\n </span>\n <span [id]=\"descriptionId\" [class]=\"descriptionClasses()\">\n <ng-content select=\"[slot='description']\" />\n @if (description()) {\n {{ description() }}\n }\n </span>\n </span>\n `,\n host: {\n 'role': 'switch',\n '[id]': 'hostId',\n '[class]': 'rootClasses()',\n '[attr.data-checked]': 'internalChecked()',\n '[attr.aria-checked]': 'internalChecked()',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.aria-required]': 'required() || null',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'effectiveAriaLabelledby() || null',\n '[attr.aria-describedby]': 'effectiveAriaDescribedby() || null',\n '[attr.tabindex]': 'isDisabled() ? -1 : 0',\n '[attr.name]': 'name() || null',\n '(click)': 'toggle()',\n '(keydown)': 'onKeydown($event)',\n '(blur)': 'onBlur()',\n },\n})\nexport class SwitchComponent implements ControlValueAccessor, OnInit {\n /** Sets the semantic color for the active (checked) track. Defaults to `'primary'`. */\n readonly color = input<TwColor>('primary');\n\n /** Controls the overall scale of the track, thumb, and label typography. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** When true, prevents interaction and applies muted styling. Defaults to `false`. */\n readonly disabled = input(false);\n\n /** When true, sets `aria-required=\"true\"` so assistive tech announces the control as required. Also inferred from `Validators.required` / `Validators.requiredTrue` on a bound control, so a reactive/template-driven form does not have to state it twice. Defaults to `false`. */\n readonly requiredInput = input(false, { alias: 'required' });\n\n /**\n * @internal Shared `errorState` / `required` / `errors` derivation — see\n * `wireErrorState`. Declared here, above `required`, because class field\n * initializers run in declaration order.\n */\n private readonly errorWiring = wireErrorState({\n ngControl: () => this.ngControl,\n matcher: () => this.errorStateMatcher(),\n required: () => this.requiredInput(),\n // A switch bound with `Validators.requiredTrue` is required too.\n requiredValidators: [Validators.required, Validators.requiredTrue],\n });\n\n /**\n * @internal Resolved required state: the `required` input OR'd with\n * `Validators.required` / `Validators.requiredTrue` on a bound `NgControl`.\n */\n readonly required: Signal<boolean> = this.errorWiring.required;\n\n /** Optional inline label rendered next to the switch. Use default content projection for rich label content instead. */\n readonly label = input<string | undefined>(undefined);\n\n /** Optional secondary description rendered under the label. Use `[slot=\"description\"]` content projection for rich content instead. */\n readonly description = input<string | undefined>(undefined);\n\n /** Position of the label/description relative to the switch. Defaults to `'after'`. */\n readonly labelPosition = input<SwitchLabelPosition>('after');\n\n /** Optional name attribute, mirrored to the host for form association. */\n readonly name = input<string | undefined>(undefined);\n\n /** Accessible name when no visible label is provided. Mirrored to `aria-label`. Defaults to `undefined`. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** ID of an external element that labels the switch. Mirrored to `aria-labelledby`. Defaults to `undefined`. */\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n /** ID of an external element that describes the switch. Mirrored to `aria-describedby`. Defaults to `undefined`. */\n readonly ariaDescribedby = input<string | undefined>(undefined, { alias: 'aria-describedby' });\n\n /**\n * Two-way bound checked state. Updates when the user toggles via click or\n * Space, **and** when a bound form writes into the control\n * (`FormControl.setValue`, `ngModel`, `writeValue`). Defaults to `false`.\n *\n * The two-way binding mints a `checkedChange` output. That output is the\n * *any-change* channel: it fires on programmatic writes as well as user\n * gestures. `(change)` is the *user-gesture-only* channel. Bind\n * `(checkedChange)` to mirror state; bind `(change)` for analytics or a\n * confirmation prompt, where a programmatic write must not count as a click.\n * Writing back into the same form from a `(checkedChange)` handler will echo.\n */\n readonly checked = model(false);\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the switch uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n /**\n * Fires after the checked state changes from a user interaction (click or\n * Space). Does **not** fire when the value is updated programmatically via\n * `writeValue` / `FormControl.setValue` / `ngModel` — for those, bind the\n * two-way binding's `(checkedChange)` instead, which fires on any change.\n */\n readonly change = output<boolean>();\n\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly destroyRef = inject(DestroyRef);\n private readonly ngControl = inject(NgControl, { optional: true, self: true });\n\n private onChange: (value: boolean) => void = () => {};\n private onTouched: () => void = () => {};\n private readonly cvaDisabled = signal(false);\n\n private readonly uid = nextId++;\n readonly hostId = `tw-switch-${this.uid}`;\n readonly labelId = `${this.hostId}-label`;\n readonly descriptionId = `${this.hostId}-description`;\n\n constructor() {\n // Material-style CVA wiring: declare ourselves as the value accessor on any\n // host-level `NgControl` (FormControlDirective, NgModel, etc.). This avoids\n // the circular-DI that a static `NG_VALUE_ACCESSOR` provider would create\n // because `NgControl` is injected with `self: true` on the same element.\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n afterNextRender(() => {\n if (isDevMode() && !this.hasAccessibleNameHint()) {\n console.warn(\n '[tw-switch] The switch has no accessible name. Provide a `label` input, project label content, or set `aria-label` / `aria-labelledby`.',\n );\n }\n });\n }\n\n readonly isDisabled = computed(() => this.disabled() || this.cvaDisabled());\n\n /** Whether the switch is in an error state per the configured `ErrorStateMatcher`. Reads the bound `NgControl.invalid` through the matcher. */\n readonly errorState: Signal<boolean> = this.errorWiring.errorState;\n\n readonly internalChecked = linkedSignal(() => this.checked());\n\n readonly effectiveAriaLabelledby = computed(() => {\n const external = this.ariaLabelledby();\n if (external) return external;\n if (this.ariaLabel()) return undefined;\n return this.labelId;\n });\n\n readonly effectiveAriaDescribedby = computed(() => {\n const external = this.ariaDescribedby();\n if (external) return external;\n return this.descriptionId;\n });\n\n private readonly variantResult = computed(() =>\n switchVariants({\n size: this.size(),\n labelPosition: this.labelPosition(),\n checked: this.internalChecked(),\n disabled: this.isDisabled(),\n errorState: this.errorState(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly switchClasses = computed(() => this.variantResult().switchEl());\n readonly labelWrapClasses = computed(() => this.variantResult().labelWrap());\n readonly labelClasses = computed(() => this.variantResult().label());\n readonly descriptionClasses = computed(() => this.variantResult().description());\n readonly iconWrapClasses = computed(() => this.variantResult().iconWrap());\n readonly thumbClasses = computed(() => this.variantResult().thumb());\n\n readonly trackClasses = computed(() => {\n const base = this.variantResult().track();\n return this.internalChecked() ? `${base} ${CHECKED_TRACK[this.color()]}` : base;\n });\n\n readonly onIconClasses = computed(() => {\n const base =\n 'inline-flex items-center justify-center transition-opacity duration-normal motion-reduce:transition-none empty:hidden';\n const visibility = this.internalChecked() ? 'opacity-100' : 'opacity-0';\n const color = this.internalChecked() ? CHECKED_ICON_COLOR[this.color()] : 'text-fg-muted';\n return `${base} ${visibility} ${color}`;\n });\n\n readonly offIconClasses = computed(() => {\n const base =\n 'inline-flex items-center justify-center transition-opacity duration-normal motion-reduce:transition-none text-fg-muted empty:hidden';\n const visibility = this.internalChecked() ? 'opacity-0' : 'opacity-100';\n return `${base} ${visibility}`;\n });\n\n // ── Interactions ──────────────────────────────────────────\n\n /** Toggles the checked state. No-op when disabled. */\n toggle(): void {\n if (this.isDisabled()) return;\n const next = !this.internalChecked();\n this.internalChecked.set(next);\n this.checked.set(next);\n this.onChange(next);\n // Deliberately NOT `onTouched()`. Angular's CVA contract registers\n // `onTouched` as the BLUR notification; calling it here flipped `touched`\n // the instant the value changed, so a consumer staging error display on\n // `touched` (\"only once they leave the field\") got different behaviour from\n // `tw-switch` than from `tw-slider` / `tw-input`. `onBlur()` below is the\n // only place that fires it.\n this.change.emit(next);\n }\n\n /** Handles keyboard activation. Space toggles the switch — matches the ARIA `switch` role pattern (Enter is intentionally NOT handled, mirroring `<tw-checkbox>`). */\n onKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) return;\n if (event.key === ' ' || event.key === 'Spacebar') {\n event.preventDefault();\n this.toggle();\n }\n }\n\n /** @internal Called on host blur to notify forms the control has been touched and recompute errorState. */\n onBlur(): void {\n this.onTouched();\n this.errorWiring.bump();\n }\n\n // ── ControlValueAccessor ──────────────────────────────────\n\n writeValue(value: boolean | null | undefined): void {\n const next = !!value;\n this.internalChecked.set(next);\n this.checked.set(next);\n }\n\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n // ── Lifecycle ─────────────────────────────────────────────\n\n ngOnInit(): void {\n this.focusMonitor.monitor(this.elementRef);\n this.destroyRef.onDestroy(() => {\n this.focusMonitor.stopMonitoring(this.elementRef);\n });\n\n // NgControl's `control` is set by the parent FormControl* directive before\n // children's `ngOnInit`. Connect here so errorState reacts to status/value\n // changes on the bound control.\n this.errorWiring.connect();\n }\n\n private hasAccessibleNameHint(): boolean {\n if (this.label() || this.ariaLabel() || this.ariaLabelledby()) return true;\n const host = this.elementRef.nativeElement;\n return host.textContent !== null && host.textContent.trim().length > 0;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, signal, ChangeDetectionStrategy, Component, contentChildren, contentChild, computed, inject,
|
|
2
|
+
import { input, signal, ChangeDetectionStrategy, Component, contentChildren, contentChild, computed, inject, effect, untracked, ElementRef, Directive } from '@angular/core';
|
|
3
3
|
import { LiveAnnouncer, FocusKeyManager } from '@angular/cdk/a11y';
|
|
4
4
|
import { Directionality } from '@angular/cdk/bidi';
|
|
5
|
-
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
6
5
|
import { tv } from 'tailwind-variants';
|
|
7
6
|
import { twMerge } from 'tailwind-merge';
|
|
8
7
|
import { tabTriggerVariants, getActiveTriggerClasses, getInactiveTriggerClasses } from '@cdevhub/ngx-tw/core';
|
|
@@ -36,7 +35,7 @@ const tabNavLayoutVariants = tv({
|
|
|
36
35
|
// ── TabNavPanel ──
|
|
37
36
|
let nextPanelId = 0;
|
|
38
37
|
class TabNavPanel {
|
|
39
|
-
/** Unique id for this panel. Referenced by the active link's `aria-controls`.
|
|
38
|
+
/** Unique id for this panel. Referenced by the active link's `aria-controls`. Defaults to an auto-generated `tw-tab-nav-panel-N` id. */
|
|
40
39
|
id = input(`tw-tab-nav-panel-${nextPanelId++}`, /* @ts-ignore */
|
|
41
40
|
...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
42
41
|
/** @internal Id of the active link — set by the associated TabNavComponent. */
|
|
@@ -79,10 +78,10 @@ class TabNavComponent {
|
|
|
79
78
|
/** Additional classes merged onto the `<nav>` host. Useful for layout tweaks or borders that the default tv() config does not cover. */
|
|
80
79
|
navClass = input('', /* @ts-ignore */
|
|
81
80
|
...(ngDevMode ? [{ debugName: "navClass" }] : /* istanbul ignore next */ []));
|
|
82
|
-
/** Additional classes merged onto every tab link. Applied after base/active/disabled classes so consumer styles always win the cascade. */
|
|
81
|
+
/** Additional classes merged onto every tab link. Applied after base/active/disabled classes so consumer styles always win the cascade. Defaults to an empty string. */
|
|
83
82
|
linkClass = input('', /* @ts-ignore */
|
|
84
83
|
...(ngDevMode ? [{ debugName: "linkClass" }] : /* istanbul ignore next */ []));
|
|
85
|
-
/** Optional label overrides for screen-reader announcements. Only used in the ARIA tabs pattern (i.e. when a panel is associated). */
|
|
84
|
+
/** Optional label overrides for screen-reader announcements. Only used in the ARIA tabs pattern (i.e. when a panel is associated). Defaults to an empty object — every field falls back to its own default. */
|
|
86
85
|
labels = input({}, /* @ts-ignore */
|
|
87
86
|
...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
|
|
88
87
|
/** @internal Tab links discovered via content projection. */
|
|
@@ -95,13 +94,14 @@ class TabNavComponent {
|
|
|
95
94
|
...(ngDevMode ? [{ debugName: "resolvedPanel" }] : /* istanbul ignore next */ []));
|
|
96
95
|
liveAnnouncer = inject(LiveAnnouncer);
|
|
97
96
|
directionality = inject(Directionality, { optional: true });
|
|
98
|
-
destroyRef = inject(DestroyRef);
|
|
99
97
|
/**
|
|
100
98
|
* Live layout direction. Hardcoding 'ltr' inverts ArrowLeft/ArrowRight in RTL
|
|
101
99
|
* locales — the arrow moves to the next link in DOM order but the previous
|
|
102
|
-
* one visually.
|
|
100
|
+
* one visually. Read straight from CDK's `Directionality.valueSignal`
|
|
101
|
+
* (CDK 22+) so the key-manager effect rebuilds on a runtime `dir` flip with
|
|
102
|
+
* no manual subscription mirror.
|
|
103
103
|
*/
|
|
104
|
-
layoutDirection =
|
|
104
|
+
layoutDirection = computed(() => this.directionality?.valueSignal() ?? 'ltr', /* @ts-ignore */
|
|
105
105
|
...(ngDevMode ? [{ debugName: "layoutDirection" }] : /* istanbul ignore next */ []));
|
|
106
106
|
/** Tracks the previously-announced active link id so we only announce on actual changes. `null` = before the first sync. */
|
|
107
107
|
previousActiveLinkId = signal(null, /* @ts-ignore */
|
|
@@ -139,10 +139,6 @@ class TabNavComponent {
|
|
|
139
139
|
// is structurally incompatible with FocusableOption.disabled (boolean).
|
|
140
140
|
keyManager = null;
|
|
141
141
|
constructor() {
|
|
142
|
-
// Rebuild the key manager when the app flips `dir` at runtime.
|
|
143
|
-
this.directionality?.change
|
|
144
|
-
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
145
|
-
.subscribe((dir) => this.layoutDirection.set(dir));
|
|
146
142
|
// Keep the associated panel's aria-labelledby in sync with the active link
|
|
147
143
|
// and announce route changes to screen readers when in the ARIA tabs pattern.
|
|
148
144
|
effect(() => {
|
|
@@ -169,8 +165,9 @@ class TabNavComponent {
|
|
|
169
165
|
: `${label}, tab ${idx + 1} of ${links.length}`;
|
|
170
166
|
this.liveAnnouncer.announce(message);
|
|
171
167
|
});
|
|
172
|
-
// Rebuild FocusKeyManager whenever the link set changes
|
|
173
|
-
//
|
|
168
|
+
// Rebuild FocusKeyManager whenever the link set changes, or the app flips
|
|
169
|
+
// `dir` at runtime (`layoutDirection()` reads `Directionality.valueSignal`).
|
|
170
|
+
// tab-nav is horizontal-only, so we always configure horizontal orientation.
|
|
174
171
|
effect((onCleanup) => {
|
|
175
172
|
const links = this.links();
|
|
176
173
|
if (links.length === 0) {
|
|
@@ -254,7 +251,7 @@ class TabLinkDirective {
|
|
|
254
251
|
/** When true, the link is visually disabled and cannot be activated by click or keyboard. Defaults to `false`. */
|
|
255
252
|
disabled = input(false, /* @ts-ignore */
|
|
256
253
|
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
257
|
-
/** Unique id for this link. Referenced by the panel's `aria-labelledby` when the link is active.
|
|
254
|
+
/** Unique id for this link. Referenced by the panel's `aria-labelledby` when the link is active. Defaults to an auto-generated `tw-tab-link-N` id. */
|
|
258
255
|
linkId = input(`tw-tab-link-${nextLinkId++}`, /* @ts-ignore */
|
|
259
256
|
...(ngDevMode ? [{ debugName: "linkId" }] : /* istanbul ignore next */ []));
|
|
260
257
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cdevhub-ngx-tw-tab-nav.mjs","sources":["../../../projects/ngx-tw/tab-nav/tab-nav.ts","../../../projects/ngx-tw/tab-nav/cdevhub-ngx-tw-tab-nav.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n Directive,\n ElementRef,\n computed,\n contentChild,\n contentChildren,\n effect,\n DestroyRef,\n inject,\n input,\n signal,\n untracked,\n} from '@angular/core';\nimport { type FocusableOption, FocusKeyManager, LiveAnnouncer } from '@angular/cdk/a11y';\nimport { Directionality } from '@angular/cdk/bidi';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { tv } from 'tailwind-variants';\nimport { twMerge } from 'tailwind-merge';\nimport {\n getActiveTriggerClasses,\n getInactiveTriggerClasses,\n tabTriggerVariants,\n type TabTriggerVariant,\n type TwColor,\n type TwSize,\n} from '@cdevhub/ngx-tw/core';\n\n/** Visual style of the tab navigation strip. */\nexport type TabNavVariant = TabTriggerVariant;\n\n/** Optional label overrides for screen-reader announcements emitted by `TabNavComponent`. */\nexport interface TabNavLabels {\n /** Formatter for the LiveAnnouncer message emitted when the active link changes in the ARIA tabs pattern. Receives the link's visible text, its 1-based index, and the total link count. */\n activeTabAnnouncement?: (label: string, index: number, total: number) => string;\n}\n\n// ── tv() config — nav-shell-only slots (trigger config is shared in core) ──\n\nconst tabNavLayoutVariants = tv(\n {\n slots: {\n nav: 'relative flex shrink-0 items-stretch',\n list: 'flex overflow-x-auto items-stretch',\n },\n variants: {\n variant: {\n underline: {\n nav: 'border-b border-border',\n list: 'gap-0',\n },\n enclosed: {\n nav: 'border-b border-border',\n list: 'gap-0',\n },\n pill: {\n nav: 'bg-surface-muted rounded-xl p-1',\n list: 'gap-1',\n },\n },\n },\n defaultVariants: {\n variant: 'underline',\n },\n },\n { twMerge: true },\n);\n\n// ── TabNavPanel ──\n\nlet nextPanelId = 0;\n\n@Component({\n selector: 'tw-tab-nav-panel',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: '<ng-content />',\n host: {\n role: 'tabpanel',\n tabindex: '0',\n '[attr.id]': 'id()',\n '[attr.aria-labelledby]': 'activeTabId()',\n },\n})\nexport class TabNavPanel {\n /** Unique id for this panel. Referenced by the active link's `aria-controls`. Auto-generated when not provided. */\n readonly id = input(`tw-tab-nav-panel-${nextPanelId++}`);\n\n /** @internal Id of the active link — set by the associated TabNavComponent. */\n readonly activeTabId = signal<string | undefined>(undefined);\n}\n\n// ── TabNavComponent ──\n\n@Component({\n selector: 'nav[twTabNav]',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: '<ng-content />',\n host: {\n '[class]': 'navClasses()',\n '[attr.role]': 'role()',\n '[attr.aria-orientation]': 'ariaOrientation()',\n '(keydown)': 'onKeydown($event)',\n },\n})\nexport class TabNavComponent {\n /** Visual style of the tab strip. Defaults to `'underline'`. */\n readonly variant = input<TabNavVariant>('underline');\n\n /** Semantic color used for the active link indicator and text. Defaults to `'primary'`. */\n readonly color = input<TwColor>('primary');\n\n /** Controls padding and font size of tab links. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** When true, tab links stretch to fill available width equally. Defaults to `false`. */\n readonly fitted = input(false);\n\n /** Associated panel element. When provided, the nav follows the ARIA tabs pattern (role=tablist). When omitted, it uses the standard navigation landmark pattern with `aria-current=\"page\"` on the active link. A panel projected as a child of the `<nav>` is auto-discovered. */\n readonly tabPanel = input<TabNavPanel | undefined>(undefined);\n\n /** Additional classes merged onto the `<nav>` host. Useful for layout tweaks or borders that the default tv() config does not cover. */\n readonly navClass = input<string>('');\n\n /** Additional classes merged onto every tab link. Applied after base/active/disabled classes so consumer styles always win the cascade. */\n readonly linkClass = input<string>('');\n\n /** Optional label overrides for screen-reader announcements. Only used in the ARIA tabs pattern (i.e. when a panel is associated). */\n readonly labels = input<TabNavLabels>({});\n\n /** @internal Tab links discovered via content projection. */\n readonly links = contentChildren(TabLinkDirective, { descendants: true });\n\n /** @internal Panel discovered as a content child of the nav. */\n readonly projectedPanel = contentChild(TabNavPanel);\n\n /** @internal Resolved panel — explicit `tabPanel` input wins, falls back to a projected `<tw-tab-nav-panel>` inside the nav. */\n readonly resolvedPanel = computed(() => this.tabPanel() ?? this.projectedPanel());\n\n private readonly liveAnnouncer = inject(LiveAnnouncer);\n private readonly directionality = inject(Directionality, { optional: true });\n private readonly destroyRef = inject(DestroyRef);\n\n /**\n * Live layout direction. Hardcoding 'ltr' inverts ArrowLeft/ArrowRight in RTL\n * locales — the arrow moves to the next link in DOM order but the previous\n * one visually. Mirrored into a signal so the key manager rebuilds on change.\n */\n private readonly layoutDirection = signal<'ltr' | 'rtl'>(\n this.directionality?.value ?? 'ltr',\n );\n\n /** Tracks the previously-announced active link id so we only announce on actual changes. `null` = before the first sync. */\n private readonly previousActiveLinkId = signal<string | null | undefined>(null);\n\n private readonly layoutResult = computed(() =>\n tabNavLayoutVariants({\n variant: this.variant(),\n }),\n );\n\n private readonly triggerResult = computed(() =>\n tabTriggerVariants({\n variant: this.variant(),\n color: this.color(),\n size: this.size(),\n fitted: this.fitted(),\n }),\n );\n\n /** @internal Combined classes applied to the `<nav>` host. */\n readonly navClasses = computed(() =>\n twMerge(this.layoutResult().nav(), this.navClass()),\n );\n\n /** @internal Base trigger classes (without active/inactive state). `no-underline` is appended because anchors need to override the default browser underline — tabs (which uses `<div role=\"tab\">`) doesn't need it. */\n readonly linkBaseClasses = computed(() =>\n twMerge(this.triggerResult().trigger(), 'no-underline'),\n );\n\n /** @internal ARIA role — `tablist` when a tabPanel is associated, otherwise inherited from `<nav>`. */\n readonly role = computed(() => (this.resolvedPanel() ? 'tablist' : null));\n\n /** @internal ARIA orientation — only set in the tabs pattern. */\n readonly ariaOrientation = computed(() => (this.resolvedPanel() ? 'horizontal' : null));\n\n /** @internal Classes applied to the active state of a link, based on current variant and color. tab-nav is horizontal-only, so the orientation argument is hard-coded. */\n readonly activeLinkClasses = computed(() =>\n getActiveTriggerClasses(this.variant(), this.color(), 'horizontal'),\n );\n\n /** @internal Classes applied to the inactive state of a link, based on current variant. */\n readonly inactiveLinkClasses = computed(() => getInactiveTriggerClasses(this.variant()));\n\n // Typed as FocusableOption because TabLinkDirective's `disabled` InputSignal\n // is structurally incompatible with FocusableOption.disabled (boolean).\n private keyManager: FocusKeyManager<FocusableOption> | null = null;\n\n constructor() {\n // Rebuild the key manager when the app flips `dir` at runtime.\n this.directionality?.change\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((dir) => this.layoutDirection.set(dir));\n\n // Keep the associated panel's aria-labelledby in sync with the active link\n // and announce route changes to screen readers when in the ARIA tabs pattern.\n effect(() => {\n const panel = this.resolvedPanel();\n if (!panel) {\n // Reset so the next time a panel is associated we don't fire a stale announcement.\n untracked(() => this.previousActiveLinkId.set(null));\n return;\n }\n const links = this.links();\n const activeLink = links.find((link) => link.active());\n const activeLinkId = activeLink?.linkId() ?? undefined;\n panel.activeTabId.set(activeLinkId);\n\n const prev = untracked(() => this.previousActiveLinkId());\n untracked(() => this.previousActiveLinkId.set(activeLinkId));\n if (prev === null || prev === activeLinkId || !activeLink) {\n return;\n }\n\n const idx = links.indexOf(activeLink);\n const label = activeLink.elementRef.nativeElement.textContent?.trim() ?? '';\n const formatter = this.labels().activeTabAnnouncement;\n const message = formatter\n ? formatter(label, idx + 1, links.length)\n : `${label}, tab ${idx + 1} of ${links.length}`;\n this.liveAnnouncer.announce(message);\n });\n\n // Rebuild FocusKeyManager whenever the link set changes. tab-nav is\n // horizontal-only, so we always configure horizontal orientation.\n effect((onCleanup) => {\n const links = this.links();\n if (links.length === 0) {\n this.keyManager = null;\n return;\n }\n // Cast through unknown because `disabled` on TabLinkDirective is an\n // InputSignal — structurally incompatible with FocusableOption's\n // `disabled?: boolean`. FocusKeyManager only calls `focus()` (which we\n // provide) and the disabled check, which we override via skipPredicate.\n const focusable = links as unknown as readonly FocusableOption[];\n const manager = (new FocusKeyManager(focusable)\n .withWrap()\n .withHomeAndEnd()\n .withHorizontalOrientation(this.layoutDirection())) as FocusKeyManager<FocusableOption>;\n // The `disabled` field on TabLinkDirective is an InputSignal (always\n // truthy as a function), so we cannot rely on FocusKeyManager's default\n // disabled check. Resolve the signal explicitly here.\n manager.skipPredicate((link) => (link as unknown as TabLinkDirective).disabled());\n this.keyManager = manager;\n\n onCleanup(() => {\n manager.destroy();\n });\n });\n }\n\n /** @internal Handles arrow-key navigation in the ARIA tabs pattern via CDK FocusKeyManager. Manual activation: focus moves, but the link is only activated on Enter/Space (handled by the anchor itself). */\n onKeydown(event: KeyboardEvent): void {\n if (!this.resolvedPanel()) return;\n if (!this.keyManager) return;\n const links = this.links();\n if (links.length === 0) return;\n\n // Sync the manager's active item with whichever link the user has DOM-focused\n // (mirrors the accordion pattern; event.target works under shadow DOM).\n const focusedIdx = links.findIndex(\n (link) => link.elementRef.nativeElement === event.target,\n );\n if (focusedIdx >= 0 && focusedIdx !== this.keyManager.activeItemIndex) {\n this.keyManager.setActiveItem(focusedIdx);\n } else if (focusedIdx < 0) {\n // No focused link inside the nav — nothing to navigate.\n return;\n }\n\n this.keyManager.onKeydown(event);\n }\n}\n\n// ── TabLinkDirective ──\n\nlet nextLinkId = 0;\n\n@Directive({\n selector: 'a[twTabLink]',\n host: {\n '[attr.id]': 'linkId()',\n '[attr.role]': 'linkRole()',\n '[attr.aria-current]': 'ariaCurrent()',\n '[attr.aria-selected]': 'ariaSelected()',\n '[attr.aria-controls]': 'ariaControls()',\n '[attr.aria-disabled]': 'ariaDisabled()',\n '[attr.tabindex]': 'tabIndex()',\n '[class]': 'classes()',\n '(click)': 'onClick($event)',\n '(keydown)': 'onKeydown($event)',\n },\n})\n/**\n * Note: we intentionally do not declare `implements FocusableOption`. The\n * FocusableOption interface requires a `disabled?: boolean` property, but\n * `disabled` here is an InputSignal — a function whose own boolean-coerced\n * value is always truthy. FocusKeyManager only requires a `focus()` method\n * (structurally satisfied below) and we override the disabled check via\n * `.skipPredicate()` when constructing the manager.\n */\nexport class TabLinkDirective {\n /** @internal */\n readonly elementRef = inject<ElementRef<HTMLAnchorElement>>(ElementRef);\n\n private readonly parent = inject(TabNavComponent);\n\n /** Whether the link represents the current active page/tab. Typically bound to router state. Defaults to `false`. */\n readonly active = input(false);\n\n /** When true, the link is visually disabled and cannot be activated by click or keyboard. Defaults to `false`. */\n readonly disabled = input(false);\n\n /** Unique id for this link. Referenced by the panel's `aria-labelledby` when the link is active. Auto-generated when not provided. */\n readonly linkId = input(`tw-tab-link-${nextLinkId++}`);\n\n /**\n * @internal ARIA role — `'tab'` when the nav is wired to a panel (APG\n * tablist pattern requires `role=\"tab\"` on every link); `null` otherwise so\n * the anchor's native `role=\"link\"` wins. Do NOT collapse to a single\n * branch — both are meaningful.\n */\n readonly linkRole = computed(() => (this.parent.resolvedPanel() ? 'tab' : null));\n\n /** @internal `aria-current=\"page\"` on the active link when no tabPanel is associated. */\n readonly ariaCurrent = computed(() => {\n if (this.parent.resolvedPanel()) return null;\n return this.active() ? 'page' : null;\n });\n\n /** @internal `aria-selected` applied only in the tabs pattern. */\n readonly ariaSelected = computed(() => {\n if (!this.parent.resolvedPanel()) return null;\n return this.active() ? 'true' : 'false';\n });\n\n /** @internal `aria-controls` points to the associated panel id. */\n readonly ariaControls = computed(() => this.parent.resolvedPanel()?.id() ?? null);\n\n /** @internal */\n readonly ariaDisabled = computed(() => (this.disabled() ? 'true' : null));\n\n /** @internal Tabindex — roving in the tabs pattern, default for navigation links, always -1 when disabled. */\n readonly tabIndex = computed(() => {\n if (this.disabled()) return -1;\n if (!this.parent.resolvedPanel()) return null;\n return this.active() ? 0 : -1;\n });\n\n /** @internal Combined classes: base + active/inactive state + disabled modifiers + consumer overrides. */\n readonly classes = computed(() => {\n const base = this.parent.linkBaseClasses();\n const state = this.active()\n ? this.parent.activeLinkClasses()\n : this.parent.inactiveLinkClasses();\n const disabled = this.disabled()\n ? 'opacity-50 pointer-events-none cursor-not-allowed'\n : '';\n return twMerge(base, state, disabled, this.parent.linkClass());\n });\n\n /** Programmatically focus this link. */\n focus(): void {\n this.elementRef.nativeElement.focus();\n }\n\n /** @internal Intercepts clicks on disabled links to prevent navigation. */\n onClick(event: MouseEvent): void {\n if (this.disabled()) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n }\n\n /** @internal Handles keyboard activation: blocks Enter/Space on disabled links, and activates the link on Space for enabled ones (anchors do not respond to Space by default). */\n onKeydown(event: KeyboardEvent): void {\n if (this.disabled()) {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n return;\n }\n if (event.key === ' ') {\n event.preventDefault();\n this.elementRef.nativeElement.click();\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cdevhub-ngx-tw-tab-nav.mjs","sources":["../../../projects/ngx-tw/tab-nav/tab-nav.ts","../../../projects/ngx-tw/tab-nav/cdevhub-ngx-tw-tab-nav.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n Directive,\n ElementRef,\n computed,\n contentChild,\n contentChildren,\n effect,\n inject,\n input,\n signal,\n untracked,\n} from '@angular/core';\nimport { type FocusableOption, FocusKeyManager, LiveAnnouncer } from '@angular/cdk/a11y';\nimport { Directionality } from '@angular/cdk/bidi';\nimport { tv } from 'tailwind-variants';\nimport { twMerge } from 'tailwind-merge';\nimport {\n getActiveTriggerClasses,\n getInactiveTriggerClasses,\n tabTriggerVariants,\n type TabTriggerVariant,\n type TwColor,\n type TwSize,\n} from '@cdevhub/ngx-tw/core';\n\n/** Visual style of the tab navigation strip. */\nexport type TabNavVariant = TabTriggerVariant;\n\n/** Optional label overrides for screen-reader announcements emitted by `TabNavComponent`. */\nexport interface TabNavLabels {\n /** Formatter for the LiveAnnouncer message emitted when the active link changes in the ARIA tabs pattern. Receives the link's visible text, its 1-based index, and the total link count. */\n activeTabAnnouncement?: (label: string, index: number, total: number) => string;\n}\n\n// ── tv() config — nav-shell-only slots (trigger config is shared in core) ──\n\nconst tabNavLayoutVariants = tv(\n {\n slots: {\n nav: 'relative flex shrink-0 items-stretch',\n list: 'flex overflow-x-auto items-stretch',\n },\n variants: {\n variant: {\n underline: {\n nav: 'border-b border-border',\n list: 'gap-0',\n },\n enclosed: {\n nav: 'border-b border-border',\n list: 'gap-0',\n },\n pill: {\n nav: 'bg-surface-muted rounded-xl p-1',\n list: 'gap-1',\n },\n },\n },\n defaultVariants: {\n variant: 'underline',\n },\n },\n { twMerge: true },\n);\n\n// ── TabNavPanel ──\n\nlet nextPanelId = 0;\n\n@Component({\n selector: 'tw-tab-nav-panel',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: '<ng-content />',\n host: {\n role: 'tabpanel',\n tabindex: '0',\n '[attr.id]': 'id()',\n '[attr.aria-labelledby]': 'activeTabId()',\n },\n})\nexport class TabNavPanel {\n /** Unique id for this panel. Referenced by the active link's `aria-controls`. Defaults to an auto-generated `tw-tab-nav-panel-N` id. */\n readonly id = input(`tw-tab-nav-panel-${nextPanelId++}`);\n\n /** @internal Id of the active link — set by the associated TabNavComponent. */\n readonly activeTabId = signal<string | undefined>(undefined);\n}\n\n// ── TabNavComponent ──\n\n@Component({\n selector: 'nav[twTabNav]',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: '<ng-content />',\n host: {\n '[class]': 'navClasses()',\n '[attr.role]': 'role()',\n '[attr.aria-orientation]': 'ariaOrientation()',\n '(keydown)': 'onKeydown($event)',\n },\n})\nexport class TabNavComponent {\n /** Visual style of the tab strip. Defaults to `'underline'`. */\n readonly variant = input<TabNavVariant>('underline');\n\n /** Semantic color used for the active link indicator and text. Defaults to `'primary'`. */\n readonly color = input<TwColor>('primary');\n\n /** Controls padding and font size of tab links. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** When true, tab links stretch to fill available width equally. Defaults to `false`. */\n readonly fitted = input(false);\n\n /** Associated panel element. When provided, the nav follows the ARIA tabs pattern (role=tablist). When omitted, it uses the standard navigation landmark pattern with `aria-current=\"page\"` on the active link. A panel projected as a child of the `<nav>` is auto-discovered. */\n readonly tabPanel = input<TabNavPanel | undefined>(undefined);\n\n /** Additional classes merged onto the `<nav>` host. Useful for layout tweaks or borders that the default tv() config does not cover. */\n readonly navClass = input<string>('');\n\n /** Additional classes merged onto every tab link. Applied after base/active/disabled classes so consumer styles always win the cascade. Defaults to an empty string. */\n readonly linkClass = input<string>('');\n\n /** Optional label overrides for screen-reader announcements. Only used in the ARIA tabs pattern (i.e. when a panel is associated). Defaults to an empty object — every field falls back to its own default. */\n readonly labels = input<TabNavLabels>({});\n\n /** @internal Tab links discovered via content projection. */\n readonly links = contentChildren(TabLinkDirective, { descendants: true });\n\n /** @internal Panel discovered as a content child of the nav. */\n readonly projectedPanel = contentChild(TabNavPanel);\n\n /** @internal Resolved panel — explicit `tabPanel` input wins, falls back to a projected `<tw-tab-nav-panel>` inside the nav. */\n readonly resolvedPanel = computed(() => this.tabPanel() ?? this.projectedPanel());\n\n private readonly liveAnnouncer = inject(LiveAnnouncer);\n private readonly directionality = inject(Directionality, { optional: true });\n\n /**\n * Live layout direction. Hardcoding 'ltr' inverts ArrowLeft/ArrowRight in RTL\n * locales — the arrow moves to the next link in DOM order but the previous\n * one visually. Read straight from CDK's `Directionality.valueSignal`\n * (CDK 22+) so the key-manager effect rebuilds on a runtime `dir` flip with\n * no manual subscription mirror.\n */\n private readonly layoutDirection = computed<'ltr' | 'rtl'>(\n () => this.directionality?.valueSignal() ?? 'ltr',\n );\n\n /** Tracks the previously-announced active link id so we only announce on actual changes. `null` = before the first sync. */\n private readonly previousActiveLinkId = signal<string | null | undefined>(null);\n\n private readonly layoutResult = computed(() =>\n tabNavLayoutVariants({\n variant: this.variant(),\n }),\n );\n\n private readonly triggerResult = computed(() =>\n tabTriggerVariants({\n variant: this.variant(),\n color: this.color(),\n size: this.size(),\n fitted: this.fitted(),\n }),\n );\n\n /** @internal Combined classes applied to the `<nav>` host. */\n readonly navClasses = computed(() =>\n twMerge(this.layoutResult().nav(), this.navClass()),\n );\n\n /** @internal Base trigger classes (without active/inactive state). `no-underline` is appended because anchors need to override the default browser underline — tabs (which uses `<div role=\"tab\">`) doesn't need it. */\n readonly linkBaseClasses = computed(() =>\n twMerge(this.triggerResult().trigger(), 'no-underline'),\n );\n\n /** @internal ARIA role — `tablist` when a tabPanel is associated, otherwise inherited from `<nav>`. */\n readonly role = computed(() => (this.resolvedPanel() ? 'tablist' : null));\n\n /** @internal ARIA orientation — only set in the tabs pattern. */\n readonly ariaOrientation = computed(() => (this.resolvedPanel() ? 'horizontal' : null));\n\n /** @internal Classes applied to the active state of a link, based on current variant and color. tab-nav is horizontal-only, so the orientation argument is hard-coded. */\n readonly activeLinkClasses = computed(() =>\n getActiveTriggerClasses(this.variant(), this.color(), 'horizontal'),\n );\n\n /** @internal Classes applied to the inactive state of a link, based on current variant. */\n readonly inactiveLinkClasses = computed(() => getInactiveTriggerClasses(this.variant()));\n\n // Typed as FocusableOption because TabLinkDirective's `disabled` InputSignal\n // is structurally incompatible with FocusableOption.disabled (boolean).\n private keyManager: FocusKeyManager<FocusableOption> | null = null;\n\n constructor() {\n // Keep the associated panel's aria-labelledby in sync with the active link\n // and announce route changes to screen readers when in the ARIA tabs pattern.\n effect(() => {\n const panel = this.resolvedPanel();\n if (!panel) {\n // Reset so the next time a panel is associated we don't fire a stale announcement.\n untracked(() => this.previousActiveLinkId.set(null));\n return;\n }\n const links = this.links();\n const activeLink = links.find((link) => link.active());\n const activeLinkId = activeLink?.linkId() ?? undefined;\n panel.activeTabId.set(activeLinkId);\n\n const prev = untracked(() => this.previousActiveLinkId());\n untracked(() => this.previousActiveLinkId.set(activeLinkId));\n if (prev === null || prev === activeLinkId || !activeLink) {\n return;\n }\n\n const idx = links.indexOf(activeLink);\n const label = activeLink.elementRef.nativeElement.textContent?.trim() ?? '';\n const formatter = this.labels().activeTabAnnouncement;\n const message = formatter\n ? formatter(label, idx + 1, links.length)\n : `${label}, tab ${idx + 1} of ${links.length}`;\n this.liveAnnouncer.announce(message);\n });\n\n // Rebuild FocusKeyManager whenever the link set changes, or the app flips\n // `dir` at runtime (`layoutDirection()` reads `Directionality.valueSignal`).\n // tab-nav is horizontal-only, so we always configure horizontal orientation.\n effect((onCleanup) => {\n const links = this.links();\n if (links.length === 0) {\n this.keyManager = null;\n return;\n }\n // Cast through unknown because `disabled` on TabLinkDirective is an\n // InputSignal — structurally incompatible with FocusableOption's\n // `disabled?: boolean`. FocusKeyManager only calls `focus()` (which we\n // provide) and the disabled check, which we override via skipPredicate.\n const focusable = links as unknown as readonly FocusableOption[];\n const manager = (new FocusKeyManager(focusable)\n .withWrap()\n .withHomeAndEnd()\n .withHorizontalOrientation(this.layoutDirection())) as FocusKeyManager<FocusableOption>;\n // The `disabled` field on TabLinkDirective is an InputSignal (always\n // truthy as a function), so we cannot rely on FocusKeyManager's default\n // disabled check. Resolve the signal explicitly here.\n manager.skipPredicate((link) => (link as unknown as TabLinkDirective).disabled());\n this.keyManager = manager;\n\n onCleanup(() => {\n manager.destroy();\n });\n });\n }\n\n /** @internal Handles arrow-key navigation in the ARIA tabs pattern via CDK FocusKeyManager. Manual activation: focus moves, but the link is only activated on Enter/Space (handled by the anchor itself). */\n onKeydown(event: KeyboardEvent): void {\n if (!this.resolvedPanel()) return;\n if (!this.keyManager) return;\n const links = this.links();\n if (links.length === 0) return;\n\n // Sync the manager's active item with whichever link the user has DOM-focused\n // (mirrors the accordion pattern; event.target works under shadow DOM).\n const focusedIdx = links.findIndex(\n (link) => link.elementRef.nativeElement === event.target,\n );\n if (focusedIdx >= 0 && focusedIdx !== this.keyManager.activeItemIndex) {\n this.keyManager.setActiveItem(focusedIdx);\n } else if (focusedIdx < 0) {\n // No focused link inside the nav — nothing to navigate.\n return;\n }\n\n this.keyManager.onKeydown(event);\n }\n}\n\n// ── TabLinkDirective ──\n\nlet nextLinkId = 0;\n\n@Directive({\n selector: 'a[twTabLink]',\n host: {\n '[attr.id]': 'linkId()',\n '[attr.role]': 'linkRole()',\n '[attr.aria-current]': 'ariaCurrent()',\n '[attr.aria-selected]': 'ariaSelected()',\n '[attr.aria-controls]': 'ariaControls()',\n '[attr.aria-disabled]': 'ariaDisabled()',\n '[attr.tabindex]': 'tabIndex()',\n '[class]': 'classes()',\n '(click)': 'onClick($event)',\n '(keydown)': 'onKeydown($event)',\n },\n})\n/**\n * Note: we intentionally do not declare `implements FocusableOption`. The\n * FocusableOption interface requires a `disabled?: boolean` property, but\n * `disabled` here is an InputSignal — a function whose own boolean-coerced\n * value is always truthy. FocusKeyManager only requires a `focus()` method\n * (structurally satisfied below) and we override the disabled check via\n * `.skipPredicate()` when constructing the manager.\n */\nexport class TabLinkDirective {\n /** @internal */\n readonly elementRef = inject<ElementRef<HTMLAnchorElement>>(ElementRef);\n\n private readonly parent = inject(TabNavComponent);\n\n /** Whether the link represents the current active page/tab. Typically bound to router state. Defaults to `false`. */\n readonly active = input(false);\n\n /** When true, the link is visually disabled and cannot be activated by click or keyboard. Defaults to `false`. */\n readonly disabled = input(false);\n\n /** Unique id for this link. Referenced by the panel's `aria-labelledby` when the link is active. Defaults to an auto-generated `tw-tab-link-N` id. */\n readonly linkId = input(`tw-tab-link-${nextLinkId++}`);\n\n /**\n * @internal ARIA role — `'tab'` when the nav is wired to a panel (APG\n * tablist pattern requires `role=\"tab\"` on every link); `null` otherwise so\n * the anchor's native `role=\"link\"` wins. Do NOT collapse to a single\n * branch — both are meaningful.\n */\n readonly linkRole = computed(() => (this.parent.resolvedPanel() ? 'tab' : null));\n\n /** @internal `aria-current=\"page\"` on the active link when no tabPanel is associated. */\n readonly ariaCurrent = computed(() => {\n if (this.parent.resolvedPanel()) return null;\n return this.active() ? 'page' : null;\n });\n\n /** @internal `aria-selected` applied only in the tabs pattern. */\n readonly ariaSelected = computed(() => {\n if (!this.parent.resolvedPanel()) return null;\n return this.active() ? 'true' : 'false';\n });\n\n /** @internal `aria-controls` points to the associated panel id. */\n readonly ariaControls = computed(() => this.parent.resolvedPanel()?.id() ?? null);\n\n /** @internal */\n readonly ariaDisabled = computed(() => (this.disabled() ? 'true' : null));\n\n /** @internal Tabindex — roving in the tabs pattern, default for navigation links, always -1 when disabled. */\n readonly tabIndex = computed(() => {\n if (this.disabled()) return -1;\n if (!this.parent.resolvedPanel()) return null;\n return this.active() ? 0 : -1;\n });\n\n /** @internal Combined classes: base + active/inactive state + disabled modifiers + consumer overrides. */\n readonly classes = computed(() => {\n const base = this.parent.linkBaseClasses();\n const state = this.active()\n ? this.parent.activeLinkClasses()\n : this.parent.inactiveLinkClasses();\n const disabled = this.disabled()\n ? 'opacity-50 pointer-events-none cursor-not-allowed'\n : '';\n return twMerge(base, state, disabled, this.parent.linkClass());\n });\n\n /** Programmatically focus this link. */\n focus(): void {\n this.elementRef.nativeElement.focus();\n }\n\n /** @internal Intercepts clicks on disabled links to prevent navigation. */\n onClick(event: MouseEvent): void {\n if (this.disabled()) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n }\n\n /** @internal Handles keyboard activation: blocks Enter/Space on disabled links, and activates the link on Space for enabled ones (anchors do not respond to Space by default). */\n onKeydown(event: KeyboardEvent): void {\n if (this.disabled()) {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n return;\n }\n if (event.key === ' ') {\n event.preventDefault();\n this.elementRef.nativeElement.click();\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|