ngwr 14.0.0 → 14.1.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 (207) hide show
  1. package/README.md +57 -8
  2. package/aurora/aurora.scss +1 -1
  3. package/aurora/styles/_dark.scss +21 -0
  4. package/aurora/styles/_index.scss +11 -30
  5. package/aurora/styles/_rules.scss +25 -0
  6. package/border-glow/styles/_dark.scss +46 -0
  7. package/border-glow/styles/_index.scss +5 -0
  8. package/border-glow/styles/_rules.scss +0 -31
  9. package/button/styles/_index.scss +16 -0
  10. package/event-calendar/styles/_index.scss +15 -0
  11. package/fesm2022/ngwr-action-sheet.mjs +3 -3
  12. package/fesm2022/ngwr-affix.mjs +3 -3
  13. package/fesm2022/ngwr-alert.mjs +3 -3
  14. package/fesm2022/ngwr-anchor.mjs +3 -3
  15. package/fesm2022/ngwr-aurora.mjs +4 -4
  16. package/fesm2022/ngwr-aurora.mjs.map +1 -1
  17. package/fesm2022/ngwr-avatar.mjs +3 -3
  18. package/fesm2022/ngwr-back-top.mjs +3 -3
  19. package/fesm2022/ngwr-badge.mjs +6 -6
  20. package/fesm2022/ngwr-bar-chart.mjs +3 -3
  21. package/fesm2022/ngwr-blur-text.mjs +3 -3
  22. package/fesm2022/ngwr-border-glow.mjs +4 -4
  23. package/fesm2022/ngwr-border-glow.mjs.map +1 -1
  24. package/fesm2022/ngwr-breadcrumbs.mjs +7 -7
  25. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  26. package/fesm2022/ngwr-burger.mjs +3 -3
  27. package/fesm2022/ngwr-button.mjs +86 -8
  28. package/fesm2022/ngwr-button.mjs.map +1 -1
  29. package/fesm2022/ngwr-calendar-heatmap.mjs +3 -3
  30. package/fesm2022/ngwr-calendar.mjs +3 -3
  31. package/fesm2022/ngwr-card.mjs +9 -9
  32. package/fesm2022/ngwr-carousel.mjs +6 -6
  33. package/fesm2022/ngwr-cascader.mjs +4 -4
  34. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  35. package/fesm2022/ngwr-checkbox.mjs +6 -6
  36. package/fesm2022/ngwr-circular-text.mjs +3 -3
  37. package/fesm2022/ngwr-click-spark.mjs +3 -3
  38. package/fesm2022/ngwr-clipboard.mjs +3 -3
  39. package/fesm2022/ngwr-collapse.mjs +9 -9
  40. package/fesm2022/ngwr-color-picker.mjs +6 -6
  41. package/fesm2022/ngwr-command-palette.mjs +84 -7
  42. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  43. package/fesm2022/ngwr-compare.mjs +3 -3
  44. package/fesm2022/ngwr-confetti.mjs +3 -3
  45. package/fesm2022/ngwr-context-menu.mjs +12 -12
  46. package/fesm2022/ngwr-cookie.mjs +3 -3
  47. package/fesm2022/ngwr-counter.mjs +6 -6
  48. package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
  49. package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
  50. package/fesm2022/ngwr-date-picker.mjs +18 -18
  51. package/fesm2022/ngwr-date.mjs +3 -3
  52. package/fesm2022/ngwr-decrypt-text.mjs +3 -3
  53. package/fesm2022/ngwr-density.mjs +6 -6
  54. package/fesm2022/ngwr-descriptions.mjs +6 -6
  55. package/fesm2022/ngwr-dialog.mjs +15 -15
  56. package/fesm2022/ngwr-directives.mjs +12 -12
  57. package/fesm2022/ngwr-divider.mjs +3 -3
  58. package/fesm2022/ngwr-donut-chart.mjs +3 -3
  59. package/fesm2022/ngwr-drag-drop.mjs +7 -7
  60. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  61. package/fesm2022/ngwr-drawer.mjs +18 -18
  62. package/fesm2022/ngwr-dropdown.mjs +28 -12
  63. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  64. package/fesm2022/ngwr-empty.mjs +3 -3
  65. package/fesm2022/ngwr-event-calendar.mjs +6 -6
  66. package/fesm2022/ngwr-falling-text.mjs +3 -3
  67. package/fesm2022/ngwr-file-upload.mjs +3 -3
  68. package/fesm2022/ngwr-form-testing.mjs +13 -7
  69. package/fesm2022/ngwr-form-testing.mjs.map +1 -1
  70. package/fesm2022/ngwr-form.mjs +44 -25
  71. package/fesm2022/ngwr-form.mjs.map +1 -1
  72. package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
  73. package/fesm2022/ngwr-gauge.mjs +3 -3
  74. package/fesm2022/ngwr-glitch-text.mjs +3 -3
  75. package/fesm2022/ngwr-gradient-text.mjs +3 -3
  76. package/fesm2022/ngwr-hotkey.mjs +6 -6
  77. package/fesm2022/ngwr-i18n-en.mjs +4 -0
  78. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  79. package/fesm2022/ngwr-i18n-ru.mjs +1 -0
  80. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  81. package/fesm2022/ngwr-i18n.mjs +9 -9
  82. package/fesm2022/ngwr-icon.mjs +6 -6
  83. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  84. package/fesm2022/ngwr-input-number.mjs +3 -3
  85. package/fesm2022/ngwr-input-otp.mjs +3 -3
  86. package/fesm2022/ngwr-input.mjs +24 -20
  87. package/fesm2022/ngwr-input.mjs.map +1 -1
  88. package/fesm2022/ngwr-keyboard.mjs +3 -3
  89. package/fesm2022/ngwr-knob.mjs +3 -3
  90. package/fesm2022/ngwr-layout.mjs +15 -15
  91. package/fesm2022/ngwr-lightbox.mjs +4 -4
  92. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  93. package/fesm2022/ngwr-line-chart.mjs +3 -3
  94. package/fesm2022/ngwr-list.mjs +7 -7
  95. package/fesm2022/ngwr-list.mjs.map +1 -1
  96. package/fesm2022/ngwr-loading-bar.mjs +6 -6
  97. package/fesm2022/ngwr-markdown.mjs +6 -6
  98. package/fesm2022/ngwr-marquee.mjs +3 -3
  99. package/fesm2022/ngwr-media.mjs +3 -3
  100. package/fesm2022/ngwr-mention.mjs +6 -6
  101. package/fesm2022/ngwr-meta.mjs +6 -6
  102. package/fesm2022/ngwr-meter-group.mjs +3 -3
  103. package/fesm2022/ngwr-overlay.mjs +6 -6
  104. package/fesm2022/ngwr-page-header.mjs +3 -3
  105. package/fesm2022/ngwr-pagination.mjs +3 -3
  106. package/fesm2022/ngwr-pipes.mjs +21 -21
  107. package/fesm2022/ngwr-platform.mjs +9 -9
  108. package/fesm2022/ngwr-popconfirm.mjs +6 -6
  109. package/fesm2022/ngwr-popover.mjs +6 -6
  110. package/fesm2022/ngwr-progress.mjs +3 -3
  111. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  112. package/fesm2022/ngwr-qr.mjs +3 -3
  113. package/fesm2022/ngwr-radio.mjs +6 -6
  114. package/fesm2022/ngwr-rating.mjs +48 -22
  115. package/fesm2022/ngwr-rating.mjs.map +1 -1
  116. package/fesm2022/ngwr-result.mjs +12 -12
  117. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  118. package/fesm2022/ngwr-scroll.mjs +3 -3
  119. package/fesm2022/ngwr-segmented.mjs +12 -8
  120. package/fesm2022/ngwr-segmented.mjs.map +1 -1
  121. package/fesm2022/ngwr-select.mjs +125 -26
  122. package/fesm2022/ngwr-select.mjs.map +1 -1
  123. package/fesm2022/ngwr-shiny-text.mjs +7 -7
  124. package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
  125. package/fesm2022/ngwr-sidebar.mjs +3 -3
  126. package/fesm2022/ngwr-skeleton.mjs +3 -3
  127. package/fesm2022/ngwr-slider.mjs +12 -8
  128. package/fesm2022/ngwr-slider.mjs.map +1 -1
  129. package/fesm2022/ngwr-sparkline.mjs +3 -3
  130. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  131. package/fesm2022/ngwr-spinner.mjs +3 -3
  132. package/fesm2022/ngwr-splash-cursor.mjs +3 -3
  133. package/fesm2022/ngwr-split-text.mjs +3 -3
  134. package/fesm2022/ngwr-splitter.mjs +3 -3
  135. package/fesm2022/ngwr-spotlight-card.mjs +7 -7
  136. package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
  137. package/fesm2022/ngwr-squircle.mjs +6 -6
  138. package/fesm2022/ngwr-star-border.mjs +4 -4
  139. package/fesm2022/ngwr-star-border.mjs.map +1 -1
  140. package/fesm2022/ngwr-statistic.mjs +9 -9
  141. package/fesm2022/ngwr-stepper.mjs +6 -6
  142. package/fesm2022/ngwr-storage.mjs +11 -3
  143. package/fesm2022/ngwr-storage.mjs.map +1 -1
  144. package/fesm2022/ngwr-switch.mjs +3 -3
  145. package/fesm2022/ngwr-table.mjs +18 -18
  146. package/fesm2022/ngwr-tabs-router.mjs +3 -3
  147. package/fesm2022/ngwr-tabs.mjs +6 -6
  148. package/fesm2022/ngwr-textarea.mjs +26 -5
  149. package/fesm2022/ngwr-textarea.mjs.map +1 -1
  150. package/fesm2022/ngwr-theme.mjs +90 -4
  151. package/fesm2022/ngwr-theme.mjs.map +1 -1
  152. package/fesm2022/ngwr-tilt-card.mjs +7 -7
  153. package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
  154. package/fesm2022/ngwr-timeline.mjs +6 -6
  155. package/fesm2022/ngwr-toast.mjs +116 -11
  156. package/fesm2022/ngwr-toast.mjs.map +1 -1
  157. package/fesm2022/ngwr-toolbar.mjs +3 -3
  158. package/fesm2022/ngwr-tour.mjs +6 -6
  159. package/fesm2022/ngwr-transfer.mjs +3 -3
  160. package/fesm2022/ngwr-tree.mjs +18 -11
  161. package/fesm2022/ngwr-tree.mjs.map +1 -1
  162. package/fesm2022/ngwr-typewriter.mjs +3 -3
  163. package/fesm2022/ngwr-typography.mjs +3 -3
  164. package/fesm2022/ngwr-version.mjs +1 -1
  165. package/fesm2022/ngwr-version.mjs.map +1 -1
  166. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  167. package/fesm2022/ngwr-waves.mjs +4 -4
  168. package/fesm2022/ngwr-waves.mjs.map +1 -1
  169. package/fesm2022/ngwr-window.mjs +12 -12
  170. package/i18n/en.json +1 -0
  171. package/i18n/ru.json +1 -0
  172. package/llms-full.txt +9 -9
  173. package/llms.txt +82 -11
  174. package/package.json +1 -1
  175. package/shiny-text/styles/_dark.scss +20 -0
  176. package/shiny-text/styles/_index.scss +5 -0
  177. package/shiny-text/styles/_rules.scss +0 -4
  178. package/spotlight-card/styles/_dark.scss +21 -0
  179. package/spotlight-card/styles/_index.scss +5 -0
  180. package/spotlight-card/styles/_rules.scss +0 -6
  181. package/star-border/styles/_dark.scss +21 -0
  182. package/star-border/styles/_index.scss +5 -0
  183. package/star-border/styles/_rules.scss +0 -5
  184. package/theme/styles/_colors.scss +102 -0
  185. package/theme/styles/_focus.scss +31 -1
  186. package/tilt-card/styles/_dark.scss +21 -0
  187. package/tilt-card/styles/_index.scss +5 -0
  188. package/tilt-card/styles/_rules.scss +0 -5
  189. package/types/ngwr-button.d.ts +43 -0
  190. package/types/ngwr-command-palette.d.ts +59 -2
  191. package/types/ngwr-dropdown.d.ts +17 -1
  192. package/types/ngwr-form-testing.d.ts +13 -7
  193. package/types/ngwr-form.d.ts +47 -12
  194. package/types/ngwr-input.d.ts +2 -1
  195. package/types/ngwr-rating.d.ts +25 -4
  196. package/types/ngwr-segmented.d.ts +1 -0
  197. package/types/ngwr-select.d.ts +45 -9
  198. package/types/ngwr-slider.d.ts +1 -0
  199. package/types/ngwr-storage.d.ts +39 -1
  200. package/types/ngwr-textarea.d.ts +20 -0
  201. package/types/ngwr-theme.d.ts +92 -2
  202. package/types/ngwr-toast.d.ts +53 -0
  203. package/types/ngwr-tree.d.ts +3 -2
  204. package/types/ngwr-version.d.ts +1 -1
  205. package/waves/styles/_dark.scss +19 -0
  206. package/waves/styles/_index.scss +5 -0
  207. package/waves/styles/_rules.scss +0 -3
@@ -34,10 +34,10 @@ class WrResult {
34
34
  ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
35
35
  classes = computed(() => `wr-result wr-result--${this.status()}`, /* @ts-ignore */
36
36
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
37
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrResult, deps: [], target: i0.ɵɵFactoryTarget.Component });
38
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: WrResult, isStandalone: true, selector: "wr-result", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: "<div class=\"wr-result__icon\" aria-hidden=\"true\">\n @switch (status()) {\n @case ('success') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M20 32 L28 40 L44 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n @case ('warning') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 18 L32 36 M32 44 L32 46\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('error') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M22 22 L42 42 M42 22 L22 42\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('empty') {\n <svg width=\"72\" height=\"56\" viewBox=\"0 0 72 56\">\n <rect x=\"6\" y=\"14\" width=\"60\" height=\"36\" rx=\"4\" fill=\"currentColor\" opacity=\"0.12\" />\n <path d=\"M6 26 L36 26 L40 20 L66 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n }\n @default {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 20 L32 36 M32 42 L32 44\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n }\n</div>\n\n@if (title()) {\n <h2 class=\"wr-result__title\">{{ title() }}</h2>\n}\n@if (description()) {\n <p class=\"wr-result__description\">{{ description() }}</p>\n}\n\n<div class=\"wr-result__extra\">\n <ng-content select=\"[wrResultExtra]\" />\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
37
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult, deps: [], target: i0.ɵɵFactoryTarget.Component });
38
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrResult, isStandalone: true, selector: "wr-result", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: "<div class=\"wr-result__icon\" aria-hidden=\"true\">\n @switch (status()) {\n @case ('success') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M20 32 L28 40 L44 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n @case ('warning') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 18 L32 36 M32 44 L32 46\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('error') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M22 22 L42 42 M42 22 L22 42\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('empty') {\n <svg width=\"72\" height=\"56\" viewBox=\"0 0 72 56\">\n <rect x=\"6\" y=\"14\" width=\"60\" height=\"36\" rx=\"4\" fill=\"currentColor\" opacity=\"0.12\" />\n <path d=\"M6 26 L36 26 L40 20 L66 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n }\n @default {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 20 L32 36 M32 42 L32 44\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n }\n</div>\n\n@if (title()) {\n <h2 class=\"wr-result__title\">{{ title() }}</h2>\n}\n@if (description()) {\n <p class=\"wr-result__description\">{{ description() }}</p>\n}\n\n<div class=\"wr-result__extra\">\n <ng-content select=\"[wrResultExtra]\" />\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
39
39
  }
40
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrResult, decorators: [{
40
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult, decorators: [{
41
41
  type: Component,
42
42
  args: [{ selector: 'wr-result', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, template: "<div class=\"wr-result__icon\" aria-hidden=\"true\">\n @switch (status()) {\n @case ('success') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M20 32 L28 40 L44 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n @case ('warning') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 18 L32 36 M32 44 L32 46\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('error') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M22 22 L42 42 M42 22 L22 42\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('empty') {\n <svg width=\"72\" height=\"56\" viewBox=\"0 0 72 56\">\n <rect x=\"6\" y=\"14\" width=\"60\" height=\"36\" rx=\"4\" fill=\"currentColor\" opacity=\"0.12\" />\n <path d=\"M6 26 L36 26 L40 20 L66 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n }\n @default {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 20 L32 36 M32 42 L32 44\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n }\n</div>\n\n@if (title()) {\n <h2 class=\"wr-result__title\">{{ title() }}</h2>\n}\n@if (description()) {\n <p class=\"wr-result__description\">{{ description() }}</p>\n}\n\n<div class=\"wr-result__extra\">\n <ng-content select=\"[wrResultExtra]\" />\n</div>\n" }]
43
43
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }] } });
@@ -67,10 +67,10 @@ class WrResult404 {
67
67
  description = input(null, /* @ts-ignore */
68
68
  ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
69
69
  desc = useI18nText(this.description, 'result.notFound', 'Sorry, the page you visited does not exist.');
70
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrResult404, deps: [], target: i0.ɵɵFactoryTarget.Component });
71
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: WrResult404, isStandalone: true, selector: "wr-result-404", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n", dependencies: [{ kind: "component", type: WrResult, selector: "wr-result", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None });
70
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult404, deps: [], target: i0.ɵɵFactoryTarget.Component });
71
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrResult404, isStandalone: true, selector: "wr-result-404", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n", dependencies: [{ kind: "component", type: WrResult, selector: "wr-result", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None });
72
72
  }
73
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrResult404, decorators: [{
73
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult404, decorators: [{
74
74
  type: Component,
75
75
  args: [{ selector: 'wr-result-404', encapsulation: ViewEncapsulation.None, imports: [WrResult], template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n" }]
76
76
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }] } });
@@ -84,10 +84,10 @@ class WrResult403 {
84
84
  description = input(null, /* @ts-ignore */
85
85
  ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
86
86
  desc = useI18nText(this.description, 'result.forbidden', 'Sorry, you are not authorized to access this page.');
87
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrResult403, deps: [], target: i0.ɵɵFactoryTarget.Component });
88
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: WrResult403, isStandalone: true, selector: "wr-result-403", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n", dependencies: [{ kind: "component", type: WrResult, selector: "wr-result", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None });
87
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult403, deps: [], target: i0.ɵɵFactoryTarget.Component });
88
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrResult403, isStandalone: true, selector: "wr-result-403", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n", dependencies: [{ kind: "component", type: WrResult, selector: "wr-result", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None });
89
89
  }
90
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrResult403, decorators: [{
90
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult403, decorators: [{
91
91
  type: Component,
92
92
  args: [{ selector: 'wr-result-403', encapsulation: ViewEncapsulation.None, imports: [WrResult], template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n" }]
93
93
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }] } });
@@ -101,10 +101,10 @@ class WrResult500 {
101
101
  description = input(null, /* @ts-ignore */
102
102
  ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
103
103
  desc = useI18nText(this.description, 'result.serverError', 'Sorry, something went wrong.');
104
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrResult500, deps: [], target: i0.ɵɵFactoryTarget.Component });
105
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: WrResult500, isStandalone: true, selector: "wr-result-500", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n", dependencies: [{ kind: "component", type: WrResult, selector: "wr-result", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None });
104
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult500, deps: [], target: i0.ɵɵFactoryTarget.Component });
105
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrResult500, isStandalone: true, selector: "wr-result-500", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n", dependencies: [{ kind: "component", type: WrResult, selector: "wr-result", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None });
106
106
  }
107
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrResult500, decorators: [{
107
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult500, decorators: [{
108
108
  type: Component,
109
109
  args: [{ selector: 'wr-result-500', encapsulation: ViewEncapsulation.None, imports: [WrResult], template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n" }]
110
110
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }] } });
@@ -262,10 +262,10 @@ class WrRotatingText {
262
262
  return i * stagger;
263
263
  }
264
264
  }
265
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrRotatingText, deps: [], target: i0.ɵɵFactoryTarget.Component });
266
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: WrRotatingText, isStandalone: true, selector: "wr-rotating-text", inputs: { texts: { classPropertyName: "texts", publicName: "texts", isSignal: true, isRequired: true, transformFunction: null }, rotationInterval: { classPropertyName: "rotationInterval", publicName: "rotationInterval", isSignal: true, isRequired: false, transformFunction: null }, splitBy: { classPropertyName: "splitBy", publicName: "splitBy", isSignal: true, isRequired: false, transformFunction: null }, auto: { classPropertyName: "auto", publicName: "auto", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, easing: { classPropertyName: "easing", publicName: "easing", isSignal: true, isRequired: false, transformFunction: null }, staggerDuration: { classPropertyName: "staggerDuration", publicName: "staggerDuration", isSignal: true, isRequired: false, transformFunction: null }, staggerFrom: { classPropertyName: "staggerFrom", publicName: "staggerFrom", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nextChange: "nextChange" }, host: { classAttribute: "wr-rotating-text" }, ngImport: i0, template: "<!--\n The readable text, once: the spans below are per-character. Deliberately NOT a\n live region \u2014 `auto` rotates every two seconds by default, and the APG's answer\n for self-advancing content is silence, not an announcement every two seconds.\n-->\n\n<span class=\"wr-rotating-text__sr-only\">{{ current() }}</span>\n\n<!-- Animated visual content. -->\n<span class=\"wr-rotating-text__inner\" aria-hidden=\"true\">\n @for (word of words(); track $index) {\n <span class=\"wr-rotating-text__word\">\n @for (char of word.characters; track $index) {\n <span class=\"wr-rotating-text__char\">{{ char }}</span>\n }\n @if (word.needsSpace) {\n <span class=\"wr-rotating-text__space\">&nbsp;</span>\n }\n </span>\n }\n</span>\n", styles: [".wr-rotating-text{display:inline-flex;align-items:center;overflow:hidden;vertical-align:bottom}.wr-rotating-text__sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}.wr-rotating-text__inner{display:inline-flex;flex-wrap:wrap}.wr-rotating-text__word{display:inline-flex;align-items:center}.wr-rotating-text__char{display:inline-block;will-change:transform,opacity}.wr-rotating-text__space{display:inline;white-space:pre}\n"], encapsulation: i0.ViewEncapsulation.None });
265
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrRotatingText, deps: [], target: i0.ɵɵFactoryTarget.Component });
266
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrRotatingText, isStandalone: true, selector: "wr-rotating-text", inputs: { texts: { classPropertyName: "texts", publicName: "texts", isSignal: true, isRequired: true, transformFunction: null }, rotationInterval: { classPropertyName: "rotationInterval", publicName: "rotationInterval", isSignal: true, isRequired: false, transformFunction: null }, splitBy: { classPropertyName: "splitBy", publicName: "splitBy", isSignal: true, isRequired: false, transformFunction: null }, auto: { classPropertyName: "auto", publicName: "auto", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, easing: { classPropertyName: "easing", publicName: "easing", isSignal: true, isRequired: false, transformFunction: null }, staggerDuration: { classPropertyName: "staggerDuration", publicName: "staggerDuration", isSignal: true, isRequired: false, transformFunction: null }, staggerFrom: { classPropertyName: "staggerFrom", publicName: "staggerFrom", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nextChange: "nextChange" }, host: { classAttribute: "wr-rotating-text" }, ngImport: i0, template: "<!--\n The readable text, once: the spans below are per-character. Deliberately NOT a\n live region \u2014 `auto` rotates every two seconds by default, and the APG's answer\n for self-advancing content is silence, not an announcement every two seconds.\n-->\n\n<span class=\"wr-rotating-text__sr-only\">{{ current() }}</span>\n\n<!-- Animated visual content. -->\n<span class=\"wr-rotating-text__inner\" aria-hidden=\"true\">\n @for (word of words(); track $index) {\n <span class=\"wr-rotating-text__word\">\n @for (char of word.characters; track $index) {\n <span class=\"wr-rotating-text__char\">{{ char }}</span>\n }\n @if (word.needsSpace) {\n <span class=\"wr-rotating-text__space\">&nbsp;</span>\n }\n </span>\n }\n</span>\n", styles: [".wr-rotating-text{display:inline-flex;align-items:center;overflow:hidden;vertical-align:bottom}.wr-rotating-text__sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}.wr-rotating-text__inner{display:inline-flex;flex-wrap:wrap}.wr-rotating-text__word{display:inline-flex;align-items:center}.wr-rotating-text__char{display:inline-block;will-change:transform,opacity}.wr-rotating-text__space{display:inline;white-space:pre}\n"], encapsulation: i0.ViewEncapsulation.None });
267
267
  }
268
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrRotatingText, decorators: [{
268
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrRotatingText, decorators: [{
269
269
  type: Component,
270
270
  args: [{ selector: 'wr-rotating-text', encapsulation: ViewEncapsulation.None, host: { class: 'wr-rotating-text' }, template: "<!--\n The readable text, once: the spans below are per-character. Deliberately NOT a\n live region \u2014 `auto` rotates every two seconds by default, and the APG's answer\n for self-advancing content is silence, not an announcement every two seconds.\n-->\n\n<span class=\"wr-rotating-text__sr-only\">{{ current() }}</span>\n\n<!-- Animated visual content. -->\n<span class=\"wr-rotating-text__inner\" aria-hidden=\"true\">\n @for (word of words(); track $index) {\n <span class=\"wr-rotating-text__word\">\n @for (char of word.characters; track $index) {\n <span class=\"wr-rotating-text__char\">{{ char }}</span>\n }\n @if (word.needsSpace) {\n <span class=\"wr-rotating-text__space\">&nbsp;</span>\n }\n </span>\n }\n</span>\n", styles: [".wr-rotating-text{display:inline-flex;align-items:center;overflow:hidden;vertical-align:bottom}.wr-rotating-text__sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}.wr-rotating-text__inner{display:inline-flex;flex-wrap:wrap}.wr-rotating-text__word{display:inline-flex;align-items:center}.wr-rotating-text__char{display:inline-block;will-change:transform,opacity}.wr-rotating-text__space{display:inline;white-space:pre}\n"] }]
271
271
  }], ctorParameters: () => [], propDecorators: { texts: [{ type: i0.Input, args: [{ isSignal: true, alias: "texts", required: true }] }], rotationInterval: [{ type: i0.Input, args: [{ isSignal: true, alias: "rotationInterval", required: false }] }], splitBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "splitBy", required: false }] }], auto: [{ type: i0.Input, args: [{ isSignal: true, alias: "auto", required: false }] }], loop: [{ type: i0.Input, args: [{ isSignal: true, alias: "loop", required: false }] }], duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], easing: [{ type: i0.Input, args: [{ isSignal: true, alias: "easing", required: false }] }], staggerDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "staggerDuration", required: false }] }], staggerFrom: [{ type: i0.Input, args: [{ isSignal: true, alias: "staggerFrom", required: false }] }], nextChange: [{ type: i0.Output, args: ["nextChange"] }] } });
@@ -92,10 +92,10 @@ class WrScroll {
92
92
  else
93
93
  container.scrollTo(options);
94
94
  }
95
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrScroll, deps: [], target: i0.ɵɵFactoryTarget.Service });
96
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.4", ngImport: i0, type: WrScroll });
95
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrScroll, deps: [], target: i0.ɵɵFactoryTarget.Service });
96
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: WrScroll });
97
97
  }
98
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrScroll, decorators: [{
98
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrScroll, decorators: [{
99
99
  type: Service
100
100
  }] });
101
101
 
@@ -2,7 +2,7 @@ import { Directionality } from '@angular/cdk/bidi';
2
2
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
3
3
  import * as i0 from '@angular/core';
4
4
  import { input, model, output, inject, ElementRef, computed, signal, afterNextRender, ViewEncapsulation, Component } from '@angular/core';
5
- import { WR_FORM_FIELD } from 'ngwr/form';
5
+ import { WR_FORM_FIELD, useFormFieldAria } from 'ngwr/form';
6
6
  import { WrIcon } from 'ngwr/icon';
7
7
 
8
8
  /**
@@ -103,10 +103,14 @@ class WrSegmented {
103
103
  * because the field only publishes an id once it is showing something — announcing
104
104
  * "invalid" while pointing at nothing is worse than staying quiet.
105
105
  */
106
- describedBy = computed(() => this.field?.describedBy() ?? null, /* @ts-ignore */
107
- ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
108
- ariaInvalid = computed(() => (this.field?.describedBy() ? 'true' : null), /* @ts-ignore */
109
- ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : /* istanbul ignore next */ []));
106
+ // Through the shared helper, not a local pair: the hint is described by
107
+ // `hintId`, which only `useFormFieldAria()` composes, and `aria-invalid` keys
108
+ // on the error COUNT rather than on "something is described". Hand-rolled here,
109
+ // these three announced the error and never the hint — and `<input wrInput>` is
110
+ // the control the report was filed against.
111
+ fieldAria = useFormFieldAria();
112
+ describedBy = this.fieldAria.describedBy;
113
+ ariaInvalid = this.fieldAria.ariaInvalid;
110
114
  /** Index of the selected option, or `-1` when nothing is selected. */
111
115
  selectedIndex = computed(() => {
112
116
  const v = this.value();
@@ -193,10 +197,10 @@ class WrSegmented {
193
197
  return;
194
198
  this.touch.emit();
195
199
  }
196
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrSegmented, deps: [], target: i0.ɵɵFactoryTarget.Component });
197
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: WrSegmented, isStandalone: true, selector: "wr-segmented", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touch: "touch" }, host: { attributes: { "role": "group" }, listeners: { "focusout": "onFocusOut($event)" }, properties: { "class": "classes()", "style": "thumbStyle()", "attr.aria-describedby": "describedBy()", "attr.aria-invalid": "ariaInvalid()" } }, ngImport: i0, template: "<span class=\"wr-segmented__thumb\" aria-hidden=\"true\"></span>\n\n<!--\n `id` on the FIRST segment only: it is the id a surrounding `<wr-form-field>`\n already points its `<label for>` at, and a `for` may only name a labelable\n element \u2014 see `controlId` in the component. `null` without a field, so a bare\n strip stamps no document-global id on anything.\n-->\n@for (option of options(); track option.value) {\n <button\n type=\"button\"\n class=\"wr-segmented__option\"\n [attr.id]=\"$first ? controlId() : null\"\n [class.wr-segmented__option--selected]=\"isSelected(option)\"\n [disabled]=\"disabled() || !!option.disabled\"\n [attr.aria-pressed]=\"isSelected(option)\"\n [attr.aria-label]=\"option.label ? null : (option.ariaLabel ?? option.value)\"\n (click)=\"select(option)\"\n >\n @if (option.icon) {\n <wr-icon class=\"wr-segmented__icon\" [name]=\"option.icon\" />\n }\n @if (option.label) {\n <span class=\"wr-segmented__label\">{{ option.label }}</span>\n }\n </button>\n}\n", dependencies: [{ kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
200
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSegmented, deps: [], target: i0.ɵɵFactoryTarget.Component });
201
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrSegmented, isStandalone: true, selector: "wr-segmented", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touch: "touch" }, host: { attributes: { "role": "group" }, listeners: { "focusout": "onFocusOut($event)" }, properties: { "class": "classes()", "style": "thumbStyle()", "attr.aria-describedby": "describedBy()", "attr.aria-invalid": "ariaInvalid()" } }, ngImport: i0, template: "<span class=\"wr-segmented__thumb\" aria-hidden=\"true\"></span>\n\n<!--\n `id` on the FIRST segment only: it is the id a surrounding `<wr-form-field>`\n already points its `<label for>` at, and a `for` may only name a labelable\n element \u2014 see `controlId` in the component. `null` without a field, so a bare\n strip stamps no document-global id on anything.\n-->\n@for (option of options(); track option.value) {\n <button\n type=\"button\"\n class=\"wr-segmented__option\"\n [attr.id]=\"$first ? controlId() : null\"\n [class.wr-segmented__option--selected]=\"isSelected(option)\"\n [disabled]=\"disabled() || !!option.disabled\"\n [attr.aria-pressed]=\"isSelected(option)\"\n [attr.aria-label]=\"option.label ? null : (option.ariaLabel ?? option.value)\"\n (click)=\"select(option)\"\n >\n @if (option.icon) {\n <wr-icon class=\"wr-segmented__icon\" [name]=\"option.icon\" />\n }\n @if (option.label) {\n <span class=\"wr-segmented__label\">{{ option.label }}</span>\n }\n </button>\n}\n", dependencies: [{ kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
198
202
  }
199
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrSegmented, decorators: [{
203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSegmented, decorators: [{
200
204
  type: Component,
201
205
  args: [{ selector: 'wr-segmented', encapsulation: ViewEncapsulation.None, host: {
202
206
  '[class]': 'classes()',
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-segmented.mjs","sources":["../../../projects/lib/segmented/segmented.ts","../../../projects/lib/segmented/segmented.html","../../../projects/lib/segmented/ngwr-segmented.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport {\n Component,\n ElementRef,\n ViewEncapsulation,\n afterNextRender,\n computed,\n inject,\n input,\n model,\n output,\n signal,\n} from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\n\nimport { WR_FORM_FIELD } from 'ngwr/form';\nimport { WrIcon } from 'ngwr/icon';\n\nimport type { WrSegmentedOption } from './interfaces';\n\n/**\n * Single-choice picker rendered as a segmented control. Two-way binds\n * the selected `value`.\n *\n * A signal-forms native control: it implements `FormValueControl<T | null>`, so\n * `[formField]` binds straight to its `value` model — no\n * `ControlValueAccessor` in between. `[(value)]` works standalone, and classic\n * `[(ngModel)]` / reactive forms keep working through Angular's bridge.\n *\n * It stays a `role=\"group\"` of `aria-pressed` toggle buttons rather than\n * becoming a `radiogroup`: being a form control changes what the value is bound\n * to, not what the widget is, and a radiogroup would owe a roving tab stop and\n * arrow-key selection — a different keyboard contract for every consumer who\n * already ships this. The group is what the field describes (`aria-describedby`\n * / `aria-invalid` land on the host), while the `<label for>` has to name a\n * labelable element, so the id goes on the first segment.\n *\n * @example\n * ```html\n * <!-- signal forms -->\n * <wr-segmented [options]=\"ranges\" [formField]=\"form.range\" />\n *\n * <!-- standalone two-way binding -->\n * <wr-segmented\n * [options]=\"[\n * { value: 'day', label: 'Day' },\n * { value: 'week', label: 'Week' },\n * { value: 'month', label: 'Month' },\n * ]\"\n * [(value)]=\"range\"\n * />\n * ```\n *\n * @see https://ngwr.dev/reference/components/segmented\n */\nexport type WrSegmentedSize = 'sm' | 'md' | 'lg';\n\n@Component({\n selector: 'wr-segmented',\n templateUrl: './segmented.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[style]': 'thumbStyle()',\n role: 'group',\n '[attr.aria-describedby]': 'describedBy()',\n '[attr.aria-invalid]': 'ariaInvalid()',\n '(focusout)': 'onFocusOut($event)',\n },\n imports: [WrIcon],\n})\nexport class WrSegmented<T = unknown> implements FormValueControl<T | null> {\n /** The segments to render. */\n readonly options = input.required<readonly WrSegmentedOption<T>[]>();\n\n // The model keeps the component's own `T`, and the contract is satisfied as\n // `FormValueControl<T | null>` — legal because `FormField<T>` infers its type from\n // the FIELD it is handed and never from the host component, so the interface's\n // parameter describes this model rather than constraining the binding.\n // `wr-cascader` and `wr-tree` widen theirs to `unknown` because their value SHAPE\n // changes with a mode input (`TId | null` in single mode, a `readonly TId[]` in\n // multi) and no one type is true of both. A segmented control has one shape, so\n // widening here would only throw away what `[options]` already proved: every\n // `(valueChange)=\"pick($event)\"` in a typed app would start receiving `unknown`.\n // With the default type parameter this degenerates to exactly the catalog's\n // `FormValueControl<unknown>`.\n /**\n * The picked segment's `value`, `null` when nothing is selected. Bound by\n * `[formField]`, or two-way via `[(value)]`.\n */\n readonly value = model<T | null>(null);\n\n /** Emitted when focus leaves the strip, so a bound field can mark itself touched. */\n readonly touch = output<void>();\n\n /**\n * Disable the whole control. Bound automatically from the field's disabled\n * state when used with `[formField]`.\n *\n * @default false\n */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Refuse changes while every segment stays focusable and the value still\n * submits. Bound automatically from the field's readonly state when used with\n * `[formField]`.\n *\n * NOTHING is mirrored into ARIA here, deliberately: the strip is a\n * `role=\"group\"` of `aria-pressed` buttons, and ARIA defines `aria-readonly`\n * for neither role — it is a state of `checkbox` / `radiogroup` / `textbox`\n * and their kin, and it is not global. `aria-disabled` is the only attribute\n * that would apply to a button, and it says the wrong thing: these segments\n * are still focusable and the value still submits. So the state is honest in\n * the DOM (`wr-segmented--readonly`) and silent in the accessibility tree\n * rather than announced with a word that means something else.\n *\n * @default false\n */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n\n /** Control size — shares the `--wr-control-*` contract. @default 'md' */\n readonly size = input<WrSegmentedSize>('md');\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly field = inject(WR_FORM_FIELD, { optional: true });\n\n /**\n * Id the surrounding `<wr-form-field>`'s `<label for>` points at, stamped on the\n * FIRST segment.\n *\n * The field renders its label before it can see what was projected into it, so the\n * id travels the other way and the control adopts it, exactly as `[wrInput]`,\n * `wr-slider` and `wr-select` do. Without this the `for` named an element that was\n * nowhere in the document: clicking the label did nothing.\n *\n * It cannot go on the host — only a labelable element can be a label's target, and\n * `<wr-segmented>` is not one — and there is no single control to put it on, so it\n * goes where clicking the label should land a user: the first segment, which is\n * also the strip's first tab stop. The same choice `wr-slider` makes with its low\n * thumb.\n *\n * What this does NOT change is that segment's NAME: it is named by its own label,\n * and a `<label for>` cannot outrank text content in the accname order anyway.\n *\n * The one shape this reads wrong is a strip NESTED inside another control that is\n * itself the field — `<wr-color-picker>`'s own format tabs are the only case in\n * the library — where the id lands on a tab instead of on the picker. That is the\n * same exposure `[wrInput]`, `wr-slider` and `wr-select` all carry, and the fix\n * belongs to the outer control (shield its subtree by providing `WR_FORM_FIELD`\n * as `null`), not to a strip that cannot tell whose field it is in.\n */\n protected readonly controlId = computed(() => this.field?.controlId() ?? null);\n\n /**\n * The field's error message, wired to the GROUP rather than to a segment.\n *\n * A segmented control is one field made of several buttons, so the description\n * belongs to the thing the field describes — repeated on every segment it would be\n * announced once per Tab. `role=\"group\"` supports neither state as a role-specific\n * attribute, but both are ARIA globals, so this is valid where an `aria-checked`\n * would not be.\n *\n * `aria-invalid` is keyed on the message EXISTING rather than on `errorKeys()`,\n * because the field only publishes an id once it is showing something — announcing\n * \"invalid\" while pointing at nothing is worse than staying quiet.\n */\n protected readonly describedBy = computed(() => this.field?.describedBy() ?? null);\n protected readonly ariaInvalid = computed(() => (this.field?.describedBy() ? 'true' : null));\n\n /** Index of the selected option, or `-1` when nothing is selected. */\n protected readonly selectedIndex = computed(() => {\n const v = this.value();\n return this.options().findIndex(o => o.value === v);\n });\n\n /** Flips true after the first paint so the thumb only animates user-driven changes, not the initial snap. */\n private readonly mounted = signal(false);\n\n constructor() {\n afterNextRender(() => this.mounted.set(true));\n }\n\n protected readonly classes = computed(() => {\n const parts = ['wr-segmented'];\n const size = this.size();\n if (size !== 'md') parts.push(`wr-segmented--${size}`);\n if (this.disabled()) parts.push('wr-segmented--disabled');\n else if (this.readonly()) parts.push('wr-segmented--readonly');\n if (this.selectedIndex() < 0) parts.push('wr-segmented--unselected');\n if (this.mounted()) parts.push('wr-segmented--mounted');\n return parts.join(' ');\n });\n\n private readonly dir = inject(Directionality, { optional: true });\n\n /**\n * Reading direction of the strip. `Directionality` is root-provided, so this\n * always resolves — `optional` only guards a consumer who has deliberately\n * torn the provider out. A subtree that overrides the direction does it with\n * the CDK's `Dir` directive, which writes `valueSignal`, so `thumbStyle`\n * re-renders instead of leaving the thumb parked on the old segment.\n */\n private readonly isRtl = computed(() => this.dir?.valueSignal() === 'rtl');\n\n /**\n * Inline CSS vars driving the sliding thumb position.\n *\n * `--wr-segmented-thumb-index` is the SLOT the thumb parks in, counted from the\n * physical left, which is the selected index only in LTR. The stylesheet anchors\n * the thumb with a physical `left` and slides it with `translateX` — neither has\n * a logical form — while the options are a grid that mirrors, so under `dir=\"rtl\"`\n * the segment at logical index `i` occupies slot `count - 1 - i`. Left unsigned,\n * the pill sat under a different label than the one it marks (the whole strip's\n * worth of offset at the far end), which is the carousel's `trackStyle` problem\n * one component over.\n */\n protected readonly thumbStyle = computed<Record<string, string>>(() => {\n const i = Math.max(0, this.selectedIndex());\n const count = Math.max(1, this.options().length);\n const slot = this.isRtl() ? count - 1 - i : i;\n return {\n '--wr-segmented-thumb-index': `${slot}`,\n '--wr-segmented-thumb-count': `${count}`,\n };\n });\n\n protected isSelected(option: WrSegmentedOption<T>): boolean {\n return this.value() === option.value;\n }\n\n protected select(option: WrSegmentedOption<T>): void {\n if (this.disabled() || this.readonly() || option.disabled || this.isSelected(option)) return;\n this.value.set(option.value);\n }\n\n protected trackByValue(_: number, option: WrSegmentedOption<T>): unknown {\n return option.value;\n }\n\n /**\n * A bound field learns it may show its validation copy from `touch`, and a click\n * cannot be the source: a strip tabbed into and out of without a pick left the\n * field untouched forever — which is exactly the case `touched` exists for.\n *\n * `wr-knob` and `wr-rating` bind `(blur)` on the one element they own; this\n * component owns one button per option, so it listens for the bubbling `focusout`\n * on its host instead — and ignores the one that only moves focus from one segment\n * to the next, the way `wr-slider` ignores the hop between its two thumbs.\n */\n protected onFocusOut(event: FocusEvent): void {\n if (this.host.nativeElement.contains(event.relatedTarget as Node | null)) return;\n this.touch.emit();\n }\n}\n","<span class=\"wr-segmented__thumb\" aria-hidden=\"true\"></span>\n\n<!--\n `id` on the FIRST segment only: it is the id a surrounding `<wr-form-field>`\n already points its `<label for>` at, and a `for` may only name a labelable\n element — see `controlId` in the component. `null` without a field, so a bare\n strip stamps no document-global id on anything.\n-->\n@for (option of options(); track option.value) {\n <button\n type=\"button\"\n class=\"wr-segmented__option\"\n [attr.id]=\"$first ? controlId() : null\"\n [class.wr-segmented__option--selected]=\"isSelected(option)\"\n [disabled]=\"disabled() || !!option.disabled\"\n [attr.aria-pressed]=\"isSelected(option)\"\n [attr.aria-label]=\"option.label ? null : (option.ariaLabel ?? option.value)\"\n (click)=\"select(option)\"\n >\n @if (option.icon) {\n <wr-icon class=\"wr-segmented__icon\" [name]=\"option.icon\" />\n }\n @if (option.label) {\n <span class=\"wr-segmented__label\">{{ option.label }}</span>\n }\n </button>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-segmented.mjs","sources":["../../../projects/lib/segmented/segmented.ts","../../../projects/lib/segmented/segmented.html","../../../projects/lib/segmented/ngwr-segmented.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport {\n Component,\n ElementRef,\n ViewEncapsulation,\n afterNextRender,\n computed,\n inject,\n input,\n model,\n output,\n signal,\n} from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\n\nimport { WR_FORM_FIELD, useFormFieldAria } from 'ngwr/form';\nimport { WrIcon } from 'ngwr/icon';\n\nimport type { WrSegmentedOption } from './interfaces';\n\n/**\n * Single-choice picker rendered as a segmented control. Two-way binds\n * the selected `value`.\n *\n * A signal-forms native control: it implements `FormValueControl<T | null>`, so\n * `[formField]` binds straight to its `value` model — no\n * `ControlValueAccessor` in between. `[(value)]` works standalone, and classic\n * `[(ngModel)]` / reactive forms keep working through Angular's bridge.\n *\n * It stays a `role=\"group\"` of `aria-pressed` toggle buttons rather than\n * becoming a `radiogroup`: being a form control changes what the value is bound\n * to, not what the widget is, and a radiogroup would owe a roving tab stop and\n * arrow-key selection — a different keyboard contract for every consumer who\n * already ships this. The group is what the field describes (`aria-describedby`\n * / `aria-invalid` land on the host), while the `<label for>` has to name a\n * labelable element, so the id goes on the first segment.\n *\n * @example\n * ```html\n * <!-- signal forms -->\n * <wr-segmented [options]=\"ranges\" [formField]=\"form.range\" />\n *\n * <!-- standalone two-way binding -->\n * <wr-segmented\n * [options]=\"[\n * { value: 'day', label: 'Day' },\n * { value: 'week', label: 'Week' },\n * { value: 'month', label: 'Month' },\n * ]\"\n * [(value)]=\"range\"\n * />\n * ```\n *\n * @see https://ngwr.dev/reference/components/segmented\n */\nexport type WrSegmentedSize = 'sm' | 'md' | 'lg';\n\n@Component({\n selector: 'wr-segmented',\n templateUrl: './segmented.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[style]': 'thumbStyle()',\n role: 'group',\n '[attr.aria-describedby]': 'describedBy()',\n '[attr.aria-invalid]': 'ariaInvalid()',\n '(focusout)': 'onFocusOut($event)',\n },\n imports: [WrIcon],\n})\nexport class WrSegmented<T = unknown> implements FormValueControl<T | null> {\n /** The segments to render. */\n readonly options = input.required<readonly WrSegmentedOption<T>[]>();\n\n // The model keeps the component's own `T`, and the contract is satisfied as\n // `FormValueControl<T | null>` — legal because `FormField<T>` infers its type from\n // the FIELD it is handed and never from the host component, so the interface's\n // parameter describes this model rather than constraining the binding.\n // `wr-cascader` and `wr-tree` widen theirs to `unknown` because their value SHAPE\n // changes with a mode input (`TId | null` in single mode, a `readonly TId[]` in\n // multi) and no one type is true of both. A segmented control has one shape, so\n // widening here would only throw away what `[options]` already proved: every\n // `(valueChange)=\"pick($event)\"` in a typed app would start receiving `unknown`.\n // With the default type parameter this degenerates to exactly the catalog's\n // `FormValueControl<unknown>`.\n /**\n * The picked segment's `value`, `null` when nothing is selected. Bound by\n * `[formField]`, or two-way via `[(value)]`.\n */\n readonly value = model<T | null>(null);\n\n /** Emitted when focus leaves the strip, so a bound field can mark itself touched. */\n readonly touch = output<void>();\n\n /**\n * Disable the whole control. Bound automatically from the field's disabled\n * state when used with `[formField]`.\n *\n * @default false\n */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Refuse changes while every segment stays focusable and the value still\n * submits. Bound automatically from the field's readonly state when used with\n * `[formField]`.\n *\n * NOTHING is mirrored into ARIA here, deliberately: the strip is a\n * `role=\"group\"` of `aria-pressed` buttons, and ARIA defines `aria-readonly`\n * for neither role — it is a state of `checkbox` / `radiogroup` / `textbox`\n * and their kin, and it is not global. `aria-disabled` is the only attribute\n * that would apply to a button, and it says the wrong thing: these segments\n * are still focusable and the value still submits. So the state is honest in\n * the DOM (`wr-segmented--readonly`) and silent in the accessibility tree\n * rather than announced with a word that means something else.\n *\n * @default false\n */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n\n /** Control size — shares the `--wr-control-*` contract. @default 'md' */\n readonly size = input<WrSegmentedSize>('md');\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly field = inject(WR_FORM_FIELD, { optional: true });\n\n /**\n * Id the surrounding `<wr-form-field>`'s `<label for>` points at, stamped on the\n * FIRST segment.\n *\n * The field renders its label before it can see what was projected into it, so the\n * id travels the other way and the control adopts it, exactly as `[wrInput]`,\n * `wr-slider` and `wr-select` do. Without this the `for` named an element that was\n * nowhere in the document: clicking the label did nothing.\n *\n * It cannot go on the host — only a labelable element can be a label's target, and\n * `<wr-segmented>` is not one — and there is no single control to put it on, so it\n * goes where clicking the label should land a user: the first segment, which is\n * also the strip's first tab stop. The same choice `wr-slider` makes with its low\n * thumb.\n *\n * What this does NOT change is that segment's NAME: it is named by its own label,\n * and a `<label for>` cannot outrank text content in the accname order anyway.\n *\n * The one shape this reads wrong is a strip NESTED inside another control that is\n * itself the field — `<wr-color-picker>`'s own format tabs are the only case in\n * the library — where the id lands on a tab instead of on the picker. That is the\n * same exposure `[wrInput]`, `wr-slider` and `wr-select` all carry, and the fix\n * belongs to the outer control (shield its subtree by providing `WR_FORM_FIELD`\n * as `null`), not to a strip that cannot tell whose field it is in.\n */\n protected readonly controlId = computed(() => this.field?.controlId() ?? null);\n\n /**\n * The field's error message, wired to the GROUP rather than to a segment.\n *\n * A segmented control is one field made of several buttons, so the description\n * belongs to the thing the field describes — repeated on every segment it would be\n * announced once per Tab. `role=\"group\"` supports neither state as a role-specific\n * attribute, but both are ARIA globals, so this is valid where an `aria-checked`\n * would not be.\n *\n * `aria-invalid` is keyed on the message EXISTING rather than on `errorKeys()`,\n * because the field only publishes an id once it is showing something — announcing\n * \"invalid\" while pointing at nothing is worse than staying quiet.\n */\n // Through the shared helper, not a local pair: the hint is described by\n // `hintId`, which only `useFormFieldAria()` composes, and `aria-invalid` keys\n // on the error COUNT rather than on \"something is described\". Hand-rolled here,\n // these three announced the error and never the hint — and `<input wrInput>` is\n // the control the report was filed against.\n private readonly fieldAria = useFormFieldAria();\n protected readonly describedBy = this.fieldAria.describedBy;\n protected readonly ariaInvalid = this.fieldAria.ariaInvalid;\n\n /** Index of the selected option, or `-1` when nothing is selected. */\n protected readonly selectedIndex = computed(() => {\n const v = this.value();\n return this.options().findIndex(o => o.value === v);\n });\n\n /** Flips true after the first paint so the thumb only animates user-driven changes, not the initial snap. */\n private readonly mounted = signal(false);\n\n constructor() {\n afterNextRender(() => this.mounted.set(true));\n }\n\n protected readonly classes = computed(() => {\n const parts = ['wr-segmented'];\n const size = this.size();\n if (size !== 'md') parts.push(`wr-segmented--${size}`);\n if (this.disabled()) parts.push('wr-segmented--disabled');\n else if (this.readonly()) parts.push('wr-segmented--readonly');\n if (this.selectedIndex() < 0) parts.push('wr-segmented--unselected');\n if (this.mounted()) parts.push('wr-segmented--mounted');\n return parts.join(' ');\n });\n\n private readonly dir = inject(Directionality, { optional: true });\n\n /**\n * Reading direction of the strip. `Directionality` is root-provided, so this\n * always resolves — `optional` only guards a consumer who has deliberately\n * torn the provider out. A subtree that overrides the direction does it with\n * the CDK's `Dir` directive, which writes `valueSignal`, so `thumbStyle`\n * re-renders instead of leaving the thumb parked on the old segment.\n */\n private readonly isRtl = computed(() => this.dir?.valueSignal() === 'rtl');\n\n /**\n * Inline CSS vars driving the sliding thumb position.\n *\n * `--wr-segmented-thumb-index` is the SLOT the thumb parks in, counted from the\n * physical left, which is the selected index only in LTR. The stylesheet anchors\n * the thumb with a physical `left` and slides it with `translateX` — neither has\n * a logical form — while the options are a grid that mirrors, so under `dir=\"rtl\"`\n * the segment at logical index `i` occupies slot `count - 1 - i`. Left unsigned,\n * the pill sat under a different label than the one it marks (the whole strip's\n * worth of offset at the far end), which is the carousel's `trackStyle` problem\n * one component over.\n */\n protected readonly thumbStyle = computed<Record<string, string>>(() => {\n const i = Math.max(0, this.selectedIndex());\n const count = Math.max(1, this.options().length);\n const slot = this.isRtl() ? count - 1 - i : i;\n return {\n '--wr-segmented-thumb-index': `${slot}`,\n '--wr-segmented-thumb-count': `${count}`,\n };\n });\n\n protected isSelected(option: WrSegmentedOption<T>): boolean {\n return this.value() === option.value;\n }\n\n protected select(option: WrSegmentedOption<T>): void {\n if (this.disabled() || this.readonly() || option.disabled || this.isSelected(option)) return;\n this.value.set(option.value);\n }\n\n protected trackByValue(_: number, option: WrSegmentedOption<T>): unknown {\n return option.value;\n }\n\n /**\n * A bound field learns it may show its validation copy from `touch`, and a click\n * cannot be the source: a strip tabbed into and out of without a pick left the\n * field untouched forever — which is exactly the case `touched` exists for.\n *\n * `wr-knob` and `wr-rating` bind `(blur)` on the one element they own; this\n * component owns one button per option, so it listens for the bubbling `focusout`\n * on its host instead — and ignores the one that only moves focus from one segment\n * to the next, the way `wr-slider` ignores the hop between its two thumbs.\n */\n protected onFocusOut(event: FocusEvent): void {\n if (this.host.nativeElement.contains(event.relatedTarget as Node | null)) return;\n this.touch.emit();\n }\n}\n","<span class=\"wr-segmented__thumb\" aria-hidden=\"true\"></span>\n\n<!--\n `id` on the FIRST segment only: it is the id a surrounding `<wr-form-field>`\n already points its `<label for>` at, and a `for` may only name a labelable\n element — see `controlId` in the component. `null` without a field, so a bare\n strip stamps no document-global id on anything.\n-->\n@for (option of options(); track option.value) {\n <button\n type=\"button\"\n class=\"wr-segmented__option\"\n [attr.id]=\"$first ? controlId() : null\"\n [class.wr-segmented__option--selected]=\"isSelected(option)\"\n [disabled]=\"disabled() || !!option.disabled\"\n [attr.aria-pressed]=\"isSelected(option)\"\n [attr.aria-label]=\"option.label ? null : (option.ariaLabel ?? option.value)\"\n (click)=\"select(option)\"\n >\n @if (option.icon) {\n <wr-icon class=\"wr-segmented__icon\" [name]=\"option.icon\" />\n }\n @if (option.label) {\n <span class=\"wr-segmented__label\">{{ option.label }}</span>\n }\n </button>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}