@cdevhub/ngx-tw 0.2.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 (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/fesm2022/cdevhub-ngx-tw-accordion.mjs +108 -0
  4. package/fesm2022/cdevhub-ngx-tw-accordion.mjs.map +1 -0
  5. package/fesm2022/cdevhub-ngx-tw-alert.mjs +240 -0
  6. package/fesm2022/cdevhub-ngx-tw-alert.mjs.map +1 -0
  7. package/fesm2022/cdevhub-ngx-tw-avatar.mjs +287 -0
  8. package/fesm2022/cdevhub-ngx-tw-avatar.mjs.map +1 -0
  9. package/fesm2022/cdevhub-ngx-tw-badge.mjs +332 -0
  10. package/fesm2022/cdevhub-ngx-tw-badge.mjs.map +1 -0
  11. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs +452 -0
  12. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs.map +1 -0
  13. package/fesm2022/cdevhub-ngx-tw-button.mjs +227 -0
  14. package/fesm2022/cdevhub-ngx-tw-button.mjs.map +1 -0
  15. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs +417 -0
  16. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs.map +1 -0
  17. package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs +232 -0
  18. package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs.map +1 -0
  19. package/fesm2022/cdevhub-ngx-tw-calendar.mjs +4482 -0
  20. package/fesm2022/cdevhub-ngx-tw-calendar.mjs.map +1 -0
  21. package/fesm2022/cdevhub-ngx-tw-card.mjs +157 -0
  22. package/fesm2022/cdevhub-ngx-tw-card.mjs.map +1 -0
  23. package/fesm2022/cdevhub-ngx-tw-carousel.mjs +1454 -0
  24. package/fesm2022/cdevhub-ngx-tw-carousel.mjs.map +1 -0
  25. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs +593 -0
  26. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs.map +1 -0
  27. package/fesm2022/cdevhub-ngx-tw-code-block.mjs +228 -0
  28. package/fesm2022/cdevhub-ngx-tw-code-block.mjs.map +1 -0
  29. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs +510 -0
  30. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs.map +1 -0
  31. package/fesm2022/cdevhub-ngx-tw-combobox.mjs +1721 -0
  32. package/fesm2022/cdevhub-ngx-tw-combobox.mjs.map +1 -0
  33. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs +721 -0
  34. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs.map +1 -0
  35. package/fesm2022/cdevhub-ngx-tw-core.mjs +861 -0
  36. package/fesm2022/cdevhub-ngx-tw-core.mjs.map +1 -0
  37. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs +1558 -0
  38. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs.map +1 -0
  39. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs +1833 -0
  40. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs.map +1 -0
  41. package/fesm2022/cdevhub-ngx-tw-dialog.mjs +693 -0
  42. package/fesm2022/cdevhub-ngx-tw-dialog.mjs.map +1 -0
  43. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs +331 -0
  44. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs.map +1 -0
  45. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs +289 -0
  46. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs.map +1 -0
  47. package/fesm2022/cdevhub-ngx-tw-form-field.mjs +572 -0
  48. package/fesm2022/cdevhub-ngx-tw-form-field.mjs.map +1 -0
  49. package/fesm2022/cdevhub-ngx-tw-icon-lucide.mjs +36 -0
  50. package/fesm2022/cdevhub-ngx-tw-icon-lucide.mjs.map +1 -0
  51. package/fesm2022/cdevhub-ngx-tw-icon.mjs +278 -0
  52. package/fesm2022/cdevhub-ngx-tw-icon.mjs.map +1 -0
  53. package/fesm2022/cdevhub-ngx-tw-input.mjs +355 -0
  54. package/fesm2022/cdevhub-ngx-tw-input.mjs.map +1 -0
  55. package/fesm2022/cdevhub-ngx-tw-item.mjs +241 -0
  56. package/fesm2022/cdevhub-ngx-tw-item.mjs.map +1 -0
  57. package/fesm2022/cdevhub-ngx-tw-menu.mjs +433 -0
  58. package/fesm2022/cdevhub-ngx-tw-menu.mjs.map +1 -0
  59. package/fesm2022/cdevhub-ngx-tw-paginator.mjs +691 -0
  60. package/fesm2022/cdevhub-ngx-tw-paginator.mjs.map +1 -0
  61. package/fesm2022/cdevhub-ngx-tw-popover.mjs +678 -0
  62. package/fesm2022/cdevhub-ngx-tw-popover.mjs.map +1 -0
  63. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs +335 -0
  64. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs.map +1 -0
  65. package/fesm2022/cdevhub-ngx-tw-radio.mjs +708 -0
  66. package/fesm2022/cdevhub-ngx-tw-radio.mjs.map +1 -0
  67. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs +319 -0
  68. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs.map +1 -0
  69. package/fesm2022/cdevhub-ngx-tw-select.mjs +1722 -0
  70. package/fesm2022/cdevhub-ngx-tw-select.mjs.map +1 -0
  71. package/fesm2022/cdevhub-ngx-tw-separator.mjs +115 -0
  72. package/fesm2022/cdevhub-ngx-tw-separator.mjs.map +1 -0
  73. package/fesm2022/cdevhub-ngx-tw-sheet.mjs +768 -0
  74. package/fesm2022/cdevhub-ngx-tw-sheet.mjs.map +1 -0
  75. package/fesm2022/cdevhub-ngx-tw-skeleton.mjs +149 -0
  76. package/fesm2022/cdevhub-ngx-tw-skeleton.mjs.map +1 -0
  77. package/fesm2022/cdevhub-ngx-tw-slider.mjs +1147 -0
  78. package/fesm2022/cdevhub-ngx-tw-slider.mjs.map +1 -0
  79. package/fesm2022/cdevhub-ngx-tw-sort.mjs +346 -0
  80. package/fesm2022/cdevhub-ngx-tw-sort.mjs.map +1 -0
  81. package/fesm2022/cdevhub-ngx-tw-spinner.mjs +186 -0
  82. package/fesm2022/cdevhub-ngx-tw-spinner.mjs.map +1 -0
  83. package/fesm2022/cdevhub-ngx-tw-split.mjs +1082 -0
  84. package/fesm2022/cdevhub-ngx-tw-split.mjs.map +1 -0
  85. package/fesm2022/cdevhub-ngx-tw-stat.mjs +579 -0
  86. package/fesm2022/cdevhub-ngx-tw-stat.mjs.map +1 -0
  87. package/fesm2022/cdevhub-ngx-tw-stepper.mjs +443 -0
  88. package/fesm2022/cdevhub-ngx-tw-stepper.mjs.map +1 -0
  89. package/fesm2022/cdevhub-ngx-tw-switch.mjs +391 -0
  90. package/fesm2022/cdevhub-ngx-tw-switch.mjs.map +1 -0
  91. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs +315 -0
  92. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs.map +1 -0
  93. package/fesm2022/cdevhub-ngx-tw-table.mjs +994 -0
  94. package/fesm2022/cdevhub-ngx-tw-table.mjs.map +1 -0
  95. package/fesm2022/cdevhub-ngx-tw-tabs.mjs +508 -0
  96. package/fesm2022/cdevhub-ngx-tw-tabs.mjs.map +1 -0
  97. package/fesm2022/cdevhub-ngx-tw-textarea.mjs +147 -0
  98. package/fesm2022/cdevhub-ngx-tw-textarea.mjs.map +1 -0
  99. package/fesm2022/cdevhub-ngx-tw-theme.mjs +178 -0
  100. package/fesm2022/cdevhub-ngx-tw-theme.mjs.map +1 -0
  101. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs +1344 -0
  102. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs.map +1 -0
  103. package/fesm2022/cdevhub-ngx-tw-timeline.mjs +1136 -0
  104. package/fesm2022/cdevhub-ngx-tw-timeline.mjs.map +1 -0
  105. package/fesm2022/cdevhub-ngx-tw-toast.mjs +1311 -0
  106. package/fesm2022/cdevhub-ngx-tw-toast.mjs.map +1 -0
  107. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs +533 -0
  108. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs.map +1 -0
  109. package/fesm2022/cdevhub-ngx-tw.mjs +61 -0
  110. package/fesm2022/cdevhub-ngx-tw.mjs.map +1 -0
  111. package/package.json +265 -0
  112. package/theme/_base.css +394 -0
  113. package/theme/_dark.css +510 -0
  114. package/theme/_high-contrast.css +290 -0
  115. package/theme/_semantic.css +317 -0
  116. package/theme/_typography.css +9 -0
  117. package/theme/index.css +54 -0
  118. package/types/cdevhub-ngx-tw-accordion.d.ts +48 -0
  119. package/types/cdevhub-ngx-tw-alert.d.ts +67 -0
  120. package/types/cdevhub-ngx-tw-avatar.d.ts +79 -0
  121. package/types/cdevhub-ngx-tw-badge.d.ts +94 -0
  122. package/types/cdevhub-ngx-tw-breadcrumbs.d.ts +227 -0
  123. package/types/cdevhub-ngx-tw-button.d.ts +74 -0
  124. package/types/cdevhub-ngx-tw-calendar-luxon.d.ts +200 -0
  125. package/types/cdevhub-ngx-tw-calendar-testing.d.ts +113 -0
  126. package/types/cdevhub-ngx-tw-calendar.d.ts +1704 -0
  127. package/types/cdevhub-ngx-tw-card.d.ts +48 -0
  128. package/types/cdevhub-ngx-tw-carousel.d.ts +406 -0
  129. package/types/cdevhub-ngx-tw-checkbox.d.ts +136 -0
  130. package/types/cdevhub-ngx-tw-code-block.d.ts +93 -0
  131. package/types/cdevhub-ngx-tw-collapsible.d.ts +151 -0
  132. package/types/cdevhub-ngx-tw-combobox.d.ts +389 -0
  133. package/types/cdevhub-ngx-tw-command-palette.d.ts +215 -0
  134. package/types/cdevhub-ngx-tw-core.d.ts +719 -0
  135. package/types/cdevhub-ngx-tw-date-picker.d.ts +317 -0
  136. package/types/cdevhub-ngx-tw-date-range-picker.d.ts +313 -0
  137. package/types/cdevhub-ngx-tw-dialog.d.ts +303 -0
  138. package/types/cdevhub-ngx-tw-empty-state.d.ts +104 -0
  139. package/types/cdevhub-ngx-tw-flip-card.d.ts +95 -0
  140. package/types/cdevhub-ngx-tw-form-field.d.ts +210 -0
  141. package/types/cdevhub-ngx-tw-icon-lucide.d.ts +29 -0
  142. package/types/cdevhub-ngx-tw-icon.d.ts +134 -0
  143. package/types/cdevhub-ngx-tw-input.d.ts +110 -0
  144. package/types/cdevhub-ngx-tw-item.d.ts +70 -0
  145. package/types/cdevhub-ngx-tw-menu.d.ts +99 -0
  146. package/types/cdevhub-ngx-tw-paginator.d.ts +305 -0
  147. package/types/cdevhub-ngx-tw-popover.d.ts +157 -0
  148. package/types/cdevhub-ngx-tw-progress-bar.d.ts +100 -0
  149. package/types/cdevhub-ngx-tw-radio.d.ts +174 -0
  150. package/types/cdevhub-ngx-tw-segmented-control.d.ts +66 -0
  151. package/types/cdevhub-ngx-tw-select.d.ts +384 -0
  152. package/types/cdevhub-ngx-tw-separator.d.ts +28 -0
  153. package/types/cdevhub-ngx-tw-sheet.d.ts +335 -0
  154. package/types/cdevhub-ngx-tw-skeleton.d.ts +52 -0
  155. package/types/cdevhub-ngx-tw-slider.d.ts +258 -0
  156. package/types/cdevhub-ngx-tw-sort.d.ts +136 -0
  157. package/types/cdevhub-ngx-tw-spinner.d.ts +50 -0
  158. package/types/cdevhub-ngx-tw-split.d.ts +265 -0
  159. package/types/cdevhub-ngx-tw-stat.d.ts +140 -0
  160. package/types/cdevhub-ngx-tw-stepper.d.ts +127 -0
  161. package/types/cdevhub-ngx-tw-switch.d.ts +88 -0
  162. package/types/cdevhub-ngx-tw-tab-nav.d.ts +107 -0
  163. package/types/cdevhub-ngx-tw-table.d.ts +479 -0
  164. package/types/cdevhub-ngx-tw-tabs.d.ts +121 -0
  165. package/types/cdevhub-ngx-tw-textarea.d.ts +62 -0
  166. package/types/cdevhub-ngx-tw-theme.d.ts +106 -0
  167. package/types/cdevhub-ngx-tw-time-picker.d.ts +303 -0
  168. package/types/cdevhub-ngx-tw-timeline.d.ts +278 -0
  169. package/types/cdevhub-ngx-tw-toast.d.ts +388 -0
  170. package/types/cdevhub-ngx-tw-tooltip.d.ts +95 -0
  171. package/types/cdevhub-ngx-tw.d.ts +49 -0
@@ -0,0 +1,289 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, booleanAttribute, model, inject, DestroyRef, viewChild, signal, computed, afterNextRender, effect, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { LiveAnnouncer } from '@angular/cdk/a11y';
4
+ import { tv } from 'tailwind-variants';
5
+
6
+ // ── tv() config ──
7
+ const flipCardVariants = tv({
8
+ slots: {
9
+ root: 'relative block rounded-lg transition-shadow duration-normal motion-reduce:transition-none tw-flip-perspective',
10
+ inner: 'relative h-full w-full tw-flip-inner transition-transform duration-300 ease-in-out motion-reduce:transition-none',
11
+ face: 'absolute inset-0 h-full w-full rounded-lg overflow-hidden tw-flip-face',
12
+ front: '',
13
+ back: 'tw-flip-back-face',
14
+ },
15
+ variants: {
16
+ variant: {
17
+ outlined: {
18
+ face: 'bg-surface border border-border text-fg',
19
+ },
20
+ elevated: {
21
+ face: 'bg-surface-raised shadow text-fg',
22
+ root: 'hover:shadow-md',
23
+ },
24
+ ghost: {
25
+ face: 'bg-transparent text-fg',
26
+ },
27
+ },
28
+ direction: {
29
+ horizontal: {
30
+ inner: 'tw-flip-axis-y',
31
+ back: 'tw-flip-back-y',
32
+ },
33
+ vertical: {
34
+ inner: 'tw-flip-axis-x',
35
+ back: 'tw-flip-back-x',
36
+ },
37
+ },
38
+ flipped: {
39
+ true: { inner: 'tw-flip-rotated' },
40
+ false: {},
41
+ },
42
+ interactive: {
43
+ true: {
44
+ root: 'cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',
45
+ },
46
+ false: {},
47
+ },
48
+ disabled: {
49
+ true: { root: 'opacity-50 cursor-not-allowed' },
50
+ false: {},
51
+ },
52
+ },
53
+ defaultVariants: {
54
+ variant: 'outlined',
55
+ direction: 'horizontal',
56
+ flipped: false,
57
+ interactive: true,
58
+ disabled: false,
59
+ },
60
+ }, { twMerge: true });
61
+ /**
62
+ * Two-faced card with a CSS 3D-perspective flip animation.
63
+ *
64
+ * @remarks
65
+ * **Hard theme dependency.** The flip animation is driven by helper classes
66
+ * (`tw-flip-perspective`, `tw-flip-inner`, `tw-flip-face`, `tw-flip-back-face`,
67
+ * `tw-flip-axis-x`, `tw-flip-axis-y`, `tw-flip-rotated`, `tw-flip-back-x`,
68
+ * `tw-flip-back-y`) declared in `projects/ngx-tw/theme/_base.css` and re-exported
69
+ * via `ngx-tw/theme/default.css`. Consumers MUST import the theme stylesheet —
70
+ * without it the card renders as two stacked faces with no perspective and no
71
+ * rotation, and there is no run-time fallback. `prefers-reduced-motion: reduce`
72
+ * is handled in the theme CSS, not here.
73
+ */
74
+ class FlipCardComponent {
75
+ /**
76
+ * Visual style of the card chrome. Mirrors `tw-card`'s variant vocabulary.
77
+ * Defaults to `'outlined'` (vs `tw-card`'s `'elevated'` default) so the flip
78
+ * animation reads more clearly without a baseline shadow underneath.
79
+ */
80
+ variant = input('outlined', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
81
+ /** Axis of rotation. `'horizontal'` rotates around the Y axis (left/right flip); `'vertical'` rotates around the X axis (top/bottom flip). Defaults to `'horizontal'`. */
82
+ direction = input('horizontal', ...(ngDevMode ? [{ debugName: "direction" }] : /* istanbul ignore next */ []));
83
+ /** Which user action flips the card. `'both'` enables click and hover. `'manual'` disables all triggers and defers control to the `flipped` model. Defaults to `'both'`. */
84
+ trigger = input('both', ...(ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []));
85
+ /** When true, all triggers and keyboard handling are disabled; the current face stays visible. Defaults to `false`. */
86
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
87
+ /** Whether the back face is currently visible. Two-way bindable via `[(flipped)]`. Defaults to `false`. The `flippedChange` event fires on every toggle. */
88
+ flipped = model(false, ...(ngDevMode ? [{ debugName: "flipped" }] : /* istanbul ignore next */ []));
89
+ /**
90
+ * Accessible name for the host element. Required when `trigger` is
91
+ * `'manual'` (the host renders as `role="region"`, which AXE requires to
92
+ * have an accessible name); a default of `'Flip card'` is used in that
93
+ * mode if no value is provided. In interactive modes the host's accessible
94
+ * name is normally derived from the visible face's content — set this
95
+ * input to override.
96
+ */
97
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
98
+ liveAnnouncer = inject(LiveAnnouncer);
99
+ destroyRef = inject(DestroyRef);
100
+ backWrapper = viewChild('backWrapper', ...(ngDevMode ? [{ debugName: "backWrapper" }] : /* istanbul ignore next */ []));
101
+ _hasBack = signal(false, ...(ngDevMode ? [{ debugName: "_hasBack" }] : /* istanbul ignore next */ []));
102
+ /** @internal */
103
+ hasBack = this._hasBack.asReadonly();
104
+ /** @internal */
105
+ interactive = computed(() => this.trigger() !== 'manual' && !this.disabled() && this.hasBack(), ...(ngDevMode ? [{ debugName: "interactive" }] : /* istanbul ignore next */ []));
106
+ /** @internal */
107
+ hostRole = computed(() => this.trigger() === 'manual' ? 'region' : 'button', ...(ngDevMode ? [{ debugName: "hostRole" }] : /* istanbul ignore next */ []));
108
+ /** @internal */
109
+ hostTabindex = computed(() => (this.interactive() ? 0 : null), ...(ngDevMode ? [{ debugName: "hostTabindex" }] : /* istanbul ignore next */ []));
110
+ /** @internal */
111
+ ariaPressed = computed(() => this.interactive() ? String(this.flipped()) : null, ...(ngDevMode ? [{ debugName: "ariaPressed" }] : /* istanbul ignore next */ []));
112
+ /** @internal */
113
+ ariaLive = computed(() => this.trigger() === 'manual' ? 'polite' : null, ...(ngDevMode ? [{ debugName: "ariaLive" }] : /* istanbul ignore next */ []));
114
+ /** @internal */
115
+ ariaDisabled = computed(() => this.disabled() ? 'true' : null, ...(ngDevMode ? [{ debugName: "ariaDisabled" }] : /* istanbul ignore next */ []));
116
+ /** @internal */
117
+ hostAriaLabel = computed(() => {
118
+ const explicit = this.ariaLabel();
119
+ if (explicit !== undefined && explicit !== '')
120
+ return explicit;
121
+ return this.trigger() === 'manual' ? 'Flip card' : null;
122
+ }, ...(ngDevMode ? [{ debugName: "hostAriaLabel" }] : /* istanbul ignore next */ []));
123
+ /** @internal */
124
+ frontAriaHidden = computed(() => this.hasBack() && this.flipped() ? 'true' : null, ...(ngDevMode ? [{ debugName: "frontAriaHidden" }] : /* istanbul ignore next */ []));
125
+ /** @internal */
126
+ backAriaHidden = computed(() => !this.hasBack() || !this.flipped() ? 'true' : null, ...(ngDevMode ? [{ debugName: "backAriaHidden" }] : /* istanbul ignore next */ []));
127
+ /** @internal */
128
+ frontInert = computed(() => this.hasBack() && this.flipped() ? '' : null, ...(ngDevMode ? [{ debugName: "frontInert" }] : /* istanbul ignore next */ []));
129
+ /** @internal */
130
+ backInert = computed(() => !this.hasBack() || !this.flipped() ? '' : null, ...(ngDevMode ? [{ debugName: "backInert" }] : /* istanbul ignore next */ []));
131
+ variantResult = computed(() => flipCardVariants({
132
+ variant: this.variant(),
133
+ direction: this.direction(),
134
+ flipped: this.flipped(),
135
+ interactive: this.interactive(),
136
+ disabled: this.disabled(),
137
+ }), ...(ngDevMode ? [{ debugName: "variantResult" }] : /* istanbul ignore next */ []));
138
+ rootClasses = computed(() => this.variantResult().root(), ...(ngDevMode ? [{ debugName: "rootClasses" }] : /* istanbul ignore next */ []));
139
+ innerClasses = computed(() => this.variantResult().inner(), ...(ngDevMode ? [{ debugName: "innerClasses" }] : /* istanbul ignore next */ []));
140
+ frontClasses = computed(() => `${this.variantResult().face()} ${this.variantResult().front()}`, ...(ngDevMode ? [{ debugName: "frontClasses" }] : /* istanbul ignore next */ []));
141
+ backClasses = computed(() => `${this.variantResult().face()} ${this.variantResult().back()}`, ...(ngDevMode ? [{ debugName: "backClasses" }] : /* istanbul ignore next */ []));
142
+ constructor() {
143
+ // `MutationObserver` (not `contentChild`) because the spec exercises
144
+ // *dynamic* projection toggled by an `@if` in the host template
145
+ // (see `DynamicBackHost` in flip-card.spec.ts). `contentChild` resolves
146
+ // the parent's own content children — it does NOT see elements projected
147
+ // *through* the host via `<ng-content select="[slot='back']" />`. The
148
+ // observer is single-target and listens only for `childList` on the back
149
+ // wrapper, so the cost is bounded and the disconnect runs on destroy.
150
+ afterNextRender(() => {
151
+ const el = this.backWrapper()?.nativeElement;
152
+ if (!el)
153
+ return;
154
+ const update = () => this._hasBack.set(el.childElementCount > 0);
155
+ update();
156
+ const observer = new MutationObserver(update);
157
+ observer.observe(el, { childList: true });
158
+ this.destroyRef.onDestroy(() => observer.disconnect());
159
+ });
160
+ let firstRun = true;
161
+ effect(() => {
162
+ const isFlipped = this.flipped();
163
+ if (firstRun) {
164
+ firstRun = false;
165
+ return;
166
+ }
167
+ // Announce in any mode that exposes a flippable back face. Manual mode
168
+ // historically owned this because it sets `aria-live='polite'` on the
169
+ // host; interactive modes (hover, click, both) still need an explicit
170
+ // `LiveAnnouncer.announce` so screen-reader users hear the transition
171
+ // when triggering the card via keyboard or pointer.
172
+ if (this.hasBack()) {
173
+ this.liveAnnouncer.announce(isFlipped ? 'Back face visible' : 'Front face visible');
174
+ }
175
+ });
176
+ }
177
+ /** @internal */
178
+ onClick() {
179
+ if (this.disabled() || !this.hasBack())
180
+ return;
181
+ const t = this.trigger();
182
+ if (t === 'manual')
183
+ return;
184
+ this.toggle();
185
+ }
186
+ /** @internal */
187
+ onKeydown(event) {
188
+ if (!this.interactive())
189
+ return;
190
+ if (event.key === 'Enter' || event.key === ' ') {
191
+ event.preventDefault();
192
+ this.toggle();
193
+ }
194
+ }
195
+ /** @internal */
196
+ onMouseEnter() {
197
+ if (this.disabled() || !this.hasBack())
198
+ return;
199
+ const t = this.trigger();
200
+ if (t !== 'hover' && t !== 'both')
201
+ return;
202
+ this.setFlipped(true);
203
+ }
204
+ /** @internal */
205
+ onMouseLeave() {
206
+ if (this.disabled() || !this.hasBack())
207
+ return;
208
+ const t = this.trigger();
209
+ if (t !== 'hover' && t !== 'both')
210
+ return;
211
+ this.setFlipped(false);
212
+ }
213
+ toggle() {
214
+ this.setFlipped(!this.flipped());
215
+ }
216
+ setFlipped(next) {
217
+ if (this.flipped() === next)
218
+ return;
219
+ this.flipped.set(next);
220
+ }
221
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: FlipCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
222
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.14", type: FlipCardComponent, isStandalone: true, selector: "tw-flip-card", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, flipped: { classPropertyName: "flipped", publicName: "flipped", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { flipped: "flippedChange" }, host: { listeners: { "click": "onClick()", "keydown": "onKeydown($event)", "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" }, properties: { "class": "rootClasses()", "attr.role": "hostRole()", "attr.tabindex": "hostTabindex()", "attr.aria-pressed": "ariaPressed()", "attr.aria-live": "ariaLive()", "attr.aria-disabled": "ariaDisabled()", "attr.aria-label": "hostAriaLabel()" } }, viewQueries: [{ propertyName: "backWrapper", first: true, predicate: ["backWrapper"], descendants: true, isSignal: true }], ngImport: i0, template: `
223
+ <div [class]="innerClasses()">
224
+ <div
225
+ [class]="frontClasses()"
226
+ [attr.aria-hidden]="frontAriaHidden()"
227
+ [attr.inert]="frontInert()"
228
+ >
229
+ <ng-content select="[slot='front']" />
230
+ </div>
231
+ <div
232
+ #backWrapper
233
+ [class]="backClasses()"
234
+ [class.hidden]="!hasBack()"
235
+ [attr.aria-hidden]="backAriaHidden()"
236
+ [attr.inert]="backInert()"
237
+ >
238
+ <ng-content select="[slot='back']" />
239
+ </div>
240
+ </div>
241
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
242
+ }
243
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: FlipCardComponent, decorators: [{
244
+ type: Component,
245
+ args: [{
246
+ selector: 'tw-flip-card',
247
+ changeDetection: ChangeDetectionStrategy.OnPush,
248
+ host: {
249
+ '[class]': 'rootClasses()',
250
+ '[attr.role]': 'hostRole()',
251
+ '[attr.tabindex]': 'hostTabindex()',
252
+ '[attr.aria-pressed]': 'ariaPressed()',
253
+ '[attr.aria-live]': 'ariaLive()',
254
+ '[attr.aria-disabled]': 'ariaDisabled()',
255
+ '[attr.aria-label]': 'hostAriaLabel()',
256
+ '(click)': 'onClick()',
257
+ '(keydown)': 'onKeydown($event)',
258
+ '(mouseenter)': 'onMouseEnter()',
259
+ '(mouseleave)': 'onMouseLeave()',
260
+ },
261
+ template: `
262
+ <div [class]="innerClasses()">
263
+ <div
264
+ [class]="frontClasses()"
265
+ [attr.aria-hidden]="frontAriaHidden()"
266
+ [attr.inert]="frontInert()"
267
+ >
268
+ <ng-content select="[slot='front']" />
269
+ </div>
270
+ <div
271
+ #backWrapper
272
+ [class]="backClasses()"
273
+ [class.hidden]="!hasBack()"
274
+ [attr.aria-hidden]="backAriaHidden()"
275
+ [attr.inert]="backInert()"
276
+ >
277
+ <ng-content select="[slot='back']" />
278
+ </div>
279
+ </div>
280
+ `,
281
+ }]
282
+ }], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], flipped: [{ type: i0.Input, args: [{ isSignal: true, alias: "flipped", required: false }] }, { type: i0.Output, args: ["flippedChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], backWrapper: [{ type: i0.ViewChild, args: ['backWrapper', { isSignal: true }] }] } });
283
+
284
+ /**
285
+ * Generated bundle index. Do not edit.
286
+ */
287
+
288
+ export { FlipCardComponent };
289
+ //# sourceMappingURL=cdevhub-ngx-tw-flip-card.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdevhub-ngx-tw-flip-card.mjs","sources":["../../../projects/ngx-tw/flip-card/flip-card.ts","../../../projects/ngx-tw/flip-card/cdevhub-ngx-tw-flip-card.ts"],"sourcesContent":["import {\n afterNextRender,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n type ElementRef,\n inject,\n input,\n model,\n signal,\n viewChild,\n} from '@angular/core';\nimport { LiveAnnouncer } from '@angular/cdk/a11y';\nimport { tv } from 'tailwind-variants';\n\n/** Visual style of the flip card chrome. Mirrors `tw-card`. */\nexport type FlipCardVariant = 'outlined' | 'elevated' | 'ghost';\n\n/** Axis of rotation for the flip animation. */\nexport type FlipCardDirection = 'horizontal' | 'vertical';\n\n/** Which user interaction flips the card. */\nexport type FlipCardTrigger = 'hover' | 'click' | 'manual' | 'both';\n\n// ── tv() config ──\n\nconst flipCardVariants = tv(\n {\n slots: {\n root:\n 'relative block rounded-lg transition-shadow duration-normal motion-reduce:transition-none tw-flip-perspective',\n inner:\n 'relative h-full w-full tw-flip-inner transition-transform duration-300 ease-in-out motion-reduce:transition-none',\n face:\n 'absolute inset-0 h-full w-full rounded-lg overflow-hidden tw-flip-face',\n front: '',\n back: 'tw-flip-back-face',\n },\n variants: {\n variant: {\n outlined: {\n face: 'bg-surface border border-border text-fg',\n },\n elevated: {\n face: 'bg-surface-raised shadow text-fg',\n root: 'hover:shadow-md',\n },\n ghost: {\n face: 'bg-transparent text-fg',\n },\n },\n direction: {\n horizontal: {\n inner: 'tw-flip-axis-y',\n back: 'tw-flip-back-y',\n },\n vertical: {\n inner: 'tw-flip-axis-x',\n back: 'tw-flip-back-x',\n },\n },\n flipped: {\n true: { inner: 'tw-flip-rotated' },\n false: {},\n },\n interactive: {\n true: {\n root:\n 'cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n },\n false: {},\n },\n disabled: {\n true: { root: 'opacity-50 cursor-not-allowed' },\n false: {},\n },\n },\n defaultVariants: {\n variant: 'outlined',\n direction: 'horizontal',\n flipped: false,\n interactive: true,\n disabled: false,\n },\n },\n { twMerge: true },\n);\n\n/**\n * Two-faced card with a CSS 3D-perspective flip animation.\n *\n * @remarks\n * **Hard theme dependency.** The flip animation is driven by helper classes\n * (`tw-flip-perspective`, `tw-flip-inner`, `tw-flip-face`, `tw-flip-back-face`,\n * `tw-flip-axis-x`, `tw-flip-axis-y`, `tw-flip-rotated`, `tw-flip-back-x`,\n * `tw-flip-back-y`) declared in `projects/ngx-tw/theme/_base.css` and re-exported\n * via `ngx-tw/theme/default.css`. Consumers MUST import the theme stylesheet —\n * without it the card renders as two stacked faces with no perspective and no\n * rotation, and there is no run-time fallback. `prefers-reduced-motion: reduce`\n * is handled in the theme CSS, not here.\n */\n@Component({\n selector: 'tw-flip-card',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'rootClasses()',\n '[attr.role]': 'hostRole()',\n '[attr.tabindex]': 'hostTabindex()',\n '[attr.aria-pressed]': 'ariaPressed()',\n '[attr.aria-live]': 'ariaLive()',\n '[attr.aria-disabled]': 'ariaDisabled()',\n '[attr.aria-label]': 'hostAriaLabel()',\n '(click)': 'onClick()',\n '(keydown)': 'onKeydown($event)',\n '(mouseenter)': 'onMouseEnter()',\n '(mouseleave)': 'onMouseLeave()',\n },\n template: `\n <div [class]=\"innerClasses()\">\n <div\n [class]=\"frontClasses()\"\n [attr.aria-hidden]=\"frontAriaHidden()\"\n [attr.inert]=\"frontInert()\"\n >\n <ng-content select=\"[slot='front']\" />\n </div>\n <div\n #backWrapper\n [class]=\"backClasses()\"\n [class.hidden]=\"!hasBack()\"\n [attr.aria-hidden]=\"backAriaHidden()\"\n [attr.inert]=\"backInert()\"\n >\n <ng-content select=\"[slot='back']\" />\n </div>\n </div>\n `,\n})\nexport class FlipCardComponent {\n /**\n * Visual style of the card chrome. Mirrors `tw-card`'s variant vocabulary.\n * Defaults to `'outlined'` (vs `tw-card`'s `'elevated'` default) so the flip\n * animation reads more clearly without a baseline shadow underneath.\n */\n readonly variant = input<FlipCardVariant>('outlined');\n\n /** Axis of rotation. `'horizontal'` rotates around the Y axis (left/right flip); `'vertical'` rotates around the X axis (top/bottom flip). Defaults to `'horizontal'`. */\n readonly direction = input<FlipCardDirection>('horizontal');\n\n /** Which user action flips the card. `'both'` enables click and hover. `'manual'` disables all triggers and defers control to the `flipped` model. Defaults to `'both'`. */\n readonly trigger = input<FlipCardTrigger>('both');\n\n /** When true, all triggers and keyboard handling are disabled; the current face stays visible. Defaults to `false`. */\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /** Whether the back face is currently visible. Two-way bindable via `[(flipped)]`. Defaults to `false`. The `flippedChange` event fires on every toggle. */\n readonly flipped = model(false);\n\n /**\n * Accessible name for the host element. Required when `trigger` is\n * `'manual'` (the host renders as `role=\"region\"`, which AXE requires to\n * have an accessible name); a default of `'Flip card'` is used in that\n * mode if no value is provided. In interactive modes the host's accessible\n * name is normally derived from the visible face's content — set this\n * input to override.\n */\n readonly ariaLabel = input<string | undefined>(undefined);\n\n private readonly liveAnnouncer = inject(LiveAnnouncer);\n private readonly destroyRef = inject(DestroyRef);\n private readonly backWrapper = viewChild<ElementRef<HTMLElement>>('backWrapper');\n\n private readonly _hasBack = signal(false);\n /** @internal */\n readonly hasBack = this._hasBack.asReadonly();\n\n /** @internal */\n readonly interactive = computed(\n () => this.trigger() !== 'manual' && !this.disabled() && this.hasBack(),\n );\n\n /** @internal */\n readonly hostRole = computed(() =>\n this.trigger() === 'manual' ? 'region' : 'button',\n );\n\n /** @internal */\n readonly hostTabindex = computed(() => (this.interactive() ? 0 : null));\n\n /** @internal */\n readonly ariaPressed = computed(() =>\n this.interactive() ? String(this.flipped()) : null,\n );\n\n /** @internal */\n readonly ariaLive = computed(() =>\n this.trigger() === 'manual' ? 'polite' : null,\n );\n\n /** @internal */\n readonly ariaDisabled = computed(() =>\n this.disabled() ? 'true' : null,\n );\n\n /** @internal */\n readonly hostAriaLabel = computed(() => {\n const explicit = this.ariaLabel();\n if (explicit !== undefined && explicit !== '') return explicit;\n return this.trigger() === 'manual' ? 'Flip card' : null;\n });\n\n /** @internal */\n readonly frontAriaHidden = computed(() =>\n this.hasBack() && this.flipped() ? 'true' : null,\n );\n\n /** @internal */\n readonly backAriaHidden = computed(() =>\n !this.hasBack() || !this.flipped() ? 'true' : null,\n );\n\n /** @internal */\n readonly frontInert = computed(() =>\n this.hasBack() && this.flipped() ? '' : null,\n );\n\n /** @internal */\n readonly backInert = computed(() =>\n !this.hasBack() || !this.flipped() ? '' : null,\n );\n\n private readonly variantResult = computed(() =>\n flipCardVariants({\n variant: this.variant(),\n direction: this.direction(),\n flipped: this.flipped(),\n interactive: this.interactive(),\n disabled: this.disabled(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly innerClasses = computed(() => this.variantResult().inner());\n readonly frontClasses = computed(\n () => `${this.variantResult().face()} ${this.variantResult().front()}`,\n );\n readonly backClasses = computed(\n () => `${this.variantResult().face()} ${this.variantResult().back()}`,\n );\n\n constructor() {\n // `MutationObserver` (not `contentChild`) because the spec exercises\n // *dynamic* projection toggled by an `@if` in the host template\n // (see `DynamicBackHost` in flip-card.spec.ts). `contentChild` resolves\n // the parent's own content children — it does NOT see elements projected\n // *through* the host via `<ng-content select=\"[slot='back']\" />`. The\n // observer is single-target and listens only for `childList` on the back\n // wrapper, so the cost is bounded and the disconnect runs on destroy.\n afterNextRender(() => {\n const el = this.backWrapper()?.nativeElement;\n if (!el) return;\n const update = () => this._hasBack.set(el.childElementCount > 0);\n update();\n const observer = new MutationObserver(update);\n observer.observe(el, { childList: true });\n this.destroyRef.onDestroy(() => observer.disconnect());\n });\n\n let firstRun = true;\n effect(() => {\n const isFlipped = this.flipped();\n if (firstRun) {\n firstRun = false;\n return;\n }\n // Announce in any mode that exposes a flippable back face. Manual mode\n // historically owned this because it sets `aria-live='polite'` on the\n // host; interactive modes (hover, click, both) still need an explicit\n // `LiveAnnouncer.announce` so screen-reader users hear the transition\n // when triggering the card via keyboard or pointer.\n if (this.hasBack()) {\n this.liveAnnouncer.announce(\n isFlipped ? 'Back face visible' : 'Front face visible',\n );\n }\n });\n }\n\n /** @internal */\n onClick(): void {\n if (this.disabled() || !this.hasBack()) return;\n const t = this.trigger();\n if (t === 'manual') return;\n this.toggle();\n }\n\n /** @internal */\n onKeydown(event: KeyboardEvent): void {\n if (!this.interactive()) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.toggle();\n }\n }\n\n /** @internal */\n onMouseEnter(): void {\n if (this.disabled() || !this.hasBack()) return;\n const t = this.trigger();\n if (t !== 'hover' && t !== 'both') return;\n this.setFlipped(true);\n }\n\n /** @internal */\n onMouseLeave(): void {\n if (this.disabled() || !this.hasBack()) return;\n const t = this.trigger();\n if (t !== 'hover' && t !== 'both') return;\n this.setFlipped(false);\n }\n\n private toggle(): void {\n this.setFlipped(!this.flipped());\n }\n\n private setFlipped(next: boolean): void {\n if (this.flipped() === next) return;\n this.flipped.set(next);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}