@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-checkbox.mjs","sources":["../../../projects/ngx-tw/checkbox/checkbox.ts","../../../projects/ngx-tw/checkbox/cdevhub-ngx-tw-checkbox.ts"],"sourcesContent":["import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n forwardRef,\n inject,\n input,\n isDevMode,\n linkedSignal,\n model,\n type OnInit,\n output,\n signal,\n type Signal,\n} from '@angular/core';\nimport {\n type ControlValueAccessor,\n FormGroupDirective,\n NgControl,\n NgForm,\n Validators,\n} from '@angular/forms';\nimport { FocusMonitor } 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 { FormFieldControl, TW_FORM_FIELD_CONTROL } from '@cdevhub/ngx-tw/form-field';\n\n/** Visual style of the checkbox when checked or indeterminate. */\nexport type CheckboxVariant = 'solid' | 'outline';\n\n/** Position of the label relative to the checkbox control. */\nexport type CheckboxLabelPosition = 'before' | 'after';\n\n// ── tv() config ──────────────────────────────────────────────────\n\nconst checkboxVariants = tv(\n {\n slots: {\n // `items-start` aligns the boxWrap with the top of the label container; combined with\n // a `min-h-N` matching the label's first-line line-height on boxWrap, the box stays\n // centered on the first line of the label whether it spans one line or many.\n root: 'relative inline-flex items-start gap-3 cursor-pointer select-none rounded-md focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n boxWrap: 'relative inline-flex items-center justify-center shrink-0',\n box: 'inline-flex items-center justify-center rounded-md border transition-colors duration-normal motion-reduce:transition-none',\n icon: 'absolute inset-0 flex items-center justify-center pointer-events-none empty:hidden',\n labelWrap: 'flex flex-col min-w-0 empty:hidden',\n label: 'font-medium text-fg empty:hidden',\n description: 'text-fg-muted empty:hidden',\n },\n variants: {\n size: {\n xs: {\n // `size-3.5` half-step: aligns with text-xs/leading-4. Codified per CLAUDE.md.\n box: 'size-3.5',\n icon: '[&_svg]:size-3',\n boxWrap: 'min-h-4',\n label: 'text-xs leading-4',\n description: 'text-2xs leading-4',\n },\n sm: {\n box: 'size-4',\n icon: '[&_svg]:size-3',\n boxWrap: 'min-h-5',\n label: 'text-sm leading-5',\n description: 'text-xs leading-4',\n },\n md: {\n box: 'size-5',\n // md icon uses `size-3.5` (14px) — proportional inset (70%) of the\n // size-5 (20px) box; the half-step is the only size that fills the\n // checkmark without crowding the box edges.\n icon: '[&_svg]:size-3.5',\n boxWrap: 'min-h-5',\n label: 'text-sm leading-5',\n description: 'text-xs leading-4',\n },\n lg: {\n box: 'size-6',\n icon: '[&_svg]:size-4',\n boxWrap: 'min-h-6',\n label: 'text-base leading-6',\n description: 'text-sm leading-5',\n },\n xl: {\n box: 'size-7',\n icon: '[&_svg]:size-5',\n // xl box (28px) > default text-base line-height (24px); bump leading to leading-7\n // so the first line height matches the box and they align cleanly.\n boxWrap: 'min-h-7',\n label: 'text-base leading-7',\n description: 'text-sm leading-5',\n },\n },\n labelPosition: {\n before: { root: 'flex-row-reverse' },\n after: { root: 'flex-row' },\n },\n active: {\n true: { box: '' },\n false: { box: 'bg-surface border-border hover:border-border-strong' },\n },\n disabled: {\n true: { root: 'opacity-50 pointer-events-none cursor-not-allowed' },\n false: { root: '' },\n },\n },\n defaultVariants: {\n size: 'md',\n labelPosition: 'after',\n active: false,\n disabled: false,\n },\n },\n { twMerge: true },\n);\n\n// ── Static active-state color lookups (statically written for Tailwind v4 scanning) ──\n\nconst SOLID_BOX: Record<TwColor, string> = {\n primary: 'bg-primary-600 border-primary-600',\n secondary: 'bg-secondary-600 border-secondary-600',\n accent: 'bg-accent-600 border-accent-600',\n neutral: 'bg-fg border-fg',\n info: 'bg-info-600 border-info-600',\n success: 'bg-success-600 border-success-600',\n warning: 'bg-warning-500 border-warning-500',\n error: 'bg-error-600 border-error-600',\n};\n\nconst SOLID_ICON: Record<TwColor, string> = {\n primary: 'text-on-primary',\n secondary: 'text-on-secondary',\n accent: 'text-on-accent',\n neutral: 'text-on-neutral',\n info: 'text-on-info',\n success: 'text-on-success',\n warning: 'text-on-warning',\n error: 'text-on-error',\n};\n\nconst OUTLINE_BOX: Record<TwColor, string> = {\n primary: 'bg-surface border-primary-600',\n secondary: 'bg-surface border-secondary-600',\n accent: 'bg-surface border-accent-600',\n neutral: 'bg-surface border-fg',\n info: 'bg-surface border-info-600',\n success: 'bg-surface border-success-600',\n warning: 'bg-surface border-warning-500',\n error: 'bg-surface border-error-600',\n};\n\nconst OUTLINE_ICON: Record<TwColor, string> = {\n primary: 'text-primary-600',\n secondary: 'text-secondary-600',\n accent: 'text-accent-600',\n neutral: 'text-fg',\n info: 'text-info-600',\n success: 'text-success-600',\n warning: 'text-warning-600',\n error: 'text-error-600',\n};\n\nlet nextId = 0;\n\n// ── CheckboxComponent ────────────────────────────────────────────\n\n@Component({\n selector: 'tw-checkbox',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: TW_FORM_FIELD_CONTROL,\n useExisting: forwardRef(() => CheckboxComponent),\n },\n ],\n template: `\n <input\n type=\"checkbox\"\n class=\"sr-only\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [name]=\"name() || null\"\n [checked]=\"internalChecked()\"\n [disabled]=\"isDisabled()\"\n />\n\n <span [class]=\"boxWrapClasses()\">\n <span [class]=\"boxClasses()\">\n <span [class]=\"iconClasses()\">\n @if (internalIndeterminate()) {\n <span [class]=\"iconColorClasses()\" animate.enter=\"check-in\">\n <ng-content select=\"[slot='indeterminate-icon']\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path\n d=\"M5 12 h14\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </ng-content>\n </span>\n } @else if (internalChecked()) {\n <span [class]=\"iconColorClasses()\" animate.enter=\"check-in\">\n <ng-content select=\"[slot='check-icon']\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path\n d=\"M5 12 l5 5 l9 -11\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </ng-content>\n </span>\n }\n </span>\n </span>\n </span>\n\n <span [class]=\"labelWrapClasses()\">\n <span [id]=\"labelElementId()\" [class]=\"labelClasses()\">\n <ng-content>\n @if (label()) {\n {{ label() }}\n }\n </ng-content>\n </span>\n <span [id]=\"descriptionElementId()\" [class]=\"descriptionClasses()\">\n <ng-content select=\"[slot='description']\">\n @if (description()) {\n {{ description() }}\n }\n </ng-content>\n </span>\n </span>\n `,\n host: {\n 'role': 'checkbox',\n '[id]': 'id()',\n '[class]': 'rootClasses()',\n '[attr.data-checked]': 'internalChecked()',\n '[attr.data-indeterminate]': 'internalIndeterminate()',\n '[attr.aria-checked]': 'ariaCheckedValue()',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '[attr.aria-required]': 'required() || null',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'effectiveAriaLabelledby() || null',\n '[attr.aria-describedby]': 'effectiveAriaDescribedby() || null',\n '[attr.tabindex]': 'isDisabled() ? -1 : 0',\n '[attr.name]': 'name() || null',\n '(click)': 'toggle()',\n '(keydown)': 'onKeydown($event)',\n '(blur)': 'onBlur()',\n },\n})\nexport class CheckboxComponent\n extends FormFieldControl<boolean>\n implements ControlValueAccessor, OnInit\n{\n /** Sets the semantic color for the checked and indeterminate box fill/border. Defaults to `'primary'`. */\n readonly color = input<TwColor>('primary');\n\n /** Controls the overall scale of the box, check icon, and label typography. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Visual style when checked or indeterminate. `'solid'` fills the box with the color; `'outline'` keeps a transparent fill with a colored border and check. Defaults to `'solid'`. */\n readonly variant = input<CheckboxVariant>('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\"` so assistive tech announces the control as required. Defaults to `false`. */\n readonly requiredInput = input(false, { alias: 'required' });\n\n /** Optional inline label rendered next to the checkbox. Use default content projection for rich label content instead. Projection takes precedence. */\n readonly label = input<string | undefined>(undefined);\n\n /** Optional secondary description rendered under the label. Use `[slot=\"description\"]` content projection for rich content instead. Projection takes precedence. */\n readonly description = input<string | undefined>(undefined);\n\n /** Position of the label/description relative to the checkbox. Defaults to `'after'`. */\n readonly labelPosition = input<CheckboxLabelPosition>('after');\n\n /** Optional name attribute, applied to the hidden native `<input type=\"checkbox\">` so native form submission includes the control. */\n readonly name = input<string | undefined>(undefined);\n\n /** Id on the host element. Auto-generated as `tw-checkbox-N` when not provided. Used by the form-field's `<label for>` attribute. */\n readonly idInput = input<string | undefined>(undefined, { alias: 'id' });\n\n /** Accessible name when no visible label is provided. Mirrored to `aria-label`. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** ID of an external element that labels the checkbox. Mirrored to `aria-labelledby`. */\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n /** ID of an external element that describes the checkbox. Mirrored to `aria-describedby`. 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, the directive uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n /** Two-way bound checked state. Updates when the user toggles via click or Space. */\n readonly checked = model(false);\n\n /** Two-way bound indeterminate state. When true, the box shows a dash and the host exposes `aria-checked=\"mixed\"`. Any user toggle clears indeterminate and sets `checked` to `true`. */\n readonly indeterminate = model(false);\n\n /** Fires after the checked state changes from a user interaction. Does not fire when the value is updated programmatically via `writeValue`. */\n readonly change = output<boolean>();\n\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly destroyRef = inject(DestroyRef);\n private readonly ngControl = inject(NgControl, { optional: true, self: true });\n private readonly parentForm = inject(NgForm, { optional: true });\n private readonly parentFormGroup = inject(FormGroupDirective, { optional: true });\n private readonly defaultMatcher = inject(TW_ERROR_STATE_MATCHER);\n\n private onChange: (value: boolean) => void = () => {};\n private onTouched: () => void = () => {};\n private readonly cvaDisabled = signal(false);\n\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\n private readonly uid = nextId++;\n /** @internal Fallback id used when the consumer does not set `[id]`. */\n readonly hostId = `tw-checkbox-${this.uid}`;\n\n /** @internal Resolved id on the host element. */\n readonly id: Signal<string> = computed(() => this.idInput() ?? this.hostId);\n\n /** @internal Id of the internal label `<span>`, derived from the resolved host id. */\n readonly labelElementId = computed(() => `${this.id()}-label`);\n\n /** @internal Id of the internal description `<span>`, derived from the resolved host id. */\n readonly descriptionElementId = computed(() => `${this.id()}-description`);\n\n constructor() {\n super();\n // Material-style CVA wiring: declare ourselves as the value accessor on any\n // host-level `NgControl` (FormControlDirective, NgModel, etc.). This avoids\n // the circular-DI that a static `NG_VALUE_ACCESSOR` provider would create\n // because `NgControl` is injected with `self: true` on the same element.\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n afterNextRender(() => {\n if (isDevMode() && !this.hasAccessibleNameHint()) {\n console.warn(\n '[tw-checkbox] The checkbox has no accessible name. Provide a `label` input, project label content, or set `aria-label` / `aria-labelledby`.',\n );\n }\n });\n }\n\n /** @internal */\n readonly isDisabled = computed(() => this.disabled() || this.cvaDisabled());\n\n /**\n * @internal Visible-state mirror of the `checked` model. `linkedSignal` keeps it\n * synced with parent updates (including `writeValue` from reactive forms), while\n * also accepting explicit `set()` calls from `toggle()` / `writeValue()` so the\n * DOM reflects the new state synchronously — before `checkedChange` propagates\n * through the host binding round-trip. Reading this signal in host bindings\n * (`aria-checked`, `data-checked`, box classes) decouples render from the\n * model's notification cadence.\n */\n readonly internalChecked = linkedSignal(() => this.checked());\n\n /**\n * @internal Visible-state mirror of the `indeterminate` model. Same rationale as\n * `internalChecked` — `toggle()` and `writeValue()` clear it synchronously so\n * `aria-checked=\"mixed\"` flips off in the same microtask as `aria-checked=\"true\"`.\n */\n readonly internalIndeterminate = linkedSignal(() => this.indeterminate());\n\n readonly ariaCheckedValue = computed(() => {\n if (this.internalIndeterminate()) return 'mixed';\n return this.internalChecked() ? 'true' : 'false';\n });\n\n readonly effectiveAriaLabelledby = computed(() => {\n const external = this.ariaLabelledby();\n if (external) return external;\n if (this.ariaLabel()) return undefined;\n return this.labelElementId();\n });\n\n readonly effectiveAriaDescribedby = computed(() => {\n const merged: string[] = [];\n const extra = this.describedByIdsSignal();\n for (const id of extra) merged.push(id);\n const external = this.ariaDescribedby();\n if (external) {\n for (const id of external.split(/\\s+/).filter(Boolean)) merged.push(id);\n } else if (extra.length === 0) {\n // Only fall back to the internal description id when no external sources are wired.\n merged.push(this.descriptionElementId());\n }\n return merged.length ? merged.join(' ') : undefined;\n });\n\n private readonly isActive = computed(() => this.internalChecked() || this.internalIndeterminate());\n\n // ── FormFieldControl signals ──\n\n /** @internal */\n readonly value: Signal<boolean | null> = computed(() => this.internalChecked());\n\n /** @internal */\n readonly focused: Signal<boolean> = this._focused.asReadonly();\n\n /** @internal Checkboxes are never empty in the form-field sense — they always have a boolean value. */\n readonly empty: Signal<boolean> = computed(() => false);\n\n /** @internal */\n readonly required: Signal<boolean> = computed(() => {\n this._ngControlRev();\n if (this.requiredInput()) return true;\n const ctrl = this.ngControl?.control;\n if (!ctrl) return false;\n return ctrl.hasValidator(Validators.required) || ctrl.hasValidator(Validators.requiredTrue);\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 */\n readonly controlType = 'checkbox';\n\n /** @internal */\n readonly userAriaDescribedBy: Signal<string | undefined> = computed(() => this.ariaDescribedby());\n\n private readonly variantResult = computed(() =>\n checkboxVariants({\n size: this.size(),\n labelPosition: this.labelPosition(),\n active: this.isActive(),\n disabled: this.isDisabled(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly boxWrapClasses = computed(() => this.variantResult().boxWrap());\n readonly iconClasses = computed(() => this.variantResult().icon());\n readonly labelWrapClasses = computed(() => this.variantResult().labelWrap());\n readonly labelClasses = computed(() => this.variantResult().label());\n readonly descriptionClasses = computed(() => this.variantResult().description());\n\n readonly boxClasses = computed(() => {\n const base = this.variantResult().box();\n const active = this.isActive();\n const error = this.errorState();\n const variant = this.variant();\n const effectiveColor: TwColor = error ? 'error' : this.color();\n if (!active) {\n if (error) return `${base} border-error-500`;\n return base;\n }\n const lookup = variant === 'solid' ? SOLID_BOX : OUTLINE_BOX;\n return `${base} ${lookup[effectiveColor]}`;\n });\n\n readonly iconColorClasses = computed(() => {\n const lookup = this.variant() === 'solid' ? SOLID_ICON : OUTLINE_ICON;\n const effectiveColor: TwColor = this.errorState() ? 'error' : this.color();\n return `inline-flex items-center justify-center ${lookup[effectiveColor]}`;\n });\n\n // ── Interactions ──────────────────────────────────────────\n\n /** Toggles the checked state. Clears indeterminate if set. No-op when disabled. */\n toggle(): void {\n if (this.isDisabled()) return;\n const wasIndeterminate = this.internalIndeterminate();\n const next = wasIndeterminate ? true : !this.internalChecked();\n this.internalChecked.set(next);\n this.checked.set(next);\n if (wasIndeterminate) {\n this.internalIndeterminate.set(false);\n this.indeterminate.set(false);\n }\n this.onChange(next);\n this.onTouched();\n this.change.emit(next);\n }\n\n /** Handles keyboard activation. Only Space toggles — matches native checkbox semantics. */\n onKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) return;\n if (event.key === ' ' || event.key === 'Spacebar') {\n event.preventDefault();\n this.toggle();\n }\n }\n\n /** @internal Called on host blur to notify forms the control has been touched and recompute errorState. */\n onBlur(): void {\n this.onTouched();\n this._ngControlRev.update((n) => n + 1);\n }\n\n // ── ControlValueAccessor ──────────────────────────────────\n\n writeValue(value: boolean | null | undefined): void {\n const next = !!value;\n this.internalChecked.set(next);\n this.checked.set(next);\n this.internalIndeterminate.set(false);\n this.indeterminate.set(false);\n }\n\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n // ── FormFieldControl methods ──\n\n /** @internal Called by the form-field once it has computed the merged describedby ids. */\n setDescribedByIds(ids: string[]): void {\n this.describedByIdsSignal.set([...ids]);\n }\n\n /** @internal Called when the form-field container is clicked — focus the host without toggling. */\n onContainerClick(event: MouseEvent): void {\n if (this.isDisabled()) 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 host.focus();\n }\n\n // ── Lifecycle ─────────────────────────────────────────────\n\n ngOnInit(): void {\n const monitor$ = this.focusMonitor.monitor(this.elementRef);\n if (isObservable(monitor$)) {\n monitor$\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((origin) => {\n const wasFocused = this._focused();\n this._focused.set(!!origin);\n if (wasFocused && !origin) {\n // Blur often flips `touched` on the bound `NgControl`; notify forms\n // and bump the revision so `errorState` recomputes.\n this.onTouched();\n this._ngControlRev.update((n) => n + 1);\n }\n });\n }\n this.destroyRef.onDestroy(() => {\n this.focusMonitor.stopMonitoring(this.elementRef);\n });\n\n // NgControl's `control` is set by the parent FormControl* directive before\n // children's `ngOnInit`. Subscribe here so errorState reacts to status/value\n // changes on the bound control.\n const ctrl = this.ngControl?.control;\n if (ctrl) {\n const streams = [ctrl.statusChanges, ctrl.valueChanges].filter(\n (s): s is NonNullable<typeof s> => !!s,\n );\n if (streams.length) {\n merge(...streams)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._ngControlRev.update((n) => n + 1));\n }\n }\n\n const submit = this.parentFormGroup?.ngSubmit ?? this.parentForm?.ngSubmit;\n if (submit) {\n submit\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._formSubmitRev.update((n) => n + 1));\n }\n }\n\n private hasAccessibleNameHint(): boolean {\n if (this.label() || this.ariaLabel() || this.ariaLabelledby()) return true;\n const host = this.elementRef.nativeElement;\n return host.textContent !== null && host.textContent.trim().length > 0;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,228 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Directive, input, booleanAttribute, output, model, inject, DestroyRef, computed, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { Clipboard } from '@angular/cdk/clipboard';
4
+ import { LiveAnnouncer } from '@angular/cdk/a11y';
5
+ import { tv } from 'tailwind-variants';
6
+
7
+ /**
8
+ * Marker directive for projected header content (e.g. filename, secondary
9
+ * actions). Sits alongside the language label inside the code block's
10
+ * header row.
11
+ *
12
+ * @remarks
13
+ * The host class (`inline-flex items-center gap-2 min-w-0`) styles the
14
+ * projected element's *own* children — e.g. a filename `<span>` next to a
15
+ * "modified" badge — and is distinct from the library's `headerStart` slot
16
+ * wrapper that contains this element. The two carry overlapping utility names
17
+ * (`items-center gap-2 min-w-0`) because both lay out flex children, but they
18
+ * apply to different DOM nodes (parent slot vs the projected element itself)
19
+ * and serve different jobs (slot row geometry vs the consumer's badge group).
20
+ */
21
+ class CodeBlockHeaderDirective {
22
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CodeBlockHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
23
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.14", type: CodeBlockHeaderDirective, isStandalone: true, selector: "[twCodeBlockHeader]", host: { classAttribute: "inline-flex items-center gap-2 min-w-0" }, ngImport: i0 });
24
+ }
25
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CodeBlockHeaderDirective, decorators: [{
26
+ type: Directive,
27
+ args: [{
28
+ selector: '[twCodeBlockHeader]',
29
+ host: {
30
+ class: 'inline-flex items-center gap-2 min-w-0',
31
+ },
32
+ }]
33
+ }] });
34
+ const codeBlockVariants = tv({
35
+ slots: {
36
+ root: 'flex flex-col rounded-lg overflow-hidden font-mono text-sm',
37
+ header: 'flex items-center justify-between gap-2 px-4 py-2 border-b border-border text-xs text-fg-muted',
38
+ headerStart: 'flex items-center gap-2 min-w-0 flex-1',
39
+ pre: 'p-4 text-fg overflow-x-auto tw-scrollbar-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',
40
+ copyButton: 'inline-flex items-center justify-center size-8 rounded-md cursor-pointer text-fg-muted hover:text-fg hover:bg-surface-muted transition-colors duration-normal motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',
41
+ copyIcon: 'size-4 shrink-0',
42
+ },
43
+ variants: {
44
+ variant: {
45
+ filled: { root: 'bg-surface-sunken border border-border-strong' },
46
+ outlined: { root: 'bg-transparent border border-border' },
47
+ },
48
+ copied: {
49
+ true: { copyButton: 'text-success-500 hover:text-success-500' },
50
+ false: {},
51
+ },
52
+ },
53
+ defaultVariants: {
54
+ variant: 'filled',
55
+ copied: false,
56
+ },
57
+ }, {
58
+ twMerge: true,
59
+ });
60
+ /**
61
+ * Code-display surface with copy-to-clipboard, optional language label, and a
62
+ * projection slot for filename / extra actions.
63
+ *
64
+ * @remarks
65
+ * **`role="region"` ownership.** The outer host is a presentational container —
66
+ * the inner `<pre tabindex="0" role="region" aria-label="...">` owns the
67
+ * scrollable-content region semantics that screen readers and AXE care about.
68
+ * Promoting the host to `role="region"` as well would double-announce the
69
+ * landmark; the `<pre>` is the focusable, keyboard-reachable target, so the
70
+ * region role belongs there. This matches APG guidance for scroll-region
71
+ * widgets and Material's `pre`-as-region pattern.
72
+ */
73
+ class CodeBlockComponent {
74
+ /** The code string to display and copy to clipboard. */
75
+ code = input.required(...(ngDevMode ? [{ debugName: "code" }] : /* istanbul ignore next */ []));
76
+ /** Optional language label displayed in the header (e.g. `'TypeScript'`, `'HTML'`). */
77
+ language = input(...(ngDevMode ? [undefined, { debugName: "language" }] : /* istanbul ignore next */ []));
78
+ /** Visual style of the container. Defaults to `'filled'`. */
79
+ variant = input('filled', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
80
+ /** When true, wraps long lines instead of horizontal scrolling. Defaults to `false`. */
81
+ wrap = input(false, { ...(ngDevMode ? { debugName: "wrap" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
82
+ /**
83
+ * Localizable strings for the copy button's aria-labels and the
84
+ * screen-reader announcement. Provide a partial override; missing fields
85
+ * fall back to English defaults.
86
+ */
87
+ labels = input({}, ...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
88
+ /** Fires when code is successfully copied to clipboard. */
89
+ copied = output();
90
+ /** Fires when the clipboard copy fails (e.g. user denied permission, no clipboard API available). Payload is an `Error` describing the failure. */
91
+ copyFailed = output();
92
+ /** Whether the copy-to-clipboard button is currently in its "copied" confirmation state. Two-way bindable via `[(isCopied)]`. Set to `true` for ~2s after a successful copy, then auto-resets to `false`. Defaults to `false`. */
93
+ isCopied = model(false, ...(ngDevMode ? [{ debugName: "isCopied" }] : /* istanbul ignore next */ []));
94
+ clipboard = inject(Clipboard);
95
+ liveAnnouncer = inject(LiveAnnouncer);
96
+ destroyRef = inject(DestroyRef);
97
+ timeoutId;
98
+ resolvedLabels = computed(() => {
99
+ const l = this.labels();
100
+ return {
101
+ copy: l.copy ?? 'Copy code',
102
+ copied: l.copied ?? 'Copied',
103
+ announcement: l.announcement ?? 'Copied to clipboard',
104
+ };
105
+ }, ...(ngDevMode ? [{ debugName: "resolvedLabels" }] : /* istanbul ignore next */ []));
106
+ variantResult = computed(() => codeBlockVariants({ variant: this.variant(), copied: this.isCopied() }), ...(ngDevMode ? [{ debugName: "variantResult" }] : /* istanbul ignore next */ []));
107
+ rootClasses = computed(() => this.variantResult().root(), ...(ngDevMode ? [{ debugName: "rootClasses" }] : /* istanbul ignore next */ []));
108
+ headerClasses = computed(() => this.variantResult().header(), ...(ngDevMode ? [{ debugName: "headerClasses" }] : /* istanbul ignore next */ []));
109
+ headerStartClasses = computed(() => this.variantResult().headerStart(), ...(ngDevMode ? [{ debugName: "headerStartClasses" }] : /* istanbul ignore next */ []));
110
+ preClasses = computed(() => {
111
+ const base = this.variantResult().pre();
112
+ return this.wrap() ? `${base} whitespace-pre-wrap` : `${base} whitespace-pre`;
113
+ }, ...(ngDevMode ? [{ debugName: "preClasses" }] : /* istanbul ignore next */ []));
114
+ copyButtonClasses = computed(() => this.variantResult().copyButton(), ...(ngDevMode ? [{ debugName: "copyButtonClasses" }] : /* istanbul ignore next */ []));
115
+ copyIconClasses = computed(() => this.variantResult().copyIcon(), ...(ngDevMode ? [{ debugName: "copyIconClasses" }] : /* istanbul ignore next */ []));
116
+ preAriaLabel = computed(() => {
117
+ const lang = this.language();
118
+ return lang ? `${lang} code` : 'Code';
119
+ }, ...(ngDevMode ? [{ debugName: "preAriaLabel" }] : /* istanbul ignore next */ []));
120
+ constructor() {
121
+ this.destroyRef.onDestroy(() => {
122
+ if (this.timeoutId) {
123
+ clearTimeout(this.timeoutId);
124
+ }
125
+ });
126
+ }
127
+ copyToClipboard() {
128
+ // `Clipboard.copy()` (CDK) is synchronous and returns `false` when the
129
+ // underlying clipboard write was blocked (permissions, insecure context,
130
+ // jsdom). Surface that as `copyFailed` so consumers can show their own
131
+ // fallback UI instead of silently dropping the action.
132
+ const success = this.clipboard.copy(this.code());
133
+ if (success) {
134
+ this.isCopied.set(true);
135
+ this.copied.emit();
136
+ this.liveAnnouncer.announce(this.resolvedLabels().announcement);
137
+ if (this.timeoutId) {
138
+ clearTimeout(this.timeoutId);
139
+ }
140
+ this.timeoutId = setTimeout(() => this.isCopied.set(false), 2000);
141
+ }
142
+ else {
143
+ this.copyFailed.emit(new Error('Clipboard copy failed'));
144
+ }
145
+ }
146
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CodeBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
147
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: CodeBlockComponent, isStandalone: true, selector: "tw-code-block", inputs: { code: { classPropertyName: "code", publicName: "code", isSignal: true, isRequired: true, transformFunction: null }, language: { classPropertyName: "language", publicName: "language", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, isCopied: { classPropertyName: "isCopied", publicName: "isCopied", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { copied: "copied", copyFailed: "copyFailed", isCopied: "isCopiedChange" }, host: { properties: { "class": "rootClasses()" } }, ngImport: i0, template: `
148
+ <div [class]="headerClasses()">
149
+ <div [class]="headerStartClasses()">
150
+ @if (language()) {
151
+ <span class="font-sans font-medium select-none">{{ language() }}</span>
152
+ }
153
+ <ng-content select="[twCodeBlockHeader]" />
154
+ </div>
155
+ <button
156
+ type="button"
157
+ [attr.aria-label]="isCopied() ? resolvedLabels().copied : resolvedLabels().copy"
158
+ [class]="copyButtonClasses()"
159
+ (click)="copyToClipboard()"
160
+ >
161
+ @if (isCopied()) {
162
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" [class]="copyIconClasses()" aria-hidden="true">
163
+ <path fill-rule="evenodd" d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z" clip-rule="evenodd"/>
164
+ </svg>
165
+ } @else {
166
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" [class]="copyIconClasses()" aria-hidden="true">
167
+ <path fill-rule="evenodd" d="M10.986 3H12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h1.014A2.25 2.25 0 0 1 7.25 1h1.5a2.25 2.25 0 0 1 2.236 2ZM9.5 4v-.75a.75.75 0 0 0-.75-.75h-1.5a.75.75 0 0 0-.75.75V4h3Z" clip-rule="evenodd"/>
168
+ </svg>
169
+ }
170
+ </button>
171
+ </div>
172
+ <pre
173
+ role="region"
174
+ tabindex="0"
175
+ [attr.aria-label]="preAriaLabel()"
176
+ [class]="preClasses()"
177
+ ><code>{{ code() }}</code></pre>
178
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
179
+ }
180
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CodeBlockComponent, decorators: [{
181
+ type: Component,
182
+ args: [{
183
+ selector: 'tw-code-block',
184
+ changeDetection: ChangeDetectionStrategy.OnPush,
185
+ host: {
186
+ '[class]': 'rootClasses()',
187
+ },
188
+ template: `
189
+ <div [class]="headerClasses()">
190
+ <div [class]="headerStartClasses()">
191
+ @if (language()) {
192
+ <span class="font-sans font-medium select-none">{{ language() }}</span>
193
+ }
194
+ <ng-content select="[twCodeBlockHeader]" />
195
+ </div>
196
+ <button
197
+ type="button"
198
+ [attr.aria-label]="isCopied() ? resolvedLabels().copied : resolvedLabels().copy"
199
+ [class]="copyButtonClasses()"
200
+ (click)="copyToClipboard()"
201
+ >
202
+ @if (isCopied()) {
203
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" [class]="copyIconClasses()" aria-hidden="true">
204
+ <path fill-rule="evenodd" d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z" clip-rule="evenodd"/>
205
+ </svg>
206
+ } @else {
207
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" [class]="copyIconClasses()" aria-hidden="true">
208
+ <path fill-rule="evenodd" d="M10.986 3H12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h1.014A2.25 2.25 0 0 1 7.25 1h1.5a2.25 2.25 0 0 1 2.236 2ZM9.5 4v-.75a.75.75 0 0 0-.75-.75h-1.5a.75.75 0 0 0-.75.75V4h3Z" clip-rule="evenodd"/>
209
+ </svg>
210
+ }
211
+ </button>
212
+ </div>
213
+ <pre
214
+ role="region"
215
+ tabindex="0"
216
+ [attr.aria-label]="preAriaLabel()"
217
+ [class]="preClasses()"
218
+ ><code>{{ code() }}</code></pre>
219
+ `,
220
+ }]
221
+ }], ctorParameters: () => [], propDecorators: { code: [{ type: i0.Input, args: [{ isSignal: true, alias: "code", required: true }] }], language: [{ type: i0.Input, args: [{ isSignal: true, alias: "language", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], wrap: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrap", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], copied: [{ type: i0.Output, args: ["copied"] }], copyFailed: [{ type: i0.Output, args: ["copyFailed"] }], isCopied: [{ type: i0.Input, args: [{ isSignal: true, alias: "isCopied", required: false }] }, { type: i0.Output, args: ["isCopiedChange"] }] } });
222
+
223
+ /**
224
+ * Generated bundle index. Do not edit.
225
+ */
226
+
227
+ export { CodeBlockComponent, CodeBlockHeaderDirective };
228
+ //# sourceMappingURL=cdevhub-ngx-tw-code-block.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdevhub-ngx-tw-code-block.mjs","sources":["../../../projects/ngx-tw/code-block/code-block.ts","../../../projects/ngx-tw/code-block/cdevhub-ngx-tw-code-block.ts"],"sourcesContent":["import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n Directive,\n inject,\n input,\n model,\n output,\n} from '@angular/core';\nimport { Clipboard } from '@angular/cdk/clipboard';\nimport { LiveAnnouncer } from '@angular/cdk/a11y';\nimport { tv } from 'tailwind-variants';\n\n/** Visual style of the code block container. */\nexport type CodeBlockVariant = 'filled' | 'outlined';\n\n/**\n * Localizable strings used by the code block. Provide a partial override —\n * any missing fields fall back to English defaults.\n */\nexport interface CodeBlockLabels {\n /** aria-label for the copy button in its resting state. Defaults to `'Copy code'`. */\n copy?: string;\n /** aria-label for the copy button after a successful copy. Defaults to `'Copied'`. */\n copied?: string;\n /** Text passed to LiveAnnouncer after a successful copy. Defaults to `'Copied to clipboard'`. */\n announcement?: string;\n}\n\n/**\n * Marker directive for projected header content (e.g. filename, secondary\n * actions). Sits alongside the language label inside the code block's\n * header row.\n *\n * @remarks\n * The host class (`inline-flex items-center gap-2 min-w-0`) styles the\n * projected element's *own* children — e.g. a filename `<span>` next to a\n * \"modified\" badge — and is distinct from the library's `headerStart` slot\n * wrapper that contains this element. The two carry overlapping utility names\n * (`items-center gap-2 min-w-0`) because both lay out flex children, but they\n * apply to different DOM nodes (parent slot vs the projected element itself)\n * and serve different jobs (slot row geometry vs the consumer's badge group).\n */\n@Directive({\n selector: '[twCodeBlockHeader]',\n host: {\n class: 'inline-flex items-center gap-2 min-w-0',\n },\n})\nexport class CodeBlockHeaderDirective {}\n\nconst codeBlockVariants = tv({\n slots: {\n root: 'flex flex-col rounded-lg overflow-hidden font-mono text-sm',\n header:\n 'flex items-center justify-between gap-2 px-4 py-2 border-b border-border text-xs text-fg-muted',\n headerStart: 'flex items-center gap-2 min-w-0 flex-1',\n pre: 'p-4 text-fg overflow-x-auto tw-scrollbar-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n copyButton:\n 'inline-flex items-center justify-center size-8 rounded-md cursor-pointer text-fg-muted hover:text-fg hover:bg-surface-muted transition-colors duration-normal motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n copyIcon: 'size-4 shrink-0',\n },\n variants: {\n variant: {\n filled: { root: 'bg-surface-sunken border border-border-strong' },\n outlined: { root: 'bg-transparent border border-border' },\n },\n copied: {\n true: { copyButton: 'text-success-500 hover:text-success-500' },\n false: {},\n },\n },\n defaultVariants: {\n variant: 'filled',\n copied: false,\n },\n}, {\n twMerge: true,\n});\n\n/**\n * Code-display surface with copy-to-clipboard, optional language label, and a\n * projection slot for filename / extra actions.\n *\n * @remarks\n * **`role=\"region\"` ownership.** The outer host is a presentational container —\n * the inner `<pre tabindex=\"0\" role=\"region\" aria-label=\"...\">` owns the\n * scrollable-content region semantics that screen readers and AXE care about.\n * Promoting the host to `role=\"region\"` as well would double-announce the\n * landmark; the `<pre>` is the focusable, keyboard-reachable target, so the\n * region role belongs there. This matches APG guidance for scroll-region\n * widgets and Material's `pre`-as-region pattern.\n */\n@Component({\n selector: 'tw-code-block',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'rootClasses()',\n },\n template: `\n <div [class]=\"headerClasses()\">\n <div [class]=\"headerStartClasses()\">\n @if (language()) {\n <span class=\"font-sans font-medium select-none\">{{ language() }}</span>\n }\n <ng-content select=\"[twCodeBlockHeader]\" />\n </div>\n <button\n type=\"button\"\n [attr.aria-label]=\"isCopied() ? resolvedLabels().copied : resolvedLabels().copy\"\n [class]=\"copyButtonClasses()\"\n (click)=\"copyToClipboard()\"\n >\n @if (isCopied()) {\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" [class]=\"copyIconClasses()\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z\" clip-rule=\"evenodd\"/>\n </svg>\n } @else {\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" [class]=\"copyIconClasses()\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10.986 3H12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h1.014A2.25 2.25 0 0 1 7.25 1h1.5a2.25 2.25 0 0 1 2.236 2ZM9.5 4v-.75a.75.75 0 0 0-.75-.75h-1.5a.75.75 0 0 0-.75.75V4h3Z\" clip-rule=\"evenodd\"/>\n </svg>\n }\n </button>\n </div>\n <pre\n role=\"region\"\n tabindex=\"0\"\n [attr.aria-label]=\"preAriaLabel()\"\n [class]=\"preClasses()\"\n ><code>{{ code() }}</code></pre>\n `,\n})\nexport class CodeBlockComponent {\n /** The code string to display and copy to clipboard. */\n readonly code = input.required<string>();\n\n /** Optional language label displayed in the header (e.g. `'TypeScript'`, `'HTML'`). */\n readonly language = input<string>();\n\n /** Visual style of the container. Defaults to `'filled'`. */\n readonly variant = input<CodeBlockVariant>('filled');\n\n /** When true, wraps long lines instead of horizontal scrolling. Defaults to `false`. */\n readonly wrap = input(false, { transform: booleanAttribute });\n\n /**\n * Localizable strings for the copy button's aria-labels and the\n * screen-reader announcement. Provide a partial override; missing fields\n * fall back to English defaults.\n */\n readonly labels = input<CodeBlockLabels>({});\n\n /** Fires when code is successfully copied to clipboard. */\n readonly copied = output<void>();\n\n /** Fires when the clipboard copy fails (e.g. user denied permission, no clipboard API available). Payload is an `Error` describing the failure. */\n readonly copyFailed = output<Error>();\n\n /** Whether the copy-to-clipboard button is currently in its \"copied\" confirmation state. Two-way bindable via `[(isCopied)]`. Set to `true` for ~2s after a successful copy, then auto-resets to `false`. Defaults to `false`. */\n readonly isCopied = model(false);\n\n private readonly clipboard = inject(Clipboard);\n private readonly liveAnnouncer = inject(LiveAnnouncer);\n private readonly destroyRef = inject(DestroyRef);\n\n private timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n protected readonly resolvedLabels = computed(() => {\n const l = this.labels();\n return {\n copy: l.copy ?? 'Copy code',\n copied: l.copied ?? 'Copied',\n announcement: l.announcement ?? 'Copied to clipboard',\n };\n });\n\n private readonly variantResult = computed(() =>\n codeBlockVariants({ variant: this.variant(), copied: this.isCopied() }),\n );\n\n protected readonly rootClasses = computed(() => this.variantResult().root());\n protected readonly headerClasses = computed(() => this.variantResult().header());\n protected readonly headerStartClasses = computed(() => this.variantResult().headerStart());\n\n protected readonly preClasses = computed(() => {\n const base = this.variantResult().pre();\n return this.wrap() ? `${base} whitespace-pre-wrap` : `${base} whitespace-pre`;\n });\n\n protected readonly copyButtonClasses = computed(() => this.variantResult().copyButton());\n protected readonly copyIconClasses = computed(() => this.variantResult().copyIcon());\n\n protected readonly preAriaLabel = computed(() => {\n const lang = this.language();\n return lang ? `${lang} code` : 'Code';\n });\n\n constructor() {\n this.destroyRef.onDestroy(() => {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n }\n });\n }\n\n protected copyToClipboard(): void {\n // `Clipboard.copy()` (CDK) is synchronous and returns `false` when the\n // underlying clipboard write was blocked (permissions, insecure context,\n // jsdom). Surface that as `copyFailed` so consumers can show their own\n // fallback UI instead of silently dropping the action.\n const success = this.clipboard.copy(this.code());\n if (success) {\n this.isCopied.set(true);\n this.copied.emit();\n this.liveAnnouncer.announce(this.resolvedLabels().announcement);\n\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n }\n this.timeoutId = setTimeout(() => this.isCopied.set(false), 2000);\n } else {\n this.copyFailed.emit(new Error('Clipboard copy failed'));\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;AAgCA;;;;;;;;;;;;;AAaG;MAOU,wBAAwB,CAAA;wGAAxB,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAxB,wBAAwB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,wCAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;4FAAxB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBANpC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,qBAAqB;AAC/B,oBAAA,IAAI,EAAE;AACJ,wBAAA,KAAK,EAAE,wCAAwC;AAChD,qBAAA;AACF,iBAAA;;AAGD,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC3B,IAAA,KAAK,EAAE;AACL,QAAA,IAAI,EAAE,4DAA4D;AAClE,QAAA,MAAM,EACJ,gGAAgG;AAClG,QAAA,WAAW,EAAE,wCAAwC;AACrD,QAAA,GAAG,EAAE,wIAAwI;AAC7I,QAAA,UAAU,EACR,sRAAsR;AACxR,QAAA,QAAQ,EAAE,iBAAiB;AAC5B,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,OAAO,EAAE;AACP,YAAA,MAAM,EAAE,EAAE,IAAI,EAAE,+CAA+C,EAAE;AACjE,YAAA,QAAQ,EAAE,EAAE,IAAI,EAAE,qCAAqC,EAAE;AAC1D,SAAA;AACD,QAAA,MAAM,EAAE;AACN,YAAA,IAAI,EAAE,EAAE,UAAU,EAAE,yCAAyC,EAAE;AAC/D,YAAA,KAAK,EAAE,EAAE;AACV,SAAA;AACF,KAAA;AACD,IAAA,eAAe,EAAE;AACf,QAAA,OAAO,EAAE,QAAQ;AACjB,QAAA,MAAM,EAAE,KAAK;AACd,KAAA;CACF,EAAE;AACD,IAAA,OAAO,EAAE,IAAI;AACd,CAAA,CAAC;AAEF;;;;;;;;;;;;AAYG;MAwCU,kBAAkB,CAAA;;AAEpB,IAAA,IAAI,GAAG,KAAK,CAAC,QAAQ,0EAAU;;IAG/B,QAAQ,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,UAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;;AAG1B,IAAA,OAAO,GAAG,KAAK,CAAmB,QAAQ,8EAAC;;IAG3C,IAAI,GAAG,KAAK,CAAC,KAAK,4EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;AAE7D;;;;AAIG;AACM,IAAA,MAAM,GAAG,KAAK,CAAkB,EAAE,6EAAC;;IAGnC,MAAM,GAAG,MAAM,EAAQ;;IAGvB,UAAU,GAAG,MAAM,EAAS;;AAG5B,IAAA,QAAQ,GAAG,KAAK,CAAC,KAAK,+EAAC;AAEf,IAAA,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;AAC7B,IAAA,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;AACrC,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAExC,IAAA,SAAS;AAEE,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAK;AAChD,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE;QACvB,OAAO;AACL,YAAA,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,WAAW;AAC3B,YAAA,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,QAAQ;AAC5B,YAAA,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,qBAAqB;SACtD;AACH,IAAA,CAAC,qFAAC;IAEe,aAAa,GAAG,QAAQ,CAAC,MACxC,iBAAiB,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,eAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CACxE;AAEkB,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,kFAAC;AACzD,IAAA,aAAa,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,oFAAC;AAC7D,IAAA,kBAAkB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE,yFAAC;AAEvE,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAK;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE;AACvC,QAAA,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,CAAA,EAAG,IAAI,CAAA,oBAAA,CAAsB,GAAG,CAAA,EAAG,IAAI,iBAAiB;AAC/E,IAAA,CAAC,iFAAC;AAEiB,IAAA,iBAAiB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,UAAU,EAAE,wFAAC;AACrE,IAAA,eAAe,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,QAAQ,EAAE,sFAAC;AAEjE,IAAA,YAAY,GAAG,QAAQ,CAAC,MAAK;AAC9C,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;QAC5B,OAAO,IAAI,GAAG,CAAA,EAAG,IAAI,CAAA,KAAA,CAAO,GAAG,MAAM;AACvC,IAAA,CAAC,mFAAC;AAEF,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;AAC7B,YAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,gBAAA,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;YAC9B;AACF,QAAA,CAAC,CAAC;IACJ;IAEU,eAAe,GAAA;;;;;AAKvB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAChD,IAAI,OAAO,EAAE;AACX,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;AACvB,YAAA,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;AAClB,YAAA,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,YAAY,CAAC;AAE/D,YAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,gBAAA,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;YAC9B;AACA,YAAA,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;QACnE;aAAO;YACL,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC1D;IACF;wGA3FW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,eAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAjCnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAEU,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAvC9B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,eAAe;oBACzB,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE,eAAe;AAC3B,qBAAA;AACD,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BT,EAAA,CAAA;AACF,iBAAA;;;ACtID;;AAEG;;;;"}