@star-ng/ui 0.0.0-stage → 0.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 (217) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +148 -2
  3. package/fesm2022/star-ng-ui-accordion.mjs +376 -0
  4. package/fesm2022/star-ng-ui-accordion.mjs.map +1 -0
  5. package/fesm2022/star-ng-ui-autocomplete.mjs +782 -0
  6. package/fesm2022/star-ng-ui-autocomplete.mjs.map +1 -0
  7. package/fesm2022/star-ng-ui-avatar.mjs +154 -0
  8. package/fesm2022/star-ng-ui-avatar.mjs.map +1 -0
  9. package/fesm2022/star-ng-ui-badge.mjs +153 -0
  10. package/fesm2022/star-ng-ui-badge.mjs.map +1 -0
  11. package/fesm2022/star-ng-ui-breadcrumb.mjs +199 -0
  12. package/fesm2022/star-ng-ui-breadcrumb.mjs.map +1 -0
  13. package/fesm2022/star-ng-ui-button.mjs +282 -0
  14. package/fesm2022/star-ng-ui-button.mjs.map +1 -0
  15. package/fesm2022/star-ng-ui-card.mjs +112 -0
  16. package/fesm2022/star-ng-ui-card.mjs.map +1 -0
  17. package/fesm2022/star-ng-ui-chart.mjs +1904 -0
  18. package/fesm2022/star-ng-ui-chart.mjs.map +1 -0
  19. package/fesm2022/star-ng-ui-checkbox.mjs +345 -0
  20. package/fesm2022/star-ng-ui-checkbox.mjs.map +1 -0
  21. package/fesm2022/star-ng-ui-core.mjs +392 -0
  22. package/fesm2022/star-ng-ui-core.mjs.map +1 -0
  23. package/fesm2022/star-ng-ui-data-display.mjs +1556 -0
  24. package/fesm2022/star-ng-ui-data-display.mjs.map +1 -0
  25. package/fesm2022/star-ng-ui-date-picker.mjs +2786 -0
  26. package/fesm2022/star-ng-ui-date-picker.mjs.map +1 -0
  27. package/fesm2022/star-ng-ui-dialog.mjs +948 -0
  28. package/fesm2022/star-ng-ui-dialog.mjs.map +1 -0
  29. package/fesm2022/star-ng-ui-drawer.mjs +158 -0
  30. package/fesm2022/star-ng-ui-drawer.mjs.map +1 -0
  31. package/fesm2022/star-ng-ui-editor.mjs +416 -0
  32. package/fesm2022/star-ng-ui-editor.mjs.map +1 -0
  33. package/fesm2022/star-ng-ui-field.mjs +378 -0
  34. package/fesm2022/star-ng-ui-field.mjs.map +1 -0
  35. package/fesm2022/star-ng-ui-file-upload.mjs +762 -0
  36. package/fesm2022/star-ng-ui-file-upload.mjs.map +1 -0
  37. package/fesm2022/star-ng-ui-i18n-de.mjs +179 -0
  38. package/fesm2022/star-ng-ui-i18n-de.mjs.map +1 -0
  39. package/fesm2022/star-ng-ui-i18n-es.mjs +179 -0
  40. package/fesm2022/star-ng-ui-i18n-es.mjs.map +1 -0
  41. package/fesm2022/star-ng-ui-input-group.mjs +188 -0
  42. package/fesm2022/star-ng-ui-input-group.mjs.map +1 -0
  43. package/fesm2022/star-ng-ui-input-mask.mjs +434 -0
  44. package/fesm2022/star-ng-ui-input-mask.mjs.map +1 -0
  45. package/fesm2022/star-ng-ui-input-number.mjs +691 -0
  46. package/fesm2022/star-ng-ui-input-number.mjs.map +1 -0
  47. package/fesm2022/star-ng-ui-input-otp.mjs +343 -0
  48. package/fesm2022/star-ng-ui-input-otp.mjs.map +1 -0
  49. package/fesm2022/star-ng-ui-input-tags.mjs +616 -0
  50. package/fesm2022/star-ng-ui-input-tags.mjs.map +1 -0
  51. package/fesm2022/star-ng-ui-knob.mjs +514 -0
  52. package/fesm2022/star-ng-ui-knob.mjs.map +1 -0
  53. package/fesm2022/star-ng-ui-layout.mjs +608 -0
  54. package/fesm2022/star-ng-ui-layout.mjs.map +1 -0
  55. package/fesm2022/star-ng-ui-listbox.mjs +978 -0
  56. package/fesm2022/star-ng-ui-listbox.mjs.map +1 -0
  57. package/fesm2022/star-ng-ui-media.mjs +833 -0
  58. package/fesm2022/star-ng-ui-media.mjs.map +1 -0
  59. package/fesm2022/star-ng-ui-menu.mjs +1840 -0
  60. package/fesm2022/star-ng-ui-menu.mjs.map +1 -0
  61. package/fesm2022/star-ng-ui-message.mjs +191 -0
  62. package/fesm2022/star-ng-ui-message.mjs.map +1 -0
  63. package/fesm2022/star-ng-ui-paginator.mjs +387 -0
  64. package/fesm2022/star-ng-ui-paginator.mjs.map +1 -0
  65. package/fesm2022/star-ng-ui-panel.mjs +324 -0
  66. package/fesm2022/star-ng-ui-panel.mjs.map +1 -0
  67. package/fesm2022/star-ng-ui-password.mjs +517 -0
  68. package/fesm2022/star-ng-ui-password.mjs.map +1 -0
  69. package/fesm2022/star-ng-ui-popover.mjs +241 -0
  70. package/fesm2022/star-ng-ui-popover.mjs.map +1 -0
  71. package/fesm2022/star-ng-ui-progress-bar.mjs +183 -0
  72. package/fesm2022/star-ng-ui-progress-bar.mjs.map +1 -0
  73. package/fesm2022/star-ng-ui-radio.mjs +411 -0
  74. package/fesm2022/star-ng-ui-radio.mjs.map +1 -0
  75. package/fesm2022/star-ng-ui-rating.mjs +211 -0
  76. package/fesm2022/star-ng-ui-rating.mjs.map +1 -0
  77. package/fesm2022/star-ng-ui-select-button.mjs +613 -0
  78. package/fesm2022/star-ng-ui-select-button.mjs.map +1 -0
  79. package/fesm2022/star-ng-ui-select.mjs +2523 -0
  80. package/fesm2022/star-ng-ui-select.mjs.map +1 -0
  81. package/fesm2022/star-ng-ui-skeleton.mjs +160 -0
  82. package/fesm2022/star-ng-ui-skeleton.mjs.map +1 -0
  83. package/fesm2022/star-ng-ui-slider.mjs +552 -0
  84. package/fesm2022/star-ng-ui-slider.mjs.map +1 -0
  85. package/fesm2022/star-ng-ui-spinner.mjs +148 -0
  86. package/fesm2022/star-ng-ui-spinner.mjs.map +1 -0
  87. package/fesm2022/star-ng-ui-stepper.mjs +360 -0
  88. package/fesm2022/star-ng-ui-stepper.mjs.map +1 -0
  89. package/fesm2022/star-ng-ui-table.mjs +3477 -0
  90. package/fesm2022/star-ng-ui-table.mjs.map +1 -0
  91. package/fesm2022/star-ng-ui-tabs.mjs +464 -0
  92. package/fesm2022/star-ng-ui-tabs.mjs.map +1 -0
  93. package/fesm2022/star-ng-ui-tag.mjs +129 -0
  94. package/fesm2022/star-ng-ui-tag.mjs.map +1 -0
  95. package/fesm2022/star-ng-ui-theme-switch.mjs +105 -0
  96. package/fesm2022/star-ng-ui-theme-switch.mjs.map +1 -0
  97. package/fesm2022/star-ng-ui-theme.mjs +98 -0
  98. package/fesm2022/star-ng-ui-theme.mjs.map +1 -0
  99. package/fesm2022/star-ng-ui-toast.mjs +298 -0
  100. package/fesm2022/star-ng-ui-toast.mjs.map +1 -0
  101. package/fesm2022/star-ng-ui-toggle-switch.mjs +316 -0
  102. package/fesm2022/star-ng-ui-toggle-switch.mjs.map +1 -0
  103. package/fesm2022/star-ng-ui-tooltip.mjs +297 -0
  104. package/fesm2022/star-ng-ui-tooltip.mjs.map +1 -0
  105. package/fesm2022/star-ng-ui-transloco.mjs +40 -0
  106. package/fesm2022/star-ng-ui-transloco.mjs.map +1 -0
  107. package/fesm2022/star-ng-ui-tree.mjs +1446 -0
  108. package/fesm2022/star-ng-ui-tree.mjs.map +1 -0
  109. package/fesm2022/star-ng-ui-utility.mjs +2134 -0
  110. package/fesm2022/star-ng-ui-utility.mjs.map +1 -0
  111. package/fesm2022/star-ng-ui.mjs +51 -0
  112. package/package.json +281 -3
  113. package/styles/_base.scss +70 -0
  114. package/styles/_shared.scss +2 -0
  115. package/styles/_tokens.scss +190 -0
  116. package/styles/controls/_accordion.scss +75 -0
  117. package/styles/controls/_autocomplete.scss +44 -0
  118. package/styles/controls/_avatar.scss +39 -0
  119. package/styles/controls/_breadcrumb.scss +45 -0
  120. package/styles/controls/_button.scss +137 -0
  121. package/styles/controls/_card.scss +38 -0
  122. package/styles/controls/_chart.scss +214 -0
  123. package/styles/controls/_chip.scss +51 -0
  124. package/styles/controls/_choice.scss +153 -0
  125. package/styles/controls/_data-display.scss +118 -0
  126. package/styles/controls/_date-picker.scss +300 -0
  127. package/styles/controls/_dialog.scss +123 -0
  128. package/styles/controls/_drawer.scss +118 -0
  129. package/styles/controls/_editor.scss +74 -0
  130. package/styles/controls/_field.scss +92 -0
  131. package/styles/controls/_file-upload.scss +136 -0
  132. package/styles/controls/_input-group.scss +104 -0
  133. package/styles/controls/_input-mask.scss +46 -0
  134. package/styles/controls/_input-number.scss +125 -0
  135. package/styles/controls/_knob.scss +76 -0
  136. package/styles/controls/_layout.scss +182 -0
  137. package/styles/controls/_listbox.scss +38 -0
  138. package/styles/controls/_media.scss +222 -0
  139. package/styles/controls/_menu.scss +254 -0
  140. package/styles/controls/_message.scss +48 -0
  141. package/styles/controls/_org-chart.scss +128 -0
  142. package/styles/controls/_paginator.scss +59 -0
  143. package/styles/controls/_panel.scss +83 -0
  144. package/styles/controls/_popover.scss +40 -0
  145. package/styles/controls/_progress-bar.scss +74 -0
  146. package/styles/controls/_select-button.scss +61 -0
  147. package/styles/controls/_select.scss +216 -0
  148. package/styles/controls/_skeleton.scss +43 -0
  149. package/styles/controls/_slider.scss +163 -0
  150. package/styles/controls/_spinner.scss +34 -0
  151. package/styles/controls/_stepper.scss +109 -0
  152. package/styles/controls/_table.scss +523 -0
  153. package/styles/controls/_tabs.scss +93 -0
  154. package/styles/controls/_tag.scss +84 -0
  155. package/styles/controls/_toast.scss +141 -0
  156. package/styles/controls/_tooltip.scss +14 -0
  157. package/styles/controls/_tree.scss +113 -0
  158. package/styles/controls/_utility.scss +654 -0
  159. package/styles/star-ng.css +5803 -0
  160. package/styles/star-ng.min.css +1 -0
  161. package/styles/star-ng.scss +50 -0
  162. package/theme/star-theme-first-paint.js +1 -0
  163. package/types/star-ng-ui-accordion.d.ts +82 -0
  164. package/types/star-ng-ui-autocomplete.d.ts +171 -0
  165. package/types/star-ng-ui-avatar.d.ts +43 -0
  166. package/types/star-ng-ui-badge.d.ts +46 -0
  167. package/types/star-ng-ui-breadcrumb.d.ts +39 -0
  168. package/types/star-ng-ui-button.d.ts +79 -0
  169. package/types/star-ng-ui-card.d.ts +29 -0
  170. package/types/star-ng-ui-chart.d.ts +337 -0
  171. package/types/star-ng-ui-checkbox.d.ts +92 -0
  172. package/types/star-ng-ui-core.d.ts +310 -0
  173. package/types/star-ng-ui-data-display.d.ts +339 -0
  174. package/types/star-ng-ui-date-picker.d.ts +701 -0
  175. package/types/star-ng-ui-dialog.d.ts +254 -0
  176. package/types/star-ng-ui-drawer.d.ts +29 -0
  177. package/types/star-ng-ui-editor.d.ts +96 -0
  178. package/types/star-ng-ui-field.d.ts +146 -0
  179. package/types/star-ng-ui-file-upload.d.ts +192 -0
  180. package/types/star-ng-ui-i18n-de.d.ts +7 -0
  181. package/types/star-ng-ui-i18n-es.d.ts +7 -0
  182. package/types/star-ng-ui-input-group.d.ts +58 -0
  183. package/types/star-ng-ui-input-mask.d.ts +126 -0
  184. package/types/star-ng-ui-input-number.d.ts +193 -0
  185. package/types/star-ng-ui-input-otp.d.ts +86 -0
  186. package/types/star-ng-ui-input-tags.d.ts +159 -0
  187. package/types/star-ng-ui-knob.d.ts +121 -0
  188. package/types/star-ng-ui-layout.d.ts +154 -0
  189. package/types/star-ng-ui-listbox.d.ts +197 -0
  190. package/types/star-ng-ui-media.d.ts +161 -0
  191. package/types/star-ng-ui-menu.d.ts +332 -0
  192. package/types/star-ng-ui-message.d.ts +52 -0
  193. package/types/star-ng-ui-paginator.d.ts +85 -0
  194. package/types/star-ng-ui-panel.d.ts +65 -0
  195. package/types/star-ng-ui-password.d.ts +129 -0
  196. package/types/star-ng-ui-popover.d.ts +57 -0
  197. package/types/star-ng-ui-progress-bar.d.ts +49 -0
  198. package/types/star-ng-ui-radio.d.ts +116 -0
  199. package/types/star-ng-ui-rating.d.ts +52 -0
  200. package/types/star-ng-ui-select-button.d.ts +169 -0
  201. package/types/star-ng-ui-select.d.ts +540 -0
  202. package/types/star-ng-ui-skeleton.d.ts +47 -0
  203. package/types/star-ng-ui-slider.d.ts +145 -0
  204. package/types/star-ng-ui-spinner.d.ts +29 -0
  205. package/types/star-ng-ui-stepper.d.ts +89 -0
  206. package/types/star-ng-ui-table.d.ts +829 -0
  207. package/types/star-ng-ui-tabs.d.ts +109 -0
  208. package/types/star-ng-ui-tag.d.ts +35 -0
  209. package/types/star-ng-ui-theme-switch.d.ts +36 -0
  210. package/types/star-ng-ui-theme.d.ts +95 -0
  211. package/types/star-ng-ui-toast.d.ts +84 -0
  212. package/types/star-ng-ui-toggle-switch.d.ts +81 -0
  213. package/types/star-ng-ui-tooltip.d.ts +66 -0
  214. package/types/star-ng-ui-transloco.d.ts +14 -0
  215. package/types/star-ng-ui-tree.d.ts +310 -0
  216. package/types/star-ng-ui-utility.d.ts +533 -0
  217. package/types/star-ng-ui.d.ts +51 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"star-ng-ui-listbox.mjs","names":[],"sources":["../../../projects/star-ng/listbox/virtual-rows.ts","../../../projects/star-ng/listbox/listbox.ts"],"sourcesContent":["/**\n * Pure helpers of the virtual list in `star-listbox`: row model, index math, keyboard target and\n * ARIA values. They have no DOM access, so unit tests can check them without layout.\n */\n\n/** One row of the virtual list. Group headings and options have the same height. */\nexport type ListboxRow<T> =\n | { readonly kind: 'group'; readonly key: string; readonly label: string; readonly id: string }\n | {\n readonly kind: 'option';\n readonly key: string;\n readonly option: T;\n /** Index in the visible options (keyboard order). */\n readonly index: number;\n /** Id of the heading row of the group, or null without groups. */\n readonly groupId: string | null;\n /** Index of the heading row of the group, or -1 without groups. */\n readonly groupRow: number;\n };\n\n/** The rows, and for each visible option the index of its row. */\nexport interface ListboxLayout<T> {\n readonly rows: readonly ListboxRow<T>[];\n readonly rowOfOption: readonly number[];\n}\n\n/**\n * Flattens headings and options into one list of rows of equal height. `options` must already be\n * in display order (each group together). A heading comes before the first option of each group.\n * The heading id has the form `<idPrefix>-group-<index of the first option of the group>`.\n */\nexport function buildLayout<T>(\n options: readonly T[],\n groupOf: ((option: T) => string) | null,\n idPrefix: string,\n): ListboxLayout<T> {\n const rows: ListboxRow<T>[] = [];\n const rowOfOption: number[] = [];\n let current: string | null = null;\n let groupId: string | null = null;\n let groupRow = -1;\n options.forEach((option, index) => {\n if (groupOf) {\n const label = groupOf(option);\n if (index === 0 || label !== current) {\n current = label;\n groupId = `${idPrefix}-group-${index}`;\n groupRow = rows.length;\n rows.push({ kind: 'group', key: `g:${index}`, label, id: groupId });\n }\n }\n rowOfOption.push(rows.length);\n rows.push({ kind: 'option', key: `o:${index}`, option, index, groupId, groupRow });\n });\n return { rows, rowOfOption };\n}\n\n/** Number of options a Page up / Page down key moves: the lines in view, minus one for overlap. */\nexport function pageSize(viewportHeight: number, itemSize: number): number {\n const lines = Math.floor(viewportHeight / Math.max(1, itemSize));\n return Math.max(1, lines - 1);\n}\n\nexport type ListNavigationKey = 'ArrowDown' | 'ArrowUp' | 'Home' | 'End' | 'PageDown' | 'PageUp';\n\n/** Index of the option a navigation key moves to, limited to the list. -1 for an empty list. */\nexport function keyboardTarget(\n key: ListNavigationKey,\n active: number,\n count: number,\n page: number,\n): number {\n if (count <= 0) return -1;\n const last = count - 1;\n let target: number;\n switch (key) {\n case 'ArrowDown':\n target = active + 1;\n break;\n case 'ArrowUp':\n target = active - 1;\n break;\n case 'Home':\n target = 0;\n break;\n case 'End':\n target = last;\n break;\n case 'PageDown':\n target = (active < 0 ? 0 : active) + page;\n break;\n case 'PageUp':\n target = (active < 0 ? last : active) - page;\n break;\n }\n return Math.min(Math.max(target, 0), last);\n}\n\n/** Index of the first option whose label starts with the typed text (compared in lower case). */\nexport function typeaheadIndex(\n count: number,\n labelAt: (index: number) => string,\n typed: string,\n): number {\n for (let i = 0; i < count; i++) {\n if (labelAt(i).toLowerCase().startsWith(typed)) return i;\n }\n return -1;\n}\n\n/** First and last row to bring into view for an option: its heading row comes with the first option. */\nexport function revealRows<T>(layout: ListboxLayout<T>, index: number): [number, number] {\n const row = layout.rowOfOption[index];\n if (row === undefined) return [0, 0];\n const above = layout.rows[row - 1];\n return [above?.kind === 'group' ? row - 1 : row, row];\n}\n\n/**\n * Scroll offset that brings rows `first` to `last` into view with the least movement, or null when\n * they are in view. Rows have the height `itemSize`.\n */\nexport function revealOffset(\n first: number,\n last: number,\n itemSize: number,\n scrollOffset: number,\n viewportHeight: number,\n): number | null {\n const top = first * itemSize;\n const bottom = (last + 1) * itemSize;\n if (top < scrollOffset) return top;\n if (viewportHeight > 0 && bottom > scrollOffset + viewportHeight) return bottom - viewportHeight;\n return null;\n}\n\n/** `aria-setsize` and `aria-posinset` of an option, for the whole list. */\nexport function ariaPosition(index: number, count: number): { setsize: number; posinset: number } {\n return { setsize: count, posinset: index + 1 };\n}\n\n/** CSS height of the list: `scrollHeight` at most, and no taller than the rows need. */\nexport function listHeight(scrollHeight: string, rowCount: number, itemSize: number): string {\n return `min(${scrollHeight}, ${rowCount * Math.max(1, itemSize)}px)`;\n}\n\n/** True when a row is inside the rendered range `[start, end)`. */\nexport function isRowRendered(row: number, range: { start: number; end: number }): boolean {\n return row >= range.start && row < range.end;\n}\n","import { _IdGenerator } from '@angular/cdk/a11y';\nimport {\n CdkFixedSizeVirtualScroll,\n CdkVirtualForOf,\n CdkVirtualScrollViewport,\n} from '@angular/cdk/scrolling';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n afterNextRender,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n effect,\n ElementRef,\n inject,\n Injector,\n input,\n model,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\nimport {\n matchesFilter,\n optionText,\n readOption,\n STAR_UI_TEXT,\n StarOptionKey,\n} from '@star-ng/ui/core';\nimport { StarOptionTemplate } from '@star-ng/ui/select';\nimport {\n ariaPosition,\n buildLayout,\n isRowRendered,\n keyboardTarget,\n ListboxRow,\n listHeight,\n ListNavigationKey,\n pageSize,\n revealOffset,\n revealRows,\n typeaheadIndex,\n} from './virtual-rows';\n\n/**\n * Inline list choice (PrimeNG `p-listbox`): single or `multiple` (checkboxes), filter,\n * option template, WAI-ARIA listbox keyboard (Arrow, Home / End, Space / Enter, typeahead).\n * Value: one value, or an array in `multiple` mode.\n *\n * `<star-listbox [options]=\"queues\" optionLabel=\"name\" optionValue=\"id\" [(value)]=\"queue\" filter ariaLabel=\"Queue\" />`\n */\n@Component({\n selector: 'star-listbox',\n imports: [NgTemplateOutlet, CdkVirtualScrollViewport, CdkFixedSizeVirtualScroll, CdkVirtualForOf],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'star-listbox-box',\n '[class.star-listbox-box--disabled]': 'disabled()',\n '[class.star-listbox-box--invalid]': 'invalid() && touched()',\n },\n template: `\n @if (filter()) {\n <div class=\"star-panel__filter\">\n <i class=\"ph-bold ph-magnifying-glass\" aria-hidden=\"true\"></i>\n <input\n #filterInput\n type=\"search\"\n class=\"star-input star-input--sm\"\n autocomplete=\"off\"\n [attr.aria-label]=\"text.filterPlaceholder\"\n [attr.aria-controls]=\"listId\"\n [placeholder]=\"text.filterPlaceholder\"\n [value]=\"query()\"\n (input)=\"onFilterInput(filterInput.value)\"\n (keydown)=\"onKeydown($event)\"\n />\n </div>\n }\n @if (virtualScroll()) {\n <!-- Virtual scroll: the CDK viewport is the listbox. Group headings and options are rows of one height. -->\n <cdk-virtual-scroll-viewport\n #list\n class=\"star-listbox star-listbox--virtual star-listbox--viewport\"\n role=\"listbox\"\n [id]=\"listId\"\n [itemSize]=\"itemSize()\"\n [minBufferPx]=\"itemSize() * 4\"\n [maxBufferPx]=\"itemSize() * 8\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-multiselectable]=\"multiple() || null\"\n [attr.aria-activedescendant]=\"activeId()\"\n [attr.aria-disabled]=\"disabled() || null\"\n [style.--star-item-size.px]=\"itemSize()\"\n [style.height]=\"viewportHeight()\"\n (keydown)=\"onKeydown($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"touch.emit()\"\n >\n <ng-container *cdkVirtualFor=\"let row of layout().rows; trackBy: trackRow\">\n @if (row.kind === 'group') {\n <div class=\"star-listbox__group\" role=\"presentation\" [id]=\"row.id\">\n {{ row.label }}\n </div>\n } @else {\n @let option = row.option;\n @let i = row.index;\n @let position = positionOf(i);\n <!-- Keyboard is handled on the listbox via aria-activedescendant. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n class=\"star-listbox__option\"\n role=\"option\"\n [id]=\"listId + '-' + i\"\n [class.star-listbox__option--active]=\"active() === i\"\n [class.star-listbox__option--selected]=\"isSelected(option)\"\n [attr.aria-selected]=\"isSelected(option)\"\n [attr.aria-disabled]=\"isDisabled(option) || null\"\n [attr.aria-describedby]=\"describedBy(row)\"\n [attr.aria-setsize]=\"position.setsize\"\n [attr.aria-posinset]=\"position.posinset\"\n (click)=\"active.set(i); choose(option)\"\n >\n @if (multiple()) {\n <span class=\"star-check__box\" aria-hidden=\"true\">\n @if (isSelected(option)) {\n <i class=\"ph-bold ph-check\"></i>\n }\n </span>\n }\n <span class=\"star-listbox__label\">\n @if (optionTemplate(); as custom) {\n <ng-container\n *ngTemplateOutlet=\"\n custom.template;\n context: { $implicit: option, selected: isSelected(option), index: i }\n \"\n />\n } @else {\n {{ labelOf(option) }}\n }\n </span>\n </div>\n }\n </ng-container>\n </cdk-virtual-scroll-viewport>\n @if (!visible().length) {\n <div class=\"star-listbox__empty\" role=\"presentation\">{{ text.emptyFilterMessage }}</div>\n }\n } @else {\n <ul\n #list\n class=\"star-listbox\"\n role=\"listbox\"\n [id]=\"listId\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-multiselectable]=\"multiple() || null\"\n [attr.aria-activedescendant]=\"activeId()\"\n [attr.aria-disabled]=\"disabled() || null\"\n [style.max-height]=\"scrollHeight()\"\n (keydown)=\"onKeydown($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"touch.emit()\"\n >\n @for (option of visible(); track $index; let i = $index) {\n @if (groupHeading(i); as heading) {\n <li class=\"star-listbox__group\" role=\"presentation\" [id]=\"groupId(i)\">{{ heading }}</li>\n }\n <!-- Keyboard is handled on the listbox via aria-activedescendant. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <li\n class=\"star-listbox__option\"\n role=\"option\"\n [id]=\"listId + '-' + i\"\n [class.star-listbox__option--active]=\"active() === i\"\n [class.star-listbox__option--selected]=\"isSelected(option)\"\n [attr.aria-selected]=\"isSelected(option)\"\n [attr.aria-disabled]=\"isDisabled(option) || null\"\n [attr.aria-describedby]=\"groupId(i)\"\n (click)=\"active.set(i); choose(option)\"\n >\n @if (multiple()) {\n <span class=\"star-check__box\" aria-hidden=\"true\">\n @if (isSelected(option)) {\n <i class=\"ph-bold ph-check\"></i>\n }\n </span>\n }\n <span class=\"star-listbox__label\">\n @if (optionTemplate(); as custom) {\n <ng-container\n *ngTemplateOutlet=\"\n custom.template;\n context: { $implicit: option, selected: isSelected(option), index: i }\n \"\n />\n } @else {\n {{ labelOf(option) }}\n }\n </span>\n </li>\n }\n </ul>\n <!-- Outside the listbox: a listbox may contain options and groups only. -->\n @if (!visible().length) {\n <div class=\"star-listbox__empty\" role=\"presentation\">{{ text.emptyFilterMessage }}</div>\n }\n }\n `,\n})\nexport class StarListbox<TOption = unknown, TValue = TOption> implements FormValueControl<\n TValue | readonly TValue[] | null\n> {\n protected readonly text = inject(STAR_UI_TEXT);\n protected readonly listId = inject(_IdGenerator).getId('star-listbox-');\n\n readonly value = model<TValue | readonly TValue[] | null>(null);\n readonly options = input<readonly TOption[]>([]);\n readonly optionLabel = input<StarOptionKey<TOption> | null>(null);\n readonly optionValue = input<StarOptionKey<TOption> | null>(null);\n readonly optionDisabled = input<StarOptionKey<TOption> | null>(null);\n /**\n * Group heading of an option (property name or function). Options with the same heading\n * show together under it, in the order in which the headings first appear.\n */\n readonly optionGroup = input<StarOptionKey<TOption> | null>(null);\n readonly multiple = input(false, { transform: booleanAttribute });\n readonly filter = input(false, { transform: booleanAttribute });\n /** Height of the list. With `virtualScroll` it is the height of the list, or less for a short list. */\n readonly scrollHeight = input('16rem');\n /**\n * Renders only the rows in and near the view (CDK virtual scroll), for lists of thousands of\n * options. Every row, group headings included, has the height `virtualItemSize` and the text\n * stays on one line. Keys and type-ahead work over all options. Page up and Page down move by\n * the lines in view.\n */\n readonly virtualScroll = input(false, { transform: booleanAttribute });\n /** Row height in pixels with `virtualScroll`. */\n readonly virtualItemSize = input(40);\n readonly ariaLabel = input<string | null>(null);\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly invalid = input(false, { transform: booleanAttribute });\n readonly touched = input(false, { transform: booleanAttribute });\n readonly touch = output<void>();\n\n protected readonly optionTemplate = contentChild(StarOptionTemplate);\n private readonly list = viewChild<unknown, ElementRef<HTMLElement>>('list', { read: ElementRef });\n private readonly viewport = viewChild(CdkVirtualScrollViewport);\n private readonly injector = inject(Injector);\n protected readonly query = signal('');\n protected readonly active = signal(-1);\n private typeahead = '';\n private typeaheadAt = 0;\n\n protected readonly visible = computed(() => {\n const options = this.options().filter((option) =>\n matchesFilter(this.labelOf(option), this.query()),\n );\n if (!this.optionGroup()) return options;\n // Keep each group together, in the order in which the groups first appear.\n const order = new Map<string, number>();\n for (const option of options) {\n const group = this.groupOf(option);\n if (!order.has(group)) order.set(group, order.size);\n }\n return options\n .map((option, index) => ({ option, index, rank: order.get(this.groupOf(option)) ?? 0 }))\n .sort((a, b) => a.rank - b.rank || a.index - b.index)\n .map(({ option }) => option);\n });\n\n protected groupOf(option: TOption): string {\n const key = this.optionGroup();\n const group = key ? readOption(option, key) : null;\n return group === null || group === undefined ? '' : String(group);\n }\n\n /** Heading to show before the option at an index: the first option of each group. */\n protected groupHeading(index: number): string | null {\n if (!this.optionGroup()) return null;\n const options = this.visible();\n const group = this.groupOf(options[index]);\n return index === 0 || this.groupOf(options[index - 1]) !== group ? group : null;\n }\n\n protected groupId(index: number): string | null {\n if (!this.optionGroup()) return null;\n const options = this.visible();\n let first = index;\n while (first > 0 && this.groupOf(options[first - 1]) === this.groupOf(options[index])) first--;\n return `${this.listId}-group-${first}`;\n }\n\n // ---- Virtual scroll ----\n\n protected readonly itemSize = computed(() => Math.max(1, this.virtualItemSize()));\n\n /** Group headings and options in one list of rows of equal height. */\n protected readonly layout = computed(() =>\n buildLayout(\n this.visible(),\n this.optionGroup() ? (option) => this.groupOf(option) : null,\n this.listId,\n ),\n );\n\n protected readonly viewportHeight = computed(() =>\n listHeight(this.scrollHeight(), this.layout().rows.length, this.itemSize()),\n );\n\n /** Rows that are in the DOM now: `[start, end)`, reported by the CDK viewport. */\n private readonly renderedRange = signal({ start: 0, end: 0 });\n\n protected readonly trackRow = (_index: number, row: ListboxRow<TOption>): string => row.key;\n\n protected positionOf(index: number): { setsize: number; posinset: number } {\n return ariaPosition(index, this.visible().length);\n }\n\n /** The heading of the group, only while its row is in the DOM (the id must exist). */\n protected describedBy(row: Extract<ListboxRow<TOption>, { kind: 'option' }>): string | null {\n return row.groupId !== null && isRowRendered(row.groupRow, this.renderedRange())\n ? row.groupId\n : null;\n }\n\n /** `aria-activedescendant` only names an option that is in the DOM. */\n protected readonly activeId = computed(() => {\n const index = this.active();\n if (index < 0 || index >= this.visible().length) return null;\n if (this.virtualScroll()) {\n const row = this.layout().rowOfOption[index];\n if (row === undefined || !isRowRendered(row, this.renderedRange())) return null;\n }\n return `${this.listId}-${index}`;\n });\n\n constructor() {\n effect((onCleanup) => {\n const viewport = this.viewport();\n if (!viewport) return;\n const element = viewport.getElementRef().nativeElement;\n this.renderedRange.set(viewport.getRenderedRange());\n // The range is read after the rows have been drawn, so the ids it allows exist.\n const range = viewport.renderedRangeStream.subscribe((next) =>\n afterNextRender(() => this.renderedRange.set({ ...next }), { injector: this.injector }),\n );\n afterNextRender(\n () =>\n element\n .querySelector('.cdk-virtual-scroll-content-wrapper')\n ?.setAttribute('role', 'presentation'),\n { injector: this.injector },\n );\n // The viewport measures its height once; a new height (filter, hidden parent) needs a new measure.\n const observer =\n typeof ResizeObserver === 'undefined'\n ? null\n : new ResizeObserver(() => viewport.checkViewportSize());\n observer?.observe(element);\n onCleanup(() => {\n range.unsubscribe();\n observer?.disconnect();\n });\n });\n }\n\n protected labelOf(option: TOption): string {\n return optionText(option, this.optionLabel());\n }\n protected isDisabled(option: TOption): boolean {\n const key = this.optionDisabled();\n return key ? !!readOption(option, key) : false;\n }\n private valueOf(option: TOption): TValue {\n return readOption(option, this.optionValue()) as TValue;\n }\n protected isSelected(option: TOption): boolean {\n const value = this.value();\n const optionValue = this.valueOf(option);\n return Array.isArray(value)\n ? value.some((v) => Object.is(v, optionValue))\n : Object.is(value, optionValue);\n }\n protected firstSelectedOrZero(): number {\n return Math.max(\n 0,\n this.visible().findIndex((option) => this.isSelected(option)),\n );\n }\n\n protected choose(option: TOption): void {\n if (this.disabled() || this.isDisabled(option)) return;\n const optionValue = this.valueOf(option);\n if (this.multiple()) {\n const current = Array.isArray(this.value()) ? (this.value() as readonly TValue[]) : [];\n this.value.set(\n this.isSelected(option)\n ? current.filter((v) => !Object.is(v, optionValue))\n : [...current, optionValue],\n );\n } else {\n this.value.set(optionValue);\n }\n }\n\n protected onFilterInput(text: string): void {\n this.query.set(text);\n this.active.set(0);\n // The shorter list starts at its top.\n this.viewport()?.scrollToOffset(0);\n }\n\n protected onFocus(): void {\n if (this.active() >= 0) return;\n this.active.set(this.firstSelectedOrZero());\n if (this.virtualScroll()) this.reveal(this.active());\n }\n\n /**\n * Brings the active option into view. With `virtualScroll` the option may not be in the DOM yet:\n * the viewport scrolls to it (least movement, heading row included) and then renders it.\n */\n private reveal(index: number): void {\n if (!this.virtualScroll()) {\n queueMicrotask(() =>\n this.list()\n ?.nativeElement.querySelector(`#${CSS.escape(this.activeId() ?? '')}`)\n ?.scrollIntoView?.({ block: 'nearest' }),\n );\n return;\n }\n const viewport = this.viewport();\n if (!viewport) return;\n const [first, last] = revealRows(this.layout(), index);\n const offset = revealOffset(\n first,\n last,\n this.itemSize(),\n viewport.measureScrollOffset(),\n viewport.getViewportSize(),\n );\n if (offset !== null) viewport.scrollToOffset(offset);\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n const options = this.visible();\n if (!options.length || this.disabled()) return;\n const fromInput = event.target instanceof HTMLInputElement;\n const page = pageSize(this.viewport()?.getViewportSize() || 256, this.itemSize());\n const move = (key: ListNavigationKey | number) => {\n event.preventDefault();\n this.active.set(\n typeof key === 'number' ? key : keyboardTarget(key, this.active(), options.length, page),\n );\n this.reveal(this.active());\n if (!this.multiple() && !fromInput) {\n const option = options[this.active()];\n if (!this.isDisabled(option)) this.value.set(this.valueOf(option));\n }\n };\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n return move(event.key);\n case 'Home':\n case 'End':\n if (fromInput) return;\n return move(event.key);\n case 'PageDown':\n case 'PageUp':\n // Without `virtualScroll` the browser scrolls the list by a page.\n if (fromInput || !this.virtualScroll()) return;\n return move(event.key);\n case ' ':\n case 'Enter':\n if (event.key === ' ' && fromInput) return;\n event.preventDefault();\n if (options[this.active()] !== undefined) this.choose(options[this.active()]);\n return;\n default:\n if (event.key.length === 1 && !fromInput) {\n const now = Date.now();\n this.typeahead =\n (now - this.typeaheadAt > 500 ? '' : this.typeahead) + event.key.toLowerCase();\n this.typeaheadAt = now;\n // Over all options, also those that are not in the DOM.\n const index = typeaheadIndex(\n options.length,\n (i) => this.labelOf(options[i]),\n this.typeahead,\n );\n if (index >= 0) move(index);\n }\n }\n }\n\n focus(): void {\n this.list()?.nativeElement.focus();\n }\n}\n"],"mappings":"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"}