@kouji-ui/core 0.0.3 → 0.1.1

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 (534) hide show
  1. package/.turbo/turbo-build.log +6 -3
  2. package/CHANGELOG.md +177 -0
  3. package/ng-package.json +5 -1
  4. package/package.json +18 -6
  5. package/src/a11y/aria-describedby.ts +7 -3
  6. package/src/a11y/aria-labelledby.spec.ts +55 -0
  7. package/src/a11y/aria-labelledby.ts +38 -0
  8. package/src/a11y/focus-trap.ts +4 -2
  9. package/src/a11y/index.ts +1 -0
  10. package/src/a11y/live-region.ts +4 -2
  11. package/src/a11y/roving-tabindex.spec.ts +139 -0
  12. package/src/a11y/roving-tabindex.ts +56 -7
  13. package/src/a11y/visually-hidden.ts +4 -2
  14. package/src/accordion/accordion.context.ts +22 -0
  15. package/src/accordion/accordion.spec.ts +233 -23
  16. package/src/accordion/accordion.ts +311 -39
  17. package/src/accordion/index.ts +8 -2
  18. package/src/alert/alert.context.ts +28 -0
  19. package/src/alert/alert.spec.ts +217 -0
  20. package/src/alert/alert.ts +417 -0
  21. package/src/alert/config.ts +46 -0
  22. package/src/alert/index.ts +19 -0
  23. package/src/avatar/avatar-group.context.ts +45 -0
  24. package/src/avatar/avatar-group.spec.ts +358 -0
  25. package/src/avatar/avatar-group.ts +259 -0
  26. package/src/avatar/avatar.ts +17 -4
  27. package/src/avatar/index.ts +11 -1
  28. package/src/badge/badge.spec.ts +8 -0
  29. package/src/badge/badge.ts +24 -3
  30. package/src/breadcrumb/breadcrumb-current.ts +38 -0
  31. package/src/breadcrumb/breadcrumb-ellipsis.ts +71 -0
  32. package/src/breadcrumb/breadcrumb-item.ts +41 -0
  33. package/src/breadcrumb/breadcrumb-link.ts +44 -0
  34. package/src/breadcrumb/breadcrumb-list.ts +42 -0
  35. package/src/breadcrumb/breadcrumb-separator.ts +45 -0
  36. package/src/breadcrumb/breadcrumb.context.ts +45 -0
  37. package/src/breadcrumb/breadcrumb.spec.ts +354 -0
  38. package/src/breadcrumb/breadcrumb.ts +239 -0
  39. package/src/breadcrumb/config.ts +84 -0
  40. package/src/breadcrumb/index.ts +18 -0
  41. package/src/button/_examples/button.example.ts +71 -0
  42. package/src/button/_examples/button.finance.example.ts +83 -0
  43. package/src/button/_examples/button.retro.example.ts +91 -0
  44. package/src/button/_examples/button.sizes.example.ts +60 -0
  45. package/src/button/_examples/index.ts +6 -0
  46. package/src/button/button.spec.ts +139 -8
  47. package/src/button/button.ts +114 -16
  48. package/src/button/config.spec.ts +33 -0
  49. package/src/button/config.ts +45 -0
  50. package/src/button/index.ts +2 -1
  51. package/src/button-group/button-group.context.ts +28 -0
  52. package/src/button-group/button-group.spec.ts +99 -0
  53. package/src/button-group/button-group.ts +99 -0
  54. package/src/button-group/index.ts +2 -0
  55. package/src/calendar/calendar-day.ts +102 -0
  56. package/src/calendar/calendar-grid.ts +90 -0
  57. package/src/calendar/calendar-header.ts +65 -0
  58. package/src/calendar/calendar.context.ts +53 -0
  59. package/src/calendar/calendar.spec.ts +225 -0
  60. package/src/calendar/calendar.ts +233 -0
  61. package/src/calendar/date-utils.ts +225 -0
  62. package/src/calendar/index.ts +28 -0
  63. package/src/carousel/carousel.context.ts +81 -0
  64. package/src/carousel/carousel.spec.ts +337 -0
  65. package/src/carousel/carousel.ts +919 -0
  66. package/src/carousel/index.ts +22 -0
  67. package/src/cascade-select/cascade-select-option.ts +205 -0
  68. package/src/cascade-select/cascade-select-panel.ts +106 -0
  69. package/src/cascade-select/cascade-select-root.ts +265 -0
  70. package/src/cascade-select/cascade-select-sub-panel.ts +168 -0
  71. package/src/cascade-select/cascade-select-trigger.ts +44 -0
  72. package/src/cascade-select/cascade-select.context.ts +71 -0
  73. package/src/cascade-select/cascade-select.spec.ts +241 -0
  74. package/src/cascade-select/cascade-select.ts +5 -0
  75. package/src/cascade-select/index.ts +11 -0
  76. package/src/chart/chart.ts +6 -2
  77. package/src/chat/chat-avatar.ts +31 -0
  78. package/src/chat/chat-bubble.ts +49 -0
  79. package/src/chat/chat-footer.ts +67 -0
  80. package/src/chat/chat-header.ts +41 -0
  81. package/src/chat/chat-log.ts +43 -0
  82. package/src/chat/chat.context.ts +64 -0
  83. package/src/chat/chat.spec.ts +341 -0
  84. package/src/chat/chat.ts +191 -0
  85. package/src/chat/config.ts +53 -0
  86. package/src/chat/index.ts +21 -0
  87. package/src/checkbox/checkbox.ts +9 -2
  88. package/src/color-picker/color-picker.context.ts +74 -0
  89. package/src/color-picker/color-picker.spec.ts +241 -0
  90. package/src/color-picker/color-picker.ts +698 -0
  91. package/src/color-picker/color-picker.utils.ts +140 -0
  92. package/src/color-picker/index.ts +28 -0
  93. package/src/combobox/combobox-input.ts +143 -0
  94. package/src/combobox/combobox-listbox.ts +49 -0
  95. package/src/combobox/combobox-option.ts +43 -0
  96. package/src/combobox/combobox-root.ts +281 -0
  97. package/src/combobox/combobox.spec.ts +75 -0
  98. package/src/combobox/combobox.ts +4 -0
  99. package/src/combobox/index.ts +4 -0
  100. package/src/command-palette/command-empty.ts +36 -0
  101. package/src/command-palette/command-group.ts +21 -0
  102. package/src/command-palette/command-input.ts +70 -0
  103. package/src/command-palette/command-item.ts +60 -0
  104. package/src/command-palette/command-list.ts +25 -0
  105. package/src/command-palette/command-palette-dialog.ts +74 -0
  106. package/src/command-palette/command-palette-trigger.ts +64 -0
  107. package/src/command-palette/command-palette.filters.ts +53 -0
  108. package/src/command-palette/command-palette.spec.ts +349 -0
  109. package/src/command-palette/command-palette.ts +204 -0
  110. package/src/command-palette/command-separator.ts +18 -0
  111. package/src/command-palette/index.ts +15 -0
  112. package/src/confirm-popup/confirm-popup-action.ts +39 -0
  113. package/src/confirm-popup/confirm-popup-cancel.ts +38 -0
  114. package/src/confirm-popup/confirm-popup-content.ts +113 -0
  115. package/src/confirm-popup/confirm-popup-message.ts +36 -0
  116. package/src/confirm-popup/confirm-popup-trigger.ts +31 -0
  117. package/src/confirm-popup/confirm-popup.context.ts +41 -0
  118. package/src/confirm-popup/confirm-popup.spec.ts +337 -0
  119. package/src/confirm-popup/confirm-popup.ts +109 -0
  120. package/src/confirm-popup/index.ts +12 -0
  121. package/src/date-picker/date-picker-calendar.ts +65 -0
  122. package/src/date-picker/date-picker-trigger.ts +215 -0
  123. package/src/date-picker/date-picker.context.ts +50 -0
  124. package/src/date-picker/date-picker.spec.ts +117 -0
  125. package/src/date-picker/date-picker.ts +127 -0
  126. package/src/date-picker/index.ts +7 -0
  127. package/src/dialog/_examples/dialog.confirm.example.ts +145 -0
  128. package/src/dialog/_examples/dialog.example.ts +106 -0
  129. package/src/dialog/_examples/dialog.finance.example.ts +121 -0
  130. package/src/dialog/_examples/dialog.retro.example.ts +126 -0
  131. package/src/dialog/_examples/index.ts +6 -0
  132. package/src/dialog/dialog.ref.ts +42 -0
  133. package/src/dialog/dialog.service.ts +57 -167
  134. package/src/dialog/dialog.spec.ts +35 -120
  135. package/src/dialog/dialog.ts +17 -192
  136. package/src/dialog/index.ts +3 -9
  137. package/src/divider/divider.spec.ts +223 -0
  138. package/src/divider/divider.ts +137 -0
  139. package/src/divider/index.ts +5 -0
  140. package/src/drawer/drawer.ref.ts +63 -0
  141. package/src/drawer/drawer.service.ts +106 -0
  142. package/src/drawer/drawer.spec.ts +117 -0
  143. package/src/drawer/drawer.ts +122 -0
  144. package/src/drawer/index.ts +10 -0
  145. package/src/dropdown-menu/dropdown-menu-content.ts +258 -0
  146. package/src/dropdown-menu/dropdown-menu-group.ts +31 -0
  147. package/src/dropdown-menu/dropdown-menu-item.ts +51 -0
  148. package/src/dropdown-menu/dropdown-menu-label.ts +41 -0
  149. package/src/dropdown-menu/dropdown-menu-separator.ts +27 -0
  150. package/src/dropdown-menu/dropdown-menu-trigger.ts +140 -0
  151. package/src/dropdown-menu/dropdown-menu.spec.ts +265 -0
  152. package/src/dropdown-menu/dropdown-menu.ts +60 -0
  153. package/src/dropdown-menu/index.ts +15 -0
  154. package/src/example-components.ts +39 -30
  155. package/src/field/field-error.ts +49 -0
  156. package/src/field/field-group.ts +39 -0
  157. package/src/field/field-help.ts +47 -0
  158. package/src/field/field-label.ts +30 -0
  159. package/src/field/field.context.ts +28 -0
  160. package/src/field/field.spec.ts +179 -0
  161. package/src/field/field.ts +121 -0
  162. package/src/field/index.ts +6 -0
  163. package/src/file-upload/file-upload.context.ts +89 -0
  164. package/src/file-upload/file-upload.spec.ts +290 -0
  165. package/src/file-upload/file-upload.ts +639 -0
  166. package/src/file-upload/file-upload.types.ts +59 -0
  167. package/src/file-upload/index.ts +23 -0
  168. package/src/form/form-error-summary.ts +87 -0
  169. package/src/form/form-field.context.ts +3 -0
  170. package/src/form/form-field.spec.ts +25 -0
  171. package/src/form/form-field.ts +52 -0
  172. package/src/form/form.context.ts +52 -2
  173. package/src/form/form.spec.ts +155 -18
  174. package/src/form/form.ts +315 -35
  175. package/src/form/index.ts +11 -2
  176. package/src/icon/E2E.md +14 -0
  177. package/src/icon/icon.css +40 -0
  178. package/src/icon/icon.directive.spec.ts +198 -0
  179. package/src/icon/icon.directive.ts +113 -0
  180. package/src/icon/icon.mode.spec.ts +29 -0
  181. package/src/icon/icon.mode.ts +23 -0
  182. package/src/icon/icon.providers.spec.ts +63 -0
  183. package/src/icon/icon.providers.ts +47 -0
  184. package/src/icon/icon.resolver.spec.ts +96 -0
  185. package/src/icon/icon.resolver.ts +49 -0
  186. package/src/icon/icon.tokens.ts +88 -0
  187. package/src/icon/icon.types.ts +48 -0
  188. package/src/icon/index.ts +21 -0
  189. package/src/input/input.ts +12 -3
  190. package/src/input-group/index.ts +3 -0
  191. package/src/input-group/input-group-addon.ts +92 -0
  192. package/src/input-group/input-group.context.ts +27 -0
  193. package/src/input-group/input-group.spec.ts +186 -0
  194. package/src/input-group/input-group.ts +136 -0
  195. package/src/input-mask/index.ts +11 -0
  196. package/src/input-mask/input-mask.compile.ts +69 -0
  197. package/src/input-mask/input-mask.engine.ts +376 -0
  198. package/src/input-mask/input-mask.presets.ts +24 -0
  199. package/src/input-mask/input-mask.spec.ts +304 -0
  200. package/src/input-mask/input-mask.tokens.ts +49 -0
  201. package/src/input-mask/input-mask.ts +280 -0
  202. package/src/input-otp/index.ts +2 -0
  203. package/src/input-otp/input-otp.context.ts +41 -0
  204. package/src/input-otp/input-otp.spec.ts +308 -0
  205. package/src/input-otp/input-otp.ts +470 -0
  206. package/src/kbd/index.ts +1 -0
  207. package/src/kbd/kbd.spec.ts +127 -0
  208. package/src/kbd/kbd.ts +132 -0
  209. package/src/link/config.ts +44 -0
  210. package/src/link/index.ts +2 -0
  211. package/src/link/link.spec.ts +246 -0
  212. package/src/link/link.ts +226 -0
  213. package/src/list/index.ts +11 -0
  214. package/src/list/list.spec.ts +237 -0
  215. package/src/list/list.ts +277 -0
  216. package/src/menubar/index.ts +7 -0
  217. package/src/menubar/menubar-item.ts +204 -0
  218. package/src/menubar/menubar.context.ts +43 -0
  219. package/src/menubar/menubar.spec.ts +433 -0
  220. package/src/menubar/menubar.ts +309 -0
  221. package/src/number-input/index.ts +4 -0
  222. package/src/number-input/number-input-group.ts +64 -0
  223. package/src/number-input/number-input.context.ts +31 -0
  224. package/src/number-input/number-input.format.ts +148 -0
  225. package/src/number-input/number-input.spec.ts +170 -0
  226. package/src/number-input/number-input.ts +457 -0
  227. package/src/number-input/number-stepper.ts +193 -0
  228. package/src/overlay-badge/index.ts +7 -0
  229. package/src/overlay-badge/overlay-badge-content.ts +73 -0
  230. package/src/overlay-badge/overlay-badge.context.ts +37 -0
  231. package/src/overlay-badge/overlay-badge.spec.ts +220 -0
  232. package/src/overlay-badge/overlay-badge.ts +128 -0
  233. package/src/pagination/config.ts +82 -0
  234. package/src/pagination/index.ts +19 -0
  235. package/src/pagination/page-tokens.ts +78 -0
  236. package/src/pagination/pagination-ellipsis.ts +69 -0
  237. package/src/pagination/pagination-first.ts +84 -0
  238. package/src/pagination/pagination-info.ts +70 -0
  239. package/src/pagination/pagination-item.ts +81 -0
  240. package/src/pagination/pagination-last.ts +85 -0
  241. package/src/pagination/pagination-next.ts +86 -0
  242. package/src/pagination/pagination-previous.ts +90 -0
  243. package/src/pagination/pagination.context.ts +52 -0
  244. package/src/pagination/pagination.spec.ts +388 -0
  245. package/src/pagination/pagination.ts +288 -0
  246. package/src/password-input/index.ts +15 -0
  247. package/src/password-input/password-input.context.ts +65 -0
  248. package/src/password-input/password-input.scorer.ts +34 -0
  249. package/src/password-input/password-input.spec.ts +274 -0
  250. package/src/password-input/password-input.ts +488 -0
  251. package/src/popover/_examples/index.ts +5 -0
  252. package/src/popover/_examples/popover.example.ts +92 -0
  253. package/src/popover/_examples/popover.finance.example.ts +106 -0
  254. package/src/popover/_examples/popover.retro.example.ts +103 -0
  255. package/src/popover/index.ts +5 -12
  256. package/src/popover/popover-arrow.ts +30 -0
  257. package/src/popover/popover-close.ts +36 -0
  258. package/src/popover/popover-content.ts +41 -0
  259. package/src/popover/popover-title.ts +39 -0
  260. package/src/popover/popover-trigger.ts +40 -0
  261. package/src/popover/popover.spec.ts +51 -44
  262. package/src/popover/popover.ts +5 -124
  263. package/src/presets/bind-presets.spec.ts +50 -0
  264. package/src/presets/bind-presets.ts +43 -0
  265. package/src/presets/index.ts +3 -0
  266. package/src/presets/size.spec.ts +67 -0
  267. package/src/presets/size.ts +59 -0
  268. package/src/presets/variant.spec.ts +72 -0
  269. package/src/presets/variant.ts +62 -0
  270. package/src/primitives/directionality/directionality.spec.ts +112 -0
  271. package/src/primitives/directionality/directionality.ts +89 -0
  272. package/src/primitives/directionality/index.ts +1 -0
  273. package/src/primitives/forms/form-control.spec.ts +14 -6
  274. package/src/primitives/forms/form-control.ts +6 -2
  275. package/src/primitives/index.ts +3 -0
  276. package/src/primitives/interaction/disabled.ts +12 -5
  277. package/src/primitives/interaction/focus-ring.ts +4 -2
  278. package/src/primitives/list/filterable-list.spec.ts +114 -0
  279. package/src/primitives/list/filterable-list.ts +126 -0
  280. package/src/primitives/list/group.spec.ts +99 -0
  281. package/src/primitives/list/group.ts +139 -0
  282. package/src/primitives/list/index.ts +8 -0
  283. package/src/primitives/list/inject-helpers.ts +8 -0
  284. package/src/primitives/list/item.spec.ts +173 -0
  285. package/src/primitives/list/item.ts +222 -0
  286. package/src/primitives/list/navigator.spec.ts +286 -0
  287. package/src/primitives/list/navigator.ts +238 -0
  288. package/src/primitives/list/selection.spec.ts +214 -0
  289. package/src/primitives/list/selection.ts +339 -0
  290. package/src/primitives/list/tokens.ts +106 -0
  291. package/src/primitives/list/type-ahead.spec.ts +58 -0
  292. package/src/primitives/list/type-ahead.ts +46 -0
  293. package/src/primitives/overlay/backdrop.spec.ts +54 -0
  294. package/src/primitives/overlay/backdrop.ts +31 -0
  295. package/src/primitives/overlay/builder.spec.ts +38 -0
  296. package/src/primitives/overlay/builder.ts +151 -0
  297. package/src/primitives/overlay/container.ts +42 -0
  298. package/src/primitives/overlay/context.ts +14 -0
  299. package/src/primitives/overlay/controller.spec.ts +86 -0
  300. package/src/primitives/overlay/controller.ts +190 -0
  301. package/src/primitives/overlay/id.spec.ts +24 -0
  302. package/src/primitives/overlay/id.ts +17 -0
  303. package/src/primitives/overlay/index.ts +18 -1
  304. package/src/primitives/overlay/overlay.css +42 -0
  305. package/src/primitives/overlay/panel.spec.ts +52 -0
  306. package/src/primitives/overlay/panel.ts +102 -0
  307. package/src/primitives/overlay/stack.spec.ts +55 -0
  308. package/src/primitives/overlay/stack.ts +113 -0
  309. package/src/primitives/overlay/strategies/backdrop/blurred.spec.ts +11 -0
  310. package/src/primitives/overlay/strategies/backdrop/blurred.ts +5 -0
  311. package/src/primitives/overlay/strategies/backdrop/none.spec.ts +10 -0
  312. package/src/primitives/overlay/strategies/backdrop/none.ts +9 -0
  313. package/src/primitives/overlay/strategies/backdrop/solid.spec.ts +18 -0
  314. package/src/primitives/overlay/strategies/backdrop/solid.ts +23 -0
  315. package/src/primitives/overlay/strategies/focus-trap/inert-based.spec.ts +28 -0
  316. package/src/primitives/overlay/strategies/focus-trap/inert-based.ts +38 -0
  317. package/src/primitives/overlay/strategies/focus-trap/no-trap.spec.ts +9 -0
  318. package/src/primitives/overlay/strategies/focus-trap/no-trap.ts +8 -0
  319. package/src/primitives/overlay/strategies/focus-trap/tab-cycle.spec.ts +49 -0
  320. package/src/primitives/overlay/strategies/focus-trap/tab-cycle.ts +85 -0
  321. package/src/primitives/overlay/strategies/index.ts +34 -0
  322. package/src/primitives/overlay/strategies/live-announcer/_announce.ts +35 -0
  323. package/src/primitives/overlay/strategies/live-announcer/assertive.spec.ts +21 -0
  324. package/src/primitives/overlay/strategies/live-announcer/assertive.ts +11 -0
  325. package/src/primitives/overlay/strategies/live-announcer/polite.spec.ts +21 -0
  326. package/src/primitives/overlay/strategies/live-announcer/polite.ts +11 -0
  327. package/src/primitives/overlay/strategies/live-announcer/silent.spec.ts +12 -0
  328. package/src/primitives/overlay/strategies/live-announcer/silent.ts +5 -0
  329. package/src/primitives/overlay/strategies/mount/body-portal.spec.ts +40 -0
  330. package/src/primitives/overlay/strategies/mount/body-portal.ts +91 -0
  331. package/src/primitives/overlay/strategies/mount/in-container.spec.ts +43 -0
  332. package/src/primitives/overlay/strategies/mount/in-container.ts +39 -0
  333. package/src/primitives/overlay/strategies/mount/in-place.spec.ts +40 -0
  334. package/src/primitives/overlay/strategies/mount/in-place.ts +20 -0
  335. package/src/primitives/overlay/strategies/position/anchored-to.spec.ts +56 -0
  336. package/src/primitives/overlay/strategies/position/anchored-to.ts +248 -0
  337. package/src/primitives/overlay/strategies/position/corner.spec.ts +36 -0
  338. package/src/primitives/overlay/strategies/position/corner.ts +33 -0
  339. package/src/primitives/overlay/strategies/position/edge-sheet.spec.ts +32 -0
  340. package/src/primitives/overlay/strategies/position/edge-sheet.ts +36 -0
  341. package/src/primitives/overlay/strategies/position/in-place-sibling.spec.ts +25 -0
  342. package/src/primitives/overlay/strategies/position/in-place-sibling.ts +13 -0
  343. package/src/primitives/overlay/strategies/position/point-at.spec.ts +40 -0
  344. package/src/primitives/overlay/strategies/position/point-at.ts +34 -0
  345. package/src/primitives/overlay/strategies/position/viewport-centered.spec.ts +31 -0
  346. package/src/primitives/overlay/strategies/position/viewport-centered.ts +31 -0
  347. package/src/primitives/overlay/strategies/scroll-lock/css-clip.spec.ts +15 -0
  348. package/src/primitives/overlay/strategies/scroll-lock/css-clip.ts +39 -0
  349. package/src/primitives/overlay/strategies/scroll-lock/html-overflow.spec.ts +21 -0
  350. package/src/primitives/overlay/strategies/scroll-lock/html-overflow.ts +44 -0
  351. package/src/primitives/overlay/strategies/scroll-lock/none.spec.ts +9 -0
  352. package/src/primitives/overlay/strategies/scroll-lock/none.ts +5 -0
  353. package/src/primitives/overlay/strategies/trigger-event/on-click.spec.ts +32 -0
  354. package/src/primitives/overlay/strategies/trigger-event/on-click.ts +28 -0
  355. package/src/primitives/overlay/strategies/trigger-event/on-context-menu.spec.ts +45 -0
  356. package/src/primitives/overlay/strategies/trigger-event/on-context-menu.ts +70 -0
  357. package/src/primitives/overlay/strategies/trigger-event/on-focus-or-input.spec.ts +35 -0
  358. package/src/primitives/overlay/strategies/trigger-event/on-focus-or-input.ts +34 -0
  359. package/src/primitives/overlay/strategies/trigger-event/on-focus.spec.ts +64 -0
  360. package/src/primitives/overlay/strategies/trigger-event/on-focus.ts +37 -0
  361. package/src/primitives/overlay/strategies/trigger-event/on-hotkey.spec.ts +37 -0
  362. package/src/primitives/overlay/strategies/trigger-event/on-hotkey.ts +59 -0
  363. package/src/primitives/overlay/strategies/trigger-event/on-hover.spec.ts +34 -0
  364. package/src/primitives/overlay/strategies/trigger-event/on-hover.ts +86 -0
  365. package/src/primitives/overlay/strategies/trigger-event/programmatic.spec.ts +16 -0
  366. package/src/primitives/overlay/strategies/trigger-event/programmatic.ts +12 -0
  367. package/src/primitives/overlay/tokens.ts +54 -0
  368. package/src/primitives/overlay/trigger.spec.ts +103 -0
  369. package/src/primitives/overlay/trigger.ts +75 -0
  370. package/src/primitives/overlay/types.ts +24 -0
  371. package/src/primitives/overlay/wrapper.ts +50 -0
  372. package/src/primitives/signals/deep-signal.ts +109 -0
  373. package/src/primitives/signals/index.ts +1 -0
  374. package/src/progress-bar/config.ts +48 -0
  375. package/src/progress-bar/index.ts +12 -0
  376. package/src/progress-bar/progress-bar-fill.ts +37 -0
  377. package/src/progress-bar/progress-bar.context.ts +34 -0
  378. package/src/progress-bar/progress-bar.spec.ts +423 -0
  379. package/src/progress-bar/progress-bar.ts +217 -0
  380. package/src/public-api.ts +58 -9
  381. package/src/radio/radio.ts +14 -3
  382. package/src/select/index.ts +4 -2
  383. package/src/select/select-content.ts +69 -0
  384. package/src/select/select-option.ts +35 -0
  385. package/src/select/select-root.ts +129 -0
  386. package/src/select/select-trigger.ts +93 -0
  387. package/src/select/select.spec.ts +133 -140
  388. package/src/select/select.ts +4 -250
  389. package/src/skeleton/index.ts +5 -0
  390. package/src/skeleton/skeleton.spec.ts +115 -0
  391. package/src/skeleton/skeleton.ts +56 -0
  392. package/src/slider/index.ts +10 -0
  393. package/src/slider/slider-range.ts +49 -0
  394. package/src/slider/slider-thumb.ts +335 -0
  395. package/src/slider/slider-track.ts +70 -0
  396. package/src/slider/slider.context.ts +79 -0
  397. package/src/slider/slider.geometry.ts +73 -0
  398. package/src/slider/slider.spec.ts +216 -0
  399. package/src/slider/slider.ts +443 -0
  400. package/src/speed-dial/index.ts +10 -0
  401. package/src/speed-dial/speed-dial-action.ts +40 -0
  402. package/src/speed-dial/speed-dial-actions.ts +31 -0
  403. package/src/speed-dial/speed-dial-trigger.ts +55 -0
  404. package/src/speed-dial/speed-dial.context.ts +36 -0
  405. package/src/speed-dial/speed-dial.spec.ts +143 -0
  406. package/src/speed-dial/speed-dial.ts +127 -0
  407. package/src/spinner/config.ts +48 -0
  408. package/src/spinner/index.ts +8 -0
  409. package/src/spinner/spinner.spec.ts +262 -0
  410. package/src/spinner/spinner.ts +129 -0
  411. package/src/stepper/index.ts +15 -0
  412. package/src/stepper/stepper.context.ts +63 -0
  413. package/src/stepper/stepper.spec.ts +403 -0
  414. package/src/stepper/stepper.ts +544 -0
  415. package/src/styles.css +17 -0
  416. package/src/table/column-helpers.spec.ts +74 -0
  417. package/src/table/column-helpers.ts +68 -0
  418. package/src/table/filter-fns.ts +230 -0
  419. package/src/table/filter-models.spec.ts +240 -0
  420. package/src/table/filter-models.ts +124 -0
  421. package/src/table/filter-params.ts +90 -0
  422. package/src/table/grid-api-impl.ts +321 -0
  423. package/src/table/grid-api.spec.ts +178 -0
  424. package/src/table/grid-api.ts +285 -0
  425. package/src/table/index.ts +73 -1
  426. package/src/table/table-cell.spec.ts +43 -0
  427. package/src/table/table-cell.ts +38 -0
  428. package/src/table/table-filter-outlet.ts +120 -0
  429. package/src/table/table-header.spec.ts +54 -0
  430. package/src/table/table-header.ts +63 -0
  431. package/src/table/table-keyboard.spec.ts +68 -0
  432. package/src/table/table-keyboard.ts +107 -0
  433. package/src/table/table-resource.spec.ts +37 -0
  434. package/src/table/table-resource.ts +36 -0
  435. package/src/table/table-row.spec.ts +54 -0
  436. package/src/table/table-row.ts +31 -0
  437. package/src/table/table-storage.spec.ts +67 -0
  438. package/src/table/table-storage.ts +76 -0
  439. package/src/table/table.spec.ts +102 -43
  440. package/src/table/table.ts +228 -73
  441. package/src/table/table.types.ts +83 -0
  442. package/src/tabs/index.ts +7 -2
  443. package/src/tabs/tabs.context.ts +27 -4
  444. package/src/tabs/tabs.spec.ts +336 -24
  445. package/src/tabs/tabs.ts +313 -79
  446. package/src/tag/config.ts +53 -0
  447. package/src/tag/index.ts +7 -0
  448. package/src/tag/tag-list.ts +76 -0
  449. package/src/tag/tag-remove.ts +61 -0
  450. package/src/tag/tag.context.ts +36 -0
  451. package/src/tag/tag.spec.ts +240 -0
  452. package/src/tag/tag.ts +203 -0
  453. package/src/textarea/config.ts +42 -0
  454. package/src/textarea/index.ts +8 -0
  455. package/src/textarea/textarea.spec.ts +176 -0
  456. package/src/textarea/textarea.ts +235 -0
  457. package/src/time-picker/index.ts +15 -0
  458. package/src/time-picker/time-picker-meridiem.ts +123 -0
  459. package/src/time-picker/time-picker-segment.ts +318 -0
  460. package/src/time-picker/time-picker.context.ts +38 -0
  461. package/src/time-picker/time-picker.format.ts +181 -0
  462. package/src/time-picker/time-picker.spec.ts +189 -0
  463. package/src/time-picker/time-picker.ts +274 -0
  464. package/src/toast/_examples/index.ts +5 -0
  465. package/src/toast/_examples/toast.example.ts +282 -0
  466. package/src/toast/_examples/toast.finance.example.ts +180 -0
  467. package/src/toast/_examples/toast.retro.example.ts +161 -0
  468. package/src/toast/index.ts +8 -1
  469. package/src/toast/toast.ref.ts +26 -0
  470. package/src/toast/toast.service.ts +227 -41
  471. package/src/toast/toast.spec.ts +178 -25
  472. package/src/toast/toast.strategy.ts +10 -0
  473. package/src/toast/toast.ts +178 -22
  474. package/src/toggle/toggle.ts +10 -2
  475. package/src/tooltip/_examples/index.ts +6 -0
  476. package/src/tooltip/_examples/tooltip.example.ts +82 -0
  477. package/src/tooltip/_examples/tooltip.finance.example.ts +97 -0
  478. package/src/tooltip/_examples/tooltip.placements.example.ts +83 -0
  479. package/src/tooltip/_examples/tooltip.retro.example.ts +107 -0
  480. package/src/tooltip/index.ts +4 -5
  481. package/src/tooltip/tooltip-arrow.ts +31 -0
  482. package/src/tooltip/tooltip-content.ts +38 -0
  483. package/src/tooltip/tooltip-group.ts +32 -0
  484. package/src/tooltip/tooltip-trigger.ts +47 -0
  485. package/src/tooltip/tooltip.spec.ts +38 -102
  486. package/src/tooltip/tooltip.ts +5 -129
  487. package/src/tree-select/index.ts +12 -0
  488. package/src/tree-select/tree-select-content.ts +199 -0
  489. package/src/tree-select/tree-select-node.ts +132 -0
  490. package/src/tree-select/tree-select-root.ts +272 -0
  491. package/src/tree-select/tree-select-trigger.ts +90 -0
  492. package/src/tree-select/tree-select.context.ts +63 -0
  493. package/src/tree-select/tree-select.spec.ts +433 -0
  494. package/src/tree-select/tree-select.ts +2 -0
  495. package/src/typography/blockquote.ts +57 -0
  496. package/src/typography/code.ts +53 -0
  497. package/src/typography/index.ts +22 -0
  498. package/src/typography/lead.ts +49 -0
  499. package/src/typography/muted.ts +29 -0
  500. package/src/typography/prose.css +312 -0
  501. package/src/typography/truncate.ts +99 -0
  502. package/src/typography/typography.spec.ts +203 -0
  503. package/tsconfig.lib.json +9 -1
  504. package/tsconfig.lib.prod.json +7 -1
  505. package/tsconfig.spec.json +9 -1
  506. package/vite.config.ts +8 -0
  507. package/src/button/button.example.ts +0 -30
  508. package/src/button/button.finance.example.ts +0 -37
  509. package/src/button/button.retro.example.ts +0 -47
  510. package/src/button/button.sizes.example.ts +0 -25
  511. package/src/dialog/dialog.confirm.example.ts +0 -57
  512. package/src/dialog/dialog.context.ts +0 -11
  513. package/src/dialog/dialog.example.ts +0 -40
  514. package/src/dialog/dialog.finance.example.ts +0 -47
  515. package/src/dialog/dialog.retro.example.ts +0 -46
  516. package/src/menu/index.ts +0 -2
  517. package/src/menu/menu.context.ts +0 -10
  518. package/src/menu/menu.example.ts +0 -39
  519. package/src/menu/menu.spec.ts +0 -168
  520. package/src/menu/menu.ts +0 -176
  521. package/src/popover/popover.context.ts +0 -18
  522. package/src/popover/popover.example.ts +0 -50
  523. package/src/popover/popover.finance.example.ts +0 -52
  524. package/src/popover/popover.retro.example.ts +0 -53
  525. package/src/primitives/overlay/overlay.spec.ts +0 -90
  526. package/src/primitives/overlay/overlay.ts +0 -102
  527. package/src/select/select.context.ts +0 -3
  528. package/src/toast/toast.example.ts +0 -134
  529. package/src/toast/toast.finance.example.ts +0 -68
  530. package/src/toast/toast.retro.example.ts +0 -69
  531. package/src/tooltip/tooltip.example.ts +0 -46
  532. package/src/tooltip/tooltip.finance.example.ts +0 -54
  533. package/src/tooltip/tooltip.placements.example.ts +0 -56
  534. package/src/tooltip/tooltip.retro.example.ts +0 -65
@@ -0,0 +1,75 @@
1
+ import { Component } from '@angular/core';
2
+ import { render } from '@testing-library/angular';
3
+ import { describe, it, expect } from 'vitest';
4
+ import {
5
+ KjCombobox,
6
+ KjComboboxInput,
7
+ KjComboboxListbox,
8
+ KjComboboxOption,
9
+ } from './combobox';
10
+
11
+ describe('KjCombobox', () => {
12
+ it('input has role=combobox and aria-haspopup=listbox', async () => {
13
+ @Component({
14
+ selector: 'kj-cb-host',
15
+ standalone: true,
16
+ imports: [KjCombobox, KjComboboxInput, KjComboboxListbox, KjComboboxOption],
17
+ template: `
18
+ <div kjCombobox>
19
+ <input kjComboboxInput #t="kjOverlayTrigger" aria-label="Country" />
20
+ <div kjComboboxListbox [kjFor]="t">
21
+ <button kjComboboxOption [kjOptionValue]="'fr'">France</button>
22
+ </div>
23
+ </div>
24
+ `,
25
+ })
26
+ class Host {}
27
+ const { container } = await render(Host);
28
+ const input = container.querySelector('input[kjComboboxInput]')!;
29
+ expect(input.getAttribute('role')).toBe('combobox');
30
+ expect(input.getAttribute('aria-haspopup')).toBe('listbox');
31
+ expect(input.getAttribute('aria-expanded')).toBe('false');
32
+ });
33
+
34
+ it('panel exposes role=listbox', async () => {
35
+ @Component({
36
+ selector: 'kj-cb-host',
37
+ standalone: true,
38
+ imports: [KjCombobox, KjComboboxInput, KjComboboxListbox, KjComboboxOption],
39
+ template: `
40
+ <div kjCombobox>
41
+ <input kjComboboxInput #t="kjOverlayTrigger" aria-label="Country" />
42
+ <div kjComboboxListbox [kjFor]="t">
43
+ <button kjComboboxOption [kjOptionValue]="'fr'">France</button>
44
+ </div>
45
+ </div>
46
+ `,
47
+ })
48
+ class Host {}
49
+ const { container } = await render(Host);
50
+ const panel = container.querySelector('[kjComboboxListbox]') as HTMLElement;
51
+ expect(panel.getAttribute('role')).toBe('listbox');
52
+ });
53
+
54
+ it('options carry role=option', async () => {
55
+ @Component({
56
+ selector: 'kj-cb-host',
57
+ standalone: true,
58
+ imports: [KjCombobox, KjComboboxInput, KjComboboxListbox, KjComboboxOption],
59
+ template: `
60
+ <div kjCombobox>
61
+ <input kjComboboxInput #t="kjOverlayTrigger" aria-label="Country" />
62
+ <div kjComboboxListbox [kjFor]="t">
63
+ <button kjComboboxOption [kjOptionValue]="'fr'">France</button>
64
+ <button kjComboboxOption [kjOptionValue]="'de'">Germany</button>
65
+ </div>
66
+ </div>
67
+ `,
68
+ })
69
+ class Host {}
70
+ const { container } = await render(Host);
71
+ const opts = container.querySelectorAll('[kjComboboxOption]');
72
+ expect(opts.length).toBe(2);
73
+ opts.forEach(o => expect(o.getAttribute('role')).toBe('option'));
74
+ });
75
+ });
@@ -0,0 +1,4 @@
1
+ export * from './combobox-root';
2
+ export * from './combobox-input';
3
+ export * from './combobox-listbox';
4
+ export * from './combobox-option';
@@ -0,0 +1,4 @@
1
+ export * from './combobox-root';
2
+ export * from './combobox-input';
3
+ export * from './combobox-listbox';
4
+ export * from './combobox-option';
@@ -0,0 +1,36 @@
1
+ import { Directive, computed, inject } from '@angular/core';
2
+ import { KjCommandPalette } from './command-palette';
3
+
4
+ /**
5
+ * Slot shown when the palette has no visible items and is not loading.
6
+ * Sets `role="status"` and `aria-live="polite"` for live-region announcements.
7
+ * Hidden when items are visible or loading is active.
8
+ *
9
+ * @example
10
+ * ```html
11
+ * <div kjCommandList>
12
+ * <div kjCommandEmpty>No results found.</div>
13
+ * <button kjCommandItem>…</button>
14
+ * </div>
15
+ * ```
16
+ * @doc-category Core/Actions
17
+ * @doc
18
+ * @doc-name command-palette
19
+ */
20
+ @Directive({
21
+ selector: '[kjCommandEmpty]',
22
+ standalone: true,
23
+ host: {
24
+ 'role': 'status',
25
+ 'aria-live': 'polite',
26
+ '[hidden]': 'isHidden()',
27
+ },
28
+ })
29
+ export class KjCommandEmpty {
30
+ private readonly ctx = inject(KjCommandPalette);
31
+
32
+ /** Hidden unless there are no visible items and loading is false. */
33
+ readonly isHidden = computed(() =>
34
+ this.ctx.visibleItems().length > 0 || this.ctx.loading()
35
+ );
36
+ }
@@ -0,0 +1,21 @@
1
+ import { Directive } from '@angular/core';
2
+ import { KjListGroup } from '../primitives/list';
3
+
4
+ /**
5
+ * Group wrapper for command items. Composes `KjListGroup` for the
6
+ * shared role=group / aria-labelledby / auto-hide-when-empty behavior;
7
+ * this selector exists so existing command-palette templates keep
8
+ * working unchanged.
9
+ *
10
+ * Pair with a `[kjListGroupLabel]` heading element for the section title.
11
+ *
12
+ * @doc-category Core/Actions
13
+ * @doc
14
+ * @doc-name command-palette
15
+ */
16
+ @Directive({
17
+ selector: '[kjCommandGroup]',
18
+ standalone: true,
19
+ hostDirectives: [KjListGroup],
20
+ })
21
+ export class KjCommandGroup {}
@@ -0,0 +1,70 @@
1
+ import {
2
+ Directive,
3
+ ElementRef,
4
+ HostListener,
5
+ OnDestroy,
6
+ OnInit,
7
+ inject,
8
+ } from '@angular/core';
9
+ import { KjListNavigator } from '../primitives/list';
10
+ import { KjCommandPalette } from './command-palette';
11
+
12
+ /**
13
+ * Search input inside the command palette. Composes `KjListNavigator`
14
+ * — `aria-activedescendant` and the APG combobox 1.2 keyboard contract
15
+ * live here, not on the listbox.
16
+ *
17
+ * Keyboard contract:
18
+ * - `ArrowDown` / `ArrowUp` — move active item (handled by `KjListNavigator`)
19
+ * - `Home` / `End` — jump to first/last (handled by `KjListNavigator`)
20
+ * - `Enter` — activate active item (handled by `KjListNavigator`)
21
+ * - `Escape` — first press clears query; second press propagates to dialog
22
+ *
23
+ * @doc-category Core/Actions
24
+ * @doc
25
+ * @doc-name command-palette
26
+ */
27
+ @Directive({
28
+ selector: 'input[kjCommandInput]',
29
+ standalone: true,
30
+ exportAs: 'kjCommandInput',
31
+ hostDirectives: [KjListNavigator],
32
+ host: {
33
+ 'role': 'combobox',
34
+ 'autocomplete': 'off',
35
+ 'autocorrect': 'off',
36
+ 'spellcheck': 'false',
37
+ 'aria-autocomplete': 'list',
38
+ 'aria-haspopup': 'listbox',
39
+ '[attr.aria-controls]': 'palette.listId',
40
+ '[attr.aria-expanded]': '"true"',
41
+ '[attr.aria-busy]': 'palette.loading() ? "true" : null',
42
+ '(input)': 'palette.setQuery($any($event.target).value)',
43
+ },
44
+ })
45
+ export class KjCommandInput implements OnInit, OnDestroy {
46
+ protected readonly palette = inject(KjCommandPalette);
47
+ private readonly nav = inject(KjListNavigator);
48
+ private readonly el = inject<ElementRef<HTMLInputElement>>(ElementRef);
49
+
50
+ ngOnInit(): void {
51
+ this.palette._setNavigator(this.nav);
52
+ }
53
+
54
+ ngOnDestroy(): void {
55
+ this.palette._setNavigator(null);
56
+ }
57
+
58
+ @HostListener('keydown', ['$event'])
59
+ onKeydown(event: KeyboardEvent): void {
60
+ if (event.key === 'Escape') {
61
+ // First press: clear query. Second press propagates to the dialog.
62
+ if (this.palette.query()) {
63
+ event.stopPropagation();
64
+ this.palette.setQuery('');
65
+ this.el.nativeElement.value = '';
66
+ }
67
+ // If query is already empty, let the event bubble to KjDialog's Escape handler
68
+ }
69
+ }
70
+ }
@@ -0,0 +1,60 @@
1
+ import {
2
+ Directive,
3
+ computed,
4
+ inject,
5
+ } from '@angular/core';
6
+ import { KjListItem, injectListItem } from '../primitives/list';
7
+ import { KjCommandPalette } from './command-palette';
8
+
9
+ /**
10
+ * Individual command item (`role="option"`). Composes `KjListItem` for
11
+ * id / value / label / keywords / disabled / click+keyboard activation.
12
+ * The activation → `palette.activate(value)` wiring is now handled
13
+ * centrally by `KjCommandPalette.afterSelect`, called from
14
+ * `KjListItem` — this directive only contributes role, classes, the
15
+ * `kj*` input aliases, and the active-item ARIA / data attributes.
16
+ *
17
+ * @example
18
+ * ```html
19
+ * <div kjCommandPalette>
20
+ * <div kjCommandList>
21
+ * <button kjCommandItem [kjValue]="'open-settings'">Settings</button>
22
+ * </div>
23
+ * </div>
24
+ * ```
25
+ * @doc-category Core/Actions
26
+ * @doc
27
+ * @doc-name command-palette
28
+ */
29
+ @Directive({
30
+ selector: '[kjCommandItem]',
31
+ standalone: true,
32
+ exportAs: 'kjCommandItem',
33
+ hostDirectives: [
34
+ {
35
+ directive: KjListItem,
36
+ inputs: [
37
+ 'kjItemValue:kjValue',
38
+ 'kjItemLabel:kjLabel',
39
+ 'kjItemKeywords:kjKeywords',
40
+ 'kjShortcut:kjShortcut',
41
+ 'kjDisabled:kjDisabled',
42
+ ],
43
+ },
44
+ ],
45
+ host: {
46
+ 'class': 'kj-command-item',
47
+ 'role': 'option',
48
+ '[attr.aria-selected]': 'isActive() ? "true" : "false"',
49
+ '[attr.data-active]': 'isActive() ? "" : null',
50
+ },
51
+ })
52
+ export class KjCommandItem {
53
+ private readonly item = injectListItem<unknown>();
54
+ private readonly palette = inject(KjCommandPalette);
55
+
56
+ /** Whether this item is the active (highlighted) item. */
57
+ readonly isActive = computed(() =>
58
+ this.palette.activeId() !== null && this.palette.activeId() === this.item.id,
59
+ );
60
+ }
@@ -0,0 +1,25 @@
1
+ import { Directive, inject } from '@angular/core';
2
+ import { KjCommandPalette } from './command-palette';
3
+
4
+ /**
5
+ * Listbox panel for the command palette. Role-only — keyboard nav
6
+ * lives on `KjCommandInput` per APG combobox 1.2.
7
+ *
8
+ * @doc-category Core/Actions
9
+ * @doc
10
+ * @doc-name command-palette
11
+ */
12
+ @Directive({
13
+ selector: '[kjCommandList]',
14
+ standalone: true,
15
+ host: {
16
+ 'role': 'listbox',
17
+ '[id]': 'palette.listId',
18
+ 'class': 'kj-command-list',
19
+ '[attr.aria-label]': '"Commands"',
20
+ },
21
+ })
22
+ export class KjCommandList {
23
+ /** @internal — for the [id] host binding. */
24
+ protected readonly palette = inject(KjCommandPalette);
25
+ }
@@ -0,0 +1,74 @@
1
+ // command-palette-dialog.ts
2
+ import {
3
+ Component,
4
+ ChangeDetectionStrategy,
5
+ ViewEncapsulation,
6
+ } from '@angular/core';
7
+ import { KjOverlayPanel } from '../primitives/overlay/panel';
8
+ import { KjOverlayController } from '../primitives/overlay/controller';
9
+ import {
10
+ KJ_OVERLAY_MOUNT_STRATEGY,
11
+ KJ_OVERLAY_POSITION_STRATEGY,
12
+ KJ_OVERLAY_BACKDROP_STRATEGY,
13
+ KJ_OVERLAY_FOCUS_TRAP_STRATEGY,
14
+ KJ_OVERLAY_SCROLL_LOCK_STRATEGY,
15
+ KJ_OVERLAY_LIVE_ANNOUNCER_STRATEGY,
16
+ KJ_OVERLAY_TRIGGER_EVENT_STRATEGY,
17
+ KJ_OVERLAY_PANEL_ROLE,
18
+ } from '../primitives/overlay/tokens';
19
+ import { bodyPortal } from '../primitives/overlay/strategies/mount/body-portal';
20
+ import { viewportCentered } from '../primitives/overlay/strategies/position/viewport-centered';
21
+ import { solidBackdrop } from '../primitives/overlay/strategies/backdrop/solid';
22
+ import { tabCycle } from '../primitives/overlay/strategies/focus-trap/tab-cycle';
23
+ import { htmlOverflow } from '../primitives/overlay/strategies/scroll-lock/html-overflow';
24
+ import { silent } from '../primitives/overlay/strategies/live-announcer/silent';
25
+ import { programmatic } from '../primitives/overlay/strategies/trigger-event/programmatic';
26
+
27
+ /**
28
+ * Modal panel for the command palette (Cmd-K pattern). Composes
29
+ * `KjOverlayPanel` and provides the modal-list strategy bundle: portalled
30
+ * mount, viewport-centered position, solid (inert + close-on-click) backdrop,
31
+ * tab-cycle focus trap with first-focus + return, html-overflow scroll lock,
32
+ * and a silent live announcer.
33
+ *
34
+ * Pair with `[kjCommandPaletteTrigger]` (which supplies an `onHotkey`
35
+ * trigger-event strategy) for the standard mod+k flow, or use programmatic
36
+ * open/close via the bound `KjOverlayController`.
37
+ *
38
+ * The host element gets `aria-label="Command palette"` and `role="dialog"`.
39
+ *
40
+ * @doc-category Core/Actions
41
+ * @doc
42
+ * @doc-name command-palette
43
+ */
44
+ @Component({
45
+ selector: 'kj-command-palette-dialog',
46
+ standalone: true,
47
+ hostDirectives: [
48
+ { directive: KjOverlayPanel, inputs: ['kjFor'] },
49
+ ],
50
+ providers: [
51
+ KjOverlayController,
52
+ { provide: KJ_OVERLAY_MOUNT_STRATEGY, useFactory: () => bodyPortal() },
53
+ { provide: KJ_OVERLAY_POSITION_STRATEGY, useFactory: () => viewportCentered() },
54
+ {
55
+ provide: KJ_OVERLAY_BACKDROP_STRATEGY,
56
+ useFactory: () => solidBackdrop({ inert: true, closeOnClick: true }),
57
+ },
58
+ {
59
+ provide: KJ_OVERLAY_FOCUS_TRAP_STRATEGY,
60
+ useFactory: () => tabCycle({ initialFocus: 'first', returnFocus: true }),
61
+ },
62
+ { provide: KJ_OVERLAY_SCROLL_LOCK_STRATEGY, useFactory: () => htmlOverflow() },
63
+ { provide: KJ_OVERLAY_LIVE_ANNOUNCER_STRATEGY, useFactory: () => silent() },
64
+ { provide: KJ_OVERLAY_TRIGGER_EVENT_STRATEGY, useFactory: () => programmatic() },
65
+ { provide: KJ_OVERLAY_PANEL_ROLE, useValue: 'dialog' as const },
66
+ ],
67
+ changeDetection: ChangeDetectionStrategy.OnPush,
68
+ encapsulation: ViewEncapsulation.None,
69
+ host: {
70
+ '[attr.aria-label]': '"Command palette"',
71
+ },
72
+ template: `<ng-content />`,
73
+ })
74
+ export class KjCommandPaletteDialog {}
@@ -0,0 +1,64 @@
1
+ // command-palette-trigger.ts
2
+ import { Directive, inject, input } from '@angular/core';
3
+ import { KjOverlayTrigger } from '../primitives/overlay/trigger';
4
+ import type { KjOverlayPanel } from '../primitives/overlay/panel';
5
+ import { KjOverlayController } from '../primitives/overlay/controller';
6
+ import {
7
+ KJ_OVERLAY_TRIGGER_EVENT_STRATEGY,
8
+ KJ_OVERLAY_PANEL_ROLE,
9
+ } from '../primitives/overlay/tokens';
10
+ import { onHotkey } from '../primitives/overlay/strategies/trigger-event/on-hotkey';
11
+
12
+ /**
13
+ * Hotkey-driven trigger for the command palette. Toggles the linked
14
+ * `<kj-command-palette-dialog>` panel when the configured chord fires
15
+ * (default `mod+k` — Cmd+K on macOS, Ctrl+K elsewhere).
16
+ *
17
+ * Composes `KjOverlayTrigger` via `hostDirectives` and provides an
18
+ * `onHotkey()` trigger-event strategy (replacing the legacy
19
+ * `KjCommandPaletteHotkey` directive).
20
+ *
21
+ * @example
22
+ * ```html
23
+ * <button kjCommandPaletteTrigger #t="kjCommandPaletteTrigger" kjHotkey="mod+k">
24
+ * Open palette
25
+ * </button>
26
+ * <kj-command-palette-dialog [kjFor]="t">
27
+ * <div kjCommandPalette>...</div>
28
+ * </kj-command-palette-dialog>
29
+ * ```
30
+ *
31
+ * @doc-category Core/Actions
32
+ */
33
+ @Directive({
34
+ selector: '[kjCommandPaletteTrigger]',
35
+ exportAs: 'kjCommandPaletteTrigger',
36
+ standalone: true,
37
+ hostDirectives: [
38
+ { directive: KjOverlayTrigger, inputs: ['kjOpen'] },
39
+ ],
40
+ providers: [
41
+ KjOverlayController,
42
+ {
43
+ provide: KJ_OVERLAY_TRIGGER_EVENT_STRATEGY,
44
+ useFactory: () => onHotkey('mod+k'),
45
+ },
46
+ { provide: KJ_OVERLAY_PANEL_ROLE, useValue: 'dialog' as const },
47
+ ],
48
+ })
49
+ export class KjCommandPaletteTrigger {
50
+ /**
51
+ * Keyboard chord. `mod` resolves to `Meta` on macOS, `Ctrl` elsewhere.
52
+ * Captured at provider construction; reactive switching is a follow-up.
53
+ */
54
+ readonly kjHotkey = input<string>('mod+k');
55
+
56
+ private readonly _overlayTrigger = inject(KjOverlayTrigger, { self: true });
57
+ /** The controller of the composed `KjOverlayTrigger`, exposed for sibling `[kjFor]` panels. */
58
+ get controller(): KjOverlayController {
59
+ return this._overlayTrigger.controller;
60
+ }
61
+ attachPanel(panel: KjOverlayPanel): void {
62
+ this._overlayTrigger.attachPanel(panel);
63
+ }
64
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Filter function type for the command palette.
3
+ * Returns a numeric score: > 0 means the item is visible, 0 means hidden.
4
+ * Higher scores are more relevant when sorting by score.
5
+ */
6
+ export type KjCommandFilter = (query: string, haystacks: readonly string[]) => number;
7
+
8
+ /**
9
+ * Strip diacritic marks from a string (e.g. `café` → `cafe`).
10
+ * Uses NFD normalisation followed by removal of Unicode diacritic characters.
11
+ * Note: locale-naive for v1 (Turkish/German edge cases are documented).
12
+ */
13
+ export function stripDiacritics(str: string): string {
14
+ return str.normalize('NFD').replace(/\p{Diacritic}/gu, '');
15
+ }
16
+
17
+ /**
18
+ * Default filter: case- and diacritic-insensitive substring match.
19
+ * Returns score 1 if any haystack contains the needle, 0 otherwise.
20
+ * Returns 1 for empty queries (all items visible).
21
+ */
22
+ export const kjSubstringFilter: KjCommandFilter = (query, haystacks) => {
23
+ if (!query) return 1;
24
+ const needle = stripDiacritics(query.toLowerCase());
25
+ return haystacks.some(h => stripDiacritics(h.toLowerCase()).includes(needle)) ? 1 : 0;
26
+ };
27
+
28
+ /**
29
+ * Optional fuzzy filter: checks whether all characters of the query appear
30
+ * in the haystack in order (abbreviation matching).
31
+ * E.g. `gth` matches `git checkout`.
32
+ * Returns score 1 if any haystack matches, 0 otherwise.
33
+ * Returns 1 for empty queries.
34
+ *
35
+ * @example
36
+ * ```html
37
+ * <div kjCommandPalette [kjFilter]="kjFuzzyFilter">…</div>
38
+ * ```
39
+ */
40
+ export const kjFuzzyFilter: KjCommandFilter = (query, haystacks) => {
41
+ if (!query) return 1;
42
+ const needle = query.toLowerCase();
43
+ return haystacks.some(h => {
44
+ const hay = h.toLowerCase();
45
+ let i = 0;
46
+ for (const c of needle) {
47
+ const j = hay.indexOf(c, i);
48
+ if (j < 0) return false;
49
+ i = j + 1;
50
+ }
51
+ return true;
52
+ }) ? 1 : 0;
53
+ };