@cdevhub/ngx-tw 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +264 -49
  2. package/fesm2022/cdevhub-ngx-tw-accordion.mjs +11 -7
  3. package/fesm2022/cdevhub-ngx-tw-accordion.mjs.map +1 -1
  4. package/fesm2022/cdevhub-ngx-tw-alert.mjs +43 -29
  5. package/fesm2022/cdevhub-ngx-tw-alert.mjs.map +1 -1
  6. package/fesm2022/cdevhub-ngx-tw-aspect-ratio.mjs +103 -0
  7. package/fesm2022/cdevhub-ngx-tw-aspect-ratio.mjs.map +1 -0
  8. package/fesm2022/cdevhub-ngx-tw-avatar.mjs +56 -31
  9. package/fesm2022/cdevhub-ngx-tw-avatar.mjs.map +1 -1
  10. package/fesm2022/cdevhub-ngx-tw-badge.mjs +61 -35
  11. package/fesm2022/cdevhub-ngx-tw-badge.mjs.map +1 -1
  12. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs +154 -93
  13. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs.map +1 -1
  14. package/fesm2022/cdevhub-ngx-tw-button.mjs +24 -15
  15. package/fesm2022/cdevhub-ngx-tw-button.mjs.map +1 -1
  16. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs +3 -3
  17. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs.map +1 -1
  18. package/fesm2022/cdevhub-ngx-tw-calendar.mjs +408 -215
  19. package/fesm2022/cdevhub-ngx-tw-calendar.mjs.map +1 -1
  20. package/fesm2022/cdevhub-ngx-tw-card.mjs +33 -24
  21. package/fesm2022/cdevhub-ngx-tw-card.mjs.map +1 -1
  22. package/fesm2022/cdevhub-ngx-tw-carousel.mjs +144 -79
  23. package/fesm2022/cdevhub-ngx-tw-carousel.mjs.map +1 -1
  24. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs +99 -47
  25. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs.map +1 -1
  26. package/fesm2022/cdevhub-ngx-tw-code-block.mjs +34 -20
  27. package/fesm2022/cdevhub-ngx-tw-code-block.mjs.map +1 -1
  28. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs +46 -29
  29. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs.map +1 -1
  30. package/fesm2022/cdevhub-ngx-tw-combobox.mjs +195 -110
  31. package/fesm2022/cdevhub-ngx-tw-combobox.mjs.map +1 -1
  32. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs +140 -73
  33. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs.map +1 -1
  34. package/fesm2022/cdevhub-ngx-tw-core.mjs +16 -11
  35. package/fesm2022/cdevhub-ngx-tw-core.mjs.map +1 -1
  36. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs +393 -149
  37. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs.map +1 -1
  38. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs +305 -150
  39. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs.map +1 -1
  40. package/fesm2022/cdevhub-ngx-tw-dialog.mjs +56 -43
  41. package/fesm2022/cdevhub-ngx-tw-dialog.mjs.map +1 -1
  42. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs +51 -33
  43. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs.map +1 -1
  44. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs +905 -0
  45. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs.map +1 -0
  46. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs +49 -26
  47. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs.map +1 -1
  48. package/fesm2022/cdevhub-ngx-tw-form-field.mjs +133 -74
  49. package/fesm2022/cdevhub-ngx-tw-form-field.mjs.map +1 -1
  50. package/fesm2022/cdevhub-ngx-tw-icon-lucide.mjs +2 -2
  51. package/fesm2022/cdevhub-ngx-tw-icon-lucide.mjs.map +1 -1
  52. package/fesm2022/cdevhub-ngx-tw-icon.mjs +28 -17
  53. package/fesm2022/cdevhub-ngx-tw-icon.mjs.map +1 -1
  54. package/fesm2022/cdevhub-ngx-tw-input.mjs +37 -21
  55. package/fesm2022/cdevhub-ngx-tw-input.mjs.map +1 -1
  56. package/fesm2022/cdevhub-ngx-tw-item.mjs +33 -24
  57. package/fesm2022/cdevhub-ngx-tw-item.mjs.map +1 -1
  58. package/fesm2022/cdevhub-ngx-tw-menu.mjs +63 -48
  59. package/fesm2022/cdevhub-ngx-tw-menu.mjs.map +1 -1
  60. package/fesm2022/cdevhub-ngx-tw-number-input.mjs +622 -0
  61. package/fesm2022/cdevhub-ngx-tw-number-input.mjs.map +1 -0
  62. package/fesm2022/cdevhub-ngx-tw-paginator.mjs +137 -71
  63. package/fesm2022/cdevhub-ngx-tw-paginator.mjs.map +1 -1
  64. package/fesm2022/cdevhub-ngx-tw-popover.mjs +101 -46
  65. package/fesm2022/cdevhub-ngx-tw-popover.mjs.map +1 -1
  66. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs +57 -30
  67. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs.map +1 -1
  68. package/fesm2022/cdevhub-ngx-tw-radio.mjs +108 -57
  69. package/fesm2022/cdevhub-ngx-tw-radio.mjs.map +1 -1
  70. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs +46 -26
  71. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs.map +1 -1
  72. package/fesm2022/cdevhub-ngx-tw-select.mjs +217 -122
  73. package/fesm2022/cdevhub-ngx-tw-select.mjs.map +1 -1
  74. package/fesm2022/cdevhub-ngx-tw-separator.mjs +21 -12
  75. package/fesm2022/cdevhub-ngx-tw-separator.mjs.map +1 -1
  76. package/fesm2022/cdevhub-ngx-tw-sheet.mjs +58 -44
  77. package/fesm2022/cdevhub-ngx-tw-sheet.mjs.map +1 -1
  78. package/fesm2022/cdevhub-ngx-tw-skeleton.mjs +25 -14
  79. package/fesm2022/cdevhub-ngx-tw-skeleton.mjs.map +1 -1
  80. package/fesm2022/cdevhub-ngx-tw-slider.mjs +155 -79
  81. package/fesm2022/cdevhub-ngx-tw-slider.mjs.map +1 -1
  82. package/fesm2022/cdevhub-ngx-tw-sort.mjs +44 -25
  83. package/fesm2022/cdevhub-ngx-tw-sort.mjs.map +1 -1
  84. package/fesm2022/cdevhub-ngx-tw-spinner.mjs +29 -16
  85. package/fesm2022/cdevhub-ngx-tw-spinner.mjs.map +1 -1
  86. package/fesm2022/cdevhub-ngx-tw-split.mjs +72 -42
  87. package/fesm2022/cdevhub-ngx-tw-split.mjs.map +1 -1
  88. package/fesm2022/cdevhub-ngx-tw-stat.mjs +107 -64
  89. package/fesm2022/cdevhub-ngx-tw-stat.mjs.map +1 -1
  90. package/fesm2022/cdevhub-ngx-tw-stepper.mjs +113 -47
  91. package/fesm2022/cdevhub-ngx-tw-stepper.mjs.map +1 -1
  92. package/fesm2022/cdevhub-ngx-tw-switch.mjs +61 -32
  93. package/fesm2022/cdevhub-ngx-tw-switch.mjs.map +1 -1
  94. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs +88 -42
  95. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs.map +1 -1
  96. package/fesm2022/cdevhub-ngx-tw-table.mjs +266 -118
  97. package/fesm2022/cdevhub-ngx-tw-table.mjs.map +1 -1
  98. package/fesm2022/cdevhub-ngx-tw-tabs.mjs +101 -51
  99. package/fesm2022/cdevhub-ngx-tw-tabs.mjs.map +1 -1
  100. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs +798 -0
  101. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs.map +1 -0
  102. package/fesm2022/cdevhub-ngx-tw-textarea.mjs +11 -7
  103. package/fesm2022/cdevhub-ngx-tw-textarea.mjs.map +1 -1
  104. package/fesm2022/cdevhub-ngx-tw-theme.mjs +22 -14
  105. package/fesm2022/cdevhub-ngx-tw-theme.mjs.map +1 -1
  106. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs +243 -95
  107. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs.map +1 -1
  108. package/fesm2022/cdevhub-ngx-tw-timeline.mjs +149 -82
  109. package/fesm2022/cdevhub-ngx-tw-timeline.mjs.map +1 -1
  110. package/fesm2022/cdevhub-ngx-tw-toast.mjs +89 -55
  111. package/fesm2022/cdevhub-ngx-tw-toast.mjs.map +1 -1
  112. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs +50 -28
  113. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs.map +1 -1
  114. package/fesm2022/cdevhub-ngx-tw-transfer.mjs +1129 -0
  115. package/fesm2022/cdevhub-ngx-tw-transfer.mjs.map +1 -0
  116. package/fesm2022/cdevhub-ngx-tw-tree.mjs +554 -0
  117. package/fesm2022/cdevhub-ngx-tw-tree.mjs.map +1 -0
  118. package/fesm2022/cdevhub-ngx-tw.mjs +7 -0
  119. package/fesm2022/cdevhub-ngx-tw.mjs.map +1 -1
  120. package/package.json +45 -20
  121. package/theme/index.css +10 -2
  122. package/types/cdevhub-ngx-tw-aspect-ratio.d.ts +40 -0
  123. package/types/cdevhub-ngx-tw-calendar.d.ts +39 -8
  124. package/types/cdevhub-ngx-tw-command-palette.d.ts +7 -0
  125. package/types/cdevhub-ngx-tw-date-picker.d.ts +36 -10
  126. package/types/cdevhub-ngx-tw-file-upload.d.ts +250 -0
  127. package/types/cdevhub-ngx-tw-form-field.d.ts +22 -3
  128. package/types/cdevhub-ngx-tw-icon-lucide.d.ts +21 -3
  129. package/types/cdevhub-ngx-tw-number-input.d.ts +130 -0
  130. package/types/cdevhub-ngx-tw-popover.d.ts +8 -0
  131. package/types/cdevhub-ngx-tw-stepper.d.ts +30 -2
  132. package/types/cdevhub-ngx-tw-tab-nav.d.ts +8 -0
  133. package/types/cdevhub-ngx-tw-table.d.ts +30 -1
  134. package/types/cdevhub-ngx-tw-tabs.d.ts +8 -0
  135. package/types/cdevhub-ngx-tw-tags-input.d.ts +217 -0
  136. package/types/cdevhub-ngx-tw-time-picker.d.ts +31 -6
  137. package/types/cdevhub-ngx-tw-transfer.d.ts +330 -0
  138. package/types/cdevhub-ngx-tw-tree.d.ts +189 -0
  139. package/types/cdevhub-ngx-tw.d.ts +7 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdevhub-ngx-tw-tags-input.mjs","sources":["../../../projects/ngx-tw/tags-input/tags-input.ts","../../../projects/ngx-tw/tags-input/cdevhub-ngx-tw-tags-input.ts"],"sourcesContent":["import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n ElementRef,\n forwardRef,\n inject,\n input,\n isDevMode,\n type OnInit,\n output,\n signal,\n type Signal,\n untracked,\n viewChild,\n viewChildren,\n} from '@angular/core';\nimport {\n type ControlValueAccessor,\n FormGroupDirective,\n NgControl,\n NgForm,\n Validators,\n} from '@angular/forms';\nimport { FocusMonitor, LiveAnnouncer } from '@angular/cdk/a11y';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { isObservable, merge } from 'rxjs';\nimport { tv } from 'tailwind-variants';\nimport {\n type ErrorStateMatcher,\n TW_ERROR_STATE_MATCHER,\n type TwColor,\n type TwFormSubmitted,\n type TwSize,\n} from '@cdevhub/ngx-tw/core';\nimport {\n FormFieldControl,\n TW_FORM_FIELD,\n TW_FORM_FIELD_CONTROL,\n} from '@cdevhub/ngx-tw/form-field';\nimport { BadgeComponent } from '@cdevhub/ngx-tw/badge';\nimport type {\n TwTagAddedEvent,\n TwTagCompareFn,\n TwTagFactory,\n TwTagLabelFn,\n TwTagRemovedEvent,\n} from './types';\n\n// ── tv() config ──\n// `focus-within:outline-{color}-500` and the chip color classes are emitted by\n// combobox / badge already, so the Tailwind v4 JIT scanner picks them up.\n\nconst tagsInputVariants = tv(\n {\n slots: {\n // Host is the `role=\"group\"` chip strip. `flex-wrap` lets chips wrap; the\n // container owns the focus-within ring (standalone) or strips its chrome\n // inside a `<tw-form-field>` (the field draws the border / focus border).\n root: 'flex flex-wrap items-center gap-1.5 w-full text-fg',\n chip: 'max-w-full min-w-0',\n chipLabel: 'truncate',\n // Real DOM focus → canonical outline ring (NOT the activedescendant\n // background-shift carve-out). `text-current` inherits the chip color.\n // Per-size sets the square-interactive target size + negative margins.\n removeButton:\n 'inline-flex items-center justify-center shrink-0 ml-0.5 rounded-md text-current opacity-70 hover:opacity-100 transition-opacity duration-normal motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500 disabled:pointer-events-none',\n removeIcon: 'shrink-0',\n input:\n 'flex-1 min-w-24 bg-transparent text-fg placeholder:text-fg-subtle outline-none disabled:cursor-not-allowed',\n },\n variants: {\n inFormField: {\n // Inside a form-field: keep only the chip-strip layout; the field owns\n // border, padding, background and the focused-border indicator.\n true: { root: '' },\n false: {\n root: 'rounded-md border border-border bg-surface transition-colors duration-normal motion-reduce:transition-none hover:border-border-strong focus-within:outline-2 focus-within:outline-offset-2',\n },\n },\n size: {\n // removeButton uses the square-interactive sub-scale (the button IS the\n // touch target): size-6 (24px) meets WCAG 2.5.8; negative margins absorb\n // the overflow so the chip height is unchanged. Mirrors badge's dismiss.\n // `size-3.5` half-step on the md remove glyph lines up the X with text-sm\n // at md density (codified half-step per CLAUDE.md icon sizing).\n xs: { root: 'text-xs', removeButton: 'size-6 -my-1 -mr-1', removeIcon: 'size-3' },\n sm: { root: 'text-sm', removeButton: 'size-6 -my-1 -mr-1', removeIcon: 'size-3' },\n md: { root: 'text-sm', removeButton: 'size-7 -my-1.5 -mr-1.5', removeIcon: 'size-3.5' },\n lg: { root: 'text-base', removeButton: 'size-8 -my-1.5 -mr-1.5', removeIcon: 'size-4' },\n xl: { root: 'text-base', removeButton: 'size-8 -my-1.5 -mr-1.5', removeIcon: 'size-4' },\n },\n color: {\n primary: { root: 'focus-within:outline-primary-500' },\n secondary: { root: 'focus-within:outline-secondary-500' },\n accent: { root: 'focus-within:outline-accent-500' },\n neutral: { root: 'focus-within:outline-border-strong' },\n info: { root: 'focus-within:outline-info-500' },\n success: { root: 'focus-within:outline-success-500' },\n warning: { root: 'focus-within:outline-warning-500' },\n error: { root: 'focus-within:outline-error-500' },\n },\n disabled: {\n true: { root: 'opacity-50 pointer-events-none cursor-not-allowed' },\n false: {},\n },\n errorState: {\n true: {},\n false: {},\n },\n },\n compoundVariants: [\n // Standalone density × size — inline padding scale (mirrors combobox trigger).\n { inFormField: false, size: 'xs', class: { root: 'px-2 py-1' } },\n { inFormField: false, size: 'sm', class: { root: 'px-3 py-1.5' } },\n { inFormField: false, size: 'md', class: { root: 'px-4 py-2' } },\n { inFormField: false, size: 'lg', class: { root: 'px-5 py-2.5' } },\n { inFormField: false, size: 'xl', class: { root: 'px-6 py-3' } },\n // Standalone error state — colored border + focus ring.\n {\n inFormField: false,\n errorState: true,\n class: { root: 'border-error-500 focus-within:outline-error-500' },\n },\n ],\n defaultVariants: {\n inFormField: false,\n size: 'md',\n color: 'primary',\n disabled: false,\n errorState: false,\n },\n },\n { twMerge: true },\n);\n\nconst DEFAULT_SEPARATORS: readonly string[] = ['Enter', ','];\n\nlet nextId = 0;\n\n/**\n * Free-text multi-value input. The user types a token and commits it via Enter,\n * a separator key, paste, or blur; committed tokens render as dismissible chips\n * (composing `[twBadge]`) inline with the text input. The value is exposed as a\n * real `T[]` (default `string[]`) through `ControlValueAccessor`, so it works\n * with template-driven, reactive, and signal forms and integrates with\n * `<tw-form-field>` for label / hint / error chrome.\n *\n * The control is a single tab stop with a roving-tabindex chip strip\n * (Material `MatChipGrid` interaction model): Arrow keys traverse chips and the\n * input, Delete / a two-step Backspace remove chips, and `LiveAnnouncer` voices\n * add / remove. Autocomplete suggestions are out of scope (use `tw-combobox`).\n */\n@Component({\n selector: 'tw-tags-input',\n exportAs: 'twTagsInput',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [BadgeComponent],\n providers: [\n {\n provide: TW_FORM_FIELD_CONTROL,\n useExisting: forwardRef(() => TagsInputComponent),\n },\n ],\n template: `\n @for (chip of chipViews(); track chip.index) {\n <span twBadge variant=\"soft\" [color]=\"color()\" [size]=\"size()\" [class]=\"chipClasses()\">\n <span [class]=\"chipLabelClasses()\">{{ chip.label }}</span>\n <button\n #removeBtn\n type=\"button\"\n [class]=\"removeButtonClasses()\"\n [attr.tabindex]=\"activeChipIndex() === chip.index ? 0 : -1\"\n [attr.aria-label]=\"chip.removeLabel\"\n [disabled]=\"disabled()\"\n (click)=\"onRemoveClick(chip.index)\"\n (keydown)=\"onChipKeydown($event, chip.index)\"\n >\n <svg\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n [class]=\"removeIconClasses()\"\n >\n <path\n d=\"M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z\"\n />\n </svg>\n </button>\n </span>\n }\n <input\n #textInput\n type=\"text\"\n [class]=\"inputClasses()\"\n [attr.tabindex]=\"activeChipIndex() === null ? 0 : -1\"\n [attr.placeholder]=\"placeholder() || null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-labelledby]=\"resolvedLabelledBy() || null\"\n [attr.aria-describedby]=\"resolvedDescribedBy() || null\"\n [attr.aria-invalid]=\"errorState() || null\"\n [attr.name]=\"name() || null\"\n [disabled]=\"disabled()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onInputKeydown($event)\"\n (paste)=\"onPaste($event)\"\n />\n `,\n host: {\n 'role': 'group',\n '[id]': 'id()',\n '[class]': 'rootClasses()',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'resolvedLabelledBy() || null',\n '[attr.aria-describedby]': 'resolvedDescribedBy() || null',\n '[attr.aria-disabled]': 'disabled() || null',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.data-focused]': 'focused() || null',\n },\n})\nexport class TagsInputComponent<T = string>\n extends FormFieldControl<T[]>\n implements ControlValueAccessor, OnInit\n{\n /** Semantic color for the container focus-within ring and the chip accent. Defaults to `'primary'`. */\n readonly color = input<TwColor>('primary');\n\n /** Controls overall density: container padding, chip size, and text scale. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** When true, blocks typing, committing, and chip removal, and applies muted styling. Reactive forms also propagate disabled via `setDisabledState`. Defaults to `false`. */\n readonly disabledInput = input(false, { alias: 'disabled' });\n\n /** Marks the control as required. Mirrored to the input's `aria-required`. Also inferred from `Validators.required` on a bound control. Defaults to `false`. */\n readonly requiredInput = input(false, { alias: 'required' });\n\n /** Placeholder shown in the text input only while there are no chips and the input is empty. */\n readonly placeholder = input<string | undefined>(undefined);\n\n /** Keys that commit the in-progress text as a tag. Each entry is a `KeyboardEvent.key` value (`'Enter'`) or a single separator character (`','`). Single-character separators also split pasted text. Defaults to `['Enter', ',']`. */\n readonly separatorKeys = input<readonly string[]>(DEFAULT_SEPARATORS);\n\n /** When true, blurring the control while the input holds non-empty text commits it as a tag. Defaults to `false`. */\n readonly addOnBlur = input(false);\n\n /** Maximum number of tags. Once reached, further commits are blocked and announced. Does not truncate an oversized `writeValue`. Defaults to `undefined` (no limit). */\n readonly maxTags = input<number | undefined>(undefined);\n\n /** When false (default), a committed tag equal (per `compareWith`) to an existing tag is dropped silently. When true, duplicates are kept. Defaults to `false`. */\n readonly allowDuplicates = input(false);\n\n /** Maps committed text to a tag value. Default is identity — the trimmed string. Override to build object tags. */\n readonly createTag = input<TwTagFactory<T>>(\n ((text: string) => text) as unknown as TwTagFactory<T>,\n );\n\n /** Maps a tag value to its visible chip label and the remove-button accessible name. Defaults to `String(tag)`. */\n readonly tagLabel = input<TwTagLabelFn<T>>((tag: T) => String(tag));\n\n /** Equality comparator used for dedup when `allowDuplicates` is false. Defaults to `Object.is` (reference / value identity). String tags dedupe case-sensitively by default; pass `(a, b) => a.toLowerCase() === b.toLowerCase()` for case-insensitive dedup. */\n readonly compareWith = input<TwTagCompareFn<T>>((a: T, b: T) => Object.is(a, b));\n\n /** Applied to the text input for labeling and identification only; does not submit the tag array via native (non-Angular) form posting. */\n readonly name = input<string | undefined>(undefined);\n\n /** Id on the host element. Auto-generated as `tw-tags-input-N` when not provided. Used by the form-field's `<label for>` association. */\n readonly idInput = input<string | undefined>(undefined, { alias: 'id' });\n\n /** Accessible name applied to the control when no visible label is wired. Mirrored to `aria-label`. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** ID of an external element that labels the control. Mirrored to `aria-labelledby`. */\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n /** ID of an external element that describes the control. Form-field merges its hint / error ids alongside. */\n readonly ariaDescribedby = input<string | undefined>(undefined, { alias: 'aria-describedby' });\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n /** Fires when the tag array changes through user interaction (add, remove, clear). Emits a fresh array reference. Does not fire on `writeValue`. */\n readonly valueChange = output<T[]>();\n\n /** Fires when a tag is committed via Enter, a separator key, paste, or `addTag()`. Does not fire for dropped duplicates, blocked-by-max commits, empty commits, or `writeValue`. */\n readonly tagAdded = output<TwTagAddedEvent<T>>();\n\n /** Fires when a tag is removed via the remove button, Backspace / Delete, or `removeTag()`. Does not fire on `writeValue` or `clear()`. */\n readonly tagRemoved = output<TwTagRemovedEvent<T>>();\n\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly liveAnnouncer = inject(LiveAnnouncer);\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly destroyRef = inject(DestroyRef);\n private readonly ngControl = inject(NgControl, { optional: true, self: true });\n private readonly parentForm = inject(NgForm, { optional: true });\n private readonly parentFormGroup = inject(FormGroupDirective, { optional: true });\n private readonly defaultMatcher = inject(TW_ERROR_STATE_MATCHER);\n private readonly formField = inject(TW_FORM_FIELD, { optional: true });\n\n private readonly textInputRef = viewChild<ElementRef<HTMLInputElement>>('textInput');\n private readonly removeButtons = viewChildren<ElementRef<HTMLButtonElement>>('removeBtn');\n\n private onChange: (value: T[]) => void = () => {};\n private onTouched: () => void = () => {};\n\n private readonly tags = signal<T[]>([]);\n /** The current in-progress (uncommitted) text in the input. Empty when nothing is typed. */\n readonly inputText = signal('');\n /** @internal Roving-tabindex position. `null` = the text input is the active element; a number = that chip's remove button. */\n protected readonly activeChipIndex = signal<number | null>(null);\n private readonly cvaDisabled = signal(false);\n private readonly _focused = signal(false);\n private readonly _ngControlRev = signal(0);\n private readonly _formSubmitRev = signal(0);\n private readonly describedByIdsSignal = signal<readonly string[]>([]);\n private readonly labelledByIdsSignal = signal<readonly string[]>([]);\n /** Nonce bumped only on explicit focus intent — keeps the focus effect from stealing focus on unrelated renders. */\n private readonly focusNonce = signal(0);\n private lastMaxAnnounce = 0;\n\n private readonly uid = nextId++;\n /** @internal Fallback id used when the consumer does not set `[id]`. */\n readonly hostId = `tw-tags-input-${this.uid}`;\n\n // ── FormFieldControl signals ──\n\n /** @internal */\n readonly id: Signal<string> = computed(() => this.idInput() ?? this.hostId);\n\n /** The current tag array (empty array when there are no tags). Read from a template ref (`#t=\"twTagsInput\"`) for non-form usage. Doubles as the `FormFieldControl` contract member. */\n readonly value: Signal<T[]> = this.tags.asReadonly();\n\n /** @internal */\n readonly focused: Signal<boolean> = this._focused.asReadonly();\n\n /** @internal Empty when there are no chips AND the input text is blank — drives the form-field floating label. */\n readonly empty: Signal<boolean> = computed(\n () => this.tags().length === 0 && this.inputText().trim().length === 0,\n );\n\n /** @internal */\n readonly disabled: Signal<boolean> = computed(\n () => this.disabledInput() || this.cvaDisabled(),\n );\n\n /** @internal */\n readonly required: Signal<boolean> = computed(() => {\n this._ngControlRev();\n if (this.requiredInput()) return true;\n return !!this.ngControl?.control?.hasValidator(Validators.required);\n });\n\n /** @internal */\n readonly errorState: Signal<boolean> = computed(() => {\n this._ngControlRev();\n this._formSubmitRev();\n this._focused();\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 /** @internal Active validation errors map from the bound control, for `[twError match=\"…\"]` filtering. */\n override readonly errors = computed<Record<string, unknown> | null>(() => {\n this._ngControlRev();\n return (this.ngControl?.control?.errors as Record<string, unknown> | null) ?? null;\n });\n\n /** @internal */\n readonly controlType = 'tags-input';\n\n /** @internal */\n readonly userAriaDescribedBy: Signal<string | undefined> = computed(() => this.ariaDescribedby());\n\n /** @internal */\n override readonly userAriaLabelledby: Signal<string | undefined> = computed(() =>\n this.ariaLabelledby(),\n );\n\n // ── Effective ARIA ──\n //\n // When wrapped by `<tw-form-field>`, the form-field pushes the FULLY MERGED\n // id list (hint/error/label + the consumer's `aria-*by` ids) via\n // `setDescribedByIds` / `setLabelledByIds`. In that case the pushed ids alone\n // are the source of truth — re-merging the consumer's `aria-*by` input on top\n // would duplicate ids. When standalone, fall back to the consumer-supplied\n // `aria-*by` input.\n\n /** @internal Merged `aria-describedby` (form-field hint/error ids + consumer-supplied). */\n readonly resolvedDescribedBy = computed(() => {\n const pushed = this.describedByIdsSignal();\n if (pushed.length) return pushed.join(' ');\n const user = this.ariaDescribedby();\n if (user) return user.split(/\\s+/).filter(Boolean).join(' ');\n return '';\n });\n\n /** @internal Merged `aria-labelledby` (form-field label id + consumer-supplied). */\n readonly resolvedLabelledBy = computed(() => {\n const pushed = this.labelledByIdsSignal();\n if (pushed.length) return pushed.join(' ');\n const user = this.ariaLabelledby();\n if (user) return user.split(/\\s+/).filter(Boolean).join(' ');\n return '';\n });\n\n // ── tv() class bindings ──\n\n private readonly variantResult = computed(() =>\n tagsInputVariants({\n inFormField: !!this.formField,\n size: this.size(),\n color: this.color(),\n disabled: this.disabled(),\n errorState: this.errorState(),\n }),\n );\n\n /** @internal */\n readonly rootClasses = computed(() => this.variantResult().root());\n /** @internal */\n readonly chipClasses = computed(() => this.variantResult().chip());\n /** @internal */\n readonly chipLabelClasses = computed(() => this.variantResult().chipLabel());\n /** @internal */\n readonly removeButtonClasses = computed(() => this.variantResult().removeButton());\n /** @internal */\n readonly removeIconClasses = computed(() => this.variantResult().removeIcon());\n /** @internal */\n readonly inputClasses = computed(() => this.variantResult().input());\n\n /** @internal Pre-resolved chip view models so the template never calls accessor functions inline. */\n readonly chipViews = computed(() => {\n const label = this.tagLabel();\n return this.tags().map((tag, index) => {\n const text = label(tag);\n return { tag, label: text, removeLabel: `Remove ${text}`, index };\n });\n });\n\n constructor() {\n super();\n // Runtime CVA wiring — register on any host-level NgControl. The component\n // injects `NgControl { self }` for TW_ERROR_STATE_MATCHER, so a static\n // NG_VALUE_ACCESSOR provider would create circular DI on the same instance.\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n // Focus side-effect (leaves the signal graph; writes no signal → no cycle).\n // Triggered only by `focusNonce` bumps so it never steals focus on an\n // unrelated render (e.g. initial mount). Reads the active index and refs\n // untracked so it does not re-fire when the chip list changes on its own.\n effect(() => {\n if (this.focusNonce() === 0) return;\n untracked(() => {\n const idx = this.activeChipIndex();\n if (idx === null) {\n this.textInputRef()?.nativeElement.focus();\n } else {\n this.removeButtons()[idx]?.nativeElement.focus();\n }\n });\n });\n\n afterNextRender(() => {\n if (isDevMode() && !this.hasAccessibleNameHint()) {\n console.warn(\n '[tw-tags-input] The control has no accessible name. Provide `aria-label` / `aria-labelledby`, or wrap it in a <tw-form-field> with a <label twLabel>.',\n );\n }\n });\n }\n\n // ── Public instance API ──\n\n /** Commits `text` as a tag (trim → `createTag` → dedup unless `allowDuplicates` → `maxTags` check). Returns true if a tag was added, false if dropped (empty / duplicate / max). Emits `tagAdded` + `valueChange` on success. No-op when disabled. */\n addTag(text: string): boolean {\n if (this.disabled()) return false;\n const trimmed = text.trim();\n if (!trimmed) return false;\n return this.tryAdd(this.createTag()(trimmed)) === 'added';\n }\n\n /** Removes a tag by value (first match via `compareWith`) or by index when a number is passed. Emits `tagRemoved` + `valueChange` and restores focus. No-op when disabled or when no match. Note: when the tag type is `number`, the argument is treated as an index. */\n removeTag(tag: T | number): void {\n if (this.disabled()) return;\n if (typeof tag === 'number') {\n this.removeAt(tag);\n return;\n }\n const cmp = this.compareWith();\n const idx = this.tags().findIndex((t) => cmp(t, tag));\n if (idx >= 0) this.removeAt(idx);\n }\n\n /** Removes all tags and clears the in-progress input text. Emits `valueChange` with `[]`. Does NOT emit `tagRemoved` per tag (bulk reset). No-op when already empty or disabled. */\n clear(): void {\n if (this.disabled()) return;\n if (this.tags().length === 0 && this.inputText().length === 0) return;\n this.tags.set([]);\n this.setInputText('');\n this.activeChipIndex.set(null);\n this.onChange([]);\n this.valueChange.emit([]);\n this.liveAnnouncer.announce('All tags removed', 'polite');\n }\n\n /** Moves focus to the text input. */\n focus(): void {\n this.activeChipIndex.set(null);\n this.requestFocus();\n }\n\n // ── Internal commit / remove pipeline ──\n\n private tryAdd(tag: T): 'added' | 'duplicate' | 'max' {\n const current = this.tags();\n if (!this.allowDuplicates()) {\n const cmp = this.compareWith();\n if (current.some((e) => cmp(e, tag))) return 'duplicate';\n }\n const max = this.maxTags();\n if (max !== undefined && current.length >= max) {\n this.announceMax();\n return 'max';\n }\n const next = [...current, tag];\n this.tags.set(next);\n this.onChange(next);\n this.tagAdded.emit({ tag, value: next });\n this.valueChange.emit(next);\n this.liveAnnouncer.announce(`${this.tagLabel()(tag)} added`, 'polite');\n return 'added';\n }\n\n private commitInput(): void {\n if (this.disabled()) return;\n const trimmed = this.inputText().trim();\n if (!trimmed) {\n this.setInputText('');\n return;\n }\n const result = this.tryAdd(this.createTag()(trimmed));\n // Clear on success or duplicate (gesture consumed); retain on max so the\n // user can retry after removing a tag.\n if (result !== 'max') this.setInputText('');\n }\n\n private removeAt(index: number): void {\n if (this.disabled()) return;\n const current = this.tags();\n if (index < 0 || index >= current.length) return;\n const tag = current[index];\n const next = current.filter((_, i) => i !== index);\n this.tags.set(next);\n this.onChange(next);\n this.tagRemoved.emit({ tag, value: next, index });\n this.valueChange.emit(next);\n this.liveAnnouncer.announce(`${this.tagLabel()(tag)} removed`, 'polite');\n // Focus restoration: next chip at this index, else the previous chip, else the input.\n if (next.length === 0) {\n this.focusInput();\n } else if (index < next.length) {\n this.focusChip(index);\n } else {\n this.focusChip(next.length - 1);\n }\n }\n\n // ── DOM event handlers ──\n\n /** @internal */\n onInput(event: Event): void {\n this.inputText.set((event.target as HTMLInputElement).value);\n }\n\n /** @internal */\n onInputKeydown(event: KeyboardEvent): void {\n if (this.disabled()) return;\n const separators = this.separatorKeys();\n const key = event.key;\n\n // Single-character separator → commit (and swallow the character).\n if (key.length === 1 && separators.includes(key)) {\n event.preventDefault();\n this.commitInput();\n return;\n }\n // Enter separator → commit only when there is text (otherwise let the form submit).\n if (key === 'Enter' && separators.includes('Enter')) {\n if (this.inputText().trim().length > 0) {\n event.preventDefault();\n this.commitInput();\n }\n return;\n }\n if (key === 'ArrowLeft') {\n const el = event.target as HTMLInputElement;\n const atStart = (el.selectionStart ?? 0) === 0 && (el.selectionEnd ?? 0) === 0;\n if (atStart && this.tags().length > 0) {\n event.preventDefault();\n this.focusChip(this.tags().length - 1);\n }\n return;\n }\n if (key === 'Backspace' && this.inputText().length === 0) {\n if (this.tags().length > 0) {\n event.preventDefault();\n this.focusChip(this.tags().length - 1);\n }\n return;\n }\n if (key === 'Escape' && this.inputText().length > 0) {\n event.preventDefault();\n this.setInputText('');\n }\n }\n\n /** @internal */\n onChipKeydown(event: KeyboardEvent, index: number): void {\n if (this.disabled()) return;\n const last = this.tags().length - 1;\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n if (index > 0) this.focusChip(index - 1);\n return;\n case 'ArrowRight':\n event.preventDefault();\n if (index < last) this.focusChip(index + 1);\n else this.focusInput();\n return;\n case 'Home':\n event.preventDefault();\n this.focusChip(0);\n return;\n case 'End':\n event.preventDefault();\n this.focusInput();\n return;\n case 'Delete':\n case 'Backspace':\n event.preventDefault();\n this.removeAt(index);\n return;\n case 'Escape':\n event.preventDefault();\n this.focusInput();\n return;\n default:\n return;\n }\n }\n\n /** @internal */\n onRemoveClick(index: number): void {\n this.removeAt(index);\n }\n\n /** @internal */\n onPaste(event: ClipboardEvent): void {\n if (this.disabled()) return;\n const data = event.clipboardData?.getData('text') ?? '';\n const charSeparators = this.separatorKeys().filter((k) => k.length === 1);\n const hasSeparator = charSeparators.some((s) => data.includes(s));\n if (!hasSeparator) {\n // No separator: let the browser merge the text into the input natively.\n return;\n }\n event.preventDefault();\n const combined = this.inputText() + data;\n this.setInputText('');\n for (const piece of this.splitOnSeparators(combined, charSeparators)) {\n const trimmed = piece.trim();\n if (!trimmed) continue;\n if (this.tryAdd(this.createTag()(trimmed)) === 'max') break;\n }\n }\n\n // ── ControlValueAccessor ──\n\n writeValue(value: T[] | null | undefined): void {\n this.tags.set(Array.isArray(value) ? [...value] : []);\n this.setInputText('');\n }\n\n registerOnChange(fn: (value: T[]) => 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 // ── FormFieldControl methods ──\n\n /** @internal */\n setDescribedByIds(ids: string[]): void {\n this.describedByIdsSignal.set([...ids]);\n }\n\n /** @internal */\n override setLabelledByIds(ids: string[]): void {\n this.labelledByIdsSignal.set([...ids]);\n }\n\n /** @internal Clicking the form-field surface (outside the control) focuses the text input. Clicks inside the control are left alone so chip removal keeps its own focus restoration. */\n onContainerClick(event: MouseEvent): void {\n if (this.disabled()) return;\n if (event.defaultPrevented) return;\n const host = this.elementRef.nativeElement;\n if (event.target === host || host.contains(event.target as Node)) return;\n this.focus();\n }\n\n // ── Lifecycle ──\n\n ngOnInit(): void {\n // checkChildren: true — internal focus moves (input ↔ chips) stay \"focused\";\n // origin === null fires only when focus leaves the whole control, the single\n // source for onTouched and the addOnBlur commit.\n const monitor$ = this.focusMonitor.monitor(this.elementRef, true);\n if (isObservable(monitor$)) {\n monitor$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((origin) => {\n const wasFocused = this._focused();\n this._focused.set(!!origin);\n if (wasFocused && !origin) {\n if (this.addOnBlur() && this.inputText().trim().length > 0) {\n this.commitInput();\n }\n this.onTouched();\n this._ngControlRev.update((n) => n + 1);\n // Reset roving so the next Tab into the control lands on the input.\n this.activeChipIndex.set(null);\n }\n });\n }\n this.destroyRef.onDestroy(() => this.focusMonitor.stopMonitoring(this.elementRef));\n\n const ctrl = this.ngControl?.control;\n if (ctrl) {\n const streams = [ctrl.statusChanges, ctrl.valueChanges].filter(\n (s): s is NonNullable<typeof s> => !!s,\n );\n if (streams.length) {\n merge(...streams)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._ngControlRev.update((n) => n + 1));\n }\n }\n\n const submit = this.parentFormGroup?.ngSubmit ?? this.parentForm?.ngSubmit;\n if (submit) {\n submit\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._formSubmitRev.update((n) => n + 1));\n }\n }\n\n // ── Helpers ──\n\n private focusChip(index: number): void {\n this.activeChipIndex.set(index);\n this.requestFocus();\n }\n\n private focusInput(): void {\n this.activeChipIndex.set(null);\n this.requestFocus();\n }\n\n private requestFocus(): void {\n this.focusNonce.update((n) => n + 1);\n }\n\n private setInputText(value: string): void {\n this.inputText.set(value);\n const el = this.textInputRef()?.nativeElement;\n if (el && el.value !== value) el.value = value;\n }\n\n private announceMax(): void {\n const now = Date.now();\n if (now - this.lastMaxAnnounce < 500) return;\n this.lastMaxAnnounce = now;\n this.liveAnnouncer.announce(`Maximum ${this.maxTags()} tags reached`, 'assertive');\n }\n\n private splitOnSeparators(text: string, separators: readonly string[]): string[] {\n if (separators.length === 0) return [text];\n let normalized = text;\n for (const s of separators) normalized = normalized.split(s).join('\\u0000');\n return normalized.split('\\u0000');\n }\n\n private hasAccessibleNameHint(): boolean {\n return (\n !!this.ariaLabel() ||\n !!this.ariaLabelledby() ||\n this.labelledByIdsSignal().length > 0\n );\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -64,7 +64,8 @@ class TextareaDirective extends InputDirective {
64
64
  // the longer comment above for the full reasoning.
65
65
  /* eslint-disable-next-line @typescript-eslint/ban-ts-comment */
66
66
  // @ts-ignore — see comment above.
67
- size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
67
+ size = input('md', /* @ts-ignore */
68
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
68
69
  /** Grows the textarea with its content (composed from CDK's `CdkTextareaAutosize`). When `true` the user-resize handle is forced off — autosize owns the height. Defaults to `false`. */
69
70
  autosize = input(false, { ...(ngDevMode ? { debugName: "autosize" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
70
71
  /** Minimum number of rows the textarea collapses to when `autosize` is `true`. Ignored when autosize is off. Defaults to `1`. */
@@ -74,18 +75,21 @@ class TextareaDirective extends InputDirective {
74
75
  /** Number of rows for the initial render height (native `rows` attribute). Browsers honor this even when `autosize` is `true`, so first paint uses this value. Defaults to `3`. */
75
76
  rows = input(3, { ...(ngDevMode ? { debugName: "rows" } : /* istanbul ignore next */ {}), transform: numberAttribute });
76
77
  /** Controls the user-resize handle: `'none'` locks the size, `'vertical'` (default) allows vertical drag, `'both'` allows both axes. Forced to `'none'` when `autosize` is `true`. Horizontal-only is intentionally not supported. */
77
- resize = input('vertical', ...(ngDevMode ? [{ debugName: "resize" }] : /* istanbul ignore next */ []));
78
+ resize = input('vertical', /* @ts-ignore */
79
+ ...(ngDevMode ? [{ debugName: "resize" }] : /* istanbul ignore next */ []));
78
80
  /** Maximum character count. Mirrors to the native `maxlength` attribute when defined and is exposed via the `valueLength` signal so consumers can render a "X / N" hint. Defaults to `undefined`. */
79
81
  maxLength = input(undefined, { ...(ngDevMode ? { debugName: "maxLength" } : /* istanbul ignore next */ {}), transform: (v) => (v === undefined || v === null || v === '' ? undefined : numberAttribute(v)) });
80
82
  /** Current value length, updates on every `input` event. Wire `<span twHint align="end">{{ ta.valueLength() }} / {{ ta.maxLength() }}</span>` for a character counter. */
81
- valueLength = computed(() => this.value()?.length ?? 0, ...(ngDevMode ? [{ debugName: "valueLength" }] : /* istanbul ignore next */ []));
83
+ valueLength = computed(() => this.value()?.length ?? 0, /* @ts-ignore */
84
+ ...(ngDevMode ? [{ debugName: "valueLength" }] : /* istanbul ignore next */ []));
82
85
  /** @internal Textarea-specific Tailwind classes (resize axis). Combined with the inherited `classes()` in the host `[class]` binding. */
83
86
  textareaClasses = computed(() =>
84
87
  // Short-circuit the resize/autosize conflict deterministically — don't
85
88
  // rely on tv variant emission order or twMerge "last wins" semantics.
86
89
  this.autosize()
87
90
  ? textareaVariants({ resize: 'none' })
88
- : textareaVariants({ resize: this.resize() }), ...(ngDevMode ? [{ debugName: "textareaClasses" }] : /* istanbul ignore next */ []));
91
+ : textareaVariants({ resize: this.resize() }), /* @ts-ignore */
92
+ ...(ngDevMode ? [{ debugName: "textareaClasses" }] : /* istanbul ignore next */ []));
89
93
  constructor() {
90
94
  super();
91
95
  // Wire the autosize toggle. The CDK directive is always mounted via
@@ -102,15 +106,15 @@ class TextareaDirective extends InputDirective {
102
106
  this.cdkAutosize.resizeToFitContent(force);
103
107
  }
104
108
  }
105
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: TextareaDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
106
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: TextareaDirective, isStandalone: true, selector: "textarea[twTextarea]", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, autosize: { classPropertyName: "autosize", publicName: "autosize", isSignal: true, isRequired: false, transformFunction: null }, minRows: { classPropertyName: "minRows", publicName: "minRows", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, resize: { classPropertyName: "resize", publicName: "resize", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "input": "_onInput()" }, properties: { "class": "classes() + \" \" + textareaClasses()", "attr.id": "id()", "attr.rows": "rows()", "attr.maxlength": "maxLength() ?? null", "disabled": "disabled()", "attr.aria-invalid": "errorState() || null", "attr.aria-required": "required() || null" } }, providers: [
109
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TextareaDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
110
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: TextareaDirective, isStandalone: true, selector: "textarea[twTextarea]", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, autosize: { classPropertyName: "autosize", publicName: "autosize", isSignal: true, isRequired: false, transformFunction: null }, minRows: { classPropertyName: "minRows", publicName: "minRows", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, resize: { classPropertyName: "resize", publicName: "resize", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "input": "_onInput()" }, properties: { "class": "classes() + \" \" + textareaClasses()", "attr.id": "id()", "attr.rows": "rows()", "attr.maxlength": "maxLength() ?? null", "disabled": "disabled()", "attr.aria-invalid": "errorState() || null", "attr.aria-required": "required() || null" } }, providers: [
107
111
  {
108
112
  provide: TW_FORM_FIELD_CONTROL,
109
113
  useExisting: forwardRef(() => TextareaDirective),
110
114
  },
111
115
  ], exportAs: ["twTextarea"], usesInheritance: true, hostDirectives: [{ directive: i1.CdkTextareaAutosize, inputs: ["cdkAutosizeMinRows", "minRows", "cdkAutosizeMaxRows", "maxRows"] }], ngImport: i0 });
112
116
  }
113
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: TextareaDirective, decorators: [{
117
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TextareaDirective, decorators: [{
114
118
  type: Directive,
115
119
  args: [{
116
120
  selector: 'textarea[twTextarea]',
@@ -1 +1 @@
1
- {"version":3,"file":"cdevhub-ngx-tw-textarea.mjs","sources":["../../../projects/ngx-tw/textarea/textarea.ts","../../../projects/ngx-tw/textarea/cdevhub-ngx-tw-textarea.ts"],"sourcesContent":["import {\n booleanAttribute,\n computed,\n Directive,\n effect,\n forwardRef,\n inject,\n input,\n numberAttribute,\n type Signal,\n} from '@angular/core';\nimport { CdkTextareaAutosize } from '@angular/cdk/text-field';\nimport { tv } from 'tailwind-variants';\nimport type { TwSize } from '@cdevhub/ngx-tw/core';\nimport { TW_FORM_FIELD_CONTROL } from '@cdevhub/ngx-tw/form-field';\nimport { InputDirective } from '@cdevhub/ngx-tw/input';\n\n/**\n * How the user-resize handle behaves on the textarea. `'vertical'` (the\n * default) lets users drag the bottom edge to grow the textarea; `'none'`\n * locks the size; `'both'` allows free resizing on both axes (rarely useful\n * inside a form-field — the textarea can overflow the wrapper). Horizontal\n * is intentionally omitted — it breaks form-field layout in practice.\n */\nexport type TwTextareaResize = 'none' | 'vertical' | 'both';\n\nconst textareaVariants = tv(\n {\n base: '',\n variants: {\n resize: {\n none: 'resize-none',\n vertical: 'resize-y',\n both: 'resize',\n },\n },\n defaultVariants: {\n resize: 'vertical',\n },\n },\n { twMerge: true },\n);\n\n/**\n * Adapts a native `<textarea>` into an ngx-tw form-field-compatible multi-line\n * control. Extends {@link InputDirective} — inherits its form-field\n * integration, error-state machinery, autofill / focus tracking, ARIA wiring,\n * and standalone styling. Adds textarea-specific behavior: autosize composition\n * via CDK's `CdkTextareaAutosize`, a `resize` axis for the user-resize handle,\n * `rows` / `minRows` / `maxRows`, and `maxLength` with a `valueLength` signal\n * for character counters.\n *\n * Like `InputDirective`, this directive deliberately does NOT implement\n * `ControlValueAccessor`. Angular's built-in `DefaultValueAccessor` attaches to\n * the native `<textarea>` and handles value I/O for template-driven\n * (`ngModel`), reactive (`FormControl` / `formControlName`), and signal-forms\n * (`formField`) bindings — no library glue required.\n *\n * Form-control input-cap exception applies (codified in CLAUDE.md): ARIA +\n * forms baseline plus textarea-specific surface exceeds the 5–6 cap;\n * `checkbox` is the canonical 12+ exemplar.\n */\n@Directive({\n selector: 'textarea[twTextarea]',\n exportAs: 'twTextarea',\n hostDirectives: [\n {\n directive: CdkTextareaAutosize,\n inputs: [\n 'cdkAutosizeMinRows: minRows',\n 'cdkAutosizeMaxRows: maxRows',\n ],\n },\n ],\n providers: [\n {\n provide: TW_FORM_FIELD_CONTROL,\n useExisting: forwardRef(() => TextareaDirective),\n },\n ],\n host: {\n '[class]': 'classes() + \" \" + textareaClasses()',\n '[attr.id]': 'id()',\n '[attr.rows]': 'rows()',\n '[attr.maxlength]': 'maxLength() ?? null',\n '[disabled]': 'disabled()',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.aria-required]': 'required() || null',\n '(input)': '_onInput()',\n },\n})\nexport class TextareaDirective extends InputDirective {\n private readonly cdkAutosize = inject(CdkTextareaAutosize, {\n self: true,\n optional: true,\n });\n\n // @internal Re-declares the `size` input inherited from `InputDirective` so\n // it lands on this directive's own `ɵdir` input metadata. ng-packagr emits\n // `ɵdir` with only the child's directly declared inputs, so without this the\n // consumer-side strict template-check rejects `<textarea twTextarea\n // [size]=\"…\">` with NG8002. Both signals share the same `'md'` default and\n // the inherited `classes()` computed reads through polymorphism, so runtime\n // behaviour is unchanged.\n //\n // The `@ts-ignore` is needed for a CI-only quirk: under\n // `noImplicitOverride`, partial compilation resolves `InputDirective`\n // through the just-built `dist/` d.ts on CI, where TypeScript decides the\n // base member isn't visible and rejects `override` with TS4113. Locally\n // the same resolution sees the member, so `@ts-expect-error` would itself\n // flag as unused. `@ts-ignore` suppresses whichever error fires and is\n // a no-op when neither does.\n /** Density of a standalone textarea. Maps to the inline-padding + font scale (`xs` … `xl`). Ignored inside a `<tw-form-field>` — the wrapper's `size` carries density. Defaults to `'md'`. */\n // TS4113 (CI) vs TS4114 (local) divergence means neither directive matches\n // both, so we intentionally pick `@ts-ignore` over `@ts-expect-error`; see\n // the longer comment above for the full reasoning.\n /* eslint-disable-next-line @typescript-eslint/ban-ts-comment */\n // @ts-ignore — see comment above.\n override readonly size = input<TwSize>('md');\n\n /** Grows the textarea with its content (composed from CDK's `CdkTextareaAutosize`). When `true` the user-resize handle is forced off — autosize owns the height. Defaults to `false`. */\n readonly autosize = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n\n /** Minimum number of rows the textarea collapses to when `autosize` is `true`. Ignored when autosize is off. Defaults to `1`. */\n readonly minRows = input<number, unknown>(1, { transform: numberAttribute });\n\n /** Maximum number of rows the textarea expands to before scrolling, when `autosize` is `true`. `undefined` removes the cap. Ignored when autosize is off. Defaults to `undefined`. */\n readonly maxRows = input<number | undefined, unknown>(undefined, {\n transform: (v) => (v === undefined || v === null || v === '' ? undefined : numberAttribute(v)),\n });\n\n /** Number of rows for the initial render height (native `rows` attribute). Browsers honor this even when `autosize` is `true`, so first paint uses this value. Defaults to `3`. */\n readonly rows = input<number, unknown>(3, { transform: numberAttribute });\n\n /** Controls the user-resize handle: `'none'` locks the size, `'vertical'` (default) allows vertical drag, `'both'` allows both axes. Forced to `'none'` when `autosize` is `true`. Horizontal-only is intentionally not supported. */\n readonly resize = input<TwTextareaResize>('vertical');\n\n /** Maximum character count. Mirrors to the native `maxlength` attribute when defined and is exposed via the `valueLength` signal so consumers can render a \"X / N\" hint. Defaults to `undefined`. */\n readonly maxLength = input<number | undefined, unknown>(undefined, {\n transform: (v) => (v === undefined || v === null || v === '' ? undefined : numberAttribute(v)),\n });\n\n /** Current value length, updates on every `input` event. Wire `<span twHint align=\"end\">{{ ta.valueLength() }} / {{ ta.maxLength() }}</span>` for a character counter. */\n readonly valueLength: Signal<number> = computed(() => this.value()?.length ?? 0);\n\n /** @internal Textarea-specific Tailwind classes (resize axis). Combined with the inherited `classes()` in the host `[class]` binding. */\n readonly textareaClasses = computed(() =>\n // Short-circuit the resize/autosize conflict deterministically — don't\n // rely on tv variant emission order or twMerge \"last wins\" semantics.\n this.autosize()\n ? textareaVariants({ resize: 'none' })\n : textareaVariants({ resize: this.resize() }),\n );\n\n constructor() {\n super();\n\n // Wire the autosize toggle. The CDK directive is always mounted via\n // hostDirectives; we just flip its `enabled` setter based on our input.\n effect(() => {\n if (this.cdkAutosize) {\n this.cdkAutosize.enabled = this.autosize();\n }\n });\n }\n\n /** Triggers a CDK autosize recalculation. Useful after programmatic value changes that bypass the native `(input)` event (e.g., clipboard write APIs). No-op when `autosize` is `false`. */\n resizeToFitContent(force = false): void {\n if (this.cdkAutosize && this.autosize()) {\n this.cdkAutosize.resizeToFitContent(force);\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cdevhub-ngx-tw-textarea.mjs","sources":["../../../projects/ngx-tw/textarea/textarea.ts","../../../projects/ngx-tw/textarea/cdevhub-ngx-tw-textarea.ts"],"sourcesContent":["import {\n booleanAttribute,\n computed,\n Directive,\n effect,\n forwardRef,\n inject,\n input,\n numberAttribute,\n type Signal,\n} from '@angular/core';\nimport { CdkTextareaAutosize } from '@angular/cdk/text-field';\nimport { tv } from 'tailwind-variants';\nimport type { TwSize } from '@cdevhub/ngx-tw/core';\nimport { TW_FORM_FIELD_CONTROL } from '@cdevhub/ngx-tw/form-field';\nimport { InputDirective } from '@cdevhub/ngx-tw/input';\n\n/**\n * How the user-resize handle behaves on the textarea. `'vertical'` (the\n * default) lets users drag the bottom edge to grow the textarea; `'none'`\n * locks the size; `'both'` allows free resizing on both axes (rarely useful\n * inside a form-field — the textarea can overflow the wrapper). Horizontal\n * is intentionally omitted — it breaks form-field layout in practice.\n */\nexport type TwTextareaResize = 'none' | 'vertical' | 'both';\n\nconst textareaVariants = tv(\n {\n base: '',\n variants: {\n resize: {\n none: 'resize-none',\n vertical: 'resize-y',\n both: 'resize',\n },\n },\n defaultVariants: {\n resize: 'vertical',\n },\n },\n { twMerge: true },\n);\n\n/**\n * Adapts a native `<textarea>` into an ngx-tw form-field-compatible multi-line\n * control. Extends {@link InputDirective} — inherits its form-field\n * integration, error-state machinery, autofill / focus tracking, ARIA wiring,\n * and standalone styling. Adds textarea-specific behavior: autosize composition\n * via CDK's `CdkTextareaAutosize`, a `resize` axis for the user-resize handle,\n * `rows` / `minRows` / `maxRows`, and `maxLength` with a `valueLength` signal\n * for character counters.\n *\n * Like `InputDirective`, this directive deliberately does NOT implement\n * `ControlValueAccessor`. Angular's built-in `DefaultValueAccessor` attaches to\n * the native `<textarea>` and handles value I/O for template-driven\n * (`ngModel`), reactive (`FormControl` / `formControlName`), and signal-forms\n * (`formField`) bindings — no library glue required.\n *\n * Form-control input-cap exception applies (codified in CLAUDE.md): ARIA +\n * forms baseline plus textarea-specific surface exceeds the 5–6 cap;\n * `checkbox` is the canonical 12+ exemplar.\n */\n@Directive({\n selector: 'textarea[twTextarea]',\n exportAs: 'twTextarea',\n hostDirectives: [\n {\n directive: CdkTextareaAutosize,\n inputs: [\n 'cdkAutosizeMinRows: minRows',\n 'cdkAutosizeMaxRows: maxRows',\n ],\n },\n ],\n providers: [\n {\n provide: TW_FORM_FIELD_CONTROL,\n useExisting: forwardRef(() => TextareaDirective),\n },\n ],\n host: {\n '[class]': 'classes() + \" \" + textareaClasses()',\n '[attr.id]': 'id()',\n '[attr.rows]': 'rows()',\n '[attr.maxlength]': 'maxLength() ?? null',\n '[disabled]': 'disabled()',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.aria-required]': 'required() || null',\n '(input)': '_onInput()',\n },\n})\nexport class TextareaDirective extends InputDirective {\n private readonly cdkAutosize = inject(CdkTextareaAutosize, {\n self: true,\n optional: true,\n });\n\n // @internal Re-declares the `size` input inherited from `InputDirective` so\n // it lands on this directive's own `ɵdir` input metadata. ng-packagr emits\n // `ɵdir` with only the child's directly declared inputs, so without this the\n // consumer-side strict template-check rejects `<textarea twTextarea\n // [size]=\"…\">` with NG8002. Both signals share the same `'md'` default and\n // the inherited `classes()` computed reads through polymorphism, so runtime\n // behaviour is unchanged.\n //\n // The `@ts-ignore` is needed for a CI-only quirk: under\n // `noImplicitOverride`, partial compilation resolves `InputDirective`\n // through the just-built `dist/` d.ts on CI, where TypeScript decides the\n // base member isn't visible and rejects `override` with TS4113. Locally\n // the same resolution sees the member, so `@ts-expect-error` would itself\n // flag as unused. `@ts-ignore` suppresses whichever error fires and is\n // a no-op when neither does.\n /** Density of a standalone textarea. Maps to the inline-padding + font scale (`xs` … `xl`). Ignored inside a `<tw-form-field>` — the wrapper's `size` carries density. Defaults to `'md'`. */\n // TS4113 (CI) vs TS4114 (local) divergence means neither directive matches\n // both, so we intentionally pick `@ts-ignore` over `@ts-expect-error`; see\n // the longer comment above for the full reasoning.\n /* eslint-disable-next-line @typescript-eslint/ban-ts-comment */\n // @ts-ignore — see comment above.\n override readonly size = input<TwSize>('md');\n\n /** Grows the textarea with its content (composed from CDK's `CdkTextareaAutosize`). When `true` the user-resize handle is forced off — autosize owns the height. Defaults to `false`. */\n readonly autosize = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n\n /** Minimum number of rows the textarea collapses to when `autosize` is `true`. Ignored when autosize is off. Defaults to `1`. */\n readonly minRows = input<number, unknown>(1, { transform: numberAttribute });\n\n /** Maximum number of rows the textarea expands to before scrolling, when `autosize` is `true`. `undefined` removes the cap. Ignored when autosize is off. Defaults to `undefined`. */\n readonly maxRows = input<number | undefined, unknown>(undefined, {\n transform: (v) => (v === undefined || v === null || v === '' ? undefined : numberAttribute(v)),\n });\n\n /** Number of rows for the initial render height (native `rows` attribute). Browsers honor this even when `autosize` is `true`, so first paint uses this value. Defaults to `3`. */\n readonly rows = input<number, unknown>(3, { transform: numberAttribute });\n\n /** Controls the user-resize handle: `'none'` locks the size, `'vertical'` (default) allows vertical drag, `'both'` allows both axes. Forced to `'none'` when `autosize` is `true`. Horizontal-only is intentionally not supported. */\n readonly resize = input<TwTextareaResize>('vertical');\n\n /** Maximum character count. Mirrors to the native `maxlength` attribute when defined and is exposed via the `valueLength` signal so consumers can render a \"X / N\" hint. Defaults to `undefined`. */\n readonly maxLength = input<number | undefined, unknown>(undefined, {\n transform: (v) => (v === undefined || v === null || v === '' ? undefined : numberAttribute(v)),\n });\n\n /** Current value length, updates on every `input` event. Wire `<span twHint align=\"end\">{{ ta.valueLength() }} / {{ ta.maxLength() }}</span>` for a character counter. */\n readonly valueLength: Signal<number> = computed(() => this.value()?.length ?? 0);\n\n /** @internal Textarea-specific Tailwind classes (resize axis). Combined with the inherited `classes()` in the host `[class]` binding. */\n readonly textareaClasses = computed(() =>\n // Short-circuit the resize/autosize conflict deterministically — don't\n // rely on tv variant emission order or twMerge \"last wins\" semantics.\n this.autosize()\n ? textareaVariants({ resize: 'none' })\n : textareaVariants({ resize: this.resize() }),\n );\n\n constructor() {\n super();\n\n // Wire the autosize toggle. The CDK directive is always mounted via\n // hostDirectives; we just flip its `enabled` setter based on our input.\n effect(() => {\n if (this.cdkAutosize) {\n this.cdkAutosize.enabled = this.autosize();\n }\n });\n }\n\n /** Triggers a CDK autosize recalculation. Useful after programmatic value changes that bypass the native `(input)` event (e.g., clipboard write APIs). No-op when `autosize` is `false`. */\n resizeToFitContent(force = false): void {\n if (this.cdkAutosize && this.autosize()) {\n this.cdkAutosize.resizeToFitContent(force);\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -52,20 +52,26 @@ class ThemeService {
52
52
  this.systemTheme.set(e.matches ? 'dark' : 'light');
53
53
  };
54
54
  /** The user-selected theme (may be `'system'`). */
55
- theme = signal(this.loadInitialTheme(), ...(ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []));
55
+ theme = signal(this.loadInitialTheme(), /* @ts-ignore */
56
+ ...(ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []));
56
57
  /** The OS color scheme preference. */
57
- systemTheme = signal(this.detectSystemTheme(), ...(ngDevMode ? [{ debugName: "systemTheme" }] : /* istanbul ignore next */ []));
58
+ systemTheme = signal(this.detectSystemTheme(), /* @ts-ignore */
59
+ ...(ngDevMode ? [{ debugName: "systemTheme" }] : /* istanbul ignore next */ []));
58
60
  /** The resolved theme actually applied to the DOM (never `'system'`). */
59
61
  resolvedTheme = computed(() => {
60
62
  const t = this.theme();
61
63
  return t === 'system' ? this.systemTheme() : t;
62
- }, ...(ngDevMode ? [{ debugName: "resolvedTheme" }] : /* istanbul ignore next */ []));
64
+ }, /* @ts-ignore */
65
+ ...(ngDevMode ? [{ debugName: "resolvedTheme" }] : /* istanbul ignore next */ []));
63
66
  /** True when the resolved theme is `'dark'`. */
64
- isDark = computed(() => this.resolvedTheme() === 'dark', ...(ngDevMode ? [{ debugName: "isDark" }] : /* istanbul ignore next */ []));
67
+ isDark = computed(() => this.resolvedTheme() === 'dark', /* @ts-ignore */
68
+ ...(ngDevMode ? [{ debugName: "isDark" }] : /* istanbul ignore next */ []));
65
69
  /** True when the resolved theme is `'light'`. */
66
- isLight = computed(() => this.resolvedTheme() === 'light', ...(ngDevMode ? [{ debugName: "isLight" }] : /* istanbul ignore next */ []));
70
+ isLight = computed(() => this.resolvedTheme() === 'light', /* @ts-ignore */
71
+ ...(ngDevMode ? [{ debugName: "isLight" }] : /* istanbul ignore next */ []));
67
72
  /** True when the resolved theme is `'high-contrast'`. */
68
- isHighContrast = computed(() => this.resolvedTheme() === 'high-contrast', ...(ngDevMode ? [{ debugName: "isHighContrast" }] : /* istanbul ignore next */ []));
73
+ isHighContrast = computed(() => this.resolvedTheme() === 'high-contrast', /* @ts-ignore */
74
+ ...(ngDevMode ? [{ debugName: "isHighContrast" }] : /* istanbul ignore next */ []));
69
75
  /** Snapshot of the full theme state — selected, resolved, system, and boolean flags. */
70
76
  state = computed(() => ({
71
77
  theme: this.theme(),
@@ -74,7 +80,8 @@ class ThemeService {
74
80
  isDark: this.isDark(),
75
81
  isLight: this.isLight(),
76
82
  isHighContrast: this.isHighContrast(),
77
- }), ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
83
+ }), /* @ts-ignore */
84
+ ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
78
85
  constructor() {
79
86
  if (this.isBrowser) {
80
87
  // Register the media-query listener outside the Angular zone — it fires
@@ -147,20 +154,21 @@ class ThemeService {
147
154
  /* localStorage unavailable */
148
155
  }
149
156
  }
150
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
151
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ThemeService });
157
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
158
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ThemeService });
152
159
  }
153
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ThemeService, decorators: [{
160
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ThemeService, decorators: [{
154
161
  type: Injectable
155
162
  }], ctorParameters: () => [] });
156
163
 
157
164
  class ThemeDirective {
158
165
  /** Scopes a subtree to a specific resolved theme by writing `data-theme` on the host. Required. */
159
- twTheme = input.required(...(ngDevMode ? [{ debugName: "twTheme" }] : /* istanbul ignore next */ []));
160
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ThemeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
161
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: ThemeDirective, isStandalone: true, selector: "[twTheme]", inputs: { twTheme: { classPropertyName: "twTheme", publicName: "twTheme", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.data-theme": "twTheme()" } }, ngImport: i0 });
166
+ twTheme = input.required(/* @ts-ignore */
167
+ ...(ngDevMode ? [{ debugName: "twTheme" }] : /* istanbul ignore next */ []));
168
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ThemeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
169
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: ThemeDirective, isStandalone: true, selector: "[twTheme]", inputs: { twTheme: { classPropertyName: "twTheme", publicName: "twTheme", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.data-theme": "twTheme()" } }, ngImport: i0 });
162
170
  }
163
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ThemeDirective, decorators: [{
171
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ThemeDirective, decorators: [{
164
172
  type: Directive,
165
173
  args: [{
166
174
  selector: '[twTheme]',
@@ -1 +1 @@
1
- {"version":3,"file":"cdevhub-ngx-tw-theme.mjs","sources":["../../../projects/ngx-tw/theme/theme.types.ts","../../../projects/ngx-tw/theme/theme.config.ts","../../../projects/ngx-tw/theme/theme.service.ts","../../../projects/ngx-tw/theme/theme.directive.ts","../../../projects/ngx-tw/theme/cdevhub-ngx-tw-theme.ts"],"sourcesContent":["/** The user-selectable theme. `'system'` defers to the OS `prefers-color-scheme` setting. */\nexport type TwTheme = 'light' | 'dark' | 'high-contrast' | 'system';\n\n/** The theme actually applied to the DOM after resolving `'system'` against the OS preference. */\nexport type TwResolvedTheme = 'light' | 'dark' | 'high-contrast';\n\n/** Ordered list of every {@link TwTheme} value, used by `cycleTheme()` and for UI iteration. */\nexport const TW_THEMES = ['light', 'dark', 'high-contrast', 'system'] as const satisfies readonly TwTheme[];\n\n/** Ordered list of every {@link TwResolvedTheme} value (i.e. {@link TW_THEMES} minus `'system'`). */\nexport const TW_RESOLVED_THEMES = ['light', 'dark', 'high-contrast'] as const satisfies readonly TwResolvedTheme[];\n\n/** Runtime configuration for {@link provideTheme}; controls storage, attribute name, target element, and default. */\nexport interface TwThemeConfig {\n /** The default theme when no preference is stored. Defaults to `'system'`. */\n defaultTheme: TwTheme;\n /** localStorage key for persisting theme preference. Defaults to `'ngx-tw-theme'`. */\n storageKey: string;\n /** The HTML attribute written to the target element. Defaults to `'data-theme'`. */\n attribute: string;\n /** Which element receives the theme attribute. Defaults to `'documentElement'`. */\n target: 'documentElement' | 'body';\n}\n\n/** Composite snapshot of `ThemeService` state — selected, resolved, system, and boolean flags. */\nexport interface TwThemeState {\n /** The user-selected theme — may be `'system'`. */\n readonly theme: TwTheme;\n /** The theme actually applied to the DOM — never `'system'`. */\n readonly resolvedTheme: TwResolvedTheme;\n /** The OS color-scheme preference detected via `prefers-color-scheme`. */\n readonly systemTheme: TwResolvedTheme;\n /** True when {@link resolvedTheme} is `'dark'`. */\n readonly isDark: boolean;\n /** True when {@link resolvedTheme} is `'light'`. */\n readonly isLight: boolean;\n /** True when {@link resolvedTheme} is `'high-contrast'`. */\n readonly isHighContrast: boolean;\n}\n\n/** Built-in defaults merged under any user-provided {@link TwThemeConfig} by `provideTheme()`. */\nexport const DEFAULT_TW_THEME_CONFIG: TwThemeConfig = {\n defaultTheme: 'system',\n storageKey: 'ngx-tw-theme',\n attribute: 'data-theme',\n target: 'documentElement',\n};\n","import { InjectionToken, makeEnvironmentProviders, type EnvironmentProviders } from '@angular/core';\nimport { type TwThemeConfig, DEFAULT_TW_THEME_CONFIG } from './theme.types';\nimport { ThemeService } from './theme.service';\n\n/** Injection token carrying the resolved {@link TwThemeConfig} (storage key, attribute, target element, default theme). */\nexport const THEME_CONFIG = new InjectionToken<TwThemeConfig>('THEME_CONFIG');\n\n/**\n * Registers {@link ThemeService} and a {@link THEME_CONFIG} value built by\n * merging `config` over {@link DEFAULT_TW_THEME_CONFIG}. Call once in the\n * app's environment providers.\n */\nexport function provideTheme(config?: Partial<TwThemeConfig>): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: THEME_CONFIG,\n useValue: { ...DEFAULT_TW_THEME_CONFIG, ...config },\n },\n ThemeService,\n ]);\n}\n","import {\n Injectable,\n NgZone,\n computed,\n effect,\n inject,\n signal,\n PLATFORM_ID,\n type OnDestroy,\n} from '@angular/core';\nimport { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { THEME_CONFIG } from './theme.config';\nimport { TW_THEMES, type TwTheme, type TwResolvedTheme, type TwThemeState } from './theme.types';\n\n/**\n * Stateful runtime service that owns the active theme, reacts to OS\n * `prefers-color-scheme` changes, persists the user selection to\n * `localStorage`, and writes the resolved theme onto the configured DOM\n * target as a `data-theme` attribute.\n *\n * The selected {@link theme} may be `'system'` (defer to the OS); the\n * {@link resolvedTheme} computed from it is always one of `'light'`,\n * `'dark'`, or `'high-contrast'` — never `'system'`. Register via\n * {@link provideTheme} in the app's environment providers.\n */\n@Injectable()\nexport class ThemeService implements OnDestroy {\n private readonly config = inject(THEME_CONFIG);\n private readonly document = inject(DOCUMENT);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly ngZone = inject(NgZone);\n\n private mediaQuery: MediaQueryList | null = null;\n private readonly mediaListener = (e: MediaQueryListEvent) => {\n this.systemTheme.set(e.matches ? 'dark' : 'light');\n };\n\n /** The user-selected theme (may be `'system'`). */\n readonly theme = signal<TwTheme>(this.loadInitialTheme());\n\n /** The OS color scheme preference. */\n readonly systemTheme = signal<TwResolvedTheme>(this.detectSystemTheme());\n\n /** The resolved theme actually applied to the DOM (never `'system'`). */\n readonly resolvedTheme = computed<TwResolvedTheme>(() => {\n const t = this.theme();\n return t === 'system' ? this.systemTheme() : t;\n });\n\n /** True when the resolved theme is `'dark'`. */\n readonly isDark = computed(() => this.resolvedTheme() === 'dark');\n /** True when the resolved theme is `'light'`. */\n readonly isLight = computed(() => this.resolvedTheme() === 'light');\n /** True when the resolved theme is `'high-contrast'`. */\n readonly isHighContrast = computed(() => this.resolvedTheme() === 'high-contrast');\n\n /** Snapshot of the full theme state — selected, resolved, system, and boolean flags. */\n readonly state = computed<TwThemeState>(() => ({\n theme: this.theme(),\n resolvedTheme: this.resolvedTheme(),\n systemTheme: this.systemTheme(),\n isDark: this.isDark(),\n isLight: this.isLight(),\n isHighContrast: this.isHighContrast(),\n }));\n\n constructor() {\n if (this.isBrowser) {\n // Register the media-query listener outside the Angular zone — it fires\n // on OS theme changes, not user interaction, and we don't want zone.js\n // bookkeeping for every system colour-scheme tick. The listener calls\n // `signal.set()`, which schedules its own change detection.\n this.ngZone.runOutsideAngular(() => {\n this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n this.mediaQuery.addEventListener('change', this.mediaListener);\n });\n }\n\n effect(() => {\n const resolved = this.resolvedTheme();\n const selected = this.theme();\n this.applyToDocument(resolved);\n this.persistTheme(selected);\n });\n }\n\n /** Sets the selected theme. Pass `'system'` to follow the OS preference. */\n setTheme(theme: TwTheme): void {\n this.theme.set(theme);\n }\n\n /** Advances the selected theme to the next entry in {@link TW_THEMES}, wrapping around. */\n cycleTheme(): void {\n const current = this.theme();\n const idx = TW_THEMES.indexOf(current);\n this.theme.set(TW_THEMES[(idx + 1) % TW_THEMES.length]);\n }\n\n /** Writes the configured theme attribute onto an arbitrary element — used to scope themes to a subtree. */\n applyToElement(element: HTMLElement, theme: TwResolvedTheme): void {\n element.setAttribute(this.config.attribute, theme);\n }\n\n ngOnDestroy(): void {\n this.mediaQuery?.removeEventListener('change', this.mediaListener);\n }\n\n private loadInitialTheme(): TwTheme {\n if (!this.isBrowser) return this.config.defaultTheme;\n try {\n const stored = localStorage.getItem(this.config.storageKey);\n if (stored && (TW_THEMES as readonly string[]).includes(stored)) {\n return stored as TwTheme;\n }\n } catch {\n /* localStorage unavailable */\n }\n return this.config.defaultTheme;\n }\n\n private detectSystemTheme(): TwResolvedTheme {\n if (!this.isBrowser) return 'light';\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n\n private applyToDocument(theme: TwResolvedTheme): void {\n if (!this.isBrowser) return;\n const target =\n this.config.target === 'documentElement'\n ? this.document.documentElement\n : this.document.body;\n target.setAttribute(this.config.attribute, theme);\n }\n\n private persistTheme(theme: TwTheme): void {\n if (!this.isBrowser) return;\n try {\n localStorage.setItem(this.config.storageKey, theme);\n } catch {\n /* localStorage unavailable */\n }\n }\n}\n","import { Directive, input } from '@angular/core';\nimport type { TwResolvedTheme } from './theme.types';\n\n@Directive({\n selector: '[twTheme]',\n host: {\n '[attr.data-theme]': 'twTheme()',\n },\n})\nexport class ThemeDirective {\n /** Scopes a subtree to a specific resolved theme by writing `data-theme` on the host. Required. */\n readonly twTheme = input.required<TwResolvedTheme>();\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cdevhub-ngx-tw-theme.mjs","sources":["../../../projects/ngx-tw/theme/theme.types.ts","../../../projects/ngx-tw/theme/theme.config.ts","../../../projects/ngx-tw/theme/theme.service.ts","../../../projects/ngx-tw/theme/theme.directive.ts","../../../projects/ngx-tw/theme/cdevhub-ngx-tw-theme.ts"],"sourcesContent":["/** The user-selectable theme. `'system'` defers to the OS `prefers-color-scheme` setting. */\nexport type TwTheme = 'light' | 'dark' | 'high-contrast' | 'system';\n\n/** The theme actually applied to the DOM after resolving `'system'` against the OS preference. */\nexport type TwResolvedTheme = 'light' | 'dark' | 'high-contrast';\n\n/** Ordered list of every {@link TwTheme} value, used by `cycleTheme()` and for UI iteration. */\nexport const TW_THEMES = ['light', 'dark', 'high-contrast', 'system'] as const satisfies readonly TwTheme[];\n\n/** Ordered list of every {@link TwResolvedTheme} value (i.e. {@link TW_THEMES} minus `'system'`). */\nexport const TW_RESOLVED_THEMES = ['light', 'dark', 'high-contrast'] as const satisfies readonly TwResolvedTheme[];\n\n/** Runtime configuration for {@link provideTheme}; controls storage, attribute name, target element, and default. */\nexport interface TwThemeConfig {\n /** The default theme when no preference is stored. Defaults to `'system'`. */\n defaultTheme: TwTheme;\n /** localStorage key for persisting theme preference. Defaults to `'ngx-tw-theme'`. */\n storageKey: string;\n /** The HTML attribute written to the target element. Defaults to `'data-theme'`. */\n attribute: string;\n /** Which element receives the theme attribute. Defaults to `'documentElement'`. */\n target: 'documentElement' | 'body';\n}\n\n/** Composite snapshot of `ThemeService` state — selected, resolved, system, and boolean flags. */\nexport interface TwThemeState {\n /** The user-selected theme — may be `'system'`. */\n readonly theme: TwTheme;\n /** The theme actually applied to the DOM — never `'system'`. */\n readonly resolvedTheme: TwResolvedTheme;\n /** The OS color-scheme preference detected via `prefers-color-scheme`. */\n readonly systemTheme: TwResolvedTheme;\n /** True when {@link resolvedTheme} is `'dark'`. */\n readonly isDark: boolean;\n /** True when {@link resolvedTheme} is `'light'`. */\n readonly isLight: boolean;\n /** True when {@link resolvedTheme} is `'high-contrast'`. */\n readonly isHighContrast: boolean;\n}\n\n/** Built-in defaults merged under any user-provided {@link TwThemeConfig} by `provideTheme()`. */\nexport const DEFAULT_TW_THEME_CONFIG: TwThemeConfig = {\n defaultTheme: 'system',\n storageKey: 'ngx-tw-theme',\n attribute: 'data-theme',\n target: 'documentElement',\n};\n","import { InjectionToken, makeEnvironmentProviders, type EnvironmentProviders } from '@angular/core';\nimport { type TwThemeConfig, DEFAULT_TW_THEME_CONFIG } from './theme.types';\nimport { ThemeService } from './theme.service';\n\n/** Injection token carrying the resolved {@link TwThemeConfig} (storage key, attribute, target element, default theme). */\nexport const THEME_CONFIG = new InjectionToken<TwThemeConfig>('THEME_CONFIG');\n\n/**\n * Registers {@link ThemeService} and a {@link THEME_CONFIG} value built by\n * merging `config` over {@link DEFAULT_TW_THEME_CONFIG}. Call once in the\n * app's environment providers.\n */\nexport function provideTheme(config?: Partial<TwThemeConfig>): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: THEME_CONFIG,\n useValue: { ...DEFAULT_TW_THEME_CONFIG, ...config },\n },\n ThemeService,\n ]);\n}\n","import {\n Injectable,\n NgZone,\n computed,\n effect,\n inject,\n signal,\n PLATFORM_ID,\n type OnDestroy,\n} from '@angular/core';\nimport { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { THEME_CONFIG } from './theme.config';\nimport { TW_THEMES, type TwTheme, type TwResolvedTheme, type TwThemeState } from './theme.types';\n\n/**\n * Stateful runtime service that owns the active theme, reacts to OS\n * `prefers-color-scheme` changes, persists the user selection to\n * `localStorage`, and writes the resolved theme onto the configured DOM\n * target as a `data-theme` attribute.\n *\n * The selected {@link theme} may be `'system'` (defer to the OS); the\n * {@link resolvedTheme} computed from it is always one of `'light'`,\n * `'dark'`, or `'high-contrast'` — never `'system'`. Register via\n * {@link provideTheme} in the app's environment providers.\n */\n@Injectable()\nexport class ThemeService implements OnDestroy {\n private readonly config = inject(THEME_CONFIG);\n private readonly document = inject(DOCUMENT);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly ngZone = inject(NgZone);\n\n private mediaQuery: MediaQueryList | null = null;\n private readonly mediaListener = (e: MediaQueryListEvent) => {\n this.systemTheme.set(e.matches ? 'dark' : 'light');\n };\n\n /** The user-selected theme (may be `'system'`). */\n readonly theme = signal<TwTheme>(this.loadInitialTheme());\n\n /** The OS color scheme preference. */\n readonly systemTheme = signal<TwResolvedTheme>(this.detectSystemTheme());\n\n /** The resolved theme actually applied to the DOM (never `'system'`). */\n readonly resolvedTheme = computed<TwResolvedTheme>(() => {\n const t = this.theme();\n return t === 'system' ? this.systemTheme() : t;\n });\n\n /** True when the resolved theme is `'dark'`. */\n readonly isDark = computed(() => this.resolvedTheme() === 'dark');\n /** True when the resolved theme is `'light'`. */\n readonly isLight = computed(() => this.resolvedTheme() === 'light');\n /** True when the resolved theme is `'high-contrast'`. */\n readonly isHighContrast = computed(() => this.resolvedTheme() === 'high-contrast');\n\n /** Snapshot of the full theme state — selected, resolved, system, and boolean flags. */\n readonly state = computed<TwThemeState>(() => ({\n theme: this.theme(),\n resolvedTheme: this.resolvedTheme(),\n systemTheme: this.systemTheme(),\n isDark: this.isDark(),\n isLight: this.isLight(),\n isHighContrast: this.isHighContrast(),\n }));\n\n constructor() {\n if (this.isBrowser) {\n // Register the media-query listener outside the Angular zone — it fires\n // on OS theme changes, not user interaction, and we don't want zone.js\n // bookkeeping for every system colour-scheme tick. The listener calls\n // `signal.set()`, which schedules its own change detection.\n this.ngZone.runOutsideAngular(() => {\n this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n this.mediaQuery.addEventListener('change', this.mediaListener);\n });\n }\n\n effect(() => {\n const resolved = this.resolvedTheme();\n const selected = this.theme();\n this.applyToDocument(resolved);\n this.persistTheme(selected);\n });\n }\n\n /** Sets the selected theme. Pass `'system'` to follow the OS preference. */\n setTheme(theme: TwTheme): void {\n this.theme.set(theme);\n }\n\n /** Advances the selected theme to the next entry in {@link TW_THEMES}, wrapping around. */\n cycleTheme(): void {\n const current = this.theme();\n const idx = TW_THEMES.indexOf(current);\n this.theme.set(TW_THEMES[(idx + 1) % TW_THEMES.length]);\n }\n\n /** Writes the configured theme attribute onto an arbitrary element — used to scope themes to a subtree. */\n applyToElement(element: HTMLElement, theme: TwResolvedTheme): void {\n element.setAttribute(this.config.attribute, theme);\n }\n\n ngOnDestroy(): void {\n this.mediaQuery?.removeEventListener('change', this.mediaListener);\n }\n\n private loadInitialTheme(): TwTheme {\n if (!this.isBrowser) return this.config.defaultTheme;\n try {\n const stored = localStorage.getItem(this.config.storageKey);\n if (stored && (TW_THEMES as readonly string[]).includes(stored)) {\n return stored as TwTheme;\n }\n } catch {\n /* localStorage unavailable */\n }\n return this.config.defaultTheme;\n }\n\n private detectSystemTheme(): TwResolvedTheme {\n if (!this.isBrowser) return 'light';\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n\n private applyToDocument(theme: TwResolvedTheme): void {\n if (!this.isBrowser) return;\n const target =\n this.config.target === 'documentElement'\n ? this.document.documentElement\n : this.document.body;\n target.setAttribute(this.config.attribute, theme);\n }\n\n private persistTheme(theme: TwTheme): void {\n if (!this.isBrowser) return;\n try {\n localStorage.setItem(this.config.storageKey, theme);\n } catch {\n /* localStorage unavailable */\n }\n }\n}\n","import { Directive, input } from '@angular/core';\nimport type { TwResolvedTheme } from './theme.types';\n\n@Directive({\n selector: '[twTheme]',\n host: {\n '[attr.data-theme]': 'twTheme()',\n },\n})\nexport class ThemeDirective {\n /** Scopes a subtree to a specific resolved theme by writing `data-theme` on the host. Required. */\n readonly twTheme = input.required<TwResolvedTheme>();\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAMA;AACO,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ;AAEpE;AACO,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe;AA8BnE;AACO,MAAM,uBAAuB,GAAkB;AACpD,IAAA,YAAY,EAAE,QAAQ;AACtB,IAAA,UAAU,EAAE,cAAc;AAC1B,IAAA,SAAS,EAAE,YAAY;AACvB,IAAA,MAAM,EAAE,iBAAiB;;;ACzC3B;MACa,YAAY,GAAG,IAAI,cAAc,CAAgB,cAAc;AAE5E;;;;AAIG;AACG,SAAU,YAAY,CAAC,MAA+B,EAAA;AAC1D,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA;AACE,YAAA,OAAO,EAAE,YAAY;AACrB,YAAA,QAAQ,EAAE,EAAE,GAAG,uBAAuB,EAAE,GAAG,MAAM,EAAE;AACpD,SAAA;QACD,YAAY;AACb,KAAA,CAAC;AACJ;;ACNA;;;;;;;;;;AAUG;MAEU,YAAY,CAAA;AACN,IAAA,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC;AAC7B,IAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC3B,SAAS,GAAG,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AAClD,IAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAEhC,UAAU,GAA0B,IAAI;AAC/B,IAAA,aAAa,GAAG,CAAC,CAAsB,KAAI;AAC1D,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AACpD,IAAA,CAAC;;AAGQ,IAAA,KAAK,GAAG,MAAM,CAAU,IAAI,CAAC,gBAAgB,EAAE;8EAAC;;AAGhD,IAAA,WAAW,GAAG,MAAM,CAAkB,IAAI,CAAC,iBAAiB,EAAE;oFAAC;;AAG/D,IAAA,aAAa,GAAG,QAAQ,CAAkB,MAAK;AACtD,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE;AACtB,QAAA,OAAO,CAAC,KAAK,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC;IAChD,CAAC;sFAAC;;IAGO,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,KAAK,MAAM;+EAAC;;IAExD,OAAO,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,KAAK,OAAO;gFAAC;;IAE1D,cAAc,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,KAAK,eAAe;uFAAC;;AAGzE,IAAA,KAAK,GAAG,QAAQ,CAAe,OAAO;AAC7C,QAAA,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;AACnB,QAAA,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE;AACnC,QAAA,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE;AAC/B,QAAA,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;AACrB,QAAA,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;AACvB,QAAA,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE;KACtC,CAAC;8EAAC;AAEH,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;;;;;AAKlB,YAAA,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,MAAK;gBACjC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC;gBACnE,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC;AAChE,YAAA,CAAC,CAAC;QACJ;QAEA,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE;AACrC,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE;AAC7B,YAAA,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;AAC9B,YAAA,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC;AAC7B,QAAA,CAAC,CAAC;IACJ;;AAGA,IAAA,QAAQ,CAAC,KAAc,EAAA;AACrB,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;IACvB;;IAGA,UAAU,GAAA;AACR,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE;QAC5B,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC;AACtC,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;IACzD;;IAGA,cAAc,CAAC,OAAoB,EAAE,KAAsB,EAAA;QACzD,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC;IACpD;IAEA,WAAW,GAAA;QACT,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC;IACpE;IAEQ,gBAAgB,GAAA;QACtB,IAAI,CAAC,IAAI,CAAC,SAAS;AAAE,YAAA,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY;AACpD,QAAA,IAAI;AACF,YAAA,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;YAC3D,IAAI,MAAM,IAAK,SAA+B,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AAC/D,gBAAA,OAAO,MAAiB;YAC1B;QACF;AAAE,QAAA,MAAM;;QAER;AACA,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY;IACjC;IAEQ,iBAAiB,GAAA;QACvB,IAAI,CAAC,IAAI,CAAC,SAAS;AAAE,YAAA,OAAO,OAAO;AACnC,QAAA,OAAO,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,OAAO,GAAG,MAAM,GAAG,OAAO;IACrF;AAEQ,IAAA,eAAe,CAAC,KAAsB,EAAA;QAC5C,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE;QACrB,MAAM,MAAM,GACV,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK;AACrB,cAAE,IAAI,CAAC,QAAQ,CAAC;AAChB,cAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;QACxB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC;IACnD;AAEQ,IAAA,YAAY,CAAC,KAAc,EAAA;QACjC,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE;AACrB,QAAA,IAAI;YACF,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC;QACrD;AAAE,QAAA,MAAM;;QAER;IACF;uGAnHW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;2GAAZ,YAAY,EAAA,CAAA;;2FAAZ,YAAY,EAAA,UAAA,EAAA,CAAA;kBADxB;;;MChBY,cAAc,CAAA;;IAEhB,OAAO,GAAG,KAAK,CAAC,QAAQ;gFAAmB;uGAFzC,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAd,cAAc,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAd,cAAc,EAAA,UAAA,EAAA,CAAA;kBAN1B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,WAAW;AACrB,oBAAA,IAAI,EAAE;AACJ,wBAAA,mBAAmB,EAAE,WAAW;AACjC,qBAAA;AACF,iBAAA;;;ACRD;;AAEG;;;;"}