@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 @@
1
+ {"version":3,"file":"cdevhub-ngx-tw-slider.mjs","sources":["../../../projects/ngx-tw/slider/slider.ts","../../../projects/ngx-tw/slider/cdevhub-ngx-tw-slider.ts"],"sourcesContent":["/**\n * `tw-slider` — select a single value or a contiguous range from a numeric scale.\n *\n * Composition usecases:\n * - Single-value control bound via `[(value)]`.\n * - Range selector via `[range]=\"true\"` with a `[number, number]` value.\n * - Quantised scale via `[step]` and optional tick `[marks]`.\n * - Custom mark labels for semantic scales (temperature, volume, brightness).\n * - Forms: works with template-driven, reactive, and signal forms through `ControlValueAccessor`.\n */\nimport {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n inject,\n input,\n isDevMode,\n linkedSignal,\n model,\n type OnInit,\n output,\n signal,\n type Signal,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport {\n type ControlValueAccessor,\n FormGroupDirective,\n NgControl,\n NgForm,\n} from '@angular/forms';\nimport { FocusMonitor } from '@angular/cdk/a11y';\nimport { Directionality } from '@angular/cdk/bidi';\nimport { merge } from 'rxjs';\nimport { tv } from 'tailwind-variants';\nimport {\n type ErrorStateMatcher,\n TW_ERROR_STATE_MATCHER,\n type TwColor,\n type TwSize,\n type TwFormSubmitted,\n} from '@cdevhub/ngx-tw/core';\n\n/** Visual style of the slider fill. */\nexport type SliderVariant = 'solid' | 'soft' | 'outline';\n\n/** Value emitted by the slider. A plain number for single mode, or `[start, end]` for range mode. */\nexport type SliderValue = number | readonly [number, number];\n\n/** A tick mark on the slider scale. Optionally carries a display label. */\nexport interface SliderMark {\n /** Numeric position of the mark on the slider scale. Must be within `[min, max]`. */\n value: number;\n /** Optional label rendered beneath the mark when `showMarkLabels` is true. */\n label?: string;\n}\n\n/** Format function for the value displayed in the value bubble, min/max labels, and `aria-valuetext`. */\nexport type SliderValueFormatter = (value: number) => string;\n\n/** Identifies which thumb is the interaction target in range mode. */\ntype ThumbId = 'single' | 'start' | 'end';\n\n// ── Static color lookups (Tailwind v4 scans class strings statically) ──\n\nconst FILL_SOLID: Record<TwColor, string> = {\n primary: 'bg-primary-500',\n secondary: 'bg-secondary-500',\n accent: 'bg-accent-500',\n neutral: 'bg-fg',\n info: 'bg-info-500',\n success: 'bg-success-500',\n warning: 'bg-warning-500',\n error: 'bg-error-500',\n};\n\nconst FILL_SOFT: Record<TwColor, string> = {\n primary: 'bg-primary-300',\n secondary: 'bg-secondary-300',\n accent: 'bg-accent-300',\n neutral: 'bg-fg-muted',\n info: 'bg-info-300',\n success: 'bg-success-300',\n warning: 'bg-warning-300',\n error: 'bg-error-300',\n};\n\nconst FILL_OUTLINE_BORDER: Record<TwColor, string> = {\n primary: 'border-primary-500',\n secondary: 'border-secondary-500',\n accent: 'border-accent-500',\n neutral: 'border-fg',\n info: 'border-info-500',\n success: 'border-success-500',\n warning: 'border-warning-500',\n error: 'border-error-500',\n};\n\nconst THUMB_BORDER: Record<TwColor, string> = {\n primary: 'border-primary-500',\n secondary: 'border-secondary-500',\n accent: 'border-accent-500',\n neutral: 'border-fg',\n info: 'border-info-500',\n success: 'border-success-500',\n warning: 'border-warning-500',\n error: 'border-error-500',\n};\n\nconst FOCUS_RING: Record<TwColor, string> = {\n primary: 'focus-visible:outline-primary-500',\n secondary: 'focus-visible:outline-secondary-500',\n accent: 'focus-visible:outline-accent-500',\n neutral: 'focus-visible:outline-fg',\n info: 'focus-visible:outline-info-500',\n success: 'focus-visible:outline-success-500',\n warning: 'focus-visible:outline-warning-500',\n error: 'focus-visible:outline-error-500',\n};\n\n// ── tv() config ──────────────────────────────────────────────────\n\nconst sliderVariants = tv(\n {\n slots: {\n root: 'flex flex-col w-full select-none',\n header: 'flex items-center justify-between gap-3',\n label: 'text-sm font-medium text-fg empty:hidden',\n valueText: 'text-sm text-fg-muted font-medium tabular-nums',\n description: 'text-xs text-fg-muted empty:hidden',\n region: 'relative flex items-center touch-none',\n rail:\n 'relative w-full rounded-full bg-surface-muted transition-colors duration-normal motion-reduce:transition-none',\n fill:\n 'absolute inset-y-0 rounded-full transition-colors duration-normal motion-reduce:transition-none',\n marksRow: 'absolute inset-0 pointer-events-none',\n mark:\n 'absolute top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-surface transition-colors duration-normal motion-reduce:transition-none',\n markActive: '',\n thumb:\n 'absolute top-1/2 -translate-x-1/2 -translate-y-1/2 inline-flex items-center justify-center rounded-full border-2 bg-surface-raised shadow-sm cursor-grab active:cursor-grabbing touch-none focus-visible:outline-2 focus-visible:outline-offset-2 transition-[transform,box-shadow] duration-fast motion-reduce:transition-none hover:shadow-md data-[dragging=true]:shadow-md data-[dragging=true]:scale-110',\n bubble:\n 'absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-2 py-0.5 rounded-md bg-fg text-surface text-xs font-medium tabular-nums whitespace-nowrap pointer-events-none opacity-0 transition-opacity duration-fast motion-reduce:transition-none',\n bubbleVisible: 'opacity-100',\n markLabelsRow: 'relative w-full mt-2',\n markLabel:\n 'absolute top-0 -translate-x-1/2 text-xs text-fg-muted tabular-nums whitespace-nowrap',\n minMaxRow: 'flex items-center justify-between mt-2 text-xs text-fg-muted tabular-nums',\n },\n variants: {\n size: {\n // Thumb sizes follow the square-interactive scale (WCAG 2.2 SC 2.5.8 target-size).\n // Rail/mark/region adjust independently for proportional visual weight.\n xs: {\n rail: 'h-1',\n thumb: 'size-6',\n mark: 'size-2',\n region: 'h-6 py-1',\n },\n sm: {\n rail: 'h-1.5',\n thumb: 'size-7',\n mark: 'size-2.5',\n region: 'h-7 py-1',\n },\n md: {\n rail: 'h-2',\n thumb: 'size-8',\n mark: 'size-3',\n region: 'h-8 py-1.5',\n },\n lg: {\n rail: 'h-2.5',\n thumb: 'size-9',\n mark: 'size-3',\n region: 'h-9 py-2',\n },\n xl: {\n rail: 'h-3',\n thumb: 'size-10',\n mark: 'size-3',\n region: 'h-10 py-2',\n },\n },\n variant: {\n solid: {},\n soft: {},\n outline: {\n rail: 'border border-border bg-transparent',\n fill: 'border border-transparent',\n },\n },\n disabled: {\n true: { root: 'opacity-50 pointer-events-none' },\n false: { root: '' },\n },\n hasHeader: {\n true: { root: 'gap-2' },\n false: { root: 'gap-0' },\n },\n },\n defaultVariants: {\n size: 'md',\n variant: 'solid',\n disabled: false,\n hasHeader: false,\n },\n },\n { twMerge: true },\n);\n\nlet nextId = 0;\n\nconst DEFAULT_FORMATTER: SliderValueFormatter = (value) => {\n if (Number.isInteger(value)) return String(value);\n return String(Math.round(value * 100) / 100);\n};\n\nconst clamp = (value: number, lo: number, hi: number): number =>\n value < lo ? lo : value > hi ? hi : value;\n\nconst toRange = (value: SliderValue | null | undefined): [number, number] => {\n if (Array.isArray(value)) return [value[0], value[1]];\n return [0, typeof value === 'number' ? value : 0];\n};\n\nconst toNumber = (value: SliderValue | null | undefined, fallback: number): number => {\n if (Array.isArray(value)) return value[1];\n return typeof value === 'number' ? value : fallback;\n};\n\n/**\n * Select a single value or a numeric range from a scale.\n *\n * @example\n * ```html\n * <tw-slider [(value)]=\"volume\" [min]=\"0\" [max]=\"100\" [step]=\"5\" />\n * <tw-slider range [(value)]=\"priceRange\" [min]=\"0\" [max]=\"1000\" [step]=\"10\" showMinMax />\n * <tw-slider [marks]=\"true\" [step]=\"25\" showMarkLabels label=\"Brightness\" />\n * ```\n */\n@Component({\n selector: 'tw-slider',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (hasHeader()) {\n <div [class]=\"headerClasses()\">\n @if (label(); as lbl) {\n <span [id]=\"labelId\" [class]=\"labelClasses()\">{{ lbl }}</span>\n } @else {\n <span></span>\n }\n @if (showValue()) {\n <span [class]=\"valueTextClasses()\">{{ headerValueText() }}</span>\n }\n </div>\n }\n @if (description(); as desc) {\n <span [id]=\"descriptionId\" [class]=\"descriptionClasses()\">{{ desc }}</span>\n }\n\n <div\n #region\n [class]=\"regionClasses()\"\n (pointerdown)=\"onTrackPointerDown($event)\"\n >\n <div [class]=\"railClasses()\">\n <div\n [class]=\"fillClasses()\"\n [style.left.%]=\"fillLeftPct()\"\n [style.width.%]=\"fillWidthPct()\"\n ></div>\n\n @if (hasVisibleMarks()) {\n <div [class]=\"marksRowClasses()\">\n @for (m of resolvedMarks(); track m.value) {\n <span\n [class]=\"markClassFor(m.value)\"\n [style.left.%]=\"valuePct(m.value)\"\n ></span>\n }\n </div>\n }\n\n @if (range()) {\n <button\n type=\"button\"\n #startThumb\n [class]=\"thumbClasses()\"\n [style.left.%]=\"startPct()\"\n role=\"slider\"\n [id]=\"startThumbId\"\n [attr.aria-label]=\"resolvedStartAriaLabel()\"\n [attr.aria-labelledby]=\"resolvedStartAriaLabelledby()\"\n [attr.aria-describedby]=\"resolvedAriaDescribedby()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"effectiveStartMax()\"\n [attr.aria-valuenow]=\"startValue()\"\n [attr.aria-valuetext]=\"format(startValue())\"\n [attr.aria-orientation]=\"'horizontal'\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"errorState() || null\"\n [attr.data-dragging]=\"activeThumb() === 'start'\"\n [attr.tabindex]=\"isDisabled() ? -1 : 0\"\n (pointerdown)=\"onThumbPointerDown($event, 'start')\"\n (keydown)=\"onThumbKeyDown($event, 'start')\"\n (blur)=\"onThumbBlur()\"\n >\n <span\n aria-hidden=\"true\"\n [class]=\"bubbleClassFor('start')\"\n >{{ format(startValue()) }}</span>\n </button>\n <button\n type=\"button\"\n #endThumb\n [class]=\"thumbClasses()\"\n [style.left.%]=\"endPct()\"\n role=\"slider\"\n [id]=\"endThumbId\"\n [attr.aria-label]=\"resolvedEndAriaLabel()\"\n [attr.aria-labelledby]=\"resolvedEndAriaLabelledby()\"\n [attr.aria-describedby]=\"resolvedAriaDescribedby()\"\n [attr.aria-valuemin]=\"effectiveEndMin()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"endValue()\"\n [attr.aria-valuetext]=\"format(endValue())\"\n [attr.aria-orientation]=\"'horizontal'\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"errorState() || null\"\n [attr.data-dragging]=\"activeThumb() === 'end'\"\n [attr.tabindex]=\"isDisabled() ? -1 : 0\"\n (pointerdown)=\"onThumbPointerDown($event, 'end')\"\n (keydown)=\"onThumbKeyDown($event, 'end')\"\n (blur)=\"onThumbBlur()\"\n >\n <span\n aria-hidden=\"true\"\n [class]=\"bubbleClassFor('end')\"\n >{{ format(endValue()) }}</span>\n </button>\n } @else {\n <button\n type=\"button\"\n #singleThumb\n [class]=\"thumbClasses()\"\n [style.left.%]=\"singlePct()\"\n role=\"slider\"\n [id]=\"singleThumbId\"\n [attr.aria-label]=\"resolvedSingleAriaLabel()\"\n [attr.aria-labelledby]=\"resolvedSingleAriaLabelledby()\"\n [attr.aria-describedby]=\"resolvedAriaDescribedby()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"singleValue()\"\n [attr.aria-valuetext]=\"format(singleValue())\"\n [attr.aria-orientation]=\"'horizontal'\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"errorState() || null\"\n [attr.data-dragging]=\"activeThumb() === 'single'\"\n [attr.tabindex]=\"isDisabled() ? -1 : 0\"\n (pointerdown)=\"onThumbPointerDown($event, 'single')\"\n (keydown)=\"onThumbKeyDown($event, 'single')\"\n (blur)=\"onThumbBlur()\"\n >\n <span\n aria-hidden=\"true\"\n [class]=\"bubbleClassFor('single')\"\n >{{ format(singleValue()) }}</span>\n </button>\n }\n </div>\n </div>\n\n @if (hasMarkLabels()) {\n <div [class]=\"markLabelsRowClasses()\" aria-hidden=\"true\">\n @for (m of resolvedMarks(); track m.value) {\n <span [class]=\"markLabelClasses()\" [style.left.%]=\"valuePct(m.value)\">\n {{ m.label ?? format(m.value) }}\n </span>\n }\n </div>\n }\n\n @if (showMinMax()) {\n <div [class]=\"minMaxRowClasses()\" aria-hidden=\"true\">\n <span>{{ format(min()) }}</span>\n <span>{{ format(max()) }}</span>\n </div>\n }\n `,\n host: {\n '[class]': 'rootClasses()',\n '[attr.data-disabled]': 'isDisabled() || null',\n },\n})\nexport class SliderComponent implements ControlValueAccessor, OnInit {\n /** Lower bound of the slider scale. Defaults to `0`. */\n readonly min = input(0);\n\n /** Upper bound of the slider scale. Defaults to `100`. */\n readonly max = input(100);\n\n /** Step increment used for snapping, keyboard nav, and auto-generated marks. Pass `null` for continuous values. Defaults to `1`. */\n readonly step = input<number | null>(1);\n\n /** Semantic color for the filled portion and thumb border. Defaults to `'primary'`. */\n readonly color = input<TwColor>('primary');\n\n /** Overall scale of the rail, thumb, and typography. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Visual style of the fill: `'solid'` (vivid), `'soft'` (muted), or `'outline'` (rail bordered, fill color-500). Defaults to `'solid'`. */\n readonly variant = input<SliderVariant>('solid');\n\n /** When true, prevents interaction and applies muted styling. Defaults to `false`. */\n readonly disabled = input(false);\n\n /** When true, sets `aria-required=\"true\"` on the thumb for assistive tech. Defaults to `false`. */\n readonly required = input(false);\n\n /** When true, the slider selects a `[start, end]` range and renders two thumbs. Defaults to `false`. */\n readonly range = input(false);\n\n /** Tick marks: `true` auto-generates one mark per step, an array supplies custom marks, `false` renders no marks. Defaults to `false`. */\n readonly marks = input<SliderMark[] | boolean>(false);\n\n /** When true, renders the mark labels beneath the rail. Requires `marks` to resolve to a list. Defaults to `false`. */\n readonly showMarkLabels = input(false);\n\n /** When true, renders the min and max values at the ends of the scale. Defaults to `false`. */\n readonly showMinMax = input(false);\n\n /** When true, renders a value bubble above the active thumb (on hover/focus/drag) and the current value in the header. Defaults to `false`. */\n readonly showValue = input(false);\n\n /** Optional visible label rendered above the rail. When set, the slider is wired to the label via `aria-labelledby`. */\n readonly label = input<string | undefined>(undefined);\n\n /** Optional secondary description rendered under the label. Mirrored to `aria-describedby`. */\n readonly description = input<string | undefined>(undefined);\n\n /** Custom formatter for the value bubble, min/max labels, and `aria-valuetext`. Defaults to an integer or 2-decimal string. */\n readonly valueFormatter = input<SliderValueFormatter | undefined>(undefined);\n\n /** Optional form name attribute. Purely informational — the component does not render a native input. */\n readonly name = input<string | undefined>(undefined);\n\n /** Accessible name for the single-value thumb when no visible label is provided. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** ID of an external element labelling the single-value thumb. */\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n /** ID of an external element describing the slider. */\n readonly ariaDescribedby = input<string | undefined>(undefined, { alias: 'aria-describedby' });\n\n /** Accessible name for the start (lower) thumb in range mode. Defaults to `\"Minimum\"`. */\n readonly ariaLabelStart = input<string>('Minimum');\n\n /** Accessible name for the end (upper) thumb in range mode. Defaults to `\"Maximum\"`. */\n readonly ariaLabelEnd = input<string>('Maximum');\n\n /** Two-way bound slider value. A `number` for single mode, or `[start, end]` for range mode. Updates on every interaction. */\n readonly value = model<SliderValue>(0);\n\n /** Fires continuously while the user drags or holds a key. Payload matches the current `value`. Template event name is `input` — the TS-side identifier is `valueInput` to avoid shadowing the imported `input` factory. */\n readonly valueInput = output<SliderValue>({ alias: 'input' });\n\n /** Fires when the user commits a change (pointer release, key release, or blur after keyboard change). Payload matches the current `value`. */\n readonly change = output<SliderValue>();\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the component uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly destroyRef = inject(DestroyRef);\n private readonly directionality = inject(Directionality, { optional: true });\n private readonly ngControl = inject(NgControl, { optional: true, self: true });\n private readonly parentForm = inject(NgForm, { optional: true });\n private readonly parentFormGroup = inject(FormGroupDirective, { optional: true });\n private readonly defaultMatcher = inject(TW_ERROR_STATE_MATCHER);\n\n private readonly _ngControlRev = signal(0);\n private readonly _formSubmitRev = signal(0);\n\n /** Whether the form control is in an error state per the configured `ErrorStateMatcher`. */\n readonly errorState: Signal<boolean> = computed(() => {\n this._ngControlRev();\n this._formSubmitRev();\n // Read focus so blur-driven `touched` transitions repaint the error\n // border even when the underlying control's status/value didn't change.\n this.focusedThumb();\n const matcher = this.errorStateMatcher() ?? this.defaultMatcher;\n const form: TwFormSubmitted | null =\n (this.parentFormGroup as TwFormSubmitted | null) ??\n (this.parentForm as TwFormSubmitted | null);\n return matcher.isErrorState(this.ngControl?.control ?? null, form);\n });\n\n private readonly region = viewChild.required<ElementRef<HTMLElement>>('region');\n private readonly startThumb = viewChild<ElementRef<HTMLButtonElement>>('startThumb');\n private readonly endThumb = viewChild<ElementRef<HTMLButtonElement>>('endThumb');\n private readonly singleThumb = viewChild<ElementRef<HTMLButtonElement>>('singleThumb');\n\n private onChange: (value: SliderValue) => void = () => {};\n private onTouched: () => void = () => {};\n private readonly cvaDisabled = signal(false);\n\n /** @internal ID of the host element. */\n private readonly uid = nextId++;\n /** @internal */\n readonly labelId = `tw-slider-${this.uid}-label`;\n /** @internal */\n readonly descriptionId = `tw-slider-${this.uid}-description`;\n /** @internal */\n readonly singleThumbId = `tw-slider-${this.uid}-thumb`;\n /** @internal */\n readonly startThumbId = `tw-slider-${this.uid}-start`;\n /** @internal */\n readonly endThumbId = `tw-slider-${this.uid}-end`;\n\n /** @internal Internal values during drag / interaction, independent of external model. */\n private readonly internalStart = linkedSignal<number>(() => toRange(this.value())[0]);\n private readonly internalEnd = linkedSignal<number>(() => toRange(this.value())[1]);\n private readonly internalSingle = linkedSignal<number>(() => toNumber(this.value(), this.min()));\n\n /** @internal Which thumb currently has an active pointer gesture (or null). Bound in the template to drive the pressed-thumb styling. */\n readonly activeThumb = signal<ThumbId | null>(null);\n /** @internal Which thumb is focused (for bubble visibility). */\n private readonly focusedThumb = signal<ThumbId | null>(null);\n /** @internal Set of pointer IDs currently captured per-thumb for release tracking. */\n private readonly capturedPointers = new Map<number, { thumb: ThumbId; target: HTMLElement }>();\n /** @internal Tracks whether a keyboard interaction has mutated the value since last blur. */\n private keyboardDirty = false;\n\n constructor() {\n // Material-style CVA wiring: declare ourselves as the value accessor on any\n // host-level `NgControl` (FormControlDirective, NgModel, etc.). This avoids\n // the circular-DI that a static `NG_VALUE_ACCESSOR` provider would create\n // because `NgControl` is injected with `self: true` on the same element.\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n afterNextRender(() => {\n if (isDevMode() && !this.hasAccessibleName()) {\n console.warn(\n '[tw-slider] No accessible name provided. Supply a `label` input, `aria-label`, or `aria-labelledby`. In range mode, `ariaLabelStart` and `ariaLabelEnd` are used as fallbacks.',\n );\n }\n });\n }\n\n // ── Derived state ─────────────────────────────────────────\n\n /** @internal Effective disabled state (input OR set via CVA). */\n readonly isDisabled = computed(() => this.disabled() || this.cvaDisabled());\n\n /** @internal Whether a label/value header row should render. */\n readonly hasHeader = computed(() => !!this.label() || this.showValue());\n\n /** @internal Effective step: min 0 (continuous). */\n private readonly effectiveStep = computed(() => {\n const s = this.step();\n if (s === null || s === undefined) return 0;\n return Math.abs(s);\n });\n\n /** @internal Current scale range. */\n private readonly scaleRange = computed(() => {\n const lo = this.min();\n const hi = this.max();\n return hi > lo ? hi - lo : 0;\n });\n\n /** @internal Whether marks are resolved as a visible list. */\n private readonly marksResolved = computed<SliderMark[]>(() => {\n const source = this.marks();\n const lo = this.min();\n const hi = this.max();\n if (Array.isArray(source)) {\n return source.filter((m) => m.value >= lo && m.value <= hi);\n }\n if (source !== true) return [];\n const step = this.effectiveStep();\n if (step <= 0 || this.scaleRange() <= 0) return [];\n const out: SliderMark[] = [];\n for (let v = lo; v <= hi + 1e-9; v += step) {\n out.push({ value: Math.round(v * 1e6) / 1e6 });\n }\n return out;\n });\n\n /** @internal */\n readonly resolvedMarks = computed(() => this.marksResolved());\n /** @internal */\n readonly hasVisibleMarks = computed(() => this.marksResolved().length > 0);\n /** @internal */\n readonly hasMarkLabels = computed(\n () => this.showMarkLabels() && this.marksResolved().length > 0,\n );\n\n /** @internal Clamped current values. */\n readonly startValue = computed(() =>\n this.clampAndSnap(Math.min(this.internalStart(), this.internalEnd())),\n );\n /** @internal */\n readonly endValue = computed(() =>\n this.clampAndSnap(Math.max(this.internalStart(), this.internalEnd())),\n );\n /** @internal */\n readonly singleValue = computed(() => this.clampAndSnap(this.internalSingle()));\n\n /** @internal aria-valuemax for the start thumb (cannot cross end thumb). */\n readonly effectiveStartMax = computed(() => this.endValue());\n /** @internal aria-valuemin for the end thumb (cannot go below start thumb). */\n readonly effectiveEndMin = computed(() => this.startValue());\n\n /** @internal Percentage position of the single thumb on the rail. */\n readonly singlePct = computed(() => this.valuePct(this.singleValue()));\n /** @internal */\n readonly startPct = computed(() => this.valuePct(this.startValue()));\n /** @internal */\n readonly endPct = computed(() => this.valuePct(this.endValue()));\n\n /** @internal Fill segment position. */\n readonly fillLeftPct = computed(() => (this.range() ? this.startPct() : 0));\n /** @internal */\n readonly fillWidthPct = computed(() =>\n this.range() ? this.endPct() - this.startPct() : this.singlePct(),\n );\n\n /** @internal Formatted display of the current value for the header. */\n readonly headerValueText = computed(() => {\n if (this.range()) {\n return `${this.format(this.startValue())} – ${this.format(this.endValue())}`;\n }\n return this.format(this.singleValue());\n });\n\n // ── tv slot classes ─────────────────────────────────────────\n\n private readonly variantResult = computed(() =>\n sliderVariants({\n size: this.size(),\n variant: this.variant(),\n disabled: this.isDisabled(),\n hasHeader: this.hasHeader(),\n }),\n );\n\n /** @internal */\n readonly rootClasses = computed(() => this.variantResult().root());\n /** @internal */\n readonly headerClasses = computed(() => this.variantResult().header());\n /** @internal */\n readonly labelClasses = computed(() => this.variantResult().label());\n /** @internal */\n readonly valueTextClasses = computed(() => this.variantResult().valueText());\n /** @internal */\n readonly descriptionClasses = computed(() => this.variantResult().description());\n /** @internal */\n readonly regionClasses = computed(() => this.variantResult().region());\n /** @internal */\n readonly railClasses = computed(() => {\n const base = this.variantResult().rail();\n if (this.variant() === 'outline') return base;\n return base;\n });\n /** @internal */\n readonly fillClasses = computed(() => {\n const base = this.variantResult().fill();\n const variant = this.variant();\n const color = this.color();\n if (variant === 'soft') return `${base} ${FILL_SOFT[color]}`;\n if (variant === 'outline') {\n return `${base} ${FILL_SOLID[color]} ${FILL_OUTLINE_BORDER[color]}`;\n }\n return `${base} ${FILL_SOLID[color]}`;\n });\n /** @internal */\n readonly marksRowClasses = computed(() => this.variantResult().marksRow());\n /** @internal */\n readonly markLabelsRowClasses = computed(() => this.variantResult().markLabelsRow());\n /** @internal */\n readonly markLabelClasses = computed(() => this.variantResult().markLabel());\n /** @internal */\n readonly minMaxRowClasses = computed(() => this.variantResult().minMaxRow());\n /** @internal */\n readonly thumbClasses = computed(\n () => `${this.variantResult().thumb()} ${THUMB_BORDER[this.color()]} ${FOCUS_RING[this.color()]}`,\n );\n\n /**\n * @internal Memoized class map for mark dots — keyed by mark value. Recomputed\n * only when the variant slots, fill range, or marks list changes; lookups\n * from the template (`markClassFor(markValue)`) are O(1) Map reads.\n */\n private readonly markClassMap = computed(() => {\n const base = this.variantResult().mark();\n const lo = this.range() ? this.startValue() : this.min();\n const hi = this.range() ? this.endValue() : this.singleValue();\n const insideClass = `${base} bg-surface`;\n const outsideClass = `${base} bg-fg-muted/30`;\n const map = new Map<number, string>();\n for (const mark of this.marksResolved()) {\n const inside = mark.value >= lo && mark.value <= hi;\n map.set(mark.value, inside ? insideClass : outsideClass);\n }\n return { map, outsideClass };\n });\n\n /** @internal Mark dot color depends on whether it falls inside the filled segment. */\n markClassFor(markValue: number): string {\n const { map, outsideClass } = this.markClassMap();\n return map.get(markValue) ?? outsideClass;\n }\n\n /**\n * @internal Memoized bubble classes per thumb — enumerated once per\n * dependency change so each `bubbleClassFor(thumb)` is a single object\n * property read.\n */\n private readonly bubbleClassMap = computed<Record<ThumbId, string>>(() => {\n const base = this.variantResult().bubble();\n if (!this.showValue()) {\n return { single: base, start: base, end: base };\n }\n const visibleClass = `${base} ${this.variantResult().bubbleVisible()}`;\n const active = this.activeThumb();\n const focused = this.focusedThumb();\n const classFor = (thumb: ThumbId): string =>\n active === thumb || focused === thumb ? visibleClass : base;\n return {\n single: classFor('single'),\n start: classFor('start'),\n end: classFor('end'),\n };\n });\n\n /** @internal Bubble visibility depends on drag / focus / hover state. */\n bubbleClassFor(thumb: ThumbId): string {\n return this.bubbleClassMap()[thumb];\n }\n\n // ── Accessible-name resolution ─────────────────────────────\n\n /** @internal */\n readonly resolvedAriaDescribedby = computed(() => {\n const external = this.ariaDescribedby();\n if (external) return external;\n return this.description() ? this.descriptionId : null;\n });\n\n /** @internal */\n readonly resolvedSingleAriaLabel = computed(() => {\n if (this.label()) return null;\n if (this.ariaLabelledby()) return null;\n return this.ariaLabel() ?? null;\n });\n /** @internal */\n readonly resolvedSingleAriaLabelledby = computed(() => {\n if (this.label()) return this.labelId;\n return this.ariaLabelledby() ?? null;\n });\n\n /** @internal */\n readonly resolvedStartAriaLabel = computed(() => {\n if (this.ariaLabelledby() || this.label()) return null;\n return this.ariaLabelStart();\n });\n /** @internal */\n readonly resolvedStartAriaLabelledby = computed(() => {\n if (this.ariaLabelledby()) return this.ariaLabelledby() ?? null;\n return this.label() ? this.labelId : null;\n });\n /** @internal */\n readonly resolvedEndAriaLabel = computed(() => {\n if (this.ariaLabelledby() || this.label()) return null;\n return this.ariaLabelEnd();\n });\n /** @internal */\n readonly resolvedEndAriaLabelledby = computed(() => {\n if (this.ariaLabelledby()) return this.ariaLabelledby() ?? null;\n return this.label() ? this.labelId : null;\n });\n\n // ── Interactions ───────────────────────────────────────────\n\n /** Track click: move the nearest thumb to the clicked position and begin a drag. */\n onTrackPointerDown(event: PointerEvent): void {\n if (this.isDisabled()) return;\n if (event.button !== 0 && event.pointerType === 'mouse') return;\n // Ignore presses that started on a thumb — its own handler runs.\n const target = event.target as HTMLElement | null;\n if (target?.closest('[role=\"slider\"]')) return;\n\n const nearest = this.nearestThumbFor(event.clientX);\n const thumbEl = this.thumbElementFor(nearest);\n if (!thumbEl) return;\n thumbEl.focus();\n this.updateValueFromClientX(nearest, event.clientX, true);\n this.beginDrag(nearest, thumbEl, event);\n }\n\n /** Thumb press: capture pointer and begin a drag gesture. */\n onThumbPointerDown(event: PointerEvent, thumb: ThumbId): void {\n if (this.isDisabled()) return;\n if (event.button !== 0 && event.pointerType === 'mouse') return;\n const target = event.currentTarget as HTMLButtonElement;\n target.focus();\n this.beginDrag(thumb, target, event);\n }\n\n private beginDrag(thumb: ThumbId, thumbEl: HTMLElement, event: PointerEvent): void {\n event.preventDefault();\n try {\n thumbEl.setPointerCapture(event.pointerId);\n } catch {\n // setPointerCapture can throw in some synthetic test environments — degrade gracefully.\n }\n this.activeThumb.set(thumb);\n this.capturedPointers.set(event.pointerId, { thumb, target: thumbEl });\n thumbEl.addEventListener('pointermove', this.onPointerMove);\n thumbEl.addEventListener('pointerup', this.onPointerUp);\n thumbEl.addEventListener('pointercancel', this.onPointerUp);\n }\n\n private readonly onPointerMove = (event: PointerEvent): void => {\n const entry = this.capturedPointers.get(event.pointerId);\n if (!entry) return;\n this.updateValueFromClientX(entry.thumb, event.clientX, false);\n };\n\n private readonly onPointerUp = (event: PointerEvent): void => {\n const entry = this.capturedPointers.get(event.pointerId);\n if (!entry) return;\n const { target } = entry;\n try {\n target.releasePointerCapture(event.pointerId);\n } catch {\n // noop\n }\n target.removeEventListener('pointermove', this.onPointerMove);\n target.removeEventListener('pointerup', this.onPointerUp);\n target.removeEventListener('pointercancel', this.onPointerUp);\n this.capturedPointers.delete(event.pointerId);\n if (this.capturedPointers.size === 0) {\n this.activeThumb.set(null);\n }\n this.commitValue();\n };\n\n /** Keyboard navigation: arrows for step, PageUp/Down for 10% jumps, Home/End for extremes. */\n onThumbKeyDown(event: KeyboardEvent, thumb: ThumbId): void {\n if (this.isDisabled()) return;\n const rtl = this.directionality?.value === 'rtl';\n const range = this.scaleRange();\n const step = this.effectiveStep() || range / 100 || 1;\n const bigStep = range > 0 ? range / 10 : step * 10;\n\n let delta = 0;\n let jumpTo: number | null = null;\n\n switch (event.key) {\n case 'ArrowRight':\n delta = rtl ? -step : step;\n break;\n case 'ArrowUp':\n delta = step;\n break;\n case 'ArrowLeft':\n delta = rtl ? step : -step;\n break;\n case 'ArrowDown':\n delta = -step;\n break;\n case 'PageUp':\n delta = bigStep;\n break;\n case 'PageDown':\n delta = -bigStep;\n break;\n case 'Home':\n jumpTo = this.min();\n break;\n case 'End':\n jumpTo = this.max();\n break;\n default:\n return;\n }\n\n event.preventDefault();\n const current = this.getThumbValue(thumb);\n const next = jumpTo !== null ? jumpTo : current + delta;\n this.setThumbValue(thumb, next, /* emitInput */ true);\n this.commitValue();\n this.keyboardDirty = true;\n }\n\n /** @internal */\n onThumbBlur(): void {\n this.focusedThumb.set(null);\n if (this.keyboardDirty) {\n this.keyboardDirty = false;\n this.onTouched();\n } else {\n this.onTouched();\n }\n }\n\n // ── Value math ─────────────────────────────────────────────\n\n /** @internal Clamp to min/max and snap to step. Returns a finite number. */\n private clampAndSnap(raw: number): number {\n if (!Number.isFinite(raw)) return this.min();\n const lo = this.min();\n const hi = this.max();\n const bounded = clamp(raw, lo, hi);\n const step = this.effectiveStep();\n if (step <= 0) return bounded;\n const snapped = Math.round((bounded - lo) / step) * step + lo;\n // Protect against floating-point drift that pushes values just past max.\n return clamp(snapped, lo, hi);\n }\n\n /** @internal Percent of value along the scale, in [0, 100]. */\n valuePct(value: number): number {\n const range = this.scaleRange();\n if (range <= 0) return 0;\n return ((value - this.min()) / range) * 100;\n }\n\n /** @internal Format a single number using the configured formatter. */\n format(value: number): string {\n const fmt = this.valueFormatter() ?? DEFAULT_FORMATTER;\n return fmt(value);\n }\n\n private getThumbValue(thumb: ThumbId): number {\n if (thumb === 'start') return this.startValue();\n if (thumb === 'end') return this.endValue();\n return this.singleValue();\n }\n\n private setThumbValue(thumb: ThumbId, raw: number, emitInput: boolean): void {\n const snapped = this.clampAndSnap(raw);\n if (thumb === 'single') {\n if (snapped === this.internalSingle()) return;\n this.internalSingle.set(snapped);\n } else if (thumb === 'start') {\n const clamped = Math.min(snapped, this.internalEnd());\n if (clamped === this.internalStart()) return;\n this.internalStart.set(clamped);\n } else {\n const clamped = Math.max(snapped, this.internalStart());\n if (clamped === this.internalEnd()) return;\n this.internalEnd.set(clamped);\n }\n const current = this.currentValue();\n this.value.set(current);\n if (emitInput) this.valueInput.emit(current);\n }\n\n private updateValueFromClientX(\n thumb: ThumbId,\n clientX: number,\n focusThumb: boolean,\n ): void {\n const regionEl = this.region().nativeElement;\n const rect = regionEl.getBoundingClientRect();\n if (rect.width <= 0) return;\n const rtl = this.directionality?.value === 'rtl';\n const ratio = (clientX - rect.left) / rect.width;\n const pct = clamp(rtl ? 1 - ratio : ratio, 0, 1);\n const raw = this.min() + pct * this.scaleRange();\n this.setThumbValue(thumb, raw, true);\n if (focusThumb) {\n const thumbEl = this.thumbElementFor(thumb);\n thumbEl?.focus();\n }\n }\n\n private thumbElementFor(thumb: ThumbId): HTMLButtonElement | undefined {\n if (thumb === 'single') return this.singleThumb()?.nativeElement;\n if (thumb === 'start') return this.startThumb()?.nativeElement;\n return this.endThumb()?.nativeElement;\n }\n\n private nearestThumbFor(clientX: number): ThumbId {\n if (!this.range()) return 'single';\n const regionEl = this.region().nativeElement;\n const rect = regionEl.getBoundingClientRect();\n if (rect.width <= 0) return 'start';\n const rtl = this.directionality?.value === 'rtl';\n const ratio = (clientX - rect.left) / rect.width;\n const pct = clamp(rtl ? 1 - ratio : ratio, 0, 1);\n const target = this.min() + pct * this.scaleRange();\n const distStart = Math.abs(target - this.startValue());\n const distEnd = Math.abs(target - this.endValue());\n if (distStart === distEnd) {\n // Prefer the end thumb when to the right of the fill, start otherwise.\n return target >= this.endValue() ? 'end' : 'start';\n }\n return distStart < distEnd ? 'start' : 'end';\n }\n\n private currentValue(): SliderValue {\n if (this.range()) return [this.startValue(), this.endValue()] as const;\n return this.singleValue();\n }\n\n private commitValue(): void {\n const current = this.currentValue();\n this.value.set(current);\n this.onChange(current);\n this.change.emit(current);\n }\n\n private hasAccessibleName(): boolean {\n if (this.label() || this.ariaLabel() || this.ariaLabelledby()) return true;\n // In range mode, explicit per-thumb labels default to Minimum/Maximum.\n return this.range();\n }\n\n // ── ControlValueAccessor ──────────────────────────────────\n\n writeValue(value: SliderValue | null | undefined): void {\n if (value === null || value === undefined) {\n this.internalSingle.set(this.clampAndSnap(this.min()));\n this.internalStart.set(this.clampAndSnap(this.min()));\n this.internalEnd.set(this.clampAndSnap(this.max()));\n return;\n }\n if (Array.isArray(value)) {\n const [start, end] = value as readonly [number, number];\n this.internalStart.set(this.clampAndSnap(start));\n this.internalEnd.set(this.clampAndSnap(end));\n } else {\n this.internalSingle.set(this.clampAndSnap(value as number));\n }\n }\n\n registerOnChange(fn: (value: SliderValue) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n // ── Lifecycle ─────────────────────────────────────────────\n\n ngOnInit(): void {\n this.focusMonitor\n .monitor(this.elementRef, true)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((origin) => {\n if (origin === null) {\n this.focusedThumb.set(null);\n return;\n }\n const active = this.elementRef.nativeElement.ownerDocument?.activeElement;\n if (!active) return;\n if (active === this.singleThumb()?.nativeElement) this.focusedThumb.set('single');\n else if (active === this.startThumb()?.nativeElement) this.focusedThumb.set('start');\n else if (active === this.endThumb()?.nativeElement) this.focusedThumb.set('end');\n else this.focusedThumb.set(null);\n });\n\n // Re-run the error-state matcher when the bound control's status/value\n // changes or the parent form is submitted. `ngOnInit` is the natural\n // mount point — by here, the parent `FormControl*` directive's\n // `ngOnChanges` has already populated `ngControl.control`.\n const ctrl = this.ngControl?.control;\n if (ctrl) {\n const streams = [ctrl.statusChanges, ctrl.valueChanges].filter(\n (s): s is NonNullable<typeof s> => !!s,\n );\n if (streams.length) {\n merge(...streams)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._ngControlRev.update((v) => v + 1));\n }\n }\n\n const submit = this.parentFormGroup?.ngSubmit ?? this.parentForm?.ngSubmit;\n if (submit) {\n submit\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._formSubmitRev.update((v) => v + 1));\n }\n\n this.destroyRef.onDestroy(() => {\n this.focusMonitor.stopMonitoring(this.elementRef);\n for (const { target } of this.capturedPointers.values()) {\n target.removeEventListener('pointermove', this.onPointerMove);\n target.removeEventListener('pointerup', this.onPointerUp);\n target.removeEventListener('pointercancel', this.onPointerUp);\n }\n this.capturedPointers.clear();\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,346 @@
1
+ import * as i0 from '@angular/core';
2
+ import { model, input, output, isDevMode, Directive, inject, viewChild, effect, computed, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { TW_SORT_HANDLE } from '@cdevhub/ngx-tw/core';
4
+ import { NgTemplateOutlet } from '@angular/common';
5
+ import { FocusMonitor, AriaDescriber } from '@angular/cdk/a11y';
6
+ import { tv } from 'tailwind-variants';
7
+
8
+ /**
9
+ * Returns the direction cycle for a given starting direction and disable-clear flag.
10
+ * @internal Exported for unit tests; not part of the public API.
11
+ */
12
+ function getSortDirectionCycle(start, disableClear) {
13
+ const cycle = start === 'desc' ? ['desc', 'asc'] : ['asc', 'desc'];
14
+ if (!disableClear)
15
+ cycle.push(null);
16
+ return cycle;
17
+ }
18
+ /**
19
+ * Container directive that holds the current sort state (`active` id + `direction`) and
20
+ * coordinates with child `SortHeaderComponent` instances. Compose with any rendering layer —
21
+ * tables, lists, custom grids — by placing child headers inside an element marked `[twSort]`.
22
+ *
23
+ * @remarks
24
+ * **`tw*` input/output aliases.** Every `input()` / `output()` / `model()` on this directive
25
+ * carries a `tw*` alias (e.g. `'twSortActive'`, `'twSortDirection'`, `'twSortChange'`). The
26
+ * aliases namespace bindings under the directive selector so they cannot collide with
27
+ * attributes the host element already owns (a `<table>` consumer binding `[active]` would
28
+ * otherwise be ambiguous). This mirrors Angular Material's `mat*` aliasing precedent on
29
+ * `MatSort`. Compodoc surfaces both the field name and the alias; consumer templates MUST
30
+ * bind via the aliased name (`[twSortActive]`, `(twSortChange)`, …). Removing an alias is a
31
+ * breaking API change requiring a major version bump.
32
+ */
33
+ class SortDirective {
34
+ /** The id of the currently sorted header, or `null` when nothing is sorted. Two-way bindable via `[(twSortActive)]`. Defaults to `null`. */
35
+ active = model(null, { ...(ngDevMode ? { debugName: "active" } : /* istanbul ignore next */ {}), alias: 'twSortActive' });
36
+ /** Current sort direction. `null` represents the cleared state. Two-way bindable via `[(twSortDirection)]`. Defaults to `null`. */
37
+ direction = model(null, { ...(ngDevMode ? { debugName: "direction" } : /* istanbul ignore next */ {}), alias: 'twSortDirection' });
38
+ /** Starting direction used when a header becomes active for the first time. Per-header `start` overrides this. Defaults to `'asc'`. */
39
+ start = input('asc', { ...(ngDevMode ? { debugName: "start" } : /* istanbul ignore next */ {}), alias: 'twSortStart' });
40
+ /** When true, the direction cycle skips the cleared (`null`) state — headers toggle between `'asc'` and `'desc'` only. Per-header `disableClear` overrides this. Defaults to `false`. */
41
+ disableClear = input(false, { ...(ngDevMode ? { debugName: "disableClear" } : /* istanbul ignore next */ {}), alias: 'twSortDisableClear' });
42
+ /** When true, all child sort headers are disabled. Defaults to `false`. */
43
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), alias: 'twSortDisabled' });
44
+ /** Fires whenever the user changes `active` or `direction` by interacting with a header. Programmatic writes to `[(twSortActive)]` / `[(twSortDirection)]` do NOT emit. */
45
+ sortChange = output({ alias: 'twSortChange' });
46
+ sortableIds = new Set();
47
+ /** Registers a header id so duplicates can be detected. Called by `SortHeaderComponent` on init. Throws in dev mode if another header with the same id is already registered. */
48
+ register(id) {
49
+ if (isDevMode()) {
50
+ if (!id) {
51
+ throw new Error('tw-sort-header must be provided with a unique id.');
52
+ }
53
+ if (this.sortableIds.has(id)) {
54
+ throw new Error(`Cannot have two tw-sort-header elements with the same id (${id}).`);
55
+ }
56
+ }
57
+ this.sortableIds.add(id);
58
+ }
59
+ /** Deregisters a header id. Called on destroy. */
60
+ deregister(id) {
61
+ this.sortableIds.delete(id);
62
+ }
63
+ /** Cycles the direction for the given header and emits `sortChange`. No-op when the directive or the header is disabled. */
64
+ sort(sortable) {
65
+ if (this.disabled() || sortable.disabled)
66
+ return;
67
+ const previousActive = this.active();
68
+ const previousDirection = this.direction();
69
+ let nextActive;
70
+ let nextDirection;
71
+ if (previousActive !== sortable.id) {
72
+ nextActive = sortable.id;
73
+ nextDirection = sortable.start ?? this.start();
74
+ }
75
+ else {
76
+ nextDirection = this.getNextSortDirection(sortable);
77
+ nextActive = nextDirection === null ? null : sortable.id;
78
+ }
79
+ this.active.set(nextActive);
80
+ this.direction.set(nextDirection);
81
+ this.sortChange.emit({
82
+ active: nextActive,
83
+ direction: nextDirection,
84
+ previous: {
85
+ active: previousActive,
86
+ direction: previousDirection,
87
+ },
88
+ });
89
+ }
90
+ /** Returns the next direction in the cycle for the given header, based on the current state and header/parent overrides. */
91
+ getNextSortDirection(sortable) {
92
+ const start = sortable.start ?? this.start();
93
+ const disableClear = sortable.disableClear ?? this.disableClear();
94
+ const cycle = getSortDirectionCycle(start, disableClear);
95
+ // If the header is not currently active, the next direction is the starting one.
96
+ if (this.active() !== sortable.id) {
97
+ return start;
98
+ }
99
+ const currentIndex = cycle.indexOf(this.direction());
100
+ if (currentIndex < 0) {
101
+ return start;
102
+ }
103
+ return cycle[(currentIndex + 1) % cycle.length];
104
+ }
105
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SortDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
106
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: SortDirective, isStandalone: true, selector: "[twSort]", inputs: { active: { classPropertyName: "active", publicName: "twSortActive", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "twSortDirection", isSignal: true, isRequired: false, transformFunction: null }, start: { classPropertyName: "start", publicName: "twSortStart", isSignal: true, isRequired: false, transformFunction: null }, disableClear: { classPropertyName: "disableClear", publicName: "twSortDisableClear", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "twSortDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { active: "twSortActiveChange", direction: "twSortDirectionChange", sortChange: "twSortChange" }, host: { classAttribute: "tw-sort" }, providers: [{ provide: TW_SORT_HANDLE, useExisting: SortDirective }], exportAs: ["twSort"], ngImport: i0 });
107
+ }
108
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SortDirective, decorators: [{
109
+ type: Directive,
110
+ args: [{
111
+ selector: '[twSort]',
112
+ exportAs: 'twSort',
113
+ host: {
114
+ 'class': 'tw-sort',
115
+ },
116
+ providers: [{ provide: TW_SORT_HANDLE, useExisting: SortDirective }],
117
+ }]
118
+ }], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "twSortActive", required: false }] }, { type: i0.Output, args: ["twSortActiveChange"] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "twSortDirection", required: false }] }, { type: i0.Output, args: ["twSortDirectionChange"] }], start: [{ type: i0.Input, args: [{ isSignal: true, alias: "twSortStart", required: false }] }], disableClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "twSortDisableClear", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "twSortDisabled", required: false }] }], sortChange: [{ type: i0.Output, args: ["twSortChange"] }] } });
119
+
120
+ function snapshot(self) {
121
+ return {
122
+ id: self.id(),
123
+ start: self.start(),
124
+ disableClear: self.disableClear(),
125
+ disabled: self.isDisabled(),
126
+ };
127
+ }
128
+ // ── Static per-color maps (Tailwind v4 requires literal class strings for its JIT scanner). ──
129
+ const ARROW_ACTIVE_COLOR = {
130
+ primary: 'text-primary-600',
131
+ secondary: 'text-secondary-600',
132
+ accent: 'text-accent-600',
133
+ neutral: 'text-fg',
134
+ info: 'text-info-600',
135
+ success: 'text-success-600',
136
+ warning: 'text-warning-600',
137
+ error: 'text-error-600',
138
+ };
139
+ // ── tv() config ──
140
+ const sortHeaderVariants = tv({
141
+ slots: {
142
+ host: 'group select-none',
143
+ container: 'inline-flex items-center gap-1.5 cursor-pointer rounded-md font-medium text-fg transition-colors duration-normal motion-reduce:transition-none hover:bg-surface-muted focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',
144
+ label: 'min-w-0',
145
+ arrow: 'inline-flex shrink-0 items-center justify-center transition-opacity duration-normal motion-reduce:transition-none',
146
+ arrowIcon: 'shrink-0 transition-transform duration-normal motion-reduce:transition-none',
147
+ },
148
+ variants: {
149
+ size: {
150
+ xs: {
151
+ container: 'px-2 py-1 text-xs',
152
+ // `size-3.5` half-step: only icon size aligning with text-xs without
153
+ // dominating it; codified per CLAUDE.md.
154
+ arrowIcon: 'size-3.5',
155
+ },
156
+ sm: {
157
+ container: 'px-2.5 py-1.5 text-sm',
158
+ arrowIcon: 'size-4',
159
+ },
160
+ md: {
161
+ container: 'px-3 py-2 text-sm',
162
+ arrowIcon: 'size-4',
163
+ },
164
+ lg: {
165
+ container: 'px-4 py-2.5 text-base',
166
+ arrowIcon: 'size-5',
167
+ },
168
+ xl: {
169
+ container: 'px-5 py-3 text-base',
170
+ arrowIcon: 'size-5',
171
+ },
172
+ },
173
+ active: {
174
+ true: {
175
+ container: 'text-fg',
176
+ arrow: 'opacity-100',
177
+ },
178
+ false: {
179
+ container: 'text-fg-muted',
180
+ arrow: 'opacity-0 group-hover:opacity-50 group-focus-within:opacity-50',
181
+ },
182
+ },
183
+ direction: {
184
+ asc: { arrowIcon: 'rotate-180' },
185
+ desc: { arrowIcon: 'rotate-0' },
186
+ none: { arrowIcon: 'rotate-0' },
187
+ },
188
+ disabled: {
189
+ true: {
190
+ host: 'opacity-50 pointer-events-none',
191
+ container: 'cursor-not-allowed',
192
+ },
193
+ false: {},
194
+ },
195
+ },
196
+ defaultVariants: {
197
+ size: 'md',
198
+ active: false,
199
+ direction: 'none',
200
+ disabled: false,
201
+ },
202
+ }, { twMerge: true });
203
+ /**
204
+ * Turns any element (e.g., `<th>`, `<div>`, `<button>`) into a sortable header under a parent
205
+ * `SortDirective`. Renders the projected label plus an arrow that reflects the current direction.
206
+ * Triggers a sort cycle on click or Enter/Space.
207
+ */
208
+ class SortHeaderComponent {
209
+ /** Unique id for this header. Required — identifies the field/column this header sorts. */
210
+ id = input.required(...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
211
+ /** Overrides the parent directive's `start` for this header only. `undefined` inherits from the parent. */
212
+ start = input(undefined, ...(ngDevMode ? [{ debugName: "start" }] : /* istanbul ignore next */ []));
213
+ /** Overrides the parent directive's `disableClear` for this header only. `undefined` inherits from the parent. */
214
+ disableClear = input(undefined, ...(ngDevMode ? [{ debugName: "disableClear" }] : /* istanbul ignore next */ []));
215
+ /** When true, this header is disabled — clicks and keyboard activation are ignored. Defaults to `false`. */
216
+ headerDisabled = input(false, { ...(ngDevMode ? { debugName: "headerDisabled" } : /* istanbul ignore next */ {}), alias: 'disabled' });
217
+ /** Whether the sort arrow renders `'before'` or `'after'` the projected label. Defaults to `'after'`. */
218
+ arrowPosition = input('after', ...(ngDevMode ? [{ debugName: "arrowPosition" }] : /* istanbul ignore next */ []));
219
+ /** Semantic color used to tint the arrow when this header is active. Defaults to `'primary'`. */
220
+ color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
221
+ /** Controls padding and font size. Uses the shared `TwSize` scale. Defaults to `'md'`. */
222
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
223
+ /** Accessible description applied via `AriaDescriber` so screen readers announce the sort action alongside the header text. Defaults to `'Sort'`. */
224
+ sortActionDescription = input('Sort', ...(ngDevMode ? [{ debugName: "sortActionDescription" }] : /* istanbul ignore next */ []));
225
+ parent = inject(SortDirective, { optional: true });
226
+ focusMonitor = inject(FocusMonitor);
227
+ ariaDescriber = inject(AriaDescriber, { optional: true });
228
+ containerRef = viewChild('container', ...(ngDevMode ? [{ debugName: "containerRef" }] : /* istanbul ignore next */ []));
229
+ _describedBy = null;
230
+ constructor() {
231
+ if (!this.parent && isDevMode()) {
232
+ throw new Error('tw-sort-header must be placed within a parent element with the twSort directive.');
233
+ }
234
+ // Reactive: re-tags the host whenever `sortActionDescription` (a public
235
+ // signal input) changes; consumers may swap the description at runtime for
236
+ // i18n / state-driven copy. Cleanup runs in `ngOnDestroy`. Not a one-shot
237
+ // `afterNextRender`: that would freeze the description at first render and
238
+ // silently ignore subsequent rebinds.
239
+ effect(() => {
240
+ const description = this.sortActionDescription();
241
+ const el = this.containerRef()?.nativeElement;
242
+ if (!el || !this.ariaDescriber)
243
+ return;
244
+ if (this._describedBy) {
245
+ this.ariaDescriber.removeDescription(el, this._describedBy);
246
+ }
247
+ this.ariaDescriber.describe(el, description);
248
+ this._describedBy = description;
249
+ });
250
+ }
251
+ // ── Derived signals ──
252
+ /** Whether this header is currently the active (sorted) header. */
253
+ isActive = computed(() => this.parent?.active() === this.id(), ...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []));
254
+ /** Whether this header is disabled via its own input or the parent directive's `disabled`. */
255
+ isDisabled = computed(() => this.headerDisabled() || (this.parent?.disabled() ?? false), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
256
+ /** Active direction for *this* header (null when not active). */
257
+ effectiveDirection = computed(() => this.isActive() ? (this.parent?.direction() ?? null) : null, ...(ngDevMode ? [{ debugName: "effectiveDirection" }] : /* istanbul ignore next */ []));
258
+ /** `aria-sort` value: `'ascending' | 'descending' | 'none'`. */
259
+ ariaSort = computed(() => {
260
+ const d = this.effectiveDirection();
261
+ if (d === 'asc')
262
+ return 'ascending';
263
+ if (d === 'desc')
264
+ return 'descending';
265
+ return 'none';
266
+ }, ...(ngDevMode ? [{ debugName: "ariaSort" }] : /* istanbul ignore next */ []));
267
+ /** Whether the arrow element should render. Active headers always render; inactive render when not disabled so hover reveals the affordance. */
268
+ renderArrow = computed(() => this.isActive() || !this.isDisabled(), ...(ngDevMode ? [{ debugName: "renderArrow" }] : /* istanbul ignore next */ []));
269
+ // ── Variant class computation ──
270
+ variantResult = computed(() => sortHeaderVariants({
271
+ size: this.size(),
272
+ active: this.isActive(),
273
+ direction: this.effectiveDirection() ?? 'none',
274
+ disabled: this.isDisabled(),
275
+ }), ...(ngDevMode ? [{ debugName: "variantResult" }] : /* istanbul ignore next */ []));
276
+ /** @internal */
277
+ hostClasses = computed(() => this.variantResult().host(), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
278
+ /** @internal */
279
+ containerClasses = computed(() => this.variantResult().container(), ...(ngDevMode ? [{ debugName: "containerClasses" }] : /* istanbul ignore next */ []));
280
+ /** @internal */
281
+ labelClasses = computed(() => this.variantResult().label(), ...(ngDevMode ? [{ debugName: "labelClasses" }] : /* istanbul ignore next */ []));
282
+ /** @internal */
283
+ arrowClasses = computed(() => {
284
+ const base = this.variantResult().arrow();
285
+ if (!this.isActive())
286
+ return base;
287
+ return `${base} ${ARROW_ACTIVE_COLOR[this.color()]}`;
288
+ }, ...(ngDevMode ? [{ debugName: "arrowClasses" }] : /* istanbul ignore next */ []));
289
+ /** @internal */
290
+ arrowIconClasses = computed(() => this.variantResult().arrowIcon(), ...(ngDevMode ? [{ debugName: "arrowIconClasses" }] : /* istanbul ignore next */ []));
291
+ // ── Lifecycle ──
292
+ ngOnInit() {
293
+ this.parent?.register(this.id());
294
+ }
295
+ ngAfterViewInit() {
296
+ const el = this.containerRef()?.nativeElement;
297
+ if (el) {
298
+ this.focusMonitor.monitor(el, true);
299
+ }
300
+ }
301
+ ngOnDestroy() {
302
+ const el = this.containerRef()?.nativeElement;
303
+ if (el) {
304
+ this.focusMonitor.stopMonitoring(el);
305
+ if (this._describedBy && this.ariaDescriber) {
306
+ this.ariaDescriber.removeDescription(el, this._describedBy);
307
+ }
308
+ }
309
+ this.parent?.deregister(this.id());
310
+ }
311
+ // ── Event handlers ──
312
+ /** @internal */
313
+ handleClick() {
314
+ if (this.isDisabled())
315
+ return;
316
+ this.parent?.sort(snapshot(this));
317
+ }
318
+ /** @internal */
319
+ handleKeydown(event) {
320
+ if (this.isDisabled())
321
+ return;
322
+ if (event.key === 'Enter' || event.key === ' ') {
323
+ event.preventDefault();
324
+ this.parent?.sort(snapshot(this));
325
+ }
326
+ }
327
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SortHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
328
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: SortHeaderComponent, isStandalone: true, selector: "[tw-sort-header]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, start: { classPropertyName: "start", publicName: "start", isSignal: true, isRequired: false, transformFunction: null }, disableClear: { classPropertyName: "disableClear", publicName: "disableClear", isSignal: true, isRequired: false, transformFunction: null }, headerDisabled: { classPropertyName: "headerDisabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, arrowPosition: { classPropertyName: "arrowPosition", publicName: "arrowPosition", 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 }, sortActionDescription: { classPropertyName: "sortActionDescription", publicName: "sortActionDescription", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "handleClick()", "keydown": "handleKeydown($event)" }, properties: { "class": "hostClasses()", "attr.aria-sort": "ariaSort()", "attr.aria-disabled": "isDisabled() ? \"true\" : null" } }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, isSignal: true }], exportAs: ["twSortHeader"], ngImport: i0, template: "<div\n #container\n [class]=\"containerClasses()\"\n [attr.role]=\"isDisabled() ? null : 'button'\"\n [attr.tabindex]=\"isDisabled() ? null : 0\"\n>\n @if (arrowPosition() === 'before' && renderArrow()) {\n <ng-container *ngTemplateOutlet=\"arrow\" />\n }\n <span [class]=\"labelClasses()\"><ng-content /></span>\n @if (arrowPosition() === 'after' && renderArrow()) {\n <ng-container *ngTemplateOutlet=\"arrow\" />\n }\n</div>\n\n<ng-template #arrow>\n <span [class]=\"arrowClasses()\" data-tw-sort-arrow>\n <ng-content select=\"[twSortHeaderIcon]\">\n <svg\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n [class]=\"arrowIconClasses()\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </ng-content>\n </span>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
329
+ }
330
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SortHeaderComponent, decorators: [{
331
+ type: Component,
332
+ args: [{ selector: '[tw-sort-header]', exportAs: 'twSortHeader', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet], host: {
333
+ '[class]': 'hostClasses()',
334
+ '[attr.aria-sort]': 'ariaSort()',
335
+ '[attr.aria-disabled]': 'isDisabled() ? "true" : null',
336
+ '(click)': 'handleClick()',
337
+ '(keydown)': 'handleKeydown($event)',
338
+ }, template: "<div\n #container\n [class]=\"containerClasses()\"\n [attr.role]=\"isDisabled() ? null : 'button'\"\n [attr.tabindex]=\"isDisabled() ? null : 0\"\n>\n @if (arrowPosition() === 'before' && renderArrow()) {\n <ng-container *ngTemplateOutlet=\"arrow\" />\n }\n <span [class]=\"labelClasses()\"><ng-content /></span>\n @if (arrowPosition() === 'after' && renderArrow()) {\n <ng-container *ngTemplateOutlet=\"arrow\" />\n }\n</div>\n\n<ng-template #arrow>\n <span [class]=\"arrowClasses()\" data-tw-sort-arrow>\n <ng-content select=\"[twSortHeaderIcon]\">\n <svg\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n [class]=\"arrowIconClasses()\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </ng-content>\n </span>\n</ng-template>\n" }]
339
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], start: [{ type: i0.Input, args: [{ isSignal: true, alias: "start", required: false }] }], disableClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableClear", required: false }] }], headerDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], arrowPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "arrowPosition", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], sortActionDescription: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortActionDescription", required: false }] }], containerRef: [{ type: i0.ViewChild, args: ['container', { isSignal: true }] }] } });
340
+
341
+ /**
342
+ * Generated bundle index. Do not edit.
343
+ */
344
+
345
+ export { SortDirective, SortHeaderComponent };
346
+ //# sourceMappingURL=cdevhub-ngx-tw-sort.mjs.map