@star-ng/ui 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +162 -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 +786 -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 +484 -0
  22. package/fesm2022/star-ng-ui-core.mjs.map +1 -0
  23. package/fesm2022/star-ng-ui-data-display.mjs +1870 -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 +886 -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 +2547 -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 +3531 -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 +285 -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 +124 -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 +5807 -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 +373 -0
  173. package/types/star-ng-ui-data-display.d.ts +438 -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 +170 -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 +563 -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 +885 -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 +343 -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,2547 @@
1
+ import { _IdGenerator } from "@angular/cdk/a11y";
2
+ import { CdkMenuTrigger } from "@angular/cdk/menu";
3
+ import * as i0 from "@angular/core";
4
+ import { ChangeDetectionStrategy, Component, DestroyRef, Directive, Injector, TemplateRef, afterNextRender, booleanAttribute, computed, contentChild, inject, input, model, output, signal, viewChild } from "@angular/core";
5
+ import { STAR_UI_TEXT, StarDirectionService, matchesFilter, optionText, readOption, starListKeyboardTarget, starListLayout, starListPageSize, starListRevealOffset, starListRevealRows, starListRowRendered } from "@star-ng/ui/core";
6
+ import { STAR_MENU_POSITIONS, StarMenu, StarMenuInDialog } from "@star-ng/ui/menu";
7
+ import { CdkConnectedOverlay, CdkOverlayOrigin } from "@angular/cdk/overlay";
8
+ import { DOCUMENT, NgTemplateOutlet } from "@angular/common";
9
+ var StarCascadeSelect = class StarCascadeSelect {
10
+ directionSync = inject(StarDirectionService);
11
+ text = inject(STAR_UI_TEXT);
12
+ positions = STAR_MENU_POSITIONS;
13
+ value = model(null, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
14
+ options = input([], ...ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []);
15
+ optionLabel = input(null, ...ngDevMode ? [{ debugName: "optionLabel" }] : /* istanbul ignore next */ []);
16
+ optionValue = input(null, ...ngDevMode ? [{ debugName: "optionValue" }] : /* istanbul ignore next */ []);
17
+ optionChildren = input("children", ...ngDevMode ? [{ debugName: "optionChildren" }] : /* istanbul ignore next */ []);
18
+ optionDisabled = input(null, ...ngDevMode ? [{ debugName: "optionDisabled" }] : /* istanbul ignore next */ []);
19
+ compareWith = input(Object.is, ...ngDevMode ? [{ debugName: "compareWith" }] : /* istanbul ignore next */ []);
20
+ placeholder = input(null, ...ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []);
21
+ showPath = input(false, {
22
+ ...ngDevMode ? { debugName: "showPath" } : /* istanbul ignore next */ {},
23
+ transform: booleanAttribute
24
+ });
25
+ showClear = input(false, {
26
+ ...ngDevMode ? { debugName: "showClear" } : /* istanbul ignore next */ {},
27
+ transform: booleanAttribute
28
+ });
29
+ size = input("md", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
30
+ ariaLabel = input(null, ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
31
+ inputId = input(inject(_IdGenerator).getId("star-cascade-"), ...ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []);
32
+ disabled = input(false, {
33
+ ...ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {},
34
+ transform: booleanAttribute
35
+ });
36
+ readonly = input(false, {
37
+ ...ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {},
38
+ transform: booleanAttribute
39
+ });
40
+ required = input(false, {
41
+ ...ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {},
42
+ transform: booleanAttribute
43
+ });
44
+ invalid = input(false, {
45
+ ...ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {},
46
+ transform: booleanAttribute
47
+ });
48
+ touched = input(false, {
49
+ ...ngDevMode ? { debugName: "touched" } : /* istanbul ignore next */ {},
50
+ transform: booleanAttribute
51
+ });
52
+ touch = output();
53
+ optionSelect = output();
54
+ childrenOf(option) {
55
+ const children = readOption(option, this.optionChildren());
56
+ return Array.isArray(children) ? children : [];
57
+ }
58
+ labelOf(option) {
59
+ return optionText(option, this.optionLabel() ?? null);
60
+ }
61
+ leaves = computed(() => {
62
+ const out = [];
63
+ const walk = (options, path) => {
64
+ for (const option of options) {
65
+ const next = [...path, this.labelOf(option)];
66
+ const children = this.childrenOf(option);
67
+ if (children.length) walk(children, next);
68
+ else out.push({
69
+ option,
70
+ value: readOption(option, this.optionValue()),
71
+ path: next
72
+ });
73
+ }
74
+ };
75
+ walk(this.options(), []);
76
+ return out;
77
+ }, ...ngDevMode ? [{ debugName: "leaves" }] : /* istanbul ignore next */ []);
78
+ selected = computed(() => {
79
+ const value = this.value();
80
+ if (value === null || value === void 0) return null;
81
+ return this.leaves().find((leaf) => this.compareWith()(leaf.value, value)) ?? null;
82
+ }, ...ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []);
83
+ menuItems = computed(() => {
84
+ const disabledKey = this.optionDisabled();
85
+ const selected = this.selected()?.option;
86
+ const build = (options) => options.map((option) => {
87
+ const children = this.childrenOf(option);
88
+ const disabled = disabledKey ? !!readOption(option, disabledKey) : false;
89
+ return children.length ? {
90
+ label: this.labelOf(option),
91
+ disabled,
92
+ items: build(children)
93
+ } : {
94
+ label: this.labelOf(option),
95
+ disabled,
96
+ icon: option === selected ? "ph-bold ph-check" : void 0,
97
+ command: () => this.choose(option)
98
+ };
99
+ });
100
+ return build(this.options());
101
+ }, ...ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []);
102
+ triggerName = computed(() => {
103
+ const label = this.ariaLabel();
104
+ if (!label) return null;
105
+ const leaf = this.selected();
106
+ return `${label}: ${leaf ? this.display(leaf) : this.placeholder() ?? this.text.selectPlaceholder}`;
107
+ }, ...ngDevMode ? [{ debugName: "triggerName" }] : /* istanbul ignore next */ []);
108
+ display(leaf) {
109
+ return this.showPath() ? leaf.path.join(" / ") : leaf.path.at(-1) ?? "";
110
+ }
111
+ choose(option) {
112
+ this.value.set(readOption(option, this.optionValue()));
113
+ this.optionSelect.emit(option);
114
+ }
115
+ clear() {
116
+ this.value.set(null);
117
+ }
118
+ static ɵfac = i0.ɵɵngDeclareFactory({
119
+ minVersion: "12.0.0",
120
+ version: "22.2.6",
121
+ ngImport: i0,
122
+ type: StarCascadeSelect,
123
+ deps: [],
124
+ target: i0.ɵɵFactoryTarget.Component
125
+ });
126
+ static ɵcmp = i0.ɵɵngDeclareComponent({
127
+ minVersion: "17.0.0",
128
+ version: "22.2.6",
129
+ type: StarCascadeSelect,
130
+ isStandalone: true,
131
+ selector: "star-cascade-select",
132
+ inputs: {
133
+ value: {
134
+ classPropertyName: "value",
135
+ publicName: "value",
136
+ isSignal: true,
137
+ isRequired: false,
138
+ transformFunction: null
139
+ },
140
+ options: {
141
+ classPropertyName: "options",
142
+ publicName: "options",
143
+ isSignal: true,
144
+ isRequired: false,
145
+ transformFunction: null
146
+ },
147
+ optionLabel: {
148
+ classPropertyName: "optionLabel",
149
+ publicName: "optionLabel",
150
+ isSignal: true,
151
+ isRequired: false,
152
+ transformFunction: null
153
+ },
154
+ optionValue: {
155
+ classPropertyName: "optionValue",
156
+ publicName: "optionValue",
157
+ isSignal: true,
158
+ isRequired: false,
159
+ transformFunction: null
160
+ },
161
+ optionChildren: {
162
+ classPropertyName: "optionChildren",
163
+ publicName: "optionChildren",
164
+ isSignal: true,
165
+ isRequired: false,
166
+ transformFunction: null
167
+ },
168
+ optionDisabled: {
169
+ classPropertyName: "optionDisabled",
170
+ publicName: "optionDisabled",
171
+ isSignal: true,
172
+ isRequired: false,
173
+ transformFunction: null
174
+ },
175
+ compareWith: {
176
+ classPropertyName: "compareWith",
177
+ publicName: "compareWith",
178
+ isSignal: true,
179
+ isRequired: false,
180
+ transformFunction: null
181
+ },
182
+ placeholder: {
183
+ classPropertyName: "placeholder",
184
+ publicName: "placeholder",
185
+ isSignal: true,
186
+ isRequired: false,
187
+ transformFunction: null
188
+ },
189
+ showPath: {
190
+ classPropertyName: "showPath",
191
+ publicName: "showPath",
192
+ isSignal: true,
193
+ isRequired: false,
194
+ transformFunction: null
195
+ },
196
+ showClear: {
197
+ classPropertyName: "showClear",
198
+ publicName: "showClear",
199
+ isSignal: true,
200
+ isRequired: false,
201
+ transformFunction: null
202
+ },
203
+ size: {
204
+ classPropertyName: "size",
205
+ publicName: "size",
206
+ isSignal: true,
207
+ isRequired: false,
208
+ transformFunction: null
209
+ },
210
+ ariaLabel: {
211
+ classPropertyName: "ariaLabel",
212
+ publicName: "ariaLabel",
213
+ isSignal: true,
214
+ isRequired: false,
215
+ transformFunction: null
216
+ },
217
+ inputId: {
218
+ classPropertyName: "inputId",
219
+ publicName: "inputId",
220
+ isSignal: true,
221
+ isRequired: false,
222
+ transformFunction: null
223
+ },
224
+ disabled: {
225
+ classPropertyName: "disabled",
226
+ publicName: "disabled",
227
+ isSignal: true,
228
+ isRequired: false,
229
+ transformFunction: null
230
+ },
231
+ readonly: {
232
+ classPropertyName: "readonly",
233
+ publicName: "readonly",
234
+ isSignal: true,
235
+ isRequired: false,
236
+ transformFunction: null
237
+ },
238
+ required: {
239
+ classPropertyName: "required",
240
+ publicName: "required",
241
+ isSignal: true,
242
+ isRequired: false,
243
+ transformFunction: null
244
+ },
245
+ invalid: {
246
+ classPropertyName: "invalid",
247
+ publicName: "invalid",
248
+ isSignal: true,
249
+ isRequired: false,
250
+ transformFunction: null
251
+ },
252
+ touched: {
253
+ classPropertyName: "touched",
254
+ publicName: "touched",
255
+ isSignal: true,
256
+ isRequired: false,
257
+ transformFunction: null
258
+ }
259
+ },
260
+ outputs: {
261
+ value: "valueChange",
262
+ touch: "touch",
263
+ optionSelect: "optionSelect"
264
+ },
265
+ host: {
266
+ properties: {
267
+ "class.star-select--disabled": "disabled()",
268
+ "class.star-select--invalid": "invalid() && touched()",
269
+ "class.star-select--sm": "size() === 'sm'"
270
+ },
271
+ classAttribute: "star-select star-cascade"
272
+ },
273
+ ngImport: i0,
274
+ template: `
275
+ <div class="star-select__control">
276
+ <button
277
+ #trigger="cdkMenuTriggerFor"
278
+ type="button"
279
+ class="star-select__trigger star-cascade__trigger"
280
+ [id]="inputId()"
281
+ [cdkMenuTriggerFor]="menu.template()"
282
+ [cdkMenuTriggerData]="{ $implicit: menuItems() }"
283
+ [cdkMenuPosition]="positions"
284
+ [disabled]="disabled() || readonly()"
285
+ [attr.aria-label]="triggerName()"
286
+ [attr.aria-invalid]="(invalid() && touched()) || null"
287
+ (cdkMenuClosed)="touch.emit()"
288
+ >
289
+ @if (selected(); as leaf) {
290
+ <span class="star-select__value">{{ display(leaf) }}</span>
291
+ } @else {
292
+ <span class="star-select__placeholder">{{
293
+ placeholder() ?? text.selectPlaceholder
294
+ }}</span>
295
+ }
296
+ </button>
297
+ @if (showClear() && selected() && !disabled() && !readonly()) {
298
+ <button
299
+ type="button"
300
+ class="star-select__icon-btn"
301
+ [attr.aria-label]="text.clear"
302
+ (click)="clear()"
303
+ >
304
+ <i class="ph-bold ph-x" aria-hidden="true"></i>
305
+ </button>
306
+ }
307
+ <i class="ph-bold ph-caret-down star-select__caret" aria-hidden="true"></i>
308
+ </div>
309
+ <star-menu #menu [ariaLabel]="ariaLabel()" />
310
+ `,
311
+ isInline: true,
312
+ dependencies: [
313
+ {
314
+ kind: "directive",
315
+ type: CdkMenuTrigger,
316
+ selector: "[cdkMenuTriggerFor]",
317
+ inputs: [
318
+ "cdkMenuTriggerFor",
319
+ "cdkMenuPosition",
320
+ "cdkMenuTriggerData",
321
+ "cdkMenuTriggerTransformOriginOn"
322
+ ],
323
+ outputs: ["cdkMenuOpened", "cdkMenuClosed"],
324
+ exportAs: ["cdkMenuTriggerFor"]
325
+ },
326
+ {
327
+ kind: "component",
328
+ type: StarMenu,
329
+ selector: "star-menu",
330
+ inputs: [
331
+ "items",
332
+ "inline",
333
+ "ariaLabel"
334
+ ],
335
+ outputs: ["itemClick"]
336
+ },
337
+ {
338
+ kind: "directive",
339
+ type: StarMenuInDialog,
340
+ selector: "[cdkMenuTriggerFor]"
341
+ }
342
+ ],
343
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
344
+ });
345
+ };
346
+ i0.ɵɵngDeclareClassMetadata({
347
+ minVersion: "12.0.0",
348
+ version: "22.2.6",
349
+ ngImport: i0,
350
+ type: StarCascadeSelect,
351
+ decorators: [{
352
+ type: Component,
353
+ args: [{
354
+ selector: "star-cascade-select",
355
+ imports: [
356
+ CdkMenuTrigger,
357
+ StarMenu,
358
+ StarMenuInDialog
359
+ ],
360
+ changeDetection: ChangeDetectionStrategy.OnPush,
361
+ host: {
362
+ class: "star-select star-cascade",
363
+ "[class.star-select--disabled]": "disabled()",
364
+ "[class.star-select--invalid]": "invalid() && touched()",
365
+ "[class.star-select--sm]": "size() === 'sm'"
366
+ },
367
+ template: `
368
+ <div class="star-select__control">
369
+ <button
370
+ #trigger="cdkMenuTriggerFor"
371
+ type="button"
372
+ class="star-select__trigger star-cascade__trigger"
373
+ [id]="inputId()"
374
+ [cdkMenuTriggerFor]="menu.template()"
375
+ [cdkMenuTriggerData]="{ $implicit: menuItems() }"
376
+ [cdkMenuPosition]="positions"
377
+ [disabled]="disabled() || readonly()"
378
+ [attr.aria-label]="triggerName()"
379
+ [attr.aria-invalid]="(invalid() && touched()) || null"
380
+ (cdkMenuClosed)="touch.emit()"
381
+ >
382
+ @if (selected(); as leaf) {
383
+ <span class="star-select__value">{{ display(leaf) }}</span>
384
+ } @else {
385
+ <span class="star-select__placeholder">{{
386
+ placeholder() ?? text.selectPlaceholder
387
+ }}</span>
388
+ }
389
+ </button>
390
+ @if (showClear() && selected() && !disabled() && !readonly()) {
391
+ <button
392
+ type="button"
393
+ class="star-select__icon-btn"
394
+ [attr.aria-label]="text.clear"
395
+ (click)="clear()"
396
+ >
397
+ <i class="ph-bold ph-x" aria-hidden="true"></i>
398
+ </button>
399
+ }
400
+ <i class="ph-bold ph-caret-down star-select__caret" aria-hidden="true"></i>
401
+ </div>
402
+ <star-menu #menu [ariaLabel]="ariaLabel()" />
403
+ `
404
+ }]
405
+ }],
406
+ propDecorators: {
407
+ value: [{
408
+ type: i0.Input,
409
+ args: [{
410
+ isSignal: true,
411
+ alias: "value",
412
+ required: false
413
+ }]
414
+ }, {
415
+ type: i0.Output,
416
+ args: ["valueChange"]
417
+ }],
418
+ options: [{
419
+ type: i0.Input,
420
+ args: [{
421
+ isSignal: true,
422
+ alias: "options",
423
+ required: false
424
+ }]
425
+ }],
426
+ optionLabel: [{
427
+ type: i0.Input,
428
+ args: [{
429
+ isSignal: true,
430
+ alias: "optionLabel",
431
+ required: false
432
+ }]
433
+ }],
434
+ optionValue: [{
435
+ type: i0.Input,
436
+ args: [{
437
+ isSignal: true,
438
+ alias: "optionValue",
439
+ required: false
440
+ }]
441
+ }],
442
+ optionChildren: [{
443
+ type: i0.Input,
444
+ args: [{
445
+ isSignal: true,
446
+ alias: "optionChildren",
447
+ required: false
448
+ }]
449
+ }],
450
+ optionDisabled: [{
451
+ type: i0.Input,
452
+ args: [{
453
+ isSignal: true,
454
+ alias: "optionDisabled",
455
+ required: false
456
+ }]
457
+ }],
458
+ compareWith: [{
459
+ type: i0.Input,
460
+ args: [{
461
+ isSignal: true,
462
+ alias: "compareWith",
463
+ required: false
464
+ }]
465
+ }],
466
+ placeholder: [{
467
+ type: i0.Input,
468
+ args: [{
469
+ isSignal: true,
470
+ alias: "placeholder",
471
+ required: false
472
+ }]
473
+ }],
474
+ showPath: [{
475
+ type: i0.Input,
476
+ args: [{
477
+ isSignal: true,
478
+ alias: "showPath",
479
+ required: false
480
+ }]
481
+ }],
482
+ showClear: [{
483
+ type: i0.Input,
484
+ args: [{
485
+ isSignal: true,
486
+ alias: "showClear",
487
+ required: false
488
+ }]
489
+ }],
490
+ size: [{
491
+ type: i0.Input,
492
+ args: [{
493
+ isSignal: true,
494
+ alias: "size",
495
+ required: false
496
+ }]
497
+ }],
498
+ ariaLabel: [{
499
+ type: i0.Input,
500
+ args: [{
501
+ isSignal: true,
502
+ alias: "ariaLabel",
503
+ required: false
504
+ }]
505
+ }],
506
+ inputId: [{
507
+ type: i0.Input,
508
+ args: [{
509
+ isSignal: true,
510
+ alias: "inputId",
511
+ required: false
512
+ }]
513
+ }],
514
+ disabled: [{
515
+ type: i0.Input,
516
+ args: [{
517
+ isSignal: true,
518
+ alias: "disabled",
519
+ required: false
520
+ }]
521
+ }],
522
+ readonly: [{
523
+ type: i0.Input,
524
+ args: [{
525
+ isSignal: true,
526
+ alias: "readonly",
527
+ required: false
528
+ }]
529
+ }],
530
+ required: [{
531
+ type: i0.Input,
532
+ args: [{
533
+ isSignal: true,
534
+ alias: "required",
535
+ required: false
536
+ }]
537
+ }],
538
+ invalid: [{
539
+ type: i0.Input,
540
+ args: [{
541
+ isSignal: true,
542
+ alias: "invalid",
543
+ required: false
544
+ }]
545
+ }],
546
+ touched: [{
547
+ type: i0.Input,
548
+ args: [{
549
+ isSignal: true,
550
+ alias: "touched",
551
+ required: false
552
+ }]
553
+ }],
554
+ touch: [{
555
+ type: i0.Output,
556
+ args: ["touch"]
557
+ }],
558
+ optionSelect: [{
559
+ type: i0.Output,
560
+ args: ["optionSelect"]
561
+ }]
562
+ }
563
+ });
564
+ var StarOptionTemplate = class StarOptionTemplate {
565
+ starOptionOf = input(null, ...ngDevMode ? [{ debugName: "starOptionOf" }] : /* istanbul ignore next */ []);
566
+ template = inject(TemplateRef);
567
+ static ngTemplateContextGuard(_dir, _ctx) {
568
+ return true;
569
+ }
570
+ static ɵfac = i0.ɵɵngDeclareFactory({
571
+ minVersion: "12.0.0",
572
+ version: "22.2.6",
573
+ ngImport: i0,
574
+ type: StarOptionTemplate,
575
+ deps: [],
576
+ target: i0.ɵɵFactoryTarget.Directive
577
+ });
578
+ static ɵdir = i0.ɵɵngDeclareDirective({
579
+ minVersion: "17.1.0",
580
+ version: "22.2.6",
581
+ type: StarOptionTemplate,
582
+ isStandalone: true,
583
+ selector: "ng-template[starOption]",
584
+ inputs: { starOptionOf: {
585
+ classPropertyName: "starOptionOf",
586
+ publicName: "starOptionOf",
587
+ isSignal: true,
588
+ isRequired: false,
589
+ transformFunction: null
590
+ } },
591
+ ngImport: i0
592
+ });
593
+ };
594
+ i0.ɵɵngDeclareClassMetadata({
595
+ minVersion: "12.0.0",
596
+ version: "22.2.6",
597
+ ngImport: i0,
598
+ type: StarOptionTemplate,
599
+ decorators: [{
600
+ type: Directive,
601
+ args: [{ selector: "ng-template[starOption]" }]
602
+ }],
603
+ propDecorators: { starOptionOf: [{
604
+ type: i0.Input,
605
+ args: [{
606
+ isSignal: true,
607
+ alias: "starOptionOf",
608
+ required: false
609
+ }]
610
+ }] }
611
+ });
612
+ const VIRTUAL_BUFFER = 6;
613
+ const VIRTUAL_FALLBACK_HEIGHT = 256;
614
+ const PANEL_POSITIONS = [{
615
+ originX: "start",
616
+ originY: "bottom",
617
+ overlayX: "start",
618
+ overlayY: "top",
619
+ offsetY: 6
620
+ }, {
621
+ originX: "start",
622
+ originY: "top",
623
+ overlayX: "start",
624
+ overlayY: "bottom",
625
+ offsetY: -6
626
+ }];
627
+ var StarOptionListBase = class StarOptionListBase {
628
+ directionSync = inject(StarDirectionService);
629
+ text = inject(STAR_UI_TEXT);
630
+ ids = inject(_IdGenerator);
631
+ document = inject(DOCUMENT);
632
+ injector = inject(Injector);
633
+ options = input([], ...ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []);
634
+ optionLabel = input(null, ...ngDevMode ? [{ debugName: "optionLabel" }] : /* istanbul ignore next */ []);
635
+ optionValue = input(null, ...ngDevMode ? [{ debugName: "optionValue" }] : /* istanbul ignore next */ []);
636
+ optionDisabled = input(null, ...ngDevMode ? [{ debugName: "optionDisabled" }] : /* istanbul ignore next */ []);
637
+ compareWith = input(Object.is, ...ngDevMode ? [{ debugName: "compareWith" }] : /* istanbul ignore next */ []);
638
+ optionGroup = input(null, ...ngDevMode ? [{ debugName: "optionGroup" }] : /* istanbul ignore next */ []);
639
+ virtualScroll = input(false, {
640
+ ...ngDevMode ? { debugName: "virtualScroll" } : /* istanbul ignore next */ {},
641
+ transform: booleanAttribute
642
+ });
643
+ virtualItemSize = input(40, ...ngDevMode ? [{ debugName: "virtualItemSize" }] : /* istanbul ignore next */ []);
644
+ placeholder = input(null, ...ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []);
645
+ filter = input(false, {
646
+ ...ngDevMode ? { debugName: "filter" } : /* istanbul ignore next */ {},
647
+ transform: booleanAttribute
648
+ });
649
+ filterPlaceholder = input(null, ...ngDevMode ? [{ debugName: "filterPlaceholder" }] : /* istanbul ignore next */ []);
650
+ showClear = input(false, {
651
+ ...ngDevMode ? { debugName: "showClear" } : /* istanbul ignore next */ {},
652
+ transform: booleanAttribute
653
+ });
654
+ loading = input(false, {
655
+ ...ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {},
656
+ transform: booleanAttribute
657
+ });
658
+ emptyMessage = input(null, ...ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []);
659
+ scrollHeight = input("16rem", ...ngDevMode ? [{ debugName: "scrollHeight" }] : /* istanbul ignore next */ []);
660
+ size = input("md", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
661
+ ariaLabel = input(null, ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
662
+ ariaLabelledBy = input(null, ...ngDevMode ? [{ debugName: "ariaLabelledBy" }] : /* istanbul ignore next */ []);
663
+ inputId = input(this.ids.getId("star-select-"), ...ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []);
664
+ disabled = input(false, {
665
+ ...ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {},
666
+ transform: booleanAttribute
667
+ });
668
+ readonly = input(false, {
669
+ ...ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {},
670
+ transform: booleanAttribute
671
+ });
672
+ required = input(false, {
673
+ ...ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {},
674
+ transform: booleanAttribute
675
+ });
676
+ invalid = input(false, {
677
+ ...ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {},
678
+ transform: booleanAttribute
679
+ });
680
+ touched = input(false, {
681
+ ...ngDevMode ? { debugName: "touched" } : /* istanbul ignore next */ {},
682
+ transform: booleanAttribute
683
+ });
684
+ name = input("", ...ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []);
685
+ touch = output();
686
+ opened = output();
687
+ closed = output();
688
+ filterChange = output();
689
+ optionTemplate = contentChild(StarOptionTemplate, ...ngDevMode ? [{ debugName: "optionTemplate" }] : /* istanbul ignore next */ []);
690
+ trigger = viewChild.required("trigger", ...ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []);
691
+ filterInput = viewChild("filterInput", ...ngDevMode ? [{ debugName: "filterInput" }] : /* istanbul ignore next */ []);
692
+ positions = PANEL_POSITIONS;
693
+ listId = this.ids.getId("star-listbox-");
694
+ open = signal(false, ...ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []);
695
+ filterValue = signal("", ...ngDevMode ? [{ debugName: "filterValue" }] : /* istanbul ignore next */ []);
696
+ activeIndex = signal(-1, ...ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []);
697
+ showInvalid = computed(() => this.invalid() && this.touched(), ...ngDevMode ? [{ debugName: "showInvalid" }] : /* istanbul ignore next */ []);
698
+ interactive = computed(() => !this.disabled() && !this.readonly(), ...ngDevMode ? [{ debugName: "interactive" }] : /* istanbul ignore next */ []);
699
+ visibleOptions = computed(() => {
700
+ const query = this.filterValue();
701
+ const all = this.options();
702
+ const options = !this.filter() || !query ? all : all.filter((option) => matchesFilter(this.labelOf(option), query));
703
+ return this.groupedOrder(options);
704
+ }, ...ngDevMode ? [{ debugName: "visibleOptions" }] : /* istanbul ignore next */ []);
705
+ groupedOrder(options) {
706
+ if (!this.optionGroup()) return options;
707
+ const order = /* @__PURE__ */ new Map();
708
+ for (const option of options) {
709
+ const group = this.groupOf(option);
710
+ if (!order.has(group)) order.set(group, order.size);
711
+ }
712
+ return options.map((option, index) => ({
713
+ option,
714
+ index,
715
+ rank: order.get(this.groupOf(option)) ?? 0
716
+ })).sort((a, b) => a.rank - b.rank || a.index - b.index).map(({ option }) => option);
717
+ }
718
+ layout = computed(() => starListLayout(this.visibleOptions(), this.optionGroup() ? (option) => this.groupOf(option) : null, this.listId), ...ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []);
719
+ rows = computed(() => this.layout().rows, ...ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []);
720
+ listScrollTop = signal(0, ...ngDevMode ? [{ debugName: "listScrollTop" }] : /* istanbul ignore next */ []);
721
+ listHeight = signal(0, ...ngDevMode ? [{ debugName: "listHeight" }] : /* istanbul ignore next */ []);
722
+ virtualWindow = computed(() => {
723
+ const count = this.rows().length;
724
+ if (!this.virtualScroll()) return {
725
+ start: 0,
726
+ end: count,
727
+ before: 0,
728
+ after: 0
729
+ };
730
+ const size = Math.max(1, this.virtualItemSize());
731
+ const visible = Math.ceil((this.listHeight() || VIRTUAL_FALLBACK_HEIGHT) / size);
732
+ const first = Math.min(Math.floor(this.listScrollTop() / size), Math.max(0, count - visible));
733
+ const start = Math.max(0, first - VIRTUAL_BUFFER);
734
+ const end = Math.min(count, first + visible + VIRTUAL_BUFFER);
735
+ return {
736
+ start,
737
+ end,
738
+ before: start * size,
739
+ after: (count - end) * size
740
+ };
741
+ }, ...ngDevMode ? [{ debugName: "virtualWindow" }] : /* istanbul ignore next */ []);
742
+ renderedRows = computed(() => {
743
+ const rows = this.rows();
744
+ const { start, end } = this.virtualWindow();
745
+ return start === 0 && end === rows.length ? rows : rows.slice(start, end);
746
+ }, ...ngDevMode ? [{ debugName: "renderedRows" }] : /* istanbul ignore next */ []);
747
+ onListScroll(event) {
748
+ if (!this.virtualScroll()) return;
749
+ const list = event.target;
750
+ this.listScrollTop.set(list.scrollTop);
751
+ this.listHeight.set(list.clientHeight);
752
+ }
753
+ activeId = computed(() => {
754
+ const index = this.activeIndex();
755
+ if (!this.open() || index < 0) return null;
756
+ const row = this.layout().rowOfOption[index];
757
+ return row !== void 0 && starListRowRendered(row, this.virtualWindow()) ? this.optionId(index) : null;
758
+ }, ...ngDevMode ? [{ debugName: "activeId" }] : /* istanbul ignore next */ []);
759
+ describedBy(row) {
760
+ return row.groupId !== null && starListRowRendered(row.groupRow, this.virtualWindow()) ? row.groupId : null;
761
+ }
762
+ emptyText = computed(() => this.filterValue() ? this.text.emptyFilterMessage : this.emptyMessage() ?? this.text.emptyMessage, ...ngDevMode ? [{ debugName: "emptyText" }] : /* istanbul ignore next */ []);
763
+ typeahead = "";
764
+ typeaheadTimer;
765
+ constructor() {
766
+ inject(DestroyRef).onDestroy(() => clearTimeout(this.typeaheadTimer));
767
+ }
768
+ labelOf(option) {
769
+ return optionText(option, this.optionLabel() ?? null);
770
+ }
771
+ groupOf(option) {
772
+ const key = this.optionGroup();
773
+ const group = key ? readOption(option, key) : null;
774
+ return group === null || group === void 0 ? "" : String(group);
775
+ }
776
+ valueOf(option) {
777
+ return readOption(option, this.optionValue());
778
+ }
779
+ isDisabled(option) {
780
+ const key = this.optionDisabled();
781
+ return key ? !!readOption(option, key) : false;
782
+ }
783
+ equals(a, b) {
784
+ return this.compareWith()(a, b);
785
+ }
786
+ optionId(index) {
787
+ return `${this.listId}-${index}`;
788
+ }
789
+ optionContext(option, index) {
790
+ return {
791
+ $implicit: option,
792
+ selected: this.isSelected(option),
793
+ index
794
+ };
795
+ }
796
+ openPanel() {
797
+ if (!this.interactive() || this.open()) return;
798
+ this.open.set(true);
799
+ this.activeIndex.set(this.initialActiveIndex());
800
+ this.opened.emit();
801
+ }
802
+ closePanel(focusTrigger = true) {
803
+ if (!this.open()) return;
804
+ this.open.set(false);
805
+ this.activeIndex.set(-1);
806
+ this.listScrollTop.set(0);
807
+ if (this.filterValue()) {
808
+ this.filterValue.set("");
809
+ this.filterChange.emit("");
810
+ }
811
+ if (focusTrigger) this.trigger().nativeElement.focus();
812
+ this.closed.emit();
813
+ }
814
+ toggle() {
815
+ if (this.open()) this.closePanel();
816
+ else this.openPanel();
817
+ }
818
+ focus(options) {
819
+ this.trigger().nativeElement.focus(options);
820
+ }
821
+ onPanelAttached() {
822
+ this.filterInput()?.nativeElement.focus();
823
+ const height = this.listElement()?.clientHeight;
824
+ if (this.virtualScroll() && height) this.listHeight.set(height);
825
+ this.scrollActiveIntoView();
826
+ if (this.virtualScroll()) afterNextRender(() => {
827
+ const list = this.listElement();
828
+ if (list?.clientHeight) this.listHeight.set(list.clientHeight);
829
+ this.scrollActiveIntoView();
830
+ }, { injector: this.injector });
831
+ }
832
+ onOutsideClick(event) {
833
+ if (this.trigger().nativeElement.contains(event.target)) return;
834
+ this.closePanel(false);
835
+ this.touch.emit();
836
+ }
837
+ onPanelMousedown(event) {
838
+ if (!(event.target instanceof HTMLInputElement)) event.preventDefault();
839
+ }
840
+ onTriggerBlur() {
841
+ if (!this.open()) this.touch.emit();
842
+ }
843
+ onFilterInput(value) {
844
+ this.filterValue.set(value);
845
+ this.filterChange.emit(value);
846
+ this.resetScroll();
847
+ this.activeIndex.set(this.firstEnabledFrom(0, 1));
848
+ }
849
+ resetScroll() {
850
+ this.listScrollTop.set(0);
851
+ const list = this.listElement();
852
+ if (list) list.scrollTop = 0;
853
+ }
854
+ onOptionClick(option, index) {
855
+ if (this.isDisabled(option)) return;
856
+ this.activeIndex.set(index);
857
+ this.choose(option);
858
+ if (this.closeOnChoose) this.closePanel();
859
+ }
860
+ onKeydown(event) {
861
+ if (!this.interactive()) return;
862
+ const open = this.open();
863
+ switch (event.key) {
864
+ case "ArrowDown":
865
+ case "ArrowUp": {
866
+ event.preventDefault();
867
+ if (!open) {
868
+ this.openPanel();
869
+ return;
870
+ }
871
+ const step = event.key === "ArrowDown" ? 1 : -1;
872
+ if (event.altKey && step === -1) {
873
+ this.chooseActive();
874
+ this.closePanel();
875
+ return;
876
+ }
877
+ this.moveActive(step);
878
+ return;
879
+ }
880
+ case "Home":
881
+ case "End":
882
+ if (!open) return;
883
+ event.preventDefault();
884
+ this.activeIndex.set(event.key === "Home" ? this.firstEnabledFrom(0, 1) : this.firstEnabledFrom(this.visibleOptions().length - 1, -1));
885
+ this.scrollActiveIntoView();
886
+ return;
887
+ case "PageDown":
888
+ case "PageUp":
889
+ if (!open || !this.virtualScroll()) return;
890
+ event.preventDefault();
891
+ this.movePage(event.key === "PageDown" ? 1 : -1);
892
+ return;
893
+ case "Enter":
894
+ event.preventDefault();
895
+ if (!open) this.openPanel();
896
+ else this.chooseActive(this.closeOnChoose);
897
+ return;
898
+ case " ":
899
+ if (event.target instanceof HTMLInputElement) return;
900
+ event.preventDefault();
901
+ if (this.typeahead) {
902
+ this.runTypeahead(" ");
903
+ return;
904
+ }
905
+ if (!open) this.openPanel();
906
+ else this.chooseActive(this.closeOnChoose);
907
+ return;
908
+ case "Escape":
909
+ if (open) {
910
+ event.preventDefault();
911
+ event.stopPropagation();
912
+ this.closePanel();
913
+ }
914
+ return;
915
+ case "Tab":
916
+ if (open) this.closePanel(false);
917
+ return;
918
+ default: if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey && !(event.target instanceof HTMLInputElement)) this.runTypeahead(event.key);
919
+ }
920
+ }
921
+ chooseActive(thenClose = false) {
922
+ const option = this.visibleOptions()[this.activeIndex()];
923
+ if (option === void 0 || this.isDisabled(option)) return;
924
+ this.choose(option);
925
+ if (thenClose) this.closePanel();
926
+ }
927
+ moveActive(step) {
928
+ const count = this.visibleOptions().length;
929
+ if (!count) return;
930
+ const start = this.activeIndex() < 0 ? step === 1 ? 0 : count - 1 : this.activeIndex() + step;
931
+ const next = this.firstEnabledFrom(Math.min(Math.max(start, 0), count - 1), step);
932
+ if (next >= 0) this.activeIndex.set(next);
933
+ this.scrollActiveIntoView();
934
+ }
935
+ movePage(step) {
936
+ const count = this.visibleOptions().length;
937
+ const height = this.listElement()?.clientHeight || VIRTUAL_FALLBACK_HEIGHT;
938
+ const target = starListKeyboardTarget(step === 1 ? "PageDown" : "PageUp", this.activeIndex(), count, starListPageSize(height, this.virtualItemSize()));
939
+ const next = this.firstEnabledFrom(target, step);
940
+ const found = next >= 0 ? next : this.firstEnabledFrom(target, step === 1 ? -1 : 1);
941
+ if (found >= 0) this.activeIndex.set(found);
942
+ this.scrollActiveIntoView();
943
+ }
944
+ firstEnabledFrom(start, step) {
945
+ const options = this.visibleOptions();
946
+ for (let i = start; i >= 0 && i < options.length; i += step) if (!this.isDisabled(options[i])) return i;
947
+ return -1;
948
+ }
949
+ runTypeahead(char) {
950
+ clearTimeout(this.typeaheadTimer);
951
+ this.typeahead += char.toLocaleLowerCase();
952
+ this.typeaheadTimer = setTimeout(() => this.typeahead = "", 500);
953
+ const options = this.visibleOptions();
954
+ const start = Math.max(this.activeIndex(), 0);
955
+ const match = [...options.keys()].map((i) => (start + (this.typeahead.length === 1 ? 1 : 0) + i) % options.length).find((i) => !this.isDisabled(options[i]) && this.labelOf(options[i]).toLocaleLowerCase().startsWith(this.typeahead));
956
+ if (match === void 0) return;
957
+ this.activeIndex.set(match);
958
+ if (!this.open() && this.closeOnChoose) this.choose(options[match]);
959
+ this.scrollActiveIntoView();
960
+ }
961
+ listElement() {
962
+ return this.document.getElementById(this.listId);
963
+ }
964
+ applyScroll(list, offset, frames) {
965
+ if (!list.isConnected || this.listScrollTop() !== offset) return;
966
+ list.scrollTop = offset;
967
+ if (frames > 0 && Math.abs(list.scrollTop - offset) > 1) this.document.defaultView?.requestAnimationFrame?.(() => this.applyScroll(list, offset, frames - 1));
968
+ }
969
+ scrollActiveIntoView() {
970
+ if (!this.open() || this.activeIndex() < 0) return;
971
+ if (this.virtualScroll()) {
972
+ const list = this.listElement();
973
+ const layout = this.layout();
974
+ if (!list || layout.rowOfOption[this.activeIndex()] === void 0) return;
975
+ const height = list.clientHeight || VIRTUAL_FALLBACK_HEIGHT;
976
+ const inset = parseFloat(getComputedStyle(list).paddingTop) || 0;
977
+ const [first, last] = starListRevealRows(layout, this.activeIndex());
978
+ const offset = starListRevealOffset(first, last, Math.max(1, this.virtualItemSize()), list.clientHeight ? list.scrollTop : this.listScrollTop(), height, inset);
979
+ this.listHeight.set(height);
980
+ if (offset === null) return;
981
+ this.listScrollTop.set(offset);
982
+ queueMicrotask(() => this.applyScroll(list, offset, 12));
983
+ return;
984
+ }
985
+ const id = this.activeId();
986
+ if (!id) return;
987
+ queueMicrotask(() => this.document.getElementById(id)?.scrollIntoView?.({ block: "nearest" }));
988
+ }
989
+ static ɵfac = i0.ɵɵngDeclareFactory({
990
+ minVersion: "12.0.0",
991
+ version: "22.2.6",
992
+ ngImport: i0,
993
+ type: StarOptionListBase,
994
+ deps: [],
995
+ target: i0.ɵɵFactoryTarget.Directive
996
+ });
997
+ static ɵdir = i0.ɵɵngDeclareDirective({
998
+ minVersion: "17.2.0",
999
+ version: "22.2.6",
1000
+ type: StarOptionListBase,
1001
+ isStandalone: true,
1002
+ inputs: {
1003
+ options: {
1004
+ classPropertyName: "options",
1005
+ publicName: "options",
1006
+ isSignal: true,
1007
+ isRequired: false,
1008
+ transformFunction: null
1009
+ },
1010
+ optionLabel: {
1011
+ classPropertyName: "optionLabel",
1012
+ publicName: "optionLabel",
1013
+ isSignal: true,
1014
+ isRequired: false,
1015
+ transformFunction: null
1016
+ },
1017
+ optionValue: {
1018
+ classPropertyName: "optionValue",
1019
+ publicName: "optionValue",
1020
+ isSignal: true,
1021
+ isRequired: false,
1022
+ transformFunction: null
1023
+ },
1024
+ optionDisabled: {
1025
+ classPropertyName: "optionDisabled",
1026
+ publicName: "optionDisabled",
1027
+ isSignal: true,
1028
+ isRequired: false,
1029
+ transformFunction: null
1030
+ },
1031
+ compareWith: {
1032
+ classPropertyName: "compareWith",
1033
+ publicName: "compareWith",
1034
+ isSignal: true,
1035
+ isRequired: false,
1036
+ transformFunction: null
1037
+ },
1038
+ optionGroup: {
1039
+ classPropertyName: "optionGroup",
1040
+ publicName: "optionGroup",
1041
+ isSignal: true,
1042
+ isRequired: false,
1043
+ transformFunction: null
1044
+ },
1045
+ virtualScroll: {
1046
+ classPropertyName: "virtualScroll",
1047
+ publicName: "virtualScroll",
1048
+ isSignal: true,
1049
+ isRequired: false,
1050
+ transformFunction: null
1051
+ },
1052
+ virtualItemSize: {
1053
+ classPropertyName: "virtualItemSize",
1054
+ publicName: "virtualItemSize",
1055
+ isSignal: true,
1056
+ isRequired: false,
1057
+ transformFunction: null
1058
+ },
1059
+ placeholder: {
1060
+ classPropertyName: "placeholder",
1061
+ publicName: "placeholder",
1062
+ isSignal: true,
1063
+ isRequired: false,
1064
+ transformFunction: null
1065
+ },
1066
+ filter: {
1067
+ classPropertyName: "filter",
1068
+ publicName: "filter",
1069
+ isSignal: true,
1070
+ isRequired: false,
1071
+ transformFunction: null
1072
+ },
1073
+ filterPlaceholder: {
1074
+ classPropertyName: "filterPlaceholder",
1075
+ publicName: "filterPlaceholder",
1076
+ isSignal: true,
1077
+ isRequired: false,
1078
+ transformFunction: null
1079
+ },
1080
+ showClear: {
1081
+ classPropertyName: "showClear",
1082
+ publicName: "showClear",
1083
+ isSignal: true,
1084
+ isRequired: false,
1085
+ transformFunction: null
1086
+ },
1087
+ loading: {
1088
+ classPropertyName: "loading",
1089
+ publicName: "loading",
1090
+ isSignal: true,
1091
+ isRequired: false,
1092
+ transformFunction: null
1093
+ },
1094
+ emptyMessage: {
1095
+ classPropertyName: "emptyMessage",
1096
+ publicName: "emptyMessage",
1097
+ isSignal: true,
1098
+ isRequired: false,
1099
+ transformFunction: null
1100
+ },
1101
+ scrollHeight: {
1102
+ classPropertyName: "scrollHeight",
1103
+ publicName: "scrollHeight",
1104
+ isSignal: true,
1105
+ isRequired: false,
1106
+ transformFunction: null
1107
+ },
1108
+ size: {
1109
+ classPropertyName: "size",
1110
+ publicName: "size",
1111
+ isSignal: true,
1112
+ isRequired: false,
1113
+ transformFunction: null
1114
+ },
1115
+ ariaLabel: {
1116
+ classPropertyName: "ariaLabel",
1117
+ publicName: "ariaLabel",
1118
+ isSignal: true,
1119
+ isRequired: false,
1120
+ transformFunction: null
1121
+ },
1122
+ ariaLabelledBy: {
1123
+ classPropertyName: "ariaLabelledBy",
1124
+ publicName: "ariaLabelledBy",
1125
+ isSignal: true,
1126
+ isRequired: false,
1127
+ transformFunction: null
1128
+ },
1129
+ inputId: {
1130
+ classPropertyName: "inputId",
1131
+ publicName: "inputId",
1132
+ isSignal: true,
1133
+ isRequired: false,
1134
+ transformFunction: null
1135
+ },
1136
+ disabled: {
1137
+ classPropertyName: "disabled",
1138
+ publicName: "disabled",
1139
+ isSignal: true,
1140
+ isRequired: false,
1141
+ transformFunction: null
1142
+ },
1143
+ readonly: {
1144
+ classPropertyName: "readonly",
1145
+ publicName: "readonly",
1146
+ isSignal: true,
1147
+ isRequired: false,
1148
+ transformFunction: null
1149
+ },
1150
+ required: {
1151
+ classPropertyName: "required",
1152
+ publicName: "required",
1153
+ isSignal: true,
1154
+ isRequired: false,
1155
+ transformFunction: null
1156
+ },
1157
+ invalid: {
1158
+ classPropertyName: "invalid",
1159
+ publicName: "invalid",
1160
+ isSignal: true,
1161
+ isRequired: false,
1162
+ transformFunction: null
1163
+ },
1164
+ touched: {
1165
+ classPropertyName: "touched",
1166
+ publicName: "touched",
1167
+ isSignal: true,
1168
+ isRequired: false,
1169
+ transformFunction: null
1170
+ },
1171
+ name: {
1172
+ classPropertyName: "name",
1173
+ publicName: "name",
1174
+ isSignal: true,
1175
+ isRequired: false,
1176
+ transformFunction: null
1177
+ }
1178
+ },
1179
+ outputs: {
1180
+ touch: "touch",
1181
+ opened: "opened",
1182
+ closed: "closed",
1183
+ filterChange: "filterChange"
1184
+ },
1185
+ queries: [{
1186
+ propertyName: "optionTemplate",
1187
+ first: true,
1188
+ predicate: StarOptionTemplate,
1189
+ descendants: true,
1190
+ isSignal: true
1191
+ }],
1192
+ viewQueries: [{
1193
+ propertyName: "trigger",
1194
+ first: true,
1195
+ predicate: ["trigger"],
1196
+ descendants: true,
1197
+ isSignal: true
1198
+ }, {
1199
+ propertyName: "filterInput",
1200
+ first: true,
1201
+ predicate: ["filterInput"],
1202
+ descendants: true,
1203
+ isSignal: true
1204
+ }],
1205
+ ngImport: i0
1206
+ });
1207
+ };
1208
+ i0.ɵɵngDeclareClassMetadata({
1209
+ minVersion: "12.0.0",
1210
+ version: "22.2.6",
1211
+ ngImport: i0,
1212
+ type: StarOptionListBase,
1213
+ decorators: [{ type: Directive }],
1214
+ ctorParameters: () => [],
1215
+ propDecorators: {
1216
+ options: [{
1217
+ type: i0.Input,
1218
+ args: [{
1219
+ isSignal: true,
1220
+ alias: "options",
1221
+ required: false
1222
+ }]
1223
+ }],
1224
+ optionLabel: [{
1225
+ type: i0.Input,
1226
+ args: [{
1227
+ isSignal: true,
1228
+ alias: "optionLabel",
1229
+ required: false
1230
+ }]
1231
+ }],
1232
+ optionValue: [{
1233
+ type: i0.Input,
1234
+ args: [{
1235
+ isSignal: true,
1236
+ alias: "optionValue",
1237
+ required: false
1238
+ }]
1239
+ }],
1240
+ optionDisabled: [{
1241
+ type: i0.Input,
1242
+ args: [{
1243
+ isSignal: true,
1244
+ alias: "optionDisabled",
1245
+ required: false
1246
+ }]
1247
+ }],
1248
+ compareWith: [{
1249
+ type: i0.Input,
1250
+ args: [{
1251
+ isSignal: true,
1252
+ alias: "compareWith",
1253
+ required: false
1254
+ }]
1255
+ }],
1256
+ optionGroup: [{
1257
+ type: i0.Input,
1258
+ args: [{
1259
+ isSignal: true,
1260
+ alias: "optionGroup",
1261
+ required: false
1262
+ }]
1263
+ }],
1264
+ virtualScroll: [{
1265
+ type: i0.Input,
1266
+ args: [{
1267
+ isSignal: true,
1268
+ alias: "virtualScroll",
1269
+ required: false
1270
+ }]
1271
+ }],
1272
+ virtualItemSize: [{
1273
+ type: i0.Input,
1274
+ args: [{
1275
+ isSignal: true,
1276
+ alias: "virtualItemSize",
1277
+ required: false
1278
+ }]
1279
+ }],
1280
+ placeholder: [{
1281
+ type: i0.Input,
1282
+ args: [{
1283
+ isSignal: true,
1284
+ alias: "placeholder",
1285
+ required: false
1286
+ }]
1287
+ }],
1288
+ filter: [{
1289
+ type: i0.Input,
1290
+ args: [{
1291
+ isSignal: true,
1292
+ alias: "filter",
1293
+ required: false
1294
+ }]
1295
+ }],
1296
+ filterPlaceholder: [{
1297
+ type: i0.Input,
1298
+ args: [{
1299
+ isSignal: true,
1300
+ alias: "filterPlaceholder",
1301
+ required: false
1302
+ }]
1303
+ }],
1304
+ showClear: [{
1305
+ type: i0.Input,
1306
+ args: [{
1307
+ isSignal: true,
1308
+ alias: "showClear",
1309
+ required: false
1310
+ }]
1311
+ }],
1312
+ loading: [{
1313
+ type: i0.Input,
1314
+ args: [{
1315
+ isSignal: true,
1316
+ alias: "loading",
1317
+ required: false
1318
+ }]
1319
+ }],
1320
+ emptyMessage: [{
1321
+ type: i0.Input,
1322
+ args: [{
1323
+ isSignal: true,
1324
+ alias: "emptyMessage",
1325
+ required: false
1326
+ }]
1327
+ }],
1328
+ scrollHeight: [{
1329
+ type: i0.Input,
1330
+ args: [{
1331
+ isSignal: true,
1332
+ alias: "scrollHeight",
1333
+ required: false
1334
+ }]
1335
+ }],
1336
+ size: [{
1337
+ type: i0.Input,
1338
+ args: [{
1339
+ isSignal: true,
1340
+ alias: "size",
1341
+ required: false
1342
+ }]
1343
+ }],
1344
+ ariaLabel: [{
1345
+ type: i0.Input,
1346
+ args: [{
1347
+ isSignal: true,
1348
+ alias: "ariaLabel",
1349
+ required: false
1350
+ }]
1351
+ }],
1352
+ ariaLabelledBy: [{
1353
+ type: i0.Input,
1354
+ args: [{
1355
+ isSignal: true,
1356
+ alias: "ariaLabelledBy",
1357
+ required: false
1358
+ }]
1359
+ }],
1360
+ inputId: [{
1361
+ type: i0.Input,
1362
+ args: [{
1363
+ isSignal: true,
1364
+ alias: "inputId",
1365
+ required: false
1366
+ }]
1367
+ }],
1368
+ disabled: [{
1369
+ type: i0.Input,
1370
+ args: [{
1371
+ isSignal: true,
1372
+ alias: "disabled",
1373
+ required: false
1374
+ }]
1375
+ }],
1376
+ readonly: [{
1377
+ type: i0.Input,
1378
+ args: [{
1379
+ isSignal: true,
1380
+ alias: "readonly",
1381
+ required: false
1382
+ }]
1383
+ }],
1384
+ required: [{
1385
+ type: i0.Input,
1386
+ args: [{
1387
+ isSignal: true,
1388
+ alias: "required",
1389
+ required: false
1390
+ }]
1391
+ }],
1392
+ invalid: [{
1393
+ type: i0.Input,
1394
+ args: [{
1395
+ isSignal: true,
1396
+ alias: "invalid",
1397
+ required: false
1398
+ }]
1399
+ }],
1400
+ touched: [{
1401
+ type: i0.Input,
1402
+ args: [{
1403
+ isSignal: true,
1404
+ alias: "touched",
1405
+ required: false
1406
+ }]
1407
+ }],
1408
+ name: [{
1409
+ type: i0.Input,
1410
+ args: [{
1411
+ isSignal: true,
1412
+ alias: "name",
1413
+ required: false
1414
+ }]
1415
+ }],
1416
+ touch: [{
1417
+ type: i0.Output,
1418
+ args: ["touch"]
1419
+ }],
1420
+ opened: [{
1421
+ type: i0.Output,
1422
+ args: ["opened"]
1423
+ }],
1424
+ closed: [{
1425
+ type: i0.Output,
1426
+ args: ["closed"]
1427
+ }],
1428
+ filterChange: [{
1429
+ type: i0.Output,
1430
+ args: ["filterChange"]
1431
+ }],
1432
+ optionTemplate: [{
1433
+ type: i0.ContentChild,
1434
+ args: [i0.forwardRef(() => StarOptionTemplate), { isSignal: true }]
1435
+ }],
1436
+ trigger: [{
1437
+ type: i0.ViewChild,
1438
+ args: ["trigger", { isSignal: true }]
1439
+ }],
1440
+ filterInput: [{
1441
+ type: i0.ViewChild,
1442
+ args: ["filterInput", { isSignal: true }]
1443
+ }]
1444
+ }
1445
+ });
1446
+ var StarMultiSelect = class StarMultiSelect extends StarOptionListBase {
1447
+ value = model([], ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
1448
+ display = input("comma", ...ngDevMode ? [{ debugName: "display" }] : /* istanbul ignore next */ []);
1449
+ maxSelectedLabels = input(3, ...ngDevMode ? [{ debugName: "maxSelectedLabels" }] : /* istanbul ignore next */ []);
1450
+ selectionLimit = input(0, ...ngDevMode ? [{ debugName: "selectionLimit" }] : /* istanbul ignore next */ []);
1451
+ showToggleAll = input(true, ...ngDevMode ? [{ debugName: "showToggleAll" }] : /* istanbul ignore next */ []);
1452
+ closeOnChoose = false;
1453
+ selectedOptions = computed(() => this.options().filter((option) => this.isSelected(option)), ...ngDevMode ? [{ debugName: "selectedOptions" }] : /* istanbul ignore next */ []);
1454
+ collapsed = computed(() => this.selectedOptions().length > this.maxSelectedLabels(), ...ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []);
1455
+ selectedLabels = computed(() => this.selectedOptions().map((option) => this.labelOf(option)).join(", "), ...ngDevMode ? [{ debugName: "selectedLabels" }] : /* istanbul ignore next */ []);
1456
+ selectableVisible = computed(() => this.visibleOptions().filter((option) => !this.isDisabled(option)), ...ngDevMode ? [{ debugName: "selectableVisible" }] : /* istanbul ignore next */ []);
1457
+ allState = computed(() => {
1458
+ const options = this.selectableVisible();
1459
+ const selected = options.filter((option) => this.isSelected(option)).length;
1460
+ if (!options.length || selected === 0) return false;
1461
+ return selected === options.length ? true : "mixed";
1462
+ }, ...ngDevMode ? [{ debugName: "allState" }] : /* istanbul ignore next */ []);
1463
+ chosenSet = computed(() => this.compareWith() === Object.is ? new Set(this.value()) : null, ...ngDevMode ? [{ debugName: "chosenSet" }] : /* istanbul ignore next */ []);
1464
+ isSelected(option) {
1465
+ const optionValue = this.valueOf(option);
1466
+ const chosen = this.chosenSet();
1467
+ return chosen ? chosen.has(optionValue) : this.value().some((value) => this.equals(value, optionValue));
1468
+ }
1469
+ choose(option) {
1470
+ if (this.isSelected(option)) {
1471
+ this.remove(option);
1472
+ return;
1473
+ }
1474
+ const limit = this.selectionLimit();
1475
+ if (limit > 0 && this.value().length >= limit) return;
1476
+ this.value.update((values) => [...values, this.valueOf(option)]);
1477
+ }
1478
+ initialActiveIndex() {
1479
+ return this.firstEnabledFrom(0, 1);
1480
+ }
1481
+ remove(option) {
1482
+ const optionValue = this.valueOf(option);
1483
+ this.value.update((values) => values.filter((value) => !this.equals(value, optionValue)));
1484
+ }
1485
+ toggleAll() {
1486
+ const options = this.selectableVisible();
1487
+ if (this.allState() === true) {
1488
+ const visibleValues = options.map((option) => this.valueOf(option));
1489
+ const visibleSet = this.compareWith() === Object.is ? new Set(visibleValues) : null;
1490
+ this.value.update((values) => values.filter((value) => visibleSet ? !visibleSet.has(value) : !visibleValues.some((visible) => this.equals(visible, value))));
1491
+ return;
1492
+ }
1493
+ const additions = options.filter((option) => !this.isSelected(option)).map((option) => this.valueOf(option));
1494
+ this.value.update((values) => [...values, ...additions]);
1495
+ }
1496
+ clear() {
1497
+ this.value.set([]);
1498
+ this.focus();
1499
+ }
1500
+ static ɵfac = i0.ɵɵngDeclareFactory({
1501
+ minVersion: "12.0.0",
1502
+ version: "22.2.6",
1503
+ ngImport: i0,
1504
+ type: StarMultiSelect,
1505
+ deps: null,
1506
+ target: i0.ɵɵFactoryTarget.Component
1507
+ });
1508
+ static ɵcmp = i0.ɵɵngDeclareComponent({
1509
+ minVersion: "17.0.0",
1510
+ version: "22.2.6",
1511
+ type: StarMultiSelect,
1512
+ isStandalone: true,
1513
+ selector: "star-multi-select",
1514
+ inputs: {
1515
+ value: {
1516
+ classPropertyName: "value",
1517
+ publicName: "value",
1518
+ isSignal: true,
1519
+ isRequired: false,
1520
+ transformFunction: null
1521
+ },
1522
+ display: {
1523
+ classPropertyName: "display",
1524
+ publicName: "display",
1525
+ isSignal: true,
1526
+ isRequired: false,
1527
+ transformFunction: null
1528
+ },
1529
+ maxSelectedLabels: {
1530
+ classPropertyName: "maxSelectedLabels",
1531
+ publicName: "maxSelectedLabels",
1532
+ isSignal: true,
1533
+ isRequired: false,
1534
+ transformFunction: null
1535
+ },
1536
+ selectionLimit: {
1537
+ classPropertyName: "selectionLimit",
1538
+ publicName: "selectionLimit",
1539
+ isSignal: true,
1540
+ isRequired: false,
1541
+ transformFunction: null
1542
+ },
1543
+ showToggleAll: {
1544
+ classPropertyName: "showToggleAll",
1545
+ publicName: "showToggleAll",
1546
+ isSignal: true,
1547
+ isRequired: false,
1548
+ transformFunction: null
1549
+ }
1550
+ },
1551
+ outputs: { value: "valueChange" },
1552
+ host: {
1553
+ properties: {
1554
+ "class.star-select--open": "open()",
1555
+ "class.star-select--disabled": "disabled()",
1556
+ "class.star-select--invalid": "showInvalid()",
1557
+ "class.star-select--sm": "size() === 'sm'"
1558
+ },
1559
+ classAttribute: "star-select star-select--multi"
1560
+ },
1561
+ usesInheritance: true,
1562
+ ngImport: i0,
1563
+ template: `
1564
+ <div class="star-select__control" cdkOverlayOrigin #origin="cdkOverlayOrigin">
1565
+ <div
1566
+ #trigger
1567
+ class="star-select__trigger"
1568
+ role="combobox"
1569
+ aria-haspopup="listbox"
1570
+ [id]="inputId()"
1571
+ [attr.tabindex]="disabled() ? -1 : 0"
1572
+ [attr.aria-expanded]="open()"
1573
+ [attr.aria-controls]="open() ? listId : null"
1574
+ [attr.aria-activedescendant]="activeId()"
1575
+ [attr.aria-label]="ariaLabel()"
1576
+ [attr.aria-labelledby]="ariaLabelledBy()"
1577
+ [attr.aria-required]="required() || null"
1578
+ [attr.aria-invalid]="showInvalid() || null"
1579
+ [attr.aria-disabled]="disabled() || null"
1580
+ [attr.aria-readonly]="readonly() || null"
1581
+ (click)="toggle()"
1582
+ (keydown)="onKeydown($event)"
1583
+ (blur)="onTriggerBlur()"
1584
+ >
1585
+ @if (selectedOptions().length === 0) {
1586
+ <span class="star-select__placeholder">{{
1587
+ placeholder() ?? text.selectPlaceholder
1588
+ }}</span>
1589
+ } @else if (collapsed()) {
1590
+ <span class="star-select__value">{{ text.selectedItems(selectedOptions().length) }}</span>
1591
+ } @else if (display() === 'chip') {
1592
+ <span class="star-select__chips">
1593
+ @for (option of selectedOptions(); track $index) {
1594
+ <span class="star-chip star-chip--sm">
1595
+ {{ labelOf(option) }}
1596
+ @if (interactive()) {
1597
+ <button
1598
+ type="button"
1599
+ class="star-chip__remove"
1600
+ tabindex="-1"
1601
+ [attr.aria-label]="text.removeItem(labelOf(option))"
1602
+ (click)="$event.stopPropagation(); remove(option)"
1603
+ >
1604
+ <i class="ph-bold ph-x" aria-hidden="true"></i>
1605
+ </button>
1606
+ }
1607
+ </span>
1608
+ }
1609
+ </span>
1610
+ } @else {
1611
+ <span class="star-select__value">{{ selectedLabels() }}</span>
1612
+ }
1613
+ </div>
1614
+ @if (showClear() && selectedOptions().length && interactive()) {
1615
+ <button
1616
+ type="button"
1617
+ class="star-select__icon-btn"
1618
+ [attr.aria-label]="text.clear"
1619
+ (click)="clear()"
1620
+ >
1621
+ <i class="ph-bold ph-x" aria-hidden="true"></i>
1622
+ </button>
1623
+ }
1624
+ @if (loading()) {
1625
+ <i
1626
+ class="ph-bold ph-spinner-gap star-spin star-select__caret"
1627
+ role="img"
1628
+ [attr.aria-label]="text.loading"
1629
+ ></i>
1630
+ } @else {
1631
+ <i class="ph-bold ph-caret-down star-select__caret" aria-hidden="true"></i>
1632
+ }
1633
+ </div>
1634
+
1635
+ <ng-template
1636
+ cdkConnectedOverlay
1637
+ cdkConnectedOverlayUsePopover="inline"
1638
+ cdkConnectedOverlayMatchWidth
1639
+ [cdkConnectedOverlayOrigin]="origin"
1640
+ [cdkConnectedOverlayOpen]="open()"
1641
+ [cdkConnectedOverlayPositions]="positions"
1642
+ (attach)="onPanelAttached()"
1643
+ (detach)="closePanel(false)"
1644
+ (overlayOutsideClick)="onOutsideClick($event)"
1645
+ >
1646
+ <div class="star-panel" (mousedown)="onPanelMousedown($event)">
1647
+ @if (showToggleAll() || filter()) {
1648
+ <div class="star-panel__filter">
1649
+ @if (showToggleAll() && !selectionLimit()) {
1650
+ <button
1651
+ type="button"
1652
+ class="star-panel__toggle-all"
1653
+ role="checkbox"
1654
+ tabindex="-1"
1655
+ [attr.aria-checked]="allState()"
1656
+ [attr.aria-label]="text.selectAll"
1657
+ (click)="toggleAll()"
1658
+ >
1659
+ <span class="star-check__box" aria-hidden="true">
1660
+ @if (allState() === 'mixed') {
1661
+ <i class="ph-bold ph-minus"></i>
1662
+ } @else if (allState() === true) {
1663
+ <i class="ph-bold ph-check"></i>
1664
+ }
1665
+ </span>
1666
+ </button>
1667
+ }
1668
+ @if (filter()) {
1669
+ <i class="ph-bold ph-magnifying-glass" aria-hidden="true"></i>
1670
+ <input
1671
+ #filterInput
1672
+ type="text"
1673
+ class="star-input star-input--sm"
1674
+ role="searchbox"
1675
+ autocomplete="off"
1676
+ [value]="filterValue()"
1677
+ [attr.placeholder]="filterPlaceholder() ?? text.filterPlaceholder"
1678
+ [attr.aria-label]="filterPlaceholder() ?? text.filterPlaceholder"
1679
+ [attr.aria-controls]="listId"
1680
+ [attr.aria-activedescendant]="activeId()"
1681
+ (input)="onFilterInput(filterInput.value)"
1682
+ (keydown)="onKeydown($event)"
1683
+ />
1684
+ } @else {
1685
+ <span class="star-panel__toggle-label">{{ text.selectAll }}</span>
1686
+ }
1687
+ </div>
1688
+ }
1689
+ <ul
1690
+ class="star-listbox"
1691
+ role="listbox"
1692
+ aria-multiselectable="true"
1693
+ [id]="listId"
1694
+ [class.star-listbox--virtual]="virtualScroll()"
1695
+ [style.--star-item-size.px]="virtualScroll() ? virtualItemSize() : null"
1696
+ [style.max-height]="scrollHeight()"
1697
+ [attr.aria-label]="ariaLabel()"
1698
+ [attr.aria-labelledby]="ariaLabelledBy()"
1699
+ (scroll)="onListScroll($event)"
1700
+ >
1701
+ @if (virtualWindow().before) {
1702
+ <li
1703
+ class="star-listbox__spacer"
1704
+ role="presentation"
1705
+ [style.height.px]="virtualWindow().before"
1706
+ ></li>
1707
+ }
1708
+ @for (row of renderedRows(); track row.key) {
1709
+ @if (row.kind === 'group') {
1710
+ <li class="star-listbox__group" role="presentation" [id]="row.id">{{ row.label }}</li>
1711
+ } @else {
1712
+ @let option = row.option;
1713
+ @let i = row.index;
1714
+ <!-- Keyboard is handled on the combobox via aria-activedescendant (WAI-ARIA combobox pattern). -->
1715
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
1716
+ <li
1717
+ class="star-listbox__option"
1718
+ role="option"
1719
+ [id]="optionId(i)"
1720
+ [class.star-listbox__option--active]="activeIndex() === i"
1721
+ [class.star-listbox__option--selected]="isSelected(option)"
1722
+ [attr.aria-selected]="isSelected(option)"
1723
+ [attr.aria-disabled]="isDisabled(option) || null"
1724
+ [attr.aria-describedby]="describedBy(row)"
1725
+ [attr.aria-setsize]="virtualScroll() ? visibleOptions().length : null"
1726
+ [attr.aria-posinset]="virtualScroll() ? i + 1 : null"
1727
+ (click)="onOptionClick(option, i)"
1728
+ (mousemove)="isDisabled(option) || activeIndex.set(i)"
1729
+ >
1730
+ <span class="star-check__box" aria-hidden="true">
1731
+ @if (isSelected(option)) {
1732
+ <i class="ph-bold ph-check"></i>
1733
+ }
1734
+ </span>
1735
+ <span class="star-listbox__label">
1736
+ @if (optionTemplate(); as custom) {
1737
+ <ng-container
1738
+ *ngTemplateOutlet="custom.template; context: optionContext(option, i)"
1739
+ />
1740
+ } @else {
1741
+ {{ labelOf(option) }}
1742
+ }
1743
+ </span>
1744
+ </li>
1745
+ }
1746
+ } @empty {
1747
+ <li class="star-listbox__empty" role="presentation">{{ emptyText() }}</li>
1748
+ }
1749
+ @if (virtualWindow().after) {
1750
+ <li
1751
+ class="star-listbox__spacer"
1752
+ role="presentation"
1753
+ [style.height.px]="virtualWindow().after"
1754
+ ></li>
1755
+ }
1756
+ </ul>
1757
+ </div>
1758
+ </ng-template>
1759
+ `,
1760
+ isInline: true,
1761
+ dependencies: [
1762
+ {
1763
+ kind: "directive",
1764
+ type: CdkConnectedOverlay,
1765
+ selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]",
1766
+ inputs: [
1767
+ "cdkConnectedOverlayOrigin",
1768
+ "cdkConnectedOverlayPositions",
1769
+ "cdkConnectedOverlayPositionStrategy",
1770
+ "cdkConnectedOverlayOffsetX",
1771
+ "cdkConnectedOverlayOffsetY",
1772
+ "cdkConnectedOverlayWidth",
1773
+ "cdkConnectedOverlayHeight",
1774
+ "cdkConnectedOverlayMinWidth",
1775
+ "cdkConnectedOverlayMinHeight",
1776
+ "cdkConnectedOverlayBackdropClass",
1777
+ "cdkConnectedOverlayPanelClass",
1778
+ "cdkConnectedOverlayViewportMargin",
1779
+ "cdkConnectedOverlayScrollStrategy",
1780
+ "cdkConnectedOverlayOpen",
1781
+ "cdkConnectedOverlayDisableClose",
1782
+ "cdkConnectedOverlayTransformOriginOn",
1783
+ "cdkConnectedOverlayHasBackdrop",
1784
+ "cdkConnectedOverlayLockPosition",
1785
+ "cdkConnectedOverlayFlexibleDimensions",
1786
+ "cdkConnectedOverlayGrowAfterOpen",
1787
+ "cdkConnectedOverlayPush",
1788
+ "cdkConnectedOverlayDisposeOnNavigation",
1789
+ "cdkConnectedOverlayUsePopover",
1790
+ "cdkConnectedOverlayMatchWidth",
1791
+ "cdkConnectedOverlay"
1792
+ ],
1793
+ outputs: [
1794
+ "backdropClick",
1795
+ "positionChange",
1796
+ "attach",
1797
+ "detach",
1798
+ "overlayKeydown",
1799
+ "overlayOutsideClick"
1800
+ ],
1801
+ exportAs: ["cdkConnectedOverlay"]
1802
+ },
1803
+ {
1804
+ kind: "directive",
1805
+ type: CdkOverlayOrigin,
1806
+ selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]",
1807
+ exportAs: ["cdkOverlayOrigin"]
1808
+ },
1809
+ {
1810
+ kind: "directive",
1811
+ type: NgTemplateOutlet,
1812
+ selector: "[ngTemplateOutlet]",
1813
+ inputs: [
1814
+ "ngTemplateOutletContext",
1815
+ "ngTemplateOutlet",
1816
+ "ngTemplateOutletInjector"
1817
+ ]
1818
+ }
1819
+ ],
1820
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
1821
+ });
1822
+ };
1823
+ i0.ɵɵngDeclareClassMetadata({
1824
+ minVersion: "12.0.0",
1825
+ version: "22.2.6",
1826
+ ngImport: i0,
1827
+ type: StarMultiSelect,
1828
+ decorators: [{
1829
+ type: Component,
1830
+ args: [{
1831
+ selector: "star-multi-select",
1832
+ imports: [
1833
+ CdkConnectedOverlay,
1834
+ CdkOverlayOrigin,
1835
+ NgTemplateOutlet
1836
+ ],
1837
+ changeDetection: ChangeDetectionStrategy.OnPush,
1838
+ host: {
1839
+ class: "star-select star-select--multi",
1840
+ "[class.star-select--open]": "open()",
1841
+ "[class.star-select--disabled]": "disabled()",
1842
+ "[class.star-select--invalid]": "showInvalid()",
1843
+ "[class.star-select--sm]": "size() === 'sm'"
1844
+ },
1845
+ template: `
1846
+ <div class="star-select__control" cdkOverlayOrigin #origin="cdkOverlayOrigin">
1847
+ <div
1848
+ #trigger
1849
+ class="star-select__trigger"
1850
+ role="combobox"
1851
+ aria-haspopup="listbox"
1852
+ [id]="inputId()"
1853
+ [attr.tabindex]="disabled() ? -1 : 0"
1854
+ [attr.aria-expanded]="open()"
1855
+ [attr.aria-controls]="open() ? listId : null"
1856
+ [attr.aria-activedescendant]="activeId()"
1857
+ [attr.aria-label]="ariaLabel()"
1858
+ [attr.aria-labelledby]="ariaLabelledBy()"
1859
+ [attr.aria-required]="required() || null"
1860
+ [attr.aria-invalid]="showInvalid() || null"
1861
+ [attr.aria-disabled]="disabled() || null"
1862
+ [attr.aria-readonly]="readonly() || null"
1863
+ (click)="toggle()"
1864
+ (keydown)="onKeydown($event)"
1865
+ (blur)="onTriggerBlur()"
1866
+ >
1867
+ @if (selectedOptions().length === 0) {
1868
+ <span class="star-select__placeholder">{{
1869
+ placeholder() ?? text.selectPlaceholder
1870
+ }}</span>
1871
+ } @else if (collapsed()) {
1872
+ <span class="star-select__value">{{ text.selectedItems(selectedOptions().length) }}</span>
1873
+ } @else if (display() === 'chip') {
1874
+ <span class="star-select__chips">
1875
+ @for (option of selectedOptions(); track $index) {
1876
+ <span class="star-chip star-chip--sm">
1877
+ {{ labelOf(option) }}
1878
+ @if (interactive()) {
1879
+ <button
1880
+ type="button"
1881
+ class="star-chip__remove"
1882
+ tabindex="-1"
1883
+ [attr.aria-label]="text.removeItem(labelOf(option))"
1884
+ (click)="$event.stopPropagation(); remove(option)"
1885
+ >
1886
+ <i class="ph-bold ph-x" aria-hidden="true"></i>
1887
+ </button>
1888
+ }
1889
+ </span>
1890
+ }
1891
+ </span>
1892
+ } @else {
1893
+ <span class="star-select__value">{{ selectedLabels() }}</span>
1894
+ }
1895
+ </div>
1896
+ @if (showClear() && selectedOptions().length && interactive()) {
1897
+ <button
1898
+ type="button"
1899
+ class="star-select__icon-btn"
1900
+ [attr.aria-label]="text.clear"
1901
+ (click)="clear()"
1902
+ >
1903
+ <i class="ph-bold ph-x" aria-hidden="true"></i>
1904
+ </button>
1905
+ }
1906
+ @if (loading()) {
1907
+ <i
1908
+ class="ph-bold ph-spinner-gap star-spin star-select__caret"
1909
+ role="img"
1910
+ [attr.aria-label]="text.loading"
1911
+ ></i>
1912
+ } @else {
1913
+ <i class="ph-bold ph-caret-down star-select__caret" aria-hidden="true"></i>
1914
+ }
1915
+ </div>
1916
+
1917
+ <ng-template
1918
+ cdkConnectedOverlay
1919
+ cdkConnectedOverlayUsePopover="inline"
1920
+ cdkConnectedOverlayMatchWidth
1921
+ [cdkConnectedOverlayOrigin]="origin"
1922
+ [cdkConnectedOverlayOpen]="open()"
1923
+ [cdkConnectedOverlayPositions]="positions"
1924
+ (attach)="onPanelAttached()"
1925
+ (detach)="closePanel(false)"
1926
+ (overlayOutsideClick)="onOutsideClick($event)"
1927
+ >
1928
+ <div class="star-panel" (mousedown)="onPanelMousedown($event)">
1929
+ @if (showToggleAll() || filter()) {
1930
+ <div class="star-panel__filter">
1931
+ @if (showToggleAll() && !selectionLimit()) {
1932
+ <button
1933
+ type="button"
1934
+ class="star-panel__toggle-all"
1935
+ role="checkbox"
1936
+ tabindex="-1"
1937
+ [attr.aria-checked]="allState()"
1938
+ [attr.aria-label]="text.selectAll"
1939
+ (click)="toggleAll()"
1940
+ >
1941
+ <span class="star-check__box" aria-hidden="true">
1942
+ @if (allState() === 'mixed') {
1943
+ <i class="ph-bold ph-minus"></i>
1944
+ } @else if (allState() === true) {
1945
+ <i class="ph-bold ph-check"></i>
1946
+ }
1947
+ </span>
1948
+ </button>
1949
+ }
1950
+ @if (filter()) {
1951
+ <i class="ph-bold ph-magnifying-glass" aria-hidden="true"></i>
1952
+ <input
1953
+ #filterInput
1954
+ type="text"
1955
+ class="star-input star-input--sm"
1956
+ role="searchbox"
1957
+ autocomplete="off"
1958
+ [value]="filterValue()"
1959
+ [attr.placeholder]="filterPlaceholder() ?? text.filterPlaceholder"
1960
+ [attr.aria-label]="filterPlaceholder() ?? text.filterPlaceholder"
1961
+ [attr.aria-controls]="listId"
1962
+ [attr.aria-activedescendant]="activeId()"
1963
+ (input)="onFilterInput(filterInput.value)"
1964
+ (keydown)="onKeydown($event)"
1965
+ />
1966
+ } @else {
1967
+ <span class="star-panel__toggle-label">{{ text.selectAll }}</span>
1968
+ }
1969
+ </div>
1970
+ }
1971
+ <ul
1972
+ class="star-listbox"
1973
+ role="listbox"
1974
+ aria-multiselectable="true"
1975
+ [id]="listId"
1976
+ [class.star-listbox--virtual]="virtualScroll()"
1977
+ [style.--star-item-size.px]="virtualScroll() ? virtualItemSize() : null"
1978
+ [style.max-height]="scrollHeight()"
1979
+ [attr.aria-label]="ariaLabel()"
1980
+ [attr.aria-labelledby]="ariaLabelledBy()"
1981
+ (scroll)="onListScroll($event)"
1982
+ >
1983
+ @if (virtualWindow().before) {
1984
+ <li
1985
+ class="star-listbox__spacer"
1986
+ role="presentation"
1987
+ [style.height.px]="virtualWindow().before"
1988
+ ></li>
1989
+ }
1990
+ @for (row of renderedRows(); track row.key) {
1991
+ @if (row.kind === 'group') {
1992
+ <li class="star-listbox__group" role="presentation" [id]="row.id">{{ row.label }}</li>
1993
+ } @else {
1994
+ @let option = row.option;
1995
+ @let i = row.index;
1996
+ <!-- Keyboard is handled on the combobox via aria-activedescendant (WAI-ARIA combobox pattern). -->
1997
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
1998
+ <li
1999
+ class="star-listbox__option"
2000
+ role="option"
2001
+ [id]="optionId(i)"
2002
+ [class.star-listbox__option--active]="activeIndex() === i"
2003
+ [class.star-listbox__option--selected]="isSelected(option)"
2004
+ [attr.aria-selected]="isSelected(option)"
2005
+ [attr.aria-disabled]="isDisabled(option) || null"
2006
+ [attr.aria-describedby]="describedBy(row)"
2007
+ [attr.aria-setsize]="virtualScroll() ? visibleOptions().length : null"
2008
+ [attr.aria-posinset]="virtualScroll() ? i + 1 : null"
2009
+ (click)="onOptionClick(option, i)"
2010
+ (mousemove)="isDisabled(option) || activeIndex.set(i)"
2011
+ >
2012
+ <span class="star-check__box" aria-hidden="true">
2013
+ @if (isSelected(option)) {
2014
+ <i class="ph-bold ph-check"></i>
2015
+ }
2016
+ </span>
2017
+ <span class="star-listbox__label">
2018
+ @if (optionTemplate(); as custom) {
2019
+ <ng-container
2020
+ *ngTemplateOutlet="custom.template; context: optionContext(option, i)"
2021
+ />
2022
+ } @else {
2023
+ {{ labelOf(option) }}
2024
+ }
2025
+ </span>
2026
+ </li>
2027
+ }
2028
+ } @empty {
2029
+ <li class="star-listbox__empty" role="presentation">{{ emptyText() }}</li>
2030
+ }
2031
+ @if (virtualWindow().after) {
2032
+ <li
2033
+ class="star-listbox__spacer"
2034
+ role="presentation"
2035
+ [style.height.px]="virtualWindow().after"
2036
+ ></li>
2037
+ }
2038
+ </ul>
2039
+ </div>
2040
+ </ng-template>
2041
+ `
2042
+ }]
2043
+ }],
2044
+ propDecorators: {
2045
+ value: [{
2046
+ type: i0.Input,
2047
+ args: [{
2048
+ isSignal: true,
2049
+ alias: "value",
2050
+ required: false
2051
+ }]
2052
+ }, {
2053
+ type: i0.Output,
2054
+ args: ["valueChange"]
2055
+ }],
2056
+ display: [{
2057
+ type: i0.Input,
2058
+ args: [{
2059
+ isSignal: true,
2060
+ alias: "display",
2061
+ required: false
2062
+ }]
2063
+ }],
2064
+ maxSelectedLabels: [{
2065
+ type: i0.Input,
2066
+ args: [{
2067
+ isSignal: true,
2068
+ alias: "maxSelectedLabels",
2069
+ required: false
2070
+ }]
2071
+ }],
2072
+ selectionLimit: [{
2073
+ type: i0.Input,
2074
+ args: [{
2075
+ isSignal: true,
2076
+ alias: "selectionLimit",
2077
+ required: false
2078
+ }]
2079
+ }],
2080
+ showToggleAll: [{
2081
+ type: i0.Input,
2082
+ args: [{
2083
+ isSignal: true,
2084
+ alias: "showToggleAll",
2085
+ required: false
2086
+ }]
2087
+ }]
2088
+ }
2089
+ });
2090
+ var StarSelect = class StarSelect extends StarOptionListBase {
2091
+ value = model(null, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
2092
+ closeOnChoose = true;
2093
+ selectedOption = computed(() => {
2094
+ const value = this.value();
2095
+ if (value === null) return void 0;
2096
+ return this.options().find((option) => this.equals(this.valueOf(option), value));
2097
+ }, ...ngDevMode ? [{ debugName: "selectedOption" }] : /* istanbul ignore next */ []);
2098
+ isSelected(option) {
2099
+ const value = this.value();
2100
+ return value !== null && this.equals(this.valueOf(option), value);
2101
+ }
2102
+ choose(option) {
2103
+ this.value.set(this.valueOf(option));
2104
+ }
2105
+ initialActiveIndex() {
2106
+ const index = this.visibleOptions().findIndex((option) => this.isSelected(option));
2107
+ return index >= 0 ? index : this.firstEnabledFrom(0, 1);
2108
+ }
2109
+ clear() {
2110
+ this.value.set(null);
2111
+ this.focus();
2112
+ }
2113
+ static ɵfac = i0.ɵɵngDeclareFactory({
2114
+ minVersion: "12.0.0",
2115
+ version: "22.2.6",
2116
+ ngImport: i0,
2117
+ type: StarSelect,
2118
+ deps: null,
2119
+ target: i0.ɵɵFactoryTarget.Component
2120
+ });
2121
+ static ɵcmp = i0.ɵɵngDeclareComponent({
2122
+ minVersion: "17.0.0",
2123
+ version: "22.2.6",
2124
+ type: StarSelect,
2125
+ isStandalone: true,
2126
+ selector: "star-select",
2127
+ inputs: { value: {
2128
+ classPropertyName: "value",
2129
+ publicName: "value",
2130
+ isSignal: true,
2131
+ isRequired: false,
2132
+ transformFunction: null
2133
+ } },
2134
+ outputs: { value: "valueChange" },
2135
+ host: {
2136
+ properties: {
2137
+ "class.star-select--open": "open()",
2138
+ "class.star-select--disabled": "disabled()",
2139
+ "class.star-select--invalid": "showInvalid()",
2140
+ "class.star-select--sm": "size() === 'sm'"
2141
+ },
2142
+ classAttribute: "star-select"
2143
+ },
2144
+ usesInheritance: true,
2145
+ ngImport: i0,
2146
+ template: `
2147
+ <div class="star-select__control" cdkOverlayOrigin #origin="cdkOverlayOrigin">
2148
+ <div
2149
+ #trigger
2150
+ class="star-select__trigger"
2151
+ role="combobox"
2152
+ aria-haspopup="listbox"
2153
+ [id]="inputId()"
2154
+ [attr.tabindex]="disabled() ? -1 : 0"
2155
+ [attr.aria-expanded]="open()"
2156
+ [attr.aria-controls]="open() ? listId : null"
2157
+ [attr.aria-activedescendant]="activeId()"
2158
+ [attr.aria-label]="ariaLabel()"
2159
+ [attr.aria-labelledby]="ariaLabelledBy()"
2160
+ [attr.aria-required]="required() || null"
2161
+ [attr.aria-invalid]="showInvalid() || null"
2162
+ [attr.aria-disabled]="disabled() || null"
2163
+ [attr.aria-readonly]="readonly() || null"
2164
+ (click)="toggle()"
2165
+ (keydown)="onKeydown($event)"
2166
+ (blur)="onTriggerBlur()"
2167
+ >
2168
+ @if (selectedOption(); as option) {
2169
+ <span class="star-select__value">{{ labelOf(option) }}</span>
2170
+ } @else {
2171
+ <span class="star-select__placeholder">{{
2172
+ placeholder() ?? text.selectPlaceholder
2173
+ }}</span>
2174
+ }
2175
+ </div>
2176
+ @if (showClear() && selectedOption() !== undefined && interactive()) {
2177
+ <button
2178
+ type="button"
2179
+ class="star-select__icon-btn"
2180
+ [attr.aria-label]="text.clear"
2181
+ (click)="clear()"
2182
+ >
2183
+ <i class="ph-bold ph-x" aria-hidden="true"></i>
2184
+ </button>
2185
+ }
2186
+ @if (loading()) {
2187
+ <i
2188
+ class="ph-bold ph-spinner-gap star-spin star-select__caret"
2189
+ role="img"
2190
+ [attr.aria-label]="text.loading"
2191
+ ></i>
2192
+ } @else {
2193
+ <i class="ph-bold ph-caret-down star-select__caret" aria-hidden="true"></i>
2194
+ }
2195
+ </div>
2196
+
2197
+ <ng-template
2198
+ cdkConnectedOverlay
2199
+ cdkConnectedOverlayUsePopover="inline"
2200
+ cdkConnectedOverlayMatchWidth
2201
+ [cdkConnectedOverlayOrigin]="origin"
2202
+ [cdkConnectedOverlayOpen]="open()"
2203
+ [cdkConnectedOverlayPositions]="positions"
2204
+ (attach)="onPanelAttached()"
2205
+ (detach)="closePanel(false)"
2206
+ (overlayOutsideClick)="onOutsideClick($event)"
2207
+ >
2208
+ <div class="star-panel" (mousedown)="onPanelMousedown($event)">
2209
+ @if (filter()) {
2210
+ <div class="star-panel__filter">
2211
+ <i class="ph-bold ph-magnifying-glass" aria-hidden="true"></i>
2212
+ <input
2213
+ #filterInput
2214
+ type="text"
2215
+ class="star-input star-input--sm"
2216
+ role="searchbox"
2217
+ autocomplete="off"
2218
+ [value]="filterValue()"
2219
+ [attr.placeholder]="filterPlaceholder() ?? text.filterPlaceholder"
2220
+ [attr.aria-label]="filterPlaceholder() ?? text.filterPlaceholder"
2221
+ [attr.aria-controls]="listId"
2222
+ [attr.aria-activedescendant]="activeId()"
2223
+ (input)="onFilterInput(filterInput.value)"
2224
+ (keydown)="onKeydown($event)"
2225
+ />
2226
+ </div>
2227
+ }
2228
+ <ul
2229
+ class="star-listbox"
2230
+ role="listbox"
2231
+ [id]="listId"
2232
+ [class.star-listbox--virtual]="virtualScroll()"
2233
+ [style.--star-item-size.px]="virtualScroll() ? virtualItemSize() : null"
2234
+ [style.max-height]="scrollHeight()"
2235
+ [attr.aria-label]="ariaLabel()"
2236
+ [attr.aria-labelledby]="ariaLabelledBy()"
2237
+ (scroll)="onListScroll($event)"
2238
+ >
2239
+ @if (virtualWindow().before) {
2240
+ <li
2241
+ class="star-listbox__spacer"
2242
+ role="presentation"
2243
+ [style.height.px]="virtualWindow().before"
2244
+ ></li>
2245
+ }
2246
+ @for (row of renderedRows(); track row.key) {
2247
+ @if (row.kind === 'group') {
2248
+ <li class="star-listbox__group" role="presentation" [id]="row.id">{{ row.label }}</li>
2249
+ } @else {
2250
+ @let option = row.option;
2251
+ @let i = row.index;
2252
+ <!-- Keyboard is handled on the combobox via aria-activedescendant (WAI-ARIA combobox pattern). -->
2253
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
2254
+ <li
2255
+ class="star-listbox__option"
2256
+ role="option"
2257
+ [id]="optionId(i)"
2258
+ [class.star-listbox__option--active]="activeIndex() === i"
2259
+ [class.star-listbox__option--selected]="isSelected(option)"
2260
+ [attr.aria-selected]="isSelected(option)"
2261
+ [attr.aria-disabled]="isDisabled(option) || null"
2262
+ [attr.aria-describedby]="describedBy(row)"
2263
+ [attr.aria-setsize]="virtualScroll() ? visibleOptions().length : null"
2264
+ [attr.aria-posinset]="virtualScroll() ? i + 1 : null"
2265
+ (click)="onOptionClick(option, i)"
2266
+ (mousemove)="isDisabled(option) || activeIndex.set(i)"
2267
+ >
2268
+ <span class="star-listbox__label">
2269
+ @if (optionTemplate(); as custom) {
2270
+ <ng-container
2271
+ *ngTemplateOutlet="custom.template; context: optionContext(option, i)"
2272
+ />
2273
+ } @else {
2274
+ {{ labelOf(option) }}
2275
+ }
2276
+ </span>
2277
+ @if (isSelected(option)) {
2278
+ <i class="ph-bold ph-check star-listbox__check" aria-hidden="true"></i>
2279
+ }
2280
+ </li>
2281
+ }
2282
+ } @empty {
2283
+ <li class="star-listbox__empty" role="presentation">{{ emptyText() }}</li>
2284
+ }
2285
+ @if (virtualWindow().after) {
2286
+ <li
2287
+ class="star-listbox__spacer"
2288
+ role="presentation"
2289
+ [style.height.px]="virtualWindow().after"
2290
+ ></li>
2291
+ }
2292
+ </ul>
2293
+ </div>
2294
+ </ng-template>
2295
+ `,
2296
+ isInline: true,
2297
+ dependencies: [
2298
+ {
2299
+ kind: "directive",
2300
+ type: CdkConnectedOverlay,
2301
+ selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]",
2302
+ inputs: [
2303
+ "cdkConnectedOverlayOrigin",
2304
+ "cdkConnectedOverlayPositions",
2305
+ "cdkConnectedOverlayPositionStrategy",
2306
+ "cdkConnectedOverlayOffsetX",
2307
+ "cdkConnectedOverlayOffsetY",
2308
+ "cdkConnectedOverlayWidth",
2309
+ "cdkConnectedOverlayHeight",
2310
+ "cdkConnectedOverlayMinWidth",
2311
+ "cdkConnectedOverlayMinHeight",
2312
+ "cdkConnectedOverlayBackdropClass",
2313
+ "cdkConnectedOverlayPanelClass",
2314
+ "cdkConnectedOverlayViewportMargin",
2315
+ "cdkConnectedOverlayScrollStrategy",
2316
+ "cdkConnectedOverlayOpen",
2317
+ "cdkConnectedOverlayDisableClose",
2318
+ "cdkConnectedOverlayTransformOriginOn",
2319
+ "cdkConnectedOverlayHasBackdrop",
2320
+ "cdkConnectedOverlayLockPosition",
2321
+ "cdkConnectedOverlayFlexibleDimensions",
2322
+ "cdkConnectedOverlayGrowAfterOpen",
2323
+ "cdkConnectedOverlayPush",
2324
+ "cdkConnectedOverlayDisposeOnNavigation",
2325
+ "cdkConnectedOverlayUsePopover",
2326
+ "cdkConnectedOverlayMatchWidth",
2327
+ "cdkConnectedOverlay"
2328
+ ],
2329
+ outputs: [
2330
+ "backdropClick",
2331
+ "positionChange",
2332
+ "attach",
2333
+ "detach",
2334
+ "overlayKeydown",
2335
+ "overlayOutsideClick"
2336
+ ],
2337
+ exportAs: ["cdkConnectedOverlay"]
2338
+ },
2339
+ {
2340
+ kind: "directive",
2341
+ type: CdkOverlayOrigin,
2342
+ selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]",
2343
+ exportAs: ["cdkOverlayOrigin"]
2344
+ },
2345
+ {
2346
+ kind: "directive",
2347
+ type: NgTemplateOutlet,
2348
+ selector: "[ngTemplateOutlet]",
2349
+ inputs: [
2350
+ "ngTemplateOutletContext",
2351
+ "ngTemplateOutlet",
2352
+ "ngTemplateOutletInjector"
2353
+ ]
2354
+ }
2355
+ ],
2356
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
2357
+ });
2358
+ };
2359
+ i0.ɵɵngDeclareClassMetadata({
2360
+ minVersion: "12.0.0",
2361
+ version: "22.2.6",
2362
+ ngImport: i0,
2363
+ type: StarSelect,
2364
+ decorators: [{
2365
+ type: Component,
2366
+ args: [{
2367
+ selector: "star-select",
2368
+ imports: [
2369
+ CdkConnectedOverlay,
2370
+ CdkOverlayOrigin,
2371
+ NgTemplateOutlet
2372
+ ],
2373
+ changeDetection: ChangeDetectionStrategy.OnPush,
2374
+ host: {
2375
+ class: "star-select",
2376
+ "[class.star-select--open]": "open()",
2377
+ "[class.star-select--disabled]": "disabled()",
2378
+ "[class.star-select--invalid]": "showInvalid()",
2379
+ "[class.star-select--sm]": "size() === 'sm'"
2380
+ },
2381
+ template: `
2382
+ <div class="star-select__control" cdkOverlayOrigin #origin="cdkOverlayOrigin">
2383
+ <div
2384
+ #trigger
2385
+ class="star-select__trigger"
2386
+ role="combobox"
2387
+ aria-haspopup="listbox"
2388
+ [id]="inputId()"
2389
+ [attr.tabindex]="disabled() ? -1 : 0"
2390
+ [attr.aria-expanded]="open()"
2391
+ [attr.aria-controls]="open() ? listId : null"
2392
+ [attr.aria-activedescendant]="activeId()"
2393
+ [attr.aria-label]="ariaLabel()"
2394
+ [attr.aria-labelledby]="ariaLabelledBy()"
2395
+ [attr.aria-required]="required() || null"
2396
+ [attr.aria-invalid]="showInvalid() || null"
2397
+ [attr.aria-disabled]="disabled() || null"
2398
+ [attr.aria-readonly]="readonly() || null"
2399
+ (click)="toggle()"
2400
+ (keydown)="onKeydown($event)"
2401
+ (blur)="onTriggerBlur()"
2402
+ >
2403
+ @if (selectedOption(); as option) {
2404
+ <span class="star-select__value">{{ labelOf(option) }}</span>
2405
+ } @else {
2406
+ <span class="star-select__placeholder">{{
2407
+ placeholder() ?? text.selectPlaceholder
2408
+ }}</span>
2409
+ }
2410
+ </div>
2411
+ @if (showClear() && selectedOption() !== undefined && interactive()) {
2412
+ <button
2413
+ type="button"
2414
+ class="star-select__icon-btn"
2415
+ [attr.aria-label]="text.clear"
2416
+ (click)="clear()"
2417
+ >
2418
+ <i class="ph-bold ph-x" aria-hidden="true"></i>
2419
+ </button>
2420
+ }
2421
+ @if (loading()) {
2422
+ <i
2423
+ class="ph-bold ph-spinner-gap star-spin star-select__caret"
2424
+ role="img"
2425
+ [attr.aria-label]="text.loading"
2426
+ ></i>
2427
+ } @else {
2428
+ <i class="ph-bold ph-caret-down star-select__caret" aria-hidden="true"></i>
2429
+ }
2430
+ </div>
2431
+
2432
+ <ng-template
2433
+ cdkConnectedOverlay
2434
+ cdkConnectedOverlayUsePopover="inline"
2435
+ cdkConnectedOverlayMatchWidth
2436
+ [cdkConnectedOverlayOrigin]="origin"
2437
+ [cdkConnectedOverlayOpen]="open()"
2438
+ [cdkConnectedOverlayPositions]="positions"
2439
+ (attach)="onPanelAttached()"
2440
+ (detach)="closePanel(false)"
2441
+ (overlayOutsideClick)="onOutsideClick($event)"
2442
+ >
2443
+ <div class="star-panel" (mousedown)="onPanelMousedown($event)">
2444
+ @if (filter()) {
2445
+ <div class="star-panel__filter">
2446
+ <i class="ph-bold ph-magnifying-glass" aria-hidden="true"></i>
2447
+ <input
2448
+ #filterInput
2449
+ type="text"
2450
+ class="star-input star-input--sm"
2451
+ role="searchbox"
2452
+ autocomplete="off"
2453
+ [value]="filterValue()"
2454
+ [attr.placeholder]="filterPlaceholder() ?? text.filterPlaceholder"
2455
+ [attr.aria-label]="filterPlaceholder() ?? text.filterPlaceholder"
2456
+ [attr.aria-controls]="listId"
2457
+ [attr.aria-activedescendant]="activeId()"
2458
+ (input)="onFilterInput(filterInput.value)"
2459
+ (keydown)="onKeydown($event)"
2460
+ />
2461
+ </div>
2462
+ }
2463
+ <ul
2464
+ class="star-listbox"
2465
+ role="listbox"
2466
+ [id]="listId"
2467
+ [class.star-listbox--virtual]="virtualScroll()"
2468
+ [style.--star-item-size.px]="virtualScroll() ? virtualItemSize() : null"
2469
+ [style.max-height]="scrollHeight()"
2470
+ [attr.aria-label]="ariaLabel()"
2471
+ [attr.aria-labelledby]="ariaLabelledBy()"
2472
+ (scroll)="onListScroll($event)"
2473
+ >
2474
+ @if (virtualWindow().before) {
2475
+ <li
2476
+ class="star-listbox__spacer"
2477
+ role="presentation"
2478
+ [style.height.px]="virtualWindow().before"
2479
+ ></li>
2480
+ }
2481
+ @for (row of renderedRows(); track row.key) {
2482
+ @if (row.kind === 'group') {
2483
+ <li class="star-listbox__group" role="presentation" [id]="row.id">{{ row.label }}</li>
2484
+ } @else {
2485
+ @let option = row.option;
2486
+ @let i = row.index;
2487
+ <!-- Keyboard is handled on the combobox via aria-activedescendant (WAI-ARIA combobox pattern). -->
2488
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
2489
+ <li
2490
+ class="star-listbox__option"
2491
+ role="option"
2492
+ [id]="optionId(i)"
2493
+ [class.star-listbox__option--active]="activeIndex() === i"
2494
+ [class.star-listbox__option--selected]="isSelected(option)"
2495
+ [attr.aria-selected]="isSelected(option)"
2496
+ [attr.aria-disabled]="isDisabled(option) || null"
2497
+ [attr.aria-describedby]="describedBy(row)"
2498
+ [attr.aria-setsize]="virtualScroll() ? visibleOptions().length : null"
2499
+ [attr.aria-posinset]="virtualScroll() ? i + 1 : null"
2500
+ (click)="onOptionClick(option, i)"
2501
+ (mousemove)="isDisabled(option) || activeIndex.set(i)"
2502
+ >
2503
+ <span class="star-listbox__label">
2504
+ @if (optionTemplate(); as custom) {
2505
+ <ng-container
2506
+ *ngTemplateOutlet="custom.template; context: optionContext(option, i)"
2507
+ />
2508
+ } @else {
2509
+ {{ labelOf(option) }}
2510
+ }
2511
+ </span>
2512
+ @if (isSelected(option)) {
2513
+ <i class="ph-bold ph-check star-listbox__check" aria-hidden="true"></i>
2514
+ }
2515
+ </li>
2516
+ }
2517
+ } @empty {
2518
+ <li class="star-listbox__empty" role="presentation">{{ emptyText() }}</li>
2519
+ }
2520
+ @if (virtualWindow().after) {
2521
+ <li
2522
+ class="star-listbox__spacer"
2523
+ role="presentation"
2524
+ [style.height.px]="virtualWindow().after"
2525
+ ></li>
2526
+ }
2527
+ </ul>
2528
+ </div>
2529
+ </ng-template>
2530
+ `
2531
+ }]
2532
+ }],
2533
+ propDecorators: { value: [{
2534
+ type: i0.Input,
2535
+ args: [{
2536
+ isSignal: true,
2537
+ alias: "value",
2538
+ required: false
2539
+ }]
2540
+ }, {
2541
+ type: i0.Output,
2542
+ args: ["valueChange"]
2543
+ }] }
2544
+ });
2545
+ export { StarCascadeSelect, StarMultiSelect, StarOptionListBase, StarOptionTemplate, StarSelect };
2546
+
2547
+ //# sourceMappingURL=star-ng-ui-select.mjs.map