@ojiepermana/angular-component 22.0.27

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 (244) hide show
  1. package/README.md +82 -0
  2. package/accordion/README.md +193 -0
  3. package/alert/README.md +180 -0
  4. package/alert-dialog/README.md +239 -0
  5. package/aspect-ratio/README.md +112 -0
  6. package/avatar/README.md +176 -0
  7. package/badge/README.md +133 -0
  8. package/breadcrumb/README.md +216 -0
  9. package/button/README.md +139 -0
  10. package/button-group/README.md +208 -0
  11. package/calendar/README.md +135 -0
  12. package/card/README.md +220 -0
  13. package/carousel/README.md +276 -0
  14. package/checkbox/README.md +149 -0
  15. package/collapsible/README.md +195 -0
  16. package/combobox/README.md +198 -0
  17. package/command/README.md +275 -0
  18. package/composer/README.md +235 -0
  19. package/context-menu/README.md +267 -0
  20. package/date-picker/README.md +179 -0
  21. package/dialog/README.md +235 -0
  22. package/drawer/README.md +145 -0
  23. package/dropdown-menu/README.md +311 -0
  24. package/editor/README.md +136 -0
  25. package/empty/README.md +183 -0
  26. package/fesm2022/ojiepermana-angular-component-accordion.mjs +186 -0
  27. package/fesm2022/ojiepermana-angular-component-accordion.mjs.map +1 -0
  28. package/fesm2022/ojiepermana-angular-component-alert-dialog.mjs +276 -0
  29. package/fesm2022/ojiepermana-angular-component-alert-dialog.mjs.map +1 -0
  30. package/fesm2022/ojiepermana-angular-component-alert.mjs +99 -0
  31. package/fesm2022/ojiepermana-angular-component-alert.mjs.map +1 -0
  32. package/fesm2022/ojiepermana-angular-component-aspect-ratio.mjs +37 -0
  33. package/fesm2022/ojiepermana-angular-component-aspect-ratio.mjs.map +1 -0
  34. package/fesm2022/ojiepermana-angular-component-avatar.mjs +139 -0
  35. package/fesm2022/ojiepermana-angular-component-avatar.mjs.map +1 -0
  36. package/fesm2022/ojiepermana-angular-component-badge.mjs +50 -0
  37. package/fesm2022/ojiepermana-angular-component-badge.mjs.map +1 -0
  38. package/fesm2022/ojiepermana-angular-component-breadcrumb.mjs +200 -0
  39. package/fesm2022/ojiepermana-angular-component-breadcrumb.mjs.map +1 -0
  40. package/fesm2022/ojiepermana-angular-component-button-group.mjs +103 -0
  41. package/fesm2022/ojiepermana-angular-component-button-group.mjs.map +1 -0
  42. package/fesm2022/ojiepermana-angular-component-button.mjs +68 -0
  43. package/fesm2022/ojiepermana-angular-component-button.mjs.map +1 -0
  44. package/fesm2022/ojiepermana-angular-component-calendar.mjs +103 -0
  45. package/fesm2022/ojiepermana-angular-component-calendar.mjs.map +1 -0
  46. package/fesm2022/ojiepermana-angular-component-card.mjs +152 -0
  47. package/fesm2022/ojiepermana-angular-component-card.mjs.map +1 -0
  48. package/fesm2022/ojiepermana-angular-component-carousel.mjs +334 -0
  49. package/fesm2022/ojiepermana-angular-component-carousel.mjs.map +1 -0
  50. package/fesm2022/ojiepermana-angular-component-checkbox.mjs +165 -0
  51. package/fesm2022/ojiepermana-angular-component-checkbox.mjs.map +1 -0
  52. package/fesm2022/ojiepermana-angular-component-collapsible.mjs +121 -0
  53. package/fesm2022/ojiepermana-angular-component-collapsible.mjs.map +1 -0
  54. package/fesm2022/ojiepermana-angular-component-combobox.mjs +274 -0
  55. package/fesm2022/ojiepermana-angular-component-combobox.mjs.map +1 -0
  56. package/fesm2022/ojiepermana-angular-component-command.mjs +297 -0
  57. package/fesm2022/ojiepermana-angular-component-command.mjs.map +1 -0
  58. package/fesm2022/ojiepermana-angular-component-composer.mjs +352 -0
  59. package/fesm2022/ojiepermana-angular-component-composer.mjs.map +1 -0
  60. package/fesm2022/ojiepermana-angular-component-context-menu.mjs +108 -0
  61. package/fesm2022/ojiepermana-angular-component-context-menu.mjs.map +1 -0
  62. package/fesm2022/ojiepermana-angular-component-date-picker.mjs +186 -0
  63. package/fesm2022/ojiepermana-angular-component-date-picker.mjs.map +1 -0
  64. package/fesm2022/ojiepermana-angular-component-dialog.mjs +283 -0
  65. package/fesm2022/ojiepermana-angular-component-dialog.mjs.map +1 -0
  66. package/fesm2022/ojiepermana-angular-component-drawer.mjs +6 -0
  67. package/fesm2022/ojiepermana-angular-component-drawer.mjs.map +1 -0
  68. package/fesm2022/ojiepermana-angular-component-dropdown-menu.mjs +494 -0
  69. package/fesm2022/ojiepermana-angular-component-dropdown-menu.mjs.map +1 -0
  70. package/fesm2022/ojiepermana-angular-component-editor.mjs +680 -0
  71. package/fesm2022/ojiepermana-angular-component-editor.mjs.map +1 -0
  72. package/fesm2022/ojiepermana-angular-component-empty.mjs +145 -0
  73. package/fesm2022/ojiepermana-angular-component-empty.mjs.map +1 -0
  74. package/fesm2022/ojiepermana-angular-component-form.mjs +364 -0
  75. package/fesm2022/ojiepermana-angular-component-form.mjs.map +1 -0
  76. package/fesm2022/ojiepermana-angular-component-hover-card.mjs +275 -0
  77. package/fesm2022/ojiepermana-angular-component-hover-card.mjs.map +1 -0
  78. package/fesm2022/ojiepermana-angular-component-icon.mjs +86 -0
  79. package/fesm2022/ojiepermana-angular-component-icon.mjs.map +1 -0
  80. package/fesm2022/ojiepermana-angular-component-input-group.mjs +179 -0
  81. package/fesm2022/ojiepermana-angular-component-input-group.mjs.map +1 -0
  82. package/fesm2022/ojiepermana-angular-component-input-otp.mjs +517 -0
  83. package/fesm2022/ojiepermana-angular-component-input-otp.mjs.map +1 -0
  84. package/fesm2022/ojiepermana-angular-component-input.mjs +45 -0
  85. package/fesm2022/ojiepermana-angular-component-input.mjs.map +1 -0
  86. package/fesm2022/ojiepermana-angular-component-item.mjs +264 -0
  87. package/fesm2022/ojiepermana-angular-component-item.mjs.map +1 -0
  88. package/fesm2022/ojiepermana-angular-component-kanban.mjs +314 -0
  89. package/fesm2022/ojiepermana-angular-component-kanban.mjs.map +1 -0
  90. package/fesm2022/ojiepermana-angular-component-kbd.mjs +55 -0
  91. package/fesm2022/ojiepermana-angular-component-kbd.mjs.map +1 -0
  92. package/fesm2022/ojiepermana-angular-component-label.mjs +33 -0
  93. package/fesm2022/ojiepermana-angular-component-label.mjs.map +1 -0
  94. package/fesm2022/ojiepermana-angular-component-menubar.mjs +311 -0
  95. package/fesm2022/ojiepermana-angular-component-menubar.mjs.map +1 -0
  96. package/fesm2022/ojiepermana-angular-component-native-select.mjs +67 -0
  97. package/fesm2022/ojiepermana-angular-component-native-select.mjs.map +1 -0
  98. package/fesm2022/ojiepermana-angular-component-navigation-menu.mjs +408 -0
  99. package/fesm2022/ojiepermana-angular-component-navigation-menu.mjs.map +1 -0
  100. package/fesm2022/ojiepermana-angular-component-pagination.mjs +226 -0
  101. package/fesm2022/ojiepermana-angular-component-pagination.mjs.map +1 -0
  102. package/fesm2022/ojiepermana-angular-component-pillbox.mjs +810 -0
  103. package/fesm2022/ojiepermana-angular-component-pillbox.mjs.map +1 -0
  104. package/fesm2022/ojiepermana-angular-component-popover.mjs +145 -0
  105. package/fesm2022/ojiepermana-angular-component-popover.mjs.map +1 -0
  106. package/fesm2022/ojiepermana-angular-component-progress.mjs +60 -0
  107. package/fesm2022/ojiepermana-angular-component-progress.mjs.map +1 -0
  108. package/fesm2022/ojiepermana-angular-component-radio.mjs +173 -0
  109. package/fesm2022/ojiepermana-angular-component-radio.mjs.map +1 -0
  110. package/fesm2022/ojiepermana-angular-component-resizable.mjs +478 -0
  111. package/fesm2022/ojiepermana-angular-component-resizable.mjs.map +1 -0
  112. package/fesm2022/ojiepermana-angular-component-scroll-area.mjs +54 -0
  113. package/fesm2022/ojiepermana-angular-component-scroll-area.mjs.map +1 -0
  114. package/fesm2022/ojiepermana-angular-component-select.mjs +297 -0
  115. package/fesm2022/ojiepermana-angular-component-select.mjs.map +1 -0
  116. package/fesm2022/ojiepermana-angular-component-separator.mjs +37 -0
  117. package/fesm2022/ojiepermana-angular-component-separator.mjs.map +1 -0
  118. package/fesm2022/ojiepermana-angular-component-sheet.mjs +297 -0
  119. package/fesm2022/ojiepermana-angular-component-sheet.mjs.map +1 -0
  120. package/fesm2022/ojiepermana-angular-component-skeleton.mjs +31 -0
  121. package/fesm2022/ojiepermana-angular-component-skeleton.mjs.map +1 -0
  122. package/fesm2022/ojiepermana-angular-component-slider.mjs +423 -0
  123. package/fesm2022/ojiepermana-angular-component-slider.mjs.map +1 -0
  124. package/fesm2022/ojiepermana-angular-component-spinner.mjs +60 -0
  125. package/fesm2022/ojiepermana-angular-component-spinner.mjs.map +1 -0
  126. package/fesm2022/ojiepermana-angular-component-switch.mjs +140 -0
  127. package/fesm2022/ojiepermana-angular-component-switch.mjs.map +1 -0
  128. package/fesm2022/ojiepermana-angular-component-table.mjs +155 -0
  129. package/fesm2022/ojiepermana-angular-component-table.mjs.map +1 -0
  130. package/fesm2022/ojiepermana-angular-component-tabs.mjs +271 -0
  131. package/fesm2022/ojiepermana-angular-component-tabs.mjs.map +1 -0
  132. package/fesm2022/ojiepermana-angular-component-textarea.mjs +39 -0
  133. package/fesm2022/ojiepermana-angular-component-textarea.mjs.map +1 -0
  134. package/fesm2022/ojiepermana-angular-component-timeline.mjs +237 -0
  135. package/fesm2022/ojiepermana-angular-component-timeline.mjs.map +1 -0
  136. package/fesm2022/ojiepermana-angular-component-toast.mjs +161 -0
  137. package/fesm2022/ojiepermana-angular-component-toast.mjs.map +1 -0
  138. package/fesm2022/ojiepermana-angular-component-toggle-group.mjs +289 -0
  139. package/fesm2022/ojiepermana-angular-component-toggle-group.mjs.map +1 -0
  140. package/fesm2022/ojiepermana-angular-component-toggle.mjs +82 -0
  141. package/fesm2022/ojiepermana-angular-component-toggle.mjs.map +1 -0
  142. package/fesm2022/ojiepermana-angular-component-tooltip.mjs +410 -0
  143. package/fesm2022/ojiepermana-angular-component-tooltip.mjs.map +1 -0
  144. package/fesm2022/ojiepermana-angular-component-utils.mjs +81 -0
  145. package/fesm2022/ojiepermana-angular-component-utils.mjs.map +1 -0
  146. package/fesm2022/ojiepermana-angular-component.mjs +11 -0
  147. package/fesm2022/ojiepermana-angular-component.mjs.map +1 -0
  148. package/form/README.md +210 -0
  149. package/hover-card/README.md +142 -0
  150. package/icon/README.md +25 -0
  151. package/input/README.md +159 -0
  152. package/input-group/README.md +237 -0
  153. package/input-otp/README.md +278 -0
  154. package/item/README.md +247 -0
  155. package/kanban/README.md +81 -0
  156. package/kbd/README.md +139 -0
  157. package/label/README.md +135 -0
  158. package/menubar/README.md +269 -0
  159. package/native-select/README.md +176 -0
  160. package/navigation-menu/README.md +160 -0
  161. package/package.json +291 -0
  162. package/pagination/README.md +144 -0
  163. package/pillbox/README.md +67 -0
  164. package/popover/README.md +43 -0
  165. package/progress/README.md +160 -0
  166. package/radio/README.md +209 -0
  167. package/resizable/README.md +168 -0
  168. package/scroll-area/README.md +143 -0
  169. package/select/README.md +174 -0
  170. package/separator/README.md +170 -0
  171. package/sheet/README.md +183 -0
  172. package/skeleton/README.md +158 -0
  173. package/slider/README.md +207 -0
  174. package/spinner/README.md +160 -0
  175. package/switch/README.md +166 -0
  176. package/table/README.md +291 -0
  177. package/tabs/README.md +214 -0
  178. package/textarea/README.md +153 -0
  179. package/timeline/README.md +94 -0
  180. package/toast/README.md +321 -0
  181. package/toggle/README.md +131 -0
  182. package/toggle-group/README.md +206 -0
  183. package/tooltip/README.md +207 -0
  184. package/types/ojiepermana-angular-component-accordion.d.ts +51 -0
  185. package/types/ojiepermana-angular-component-alert-dialog.d.ts +93 -0
  186. package/types/ojiepermana-angular-component-alert.d.ts +37 -0
  187. package/types/ojiepermana-angular-component-aspect-ratio.d.ts +12 -0
  188. package/types/ojiepermana-angular-component-avatar.d.ts +51 -0
  189. package/types/ojiepermana-angular-component-badge.d.ts +19 -0
  190. package/types/ojiepermana-angular-component-breadcrumb.d.ts +46 -0
  191. package/types/ojiepermana-angular-component-button-group.d.ts +26 -0
  192. package/types/ojiepermana-angular-component-button.d.ts +22 -0
  193. package/types/ojiepermana-angular-component-calendar.d.ts +39 -0
  194. package/types/ojiepermana-angular-component-card.d.ts +60 -0
  195. package/types/ojiepermana-angular-component-carousel.d.ts +86 -0
  196. package/types/ojiepermana-angular-component-checkbox.d.ts +42 -0
  197. package/types/ojiepermana-angular-component-collapsible.d.ts +42 -0
  198. package/types/ojiepermana-angular-component-combobox.d.ts +53 -0
  199. package/types/ojiepermana-angular-component-command.d.ts +102 -0
  200. package/types/ojiepermana-angular-component-composer.d.ts +90 -0
  201. package/types/ojiepermana-angular-component-context-menu.d.ts +36 -0
  202. package/types/ojiepermana-angular-component-date-picker.d.ts +48 -0
  203. package/types/ojiepermana-angular-component-dialog.d.ts +87 -0
  204. package/types/ojiepermana-angular-component-drawer.d.ts +1 -0
  205. package/types/ojiepermana-angular-component-dropdown-menu.d.ts +140 -0
  206. package/types/ojiepermana-angular-component-editor.d.ts +126 -0
  207. package/types/ojiepermana-angular-component-empty.d.ts +50 -0
  208. package/types/ojiepermana-angular-component-form.d.ts +140 -0
  209. package/types/ojiepermana-angular-component-hover-card.d.ts +75 -0
  210. package/types/ojiepermana-angular-component-icon.d.ts +31 -0
  211. package/types/ojiepermana-angular-component-input-group.d.ts +51 -0
  212. package/types/ojiepermana-angular-component-input-otp.d.ts +142 -0
  213. package/types/ojiepermana-angular-component-input.d.ts +16 -0
  214. package/types/ojiepermana-angular-component-item.d.ts +88 -0
  215. package/types/ojiepermana-angular-component-kanban.d.ts +70 -0
  216. package/types/ojiepermana-angular-component-kbd.d.ts +16 -0
  217. package/types/ojiepermana-angular-component-label.d.ts +11 -0
  218. package/types/ojiepermana-angular-component-menubar.d.ts +69 -0
  219. package/types/ojiepermana-angular-component-native-select.d.ts +26 -0
  220. package/types/ojiepermana-angular-component-navigation-menu.d.ts +98 -0
  221. package/types/ojiepermana-angular-component-pagination.d.ts +33 -0
  222. package/types/ojiepermana-angular-component-pillbox.d.ts +156 -0
  223. package/types/ojiepermana-angular-component-popover.d.ts +50 -0
  224. package/types/ojiepermana-angular-component-progress.d.ts +17 -0
  225. package/types/ojiepermana-angular-component-radio.d.ts +57 -0
  226. package/types/ojiepermana-angular-component-resizable.d.ts +99 -0
  227. package/types/ojiepermana-angular-component-scroll-area.d.ts +19 -0
  228. package/types/ojiepermana-angular-component-select.d.ts +56 -0
  229. package/types/ojiepermana-angular-component-separator.d.ts +14 -0
  230. package/types/ojiepermana-angular-component-sheet.d.ts +78 -0
  231. package/types/ojiepermana-angular-component-skeleton.d.ts +10 -0
  232. package/types/ojiepermana-angular-component-slider.d.ts +74 -0
  233. package/types/ojiepermana-angular-component-spinner.d.ts +13 -0
  234. package/types/ojiepermana-angular-component-switch.d.ts +44 -0
  235. package/types/ojiepermana-angular-component-table.d.ts +52 -0
  236. package/types/ojiepermana-angular-component-tabs.d.ts +92 -0
  237. package/types/ojiepermana-angular-component-textarea.d.ts +12 -0
  238. package/types/ojiepermana-angular-component-timeline.d.ts +63 -0
  239. package/types/ojiepermana-angular-component-toast.d.ts +51 -0
  240. package/types/ojiepermana-angular-component-toggle-group.d.ts +89 -0
  241. package/types/ojiepermana-angular-component-toggle.d.ts +25 -0
  242. package/types/ojiepermana-angular-component-tooltip.d.ts +101 -0
  243. package/types/ojiepermana-angular-component-utils.d.ts +30 -0
  244. package/types/ojiepermana-angular-component.d.ts +2 -0
@@ -0,0 +1,810 @@
1
+ import { DOCUMENT, NgTemplateOutlet } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, TemplateRef, Directive, ElementRef, contentChild, input, booleanAttribute, output, computed, ChangeDetectionStrategy, Component, numberAttribute, DestroyRef, signal, viewChild, contentChildren, forwardRef } from '@angular/core';
4
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
5
+ import { cn, uniqueId } from '@ojiepermana/angular-component/utils';
6
+
7
+ class PillboxContext {
8
+ }
9
+ const pillboxTriggerSizeClasses = {
10
+ default: 'min-h-10 px-3 py-2 text-sm',
11
+ sm: 'min-h-8 px-2.5 py-1.5 text-xs',
12
+ };
13
+ const pillboxPillSizeClasses = {
14
+ default: 'min-h-6 px-2 text-xs',
15
+ sm: 'min-h-5 px-1.5 text-2xs-plus',
16
+ };
17
+ class PillboxSelectedDirective {
18
+ template = inject(TemplateRef);
19
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PillboxSelectedDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
20
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: PillboxSelectedDirective, isStandalone: true, selector: "ng-template[PillboxSelected]", exportAs: ["PillboxSelected"], ngImport: i0 });
21
+ }
22
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PillboxSelectedDirective, decorators: [{
23
+ type: Directive,
24
+ args: [{
25
+ selector: 'ng-template[PillboxSelected]',
26
+ exportAs: 'PillboxSelected',
27
+ }]
28
+ }] });
29
+ class PillboxOptionComponent {
30
+ context = inject(PillboxContext);
31
+ element = inject(ElementRef);
32
+ selectedTemplate = contentChild(PillboxSelectedDirective, /* @ts-ignore */
33
+ ...(ngDevMode ? [{ debugName: "selectedTemplate" }] : /* istanbul ignore next */ []));
34
+ value = input.required(/* @ts-ignore */
35
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
36
+ label = input('', /* @ts-ignore */
37
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
38
+ selectedLabel = input('', /* @ts-ignore */
39
+ ...(ngDevMode ? [{ debugName: "selectedLabel" }] : /* istanbul ignore next */ []));
40
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
41
+ filterable = input(true, { ...(ngDevMode ? { debugName: "filterable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
42
+ class = input('', /* @ts-ignore */
43
+ ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
44
+ selectedChange = output();
45
+ selected = computed(() => this.context.optionSelected(this), /* @ts-ignore */
46
+ ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
47
+ visible = computed(() => this.context.optionVisible(this), /* @ts-ignore */
48
+ ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
49
+ classes = computed(() => cn('relative flex w-full cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors', 'hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground', 'data-[selected]:bg-accent data-[selected]:text-accent-foreground', 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50', this.class()), /* @ts-ignore */
50
+ ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
51
+ textLabel() {
52
+ return (this.label() || this.element.nativeElement.textContent || String(this.value())).trim();
53
+ }
54
+ pillLabel() {
55
+ return (this.selectedLabel() || this.textLabel()).trim();
56
+ }
57
+ pillTemplate() {
58
+ return this.selectedTemplate()?.template ?? null;
59
+ }
60
+ handleClick(event) {
61
+ this.context.chooseOption(this, event);
62
+ }
63
+ handleKeydown(event) {
64
+ event.preventDefault();
65
+ this.context.chooseOption(this, event);
66
+ }
67
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PillboxOptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
68
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: PillboxOptionComponent, isStandalone: true, selector: "PillboxOption, button[PillboxOption]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, selectedLabel: { classPropertyName: "selectedLabel", publicName: "selectedLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedChange: "selectedChange" }, host: { attributes: { "type": "button" }, listeners: { "click": "handleClick($event)", "keydown.enter": "handleKeydown($any($event))", "keydown.space": "handleKeydown($any($event))" }, properties: { "class": "classes()", "attr.data-slot": "\"pillbox-option\"", "attr.data-selected": "selected() ? \"\" : null", "attr.data-disabled": "disabled() ? \"\" : null", "attr.role": "\"option\"", "attr.aria-selected": "selected()", "attr.aria-disabled": "disabled() ? \"true\" : null", "attr.tabindex": "disabled() ? -1 : 0", "hidden": "!visible()" } }, queries: [{ propertyName: "selectedTemplate", first: true, predicate: PillboxSelectedDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
69
+ <span class="min-w-0 flex-1 truncate text-left"><ng-content /></span>
70
+ @if (selected()) {
71
+ <svg
72
+ aria-hidden="true"
73
+ class="ml-auto size-4 shrink-0"
74
+ viewBox="0 0 24 24"
75
+ fill="none"
76
+ stroke="currentColor"
77
+ stroke-width="1.75"
78
+ stroke-linecap="round"
79
+ stroke-linejoin="round">
80
+ <path d="M20 6 9 17l-5-5" />
81
+ </svg>
82
+ }
83
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
84
+ }
85
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PillboxOptionComponent, decorators: [{
86
+ type: Component,
87
+ args: [{
88
+ selector: 'PillboxOption, button[PillboxOption]',
89
+ changeDetection: ChangeDetectionStrategy.OnPush,
90
+ host: {
91
+ type: 'button',
92
+ '[class]': 'classes()',
93
+ '[attr.data-slot]': '"pillbox-option"',
94
+ '[attr.data-selected]': 'selected() ? "" : null',
95
+ '[attr.data-disabled]': 'disabled() ? "" : null',
96
+ '[attr.role]': '"option"',
97
+ '[attr.aria-selected]': 'selected()',
98
+ '[attr.aria-disabled]': 'disabled() ? "true" : null',
99
+ '[attr.tabindex]': 'disabled() ? -1 : 0',
100
+ '[hidden]': '!visible()',
101
+ '(click)': 'handleClick($event)',
102
+ '(keydown.enter)': 'handleKeydown($any($event))',
103
+ '(keydown.space)': 'handleKeydown($any($event))',
104
+ },
105
+ template: `
106
+ <span class="min-w-0 flex-1 truncate text-left"><ng-content /></span>
107
+ @if (selected()) {
108
+ <svg
109
+ aria-hidden="true"
110
+ class="ml-auto size-4 shrink-0"
111
+ viewBox="0 0 24 24"
112
+ fill="none"
113
+ stroke="currentColor"
114
+ stroke-width="1.75"
115
+ stroke-linecap="round"
116
+ stroke-linejoin="round">
117
+ <path d="M20 6 9 17l-5-5" />
118
+ </svg>
119
+ }
120
+ `,
121
+ }]
122
+ }], propDecorators: { selectedTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => PillboxSelectedDirective), { isSignal: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], selectedLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], selectedChange: [{ type: i0.Output, args: ["selectedChange"] }] } });
123
+ class PillboxOptionCreateComponent {
124
+ context = inject(PillboxContext);
125
+ minLength = input(1, { ...(ngDevMode ? { debugName: "minLength" } : /* istanbul ignore next */ {}), transform: numberAttribute });
126
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
127
+ class = input('', /* @ts-ignore */
128
+ ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
129
+ selected = output();
130
+ visible = computed(() => this.context.createVisible(this), /* @ts-ignore */
131
+ ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
132
+ classes = computed(() => cn('relative flex w-full cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm font-medium text-primary outline-none transition-colors', 'hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground', 'aria-disabled:pointer-events-none aria-disabled:opacity-50', this.class()), /* @ts-ignore */
133
+ ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
134
+ handleClick(event) {
135
+ this.context.chooseCreate(this, event);
136
+ }
137
+ handleKeydown(event) {
138
+ event.preventDefault();
139
+ this.context.chooseCreate(this, event);
140
+ }
141
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PillboxOptionCreateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
142
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.2", type: PillboxOptionCreateComponent, isStandalone: true, selector: "PillboxOptionCreate, button[PillboxOptionCreate]", inputs: { minLength: { classPropertyName: "minLength", publicName: "minLength", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected" }, host: { attributes: { "type": "button" }, listeners: { "click": "handleClick($event)", "keydown.enter": "handleKeydown($any($event))", "keydown.space": "handleKeydown($any($event))" }, properties: { "class": "classes()", "attr.data-slot": "\"pillbox-option-create\"", "attr.role": "\"option\"", "attr.tabindex": "disabled() ? -1 : 0", "attr.aria-disabled": "disabled() ? \"true\" : null", "hidden": "!visible()" } }, ngImport: i0, template: `<ng-content />`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
143
+ }
144
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PillboxOptionCreateComponent, decorators: [{
145
+ type: Component,
146
+ args: [{
147
+ selector: 'PillboxOptionCreate, button[PillboxOptionCreate]',
148
+ changeDetection: ChangeDetectionStrategy.OnPush,
149
+ host: {
150
+ type: 'button',
151
+ '[class]': 'classes()',
152
+ '[attr.data-slot]': '"pillbox-option-create"',
153
+ '[attr.role]': '"option"',
154
+ '[attr.tabindex]': 'disabled() ? -1 : 0',
155
+ '[attr.aria-disabled]': 'disabled() ? "true" : null',
156
+ '[hidden]': '!visible()',
157
+ '(click)': 'handleClick($event)',
158
+ '(keydown.enter)': 'handleKeydown($any($event))',
159
+ '(keydown.space)': 'handleKeydown($any($event))',
160
+ },
161
+ template: `<ng-content />`,
162
+ }]
163
+ }], propDecorators: { minLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minLength", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], selected: [{ type: i0.Output, args: ["selected"] }] } });
164
+ class PillboxOptionEmptyComponent {
165
+ context = inject(PillboxContext);
166
+ whenLoading = input('', /* @ts-ignore */
167
+ ...(ngDevMode ? [{ debugName: "whenLoading" }] : /* istanbul ignore next */ []));
168
+ class = input('', /* @ts-ignore */
169
+ ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
170
+ classes = computed(() => cn('px-2 py-6 text-center text-sm text-muted-foreground', this.class()), /* @ts-ignore */
171
+ ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
172
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PillboxOptionEmptyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
173
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: PillboxOptionEmptyComponent, isStandalone: true, selector: "PillboxOptionEmpty", inputs: { whenLoading: { classPropertyName: "whenLoading", publicName: "whenLoading", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "presentation" }, properties: { "class": "classes()", "attr.data-slot": "\"pillbox-option-empty\"", "hidden": "!context.emptyVisible()" } }, ngImport: i0, template: `
174
+ @if (context.emptyMessage()) {
175
+ {{ context.emptyMessage() }}
176
+ } @else {
177
+ <ng-content />
178
+ }
179
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
180
+ }
181
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PillboxOptionEmptyComponent, decorators: [{
182
+ type: Component,
183
+ args: [{
184
+ selector: 'PillboxOptionEmpty',
185
+ changeDetection: ChangeDetectionStrategy.OnPush,
186
+ host: {
187
+ '[class]': 'classes()',
188
+ '[attr.data-slot]': '"pillbox-option-empty"',
189
+ role: 'presentation',
190
+ '[hidden]': '!context.emptyVisible()',
191
+ },
192
+ template: `
193
+ @if (context.emptyMessage()) {
194
+ {{ context.emptyMessage() }}
195
+ } @else {
196
+ <ng-content />
197
+ }
198
+ `,
199
+ }]
200
+ }], propDecorators: { whenLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "whenLoading", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
201
+ class PillboxComponent extends PillboxContext {
202
+ element = inject(ElementRef);
203
+ document = inject(DOCUMENT);
204
+ destroyRef = inject(DestroyRef);
205
+ id = input(null, /* @ts-ignore */
206
+ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
207
+ placeholder = input('Choose options...', /* @ts-ignore */
208
+ ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
209
+ searchPlaceholder = input('Search...', /* @ts-ignore */
210
+ ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : /* istanbul ignore next */ []));
211
+ size = input('default', /* @ts-ignore */
212
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
213
+ variant = input('default', /* @ts-ignore */
214
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
215
+ multiple = input(false, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
216
+ searchable = input(false, { ...(ngDevMode ? { debugName: "searchable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
217
+ filter = input(true, { ...(ngDevMode ? { debugName: "filter" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
218
+ clearable = input(true, { ...(ngDevMode ? { debugName: "clearable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
219
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
220
+ invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
221
+ loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
222
+ emptyText = input('No options found.', /* @ts-ignore */
223
+ ...(ngDevMode ? [{ debugName: "emptyText" }] : /* istanbul ignore next */ []));
224
+ loadingText = input('Loading...', /* @ts-ignore */
225
+ ...(ngDevMode ? [{ debugName: "loadingText" }] : /* istanbul ignore next */ []));
226
+ ariaLabel = input(null, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
227
+ ariaDescribedby = input(null, { ...(ngDevMode ? { debugName: "ariaDescribedby" } : /* istanbul ignore next */ {}), alias: 'aria-describedby' });
228
+ ariaLabelledby = input(null, { ...(ngDevMode ? { debugName: "ariaLabelledby" } : /* istanbul ignore next */ {}), alias: 'aria-labelledby' });
229
+ class = input('', /* @ts-ignore */
230
+ ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
231
+ valueChange = output();
232
+ searchChange = output();
233
+ create = output();
234
+ openedChange = output();
235
+ query = signal('', /* @ts-ignore */
236
+ ...(ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []));
237
+ openState = signal(false, /* @ts-ignore */
238
+ ...(ngDevMode ? [{ debugName: "openState" }] : /* istanbul ignore next */ []));
239
+ selectedValues = signal([], /* @ts-ignore */
240
+ ...(ngDevMode ? [{ debugName: "selectedValues" }] : /* istanbul ignore next */ []));
241
+ disabledFromControl = signal(false, /* @ts-ignore */
242
+ ...(ngDevMode ? [{ debugName: "disabledFromControl" }] : /* istanbul ignore next */ []));
243
+ generatedId = uniqueId('Pillbox');
244
+ trigger = viewChild.required('trigger');
245
+ inlineSearch = viewChild('inlineSearch', /* @ts-ignore */
246
+ ...(ngDevMode ? [{ debugName: "inlineSearch" }] : /* istanbul ignore next */ []));
247
+ panelSearch = viewChild('panelSearch', /* @ts-ignore */
248
+ ...(ngDevMode ? [{ debugName: "panelSearch" }] : /* istanbul ignore next */ []));
249
+ options = contentChildren(PillboxOptionComponent, { ...(ngDevMode ? { debugName: "options" } : /* istanbul ignore next */ {}), descendants: true });
250
+ createOptions = contentChildren(PillboxOptionCreateComponent, { ...(ngDevMode ? { debugName: "createOptions" } : /* istanbul ignore next */ {}), descendants: true });
251
+ emptyOptions = contentChildren(PillboxOptionEmptyComponent, { ...(ngDevMode ? { debugName: "emptyOptions" } : /* istanbul ignore next */ {}), descendants: true });
252
+ removeDocumentListener = null;
253
+ onChange = () => { };
254
+ onTouched = () => { };
255
+ panelId = `${this.generatedId}-panel`;
256
+ resolvedId = computed(() => this.id() ?? this.generatedId, /* @ts-ignore */
257
+ ...(ngDevMode ? [{ debugName: "resolvedId" }] : /* istanbul ignore next */ []));
258
+ disabledState = computed(() => this.disabled() || this.disabledFromControl(), /* @ts-ignore */
259
+ ...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
260
+ classes = computed(() => cn('relative block w-full min-w-0 text-sm text-foreground', this.class()), /* @ts-ignore */
261
+ ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
262
+ triggerClasses = computed(() => cn('flex w-full min-w-0 cursor-default items-center gap-2 rounded-md border border-input bg-background shadow-sm transition-colors', 'focus-within:outline-none focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:ring-offset-background', 'hover:bg-accent/20', pillboxTriggerSizeClasses[this.size()], this.invalid() ? 'border-destructive ring-1 ring-destructive' : '', this.disabledState() ? 'pointer-events-none cursor-not-allowed opacity-50' : ''), /* @ts-ignore */
263
+ ...(ngDevMode ? [{ debugName: "triggerClasses" }] : /* istanbul ignore next */ []));
264
+ pillClasses = computed(() => cn('inline-flex max-w-full shrink-0 items-center gap-1 rounded-md border border-border bg-muted font-medium text-muted-foreground', pillboxPillSizeClasses[this.size()]), /* @ts-ignore */
265
+ ...(ngDevMode ? [{ debugName: "pillClasses" }] : /* istanbul ignore next */ []));
266
+ panelClasses = computed(() => cn('absolute left-0 right-0 z-50 mt-1 overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md', 'min-w-full'), /* @ts-ignore */
267
+ ...(ngDevMode ? [{ debugName: "panelClasses" }] : /* istanbul ignore next */ []));
268
+ selectedItems = computed(() => this.selectedValues().map((value) => {
269
+ const option = this.findOption(value);
270
+ return {
271
+ value,
272
+ label: option?.pillLabel() || String(value),
273
+ template: option?.pillTemplate() ?? null,
274
+ // Track by the option value (selected values are unique) so removing a
275
+ // middle pill doesn't recreate the DOM of every pill after it.
276
+ track: value,
277
+ };
278
+ }), /* @ts-ignore */
279
+ ...(ngDevMode ? [{ debugName: "selectedItems" }] : /* istanbul ignore next */ []));
280
+ constructor() {
281
+ super();
282
+ this.destroyRef.onDestroy(() => this.removeOutsideListener());
283
+ }
284
+ optionVisible(option) {
285
+ if (!this.filter() || !option.filterable()) {
286
+ return true;
287
+ }
288
+ const query = this.query().trim().toLowerCase();
289
+ if (!query) {
290
+ return true;
291
+ }
292
+ return option.textLabel().toLowerCase().includes(query);
293
+ }
294
+ optionSelected(option) {
295
+ return this.hasValue(option.value());
296
+ }
297
+ chooseOption(option, event) {
298
+ event.preventDefault();
299
+ event.stopPropagation();
300
+ if (this.disabledState() || option.disabled()) {
301
+ return;
302
+ }
303
+ if (this.multiple()) {
304
+ const value = option.value();
305
+ this.selectedValues.update((values) => values.some((entry) => this.sameValue(entry, value))
306
+ ? values.filter((entry) => !this.sameValue(entry, value))
307
+ : [...values, value]);
308
+ }
309
+ else {
310
+ this.selectedValues.set([option.value()]);
311
+ this.close();
312
+ }
313
+ option.selectedChange.emit(option.value());
314
+ this.query.set('');
315
+ this.emitValue();
316
+ }
317
+ createVisible(option) {
318
+ const query = this.query().trim();
319
+ if (option.disabled() || query.length < option.minLength()) {
320
+ return false;
321
+ }
322
+ return !this.options().some((entry) => entry.textLabel().trim().toLowerCase() === query.toLowerCase());
323
+ }
324
+ chooseCreate(option, event) {
325
+ event.preventDefault();
326
+ event.stopPropagation();
327
+ const query = this.query().trim();
328
+ if (this.disabledState() || option.disabled() || !this.createVisible(option)) {
329
+ return;
330
+ }
331
+ option.selected.emit(query);
332
+ this.create.emit(query);
333
+ }
334
+ emptyVisible() {
335
+ return this.options().length > 0 && !this.hasVisibleOptions() && !this.hasVisibleCreateOption();
336
+ }
337
+ emptyMessage() {
338
+ const customEmptyOption = this.emptyOptions()[0];
339
+ if (this.loading()) {
340
+ return customEmptyOption?.whenLoading() || this.loadingText();
341
+ }
342
+ return customEmptyOption ? '' : this.emptyText();
343
+ }
344
+ handleTriggerClick() {
345
+ this.open();
346
+ }
347
+ handleTriggerKeydown(event) {
348
+ if (this.disabledState()) {
349
+ return;
350
+ }
351
+ event.preventDefault();
352
+ this.open();
353
+ }
354
+ handleSearchInput(event) {
355
+ const inputElement = event.target;
356
+ this.query.set(inputElement.value);
357
+ this.searchChange.emit(inputElement.value);
358
+ this.open();
359
+ }
360
+ handleInlineBackspace(event) {
361
+ if (event.target.value.length > 0 || this.selectedValues().length === 0) {
362
+ return;
363
+ }
364
+ event.preventDefault();
365
+ this.selectedValues.update((values) => values.slice(0, -1));
366
+ this.emitValue();
367
+ }
368
+ clearSearch(event) {
369
+ event.preventDefault();
370
+ event.stopPropagation();
371
+ this.query.set('');
372
+ this.searchChange.emit('');
373
+ this.focusSearchInput();
374
+ }
375
+ clear(event) {
376
+ event.preventDefault();
377
+ event.stopPropagation();
378
+ this.selectedValues.set([]);
379
+ this.emitValue();
380
+ }
381
+ removeSelected(value, event) {
382
+ event.preventDefault();
383
+ event.stopPropagation();
384
+ this.selectedValues.update((values) => values.filter((entry) => !this.sameValue(entry, value)));
385
+ this.emitValue();
386
+ }
387
+ open() {
388
+ if (this.disabledState() || this.openState()) {
389
+ return;
390
+ }
391
+ this.openState.set(true);
392
+ this.openedChange.emit(true);
393
+ queueMicrotask(() => {
394
+ this.focusSearchInput();
395
+ this.bindOutsideListener();
396
+ });
397
+ }
398
+ close() {
399
+ if (!this.openState()) {
400
+ return;
401
+ }
402
+ this.openState.set(false);
403
+ this.openedChange.emit(false);
404
+ this.removeOutsideListener();
405
+ this.onTouched();
406
+ }
407
+ focus() {
408
+ this.trigger().nativeElement.focus();
409
+ }
410
+ writeValue(value) {
411
+ if (this.multiple()) {
412
+ this.selectedValues.set(Array.isArray(value) ? value : []);
413
+ return;
414
+ }
415
+ this.selectedValues.set(value === null || value === undefined ? [] : [value]);
416
+ }
417
+ registerOnChange(fn) {
418
+ this.onChange = fn;
419
+ }
420
+ registerOnTouched(fn) {
421
+ this.onTouched = fn;
422
+ }
423
+ setDisabledState(disabled) {
424
+ this.disabledFromControl.set(disabled);
425
+ }
426
+ emitValue() {
427
+ const nextValue = this.multiple() ? [...this.selectedValues()] : (this.selectedValues()[0] ?? null);
428
+ this.onChange(nextValue);
429
+ this.valueChange.emit(nextValue);
430
+ }
431
+ hasValue(value) {
432
+ return this.selectedValues().some((entry) => this.sameValue(entry, value));
433
+ }
434
+ findOption(value) {
435
+ return this.options().find((option) => this.sameValue(option.value(), value));
436
+ }
437
+ hasVisibleOptions() {
438
+ return this.options().some((option) => this.optionVisible(option));
439
+ }
440
+ hasVisibleCreateOption() {
441
+ return this.createOptions().some((option) => this.createVisible(option));
442
+ }
443
+ sameValue(left, right) {
444
+ return Object.is(left, right);
445
+ }
446
+ focusSearchInput() {
447
+ const searchInput = this.variant() === 'combobox' ? this.inlineSearch()?.nativeElement : this.panelSearch()?.nativeElement;
448
+ searchInput?.focus();
449
+ }
450
+ bindOutsideListener() {
451
+ this.removeOutsideListener();
452
+ const listener = (event) => {
453
+ if (!this.element.nativeElement.contains(event.target)) {
454
+ this.close();
455
+ }
456
+ };
457
+ this.document.addEventListener('pointerdown', listener, true);
458
+ this.removeDocumentListener = () => this.document.removeEventListener('pointerdown', listener, true);
459
+ }
460
+ removeOutsideListener() {
461
+ this.removeDocumentListener?.();
462
+ this.removeDocumentListener = null;
463
+ }
464
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PillboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
465
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: PillboxComponent, isStandalone: true, selector: "Pillbox", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, loadingText: { classPropertyName: "loadingText", publicName: "loadingText", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", searchChange: "searchChange", create: "create", openedChange: "openedChange" }, host: { properties: { "class": "classes()", "attr.data-slot": "\"pillbox\"", "attr.data-open": "openState() ? \"\" : null", "attr.data-size": "size()", "attr.data-variant": "variant()" } }, providers: [
466
+ { provide: PillboxContext, useExisting: forwardRef(() => PillboxComponent) },
467
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => PillboxComponent), multi: true },
468
+ ], queries: [{ propertyName: "options", predicate: PillboxOptionComponent, descendants: true, isSignal: true }, { propertyName: "createOptions", predicate: PillboxOptionCreateComponent, descendants: true, isSignal: true }, { propertyName: "emptyOptions", predicate: PillboxOptionEmptyComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "inlineSearch", first: true, predicate: ["inlineSearch"], descendants: true, isSignal: true }, { propertyName: "panelSearch", first: true, predicate: ["panelSearch"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
469
+ <div
470
+ #trigger
471
+ [attr.id]="resolvedId()"
472
+ role="combobox"
473
+ aria-haspopup="listbox"
474
+ [attr.aria-expanded]="openState()"
475
+ [attr.aria-controls]="openState() ? panelId : null"
476
+ [attr.aria-label]="ariaLabel()"
477
+ [attr.aria-labelledby]="ariaLabelledby()"
478
+ [attr.aria-describedby]="ariaDescribedby()"
479
+ [attr.aria-invalid]="invalid() ? 'true' : null"
480
+ [attr.aria-disabled]="disabledState() ? 'true' : null"
481
+ [attr.tabindex]="disabledState() ? -1 : 0"
482
+ [class]="triggerClasses()"
483
+ (click)="handleTriggerClick()"
484
+ (keydown.enter)="handleTriggerKeydown($any($event))"
485
+ (keydown.space)="handleTriggerKeydown($any($event))"
486
+ (keydown.arrowDown)="handleTriggerKeydown($any($event))"
487
+ (keydown.escape)="close()">
488
+ <div class="flex min-w-0 flex-1 flex-wrap items-center gap-1.5">
489
+ @if (selectedItems().length > 0) {
490
+ @for (item of selectedItems(); track item.track) {
491
+ <span [class]="pillClasses()">
492
+ @if (item.template; as template) {
493
+ <span class="inline-flex min-w-0 max-w-40 items-center gap-1 truncate">
494
+ <ng-container *ngTemplateOutlet="template" />
495
+ </span>
496
+ } @else {
497
+ <span class="max-w-40 truncate">{{ item.label }}</span>
498
+ }
499
+ <button
500
+ type="button"
501
+ class="-mr-1 inline-flex size-4 items-center justify-center rounded-full text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
502
+ [attr.aria-label]="'Remove ' + item.label"
503
+ [disabled]="disabledState() || null"
504
+ (click)="removeSelected(item.value, $event)">
505
+ <svg
506
+ aria-hidden="true"
507
+ class="size-3"
508
+ viewBox="0 0 24 24"
509
+ fill="none"
510
+ stroke="currentColor"
511
+ stroke-width="2"
512
+ stroke-linecap="round"
513
+ stroke-linejoin="round">
514
+ <path d="M18 6 6 18" />
515
+ <path d="m6 6 12 12" />
516
+ </svg>
517
+ </button>
518
+ </span>
519
+ }
520
+ }
521
+
522
+ @if (variant() === 'combobox') {
523
+ <input
524
+ #inlineSearch
525
+ class="min-w-28 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed"
526
+ [placeholder]="selectedItems().length === 0 ? placeholder() : ''"
527
+ [value]="query()"
528
+ [disabled]="disabledState() || null"
529
+ (click)="$event.stopPropagation(); open()"
530
+ (focus)="open()"
531
+ (input)="handleSearchInput($event)"
532
+ (keydown.backspace)="handleInlineBackspace($any($event))"
533
+ (keydown.escape)="close()" />
534
+ } @else if (selectedItems().length === 0) {
535
+ <span class="truncate text-muted-foreground">{{ placeholder() }}</span>
536
+ }
537
+ </div>
538
+
539
+ @if (clearable() && selectedItems().length > 0 && !disabledState()) {
540
+ <button
541
+ type="button"
542
+ class="inline-flex size-5 shrink-0 items-center justify-center rounded-full text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
543
+ aria-label="Clear selected options"
544
+ (click)="clear($event)">
545
+ <svg
546
+ aria-hidden="true"
547
+ class="size-3.5"
548
+ viewBox="0 0 24 24"
549
+ fill="none"
550
+ stroke="currentColor"
551
+ stroke-width="2"
552
+ stroke-linecap="round"
553
+ stroke-linejoin="round">
554
+ <path d="M18 6 6 18" />
555
+ <path d="m6 6 12 12" />
556
+ </svg>
557
+ </button>
558
+ }
559
+
560
+ <svg
561
+ aria-hidden="true"
562
+ class="size-4 shrink-0 text-muted-foreground transition-transform"
563
+ [class.rotate-180]="openState()"
564
+ viewBox="0 0 24 24"
565
+ fill="none"
566
+ stroke="currentColor"
567
+ stroke-width="1.75"
568
+ stroke-linecap="round"
569
+ stroke-linejoin="round">
570
+ <path d="m6 9 6 6 6-6" />
571
+ </svg>
572
+ </div>
573
+
574
+ <div [attr.id]="panelId" [class]="panelClasses()" [hidden]="!openState()" role="listbox">
575
+ @if (searchable() && variant() !== 'combobox') {
576
+ <div class="border-b border-border p-2">
577
+ <div class="flex items-center gap-2 rounded-md border border-input bg-background px-2">
578
+ <svg
579
+ aria-hidden="true"
580
+ class="size-4 shrink-0 text-muted-foreground"
581
+ viewBox="0 0 24 24"
582
+ fill="none"
583
+ stroke="currentColor"
584
+ stroke-width="1.75"
585
+ stroke-linecap="round"
586
+ stroke-linejoin="round">
587
+ <circle cx="11" cy="11" r="8" />
588
+ <path d="m21 21-4.35-4.35" />
589
+ </svg>
590
+ <input
591
+ #panelSearch
592
+ class="h-9 min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
593
+ [placeholder]="searchPlaceholder()"
594
+ [value]="query()"
595
+ (input)="handleSearchInput($event)"
596
+ (keydown.escape)="close()" />
597
+ @if (query().length > 0) {
598
+ <button
599
+ type="button"
600
+ class="inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground"
601
+ aria-label="Clear search"
602
+ (click)="clearSearch($event)">
603
+ <svg
604
+ aria-hidden="true"
605
+ class="size-3.5"
606
+ viewBox="0 0 24 24"
607
+ fill="none"
608
+ stroke="currentColor"
609
+ stroke-width="2"
610
+ stroke-linecap="round"
611
+ stroke-linejoin="round">
612
+ <path d="M18 6 6 18" />
613
+ <path d="m6 6 12 12" />
614
+ </svg>
615
+ </button>
616
+ }
617
+ </div>
618
+ </div>
619
+ }
620
+
621
+ <div class="max-h-72 overflow-y-auto p-1">
622
+ <ng-content />
623
+ </div>
624
+ </div>
625
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
626
+ }
627
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PillboxComponent, decorators: [{
628
+ type: Component,
629
+ args: [{
630
+ selector: 'Pillbox',
631
+ changeDetection: ChangeDetectionStrategy.OnPush,
632
+ imports: [NgTemplateOutlet],
633
+ providers: [
634
+ { provide: PillboxContext, useExisting: forwardRef(() => PillboxComponent) },
635
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => PillboxComponent), multi: true },
636
+ ],
637
+ host: {
638
+ '[class]': 'classes()',
639
+ '[attr.data-slot]': '"pillbox"',
640
+ '[attr.data-open]': 'openState() ? "" : null',
641
+ '[attr.data-size]': 'size()',
642
+ '[attr.data-variant]': 'variant()',
643
+ },
644
+ template: `
645
+ <div
646
+ #trigger
647
+ [attr.id]="resolvedId()"
648
+ role="combobox"
649
+ aria-haspopup="listbox"
650
+ [attr.aria-expanded]="openState()"
651
+ [attr.aria-controls]="openState() ? panelId : null"
652
+ [attr.aria-label]="ariaLabel()"
653
+ [attr.aria-labelledby]="ariaLabelledby()"
654
+ [attr.aria-describedby]="ariaDescribedby()"
655
+ [attr.aria-invalid]="invalid() ? 'true' : null"
656
+ [attr.aria-disabled]="disabledState() ? 'true' : null"
657
+ [attr.tabindex]="disabledState() ? -1 : 0"
658
+ [class]="triggerClasses()"
659
+ (click)="handleTriggerClick()"
660
+ (keydown.enter)="handleTriggerKeydown($any($event))"
661
+ (keydown.space)="handleTriggerKeydown($any($event))"
662
+ (keydown.arrowDown)="handleTriggerKeydown($any($event))"
663
+ (keydown.escape)="close()">
664
+ <div class="flex min-w-0 flex-1 flex-wrap items-center gap-1.5">
665
+ @if (selectedItems().length > 0) {
666
+ @for (item of selectedItems(); track item.track) {
667
+ <span [class]="pillClasses()">
668
+ @if (item.template; as template) {
669
+ <span class="inline-flex min-w-0 max-w-40 items-center gap-1 truncate">
670
+ <ng-container *ngTemplateOutlet="template" />
671
+ </span>
672
+ } @else {
673
+ <span class="max-w-40 truncate">{{ item.label }}</span>
674
+ }
675
+ <button
676
+ type="button"
677
+ class="-mr-1 inline-flex size-4 items-center justify-center rounded-full text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
678
+ [attr.aria-label]="'Remove ' + item.label"
679
+ [disabled]="disabledState() || null"
680
+ (click)="removeSelected(item.value, $event)">
681
+ <svg
682
+ aria-hidden="true"
683
+ class="size-3"
684
+ viewBox="0 0 24 24"
685
+ fill="none"
686
+ stroke="currentColor"
687
+ stroke-width="2"
688
+ stroke-linecap="round"
689
+ stroke-linejoin="round">
690
+ <path d="M18 6 6 18" />
691
+ <path d="m6 6 12 12" />
692
+ </svg>
693
+ </button>
694
+ </span>
695
+ }
696
+ }
697
+
698
+ @if (variant() === 'combobox') {
699
+ <input
700
+ #inlineSearch
701
+ class="min-w-28 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed"
702
+ [placeholder]="selectedItems().length === 0 ? placeholder() : ''"
703
+ [value]="query()"
704
+ [disabled]="disabledState() || null"
705
+ (click)="$event.stopPropagation(); open()"
706
+ (focus)="open()"
707
+ (input)="handleSearchInput($event)"
708
+ (keydown.backspace)="handleInlineBackspace($any($event))"
709
+ (keydown.escape)="close()" />
710
+ } @else if (selectedItems().length === 0) {
711
+ <span class="truncate text-muted-foreground">{{ placeholder() }}</span>
712
+ }
713
+ </div>
714
+
715
+ @if (clearable() && selectedItems().length > 0 && !disabledState()) {
716
+ <button
717
+ type="button"
718
+ class="inline-flex size-5 shrink-0 items-center justify-center rounded-full text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
719
+ aria-label="Clear selected options"
720
+ (click)="clear($event)">
721
+ <svg
722
+ aria-hidden="true"
723
+ class="size-3.5"
724
+ viewBox="0 0 24 24"
725
+ fill="none"
726
+ stroke="currentColor"
727
+ stroke-width="2"
728
+ stroke-linecap="round"
729
+ stroke-linejoin="round">
730
+ <path d="M18 6 6 18" />
731
+ <path d="m6 6 12 12" />
732
+ </svg>
733
+ </button>
734
+ }
735
+
736
+ <svg
737
+ aria-hidden="true"
738
+ class="size-4 shrink-0 text-muted-foreground transition-transform"
739
+ [class.rotate-180]="openState()"
740
+ viewBox="0 0 24 24"
741
+ fill="none"
742
+ stroke="currentColor"
743
+ stroke-width="1.75"
744
+ stroke-linecap="round"
745
+ stroke-linejoin="round">
746
+ <path d="m6 9 6 6 6-6" />
747
+ </svg>
748
+ </div>
749
+
750
+ <div [attr.id]="panelId" [class]="panelClasses()" [hidden]="!openState()" role="listbox">
751
+ @if (searchable() && variant() !== 'combobox') {
752
+ <div class="border-b border-border p-2">
753
+ <div class="flex items-center gap-2 rounded-md border border-input bg-background px-2">
754
+ <svg
755
+ aria-hidden="true"
756
+ class="size-4 shrink-0 text-muted-foreground"
757
+ viewBox="0 0 24 24"
758
+ fill="none"
759
+ stroke="currentColor"
760
+ stroke-width="1.75"
761
+ stroke-linecap="round"
762
+ stroke-linejoin="round">
763
+ <circle cx="11" cy="11" r="8" />
764
+ <path d="m21 21-4.35-4.35" />
765
+ </svg>
766
+ <input
767
+ #panelSearch
768
+ class="h-9 min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
769
+ [placeholder]="searchPlaceholder()"
770
+ [value]="query()"
771
+ (input)="handleSearchInput($event)"
772
+ (keydown.escape)="close()" />
773
+ @if (query().length > 0) {
774
+ <button
775
+ type="button"
776
+ class="inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground"
777
+ aria-label="Clear search"
778
+ (click)="clearSearch($event)">
779
+ <svg
780
+ aria-hidden="true"
781
+ class="size-3.5"
782
+ viewBox="0 0 24 24"
783
+ fill="none"
784
+ stroke="currentColor"
785
+ stroke-width="2"
786
+ stroke-linecap="round"
787
+ stroke-linejoin="round">
788
+ <path d="M18 6 6 18" />
789
+ <path d="m6 6 12 12" />
790
+ </svg>
791
+ </button>
792
+ }
793
+ </div>
794
+ </div>
795
+ }
796
+
797
+ <div class="max-h-72 overflow-y-auto p-1">
798
+ <ng-content />
799
+ </div>
800
+ </div>
801
+ `,
802
+ }]
803
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], loadingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingText", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-describedby", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], searchChange: [{ type: i0.Output, args: ["searchChange"] }], create: [{ type: i0.Output, args: ["create"] }], openedChange: [{ type: i0.Output, args: ["openedChange"] }], trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], inlineSearch: [{ type: i0.ViewChild, args: ['inlineSearch', { isSignal: true }] }], panelSearch: [{ type: i0.ViewChild, args: ['panelSearch', { isSignal: true }] }], options: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => PillboxOptionComponent), { ...{ descendants: true }, isSignal: true }] }], createOptions: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => PillboxOptionCreateComponent), { ...{ descendants: true }, isSignal: true }] }], emptyOptions: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => PillboxOptionEmptyComponent), { ...{ descendants: true }, isSignal: true }] }] } });
804
+
805
+ /**
806
+ * Generated bundle index. Do not edit.
807
+ */
808
+
809
+ export { PillboxComponent, PillboxOptionComponent, PillboxOptionCreateComponent, PillboxOptionEmptyComponent, PillboxSelectedDirective };
810
+ //# sourceMappingURL=ojiepermana-angular-component-pillbox.mjs.map