@cdevhub/ngx-tw 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/README.md +264 -49
  2. package/fesm2022/cdevhub-ngx-tw-accordion.mjs +11 -7
  3. package/fesm2022/cdevhub-ngx-tw-accordion.mjs.map +1 -1
  4. package/fesm2022/cdevhub-ngx-tw-alert.mjs +43 -29
  5. package/fesm2022/cdevhub-ngx-tw-alert.mjs.map +1 -1
  6. package/fesm2022/cdevhub-ngx-tw-aspect-ratio.mjs +103 -0
  7. package/fesm2022/cdevhub-ngx-tw-aspect-ratio.mjs.map +1 -0
  8. package/fesm2022/cdevhub-ngx-tw-avatar.mjs +56 -31
  9. package/fesm2022/cdevhub-ngx-tw-avatar.mjs.map +1 -1
  10. package/fesm2022/cdevhub-ngx-tw-badge.mjs +61 -35
  11. package/fesm2022/cdevhub-ngx-tw-badge.mjs.map +1 -1
  12. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs +154 -93
  13. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs.map +1 -1
  14. package/fesm2022/cdevhub-ngx-tw-button.mjs +35 -22
  15. package/fesm2022/cdevhub-ngx-tw-button.mjs.map +1 -1
  16. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs +3 -3
  17. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs.map +1 -1
  18. package/fesm2022/cdevhub-ngx-tw-calendar.mjs +416 -216
  19. package/fesm2022/cdevhub-ngx-tw-calendar.mjs.map +1 -1
  20. package/fesm2022/cdevhub-ngx-tw-card.mjs +33 -24
  21. package/fesm2022/cdevhub-ngx-tw-card.mjs.map +1 -1
  22. package/fesm2022/cdevhub-ngx-tw-carousel.mjs +152 -81
  23. package/fesm2022/cdevhub-ngx-tw-carousel.mjs.map +1 -1
  24. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs +99 -47
  25. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs.map +1 -1
  26. package/fesm2022/cdevhub-ngx-tw-code-block.mjs +42 -29
  27. package/fesm2022/cdevhub-ngx-tw-code-block.mjs.map +1 -1
  28. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs +46 -29
  29. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs.map +1 -1
  30. package/fesm2022/cdevhub-ngx-tw-combobox.mjs +205 -110
  31. package/fesm2022/cdevhub-ngx-tw-combobox.mjs.map +1 -1
  32. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs +141 -74
  33. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs.map +1 -1
  34. package/fesm2022/cdevhub-ngx-tw-core.mjs +16 -11
  35. package/fesm2022/cdevhub-ngx-tw-core.mjs.map +1 -1
  36. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs +395 -149
  37. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs.map +1 -1
  38. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs +305 -150
  39. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs.map +1 -1
  40. package/fesm2022/cdevhub-ngx-tw-dialog.mjs +56 -43
  41. package/fesm2022/cdevhub-ngx-tw-dialog.mjs.map +1 -1
  42. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs +51 -33
  43. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs.map +1 -1
  44. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs +905 -0
  45. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs.map +1 -0
  46. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs +49 -26
  47. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs.map +1 -1
  48. package/fesm2022/cdevhub-ngx-tw-form-field.mjs +133 -74
  49. package/fesm2022/cdevhub-ngx-tw-form-field.mjs.map +1 -1
  50. package/fesm2022/cdevhub-ngx-tw-icon-lucide.mjs +2 -2
  51. package/fesm2022/cdevhub-ngx-tw-icon-lucide.mjs.map +1 -1
  52. package/fesm2022/cdevhub-ngx-tw-icon.mjs +28 -17
  53. package/fesm2022/cdevhub-ngx-tw-icon.mjs.map +1 -1
  54. package/fesm2022/cdevhub-ngx-tw-input.mjs +37 -21
  55. package/fesm2022/cdevhub-ngx-tw-input.mjs.map +1 -1
  56. package/fesm2022/cdevhub-ngx-tw-item.mjs +33 -24
  57. package/fesm2022/cdevhub-ngx-tw-item.mjs.map +1 -1
  58. package/fesm2022/cdevhub-ngx-tw-menu.mjs +63 -48
  59. package/fesm2022/cdevhub-ngx-tw-menu.mjs.map +1 -1
  60. package/fesm2022/cdevhub-ngx-tw-number-input.mjs +622 -0
  61. package/fesm2022/cdevhub-ngx-tw-number-input.mjs.map +1 -0
  62. package/fesm2022/cdevhub-ngx-tw-paginator.mjs +142 -72
  63. package/fesm2022/cdevhub-ngx-tw-paginator.mjs.map +1 -1
  64. package/fesm2022/cdevhub-ngx-tw-popover.mjs +101 -46
  65. package/fesm2022/cdevhub-ngx-tw-popover.mjs.map +1 -1
  66. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs +57 -30
  67. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs.map +1 -1
  68. package/fesm2022/cdevhub-ngx-tw-radio.mjs +108 -57
  69. package/fesm2022/cdevhub-ngx-tw-radio.mjs.map +1 -1
  70. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs +46 -26
  71. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs.map +1 -1
  72. package/fesm2022/cdevhub-ngx-tw-select.mjs +227 -122
  73. package/fesm2022/cdevhub-ngx-tw-select.mjs.map +1 -1
  74. package/fesm2022/cdevhub-ngx-tw-separator.mjs +21 -12
  75. package/fesm2022/cdevhub-ngx-tw-separator.mjs.map +1 -1
  76. package/fesm2022/cdevhub-ngx-tw-sheet.mjs +58 -44
  77. package/fesm2022/cdevhub-ngx-tw-sheet.mjs.map +1 -1
  78. package/fesm2022/cdevhub-ngx-tw-skeleton.mjs +25 -14
  79. package/fesm2022/cdevhub-ngx-tw-skeleton.mjs.map +1 -1
  80. package/fesm2022/cdevhub-ngx-tw-slider.mjs +155 -79
  81. package/fesm2022/cdevhub-ngx-tw-slider.mjs.map +1 -1
  82. package/fesm2022/cdevhub-ngx-tw-sort.mjs +47 -25
  83. package/fesm2022/cdevhub-ngx-tw-sort.mjs.map +1 -1
  84. package/fesm2022/cdevhub-ngx-tw-spinner.mjs +29 -16
  85. package/fesm2022/cdevhub-ngx-tw-spinner.mjs.map +1 -1
  86. package/fesm2022/cdevhub-ngx-tw-split.mjs +72 -42
  87. package/fesm2022/cdevhub-ngx-tw-split.mjs.map +1 -1
  88. package/fesm2022/cdevhub-ngx-tw-stat.mjs +107 -64
  89. package/fesm2022/cdevhub-ngx-tw-stat.mjs.map +1 -1
  90. package/fesm2022/cdevhub-ngx-tw-stepper.mjs +113 -47
  91. package/fesm2022/cdevhub-ngx-tw-stepper.mjs.map +1 -1
  92. package/fesm2022/cdevhub-ngx-tw-switch.mjs +61 -32
  93. package/fesm2022/cdevhub-ngx-tw-switch.mjs.map +1 -1
  94. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs +88 -42
  95. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs.map +1 -1
  96. package/fesm2022/cdevhub-ngx-tw-table.mjs +266 -118
  97. package/fesm2022/cdevhub-ngx-tw-table.mjs.map +1 -1
  98. package/fesm2022/cdevhub-ngx-tw-tabs.mjs +102 -52
  99. package/fesm2022/cdevhub-ngx-tw-tabs.mjs.map +1 -1
  100. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs +798 -0
  101. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs.map +1 -0
  102. package/fesm2022/cdevhub-ngx-tw-textarea.mjs +16 -8
  103. package/fesm2022/cdevhub-ngx-tw-textarea.mjs.map +1 -1
  104. package/fesm2022/cdevhub-ngx-tw-theme.mjs +22 -14
  105. package/fesm2022/cdevhub-ngx-tw-theme.mjs.map +1 -1
  106. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs +243 -95
  107. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs.map +1 -1
  108. package/fesm2022/cdevhub-ngx-tw-timeline.mjs +149 -82
  109. package/fesm2022/cdevhub-ngx-tw-timeline.mjs.map +1 -1
  110. package/fesm2022/cdevhub-ngx-tw-toast.mjs +100 -55
  111. package/fesm2022/cdevhub-ngx-tw-toast.mjs.map +1 -1
  112. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs +50 -28
  113. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs.map +1 -1
  114. package/fesm2022/cdevhub-ngx-tw-transfer.mjs +1129 -0
  115. package/fesm2022/cdevhub-ngx-tw-transfer.mjs.map +1 -0
  116. package/fesm2022/cdevhub-ngx-tw-tree.mjs +554 -0
  117. package/fesm2022/cdevhub-ngx-tw-tree.mjs.map +1 -0
  118. package/fesm2022/cdevhub-ngx-tw.mjs +7 -0
  119. package/fesm2022/cdevhub-ngx-tw.mjs.map +1 -1
  120. package/package.json +45 -17
  121. package/theme/_dark.css +16 -12
  122. package/theme/_semantic.css +3 -2
  123. package/theme/index.css +10 -2
  124. package/types/cdevhub-ngx-tw-aspect-ratio.d.ts +40 -0
  125. package/types/cdevhub-ngx-tw-calendar.d.ts +39 -8
  126. package/types/cdevhub-ngx-tw-code-block.d.ts +8 -7
  127. package/types/cdevhub-ngx-tw-command-palette.d.ts +7 -0
  128. package/types/cdevhub-ngx-tw-date-picker.d.ts +36 -10
  129. package/types/cdevhub-ngx-tw-file-upload.d.ts +250 -0
  130. package/types/cdevhub-ngx-tw-form-field.d.ts +22 -3
  131. package/types/cdevhub-ngx-tw-icon-lucide.d.ts +21 -3
  132. package/types/cdevhub-ngx-tw-number-input.d.ts +130 -0
  133. package/types/cdevhub-ngx-tw-popover.d.ts +8 -0
  134. package/types/cdevhub-ngx-tw-select.d.ts +1 -1
  135. package/types/cdevhub-ngx-tw-stepper.d.ts +30 -2
  136. package/types/cdevhub-ngx-tw-tab-nav.d.ts +8 -0
  137. package/types/cdevhub-ngx-tw-table.d.ts +30 -1
  138. package/types/cdevhub-ngx-tw-tabs.d.ts +8 -0
  139. package/types/cdevhub-ngx-tw-tags-input.d.ts +217 -0
  140. package/types/cdevhub-ngx-tw-time-picker.d.ts +31 -6
  141. package/types/cdevhub-ngx-tw-toast.d.ts +1 -1
  142. package/types/cdevhub-ngx-tw-transfer.d.ts +330 -0
  143. package/types/cdevhub-ngx-tw-tree.d.ts +189 -0
  144. package/types/cdevhub-ngx-tw.d.ts +7 -0
@@ -1,6 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, signal, ChangeDetectionStrategy, Component, contentChildren, contentChild, computed, inject, effect, untracked, ElementRef, Directive } from '@angular/core';
2
+ import { input, signal, ChangeDetectionStrategy, Component, contentChildren, contentChild, computed, inject, DestroyRef, effect, untracked, ElementRef, Directive } from '@angular/core';
3
3
  import { LiveAnnouncer, FocusKeyManager } from '@angular/cdk/a11y';
4
+ import { Directionality } from '@angular/cdk/bidi';
5
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
6
  import { tv } from 'tailwind-variants';
5
7
  import { twMerge } from 'tailwind-merge';
6
8
  import { tabTriggerVariants, getActiveTriggerClasses, getInactiveTriggerClasses } from '@cdevhub/ngx-tw/core';
@@ -35,13 +37,15 @@ const tabNavLayoutVariants = tv({
35
37
  let nextPanelId = 0;
36
38
  class TabNavPanel {
37
39
  /** Unique id for this panel. Referenced by the active link's `aria-controls`. Auto-generated when not provided. */
38
- id = input(`tw-tab-nav-panel-${nextPanelId++}`, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
40
+ id = input(`tw-tab-nav-panel-${nextPanelId++}`, /* @ts-ignore */
41
+ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
39
42
  /** @internal Id of the active link — set by the associated TabNavComponent. */
40
- activeTabId = signal(undefined, ...(ngDevMode ? [{ debugName: "activeTabId" }] : /* istanbul ignore next */ []));
41
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: TabNavPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
42
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.14", type: TabNavPanel, isStandalone: true, selector: "tw-tab-nav-panel", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "tabpanel", "tabindex": "0" }, properties: { "attr.id": "id()", "attr.aria-labelledby": "activeTabId()" } }, ngImport: i0, template: '<ng-content />', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
43
+ activeTabId = signal(undefined, /* @ts-ignore */
44
+ ...(ngDevMode ? [{ debugName: "activeTabId" }] : /* istanbul ignore next */ []));
45
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TabNavPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
46
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.7", type: TabNavPanel, isStandalone: true, selector: "tw-tab-nav-panel", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "tabpanel", "tabindex": "0" }, properties: { "attr.id": "id()", "attr.aria-labelledby": "activeTabId()" } }, ngImport: i0, template: '<ng-content />', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
43
47
  }
44
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: TabNavPanel, decorators: [{
48
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TabNavPanel, decorators: [{
45
49
  type: Component,
46
50
  args: [{
47
51
  selector: 'tw-tab-nav-panel',
@@ -58,55 +62,87 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
58
62
  // ── TabNavComponent ──
59
63
  class TabNavComponent {
60
64
  /** Visual style of the tab strip. Defaults to `'underline'`. */
61
- variant = input('underline', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
65
+ variant = input('underline', /* @ts-ignore */
66
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
62
67
  /** Semantic color used for the active link indicator and text. Defaults to `'primary'`. */
63
- color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
68
+ color = input('primary', /* @ts-ignore */
69
+ ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
64
70
  /** Controls padding and font size of tab links. Defaults to `'md'`. */
65
- size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
71
+ size = input('md', /* @ts-ignore */
72
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
66
73
  /** When true, tab links stretch to fill available width equally. Defaults to `false`. */
67
- fitted = input(false, ...(ngDevMode ? [{ debugName: "fitted" }] : /* istanbul ignore next */ []));
74
+ fitted = input(false, /* @ts-ignore */
75
+ ...(ngDevMode ? [{ debugName: "fitted" }] : /* istanbul ignore next */ []));
68
76
  /** 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. */
69
- tabPanel = input(undefined, ...(ngDevMode ? [{ debugName: "tabPanel" }] : /* istanbul ignore next */ []));
77
+ tabPanel = input(undefined, /* @ts-ignore */
78
+ ...(ngDevMode ? [{ debugName: "tabPanel" }] : /* istanbul ignore next */ []));
70
79
  /** Additional classes merged onto the `<nav>` host. Useful for layout tweaks or borders that the default tv() config does not cover. */
71
- navClass = input('', ...(ngDevMode ? [{ debugName: "navClass" }] : /* istanbul ignore next */ []));
80
+ navClass = input('', /* @ts-ignore */
81
+ ...(ngDevMode ? [{ debugName: "navClass" }] : /* istanbul ignore next */ []));
72
82
  /** Additional classes merged onto every tab link. Applied after base/active/disabled classes so consumer styles always win the cascade. */
73
- linkClass = input('', ...(ngDevMode ? [{ debugName: "linkClass" }] : /* istanbul ignore next */ []));
83
+ linkClass = input('', /* @ts-ignore */
84
+ ...(ngDevMode ? [{ debugName: "linkClass" }] : /* istanbul ignore next */ []));
74
85
  /** Optional label overrides for screen-reader announcements. Only used in the ARIA tabs pattern (i.e. when a panel is associated). */
75
- labels = input({}, ...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
86
+ labels = input({}, /* @ts-ignore */
87
+ ...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
76
88
  /** @internal Tab links discovered via content projection. */
77
89
  links = contentChildren(TabLinkDirective, { ...(ngDevMode ? { debugName: "links" } : /* istanbul ignore next */ {}), descendants: true });
78
90
  /** @internal Panel discovered as a content child of the nav. */
79
- projectedPanel = contentChild(TabNavPanel, ...(ngDevMode ? [{ debugName: "projectedPanel" }] : /* istanbul ignore next */ []));
91
+ projectedPanel = contentChild(TabNavPanel, /* @ts-ignore */
92
+ ...(ngDevMode ? [{ debugName: "projectedPanel" }] : /* istanbul ignore next */ []));
80
93
  /** @internal Resolved panel — explicit `tabPanel` input wins, falls back to a projected `<tw-tab-nav-panel>` inside the nav. */
81
- resolvedPanel = computed(() => this.tabPanel() ?? this.projectedPanel(), ...(ngDevMode ? [{ debugName: "resolvedPanel" }] : /* istanbul ignore next */ []));
94
+ resolvedPanel = computed(() => this.tabPanel() ?? this.projectedPanel(), /* @ts-ignore */
95
+ ...(ngDevMode ? [{ debugName: "resolvedPanel" }] : /* istanbul ignore next */ []));
82
96
  liveAnnouncer = inject(LiveAnnouncer);
97
+ directionality = inject(Directionality, { optional: true });
98
+ destroyRef = inject(DestroyRef);
99
+ /**
100
+ * Live layout direction. Hardcoding 'ltr' inverts ArrowLeft/ArrowRight in RTL
101
+ * locales — the arrow moves to the next link in DOM order but the previous
102
+ * one visually. Mirrored into a signal so the key manager rebuilds on change.
103
+ */
104
+ layoutDirection = signal(this.directionality?.value ?? 'ltr', /* @ts-ignore */
105
+ ...(ngDevMode ? [{ debugName: "layoutDirection" }] : /* istanbul ignore next */ []));
83
106
  /** Tracks the previously-announced active link id so we only announce on actual changes. `null` = before the first sync. */
84
- previousActiveLinkId = signal(null, ...(ngDevMode ? [{ debugName: "previousActiveLinkId" }] : /* istanbul ignore next */ []));
107
+ previousActiveLinkId = signal(null, /* @ts-ignore */
108
+ ...(ngDevMode ? [{ debugName: "previousActiveLinkId" }] : /* istanbul ignore next */ []));
85
109
  layoutResult = computed(() => tabNavLayoutVariants({
86
110
  variant: this.variant(),
87
- }), ...(ngDevMode ? [{ debugName: "layoutResult" }] : /* istanbul ignore next */ []));
111
+ }), /* @ts-ignore */
112
+ ...(ngDevMode ? [{ debugName: "layoutResult" }] : /* istanbul ignore next */ []));
88
113
  triggerResult = computed(() => tabTriggerVariants({
89
114
  variant: this.variant(),
90
115
  color: this.color(),
91
116
  size: this.size(),
92
117
  fitted: this.fitted(),
93
- }), ...(ngDevMode ? [{ debugName: "triggerResult" }] : /* istanbul ignore next */ []));
118
+ }), /* @ts-ignore */
119
+ ...(ngDevMode ? [{ debugName: "triggerResult" }] : /* istanbul ignore next */ []));
94
120
  /** @internal Combined classes applied to the `<nav>` host. */
95
- navClasses = computed(() => twMerge(this.layoutResult().nav(), this.navClass()), ...(ngDevMode ? [{ debugName: "navClasses" }] : /* istanbul ignore next */ []));
121
+ navClasses = computed(() => twMerge(this.layoutResult().nav(), this.navClass()), /* @ts-ignore */
122
+ ...(ngDevMode ? [{ debugName: "navClasses" }] : /* istanbul ignore next */ []));
96
123
  /** @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. */
97
- linkBaseClasses = computed(() => twMerge(this.triggerResult().trigger(), 'no-underline'), ...(ngDevMode ? [{ debugName: "linkBaseClasses" }] : /* istanbul ignore next */ []));
124
+ linkBaseClasses = computed(() => twMerge(this.triggerResult().trigger(), 'no-underline'), /* @ts-ignore */
125
+ ...(ngDevMode ? [{ debugName: "linkBaseClasses" }] : /* istanbul ignore next */ []));
98
126
  /** @internal ARIA role — `tablist` when a tabPanel is associated, otherwise inherited from `<nav>`. */
99
- role = computed(() => (this.resolvedPanel() ? 'tablist' : null), ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
127
+ role = computed(() => (this.resolvedPanel() ? 'tablist' : null), /* @ts-ignore */
128
+ ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
100
129
  /** @internal ARIA orientation — only set in the tabs pattern. */
101
- ariaOrientation = computed(() => (this.resolvedPanel() ? 'horizontal' : null), ...(ngDevMode ? [{ debugName: "ariaOrientation" }] : /* istanbul ignore next */ []));
130
+ ariaOrientation = computed(() => (this.resolvedPanel() ? 'horizontal' : null), /* @ts-ignore */
131
+ ...(ngDevMode ? [{ debugName: "ariaOrientation" }] : /* istanbul ignore next */ []));
102
132
  /** @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. */
103
- activeLinkClasses = computed(() => getActiveTriggerClasses(this.variant(), this.color(), 'horizontal'), ...(ngDevMode ? [{ debugName: "activeLinkClasses" }] : /* istanbul ignore next */ []));
133
+ activeLinkClasses = computed(() => getActiveTriggerClasses(this.variant(), this.color(), 'horizontal'), /* @ts-ignore */
134
+ ...(ngDevMode ? [{ debugName: "activeLinkClasses" }] : /* istanbul ignore next */ []));
104
135
  /** @internal Classes applied to the inactive state of a link, based on current variant. */
105
- inactiveLinkClasses = computed(() => getInactiveTriggerClasses(this.variant()), ...(ngDevMode ? [{ debugName: "inactiveLinkClasses" }] : /* istanbul ignore next */ []));
136
+ inactiveLinkClasses = computed(() => getInactiveTriggerClasses(this.variant()), /* @ts-ignore */
137
+ ...(ngDevMode ? [{ debugName: "inactiveLinkClasses" }] : /* istanbul ignore next */ []));
106
138
  // Typed as FocusableOption because TabLinkDirective's `disabled` InputSignal
107
139
  // is structurally incompatible with FocusableOption.disabled (boolean).
108
140
  keyManager = null;
109
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));
110
146
  // Keep the associated panel's aria-labelledby in sync with the active link
111
147
  // and announce route changes to screen readers when in the ARIA tabs pattern.
112
148
  effect(() => {
@@ -149,7 +185,7 @@ class TabNavComponent {
149
185
  const manager = (new FocusKeyManager(focusable)
150
186
  .withWrap()
151
187
  .withHomeAndEnd()
152
- .withHorizontalOrientation('ltr'));
188
+ .withHorizontalOrientation(this.layoutDirection()));
153
189
  // The `disabled` field on TabLinkDirective is an InputSignal (always
154
190
  // truthy as a function), so we cannot rely on FocusKeyManager's default
155
191
  // disabled check. Resolve the signal explicitly here.
@@ -181,10 +217,10 @@ class TabNavComponent {
181
217
  }
182
218
  this.keyManager.onKeydown(event);
183
219
  }
184
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: TabNavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
185
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.14", type: TabNavComponent, isStandalone: true, selector: "nav[twTabNav]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fitted: { classPropertyName: "fitted", publicName: "fitted", isSignal: true, isRequired: false, transformFunction: null }, tabPanel: { classPropertyName: "tabPanel", publicName: "tabPanel", isSignal: true, isRequired: false, transformFunction: null }, navClass: { classPropertyName: "navClass", publicName: "navClass", isSignal: true, isRequired: false, transformFunction: null }, linkClass: { classPropertyName: "linkClass", publicName: "linkClass", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "class": "navClasses()", "attr.role": "role()", "attr.aria-orientation": "ariaOrientation()" } }, queries: [{ propertyName: "links", predicate: TabLinkDirective, descendants: true, isSignal: true }, { propertyName: "projectedPanel", first: true, predicate: TabNavPanel, descendants: true, isSignal: true }], ngImport: i0, template: '<ng-content />', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
220
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TabNavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
221
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.7", type: TabNavComponent, isStandalone: true, selector: "nav[twTabNav]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fitted: { classPropertyName: "fitted", publicName: "fitted", isSignal: true, isRequired: false, transformFunction: null }, tabPanel: { classPropertyName: "tabPanel", publicName: "tabPanel", isSignal: true, isRequired: false, transformFunction: null }, navClass: { classPropertyName: "navClass", publicName: "navClass", isSignal: true, isRequired: false, transformFunction: null }, linkClass: { classPropertyName: "linkClass", publicName: "linkClass", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "class": "navClasses()", "attr.role": "role()", "attr.aria-orientation": "ariaOrientation()" } }, queries: [{ propertyName: "links", predicate: TabLinkDirective, descendants: true, isSignal: true }, { propertyName: "projectedPanel", first: true, predicate: TabNavPanel, descendants: true, isSignal: true }], ngImport: i0, template: '<ng-content />', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
186
222
  }
187
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: TabNavComponent, decorators: [{
223
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TabNavComponent, decorators: [{
188
224
  type: Component,
189
225
  args: [{
190
226
  selector: 'nav[twTabNav]',
@@ -213,34 +249,42 @@ class TabLinkDirective {
213
249
  elementRef = inject(ElementRef);
214
250
  parent = inject(TabNavComponent);
215
251
  /** Whether the link represents the current active page/tab. Typically bound to router state. Defaults to `false`. */
216
- active = input(false, ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
252
+ active = input(false, /* @ts-ignore */
253
+ ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
217
254
  /** When true, the link is visually disabled and cannot be activated by click or keyboard. Defaults to `false`. */
218
- disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
255
+ disabled = input(false, /* @ts-ignore */
256
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
219
257
  /** Unique id for this link. Referenced by the panel's `aria-labelledby` when the link is active. Auto-generated when not provided. */
220
- linkId = input(`tw-tab-link-${nextLinkId++}`, ...(ngDevMode ? [{ debugName: "linkId" }] : /* istanbul ignore next */ []));
258
+ linkId = input(`tw-tab-link-${nextLinkId++}`, /* @ts-ignore */
259
+ ...(ngDevMode ? [{ debugName: "linkId" }] : /* istanbul ignore next */ []));
221
260
  /**
222
261
  * @internal ARIA role — `'tab'` when the nav is wired to a panel (APG
223
262
  * tablist pattern requires `role="tab"` on every link); `null` otherwise so
224
263
  * the anchor's native `role="link"` wins. Do NOT collapse to a single
225
264
  * branch — both are meaningful.
226
265
  */
227
- linkRole = computed(() => (this.parent.resolvedPanel() ? 'tab' : null), ...(ngDevMode ? [{ debugName: "linkRole" }] : /* istanbul ignore next */ []));
266
+ linkRole = computed(() => (this.parent.resolvedPanel() ? 'tab' : null), /* @ts-ignore */
267
+ ...(ngDevMode ? [{ debugName: "linkRole" }] : /* istanbul ignore next */ []));
228
268
  /** @internal `aria-current="page"` on the active link when no tabPanel is associated. */
229
269
  ariaCurrent = computed(() => {
230
270
  if (this.parent.resolvedPanel())
231
271
  return null;
232
272
  return this.active() ? 'page' : null;
233
- }, ...(ngDevMode ? [{ debugName: "ariaCurrent" }] : /* istanbul ignore next */ []));
273
+ }, /* @ts-ignore */
274
+ ...(ngDevMode ? [{ debugName: "ariaCurrent" }] : /* istanbul ignore next */ []));
234
275
  /** @internal `aria-selected` applied only in the tabs pattern. */
235
276
  ariaSelected = computed(() => {
236
277
  if (!this.parent.resolvedPanel())
237
278
  return null;
238
279
  return this.active() ? 'true' : 'false';
239
- }, ...(ngDevMode ? [{ debugName: "ariaSelected" }] : /* istanbul ignore next */ []));
280
+ }, /* @ts-ignore */
281
+ ...(ngDevMode ? [{ debugName: "ariaSelected" }] : /* istanbul ignore next */ []));
240
282
  /** @internal `aria-controls` points to the associated panel id. */
241
- ariaControls = computed(() => this.parent.resolvedPanel()?.id() ?? null, ...(ngDevMode ? [{ debugName: "ariaControls" }] : /* istanbul ignore next */ []));
283
+ ariaControls = computed(() => this.parent.resolvedPanel()?.id() ?? null, /* @ts-ignore */
284
+ ...(ngDevMode ? [{ debugName: "ariaControls" }] : /* istanbul ignore next */ []));
242
285
  /** @internal */
243
- ariaDisabled = computed(() => (this.disabled() ? 'true' : null), ...(ngDevMode ? [{ debugName: "ariaDisabled" }] : /* istanbul ignore next */ []));
286
+ ariaDisabled = computed(() => (this.disabled() ? 'true' : null), /* @ts-ignore */
287
+ ...(ngDevMode ? [{ debugName: "ariaDisabled" }] : /* istanbul ignore next */ []));
244
288
  /** @internal Tabindex — roving in the tabs pattern, default for navigation links, always -1 when disabled. */
245
289
  tabIndex = computed(() => {
246
290
  if (this.disabled())
@@ -248,7 +292,8 @@ class TabLinkDirective {
248
292
  if (!this.parent.resolvedPanel())
249
293
  return null;
250
294
  return this.active() ? 0 : -1;
251
- }, ...(ngDevMode ? [{ debugName: "tabIndex" }] : /* istanbul ignore next */ []));
295
+ }, /* @ts-ignore */
296
+ ...(ngDevMode ? [{ debugName: "tabIndex" }] : /* istanbul ignore next */ []));
252
297
  /** @internal Combined classes: base + active/inactive state + disabled modifiers + consumer overrides. */
253
298
  classes = computed(() => {
254
299
  const base = this.parent.linkBaseClasses();
@@ -259,7 +304,8 @@ class TabLinkDirective {
259
304
  ? 'opacity-50 pointer-events-none cursor-not-allowed'
260
305
  : '';
261
306
  return twMerge(base, state, disabled, this.parent.linkClass());
262
- }, ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
307
+ }, /* @ts-ignore */
308
+ ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
263
309
  /** Programmatically focus this link. */
264
310
  focus() {
265
311
  this.elementRef.nativeElement.focus();
@@ -285,10 +331,10 @@ class TabLinkDirective {
285
331
  this.elementRef.nativeElement.click();
286
332
  }
287
333
  }
288
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: TabLinkDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
289
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: TabLinkDirective, isStandalone: true, selector: "a[twTabLink]", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, linkId: { classPropertyName: "linkId", publicName: "linkId", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)", "keydown": "onKeydown($event)" }, properties: { "attr.id": "linkId()", "attr.role": "linkRole()", "attr.aria-current": "ariaCurrent()", "attr.aria-selected": "ariaSelected()", "attr.aria-controls": "ariaControls()", "attr.aria-disabled": "ariaDisabled()", "attr.tabindex": "tabIndex()", "class": "classes()" } }, ngImport: i0 });
334
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TabLinkDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
335
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: TabLinkDirective, isStandalone: true, selector: "a[twTabLink]", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, linkId: { classPropertyName: "linkId", publicName: "linkId", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)", "keydown": "onKeydown($event)" }, properties: { "attr.id": "linkId()", "attr.role": "linkRole()", "attr.aria-current": "ariaCurrent()", "attr.aria-selected": "ariaSelected()", "attr.aria-controls": "ariaControls()", "attr.aria-disabled": "ariaDisabled()", "attr.tabindex": "tabIndex()", "class": "classes()" } }, ngImport: i0 });
290
336
  }
291
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: TabLinkDirective, decorators: [{
337
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TabLinkDirective, decorators: [{
292
338
  type: Directive,
293
339
  args: [{
294
340
  selector: 'a[twTabLink]',
@@ -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 inject,\n input,\n signal,\n untracked,\n} from '@angular/core';\nimport { FocusableOption, FocusKeyManager, LiveAnnouncer } from '@angular/cdk/a11y';\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\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. 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('ltr')) 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 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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"}