@atomng/ui 1.0.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 (299) hide show
  1. package/README.md +401 -0
  2. package/atomng-ui.d.ts.map +1 -0
  3. package/atoms/atomng-ui-atoms.d.ts.map +1 -0
  4. package/atoms/avatar/avatar.component.d.ts +24 -0
  5. package/atoms/avatar/avatar.component.d.ts.map +1 -0
  6. package/atoms/avatar/index.d.ts +3 -0
  7. package/atoms/avatar/index.d.ts.map +1 -0
  8. package/atoms/badge/badge.component.d.ts +23 -0
  9. package/atoms/badge/badge.component.d.ts.map +1 -0
  10. package/atoms/badge/index.d.ts +3 -0
  11. package/atoms/badge/index.d.ts.map +1 -0
  12. package/atoms/button/button.component.d.ts +47 -0
  13. package/atoms/button/button.component.d.ts.map +1 -0
  14. package/atoms/button/index.d.ts +3 -0
  15. package/atoms/button/index.d.ts.map +1 -0
  16. package/atoms/checkbox/checkbox.component.d.ts +28 -0
  17. package/atoms/checkbox/checkbox.component.d.ts.map +1 -0
  18. package/atoms/checkbox/index.d.ts +2 -0
  19. package/atoms/checkbox/index.d.ts.map +1 -0
  20. package/atoms/chip/chip.component.d.ts +17 -0
  21. package/atoms/chip/chip.component.d.ts.map +1 -0
  22. package/atoms/chip/index.d.ts +2 -0
  23. package/atoms/chip/index.d.ts.map +1 -0
  24. package/atoms/index.d.ts +14 -0
  25. package/atoms/index.d.ts.map +1 -0
  26. package/atoms/kbd/index.d.ts +2 -0
  27. package/atoms/kbd/index.d.ts.map +1 -0
  28. package/atoms/kbd/kbd.component.d.ts +14 -0
  29. package/atoms/kbd/kbd.component.d.ts.map +1 -0
  30. package/atoms/link/index.d.ts +2 -0
  31. package/atoms/link/index.d.ts.map +1 -0
  32. package/atoms/link/link.component.d.ts +15 -0
  33. package/atoms/link/link.component.d.ts.map +1 -0
  34. package/atoms/progress/index.d.ts +3 -0
  35. package/atoms/progress/index.d.ts.map +1 -0
  36. package/atoms/progress/progress.component.d.ts +20 -0
  37. package/atoms/progress/progress.component.d.ts.map +1 -0
  38. package/atoms/separator/index.d.ts +2 -0
  39. package/atoms/separator/index.d.ts.map +1 -0
  40. package/atoms/separator/separator.component.d.ts +13 -0
  41. package/atoms/separator/separator.component.d.ts.map +1 -0
  42. package/atoms/skeleton/index.d.ts +2 -0
  43. package/atoms/skeleton/index.d.ts.map +1 -0
  44. package/atoms/skeleton/skeleton.component.d.ts +13 -0
  45. package/atoms/skeleton/skeleton.component.d.ts.map +1 -0
  46. package/atoms/slider/index.d.ts +2 -0
  47. package/atoms/slider/index.d.ts.map +1 -0
  48. package/atoms/slider/slider.component.d.ts +27 -0
  49. package/atoms/slider/slider.component.d.ts.map +1 -0
  50. package/atoms/switch/index.d.ts +2 -0
  51. package/atoms/switch/index.d.ts.map +1 -0
  52. package/atoms/switch/switch.component.d.ts +25 -0
  53. package/atoms/switch/switch.component.d.ts.map +1 -0
  54. package/atoms/tooltip/index.d.ts +2 -0
  55. package/atoms/tooltip/index.d.ts.map +1 -0
  56. package/atoms/tooltip/tooltip.component.d.ts +15 -0
  57. package/atoms/tooltip/tooltip.component.d.ts.map +1 -0
  58. package/fesm2022/atomng-ui-atoms.mjs +778 -0
  59. package/fesm2022/atomng-ui-atoms.mjs.map +1 -0
  60. package/fesm2022/atomng-ui-molecules.mjs +1590 -0
  61. package/fesm2022/atomng-ui-molecules.mjs.map +1 -0
  62. package/fesm2022/atomng-ui-organisms.mjs +1346 -0
  63. package/fesm2022/atomng-ui-organisms.mjs.map +1 -0
  64. package/fesm2022/atomng-ui-tokens.mjs +499 -0
  65. package/fesm2022/atomng-ui-tokens.mjs.map +1 -0
  66. package/fesm2022/atomng-ui.mjs +4184 -0
  67. package/fesm2022/atomng-ui.mjs.map +1 -0
  68. package/index.d.ts +5 -0
  69. package/index.d.ts.map +1 -0
  70. package/lib/atoms/avatar/avatar.component.d.ts +24 -0
  71. package/lib/atoms/avatar/avatar.component.d.ts.map +1 -0
  72. package/lib/atoms/avatar/index.d.ts +3 -0
  73. package/lib/atoms/avatar/index.d.ts.map +1 -0
  74. package/lib/atoms/badge/badge.component.d.ts +23 -0
  75. package/lib/atoms/badge/badge.component.d.ts.map +1 -0
  76. package/lib/atoms/badge/index.d.ts +3 -0
  77. package/lib/atoms/badge/index.d.ts.map +1 -0
  78. package/lib/atoms/button/button.component.d.ts +47 -0
  79. package/lib/atoms/button/button.component.d.ts.map +1 -0
  80. package/lib/atoms/button/index.d.ts +3 -0
  81. package/lib/atoms/button/index.d.ts.map +1 -0
  82. package/lib/atoms/checkbox/checkbox.component.d.ts +28 -0
  83. package/lib/atoms/checkbox/checkbox.component.d.ts.map +1 -0
  84. package/lib/atoms/checkbox/index.d.ts +2 -0
  85. package/lib/atoms/checkbox/index.d.ts.map +1 -0
  86. package/lib/atoms/chip/chip.component.d.ts +17 -0
  87. package/lib/atoms/chip/chip.component.d.ts.map +1 -0
  88. package/lib/atoms/chip/index.d.ts +2 -0
  89. package/lib/atoms/chip/index.d.ts.map +1 -0
  90. package/lib/atoms/index.d.ts +14 -0
  91. package/lib/atoms/index.d.ts.map +1 -0
  92. package/lib/atoms/kbd/index.d.ts +2 -0
  93. package/lib/atoms/kbd/index.d.ts.map +1 -0
  94. package/lib/atoms/kbd/kbd.component.d.ts +14 -0
  95. package/lib/atoms/kbd/kbd.component.d.ts.map +1 -0
  96. package/lib/atoms/link/index.d.ts +2 -0
  97. package/lib/atoms/link/index.d.ts.map +1 -0
  98. package/lib/atoms/link/link.component.d.ts +15 -0
  99. package/lib/atoms/link/link.component.d.ts.map +1 -0
  100. package/lib/atoms/progress/index.d.ts +3 -0
  101. package/lib/atoms/progress/index.d.ts.map +1 -0
  102. package/lib/atoms/progress/progress.component.d.ts +20 -0
  103. package/lib/atoms/progress/progress.component.d.ts.map +1 -0
  104. package/lib/atoms/separator/index.d.ts +2 -0
  105. package/lib/atoms/separator/index.d.ts.map +1 -0
  106. package/lib/atoms/separator/separator.component.d.ts +13 -0
  107. package/lib/atoms/separator/separator.component.d.ts.map +1 -0
  108. package/lib/atoms/skeleton/index.d.ts +2 -0
  109. package/lib/atoms/skeleton/index.d.ts.map +1 -0
  110. package/lib/atoms/skeleton/skeleton.component.d.ts +13 -0
  111. package/lib/atoms/skeleton/skeleton.component.d.ts.map +1 -0
  112. package/lib/atoms/slider/index.d.ts +2 -0
  113. package/lib/atoms/slider/index.d.ts.map +1 -0
  114. package/lib/atoms/slider/slider.component.d.ts +27 -0
  115. package/lib/atoms/slider/slider.component.d.ts.map +1 -0
  116. package/lib/atoms/switch/index.d.ts +2 -0
  117. package/lib/atoms/switch/index.d.ts.map +1 -0
  118. package/lib/atoms/switch/switch.component.d.ts +25 -0
  119. package/lib/atoms/switch/switch.component.d.ts.map +1 -0
  120. package/lib/atoms/tooltip/index.d.ts +2 -0
  121. package/lib/atoms/tooltip/index.d.ts.map +1 -0
  122. package/lib/atoms/tooltip/tooltip.component.d.ts +15 -0
  123. package/lib/atoms/tooltip/tooltip.component.d.ts.map +1 -0
  124. package/lib/molecules/alert/alert.component.d.ts +22 -0
  125. package/lib/molecules/alert/alert.component.d.ts.map +1 -0
  126. package/lib/molecules/alert/index.d.ts +2 -0
  127. package/lib/molecules/alert/index.d.ts.map +1 -0
  128. package/lib/molecules/avatar-group/avatar-group.component.d.ts +22 -0
  129. package/lib/molecules/avatar-group/avatar-group.component.d.ts.map +1 -0
  130. package/lib/molecules/avatar-group/index.d.ts +2 -0
  131. package/lib/molecules/avatar-group/index.d.ts.map +1 -0
  132. package/lib/molecules/breadcrumb/breadcrumb.component.d.ts +17 -0
  133. package/lib/molecules/breadcrumb/breadcrumb.component.d.ts.map +1 -0
  134. package/lib/molecules/breadcrumb/index.d.ts +2 -0
  135. package/lib/molecules/breadcrumb/index.d.ts.map +1 -0
  136. package/lib/molecules/button-group/button-group.component.d.ts +11 -0
  137. package/lib/molecules/button-group/button-group.component.d.ts.map +1 -0
  138. package/lib/molecules/button-group/index.d.ts +2 -0
  139. package/lib/molecules/button-group/index.d.ts.map +1 -0
  140. package/lib/molecules/form-field/form-field.component.d.ts +18 -0
  141. package/lib/molecules/form-field/form-field.component.d.ts.map +1 -0
  142. package/lib/molecules/form-field/index.d.ts +2 -0
  143. package/lib/molecules/form-field/index.d.ts.map +1 -0
  144. package/lib/molecules/index.d.ts +13 -0
  145. package/lib/molecules/index.d.ts.map +1 -0
  146. package/lib/molecules/input/index.d.ts +2 -0
  147. package/lib/molecules/input/index.d.ts.map +1 -0
  148. package/lib/molecules/input/input.component.d.ts +50 -0
  149. package/lib/molecules/input/input.component.d.ts.map +1 -0
  150. package/lib/molecules/pagination/index.d.ts +2 -0
  151. package/lib/molecules/pagination/index.d.ts.map +1 -0
  152. package/lib/molecules/pagination/pagination.component.d.ts +18 -0
  153. package/lib/molecules/pagination/pagination.component.d.ts.map +1 -0
  154. package/lib/molecules/select/index.d.ts +3 -0
  155. package/lib/molecules/select/index.d.ts.map +1 -0
  156. package/lib/molecules/select/select.component.d.ts +56 -0
  157. package/lib/molecules/select/select.component.d.ts.map +1 -0
  158. package/lib/molecules/select-search/index.d.ts +2 -0
  159. package/lib/molecules/select-search/index.d.ts.map +1 -0
  160. package/lib/molecules/select-search/select-search.component.d.ts +63 -0
  161. package/lib/molecules/select-search/select-search.component.d.ts.map +1 -0
  162. package/lib/molecules/tabs/index.d.ts +2 -0
  163. package/lib/molecules/tabs/index.d.ts.map +1 -0
  164. package/lib/molecules/tabs/tabs.component.d.ts +23 -0
  165. package/lib/molecules/tabs/tabs.component.d.ts.map +1 -0
  166. package/lib/molecules/textarea/index.d.ts +2 -0
  167. package/lib/molecules/textarea/index.d.ts.map +1 -0
  168. package/lib/molecules/textarea/textarea.component.d.ts +27 -0
  169. package/lib/molecules/textarea/textarea.component.d.ts.map +1 -0
  170. package/lib/molecules/toast/index.d.ts +2 -0
  171. package/lib/molecules/toast/index.d.ts.map +1 -0
  172. package/lib/molecules/toast/toast.component.d.ts +19 -0
  173. package/lib/molecules/toast/toast.component.d.ts.map +1 -0
  174. package/lib/organisms/accordion/accordion.component.d.ts +25 -0
  175. package/lib/organisms/accordion/accordion.component.d.ts.map +1 -0
  176. package/lib/organisms/card/card.component.d.ts +14 -0
  177. package/lib/organisms/card/card.component.d.ts.map +1 -0
  178. package/lib/organisms/dropdown-menu/dropdown-menu.component.d.ts +29 -0
  179. package/lib/organisms/dropdown-menu/dropdown-menu.component.d.ts.map +1 -0
  180. package/lib/organisms/index.d.ts +8 -0
  181. package/lib/organisms/index.d.ts.map +1 -0
  182. package/lib/organisms/modal/modal.component.d.ts +19 -0
  183. package/lib/organisms/modal/modal.component.d.ts.map +1 -0
  184. package/lib/organisms/navigation-menu/navigation-menu.component.d.ts +24 -0
  185. package/lib/organisms/navigation-menu/navigation-menu.component.d.ts.map +1 -0
  186. package/lib/organisms/sidebar/sidebar.component.d.ts +68 -0
  187. package/lib/organisms/sidebar/sidebar.component.d.ts.map +1 -0
  188. package/lib/organisms/table/index.d.ts +3 -0
  189. package/lib/organisms/table/index.d.ts.map +1 -0
  190. package/lib/organisms/table/table-cell.directive.d.ts +17 -0
  191. package/lib/organisms/table/table-cell.directive.d.ts.map +1 -0
  192. package/lib/organisms/table/table.component.d.ts +50 -0
  193. package/lib/organisms/table/table.component.d.ts.map +1 -0
  194. package/lib/tokens/index.d.ts +2 -0
  195. package/lib/tokens/index.d.ts.map +1 -0
  196. package/lib/tokens/theme/color-presets.d.ts +24 -0
  197. package/lib/tokens/theme/color-presets.d.ts.map +1 -0
  198. package/lib/tokens/theme/index.d.ts +6 -0
  199. package/lib/tokens/theme/index.d.ts.map +1 -0
  200. package/lib/tokens/theme/theme-picker.component.d.ts +11 -0
  201. package/lib/tokens/theme/theme-picker.component.d.ts.map +1 -0
  202. package/lib/tokens/theme/theme-toggle.component.d.ts +15 -0
  203. package/lib/tokens/theme/theme-toggle.component.d.ts.map +1 -0
  204. package/lib/tokens/theme/theme.provider.d.ts +4 -0
  205. package/lib/tokens/theme/theme.provider.d.ts.map +1 -0
  206. package/lib/tokens/theme/theme.service.d.ts +48 -0
  207. package/lib/tokens/theme/theme.service.d.ts.map +1 -0
  208. package/molecules/alert/alert.component.d.ts +22 -0
  209. package/molecules/alert/alert.component.d.ts.map +1 -0
  210. package/molecules/alert/index.d.ts +2 -0
  211. package/molecules/alert/index.d.ts.map +1 -0
  212. package/molecules/atomng-ui-molecules.d.ts.map +1 -0
  213. package/molecules/avatar-group/avatar-group.component.d.ts +22 -0
  214. package/molecules/avatar-group/avatar-group.component.d.ts.map +1 -0
  215. package/molecules/avatar-group/index.d.ts +2 -0
  216. package/molecules/avatar-group/index.d.ts.map +1 -0
  217. package/molecules/breadcrumb/breadcrumb.component.d.ts +17 -0
  218. package/molecules/breadcrumb/breadcrumb.component.d.ts.map +1 -0
  219. package/molecules/breadcrumb/index.d.ts +2 -0
  220. package/molecules/breadcrumb/index.d.ts.map +1 -0
  221. package/molecules/button-group/button-group.component.d.ts +11 -0
  222. package/molecules/button-group/button-group.component.d.ts.map +1 -0
  223. package/molecules/button-group/index.d.ts +2 -0
  224. package/molecules/button-group/index.d.ts.map +1 -0
  225. package/molecules/form-field/form-field.component.d.ts +18 -0
  226. package/molecules/form-field/form-field.component.d.ts.map +1 -0
  227. package/molecules/form-field/index.d.ts +2 -0
  228. package/molecules/form-field/index.d.ts.map +1 -0
  229. package/molecules/index.d.ts +13 -0
  230. package/molecules/index.d.ts.map +1 -0
  231. package/molecules/input/index.d.ts +2 -0
  232. package/molecules/input/index.d.ts.map +1 -0
  233. package/molecules/input/input.component.d.ts +50 -0
  234. package/molecules/input/input.component.d.ts.map +1 -0
  235. package/molecules/pagination/index.d.ts +2 -0
  236. package/molecules/pagination/index.d.ts.map +1 -0
  237. package/molecules/pagination/pagination.component.d.ts +18 -0
  238. package/molecules/pagination/pagination.component.d.ts.map +1 -0
  239. package/molecules/select/index.d.ts +3 -0
  240. package/molecules/select/index.d.ts.map +1 -0
  241. package/molecules/select/select.component.d.ts +56 -0
  242. package/molecules/select/select.component.d.ts.map +1 -0
  243. package/molecules/select-search/index.d.ts +2 -0
  244. package/molecules/select-search/index.d.ts.map +1 -0
  245. package/molecules/select-search/select-search.component.d.ts +63 -0
  246. package/molecules/select-search/select-search.component.d.ts.map +1 -0
  247. package/molecules/tabs/index.d.ts +2 -0
  248. package/molecules/tabs/index.d.ts.map +1 -0
  249. package/molecules/tabs/tabs.component.d.ts +23 -0
  250. package/molecules/tabs/tabs.component.d.ts.map +1 -0
  251. package/molecules/textarea/index.d.ts +2 -0
  252. package/molecules/textarea/index.d.ts.map +1 -0
  253. package/molecules/textarea/textarea.component.d.ts +27 -0
  254. package/molecules/textarea/textarea.component.d.ts.map +1 -0
  255. package/molecules/toast/index.d.ts +2 -0
  256. package/molecules/toast/index.d.ts.map +1 -0
  257. package/molecules/toast/toast.component.d.ts +19 -0
  258. package/molecules/toast/toast.component.d.ts.map +1 -0
  259. package/organisms/accordion/accordion.component.d.ts +25 -0
  260. package/organisms/accordion/accordion.component.d.ts.map +1 -0
  261. package/organisms/atomng-ui-organisms.d.ts.map +1 -0
  262. package/organisms/card/card.component.d.ts +14 -0
  263. package/organisms/card/card.component.d.ts.map +1 -0
  264. package/organisms/dropdown-menu/dropdown-menu.component.d.ts +29 -0
  265. package/organisms/dropdown-menu/dropdown-menu.component.d.ts.map +1 -0
  266. package/organisms/index.d.ts +8 -0
  267. package/organisms/index.d.ts.map +1 -0
  268. package/organisms/modal/modal.component.d.ts +19 -0
  269. package/organisms/modal/modal.component.d.ts.map +1 -0
  270. package/organisms/navigation-menu/navigation-menu.component.d.ts +24 -0
  271. package/organisms/navigation-menu/navigation-menu.component.d.ts.map +1 -0
  272. package/organisms/sidebar/sidebar.component.d.ts +68 -0
  273. package/organisms/sidebar/sidebar.component.d.ts.map +1 -0
  274. package/organisms/table/index.d.ts +3 -0
  275. package/organisms/table/index.d.ts.map +1 -0
  276. package/organisms/table/table-cell.directive.d.ts +17 -0
  277. package/organisms/table/table-cell.directive.d.ts.map +1 -0
  278. package/organisms/table/table.component.d.ts +50 -0
  279. package/organisms/table/table.component.d.ts.map +1 -0
  280. package/package.json +81 -0
  281. package/tokens/_colors.scss +150 -0
  282. package/tokens/_spacing.scss +98 -0
  283. package/tokens/_typography.scss +59 -0
  284. package/tokens/atomng-ui-tokens.d.ts.map +1 -0
  285. package/tokens/index.d.ts +2 -0
  286. package/tokens/index.d.ts.map +1 -0
  287. package/tokens/index.scss +8 -0
  288. package/tokens/theme/color-presets.d.ts +24 -0
  289. package/tokens/theme/color-presets.d.ts.map +1 -0
  290. package/tokens/theme/index.d.ts +6 -0
  291. package/tokens/theme/index.d.ts.map +1 -0
  292. package/tokens/theme/theme-picker.component.d.ts +11 -0
  293. package/tokens/theme/theme-picker.component.d.ts.map +1 -0
  294. package/tokens/theme/theme-toggle.component.d.ts +15 -0
  295. package/tokens/theme/theme-toggle.component.d.ts.map +1 -0
  296. package/tokens/theme/theme.provider.d.ts +4 -0
  297. package/tokens/theme/theme.provider.d.ts.map +1 -0
  298. package/tokens/theme/theme.service.d.ts +48 -0
  299. package/tokens/theme/theme.service.d.ts.map +1 -0
@@ -0,0 +1,1590 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, output, ChangeDetectionStrategy, Component, model, forwardRef, computed, signal, HostListener, ViewChild } from '@angular/core';
3
+ import { CommonModule } from '@angular/common';
4
+ import { AvatarComponent } from '@atomng/ui/atoms';
5
+ import * as i1 from '@angular/router';
6
+ import { RouterModule } from '@angular/router';
7
+ import * as i1$1 from '@angular/forms';
8
+ import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
9
+ import { trigger, transition, style, animate } from '@angular/animations';
10
+
11
+ /**
12
+ * Alert Molecule — Source: Nuxt UI v3 ❖ Alert
13
+ * Contextual messages with icon, title, description, actions
14
+ * Built from: icon (atom) + content + optional close button
15
+ */
16
+ class AlertComponent {
17
+ constructor() {
18
+ this.variant = input('soft');
19
+ this.color = input('info');
20
+ this.title = input(null);
21
+ this.description = input(null);
22
+ this.icon = input(true);
23
+ this.closable = input(false);
24
+ this.actions = input(false);
25
+ this.live = input('polite');
26
+ this.close = output();
27
+ }
28
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: AlertComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
29
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: AlertComponent, isStandalone: true, selector: "ui-alert", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, live: { classPropertyName: "live", publicName: "live", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close" }, ngImport: i0, template: `
30
+ <div [class]="'ui-alert ui-alert--' + variant() + ' ui-alert--' + color()"
31
+ role="alert" [attr.aria-live]="live()">
32
+ @if (icon()) {
33
+ <span class="ui-alert__icon" aria-hidden="true">
34
+ <ng-content select="[slot=icon]" />
35
+ </span>
36
+ }
37
+ <div class="ui-alert__body">
38
+ @if (title()) {
39
+ <p class="ui-alert__title">{{ title() }}</p>
40
+ }
41
+ @if (description()) {
42
+ <p class="ui-alert__description">{{ description() }}</p>
43
+ }
44
+ <ng-content />
45
+ @if (actions()) {
46
+ <div class="ui-alert__actions">
47
+ <ng-content select="[slot=actions]" />
48
+ </div>
49
+ }
50
+ </div>
51
+ @if (closable()) {
52
+ <button type="button" class="ui-alert__close" aria-label="Close" (click)="close.emit()">
53
+ <span aria-hidden="true">×</span>
54
+ </button>
55
+ }
56
+ </div>
57
+ `, isInline: true, styles: [".ui-alert{display:flex;align-items:flex-start;gap:var(--spacing-3);padding:var(--spacing-4);border-radius:var(--radius-lg);border:1px solid transparent}.ui-alert__icon{flex-shrink:0;width:1.25rem;height:1.25rem;margin-top:1px}.ui-alert__body{flex:1;min-width:0}.ui-alert__title{font-family:var(--font-sans);font-size:var(--text-sm);font-weight:var(--font-semibold);color:var(--color-text);margin:0 0 var(--spacing-1)}.ui-alert__description{font-family:var(--font-sans);font-size:var(--text-sm);color:var(--color-text-muted);margin:0}.ui-alert__actions{display:flex;gap:var(--spacing-2);margin-top:var(--spacing-3)}.ui-alert__close{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;cursor:pointer;border-radius:var(--radius-md);color:currentColor;opacity:.6;font-size:1.25rem;line-height:1}.ui-alert__close:hover{opacity:1}.ui-alert--primary.ui-alert--soft{background:color-mix(in srgb,var(--color-primary-500) 12%,transparent);border-color:color-mix(in srgb,var(--color-primary-500) 20%,transparent);color:var(--color-primary-700)}.ui-alert--primary.ui-alert--outline{background:transparent;border-color:var(--color-primary-500);color:var(--color-primary-700)}.ui-alert--primary.ui-alert--solid{background:var(--color-primary-500);color:#fff}.ui-alert--primary.ui-alert--subtle{background:color-mix(in srgb,var(--color-primary-500) 8%,transparent);border-color:transparent;color:var(--color-primary-700)}.ui-alert--success.ui-alert--soft{background:color-mix(in srgb,var(--color-success-500) 12%,transparent);border-color:color-mix(in srgb,var(--color-success-500) 20%,transparent);color:var(--color-success-700)}.ui-alert--success.ui-alert--outline{background:transparent;border-color:var(--color-success-500);color:var(--color-success-700)}.ui-alert--success.ui-alert--solid{background:var(--color-success-500);color:#fff}.ui-alert--success.ui-alert--subtle{background:color-mix(in srgb,var(--color-success-500) 8%,transparent);border-color:transparent;color:var(--color-success-700)}.ui-alert--warning.ui-alert--soft{background:color-mix(in srgb,var(--color-warning-500) 12%,transparent);border-color:color-mix(in srgb,var(--color-warning-500) 20%,transparent);color:var(--color-warning-700)}.ui-alert--warning.ui-alert--outline{background:transparent;border-color:var(--color-warning-500);color:var(--color-warning-700)}.ui-alert--warning.ui-alert--solid{background:var(--color-warning-500);color:#fff}.ui-alert--warning.ui-alert--subtle{background:color-mix(in srgb,var(--color-warning-500) 8%,transparent);border-color:transparent;color:var(--color-warning-700)}.ui-alert--error.ui-alert--soft{background:color-mix(in srgb,var(--color-error-500) 12%,transparent);border-color:color-mix(in srgb,var(--color-error-500) 20%,transparent);color:var(--color-error-700)}.ui-alert--error.ui-alert--outline{background:transparent;border-color:var(--color-error-500);color:var(--color-error-700)}.ui-alert--error.ui-alert--solid{background:var(--color-error-500);color:#fff}.ui-alert--error.ui-alert--subtle{background:color-mix(in srgb,var(--color-error-500) 8%,transparent);border-color:transparent;color:var(--color-error-700)}.ui-alert--info.ui-alert--soft{background:color-mix(in srgb,var(--color-info-500) 12%,transparent);border-color:color-mix(in srgb,var(--color-info-500) 20%,transparent);color:var(--color-info-700)}.ui-alert--info.ui-alert--outline{background:transparent;border-color:var(--color-info-500);color:var(--color-info-700)}.ui-alert--info.ui-alert--solid{background:var(--color-info-500);color:#fff}.ui-alert--info.ui-alert--subtle{background:color-mix(in srgb,var(--color-info-500) 8%,transparent);border-color:transparent;color:var(--color-info-700)}.ui-alert--neutral.ui-alert--soft{background:color-mix(in srgb,var(--color-neutral-500) 12%,transparent);border-color:color-mix(in srgb,var(--color-neutral-500) 20%,transparent);color:var(--color-neutral-700)}.ui-alert--neutral.ui-alert--outline{background:transparent;border-color:var(--color-neutral-500);color:var(--color-neutral-700)}.ui-alert--neutral.ui-alert--solid{background:var(--color-neutral-500);color:#fff}.ui-alert--neutral.ui-alert--subtle{background:color-mix(in srgb,var(--color-neutral-500) 8%,transparent);border-color:transparent;color:var(--color-neutral-700)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
58
+ }
59
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: AlertComponent, decorators: [{
60
+ type: Component,
61
+ args: [{ selector: 'ui-alert', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
62
+ <div [class]="'ui-alert ui-alert--' + variant() + ' ui-alert--' + color()"
63
+ role="alert" [attr.aria-live]="live()">
64
+ @if (icon()) {
65
+ <span class="ui-alert__icon" aria-hidden="true">
66
+ <ng-content select="[slot=icon]" />
67
+ </span>
68
+ }
69
+ <div class="ui-alert__body">
70
+ @if (title()) {
71
+ <p class="ui-alert__title">{{ title() }}</p>
72
+ }
73
+ @if (description()) {
74
+ <p class="ui-alert__description">{{ description() }}</p>
75
+ }
76
+ <ng-content />
77
+ @if (actions()) {
78
+ <div class="ui-alert__actions">
79
+ <ng-content select="[slot=actions]" />
80
+ </div>
81
+ }
82
+ </div>
83
+ @if (closable()) {
84
+ <button type="button" class="ui-alert__close" aria-label="Close" (click)="close.emit()">
85
+ <span aria-hidden="true">×</span>
86
+ </button>
87
+ }
88
+ </div>
89
+ `, styles: [".ui-alert{display:flex;align-items:flex-start;gap:var(--spacing-3);padding:var(--spacing-4);border-radius:var(--radius-lg);border:1px solid transparent}.ui-alert__icon{flex-shrink:0;width:1.25rem;height:1.25rem;margin-top:1px}.ui-alert__body{flex:1;min-width:0}.ui-alert__title{font-family:var(--font-sans);font-size:var(--text-sm);font-weight:var(--font-semibold);color:var(--color-text);margin:0 0 var(--spacing-1)}.ui-alert__description{font-family:var(--font-sans);font-size:var(--text-sm);color:var(--color-text-muted);margin:0}.ui-alert__actions{display:flex;gap:var(--spacing-2);margin-top:var(--spacing-3)}.ui-alert__close{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;cursor:pointer;border-radius:var(--radius-md);color:currentColor;opacity:.6;font-size:1.25rem;line-height:1}.ui-alert__close:hover{opacity:1}.ui-alert--primary.ui-alert--soft{background:color-mix(in srgb,var(--color-primary-500) 12%,transparent);border-color:color-mix(in srgb,var(--color-primary-500) 20%,transparent);color:var(--color-primary-700)}.ui-alert--primary.ui-alert--outline{background:transparent;border-color:var(--color-primary-500);color:var(--color-primary-700)}.ui-alert--primary.ui-alert--solid{background:var(--color-primary-500);color:#fff}.ui-alert--primary.ui-alert--subtle{background:color-mix(in srgb,var(--color-primary-500) 8%,transparent);border-color:transparent;color:var(--color-primary-700)}.ui-alert--success.ui-alert--soft{background:color-mix(in srgb,var(--color-success-500) 12%,transparent);border-color:color-mix(in srgb,var(--color-success-500) 20%,transparent);color:var(--color-success-700)}.ui-alert--success.ui-alert--outline{background:transparent;border-color:var(--color-success-500);color:var(--color-success-700)}.ui-alert--success.ui-alert--solid{background:var(--color-success-500);color:#fff}.ui-alert--success.ui-alert--subtle{background:color-mix(in srgb,var(--color-success-500) 8%,transparent);border-color:transparent;color:var(--color-success-700)}.ui-alert--warning.ui-alert--soft{background:color-mix(in srgb,var(--color-warning-500) 12%,transparent);border-color:color-mix(in srgb,var(--color-warning-500) 20%,transparent);color:var(--color-warning-700)}.ui-alert--warning.ui-alert--outline{background:transparent;border-color:var(--color-warning-500);color:var(--color-warning-700)}.ui-alert--warning.ui-alert--solid{background:var(--color-warning-500);color:#fff}.ui-alert--warning.ui-alert--subtle{background:color-mix(in srgb,var(--color-warning-500) 8%,transparent);border-color:transparent;color:var(--color-warning-700)}.ui-alert--error.ui-alert--soft{background:color-mix(in srgb,var(--color-error-500) 12%,transparent);border-color:color-mix(in srgb,var(--color-error-500) 20%,transparent);color:var(--color-error-700)}.ui-alert--error.ui-alert--outline{background:transparent;border-color:var(--color-error-500);color:var(--color-error-700)}.ui-alert--error.ui-alert--solid{background:var(--color-error-500);color:#fff}.ui-alert--error.ui-alert--subtle{background:color-mix(in srgb,var(--color-error-500) 8%,transparent);border-color:transparent;color:var(--color-error-700)}.ui-alert--info.ui-alert--soft{background:color-mix(in srgb,var(--color-info-500) 12%,transparent);border-color:color-mix(in srgb,var(--color-info-500) 20%,transparent);color:var(--color-info-700)}.ui-alert--info.ui-alert--outline{background:transparent;border-color:var(--color-info-500);color:var(--color-info-700)}.ui-alert--info.ui-alert--solid{background:var(--color-info-500);color:#fff}.ui-alert--info.ui-alert--subtle{background:color-mix(in srgb,var(--color-info-500) 8%,transparent);border-color:transparent;color:var(--color-info-700)}.ui-alert--neutral.ui-alert--soft{background:color-mix(in srgb,var(--color-neutral-500) 12%,transparent);border-color:color-mix(in srgb,var(--color-neutral-500) 20%,transparent);color:var(--color-neutral-700)}.ui-alert--neutral.ui-alert--outline{background:transparent;border-color:var(--color-neutral-500);color:var(--color-neutral-700)}.ui-alert--neutral.ui-alert--solid{background:var(--color-neutral-500);color:#fff}.ui-alert--neutral.ui-alert--subtle{background:color-mix(in srgb,var(--color-neutral-500) 8%,transparent);border-color:transparent;color:var(--color-neutral-700)}\n"] }]
90
+ }] });
91
+
92
+ /**
93
+ * AvatarGroup Molecule — Source: Nuxt UI v3 ❖ AvatarGroup
94
+ * Stacked avatar list with overflow count
95
+ * Depends on: AvatarComponent (atom)
96
+ */
97
+ class AvatarGroupComponent {
98
+ constructor() {
99
+ this.items = input.required();
100
+ this.max = input(5);
101
+ this.size = input('md');
102
+ }
103
+ get visibleItems() { return () => this.items().slice(0, this.max()); }
104
+ get overflow() { return () => Math.max(0, this.items().length - this.max()); }
105
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: AvatarGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
106
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: AvatarGroupComponent, isStandalone: true, selector: "ui-avatar-group", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
107
+ <div class="ui-avatar-group" [attr.aria-label]="'Group of ' + items().length + ' avatars'">
108
+ @for (item of visibleItems(); track item.alt) {
109
+ <ui-avatar
110
+ [src]="item.src ?? null"
111
+ [alt]="item.alt ?? null"
112
+ [initials]="item.initials ?? null"
113
+ [size]="size()"
114
+ class="ui-avatar-group__item"
115
+ />
116
+ }
117
+ @if (overflow() > 0) {
118
+ <span class="ui-avatar-group__overflow ui-avatar-group__overflow--{{ size() }}"
119
+ [attr.aria-label]="overflow() + ' more'">
120
+ +{{ overflow() }}
121
+ </span>
122
+ }
123
+ </div>
124
+ `, isInline: true, styles: [".ui-avatar-group{display:flex;align-items:center}.ui-avatar-group .ui-avatar-group__item,.ui-avatar-group ui-avatar{margin-left:-8px}.ui-avatar-group .ui-avatar-group__item:first-child,.ui-avatar-group ui-avatar:first-child{margin-left:0}.ui-avatar-group ui-avatar,.ui-avatar-group .ui-avatar-group__item{border:2px solid var(--color-bg);border-radius:50%}.ui-avatar-group__overflow{display:inline-flex;align-items:center;justify-content:center;margin-left:-8px;border:2px solid var(--color-bg);border-radius:50%;background:var(--color-neutral-100);color:var(--color-neutral-600);font-family:var(--font-sans);font-weight:var(--font-medium);flex-shrink:0}.ui-avatar-group__overflow--xs{width:20px;height:20px;font-size:10px}.ui-avatar-group__overflow--sm{width:24px;height:24px;font-size:11px}.ui-avatar-group__overflow--md{width:32px;height:32px;font-size:13px}.ui-avatar-group__overflow--lg{width:40px;height:40px;font-size:15px}.ui-avatar-group__overflow--xl{width:48px;height:48px;font-size:17px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AvatarComponent, selector: "ui-avatar", inputs: ["src", "alt", "size", "initials", "chip", "chipColor", "chipAlt", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
125
+ }
126
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: AvatarGroupComponent, decorators: [{
127
+ type: Component,
128
+ args: [{ selector: 'ui-avatar-group', standalone: true, imports: [CommonModule, AvatarComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
129
+ <div class="ui-avatar-group" [attr.aria-label]="'Group of ' + items().length + ' avatars'">
130
+ @for (item of visibleItems(); track item.alt) {
131
+ <ui-avatar
132
+ [src]="item.src ?? null"
133
+ [alt]="item.alt ?? null"
134
+ [initials]="item.initials ?? null"
135
+ [size]="size()"
136
+ class="ui-avatar-group__item"
137
+ />
138
+ }
139
+ @if (overflow() > 0) {
140
+ <span class="ui-avatar-group__overflow ui-avatar-group__overflow--{{ size() }}"
141
+ [attr.aria-label]="overflow() + ' more'">
142
+ +{{ overflow() }}
143
+ </span>
144
+ }
145
+ </div>
146
+ `, styles: [".ui-avatar-group{display:flex;align-items:center}.ui-avatar-group .ui-avatar-group__item,.ui-avatar-group ui-avatar{margin-left:-8px}.ui-avatar-group .ui-avatar-group__item:first-child,.ui-avatar-group ui-avatar:first-child{margin-left:0}.ui-avatar-group ui-avatar,.ui-avatar-group .ui-avatar-group__item{border:2px solid var(--color-bg);border-radius:50%}.ui-avatar-group__overflow{display:inline-flex;align-items:center;justify-content:center;margin-left:-8px;border:2px solid var(--color-bg);border-radius:50%;background:var(--color-neutral-100);color:var(--color-neutral-600);font-family:var(--font-sans);font-weight:var(--font-medium);flex-shrink:0}.ui-avatar-group__overflow--xs{width:20px;height:20px;font-size:10px}.ui-avatar-group__overflow--sm{width:24px;height:24px;font-size:11px}.ui-avatar-group__overflow--md{width:32px;height:32px;font-size:13px}.ui-avatar-group__overflow--lg{width:40px;height:40px;font-size:15px}.ui-avatar-group__overflow--xl{width:48px;height:48px;font-size:17px}\n"] }]
147
+ }] });
148
+
149
+ /**
150
+ * Breadcrumb Molecule — Source: Nuxt UI v3 ❖ Breadcrumb
151
+ * Navigation trail with router support
152
+ */
153
+ class BreadcrumbComponent {
154
+ constructor() {
155
+ this.items = input.required();
156
+ this.separator = input('/');
157
+ }
158
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: BreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
159
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: BreadcrumbComponent, isStandalone: true, selector: "ui-breadcrumb", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
160
+ <nav aria-label="Breadcrumb">
161
+ <ol class="ui-breadcrumb">
162
+ @for (item of items(); track item.label; let last = $last) {
163
+ <li class="ui-breadcrumb__item" [class.ui-breadcrumb__item--current]="last">
164
+ @if (!last && item.to) {
165
+ <a [routerLink]="item.to" class="ui-breadcrumb__link">{{ item.label }}</a>
166
+ } @else if (!last && item.href) {
167
+ <a [href]="item.href" class="ui-breadcrumb__link">{{ item.label }}</a>
168
+ } @else {
169
+ <span class="ui-breadcrumb__current" [attr.aria-current]="last ? 'page' : null">{{ item.label }}</span>
170
+ }
171
+ @if (!last) {
172
+ <span class="ui-breadcrumb__separator" aria-hidden="true">{{ separator() }}</span>
173
+ }
174
+ </li>
175
+ }
176
+ </ol>
177
+ </nav>
178
+ `, isInline: true, styles: [".ui-breadcrumb{display:flex;flex-wrap:wrap;align-items:center;gap:var(--spacing-1);list-style:none;padding:0;margin:0}.ui-breadcrumb__item{display:flex;align-items:center;gap:var(--spacing-1)}.ui-breadcrumb__link{font-family:var(--font-sans);font-size:var(--text-sm);color:var(--color-text-muted);text-decoration:none;transition:color var(--transition-fast)}.ui-breadcrumb__link:hover{color:var(--color-primary-500);text-decoration:underline}.ui-breadcrumb__current{font-family:var(--font-sans);font-size:var(--text-sm);color:var(--color-text);font-weight:var(--font-medium)}.ui-breadcrumb__separator{font-size:var(--text-xs);color:var(--color-text-subtle);-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
179
+ }
180
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: BreadcrumbComponent, decorators: [{
181
+ type: Component,
182
+ args: [{ selector: 'ui-breadcrumb', standalone: true, imports: [CommonModule, RouterModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
183
+ <nav aria-label="Breadcrumb">
184
+ <ol class="ui-breadcrumb">
185
+ @for (item of items(); track item.label; let last = $last) {
186
+ <li class="ui-breadcrumb__item" [class.ui-breadcrumb__item--current]="last">
187
+ @if (!last && item.to) {
188
+ <a [routerLink]="item.to" class="ui-breadcrumb__link">{{ item.label }}</a>
189
+ } @else if (!last && item.href) {
190
+ <a [href]="item.href" class="ui-breadcrumb__link">{{ item.label }}</a>
191
+ } @else {
192
+ <span class="ui-breadcrumb__current" [attr.aria-current]="last ? 'page' : null">{{ item.label }}</span>
193
+ }
194
+ @if (!last) {
195
+ <span class="ui-breadcrumb__separator" aria-hidden="true">{{ separator() }}</span>
196
+ }
197
+ </li>
198
+ }
199
+ </ol>
200
+ </nav>
201
+ `, styles: [".ui-breadcrumb{display:flex;flex-wrap:wrap;align-items:center;gap:var(--spacing-1);list-style:none;padding:0;margin:0}.ui-breadcrumb__item{display:flex;align-items:center;gap:var(--spacing-1)}.ui-breadcrumb__link{font-family:var(--font-sans);font-size:var(--text-sm);color:var(--color-text-muted);text-decoration:none;transition:color var(--transition-fast)}.ui-breadcrumb__link:hover{color:var(--color-primary-500);text-decoration:underline}.ui-breadcrumb__current{font-family:var(--font-sans);font-size:var(--text-sm);color:var(--color-text);font-weight:var(--font-medium)}.ui-breadcrumb__separator{font-size:var(--text-xs);color:var(--color-text-subtle);-webkit-user-select:none;user-select:none}\n"] }]
202
+ }] });
203
+
204
+ /**
205
+ * ButtonGroup Molecule — Source: Nuxt UI v3 ❖ ButtonGroup
206
+ * Groups buttons in a visual row (joined borders)
207
+ */
208
+ class ButtonGroupComponent {
209
+ constructor() {
210
+ this.vertical = input(false);
211
+ }
212
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ButtonGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
213
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.20", type: ButtonGroupComponent, isStandalone: true, selector: "ui-button-group", inputs: { vertical: { classPropertyName: "vertical", publicName: "vertical", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
214
+ <div class="ui-button-group" [class.ui-button-group--vertical]="vertical()" role="group">
215
+ <ng-content />
216
+ </div>
217
+ `, isInline: true, styles: [".ui-button-group{display:inline-flex;align-items:stretch}.ui-button-group ::ng-deep ui-button button,.ui-button-group ::ng-deep .ui-btn{border-radius:0;border-right-width:0}.ui-button-group ::ng-deep ui-button button:first-child,.ui-button-group ::ng-deep .ui-btn:first-child{border-radius:var(--radius-md) 0 0 var(--radius-md)}.ui-button-group ::ng-deep ui-button button:last-child,.ui-button-group ::ng-deep .ui-btn:last-child{border-radius:0 var(--radius-md) var(--radius-md) 0;border-right-width:1px}.ui-button-group--vertical{flex-direction:column}.ui-button-group--vertical ::ng-deep ui-button button,.ui-button-group--vertical ::ng-deep .ui-btn{border-bottom-width:0;border-radius:0}.ui-button-group--vertical ::ng-deep ui-button button:first-child,.ui-button-group--vertical ::ng-deep .ui-btn:first-child{border-radius:var(--radius-md) var(--radius-md) 0 0}.ui-button-group--vertical ::ng-deep ui-button button:last-child,.ui-button-group--vertical ::ng-deep .ui-btn:last-child{border-radius:0 0 var(--radius-md) var(--radius-md);border-bottom-width:1px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
218
+ }
219
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ButtonGroupComponent, decorators: [{
220
+ type: Component,
221
+ args: [{ selector: 'ui-button-group', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
222
+ <div class="ui-button-group" [class.ui-button-group--vertical]="vertical()" role="group">
223
+ <ng-content />
224
+ </div>
225
+ `, styles: [".ui-button-group{display:inline-flex;align-items:stretch}.ui-button-group ::ng-deep ui-button button,.ui-button-group ::ng-deep .ui-btn{border-radius:0;border-right-width:0}.ui-button-group ::ng-deep ui-button button:first-child,.ui-button-group ::ng-deep .ui-btn:first-child{border-radius:var(--radius-md) 0 0 var(--radius-md)}.ui-button-group ::ng-deep ui-button button:last-child,.ui-button-group ::ng-deep .ui-btn:last-child{border-radius:0 var(--radius-md) var(--radius-md) 0;border-right-width:1px}.ui-button-group--vertical{flex-direction:column}.ui-button-group--vertical ::ng-deep ui-button button,.ui-button-group--vertical ::ng-deep .ui-btn{border-bottom-width:0;border-radius:0}.ui-button-group--vertical ::ng-deep ui-button button:first-child,.ui-button-group--vertical ::ng-deep .ui-btn:first-child{border-radius:var(--radius-md) var(--radius-md) 0 0}.ui-button-group--vertical ::ng-deep ui-button button:last-child,.ui-button-group--vertical ::ng-deep .ui-btn:last-child{border-radius:0 0 var(--radius-md) var(--radius-md);border-bottom-width:1px}\n"] }]
226
+ }] });
227
+
228
+ /**
229
+ * FormField Molecule — Source: Nuxt UI v3 ❖ FormField
230
+ * Wrapper for form controls: label + control + hint + error
231
+ * Used with: Input, Textarea, Select, Checkbox, Radio...
232
+ */
233
+ class FormFieldComponent {
234
+ constructor() {
235
+ this.label = input(null);
236
+ this.name = input('');
237
+ this.hint = input(null);
238
+ this.errorMessage = input(null);
239
+ this.required = input(false);
240
+ this.size = input('md');
241
+ }
242
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
243
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: FormFieldComponent, isStandalone: true, selector: "ui-form-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
244
+ <div class="ui-form-field" [class.ui-form-field--error]="!!errorMessage()" [class.ui-form-field--required]="required()">
245
+ @if (label()) {
246
+ <label class="ui-form-field__label ui-form-field__label--{{ size() }}" [for]="name()">
247
+ {{ label() }}
248
+ @if (required()) {
249
+ <span class="ui-form-field__required" aria-hidden="true"> *</span>
250
+ }
251
+ </label>
252
+ }
253
+
254
+ <div class="ui-form-field__control">
255
+ <ng-content />
256
+ </div>
257
+
258
+ @if (hint() && !errorMessage()) {
259
+ <p class="ui-form-field__hint" [id]="name() + '-hint'">{{ hint() }}</p>
260
+ }
261
+
262
+ @if (errorMessage()) {
263
+ <p class="ui-form-field__error" role="alert" [id]="name() + '-error'">
264
+ {{ errorMessage() }}
265
+ </p>
266
+ }
267
+ </div>
268
+ `, isInline: true, styles: [".ui-form-field{display:flex;flex-direction:column;gap:var(--spacing-1-5);width:100%}.ui-form-field__label{font-family:var(--font-sans);font-weight:var(--font-medium);color:var(--color-text);cursor:pointer}.ui-form-field__label--xs,.ui-form-field__label--sm{font-size:var(--text-xs)}.ui-form-field__label--md{font-size:var(--text-sm)}.ui-form-field__label--lg{font-size:var(--text-md)}.ui-form-field__label--xl{font-size:var(--text-lg)}.ui-form-field__required{color:var(--color-error-500)}.ui-form-field__control{position:relative}.ui-form-field__hint{font-family:var(--font-sans);font-size:var(--text-xs);color:var(--color-text-muted);margin:0}.ui-form-field__error{font-family:var(--font-sans);font-size:var(--text-xs);color:var(--color-error-600);margin:0;font-weight:var(--font-medium)}.ui-form-field--error .ui-form-field__label{color:var(--color-error-600)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
269
+ }
270
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FormFieldComponent, decorators: [{
271
+ type: Component,
272
+ args: [{ selector: 'ui-form-field', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
273
+ <div class="ui-form-field" [class.ui-form-field--error]="!!errorMessage()" [class.ui-form-field--required]="required()">
274
+ @if (label()) {
275
+ <label class="ui-form-field__label ui-form-field__label--{{ size() }}" [for]="name()">
276
+ {{ label() }}
277
+ @if (required()) {
278
+ <span class="ui-form-field__required" aria-hidden="true"> *</span>
279
+ }
280
+ </label>
281
+ }
282
+
283
+ <div class="ui-form-field__control">
284
+ <ng-content />
285
+ </div>
286
+
287
+ @if (hint() && !errorMessage()) {
288
+ <p class="ui-form-field__hint" [id]="name() + '-hint'">{{ hint() }}</p>
289
+ }
290
+
291
+ @if (errorMessage()) {
292
+ <p class="ui-form-field__error" role="alert" [id]="name() + '-error'">
293
+ {{ errorMessage() }}
294
+ </p>
295
+ }
296
+ </div>
297
+ `, styles: [".ui-form-field{display:flex;flex-direction:column;gap:var(--spacing-1-5);width:100%}.ui-form-field__label{font-family:var(--font-sans);font-weight:var(--font-medium);color:var(--color-text);cursor:pointer}.ui-form-field__label--xs,.ui-form-field__label--sm{font-size:var(--text-xs)}.ui-form-field__label--md{font-size:var(--text-sm)}.ui-form-field__label--lg{font-size:var(--text-md)}.ui-form-field__label--xl{font-size:var(--text-lg)}.ui-form-field__required{color:var(--color-error-500)}.ui-form-field__control{position:relative}.ui-form-field__hint{font-family:var(--font-sans);font-size:var(--text-xs);color:var(--color-text-muted);margin:0}.ui-form-field__error{font-family:var(--font-sans);font-size:var(--text-xs);color:var(--color-error-600);margin:0;font-weight:var(--font-medium)}.ui-form-field--error .ui-form-field__label{color:var(--color-error-600)}\n"] }]
298
+ }] });
299
+
300
+ /**
301
+ * Input Molecule — Source: Nuxt UI v3 ❖ Input
302
+ *
303
+ * Slots :
304
+ * [slot=leading] — icône / contenu à gauche
305
+ * [slot=trailing] — icône / contenu à droite
306
+ *
307
+ * Pour rendre un slot cliquable (ex: toggle password) :
308
+ * [trailingClickable]="true" → rend le slot trailing en <button> et émet (trailingClick)
309
+ * [leadingClickable]="true" → rend le slot leading en <button> et émet (leadingClick)
310
+ */
311
+ class InputComponent {
312
+ constructor() {
313
+ // ── Inputs ───────────────────────────────────────────────
314
+ this.type = input('text');
315
+ this.placeholder = input('');
316
+ this.size = input('md');
317
+ this.variant = input('outline');
318
+ this.color = input('primary');
319
+ this.disabled = input(false);
320
+ this.readonly = input(false);
321
+ this.required = input(false);
322
+ this.ariaLabel = input(null);
323
+ this.leading = input(false);
324
+ this.leadingClickable = input(false);
325
+ /** aria-label du bouton leading quand leadingClickable=true */
326
+ this.leadingLabel = input('');
327
+ this.trailing = input(false);
328
+ this.trailingClickable = input(false);
329
+ /** aria-label du bouton trailing quand trailingClickable=true */
330
+ this.trailingLabel = input('');
331
+ // ── Two-way ──────────────────────────────────────────────
332
+ this.value = model('');
333
+ // ── Outputs ──────────────────────────────────────────────
334
+ this.leadingClick = output();
335
+ this.trailingClick = output();
336
+ // ── CVA ──────────────────────────────────────────────────
337
+ this._onChange = () => { };
338
+ this.onTouched = () => { };
339
+ }
340
+ // ── Classes computed ─────────────────────────────────────
341
+ wrapClass() {
342
+ return [
343
+ 'ui-input-wrap',
344
+ `ui-input-wrap--${this.size()}`,
345
+ this.leading() ? 'ui-input-wrap--has-leading' : '',
346
+ this.trailing() ? 'ui-input-wrap--has-trailing' : '',
347
+ ].filter(Boolean).join(' ');
348
+ }
349
+ inputClass() {
350
+ return `ui-input ui-input--${this.variant()} ui-input--${this.color()} ui-input--${this.size()}`;
351
+ }
352
+ onInput(e) {
353
+ const val = e.target.value;
354
+ this.value.set(val);
355
+ this._onChange(val);
356
+ }
357
+ writeValue(v) { this.value.set(v ?? ''); }
358
+ registerOnChange(fn) { this._onChange = fn; }
359
+ registerOnTouched(fn) { this.onTouched = fn; }
360
+ setDisabledState(_) { }
361
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: InputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
362
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: InputComponent, isStandalone: true, selector: "ui-input", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", 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 }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, leading: { classPropertyName: "leading", publicName: "leading", isSignal: true, isRequired: false, transformFunction: null }, leadingClickable: { classPropertyName: "leadingClickable", publicName: "leadingClickable", isSignal: true, isRequired: false, transformFunction: null }, leadingLabel: { classPropertyName: "leadingLabel", publicName: "leadingLabel", isSignal: true, isRequired: false, transformFunction: null }, trailing: { classPropertyName: "trailing", publicName: "trailing", isSignal: true, isRequired: false, transformFunction: null }, trailingClickable: { classPropertyName: "trailingClickable", publicName: "trailingClickable", isSignal: true, isRequired: false, transformFunction: null }, trailingLabel: { classPropertyName: "trailingLabel", publicName: "trailingLabel", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", leadingClick: "leadingClick", trailingClick: "trailingClick" }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputComponent), multi: true }], ngImport: i0, template: `
363
+ <div [class]="wrapClass()">
364
+
365
+ <!-- Leading slot -->
366
+ @if (leading()) {
367
+ <span
368
+ class="ui-input__leading"
369
+ [class.ui-input__slot--clickable]="leadingClickable()"
370
+ [attr.role]="leadingClickable() ? 'button' : null"
371
+ [attr.tabindex]="leadingClickable() ? 0 : null"
372
+ [attr.aria-label]="leadingClickable() ? leadingLabel() : null"
373
+ (click)="leadingClickable() && leadingClick.emit()"
374
+ (keydown.enter)="leadingClickable() && leadingClick.emit()"
375
+ (keydown.space)="leadingClickable() && leadingClick.emit()"
376
+ >
377
+ <ng-content select="[slot=leading]" />
378
+ </span>
379
+ }
380
+
381
+ <!-- Native input -->
382
+ <input
383
+ [class]="inputClass()"
384
+ [type]="type()"
385
+ [placeholder]="placeholder()"
386
+ [disabled]="disabled()"
387
+ [readonly]="readonly()"
388
+ [required]="required()"
389
+ [attr.aria-label]="ariaLabel() ?? null"
390
+ [attr.aria-invalid]="color() === 'error'"
391
+ [value]="value()"
392
+ (input)="onInput($event)"
393
+ (blur)="onTouched()"
394
+ />
395
+
396
+ <!-- Trailing slot -->
397
+ @if (trailing()) {
398
+ <span
399
+ class="ui-input__trailing"
400
+ [class.ui-input__slot--clickable]="trailingClickable()"
401
+ [attr.role]="trailingClickable() ? 'button' : null"
402
+ [attr.tabindex]="trailingClickable() ? 0 : null"
403
+ [attr.aria-label]="trailingClickable() ? trailingLabel() : null"
404
+ (click)="trailingClickable() && trailingClick.emit()"
405
+ (keydown.enter)="trailingClickable() && trailingClick.emit()"
406
+ (keydown.space)="trailingClickable() && trailingClick.emit()"
407
+ >
408
+ <ng-content select="[slot=trailing]" />
409
+ </span>
410
+ }
411
+
412
+ </div>
413
+ `, isInline: true, styles: [".ui-input-wrap{position:relative;display:flex;align-items:stretch;width:100%}.ui-input-wrap--has-leading .ui-input{padding-left:2.5rem}.ui-input-wrap--has-trailing .ui-input{padding-right:2.5rem}.ui-input{width:100%;font-family:var(--font-sans);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-bg);color:var(--color-text);outline:none;transition:var(--transition-colors)}.ui-input::placeholder{color:var(--color-text-subtle)}.ui-input:focus{border-color:var(--color-primary-500);box-shadow:0 0 0 1px var(--color-primary-500)}.ui-input:disabled{opacity:.5;cursor:not-allowed;background:var(--color-neutral-50)}.ui-input--xs{height:var(--size-xs);padding:0 8px;font-size:var(--text-xs)}.ui-input--sm{height:var(--size-sm);padding:0 10px;font-size:var(--text-xs)}.ui-input--md{height:var(--size-md);padding:0 10px;font-size:var(--text-sm)}.ui-input--lg{height:var(--size-lg);padding:0 12px;font-size:var(--text-sm)}.ui-input--xl{height:var(--size-xl);padding:0 12px;font-size:var(--text-md)}.ui-input--outline{border-color:var(--color-border)}.ui-input--soft{background:var(--color-neutral-50);border-color:transparent}.ui-input--subtle{background:transparent;border-color:transparent;border-bottom-color:var(--color-border);border-radius:0}.ui-input--none{border:none;background:transparent;box-shadow:none!important}.ui-input--error{border-color:var(--color-error-500)}.ui-input--error:focus{box-shadow:0 0 0 1px var(--color-error-500)}.ui-input--success{border-color:var(--color-success-500)}.ui-input--success:focus{box-shadow:0 0 0 1px var(--color-success-500)}.ui-input--warning{border-color:var(--color-warning-500)}.ui-input--warning:focus{box-shadow:0 0 0 1px var(--color-warning-500)}.ui-input__leading,.ui-input__trailing{position:absolute;top:50%;transform:translateY(-50%);display:flex;align-items:center;justify-content:center;color:var(--color-text-muted);width:2.25rem;height:100%;pointer-events:none}.ui-input__leading{left:0}.ui-input__trailing{right:0}.ui-input__slot--clickable{pointer-events:auto;cursor:pointer;border-radius:var(--radius-sm);color:var(--color-text-muted);transition:color var(--transition-colors)}.ui-input__slot--clickable:hover{color:var(--color-text)}.ui-input__slot--clickable:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
414
+ }
415
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: InputComponent, decorators: [{
416
+ type: Component,
417
+ args: [{ selector: 'ui-input', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputComponent), multi: true }], template: `
418
+ <div [class]="wrapClass()">
419
+
420
+ <!-- Leading slot -->
421
+ @if (leading()) {
422
+ <span
423
+ class="ui-input__leading"
424
+ [class.ui-input__slot--clickable]="leadingClickable()"
425
+ [attr.role]="leadingClickable() ? 'button' : null"
426
+ [attr.tabindex]="leadingClickable() ? 0 : null"
427
+ [attr.aria-label]="leadingClickable() ? leadingLabel() : null"
428
+ (click)="leadingClickable() && leadingClick.emit()"
429
+ (keydown.enter)="leadingClickable() && leadingClick.emit()"
430
+ (keydown.space)="leadingClickable() && leadingClick.emit()"
431
+ >
432
+ <ng-content select="[slot=leading]" />
433
+ </span>
434
+ }
435
+
436
+ <!-- Native input -->
437
+ <input
438
+ [class]="inputClass()"
439
+ [type]="type()"
440
+ [placeholder]="placeholder()"
441
+ [disabled]="disabled()"
442
+ [readonly]="readonly()"
443
+ [required]="required()"
444
+ [attr.aria-label]="ariaLabel() ?? null"
445
+ [attr.aria-invalid]="color() === 'error'"
446
+ [value]="value()"
447
+ (input)="onInput($event)"
448
+ (blur)="onTouched()"
449
+ />
450
+
451
+ <!-- Trailing slot -->
452
+ @if (trailing()) {
453
+ <span
454
+ class="ui-input__trailing"
455
+ [class.ui-input__slot--clickable]="trailingClickable()"
456
+ [attr.role]="trailingClickable() ? 'button' : null"
457
+ [attr.tabindex]="trailingClickable() ? 0 : null"
458
+ [attr.aria-label]="trailingClickable() ? trailingLabel() : null"
459
+ (click)="trailingClickable() && trailingClick.emit()"
460
+ (keydown.enter)="trailingClickable() && trailingClick.emit()"
461
+ (keydown.space)="trailingClickable() && trailingClick.emit()"
462
+ >
463
+ <ng-content select="[slot=trailing]" />
464
+ </span>
465
+ }
466
+
467
+ </div>
468
+ `, styles: [".ui-input-wrap{position:relative;display:flex;align-items:stretch;width:100%}.ui-input-wrap--has-leading .ui-input{padding-left:2.5rem}.ui-input-wrap--has-trailing .ui-input{padding-right:2.5rem}.ui-input{width:100%;font-family:var(--font-sans);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-bg);color:var(--color-text);outline:none;transition:var(--transition-colors)}.ui-input::placeholder{color:var(--color-text-subtle)}.ui-input:focus{border-color:var(--color-primary-500);box-shadow:0 0 0 1px var(--color-primary-500)}.ui-input:disabled{opacity:.5;cursor:not-allowed;background:var(--color-neutral-50)}.ui-input--xs{height:var(--size-xs);padding:0 8px;font-size:var(--text-xs)}.ui-input--sm{height:var(--size-sm);padding:0 10px;font-size:var(--text-xs)}.ui-input--md{height:var(--size-md);padding:0 10px;font-size:var(--text-sm)}.ui-input--lg{height:var(--size-lg);padding:0 12px;font-size:var(--text-sm)}.ui-input--xl{height:var(--size-xl);padding:0 12px;font-size:var(--text-md)}.ui-input--outline{border-color:var(--color-border)}.ui-input--soft{background:var(--color-neutral-50);border-color:transparent}.ui-input--subtle{background:transparent;border-color:transparent;border-bottom-color:var(--color-border);border-radius:0}.ui-input--none{border:none;background:transparent;box-shadow:none!important}.ui-input--error{border-color:var(--color-error-500)}.ui-input--error:focus{box-shadow:0 0 0 1px var(--color-error-500)}.ui-input--success{border-color:var(--color-success-500)}.ui-input--success:focus{box-shadow:0 0 0 1px var(--color-success-500)}.ui-input--warning{border-color:var(--color-warning-500)}.ui-input--warning:focus{box-shadow:0 0 0 1px var(--color-warning-500)}.ui-input__leading,.ui-input__trailing{position:absolute;top:50%;transform:translateY(-50%);display:flex;align-items:center;justify-content:center;color:var(--color-text-muted);width:2.25rem;height:100%;pointer-events:none}.ui-input__leading{left:0}.ui-input__trailing{right:0}.ui-input__slot--clickable{pointer-events:auto;cursor:pointer;border-radius:var(--radius-sm);color:var(--color-text-muted);transition:color var(--transition-colors)}.ui-input__slot--clickable:hover{color:var(--color-text)}.ui-input__slot--clickable:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}\n"] }]
469
+ }] });
470
+
471
+ /**
472
+ * Pagination Molecule — Source: Nuxt UI v3 ❖ Pagination
473
+ * Page navigation with page numbers, prev/next controls
474
+ */
475
+ class PaginationComponent {
476
+ constructor() {
477
+ this.total = input.required();
478
+ this.size = input('md');
479
+ this.page = model(1);
480
+ this.pages = computed(() => {
481
+ const current = this.page();
482
+ const last = this.total();
483
+ if (last <= 7)
484
+ return Array.from({ length: last }, (_, i) => i + 1);
485
+ const items = [1];
486
+ if (current > 3)
487
+ items.push('...');
488
+ const start = Math.max(2, current - 1);
489
+ const end = Math.min(last - 1, current + 1);
490
+ for (let i = start; i <= end; i++)
491
+ items.push(i);
492
+ if (current < last - 2)
493
+ items.push('...');
494
+ items.push(last);
495
+ return items;
496
+ });
497
+ }
498
+ prev() { if (this.page() > 1)
499
+ this.page.update(p => p - 1); }
500
+ next() { if (this.page() < this.total())
501
+ this.page.update(p => p + 1); }
502
+ goTo(p) { this.page.set(p); }
503
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
504
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: PaginationComponent, isStandalone: true, selector: "ui-pagination", inputs: { total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { page: "pageChange" }, ngImport: i0, template: `
505
+ <nav class="ui-pagination ui-pagination--{{ size() }}" aria-label="Pagination">
506
+ <button
507
+ class="ui-pagination__btn"
508
+ [disabled]="page() <= 1"
509
+ (click)="prev()"
510
+ aria-label="Previous page"
511
+ >‹</button>
512
+
513
+ @for (p of pages(); track p) {
514
+ @if (p === '...') {
515
+ <span class="ui-pagination__ellipsis" aria-hidden="true">…</span>
516
+ } @else {
517
+ <button
518
+ class="ui-pagination__btn"
519
+ [class.ui-pagination__btn--active]="p === page()"
520
+ [attr.aria-current]="p === page() ? 'page' : null"
521
+ (click)="goTo(+p)"
522
+ >{{ p }}</button>
523
+ }
524
+ }
525
+
526
+ <button
527
+ class="ui-pagination__btn"
528
+ [disabled]="page() >= total()"
529
+ (click)="next()"
530
+ aria-label="Next page"
531
+ >›</button>
532
+ </nav>
533
+ `, isInline: true, styles: [".ui-pagination{display:flex;align-items:center;gap:var(--spacing-1)}.ui-pagination--xs .ui-pagination__btn{height:var(--size-xs);min-width:var(--size-xs);font-size:var(--text-xs)}.ui-pagination--sm .ui-pagination__btn{height:var(--size-sm);min-width:var(--size-sm);font-size:var(--text-xs)}.ui-pagination--md .ui-pagination__btn{height:var(--size-md);min-width:var(--size-md);font-size:var(--text-sm)}.ui-pagination--lg .ui-pagination__btn{height:var(--size-lg);min-width:var(--size-lg);font-size:var(--text-sm)}.ui-pagination--xl .ui-pagination__btn{height:var(--size-xl);min-width:var(--size-xl);font-size:var(--text-md)}.ui-pagination__btn{display:inline-flex;align-items:center;justify-content:center;padding:0 var(--spacing-2);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-bg);color:var(--color-text);font-family:var(--font-sans);font-weight:var(--font-medium);cursor:pointer;transition:var(--transition-colors)}.ui-pagination__btn:hover:not([disabled]){background:var(--color-neutral-100);border-color:var(--color-neutral-300)}.ui-pagination__btn--active{background:var(--color-primary-500);border-color:var(--color-primary-500);color:#fff}.ui-pagination__btn[disabled]{opacity:.4;cursor:not-allowed}.ui-pagination__ellipsis{display:inline-flex;align-items:center;padding:0 var(--spacing-1);color:var(--color-text-muted);font-family:var(--font-sans);font-size:var(--text-sm)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
534
+ }
535
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: PaginationComponent, decorators: [{
536
+ type: Component,
537
+ args: [{ selector: 'ui-pagination', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
538
+ <nav class="ui-pagination ui-pagination--{{ size() }}" aria-label="Pagination">
539
+ <button
540
+ class="ui-pagination__btn"
541
+ [disabled]="page() <= 1"
542
+ (click)="prev()"
543
+ aria-label="Previous page"
544
+ >‹</button>
545
+
546
+ @for (p of pages(); track p) {
547
+ @if (p === '...') {
548
+ <span class="ui-pagination__ellipsis" aria-hidden="true">…</span>
549
+ } @else {
550
+ <button
551
+ class="ui-pagination__btn"
552
+ [class.ui-pagination__btn--active]="p === page()"
553
+ [attr.aria-current]="p === page() ? 'page' : null"
554
+ (click)="goTo(+p)"
555
+ >{{ p }}</button>
556
+ }
557
+ }
558
+
559
+ <button
560
+ class="ui-pagination__btn"
561
+ [disabled]="page() >= total()"
562
+ (click)="next()"
563
+ aria-label="Next page"
564
+ >›</button>
565
+ </nav>
566
+ `, styles: [".ui-pagination{display:flex;align-items:center;gap:var(--spacing-1)}.ui-pagination--xs .ui-pagination__btn{height:var(--size-xs);min-width:var(--size-xs);font-size:var(--text-xs)}.ui-pagination--sm .ui-pagination__btn{height:var(--size-sm);min-width:var(--size-sm);font-size:var(--text-xs)}.ui-pagination--md .ui-pagination__btn{height:var(--size-md);min-width:var(--size-md);font-size:var(--text-sm)}.ui-pagination--lg .ui-pagination__btn{height:var(--size-lg);min-width:var(--size-lg);font-size:var(--text-sm)}.ui-pagination--xl .ui-pagination__btn{height:var(--size-xl);min-width:var(--size-xl);font-size:var(--text-md)}.ui-pagination__btn{display:inline-flex;align-items:center;justify-content:center;padding:0 var(--spacing-2);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-bg);color:var(--color-text);font-family:var(--font-sans);font-weight:var(--font-medium);cursor:pointer;transition:var(--transition-colors)}.ui-pagination__btn:hover:not([disabled]){background:var(--color-neutral-100);border-color:var(--color-neutral-300)}.ui-pagination__btn--active{background:var(--color-primary-500);border-color:var(--color-primary-500);color:#fff}.ui-pagination__btn[disabled]{opacity:.4;cursor:not-allowed}.ui-pagination__ellipsis{display:inline-flex;align-items:center;padding:0 var(--spacing-1);color:var(--color-text-muted);font-family:var(--font-sans);font-size:var(--text-sm)}\n"] }]
567
+ }] });
568
+
569
+ /**
570
+ * Select Molecule — Source: Nuxt UI v3 ❖ Select
571
+ *
572
+ * Dropdown custom (non natif) :
573
+ * - Trigger stylisé comme un Input (variants, couleurs, tailles Figma)
574
+ * - Panel dropdown animé (scale + fade, 100ms ease-out)
575
+ * - Navigation clavier : ArrowUp/Down, Enter, Space, Escape, Tab
576
+ * - ClickOutside pour fermer
577
+ * - Slot leading icon dans le trigger
578
+ * - Icône + checkmark par option
579
+ * - Compatible ControlValueAccessor
580
+ */
581
+ class SelectComponent {
582
+ constructor() {
583
+ this.options = input.required();
584
+ this.placeholder = input(null);
585
+ this.size = input('md');
586
+ this.variant = input('outline');
587
+ this.color = input('neutral');
588
+ this.disabled = input(false);
589
+ this.loading = input(false);
590
+ this.leadingIcon = input(false);
591
+ this.ariaLabel = input(null);
592
+ this.value = model('');
593
+ this.change = output();
594
+ this.isOpen = signal(false);
595
+ this.activeIndex = signal(-1);
596
+ this.selectedOption = computed(() => this.options().find(o => String(o.value) === String(this.value())));
597
+ this.triggerClasses = computed(() => ['ui-select__trigger',
598
+ `ui-select__trigger--${this.size()}`,
599
+ `ui-select__trigger--${this.variant()}`,
600
+ `ui-select__trigger--${this.color()}`
601
+ ].join(' '));
602
+ // CVA
603
+ this._onChange = () => { };
604
+ this._onTouched = () => { };
605
+ }
606
+ isSelected(opt) {
607
+ return String(opt.value) === String(this.value());
608
+ }
609
+ writeValue(v) { this.value.set(v ?? ''); }
610
+ registerOnChange(fn) { this._onChange = fn; }
611
+ registerOnTouched(fn) { this._onTouched = fn; }
612
+ setDisabledState(_) { }
613
+ toggleOpen() {
614
+ if (this.disabled() || this.loading())
615
+ return;
616
+ this.isOpen.update(v => !v);
617
+ if (this.isOpen()) {
618
+ const idx = this.options().findIndex(o => this.isSelected(o));
619
+ this.activeIndex.set(idx >= 0 ? idx : 0);
620
+ }
621
+ }
622
+ selectOption(opt) {
623
+ if (opt.disabled)
624
+ return;
625
+ const val = String(opt.value);
626
+ this.value.set(val);
627
+ this._onChange(val);
628
+ this._onTouched();
629
+ this.change.emit(opt);
630
+ this.isOpen.set(false);
631
+ this.triggerEl?.nativeElement.focus();
632
+ }
633
+ onTriggerKeydown(event) {
634
+ switch (event.key) {
635
+ case 'Enter':
636
+ case ' ':
637
+ event.preventDefault();
638
+ if (!this.isOpen()) {
639
+ this.toggleOpen();
640
+ }
641
+ else {
642
+ const opt = this.options()[this.activeIndex()];
643
+ if (opt && !opt.disabled)
644
+ this.selectOption(opt);
645
+ }
646
+ break;
647
+ case 'ArrowDown':
648
+ event.preventDefault();
649
+ if (!this.isOpen()) {
650
+ this.toggleOpen();
651
+ return;
652
+ }
653
+ this.activeIndex.update(i => {
654
+ let n = i + 1;
655
+ while (n < this.options().length && this.options()[n]?.disabled)
656
+ n++;
657
+ return Math.min(n, this.options().length - 1);
658
+ });
659
+ break;
660
+ case 'ArrowUp':
661
+ event.preventDefault();
662
+ this.activeIndex.update(i => {
663
+ let n = i - 1;
664
+ while (n >= 0 && this.options()[n]?.disabled)
665
+ n--;
666
+ return Math.max(n, 0);
667
+ });
668
+ break;
669
+ case 'Escape':
670
+ case 'Tab':
671
+ this.isOpen.set(false);
672
+ break;
673
+ }
674
+ }
675
+ onDocumentClick(event) {
676
+ if (this.isOpen() && !event.target.closest('ui-select')) {
677
+ this.isOpen.set(false);
678
+ }
679
+ }
680
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: SelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
681
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: SelectComponent, isStandalone: true, selector: "ui-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", 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 }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, leadingIcon: { classPropertyName: "leadingIcon", publicName: "leadingIcon", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", change: "change" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, providers: [{
682
+ provide: NG_VALUE_ACCESSOR,
683
+ useExisting: forwardRef(() => SelectComponent),
684
+ multi: true,
685
+ }], viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerEl"], descendants: true }], ngImport: i0, template: `
686
+ <div
687
+ class="ui-select"
688
+ [class.ui-select--open]="isOpen()"
689
+ [class.ui-select--disabled]="disabled()"
690
+ >
691
+ <!-- Trigger -->
692
+ <button
693
+ #triggerEl
694
+ type="button"
695
+ [class]="triggerClasses()"
696
+ [disabled]="disabled() || loading()"
697
+ [attr.aria-haspopup]="'listbox'"
698
+ [attr.aria-expanded]="isOpen()"
699
+ [attr.aria-label]="ariaLabel() ?? null"
700
+ (click)="toggleOpen(); $event.stopPropagation()"
701
+ (keydown)="onTriggerKeydown($event)"
702
+ >
703
+ @if (leadingIcon()) {
704
+ <span class="ui-select__leading" aria-hidden="true">
705
+ <ng-content select="[slot=leading]" />
706
+ </span>
707
+ }
708
+
709
+ <span class="ui-select__value" [class.ui-select__value--placeholder]="!selectedOption()">
710
+ @if (loading()) {
711
+ <span class="ui-select__spinner" aria-hidden="true">
712
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
713
+ <circle cx="12" cy="12" r="10" stroke-opacity="0.25"/>
714
+ <path d="M12 2a10 10 0 0 1 10 10" stroke-linecap="round"/>
715
+ </svg>
716
+ </span>
717
+ } @else {
718
+ {{ selectedOption()?.label ?? placeholder() ?? 'Sélectionner...' }}
719
+ }
720
+ </span>
721
+
722
+ <span class="ui-select__chevron" [class.ui-select__chevron--open]="isOpen()" aria-hidden="true">
723
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.75"
724
+ stroke-linecap="round" stroke-linejoin="round">
725
+ <path d="M4 6l4 4 4-4"/>
726
+ </svg>
727
+ </span>
728
+ </button>
729
+
730
+ <!-- Dropdown panel -->
731
+ @if (isOpen()) {
732
+ <div
733
+ [@dropdown]
734
+ class="ui-select__panel"
735
+ role="listbox"
736
+ [attr.aria-label]="ariaLabel() ?? 'Options'"
737
+ (click)="$event.stopPropagation()"
738
+ >
739
+ @for (opt of options(); track opt.value; let i = $index) {
740
+ <button
741
+ type="button"
742
+ class="ui-select__option"
743
+ role="option"
744
+ [class.ui-select__option--selected]="isSelected(opt)"
745
+ [class.ui-select__option--highlighted]="activeIndex() === i"
746
+ [class.ui-select__option--disabled]="opt.disabled"
747
+ [attr.aria-selected]="isSelected(opt)"
748
+ [disabled]="opt.disabled"
749
+ (click)="selectOption(opt)"
750
+ (mouseenter)="activeIndex.set(i)"
751
+ >
752
+ @if (opt.icon) {
753
+ <span class="ui-select__option-icon" aria-hidden="true">{{ opt.icon }}</span>
754
+ }
755
+ <span class="ui-select__option-label">{{ opt.label }}</span>
756
+ @if (isSelected(opt)) {
757
+ <span class="ui-select__option-check" aria-hidden="true">
758
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2.25"
759
+ stroke-linecap="round" stroke-linejoin="round">
760
+ <path d="M3 8l3.5 3.5L13 5"/>
761
+ </svg>
762
+ </span>
763
+ }
764
+ </button>
765
+ }
766
+ @if (options().length === 0) {
767
+ <div class="ui-select__empty">Aucune option disponible</div>
768
+ }
769
+ </div>
770
+ }
771
+ </div>
772
+ `, isInline: true, styles: [".ui-select{position:relative;display:inline-block;width:100%}.ui-select--disabled{opacity:.5;cursor:not-allowed}.ui-select__trigger{display:inline-flex;align-items:center;gap:.375rem;width:100%;border-radius:var(--radius-md);font-family:var(--font-sans);font-weight:var(--font-medium);cursor:pointer;outline:none;transition:background-color var(--transition-colors),border-color var(--transition-colors),box-shadow var(--transition-colors);text-align:left;white-space:nowrap;overflow:hidden}.ui-select__trigger--xs{height:var(--size-xs);padding:0 8px;font-size:var(--text-xs)}.ui-select__trigger--sm{height:var(--size-sm);padding:0 10px;font-size:var(--text-xs)}.ui-select__trigger--md{height:var(--size-md);padding:0 10px;font-size:var(--text-sm)}.ui-select__trigger--lg{height:var(--size-lg);padding:0 12px;font-size:var(--text-sm)}.ui-select__trigger--xl{height:var(--size-xl);padding:0 12px;font-size:var(--text-md)}.ui-select__trigger--outline.ui-select__trigger--neutral{background:var(--color-bg);border:1px solid var(--color-border);color:var(--color-text)}.ui-select__trigger--outline.ui-select__trigger--neutral:hover:not(:disabled){border-color:var(--color-neutral-400)}.ui-select__trigger--outline.ui-select__trigger--neutral:focus-visible{border-color:var(--color-primary-500);box-shadow:0 0 0 1px var(--color-primary-500)}.ui-select__trigger--soft.ui-select__trigger--neutral{background:var(--color-neutral-100);border:1px solid transparent;color:var(--color-text)}.ui-select__trigger--soft.ui-select__trigger--neutral:hover:not(:disabled){background:var(--color-neutral-200)}.ui-select__trigger--soft.ui-select__trigger--neutral:focus-visible{box-shadow:0 0 0 2px var(--color-primary-500)}.ui-select__trigger--subtle.ui-select__trigger--neutral{background:transparent;border:1px solid transparent;color:var(--color-text)}.ui-select__trigger--subtle.ui-select__trigger--neutral:hover:not(:disabled){background:var(--color-neutral-100)}.ui-select__trigger--subtle.ui-select__trigger--neutral:focus-visible{box-shadow:0 0 0 2px var(--color-primary-500)}.ui-select__trigger--ghost.ui-select__trigger--neutral{background:transparent;border:1px solid transparent;color:var(--color-text)}.ui-select__trigger--ghost.ui-select__trigger--neutral:hover:not(:disabled){background:var(--color-neutral-100)}.ui-select__trigger--ghost.ui-select__trigger--neutral:focus-visible{box-shadow:0 0 0 2px var(--color-primary-500)}.ui-select__trigger--none.ui-select__trigger--neutral{background:transparent;border:none;color:var(--color-text)}.ui-select__trigger--outline.ui-select__trigger--primary{background:var(--color-bg);border:1px solid var(--color-primary-500);color:var(--color-primary-600)}.ui-select__trigger--outline.ui-select__trigger--primary:hover:not(:disabled){border-color:var(--color-primary-600);background:color-mix(in srgb,var(--color-primary-500) 5%,transparent)}.ui-select__trigger--outline.ui-select__trigger--primary:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary-500) 30%,transparent)}.ui-select__trigger--soft.ui-select__trigger--primary{background:color-mix(in srgb,var(--color-primary-500) 10%,transparent);border:1px solid transparent;color:var(--color-primary-600)}.ui-select__trigger--soft.ui-select__trigger--primary:hover:not(:disabled){background:color-mix(in srgb,var(--color-primary-500) 15%,transparent)}.ui-select__trigger--soft.ui-select__trigger--primary:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary-500) 40%,transparent)}.ui-select__trigger--outline.ui-select__trigger--error{background:var(--color-bg);border:1px solid var(--color-error-500);color:var(--color-error-600)}.ui-select__trigger--outline.ui-select__trigger--error:hover:not(:disabled){background:color-mix(in srgb,var(--color-error-500) 5%,transparent)}.ui-select__trigger--outline.ui-select__trigger--error:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-error-500) 30%,transparent)}.ui-select__trigger--soft.ui-select__trigger--error{background:color-mix(in srgb,var(--color-error-500) 10%,transparent);border:1px solid transparent;color:var(--color-error-700)}.ui-select__trigger--soft.ui-select__trigger--error:hover:not(:disabled){background:color-mix(in srgb,var(--color-error-500) 15%,transparent)}.ui-select__trigger--soft.ui-select__trigger--error:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-error-500) 40%,transparent)}.ui-select__trigger--outline.ui-select__trigger--warning{background:var(--color-bg);border:1px solid var(--color-warning-500);color:var(--color-warning-600)}.ui-select__trigger--outline.ui-select__trigger--warning:hover:not(:disabled){background:color-mix(in srgb,var(--color-warning-500) 5%,transparent)}.ui-select__trigger--outline.ui-select__trigger--warning:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-warning-500) 30%,transparent)}.ui-select__trigger--soft.ui-select__trigger--warning{background:color-mix(in srgb,var(--color-warning-500) 10%,transparent);border:1px solid transparent;color:var(--color-warning-700)}.ui-select__trigger--soft.ui-select__trigger--warning:hover:not(:disabled){background:color-mix(in srgb,var(--color-warning-500) 15%,transparent)}.ui-select__trigger--soft.ui-select__trigger--warning:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-warning-500) 40%,transparent)}.ui-select__trigger--outline.ui-select__trigger--success{background:var(--color-bg);border:1px solid var(--color-success-500);color:var(--color-success-600)}.ui-select__trigger--outline.ui-select__trigger--success:hover:not(:disabled){background:color-mix(in srgb,var(--color-success-500) 5%,transparent)}.ui-select__trigger--outline.ui-select__trigger--success:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-success-500) 30%,transparent)}.ui-select__trigger--soft.ui-select__trigger--success{background:color-mix(in srgb,var(--color-success-500) 10%,transparent);border:1px solid transparent;color:var(--color-success-700)}.ui-select__trigger--soft.ui-select__trigger--success:hover:not(:disabled){background:color-mix(in srgb,var(--color-success-500) 15%,transparent)}.ui-select__trigger--soft.ui-select__trigger--success:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-success-500) 40%,transparent)}.ui-select__trigger--outline.ui-select__trigger--info{background:var(--color-bg);border:1px solid var(--color-info-500);color:var(--color-info-600)}.ui-select__trigger--outline.ui-select__trigger--info:hover:not(:disabled){background:color-mix(in srgb,var(--color-info-500) 5%,transparent)}.ui-select__trigger--outline.ui-select__trigger--info:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-info-500) 30%,transparent)}.ui-select__trigger--soft.ui-select__trigger--info{background:color-mix(in srgb,var(--color-info-500) 10%,transparent);border:1px solid transparent;color:var(--color-info-700)}.ui-select__trigger--soft.ui-select__trigger--info:hover:not(:disabled){background:color-mix(in srgb,var(--color-info-500) 15%,transparent)}.ui-select__trigger--soft.ui-select__trigger--info:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-info-500) 40%,transparent)}.ui-select__trigger--outline.ui-select__trigger--secondary{background:var(--color-bg);border:1px solid var(--color-secondary-500);color:var(--color-secondary-600)}.ui-select__trigger--outline.ui-select__trigger--secondary:hover:not(:disabled){background:color-mix(in srgb,var(--color-secondary-500) 5%,transparent)}.ui-select__trigger--outline.ui-select__trigger--secondary:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-secondary-500) 30%,transparent)}.ui-select__trigger--soft.ui-select__trigger--secondary{background:color-mix(in srgb,var(--color-secondary-500) 10%,transparent);border:1px solid transparent;color:var(--color-secondary-700)}.ui-select__trigger--soft.ui-select__trigger--secondary:hover:not(:disabled){background:color-mix(in srgb,var(--color-secondary-500) 15%,transparent)}.ui-select__trigger--soft.ui-select__trigger--secondary:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-secondary-500) 40%,transparent)}.ui-select--open .ui-select__trigger--outline{border-color:var(--color-primary-500)}.ui-select__trigger:disabled{cursor:not-allowed}.ui-select__leading{display:flex;align-items:center;flex-shrink:0;color:var(--color-text-muted);width:1rem;height:1rem}.ui-select__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-select__value--placeholder{color:var(--color-text-muted)}.ui-select__chevron{display:flex;align-items:center;flex-shrink:0;color:var(--color-text-muted);width:1rem;height:1rem;transition:transform .15s ease}.ui-select__chevron svg{width:100%;height:100%}.ui-select__chevron--open{transform:rotate(180deg)}.ui-select__spinner{display:inline-flex;align-items:center}.ui-select__spinner svg{width:1em;height:1em;animation:ui-spin .75s linear infinite}@keyframes ui-spin{to{transform:rotate(360deg)}}.ui-select__panel{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:var(--z-dropdown, 50);min-width:100%;background:var(--color-bg);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:var(--shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -4px rgba(0, 0, 0, .1));padding:4px;overflow:hidden;overflow-y:auto;max-height:240px;transform-origin:top center}.ui-select__option{display:flex;align-items:center;gap:.5rem;width:100%;padding:6px 8px;border-radius:calc(var(--radius-md) - 2px);font-family:var(--font-sans);font-size:var(--text-sm);font-weight:var(--font-normal);color:var(--color-text);background:transparent;border:none;cursor:pointer;text-align:left;transition:background-color .1s ease}.ui-select__option:hover:not(:disabled),.ui-select__option--highlighted:not(:disabled){background:var(--color-neutral-100)}.ui-select__option--selected{color:var(--color-primary-600);font-weight:var(--font-medium);background:color-mix(in srgb,var(--color-primary-500) 8%,transparent)}.ui-select__option--selected:hover,.ui-select__option--selected.ui-select__option--highlighted{background:color-mix(in srgb,var(--color-primary-500) 12%,transparent)}.ui-select__option--disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.ui-select__option-icon{flex-shrink:0;font-size:1rem;line-height:1}.ui-select__option-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-select__option-check{flex-shrink:0;width:1rem;height:1rem;color:var(--color-primary-500);display:flex;align-items:center}.ui-select__option-check svg{width:100%;height:100%}.ui-select__empty{padding:12px 8px;text-align:center;font-size:var(--text-sm);color:var(--color-text-muted)}[data-theme=dark] .ui-select__trigger--outline.ui-select__trigger--neutral{background:var(--color-neutral-900);border-color:var(--color-neutral-700)}[data-theme=dark] .ui-select__trigger--outline.ui-select__trigger--neutral:hover:not(:disabled){border-color:var(--color-neutral-500)}[data-theme=dark] .ui-select__trigger--soft.ui-select__trigger--neutral{background:var(--color-neutral-800)}[data-theme=dark] .ui-select__panel{background:var(--color-neutral-900);border-color:var(--color-neutral-700)}[data-theme=dark] .ui-select__option:hover:not(:disabled),[data-theme=dark] .ui-select__option--highlighted:not(:disabled){background:var(--color-neutral-800)}[data-theme=dark] .ui-select__option--selected{background:color-mix(in srgb,var(--color-primary-500) 12%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], animations: [
773
+ trigger('dropdown', [
774
+ transition(':enter', [
775
+ style({ opacity: 0, transform: 'scale(0.96) translateY(-4px)' }),
776
+ animate('100ms ease-out', style({ opacity: 1, transform: 'scale(1) translateY(0)' })),
777
+ ]),
778
+ transition(':leave', [
779
+ animate('80ms ease-in', style({ opacity: 0, transform: 'scale(0.96) translateY(-4px)' })),
780
+ ]),
781
+ ]),
782
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
783
+ }
784
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: SelectComponent, decorators: [{
785
+ type: Component,
786
+ args: [{ selector: 'ui-select', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [{
787
+ provide: NG_VALUE_ACCESSOR,
788
+ useExisting: forwardRef(() => SelectComponent),
789
+ multi: true,
790
+ }], animations: [
791
+ trigger('dropdown', [
792
+ transition(':enter', [
793
+ style({ opacity: 0, transform: 'scale(0.96) translateY(-4px)' }),
794
+ animate('100ms ease-out', style({ opacity: 1, transform: 'scale(1) translateY(0)' })),
795
+ ]),
796
+ transition(':leave', [
797
+ animate('80ms ease-in', style({ opacity: 0, transform: 'scale(0.96) translateY(-4px)' })),
798
+ ]),
799
+ ]),
800
+ ], template: `
801
+ <div
802
+ class="ui-select"
803
+ [class.ui-select--open]="isOpen()"
804
+ [class.ui-select--disabled]="disabled()"
805
+ >
806
+ <!-- Trigger -->
807
+ <button
808
+ #triggerEl
809
+ type="button"
810
+ [class]="triggerClasses()"
811
+ [disabled]="disabled() || loading()"
812
+ [attr.aria-haspopup]="'listbox'"
813
+ [attr.aria-expanded]="isOpen()"
814
+ [attr.aria-label]="ariaLabel() ?? null"
815
+ (click)="toggleOpen(); $event.stopPropagation()"
816
+ (keydown)="onTriggerKeydown($event)"
817
+ >
818
+ @if (leadingIcon()) {
819
+ <span class="ui-select__leading" aria-hidden="true">
820
+ <ng-content select="[slot=leading]" />
821
+ </span>
822
+ }
823
+
824
+ <span class="ui-select__value" [class.ui-select__value--placeholder]="!selectedOption()">
825
+ @if (loading()) {
826
+ <span class="ui-select__spinner" aria-hidden="true">
827
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
828
+ <circle cx="12" cy="12" r="10" stroke-opacity="0.25"/>
829
+ <path d="M12 2a10 10 0 0 1 10 10" stroke-linecap="round"/>
830
+ </svg>
831
+ </span>
832
+ } @else {
833
+ {{ selectedOption()?.label ?? placeholder() ?? 'Sélectionner...' }}
834
+ }
835
+ </span>
836
+
837
+ <span class="ui-select__chevron" [class.ui-select__chevron--open]="isOpen()" aria-hidden="true">
838
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.75"
839
+ stroke-linecap="round" stroke-linejoin="round">
840
+ <path d="M4 6l4 4 4-4"/>
841
+ </svg>
842
+ </span>
843
+ </button>
844
+
845
+ <!-- Dropdown panel -->
846
+ @if (isOpen()) {
847
+ <div
848
+ [@dropdown]
849
+ class="ui-select__panel"
850
+ role="listbox"
851
+ [attr.aria-label]="ariaLabel() ?? 'Options'"
852
+ (click)="$event.stopPropagation()"
853
+ >
854
+ @for (opt of options(); track opt.value; let i = $index) {
855
+ <button
856
+ type="button"
857
+ class="ui-select__option"
858
+ role="option"
859
+ [class.ui-select__option--selected]="isSelected(opt)"
860
+ [class.ui-select__option--highlighted]="activeIndex() === i"
861
+ [class.ui-select__option--disabled]="opt.disabled"
862
+ [attr.aria-selected]="isSelected(opt)"
863
+ [disabled]="opt.disabled"
864
+ (click)="selectOption(opt)"
865
+ (mouseenter)="activeIndex.set(i)"
866
+ >
867
+ @if (opt.icon) {
868
+ <span class="ui-select__option-icon" aria-hidden="true">{{ opt.icon }}</span>
869
+ }
870
+ <span class="ui-select__option-label">{{ opt.label }}</span>
871
+ @if (isSelected(opt)) {
872
+ <span class="ui-select__option-check" aria-hidden="true">
873
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2.25"
874
+ stroke-linecap="round" stroke-linejoin="round">
875
+ <path d="M3 8l3.5 3.5L13 5"/>
876
+ </svg>
877
+ </span>
878
+ }
879
+ </button>
880
+ }
881
+ @if (options().length === 0) {
882
+ <div class="ui-select__empty">Aucune option disponible</div>
883
+ }
884
+ </div>
885
+ }
886
+ </div>
887
+ `, styles: [".ui-select{position:relative;display:inline-block;width:100%}.ui-select--disabled{opacity:.5;cursor:not-allowed}.ui-select__trigger{display:inline-flex;align-items:center;gap:.375rem;width:100%;border-radius:var(--radius-md);font-family:var(--font-sans);font-weight:var(--font-medium);cursor:pointer;outline:none;transition:background-color var(--transition-colors),border-color var(--transition-colors),box-shadow var(--transition-colors);text-align:left;white-space:nowrap;overflow:hidden}.ui-select__trigger--xs{height:var(--size-xs);padding:0 8px;font-size:var(--text-xs)}.ui-select__trigger--sm{height:var(--size-sm);padding:0 10px;font-size:var(--text-xs)}.ui-select__trigger--md{height:var(--size-md);padding:0 10px;font-size:var(--text-sm)}.ui-select__trigger--lg{height:var(--size-lg);padding:0 12px;font-size:var(--text-sm)}.ui-select__trigger--xl{height:var(--size-xl);padding:0 12px;font-size:var(--text-md)}.ui-select__trigger--outline.ui-select__trigger--neutral{background:var(--color-bg);border:1px solid var(--color-border);color:var(--color-text)}.ui-select__trigger--outline.ui-select__trigger--neutral:hover:not(:disabled){border-color:var(--color-neutral-400)}.ui-select__trigger--outline.ui-select__trigger--neutral:focus-visible{border-color:var(--color-primary-500);box-shadow:0 0 0 1px var(--color-primary-500)}.ui-select__trigger--soft.ui-select__trigger--neutral{background:var(--color-neutral-100);border:1px solid transparent;color:var(--color-text)}.ui-select__trigger--soft.ui-select__trigger--neutral:hover:not(:disabled){background:var(--color-neutral-200)}.ui-select__trigger--soft.ui-select__trigger--neutral:focus-visible{box-shadow:0 0 0 2px var(--color-primary-500)}.ui-select__trigger--subtle.ui-select__trigger--neutral{background:transparent;border:1px solid transparent;color:var(--color-text)}.ui-select__trigger--subtle.ui-select__trigger--neutral:hover:not(:disabled){background:var(--color-neutral-100)}.ui-select__trigger--subtle.ui-select__trigger--neutral:focus-visible{box-shadow:0 0 0 2px var(--color-primary-500)}.ui-select__trigger--ghost.ui-select__trigger--neutral{background:transparent;border:1px solid transparent;color:var(--color-text)}.ui-select__trigger--ghost.ui-select__trigger--neutral:hover:not(:disabled){background:var(--color-neutral-100)}.ui-select__trigger--ghost.ui-select__trigger--neutral:focus-visible{box-shadow:0 0 0 2px var(--color-primary-500)}.ui-select__trigger--none.ui-select__trigger--neutral{background:transparent;border:none;color:var(--color-text)}.ui-select__trigger--outline.ui-select__trigger--primary{background:var(--color-bg);border:1px solid var(--color-primary-500);color:var(--color-primary-600)}.ui-select__trigger--outline.ui-select__trigger--primary:hover:not(:disabled){border-color:var(--color-primary-600);background:color-mix(in srgb,var(--color-primary-500) 5%,transparent)}.ui-select__trigger--outline.ui-select__trigger--primary:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary-500) 30%,transparent)}.ui-select__trigger--soft.ui-select__trigger--primary{background:color-mix(in srgb,var(--color-primary-500) 10%,transparent);border:1px solid transparent;color:var(--color-primary-600)}.ui-select__trigger--soft.ui-select__trigger--primary:hover:not(:disabled){background:color-mix(in srgb,var(--color-primary-500) 15%,transparent)}.ui-select__trigger--soft.ui-select__trigger--primary:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary-500) 40%,transparent)}.ui-select__trigger--outline.ui-select__trigger--error{background:var(--color-bg);border:1px solid var(--color-error-500);color:var(--color-error-600)}.ui-select__trigger--outline.ui-select__trigger--error:hover:not(:disabled){background:color-mix(in srgb,var(--color-error-500) 5%,transparent)}.ui-select__trigger--outline.ui-select__trigger--error:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-error-500) 30%,transparent)}.ui-select__trigger--soft.ui-select__trigger--error{background:color-mix(in srgb,var(--color-error-500) 10%,transparent);border:1px solid transparent;color:var(--color-error-700)}.ui-select__trigger--soft.ui-select__trigger--error:hover:not(:disabled){background:color-mix(in srgb,var(--color-error-500) 15%,transparent)}.ui-select__trigger--soft.ui-select__trigger--error:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-error-500) 40%,transparent)}.ui-select__trigger--outline.ui-select__trigger--warning{background:var(--color-bg);border:1px solid var(--color-warning-500);color:var(--color-warning-600)}.ui-select__trigger--outline.ui-select__trigger--warning:hover:not(:disabled){background:color-mix(in srgb,var(--color-warning-500) 5%,transparent)}.ui-select__trigger--outline.ui-select__trigger--warning:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-warning-500) 30%,transparent)}.ui-select__trigger--soft.ui-select__trigger--warning{background:color-mix(in srgb,var(--color-warning-500) 10%,transparent);border:1px solid transparent;color:var(--color-warning-700)}.ui-select__trigger--soft.ui-select__trigger--warning:hover:not(:disabled){background:color-mix(in srgb,var(--color-warning-500) 15%,transparent)}.ui-select__trigger--soft.ui-select__trigger--warning:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-warning-500) 40%,transparent)}.ui-select__trigger--outline.ui-select__trigger--success{background:var(--color-bg);border:1px solid var(--color-success-500);color:var(--color-success-600)}.ui-select__trigger--outline.ui-select__trigger--success:hover:not(:disabled){background:color-mix(in srgb,var(--color-success-500) 5%,transparent)}.ui-select__trigger--outline.ui-select__trigger--success:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-success-500) 30%,transparent)}.ui-select__trigger--soft.ui-select__trigger--success{background:color-mix(in srgb,var(--color-success-500) 10%,transparent);border:1px solid transparent;color:var(--color-success-700)}.ui-select__trigger--soft.ui-select__trigger--success:hover:not(:disabled){background:color-mix(in srgb,var(--color-success-500) 15%,transparent)}.ui-select__trigger--soft.ui-select__trigger--success:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-success-500) 40%,transparent)}.ui-select__trigger--outline.ui-select__trigger--info{background:var(--color-bg);border:1px solid var(--color-info-500);color:var(--color-info-600)}.ui-select__trigger--outline.ui-select__trigger--info:hover:not(:disabled){background:color-mix(in srgb,var(--color-info-500) 5%,transparent)}.ui-select__trigger--outline.ui-select__trigger--info:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-info-500) 30%,transparent)}.ui-select__trigger--soft.ui-select__trigger--info{background:color-mix(in srgb,var(--color-info-500) 10%,transparent);border:1px solid transparent;color:var(--color-info-700)}.ui-select__trigger--soft.ui-select__trigger--info:hover:not(:disabled){background:color-mix(in srgb,var(--color-info-500) 15%,transparent)}.ui-select__trigger--soft.ui-select__trigger--info:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-info-500) 40%,transparent)}.ui-select__trigger--outline.ui-select__trigger--secondary{background:var(--color-bg);border:1px solid var(--color-secondary-500);color:var(--color-secondary-600)}.ui-select__trigger--outline.ui-select__trigger--secondary:hover:not(:disabled){background:color-mix(in srgb,var(--color-secondary-500) 5%,transparent)}.ui-select__trigger--outline.ui-select__trigger--secondary:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-secondary-500) 30%,transparent)}.ui-select__trigger--soft.ui-select__trigger--secondary{background:color-mix(in srgb,var(--color-secondary-500) 10%,transparent);border:1px solid transparent;color:var(--color-secondary-700)}.ui-select__trigger--soft.ui-select__trigger--secondary:hover:not(:disabled){background:color-mix(in srgb,var(--color-secondary-500) 15%,transparent)}.ui-select__trigger--soft.ui-select__trigger--secondary:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-secondary-500) 40%,transparent)}.ui-select--open .ui-select__trigger--outline{border-color:var(--color-primary-500)}.ui-select__trigger:disabled{cursor:not-allowed}.ui-select__leading{display:flex;align-items:center;flex-shrink:0;color:var(--color-text-muted);width:1rem;height:1rem}.ui-select__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-select__value--placeholder{color:var(--color-text-muted)}.ui-select__chevron{display:flex;align-items:center;flex-shrink:0;color:var(--color-text-muted);width:1rem;height:1rem;transition:transform .15s ease}.ui-select__chevron svg{width:100%;height:100%}.ui-select__chevron--open{transform:rotate(180deg)}.ui-select__spinner{display:inline-flex;align-items:center}.ui-select__spinner svg{width:1em;height:1em;animation:ui-spin .75s linear infinite}@keyframes ui-spin{to{transform:rotate(360deg)}}.ui-select__panel{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:var(--z-dropdown, 50);min-width:100%;background:var(--color-bg);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:var(--shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -4px rgba(0, 0, 0, .1));padding:4px;overflow:hidden;overflow-y:auto;max-height:240px;transform-origin:top center}.ui-select__option{display:flex;align-items:center;gap:.5rem;width:100%;padding:6px 8px;border-radius:calc(var(--radius-md) - 2px);font-family:var(--font-sans);font-size:var(--text-sm);font-weight:var(--font-normal);color:var(--color-text);background:transparent;border:none;cursor:pointer;text-align:left;transition:background-color .1s ease}.ui-select__option:hover:not(:disabled),.ui-select__option--highlighted:not(:disabled){background:var(--color-neutral-100)}.ui-select__option--selected{color:var(--color-primary-600);font-weight:var(--font-medium);background:color-mix(in srgb,var(--color-primary-500) 8%,transparent)}.ui-select__option--selected:hover,.ui-select__option--selected.ui-select__option--highlighted{background:color-mix(in srgb,var(--color-primary-500) 12%,transparent)}.ui-select__option--disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.ui-select__option-icon{flex-shrink:0;font-size:1rem;line-height:1}.ui-select__option-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-select__option-check{flex-shrink:0;width:1rem;height:1rem;color:var(--color-primary-500);display:flex;align-items:center}.ui-select__option-check svg{width:100%;height:100%}.ui-select__empty{padding:12px 8px;text-align:center;font-size:var(--text-sm);color:var(--color-text-muted)}[data-theme=dark] .ui-select__trigger--outline.ui-select__trigger--neutral{background:var(--color-neutral-900);border-color:var(--color-neutral-700)}[data-theme=dark] .ui-select__trigger--outline.ui-select__trigger--neutral:hover:not(:disabled){border-color:var(--color-neutral-500)}[data-theme=dark] .ui-select__trigger--soft.ui-select__trigger--neutral{background:var(--color-neutral-800)}[data-theme=dark] .ui-select__panel{background:var(--color-neutral-900);border-color:var(--color-neutral-700)}[data-theme=dark] .ui-select__option:hover:not(:disabled),[data-theme=dark] .ui-select__option--highlighted:not(:disabled){background:var(--color-neutral-800)}[data-theme=dark] .ui-select__option--selected{background:color-mix(in srgb,var(--color-primary-500) 12%,transparent)}\n"] }]
888
+ }], propDecorators: { triggerEl: [{
889
+ type: ViewChild,
890
+ args: ['triggerEl']
891
+ }], onDocumentClick: [{
892
+ type: HostListener,
893
+ args: ['document:click', ['$event']]
894
+ }] } });
895
+
896
+ /**
897
+ * Tabs Molecule — Source: Nuxt UI v3 ❖ Tabs
898
+ * Tabbed navigation with pill, link and underline variants
899
+ */
900
+ class TabsComponent {
901
+ constructor() {
902
+ this.items = input.required();
903
+ this.variant = input('pill');
904
+ this.size = input('md');
905
+ this.activeId = model('');
906
+ }
907
+ select(id) { this.activeId.set(id); }
908
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
909
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: TabsComponent, isStandalone: true, selector: "ui-tabs", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, activeId: { classPropertyName: "activeId", publicName: "activeId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeId: "activeIdChange" }, ngImport: i0, template: `
910
+ <div class="ui-tabs ui-tabs--{{ variant() }} ui-tabs--{{ size() }}" role="tablist">
911
+ @for (tab of items(); track tab.id) {
912
+ <button
913
+ role="tab"
914
+ type="button"
915
+ [class]="'ui-tabs__tab' + (activeId() === tab.id ? ' ui-tabs__tab--active' : '') + (tab.disabled ? ' ui-tabs__tab--disabled' : '')"
916
+ [attr.aria-selected]="activeId() === tab.id"
917
+ [attr.aria-controls]="'panel-' + tab.id"
918
+ [disabled]="tab.disabled"
919
+ (click)="select(tab.id)"
920
+ >
921
+ {{ tab.label }}
922
+ @if (tab.count !== undefined) {
923
+ <span class="ui-tabs__count">{{ tab.count }}</span>
924
+ }
925
+ </button>
926
+ }
927
+ </div>
928
+ <div class="ui-tabs__panels">
929
+ <ng-content />
930
+ </div>
931
+ `, isInline: true, styles: [".ui-tabs{display:flex;align-items:center;gap:var(--spacing-1);overflow-x:auto}.ui-tabs--xs .ui-tabs__tab{height:var(--size-xs);padding:0 8px;font-size:var(--text-xs)}.ui-tabs--sm .ui-tabs__tab{height:var(--size-sm);padding:0 10px;font-size:var(--text-xs)}.ui-tabs--md .ui-tabs__tab{height:var(--size-md);padding:0 12px;font-size:var(--text-sm)}.ui-tabs--lg .ui-tabs__tab{height:var(--size-lg);padding:0 14px;font-size:var(--text-sm)}.ui-tabs--xl .ui-tabs__tab{height:var(--size-xl);padding:0 16px;font-size:var(--text-md)}.ui-tabs__tab{display:inline-flex;align-items:center;justify-content:center;gap:var(--spacing-2);cursor:pointer;border:none;background:transparent;font-family:var(--font-sans);font-weight:var(--font-medium);color:var(--color-text-muted);border-radius:var(--radius-md);white-space:nowrap;transition:var(--transition-colors)}.ui-tabs__tab:hover:not(.ui-tabs__tab--disabled){color:var(--color-text)}.ui-tabs__tab--disabled{opacity:.5;cursor:not-allowed}.ui-tabs__count{display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 .25rem;border-radius:var(--radius-full);font-size:.75em;background:var(--color-neutral-100);color:var(--color-text-muted)}.ui-tabs--pill .ui-tabs__tab--active{background:var(--color-primary-500);color:#fff}.ui-tabs--pill .ui-tabs__tab--active .ui-tabs__count{background:#ffffff4d;color:#fff}.ui-tabs--link .ui-tabs__tab--active{color:var(--color-primary-500);font-weight:var(--font-semibold)}.ui-tabs--underline{border-bottom:1px solid var(--color-border);border-radius:0;gap:0}.ui-tabs--underline .ui-tabs__tab{border-radius:0;border-bottom:2px solid transparent;margin-bottom:-1px}.ui-tabs--underline .ui-tabs__tab--active{color:var(--color-primary-500);border-bottom-color:var(--color-primary-500)}.ui-tabs__panels{margin-top:var(--spacing-4)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
932
+ }
933
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TabsComponent, decorators: [{
934
+ type: Component,
935
+ args: [{ selector: 'ui-tabs', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
936
+ <div class="ui-tabs ui-tabs--{{ variant() }} ui-tabs--{{ size() }}" role="tablist">
937
+ @for (tab of items(); track tab.id) {
938
+ <button
939
+ role="tab"
940
+ type="button"
941
+ [class]="'ui-tabs__tab' + (activeId() === tab.id ? ' ui-tabs__tab--active' : '') + (tab.disabled ? ' ui-tabs__tab--disabled' : '')"
942
+ [attr.aria-selected]="activeId() === tab.id"
943
+ [attr.aria-controls]="'panel-' + tab.id"
944
+ [disabled]="tab.disabled"
945
+ (click)="select(tab.id)"
946
+ >
947
+ {{ tab.label }}
948
+ @if (tab.count !== undefined) {
949
+ <span class="ui-tabs__count">{{ tab.count }}</span>
950
+ }
951
+ </button>
952
+ }
953
+ </div>
954
+ <div class="ui-tabs__panels">
955
+ <ng-content />
956
+ </div>
957
+ `, styles: [".ui-tabs{display:flex;align-items:center;gap:var(--spacing-1);overflow-x:auto}.ui-tabs--xs .ui-tabs__tab{height:var(--size-xs);padding:0 8px;font-size:var(--text-xs)}.ui-tabs--sm .ui-tabs__tab{height:var(--size-sm);padding:0 10px;font-size:var(--text-xs)}.ui-tabs--md .ui-tabs__tab{height:var(--size-md);padding:0 12px;font-size:var(--text-sm)}.ui-tabs--lg .ui-tabs__tab{height:var(--size-lg);padding:0 14px;font-size:var(--text-sm)}.ui-tabs--xl .ui-tabs__tab{height:var(--size-xl);padding:0 16px;font-size:var(--text-md)}.ui-tabs__tab{display:inline-flex;align-items:center;justify-content:center;gap:var(--spacing-2);cursor:pointer;border:none;background:transparent;font-family:var(--font-sans);font-weight:var(--font-medium);color:var(--color-text-muted);border-radius:var(--radius-md);white-space:nowrap;transition:var(--transition-colors)}.ui-tabs__tab:hover:not(.ui-tabs__tab--disabled){color:var(--color-text)}.ui-tabs__tab--disabled{opacity:.5;cursor:not-allowed}.ui-tabs__count{display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 .25rem;border-radius:var(--radius-full);font-size:.75em;background:var(--color-neutral-100);color:var(--color-text-muted)}.ui-tabs--pill .ui-tabs__tab--active{background:var(--color-primary-500);color:#fff}.ui-tabs--pill .ui-tabs__tab--active .ui-tabs__count{background:#ffffff4d;color:#fff}.ui-tabs--link .ui-tabs__tab--active{color:var(--color-primary-500);font-weight:var(--font-semibold)}.ui-tabs--underline{border-bottom:1px solid var(--color-border);border-radius:0;gap:0}.ui-tabs--underline .ui-tabs__tab{border-radius:0;border-bottom:2px solid transparent;margin-bottom:-1px}.ui-tabs--underline .ui-tabs__tab--active{color:var(--color-primary-500);border-bottom-color:var(--color-primary-500)}.ui-tabs__panels{margin-top:var(--spacing-4)}\n"] }]
958
+ }] });
959
+
960
+ /**
961
+ * Textarea Molecule — Source: Nuxt UI v3 ❖ Textarea
962
+ * Multi-line text input with auto-resize support
963
+ */
964
+ class TextareaComponent {
965
+ constructor() {
966
+ this.placeholder = input('');
967
+ this.size = input('md');
968
+ this.rows = input(4);
969
+ this.disabled = input(false);
970
+ this.readonly = input(false);
971
+ this.autoResize = input(false);
972
+ this.ariaLabel = input(null);
973
+ this.value = model('');
974
+ this._onChange = () => { };
975
+ this.onTouched = () => { };
976
+ }
977
+ onInput(e) {
978
+ const el = e.target;
979
+ this.value.set(el.value);
980
+ this._onChange(el.value);
981
+ }
982
+ writeValue(v) { this.value.set(v ?? ''); }
983
+ registerOnChange(fn) { this._onChange = fn; }
984
+ registerOnTouched(fn) { this.onTouched = fn; }
985
+ setDisabledState(_) { }
986
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
987
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.20", type: TextareaComponent, isStandalone: true, selector: "ui-textarea", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, autoResize: { classPropertyName: "autoResize", publicName: "autoResize", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TextareaComponent), multi: true }], ngImport: i0, template: `
988
+ <textarea
989
+ [class]="'ui-textarea ui-textarea--' + size()"
990
+ [placeholder]="placeholder()"
991
+ [disabled]="disabled()"
992
+ [readonly]="readonly()"
993
+ [rows]="rows()"
994
+ [attr.aria-label]="ariaLabel() ?? null"
995
+ (input)="onInput($event)"
996
+ (blur)="onTouched()"
997
+ >{{ value() }}</textarea>
998
+ `, isInline: true, styles: [".ui-textarea{width:100%;display:block;font-family:var(--font-sans);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-bg);color:var(--color-text);resize:vertical;outline:none;transition:var(--transition-colors)}.ui-textarea::placeholder{color:var(--color-text-subtle)}.ui-textarea:focus{border-color:var(--color-primary-500);box-shadow:0 0 0 1px var(--color-primary-500)}.ui-textarea:disabled{opacity:.5;cursor:not-allowed;resize:none}.ui-textarea--xs{padding:6px 8px;font-size:var(--text-xs)}.ui-textarea--sm{padding:8px 10px;font-size:var(--text-xs)}.ui-textarea--md{padding:8px 10px;font-size:var(--text-sm)}.ui-textarea--lg{padding:10px 12px;font-size:var(--text-sm)}.ui-textarea--xl{padding:10px 12px;font-size:var(--text-md)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
999
+ }
1000
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: TextareaComponent, decorators: [{
1001
+ type: Component,
1002
+ args: [{ selector: 'ui-textarea', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TextareaComponent), multi: true }], template: `
1003
+ <textarea
1004
+ [class]="'ui-textarea ui-textarea--' + size()"
1005
+ [placeholder]="placeholder()"
1006
+ [disabled]="disabled()"
1007
+ [readonly]="readonly()"
1008
+ [rows]="rows()"
1009
+ [attr.aria-label]="ariaLabel() ?? null"
1010
+ (input)="onInput($event)"
1011
+ (blur)="onTouched()"
1012
+ >{{ value() }}</textarea>
1013
+ `, styles: [".ui-textarea{width:100%;display:block;font-family:var(--font-sans);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-bg);color:var(--color-text);resize:vertical;outline:none;transition:var(--transition-colors)}.ui-textarea::placeholder{color:var(--color-text-subtle)}.ui-textarea:focus{border-color:var(--color-primary-500);box-shadow:0 0 0 1px var(--color-primary-500)}.ui-textarea:disabled{opacity:.5;cursor:not-allowed;resize:none}.ui-textarea--xs{padding:6px 8px;font-size:var(--text-xs)}.ui-textarea--sm{padding:8px 10px;font-size:var(--text-xs)}.ui-textarea--md{padding:8px 10px;font-size:var(--text-sm)}.ui-textarea--lg{padding:10px 12px;font-size:var(--text-sm)}.ui-textarea--xl{padding:10px 12px;font-size:var(--text-md)}\n"] }]
1014
+ }] });
1015
+
1016
+ /**
1017
+ * Toast Molecule — Source: Nuxt UI v3 ❖ Toast
1018
+ * Transient notification with auto-close
1019
+ */
1020
+ class ToastComponent {
1021
+ constructor() {
1022
+ this.variant = input('soft');
1023
+ this.color = input('neutral');
1024
+ this.title = input(null);
1025
+ this.description = input(null);
1026
+ this.icon = input(false);
1027
+ this.closable = input(true);
1028
+ this.close = output();
1029
+ }
1030
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ToastComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1031
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: ToastComponent, isStandalone: true, selector: "ui-toast", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close" }, ngImport: i0, template: `
1032
+ <div
1033
+ [class]="'ui-toast ui-toast--' + variant() + ' ui-toast--' + color()"
1034
+ role="status"
1035
+ aria-live="polite"
1036
+ aria-atomic="true"
1037
+ >
1038
+ @if (icon()) {
1039
+ <span class="ui-toast__icon" aria-hidden="true">
1040
+ <ng-content select="[slot=icon]" />
1041
+ </span>
1042
+ }
1043
+ <div class="ui-toast__body">
1044
+ @if (title()) {
1045
+ <p class="ui-toast__title">{{ title() }}</p>
1046
+ }
1047
+ @if (description()) {
1048
+ <p class="ui-toast__description">{{ description() }}</p>
1049
+ }
1050
+ <ng-content />
1051
+ </div>
1052
+ @if (closable()) {
1053
+ <button type="button" class="ui-toast__close" aria-label="Dismiss" (click)="close.emit()">×</button>
1054
+ }
1055
+ </div>
1056
+ `, isInline: true, styles: [".ui-toast{display:flex;align-items:flex-start;gap:var(--spacing-3);padding:var(--spacing-3) var(--spacing-4);border-radius:var(--radius-lg);border:1px solid transparent;box-shadow:var(--shadow-lg);min-width:280px;max-width:480px;background:var(--color-bg);pointer-events:auto}.ui-toast__icon{flex-shrink:0;width:1.25rem;height:1.25rem}.ui-toast__body{flex:1;min-width:0}.ui-toast__title{font-family:var(--font-sans);font-size:var(--text-sm);font-weight:var(--font-semibold);color:var(--color-text);margin:0}.ui-toast__description{font-family:var(--font-sans);font-size:var(--text-xs);color:var(--color-text-muted);margin:var(--spacing-0-5) 0 0}.ui-toast__close{flex-shrink:0;cursor:pointer;border:none;background:transparent;font-size:1.25rem;color:var(--color-text-muted);line-height:1;padding:0}.ui-toast__close:hover{color:var(--color-text)}.ui-toast--success{border-color:var(--color-success-200)}.ui-toast--error{border-color:var(--color-error-200)}.ui-toast--warning{border-color:var(--color-warning-200)}.ui-toast--info{border-color:var(--color-info-200)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1057
+ }
1058
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ToastComponent, decorators: [{
1059
+ type: Component,
1060
+ args: [{ selector: 'ui-toast', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
1061
+ <div
1062
+ [class]="'ui-toast ui-toast--' + variant() + ' ui-toast--' + color()"
1063
+ role="status"
1064
+ aria-live="polite"
1065
+ aria-atomic="true"
1066
+ >
1067
+ @if (icon()) {
1068
+ <span class="ui-toast__icon" aria-hidden="true">
1069
+ <ng-content select="[slot=icon]" />
1070
+ </span>
1071
+ }
1072
+ <div class="ui-toast__body">
1073
+ @if (title()) {
1074
+ <p class="ui-toast__title">{{ title() }}</p>
1075
+ }
1076
+ @if (description()) {
1077
+ <p class="ui-toast__description">{{ description() }}</p>
1078
+ }
1079
+ <ng-content />
1080
+ </div>
1081
+ @if (closable()) {
1082
+ <button type="button" class="ui-toast__close" aria-label="Dismiss" (click)="close.emit()">×</button>
1083
+ }
1084
+ </div>
1085
+ `, styles: [".ui-toast{display:flex;align-items:flex-start;gap:var(--spacing-3);padding:var(--spacing-3) var(--spacing-4);border-radius:var(--radius-lg);border:1px solid transparent;box-shadow:var(--shadow-lg);min-width:280px;max-width:480px;background:var(--color-bg);pointer-events:auto}.ui-toast__icon{flex-shrink:0;width:1.25rem;height:1.25rem}.ui-toast__body{flex:1;min-width:0}.ui-toast__title{font-family:var(--font-sans);font-size:var(--text-sm);font-weight:var(--font-semibold);color:var(--color-text);margin:0}.ui-toast__description{font-family:var(--font-sans);font-size:var(--text-xs);color:var(--color-text-muted);margin:var(--spacing-0-5) 0 0}.ui-toast__close{flex-shrink:0;cursor:pointer;border:none;background:transparent;font-size:1.25rem;color:var(--color-text-muted);line-height:1;padding:0}.ui-toast__close:hover{color:var(--color-text)}.ui-toast--success{border-color:var(--color-success-200)}.ui-toast--error{border-color:var(--color-error-200)}.ui-toast--warning{border-color:var(--color-warning-200)}.ui-toast--info{border-color:var(--color-info-200)}\n"] }]
1086
+ }] });
1087
+
1088
+ /**
1089
+ * SelectSearch Molecule — Source: Nuxt UI v3 ❖ SelectMenu / Combobox
1090
+ *
1091
+ * Extension du Select avec un input de recherche intégré dans le panel :
1092
+ * - Filtre les options en temps réel (case-insensitive)
1093
+ * - Highlight du terme recherché dans les labels
1094
+ * - "Aucun résultat" si aucune option trouvée
1095
+ * - Clavier : ↑↓ navigue, Enter sélectionne, Escape ferme, Tab ferme
1096
+ * - Focus automatique sur l'input à l'ouverture
1097
+ * - Même API / variants / couleurs / tailles que SelectComponent
1098
+ * - Compatible ControlValueAccessor
1099
+ *
1100
+ * @example
1101
+ * <ui-select-search [options]="pays" placeholder="Rechercher un pays..." />
1102
+ * <ui-select-search [(value)]="val" variant="soft" color="primary" />
1103
+ */
1104
+ class SelectSearchComponent {
1105
+ constructor() {
1106
+ // ── Inputs ───────────────────────────────────────────────
1107
+ this.options = input.required();
1108
+ this.placeholder = input(null);
1109
+ this.searchPlaceholder = input('Rechercher...');
1110
+ this.emptyLabel = input('Aucun résultat');
1111
+ this.size = input('md');
1112
+ this.variant = input('outline');
1113
+ this.color = input('neutral');
1114
+ this.disabled = input(false);
1115
+ this.loading = input(false);
1116
+ this.leadingIcon = input(false);
1117
+ this.ariaLabel = input(null);
1118
+ // ── Two-way binding ──────────────────────────────────────
1119
+ this.value = model('');
1120
+ this.change = output();
1121
+ // ── Internal state ───────────────────────────────────────
1122
+ this.isOpen = signal(false);
1123
+ this.activeIndex = signal(-1);
1124
+ this.query = signal('');
1125
+ this.selectedOption = computed(() => this.options().find(o => String(o.value) === String(this.value())));
1126
+ this.filteredOptions = computed(() => {
1127
+ const q = this.query().trim().toLowerCase();
1128
+ if (!q)
1129
+ return this.options();
1130
+ return this.options().filter(o => o.label.toLowerCase().includes(q));
1131
+ });
1132
+ this.triggerClasses = computed(() => ['ui-select-search__trigger',
1133
+ `ui-select-search__trigger--${this.size()}`,
1134
+ `ui-select-search__trigger--${this.variant()}`,
1135
+ `ui-select-search__trigger--${this.color()}`
1136
+ ].join(' '));
1137
+ // ── CVA ──────────────────────────────────────────────────
1138
+ this._onChange = () => { };
1139
+ this._onTouched = () => { };
1140
+ }
1141
+ isSelected(opt) {
1142
+ return String(opt.value) === String(this.value());
1143
+ }
1144
+ /** Entoure le terme recherché dans le label avec <mark> */
1145
+ highlight(label) {
1146
+ const q = this.query().trim();
1147
+ if (!q)
1148
+ return label;
1149
+ const escaped = q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1150
+ return label.replace(new RegExp(`(${escaped})`, 'gi'), '<mark class="ui-select-search__highlight">$1</mark>');
1151
+ }
1152
+ writeValue(v) { this.value.set(v ?? ''); }
1153
+ registerOnChange(fn) { this._onChange = fn; }
1154
+ registerOnTouched(fn) { this._onTouched = fn; }
1155
+ setDisabledState(_) { }
1156
+ ngAfterViewInit() { }
1157
+ // ── Actions ──────────────────────────────────────────────
1158
+ toggleOpen() {
1159
+ if (this.disabled() || this.loading())
1160
+ return;
1161
+ this.isOpen.update(v => !v);
1162
+ if (this.isOpen()) {
1163
+ this.query.set('');
1164
+ const idx = this.filteredOptions().findIndex(o => this.isSelected(o));
1165
+ this.activeIndex.set(idx >= 0 ? idx : 0);
1166
+ // Focus search input after animation
1167
+ setTimeout(() => this.searchInput?.nativeElement.focus(), 60);
1168
+ }
1169
+ }
1170
+ selectOption(opt) {
1171
+ if (opt.disabled)
1172
+ return;
1173
+ const val = String(opt.value);
1174
+ this.value.set(val);
1175
+ this._onChange(val);
1176
+ this._onTouched();
1177
+ this.change.emit(opt);
1178
+ this.isOpen.set(false);
1179
+ this.query.set('');
1180
+ this.triggerEl?.nativeElement.focus();
1181
+ }
1182
+ clearQuery() {
1183
+ this.query.set('');
1184
+ this.activeIndex.set(0);
1185
+ this.searchInput?.nativeElement.focus();
1186
+ }
1187
+ // ── Keyboard — trigger ───────────────────────────────────
1188
+ onTriggerKeydown(event) {
1189
+ switch (event.key) {
1190
+ case 'Enter':
1191
+ case ' ':
1192
+ event.preventDefault();
1193
+ this.toggleOpen();
1194
+ break;
1195
+ case 'ArrowDown':
1196
+ event.preventDefault();
1197
+ this.toggleOpen();
1198
+ break;
1199
+ case 'Escape':
1200
+ this.isOpen.set(false);
1201
+ break;
1202
+ }
1203
+ }
1204
+ // ── Keyboard — search input ──────────────────────────────
1205
+ onSearchKeydown(event) {
1206
+ const opts = this.filteredOptions();
1207
+ switch (event.key) {
1208
+ case 'ArrowDown':
1209
+ event.preventDefault();
1210
+ this.activeIndex.update(i => {
1211
+ let n = i + 1;
1212
+ while (n < opts.length && opts[n]?.disabled)
1213
+ n++;
1214
+ return Math.min(n, opts.length - 1);
1215
+ });
1216
+ break;
1217
+ case 'ArrowUp':
1218
+ event.preventDefault();
1219
+ this.activeIndex.update(i => {
1220
+ let n = i - 1;
1221
+ while (n >= 0 && opts[n]?.disabled)
1222
+ n--;
1223
+ return Math.max(n, 0);
1224
+ });
1225
+ break;
1226
+ case 'Enter':
1227
+ event.preventDefault();
1228
+ const opt = opts[this.activeIndex()];
1229
+ if (opt && !opt.disabled)
1230
+ this.selectOption(opt);
1231
+ break;
1232
+ case 'Escape':
1233
+ case 'Tab':
1234
+ this.isOpen.set(false);
1235
+ this.triggerEl?.nativeElement.focus();
1236
+ break;
1237
+ }
1238
+ }
1239
+ // ── Close on outside click ───────────────────────────────
1240
+ onDocumentClick(event) {
1241
+ if (this.isOpen() && !event.target.closest('ui-select-search')) {
1242
+ this.isOpen.set(false);
1243
+ }
1244
+ }
1245
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: SelectSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1246
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: SelectSearchComponent, isStandalone: true, selector: "ui-select-search", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyLabel: { classPropertyName: "emptyLabel", publicName: "emptyLabel", 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 }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, leadingIcon: { classPropertyName: "leadingIcon", publicName: "leadingIcon", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", change: "change" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, providers: [{
1247
+ provide: NG_VALUE_ACCESSOR,
1248
+ useExisting: forwardRef(() => SelectSearchComponent),
1249
+ multi: true,
1250
+ }], viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerEl"], descendants: true }, { propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }], ngImport: i0, template: `
1251
+ <div
1252
+ class="ui-select-search"
1253
+ [class.ui-select-search--open]="isOpen()"
1254
+ [class.ui-select-search--disabled]="disabled()"
1255
+ >
1256
+ <!-- ── Trigger ──────────────────────────────────────── -->
1257
+ <button
1258
+ #triggerEl
1259
+ type="button"
1260
+ [class]="triggerClasses()"
1261
+ [disabled]="disabled() || loading()"
1262
+ [attr.aria-haspopup]="'listbox'"
1263
+ [attr.aria-expanded]="isOpen()"
1264
+ [attr.aria-label]="ariaLabel() ?? null"
1265
+ (click)="toggleOpen(); $event.stopPropagation()"
1266
+ (keydown)="onTriggerKeydown($event)"
1267
+ >
1268
+ @if (leadingIcon()) {
1269
+ <span class="ui-select-search__leading" aria-hidden="true">
1270
+ <ng-content select="[slot=leading]" />
1271
+ </span>
1272
+ }
1273
+
1274
+ <span
1275
+ class="ui-select-search__value"
1276
+ [class.ui-select-search__value--placeholder]="!selectedOption()"
1277
+ >
1278
+ @if (loading()) {
1279
+ <span class="ui-select-search__spinner" aria-hidden="true">
1280
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1281
+ <circle cx="12" cy="12" r="10" stroke-opacity="0.25"/>
1282
+ <path d="M12 2a10 10 0 0 1 10 10" stroke-linecap="round"/>
1283
+ </svg>
1284
+ </span>
1285
+ } @else {
1286
+ {{ selectedOption()?.label ?? placeholder() ?? 'Sélectionner...' }}
1287
+ }
1288
+ </span>
1289
+
1290
+ <span
1291
+ class="ui-select-search__chevron"
1292
+ [class.ui-select-search__chevron--open]="isOpen()"
1293
+ aria-hidden="true"
1294
+ >
1295
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor"
1296
+ stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
1297
+ <path d="M4 6l4 4 4-4"/>
1298
+ </svg>
1299
+ </span>
1300
+ </button>
1301
+
1302
+ <!-- ── Dropdown panel ───────────────────────────────── -->
1303
+ @if (isOpen()) {
1304
+ <div [@dropdown] class="ui-select-search__panel" (click)="$event.stopPropagation()">
1305
+
1306
+ <!-- Search input -->
1307
+ <div class="ui-select-search__search-wrap">
1308
+ <span class="ui-select-search__search-icon" aria-hidden="true">
1309
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor"
1310
+ stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
1311
+ <circle cx="6.5" cy="6.5" r="4"/>
1312
+ <path d="M10 10l3 3"/>
1313
+ </svg>
1314
+ </span>
1315
+ <input
1316
+ #searchInput
1317
+ type="text"
1318
+ class="ui-select-search__input"
1319
+ [placeholder]="searchPlaceholder()"
1320
+ [ngModel]="query()"
1321
+ (ngModelChange)="query.set($event); activeIndex.set(0)"
1322
+ (keydown)="onSearchKeydown($event)"
1323
+ aria-label="Rechercher"
1324
+ autocomplete="off"
1325
+ spellcheck="false"
1326
+ />
1327
+ @if (query()) {
1328
+ <button
1329
+ type="button"
1330
+ class="ui-select-search__clear"
1331
+ (click)="clearQuery()"
1332
+ aria-label="Effacer la recherche"
1333
+ >
1334
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor"
1335
+ stroke-width="2" stroke-linecap="round">
1336
+ <path d="M4 4l8 8M12 4l-8 8"/>
1337
+ </svg>
1338
+ </button>
1339
+ }
1340
+ </div>
1341
+
1342
+ <!-- Options list -->
1343
+ <div
1344
+ class="ui-select-search__options"
1345
+ role="listbox"
1346
+ [attr.aria-label]="ariaLabel() ?? 'Options'"
1347
+ >
1348
+ @for (opt of filteredOptions(); track opt.value; let i = $index) {
1349
+ <button
1350
+ type="button"
1351
+ class="ui-select-search__option"
1352
+ role="option"
1353
+ [class.ui-select-search__option--selected]="isSelected(opt)"
1354
+ [class.ui-select-search__option--highlighted]="activeIndex() === i"
1355
+ [class.ui-select-search__option--disabled]="opt.disabled"
1356
+ [attr.aria-selected]="isSelected(opt)"
1357
+ [disabled]="opt.disabled"
1358
+ (click)="selectOption(opt)"
1359
+ (mouseenter)="activeIndex.set(i)"
1360
+ >
1361
+ @if (opt.icon) {
1362
+ <span class="ui-select-search__option-icon" aria-hidden="true">{{ opt.icon }}</span>
1363
+ }
1364
+ <!-- Highlighted label -->
1365
+ <span
1366
+ class="ui-select-search__option-label"
1367
+ [innerHTML]="highlight(opt.label)"
1368
+ ></span>
1369
+
1370
+ @if (isSelected(opt)) {
1371
+ <span class="ui-select-search__option-check" aria-hidden="true">
1372
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor"
1373
+ stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round">
1374
+ <path d="M3 8l3.5 3.5L13 5"/>
1375
+ </svg>
1376
+ </span>
1377
+ }
1378
+ </button>
1379
+ }
1380
+
1381
+ @if (filteredOptions().length === 0) {
1382
+ <div class="ui-select-search__empty">
1383
+ <svg viewBox="0 0 20 20" fill="none" stroke="currentColor"
1384
+ stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
1385
+ <circle cx="10" cy="10" r="8"/>
1386
+ <path d="M10 6v5M10 14h.01"/>
1387
+ </svg>
1388
+ <span>{{ emptyLabel() }}</span>
1389
+ </div>
1390
+ }
1391
+ </div>
1392
+ </div>
1393
+ }
1394
+ </div>
1395
+ `, isInline: true, styles: [".ui-select-search{position:relative;display:inline-block;width:100%}.ui-select-search--disabled{opacity:.5;cursor:not-allowed}.ui-select-search__trigger{display:inline-flex;align-items:center;gap:.375rem;width:100%;border-radius:var(--radius-md);font-family:var(--font-sans);font-weight:var(--font-medium);cursor:pointer;outline:none;transition:background-color var(--transition-colors),border-color var(--transition-colors),box-shadow var(--transition-colors);text-align:left;white-space:nowrap;overflow:hidden}.ui-select-search__trigger--xs{height:var(--size-xs);padding:0 8px;font-size:var(--text-xs)}.ui-select-search__trigger--sm{height:var(--size-sm);padding:0 10px;font-size:var(--text-xs)}.ui-select-search__trigger--md{height:var(--size-md);padding:0 10px;font-size:var(--text-sm)}.ui-select-search__trigger--lg{height:var(--size-lg);padding:0 12px;font-size:var(--text-sm)}.ui-select-search__trigger--xl{height:var(--size-xl);padding:0 12px;font-size:var(--text-md)}.ui-select-search__trigger--outline.ui-select-search__trigger--neutral{background:var(--color-bg);border:1px solid var(--color-border);color:var(--color-text)}.ui-select-search__trigger--outline.ui-select-search__trigger--neutral:hover:not(:disabled){border-color:var(--color-neutral-400)}.ui-select-search__trigger--outline.ui-select-search__trigger--neutral:focus-visible{border-color:var(--color-primary-500);box-shadow:0 0 0 1px var(--color-primary-500)}.ui-select-search__trigger--soft.ui-select-search__trigger--neutral{background:var(--color-neutral-100);border:1px solid transparent;color:var(--color-text)}.ui-select-search__trigger--soft.ui-select-search__trigger--neutral:hover:not(:disabled){background:var(--color-neutral-200)}.ui-select-search__trigger--soft.ui-select-search__trigger--neutral:focus-visible{box-shadow:0 0 0 2px var(--color-primary-500)}.ui-select-search__trigger--subtle.ui-select-search__trigger--neutral,.ui-select-search__trigger--ghost.ui-select-search__trigger--neutral{background:transparent;border:1px solid transparent;color:var(--color-text)}.ui-select-search__trigger--subtle.ui-select-search__trigger--neutral:hover:not(:disabled),.ui-select-search__trigger--ghost.ui-select-search__trigger--neutral:hover:not(:disabled){background:var(--color-neutral-100)}.ui-select-search__trigger--subtle.ui-select-search__trigger--neutral:focus-visible,.ui-select-search__trigger--ghost.ui-select-search__trigger--neutral:focus-visible{box-shadow:0 0 0 2px var(--color-primary-500)}.ui-select-search__trigger--none.ui-select-search__trigger--neutral{background:transparent;border:none;color:var(--color-text)}.ui-select-search__trigger--outline.ui-select-search__trigger--primary{background:var(--color-bg);border:1px solid var(--color-primary-500);color:var(--color-primary-600)}.ui-select-search__trigger--outline.ui-select-search__trigger--primary:hover:not(:disabled){background:color-mix(in srgb,var(--color-primary-500) 5%,transparent)}.ui-select-search__trigger--outline.ui-select-search__trigger--primary:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary-500) 30%,transparent)}.ui-select-search__trigger--soft.ui-select-search__trigger--primary{background:color-mix(in srgb,var(--color-primary-500) 10%,transparent);border:1px solid transparent;color:var(--color-primary-600)}.ui-select-search__trigger--soft.ui-select-search__trigger--primary:hover:not(:disabled){background:color-mix(in srgb,var(--color-primary-500) 15%,transparent)}.ui-select-search__trigger--outline.ui-select-search__trigger--error{background:var(--color-bg);border:1px solid var(--color-error-500);color:var(--color-error-600)}.ui-select-search__trigger--outline.ui-select-search__trigger--error:hover:not(:disabled){background:color-mix(in srgb,var(--color-error-500) 5%,transparent)}.ui-select-search__trigger--soft.ui-select-search__trigger--error{background:color-mix(in srgb,var(--color-error-500) 10%,transparent);border:1px solid transparent;color:var(--color-error-700)}.ui-select-search__trigger--outline.ui-select-search__trigger--warning{background:var(--color-bg);border:1px solid var(--color-warning-500);color:var(--color-warning-600)}.ui-select-search__trigger--outline.ui-select-search__trigger--warning:hover:not(:disabled){background:color-mix(in srgb,var(--color-warning-500) 5%,transparent)}.ui-select-search__trigger--soft.ui-select-search__trigger--warning{background:color-mix(in srgb,var(--color-warning-500) 10%,transparent);border:1px solid transparent;color:var(--color-warning-700)}.ui-select-search__trigger--outline.ui-select-search__trigger--success{background:var(--color-bg);border:1px solid var(--color-success-500);color:var(--color-success-600)}.ui-select-search__trigger--outline.ui-select-search__trigger--success:hover:not(:disabled){background:color-mix(in srgb,var(--color-success-500) 5%,transparent)}.ui-select-search__trigger--soft.ui-select-search__trigger--success{background:color-mix(in srgb,var(--color-success-500) 10%,transparent);border:1px solid transparent;color:var(--color-success-700)}.ui-select-search__trigger--outline.ui-select-search__trigger--info{background:var(--color-bg);border:1px solid var(--color-info-500);color:var(--color-info-600)}.ui-select-search__trigger--outline.ui-select-search__trigger--info:hover:not(:disabled){background:color-mix(in srgb,var(--color-info-500) 5%,transparent)}.ui-select-search__trigger--soft.ui-select-search__trigger--info{background:color-mix(in srgb,var(--color-info-500) 10%,transparent);border:1px solid transparent;color:var(--color-info-700)}.ui-select-search__trigger--outline.ui-select-search__trigger--secondary{background:var(--color-bg);border:1px solid var(--color-secondary-500);color:var(--color-secondary-600)}.ui-select-search__trigger--outline.ui-select-search__trigger--secondary:hover:not(:disabled){background:color-mix(in srgb,var(--color-secondary-500) 5%,transparent)}.ui-select-search__trigger--soft.ui-select-search__trigger--secondary{background:color-mix(in srgb,var(--color-secondary-500) 10%,transparent);border:1px solid transparent;color:var(--color-secondary-700)}.ui-select-search--open .ui-select-search__trigger--outline{border-color:var(--color-primary-500)}.ui-select-search__trigger:disabled{cursor:not-allowed}.ui-select-search__leading{display:flex;align-items:center;flex-shrink:0;color:var(--color-text-muted);width:1rem;height:1rem}.ui-select-search__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-select-search__value--placeholder{color:var(--color-text-muted)}.ui-select-search__chevron{display:flex;align-items:center;flex-shrink:0;color:var(--color-text-muted);width:1rem;height:1rem;transition:transform .15s ease}.ui-select-search__chevron svg{width:100%;height:100%}.ui-select-search__chevron--open{transform:rotate(180deg)}.ui-select-search__spinner{display:inline-flex;align-items:center}.ui-select-search__spinner svg{width:1em;height:1em;animation:ui-spin .75s linear infinite}@keyframes ui-spin{to{transform:rotate(360deg)}}.ui-select-search__panel{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:var(--z-dropdown, 50);min-width:100%;background:var(--color-bg);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;overflow:hidden;transform-origin:top center}.ui-select-search__search-wrap{display:flex;align-items:center;gap:.375rem;padding:6px 8px;border-bottom:1px solid var(--color-border);background:var(--color-bg-muted, var(--color-neutral-50))}.ui-select-search__search-icon{display:flex;align-items:center;flex-shrink:0;color:var(--color-text-muted);width:14px;height:14px}.ui-select-search__search-icon svg{width:100%;height:100%}.ui-select-search__input{flex:1;border:none;background:transparent;outline:none;font-family:var(--font-sans);font-size:var(--text-sm);color:var(--color-text);min-width:0}.ui-select-search__input::placeholder{color:var(--color-text-muted)}.ui-select-search__clear{display:flex;align-items:center;flex-shrink:0;width:16px;height:16px;color:var(--color-text-muted);background:transparent;border:none;cursor:pointer;padding:0;border-radius:3px;transition:color .1s ease}.ui-select-search__clear svg{width:100%;height:100%}.ui-select-search__clear:hover{color:var(--color-text)}.ui-select-search__options{padding:4px;overflow-y:auto;max-height:200px}.ui-select-search__option{display:flex;align-items:center;gap:.5rem;width:100%;padding:6px 8px;border-radius:calc(var(--radius-md) - 2px);font-family:var(--font-sans);font-size:var(--text-sm);font-weight:var(--font-normal);color:var(--color-text);background:transparent;border:none;cursor:pointer;text-align:left;transition:background-color .1s ease}.ui-select-search__option:hover:not(:disabled),.ui-select-search__option--highlighted:not(:disabled){background:var(--color-neutral-100)}.ui-select-search__option--selected{color:var(--color-primary-600);font-weight:var(--font-medium);background:color-mix(in srgb,var(--color-primary-500) 8%,transparent)}.ui-select-search__option--selected:hover,.ui-select-search__option--selected.ui-select-search__option--highlighted{background:color-mix(in srgb,var(--color-primary-500) 12%,transparent)}.ui-select-search__option--disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.ui-select-search__option-icon{flex-shrink:0;font-size:1rem;line-height:1}.ui-select-search__option-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-select-search__option-check{flex-shrink:0;width:1rem;height:1rem;color:var(--color-primary-500);display:flex;align-items:center}.ui-select-search__option-check svg{width:100%;height:100%}:host ::ng-deep .ui-select-search__highlight{background:color-mix(in srgb,var(--color-primary-500) 20%,transparent);color:var(--color-primary-700);border-radius:2px;padding:0 1px;font-weight:var(--font-medium);font-style:normal}.ui-select-search__empty{display:flex;flex-direction:column;align-items:center;gap:8px;padding:20px 16px;color:var(--color-text-muted);font-size:var(--text-sm);text-align:center}.ui-select-search__empty svg{width:20px;height:20px;opacity:.5}[data-theme=dark] .ui-select-search__trigger--outline.ui-select-search__trigger--neutral{background:var(--color-neutral-900);border-color:var(--color-neutral-700)}[data-theme=dark] .ui-select-search__trigger--outline.ui-select-search__trigger--neutral:hover:not(:disabled){border-color:var(--color-neutral-500)}[data-theme=dark] .ui-select-search__trigger--soft.ui-select-search__trigger--neutral{background:var(--color-neutral-800)}[data-theme=dark] .ui-select-search__panel{background:var(--color-neutral-900);border-color:var(--color-neutral-700)}[data-theme=dark] .ui-select-search__search-wrap{background:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .ui-select-search__option:hover:not(:disabled),[data-theme=dark] .ui-select-search__option--highlighted:not(:disabled){background:var(--color-neutral-800)}[data-theme=dark] .ui-select-search__option--selected{background:color-mix(in srgb,var(--color-primary-500) 12%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], animations: [
1396
+ trigger('dropdown', [
1397
+ transition(':enter', [
1398
+ style({ opacity: 0, transform: 'scale(0.96) translateY(-4px)' }),
1399
+ animate('100ms ease-out', style({ opacity: 1, transform: 'scale(1) translateY(0)' })),
1400
+ ]),
1401
+ transition(':leave', [
1402
+ animate('80ms ease-in', style({ opacity: 0, transform: 'scale(0.96) translateY(-4px)' })),
1403
+ ]),
1404
+ ]),
1405
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1406
+ }
1407
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: SelectSearchComponent, decorators: [{
1408
+ type: Component,
1409
+ args: [{ selector: 'ui-select-search', standalone: true, imports: [CommonModule, FormsModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [{
1410
+ provide: NG_VALUE_ACCESSOR,
1411
+ useExisting: forwardRef(() => SelectSearchComponent),
1412
+ multi: true,
1413
+ }], animations: [
1414
+ trigger('dropdown', [
1415
+ transition(':enter', [
1416
+ style({ opacity: 0, transform: 'scale(0.96) translateY(-4px)' }),
1417
+ animate('100ms ease-out', style({ opacity: 1, transform: 'scale(1) translateY(0)' })),
1418
+ ]),
1419
+ transition(':leave', [
1420
+ animate('80ms ease-in', style({ opacity: 0, transform: 'scale(0.96) translateY(-4px)' })),
1421
+ ]),
1422
+ ]),
1423
+ ], template: `
1424
+ <div
1425
+ class="ui-select-search"
1426
+ [class.ui-select-search--open]="isOpen()"
1427
+ [class.ui-select-search--disabled]="disabled()"
1428
+ >
1429
+ <!-- ── Trigger ──────────────────────────────────────── -->
1430
+ <button
1431
+ #triggerEl
1432
+ type="button"
1433
+ [class]="triggerClasses()"
1434
+ [disabled]="disabled() || loading()"
1435
+ [attr.aria-haspopup]="'listbox'"
1436
+ [attr.aria-expanded]="isOpen()"
1437
+ [attr.aria-label]="ariaLabel() ?? null"
1438
+ (click)="toggleOpen(); $event.stopPropagation()"
1439
+ (keydown)="onTriggerKeydown($event)"
1440
+ >
1441
+ @if (leadingIcon()) {
1442
+ <span class="ui-select-search__leading" aria-hidden="true">
1443
+ <ng-content select="[slot=leading]" />
1444
+ </span>
1445
+ }
1446
+
1447
+ <span
1448
+ class="ui-select-search__value"
1449
+ [class.ui-select-search__value--placeholder]="!selectedOption()"
1450
+ >
1451
+ @if (loading()) {
1452
+ <span class="ui-select-search__spinner" aria-hidden="true">
1453
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1454
+ <circle cx="12" cy="12" r="10" stroke-opacity="0.25"/>
1455
+ <path d="M12 2a10 10 0 0 1 10 10" stroke-linecap="round"/>
1456
+ </svg>
1457
+ </span>
1458
+ } @else {
1459
+ {{ selectedOption()?.label ?? placeholder() ?? 'Sélectionner...' }}
1460
+ }
1461
+ </span>
1462
+
1463
+ <span
1464
+ class="ui-select-search__chevron"
1465
+ [class.ui-select-search__chevron--open]="isOpen()"
1466
+ aria-hidden="true"
1467
+ >
1468
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor"
1469
+ stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
1470
+ <path d="M4 6l4 4 4-4"/>
1471
+ </svg>
1472
+ </span>
1473
+ </button>
1474
+
1475
+ <!-- ── Dropdown panel ───────────────────────────────── -->
1476
+ @if (isOpen()) {
1477
+ <div [@dropdown] class="ui-select-search__panel" (click)="$event.stopPropagation()">
1478
+
1479
+ <!-- Search input -->
1480
+ <div class="ui-select-search__search-wrap">
1481
+ <span class="ui-select-search__search-icon" aria-hidden="true">
1482
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor"
1483
+ stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
1484
+ <circle cx="6.5" cy="6.5" r="4"/>
1485
+ <path d="M10 10l3 3"/>
1486
+ </svg>
1487
+ </span>
1488
+ <input
1489
+ #searchInput
1490
+ type="text"
1491
+ class="ui-select-search__input"
1492
+ [placeholder]="searchPlaceholder()"
1493
+ [ngModel]="query()"
1494
+ (ngModelChange)="query.set($event); activeIndex.set(0)"
1495
+ (keydown)="onSearchKeydown($event)"
1496
+ aria-label="Rechercher"
1497
+ autocomplete="off"
1498
+ spellcheck="false"
1499
+ />
1500
+ @if (query()) {
1501
+ <button
1502
+ type="button"
1503
+ class="ui-select-search__clear"
1504
+ (click)="clearQuery()"
1505
+ aria-label="Effacer la recherche"
1506
+ >
1507
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor"
1508
+ stroke-width="2" stroke-linecap="round">
1509
+ <path d="M4 4l8 8M12 4l-8 8"/>
1510
+ </svg>
1511
+ </button>
1512
+ }
1513
+ </div>
1514
+
1515
+ <!-- Options list -->
1516
+ <div
1517
+ class="ui-select-search__options"
1518
+ role="listbox"
1519
+ [attr.aria-label]="ariaLabel() ?? 'Options'"
1520
+ >
1521
+ @for (opt of filteredOptions(); track opt.value; let i = $index) {
1522
+ <button
1523
+ type="button"
1524
+ class="ui-select-search__option"
1525
+ role="option"
1526
+ [class.ui-select-search__option--selected]="isSelected(opt)"
1527
+ [class.ui-select-search__option--highlighted]="activeIndex() === i"
1528
+ [class.ui-select-search__option--disabled]="opt.disabled"
1529
+ [attr.aria-selected]="isSelected(opt)"
1530
+ [disabled]="opt.disabled"
1531
+ (click)="selectOption(opt)"
1532
+ (mouseenter)="activeIndex.set(i)"
1533
+ >
1534
+ @if (opt.icon) {
1535
+ <span class="ui-select-search__option-icon" aria-hidden="true">{{ opt.icon }}</span>
1536
+ }
1537
+ <!-- Highlighted label -->
1538
+ <span
1539
+ class="ui-select-search__option-label"
1540
+ [innerHTML]="highlight(opt.label)"
1541
+ ></span>
1542
+
1543
+ @if (isSelected(opt)) {
1544
+ <span class="ui-select-search__option-check" aria-hidden="true">
1545
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor"
1546
+ stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round">
1547
+ <path d="M3 8l3.5 3.5L13 5"/>
1548
+ </svg>
1549
+ </span>
1550
+ }
1551
+ </button>
1552
+ }
1553
+
1554
+ @if (filteredOptions().length === 0) {
1555
+ <div class="ui-select-search__empty">
1556
+ <svg viewBox="0 0 20 20" fill="none" stroke="currentColor"
1557
+ stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
1558
+ <circle cx="10" cy="10" r="8"/>
1559
+ <path d="M10 6v5M10 14h.01"/>
1560
+ </svg>
1561
+ <span>{{ emptyLabel() }}</span>
1562
+ </div>
1563
+ }
1564
+ </div>
1565
+ </div>
1566
+ }
1567
+ </div>
1568
+ `, styles: [".ui-select-search{position:relative;display:inline-block;width:100%}.ui-select-search--disabled{opacity:.5;cursor:not-allowed}.ui-select-search__trigger{display:inline-flex;align-items:center;gap:.375rem;width:100%;border-radius:var(--radius-md);font-family:var(--font-sans);font-weight:var(--font-medium);cursor:pointer;outline:none;transition:background-color var(--transition-colors),border-color var(--transition-colors),box-shadow var(--transition-colors);text-align:left;white-space:nowrap;overflow:hidden}.ui-select-search__trigger--xs{height:var(--size-xs);padding:0 8px;font-size:var(--text-xs)}.ui-select-search__trigger--sm{height:var(--size-sm);padding:0 10px;font-size:var(--text-xs)}.ui-select-search__trigger--md{height:var(--size-md);padding:0 10px;font-size:var(--text-sm)}.ui-select-search__trigger--lg{height:var(--size-lg);padding:0 12px;font-size:var(--text-sm)}.ui-select-search__trigger--xl{height:var(--size-xl);padding:0 12px;font-size:var(--text-md)}.ui-select-search__trigger--outline.ui-select-search__trigger--neutral{background:var(--color-bg);border:1px solid var(--color-border);color:var(--color-text)}.ui-select-search__trigger--outline.ui-select-search__trigger--neutral:hover:not(:disabled){border-color:var(--color-neutral-400)}.ui-select-search__trigger--outline.ui-select-search__trigger--neutral:focus-visible{border-color:var(--color-primary-500);box-shadow:0 0 0 1px var(--color-primary-500)}.ui-select-search__trigger--soft.ui-select-search__trigger--neutral{background:var(--color-neutral-100);border:1px solid transparent;color:var(--color-text)}.ui-select-search__trigger--soft.ui-select-search__trigger--neutral:hover:not(:disabled){background:var(--color-neutral-200)}.ui-select-search__trigger--soft.ui-select-search__trigger--neutral:focus-visible{box-shadow:0 0 0 2px var(--color-primary-500)}.ui-select-search__trigger--subtle.ui-select-search__trigger--neutral,.ui-select-search__trigger--ghost.ui-select-search__trigger--neutral{background:transparent;border:1px solid transparent;color:var(--color-text)}.ui-select-search__trigger--subtle.ui-select-search__trigger--neutral:hover:not(:disabled),.ui-select-search__trigger--ghost.ui-select-search__trigger--neutral:hover:not(:disabled){background:var(--color-neutral-100)}.ui-select-search__trigger--subtle.ui-select-search__trigger--neutral:focus-visible,.ui-select-search__trigger--ghost.ui-select-search__trigger--neutral:focus-visible{box-shadow:0 0 0 2px var(--color-primary-500)}.ui-select-search__trigger--none.ui-select-search__trigger--neutral{background:transparent;border:none;color:var(--color-text)}.ui-select-search__trigger--outline.ui-select-search__trigger--primary{background:var(--color-bg);border:1px solid var(--color-primary-500);color:var(--color-primary-600)}.ui-select-search__trigger--outline.ui-select-search__trigger--primary:hover:not(:disabled){background:color-mix(in srgb,var(--color-primary-500) 5%,transparent)}.ui-select-search__trigger--outline.ui-select-search__trigger--primary:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary-500) 30%,transparent)}.ui-select-search__trigger--soft.ui-select-search__trigger--primary{background:color-mix(in srgb,var(--color-primary-500) 10%,transparent);border:1px solid transparent;color:var(--color-primary-600)}.ui-select-search__trigger--soft.ui-select-search__trigger--primary:hover:not(:disabled){background:color-mix(in srgb,var(--color-primary-500) 15%,transparent)}.ui-select-search__trigger--outline.ui-select-search__trigger--error{background:var(--color-bg);border:1px solid var(--color-error-500);color:var(--color-error-600)}.ui-select-search__trigger--outline.ui-select-search__trigger--error:hover:not(:disabled){background:color-mix(in srgb,var(--color-error-500) 5%,transparent)}.ui-select-search__trigger--soft.ui-select-search__trigger--error{background:color-mix(in srgb,var(--color-error-500) 10%,transparent);border:1px solid transparent;color:var(--color-error-700)}.ui-select-search__trigger--outline.ui-select-search__trigger--warning{background:var(--color-bg);border:1px solid var(--color-warning-500);color:var(--color-warning-600)}.ui-select-search__trigger--outline.ui-select-search__trigger--warning:hover:not(:disabled){background:color-mix(in srgb,var(--color-warning-500) 5%,transparent)}.ui-select-search__trigger--soft.ui-select-search__trigger--warning{background:color-mix(in srgb,var(--color-warning-500) 10%,transparent);border:1px solid transparent;color:var(--color-warning-700)}.ui-select-search__trigger--outline.ui-select-search__trigger--success{background:var(--color-bg);border:1px solid var(--color-success-500);color:var(--color-success-600)}.ui-select-search__trigger--outline.ui-select-search__trigger--success:hover:not(:disabled){background:color-mix(in srgb,var(--color-success-500) 5%,transparent)}.ui-select-search__trigger--soft.ui-select-search__trigger--success{background:color-mix(in srgb,var(--color-success-500) 10%,transparent);border:1px solid transparent;color:var(--color-success-700)}.ui-select-search__trigger--outline.ui-select-search__trigger--info{background:var(--color-bg);border:1px solid var(--color-info-500);color:var(--color-info-600)}.ui-select-search__trigger--outline.ui-select-search__trigger--info:hover:not(:disabled){background:color-mix(in srgb,var(--color-info-500) 5%,transparent)}.ui-select-search__trigger--soft.ui-select-search__trigger--info{background:color-mix(in srgb,var(--color-info-500) 10%,transparent);border:1px solid transparent;color:var(--color-info-700)}.ui-select-search__trigger--outline.ui-select-search__trigger--secondary{background:var(--color-bg);border:1px solid var(--color-secondary-500);color:var(--color-secondary-600)}.ui-select-search__trigger--outline.ui-select-search__trigger--secondary:hover:not(:disabled){background:color-mix(in srgb,var(--color-secondary-500) 5%,transparent)}.ui-select-search__trigger--soft.ui-select-search__trigger--secondary{background:color-mix(in srgb,var(--color-secondary-500) 10%,transparent);border:1px solid transparent;color:var(--color-secondary-700)}.ui-select-search--open .ui-select-search__trigger--outline{border-color:var(--color-primary-500)}.ui-select-search__trigger:disabled{cursor:not-allowed}.ui-select-search__leading{display:flex;align-items:center;flex-shrink:0;color:var(--color-text-muted);width:1rem;height:1rem}.ui-select-search__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-select-search__value--placeholder{color:var(--color-text-muted)}.ui-select-search__chevron{display:flex;align-items:center;flex-shrink:0;color:var(--color-text-muted);width:1rem;height:1rem;transition:transform .15s ease}.ui-select-search__chevron svg{width:100%;height:100%}.ui-select-search__chevron--open{transform:rotate(180deg)}.ui-select-search__spinner{display:inline-flex;align-items:center}.ui-select-search__spinner svg{width:1em;height:1em;animation:ui-spin .75s linear infinite}@keyframes ui-spin{to{transform:rotate(360deg)}}.ui-select-search__panel{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:var(--z-dropdown, 50);min-width:100%;background:var(--color-bg);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;overflow:hidden;transform-origin:top center}.ui-select-search__search-wrap{display:flex;align-items:center;gap:.375rem;padding:6px 8px;border-bottom:1px solid var(--color-border);background:var(--color-bg-muted, var(--color-neutral-50))}.ui-select-search__search-icon{display:flex;align-items:center;flex-shrink:0;color:var(--color-text-muted);width:14px;height:14px}.ui-select-search__search-icon svg{width:100%;height:100%}.ui-select-search__input{flex:1;border:none;background:transparent;outline:none;font-family:var(--font-sans);font-size:var(--text-sm);color:var(--color-text);min-width:0}.ui-select-search__input::placeholder{color:var(--color-text-muted)}.ui-select-search__clear{display:flex;align-items:center;flex-shrink:0;width:16px;height:16px;color:var(--color-text-muted);background:transparent;border:none;cursor:pointer;padding:0;border-radius:3px;transition:color .1s ease}.ui-select-search__clear svg{width:100%;height:100%}.ui-select-search__clear:hover{color:var(--color-text)}.ui-select-search__options{padding:4px;overflow-y:auto;max-height:200px}.ui-select-search__option{display:flex;align-items:center;gap:.5rem;width:100%;padding:6px 8px;border-radius:calc(var(--radius-md) - 2px);font-family:var(--font-sans);font-size:var(--text-sm);font-weight:var(--font-normal);color:var(--color-text);background:transparent;border:none;cursor:pointer;text-align:left;transition:background-color .1s ease}.ui-select-search__option:hover:not(:disabled),.ui-select-search__option--highlighted:not(:disabled){background:var(--color-neutral-100)}.ui-select-search__option--selected{color:var(--color-primary-600);font-weight:var(--font-medium);background:color-mix(in srgb,var(--color-primary-500) 8%,transparent)}.ui-select-search__option--selected:hover,.ui-select-search__option--selected.ui-select-search__option--highlighted{background:color-mix(in srgb,var(--color-primary-500) 12%,transparent)}.ui-select-search__option--disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.ui-select-search__option-icon{flex-shrink:0;font-size:1rem;line-height:1}.ui-select-search__option-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-select-search__option-check{flex-shrink:0;width:1rem;height:1rem;color:var(--color-primary-500);display:flex;align-items:center}.ui-select-search__option-check svg{width:100%;height:100%}:host ::ng-deep .ui-select-search__highlight{background:color-mix(in srgb,var(--color-primary-500) 20%,transparent);color:var(--color-primary-700);border-radius:2px;padding:0 1px;font-weight:var(--font-medium);font-style:normal}.ui-select-search__empty{display:flex;flex-direction:column;align-items:center;gap:8px;padding:20px 16px;color:var(--color-text-muted);font-size:var(--text-sm);text-align:center}.ui-select-search__empty svg{width:20px;height:20px;opacity:.5}[data-theme=dark] .ui-select-search__trigger--outline.ui-select-search__trigger--neutral{background:var(--color-neutral-900);border-color:var(--color-neutral-700)}[data-theme=dark] .ui-select-search__trigger--outline.ui-select-search__trigger--neutral:hover:not(:disabled){border-color:var(--color-neutral-500)}[data-theme=dark] .ui-select-search__trigger--soft.ui-select-search__trigger--neutral{background:var(--color-neutral-800)}[data-theme=dark] .ui-select-search__panel{background:var(--color-neutral-900);border-color:var(--color-neutral-700)}[data-theme=dark] .ui-select-search__search-wrap{background:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .ui-select-search__option:hover:not(:disabled),[data-theme=dark] .ui-select-search__option--highlighted:not(:disabled){background:var(--color-neutral-800)}[data-theme=dark] .ui-select-search__option--selected{background:color-mix(in srgb,var(--color-primary-500) 12%,transparent)}\n"] }]
1569
+ }], propDecorators: { triggerEl: [{
1570
+ type: ViewChild,
1571
+ args: ['triggerEl']
1572
+ }], searchInput: [{
1573
+ type: ViewChild,
1574
+ args: ['searchInput']
1575
+ }], onDocumentClick: [{
1576
+ type: HostListener,
1577
+ args: ['document:click', ['$event']]
1578
+ }] } });
1579
+
1580
+ // ============================================================
1581
+ // MOLECULES — Nuxt UI v3 Design Kit → Angular 19 + NX
1582
+ // Combinations of atoms with focused single responsibility
1583
+ // ============================================================
1584
+
1585
+ /**
1586
+ * Generated bundle index. Do not edit.
1587
+ */
1588
+
1589
+ export { AlertComponent, AvatarGroupComponent, BreadcrumbComponent, ButtonGroupComponent, FormFieldComponent, InputComponent, PaginationComponent, SelectComponent, SelectSearchComponent, TabsComponent, TextareaComponent, ToastComponent };
1590
+ //# sourceMappingURL=atomng-ui-molecules.mjs.map