@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
@@ -1,26 +1,39 @@
1
- import { Directive, InjectionToken, inject, signal } from '@angular/core';
1
+ import { Directive, InjectionToken, inject, signal } from '@angular/core';
2
2
 
3
3
  export interface KjAvatarContext { imageLoaded: ReturnType<typeof signal<boolean>>; }
4
4
  export const KJ_AVATAR = new InjectionToken<KjAvatarContext>('KjAvatar');
5
5
 
6
6
  /**
7
7
  * Container for avatar. Tracks image load state.
8
+ *
9
+ * Compose `[kjAvatar]` with `[kjAvatarImage]` and `[kjAvatarFallback]` onto any
10
+ * elements to toggle visibility between the image and the fallback
11
+ * automatically when the image fails or is still loading. No styling attached.
12
+ *
8
13
  * @example `<span kjAvatar><img kjAvatarImage src="..." alt="..." /><span kjAvatarFallback>JD</span></span>`
9
- * @category Core/Display
14
+ * @doc-category Core/Data display
15
+ * @doc
16
+ * @doc-name avatar
17
+ * @doc-description Unstyled avatar container that swaps between an image and a fallback when loading or failing.
18
+ * @doc-is-main
10
19
  */
11
20
  @Directive({ selector: '[kjAvatar]', standalone: true, providers: [{ provide: KJ_AVATAR, useExisting: KjAvatar }] })
12
21
  export class KjAvatar implements KjAvatarContext { readonly imageLoaded = signal(false); }
13
22
 
14
23
  /**
15
24
  * Image element within a `[kjAvatar]` container.
16
- * @category Core/Display
25
+ * @doc-category Core/Data display
26
+ * @doc
27
+ * @doc-name avatar
17
28
  */
18
29
  @Directive({ selector: '[kjAvatarImage]', standalone: true, host: { '(load)': 'ctx.imageLoaded.set(true)', '(error)': 'ctx.imageLoaded.set(false)', '[attr.data-loaded]': 'ctx.imageLoaded() ? "" : null' } })
19
30
  export class KjAvatarImage { readonly ctx = inject(KJ_AVATAR); }
20
31
 
21
32
  /**
22
33
  * Fallback shown when image is unavailable.
23
- * @category Core/Display
34
+ * @doc-category Core/Data display
35
+ * @doc
36
+ * @doc-name avatar
24
37
  */
25
38
  @Directive({ selector: '[kjAvatarFallback]', standalone: true, host: { '[attr.data-visible]': '!ctx.imageLoaded() ? "" : null' } })
26
39
  export class KjAvatarFallback { readonly ctx = inject(KJ_AVATAR); }
@@ -1 +1,11 @@
1
- export { KjAvatar, KjAvatarImage, KjAvatarFallback, KJ_AVATAR } from './avatar';
1
+ export { KjAvatar, KjAvatarImage, KjAvatarFallback, KJ_AVATAR } from './avatar';
2
+ export {
3
+ KjAvatarGroup,
4
+ type KjAvatarGroupAriaLabelFormat,
5
+ } from './avatar-group';
6
+ export {
7
+ KJ_AVATAR_GROUP,
8
+ type KjAvatarGroupContext,
9
+ type KjAvatarGroupDirection,
10
+ type KjAvatarShape,
11
+ } from './avatar-group.context';
@@ -13,6 +13,14 @@ describe('KjBadge', () => {
13
13
  const { container } = await render(`<span kjBadge>Beta</span>`, { imports: [KjBadge] });
14
14
  expect(container.querySelector('span')).toHaveAttribute('data-variant', 'default');
15
15
  });
16
+ it('sets data-dot attribute when kjBadgeDot is true', async () => {
17
+ const { container } = await render(`<span kjBadge [kjBadgeDot]="true">Active</span>`, { imports: [KjBadge] });
18
+ expect(container.querySelector('span')).toHaveAttribute('data-dot', '');
19
+ });
20
+ it('omits data-dot attribute by default', async () => {
21
+ const { container } = await render(`<span kjBadge>Beta</span>`, { imports: [KjBadge] });
22
+ expect(container.querySelector('span')).not.toHaveAttribute('data-dot');
23
+ });
16
24
  it('passes axe audit', async () => {
17
25
  const { container } = await render(`<span kjBadge>Beta</span>`, { imports: [KjBadge] });
18
26
  expect(await axe(container)).toHaveNoViolations();
@@ -1,14 +1,35 @@
1
- import { Directive, input } from '@angular/core';
1
+ import { Directive, booleanAttribute, input } from '@angular/core';
2
2
 
3
3
  export type KjBadgeVariant = 'default' | 'secondary' | 'destructive' | 'outline';
4
4
 
5
5
  /**
6
6
  * Marks an element as a badge via data attributes.
7
+ *
8
+ * Apply `[kjBadge]` to any inline element to reflect a `data-variant` attribute
9
+ * that theme CSS reads — choose from `default`, `secondary`, `destructive`, or
10
+ * `outline` without adding any wrapper markup. No styling is attached.
11
+ *
12
+ * Set `kjBadgeDot` to reflect a `data-dot` attribute for theme CSS to render a
13
+ * leading status indicator.
14
+ *
7
15
  * @example `<span kjBadge [kjBadgeVariant]="'destructive'">Critical</span>`
8
- * @category Core/Display
16
+ * @doc-category Core/Data display
17
+ * @doc
18
+ * @doc-name badge
19
+ * @doc-description Marks an inline element as a badge with a variant data attribute that theme CSS picks up.
20
+ * @doc-is-main
9
21
  */
10
- @Directive({ selector: '[kjBadge]', standalone: true, host: { '[attr.data-variant]': 'kjBadgeVariant()' } })
22
+ @Directive({
23
+ selector: '[kjBadge]',
24
+ standalone: true,
25
+ host: {
26
+ '[attr.data-variant]': 'kjBadgeVariant()',
27
+ '[attr.data-dot]': 'kjBadgeDot() ? "" : null',
28
+ },
29
+ })
11
30
  export class KjBadge {
12
31
  /** The visual variant of the badge. Defaults to `'default'`. */
13
32
  kjBadgeVariant = input<KjBadgeVariant>('default');
33
+ /** Reflects `data-dot` so theme CSS can render a leading status dot. Defaults to `false`. */
34
+ kjBadgeDot = input(false, { transform: booleanAttribute });
14
35
  }
@@ -0,0 +1,38 @@
1
+ import { Directive, OnDestroy, inject } from '@angular/core';
2
+ import { KJ_BREADCRUMB } from './breadcrumb.context';
3
+
4
+ /**
5
+ * The terminal "current page" cell. Emits `aria-current="page"` and
6
+ * registers with the parent so auto-current detection knows to step aside.
7
+ *
8
+ * The element is text — not focusable, not an anchor. Place inside the last
9
+ * `<li kjBreadcrumbItem>` to mark the current page explicitly.
10
+ *
11
+ * @example
12
+ * ```html
13
+ * <span kjBreadcrumbCurrent>Data</span>
14
+ * ```
15
+ *
16
+ * @doc-category Core/Navigation
17
+ * @doc
18
+ * @doc-name breadcrumb
19
+ */
20
+ @Directive({
21
+ selector: 'span[kjBreadcrumbCurrent], [kjBreadcrumbCurrent]',
22
+ standalone: true,
23
+ host: {
24
+ '[attr.aria-current]': '"page"',
25
+ '[attr.data-breadcrumb-current]': '""',
26
+ },
27
+ })
28
+ export class KjBreadcrumbCurrent implements OnDestroy {
29
+ private readonly root = inject(KJ_BREADCRUMB);
30
+
31
+ constructor() {
32
+ this.root.registerCurrent();
33
+ }
34
+
35
+ ngOnDestroy(): void {
36
+ this.root.unregisterCurrent();
37
+ }
38
+ }
@@ -0,0 +1,71 @@
1
+ import {
2
+ Directive,
3
+ booleanAttribute,
4
+ computed,
5
+ inject,
6
+ input,
7
+ } from '@angular/core';
8
+ import { KjFocusRing } from '../primitives';
9
+ import { KJ_BREADCRUMB } from './breadcrumb.context';
10
+ import { KJ_BREADCRUMB_CONFIG } from './config';
11
+
12
+ /**
13
+ * Overflow indicator rendered in place of truncated middle crumbs.
14
+ *
15
+ * - In `'truncate'` overflow mode: behaves like a static glyph,
16
+ * `aria-hidden="true"`.
17
+ * - In `'menu'` overflow mode: an interactive cell with
18
+ * `aria-haspopup="true"`. Consumers wire a `KjDropdownMenu` to the host
19
+ * to expose the hidden crumbs as menu items.
20
+ *
21
+ * Visible only when there are hidden crumbs (`ctx.hiddenIndices().length > 0`).
22
+ * The host wrapper component conditionally renders the directive based on
23
+ * this signal.
24
+ *
25
+ * @example
26
+ * ```html
27
+ * <li kjBreadcrumbItem><span kjBreadcrumbEllipsis>…</span></li>
28
+ * ```
29
+ *
30
+ * @doc-category Core/Navigation
31
+ * @doc
32
+ * @doc-name breadcrumb
33
+ */
34
+ @Directive({
35
+ selector: '[kjBreadcrumbEllipsis]',
36
+ standalone: true,
37
+ hostDirectives: [KjFocusRing],
38
+ host: {
39
+ '[attr.aria-hidden]': 'isAriaHidden() ? "true" : null',
40
+ '[attr.aria-label]': 'computedAriaLabel()',
41
+ '[attr.aria-haspopup]': 'isMenu() ? "true" : null',
42
+ '[attr.data-overflow]': 'ctx.overflow()',
43
+ '[attr.data-hidden-count]': 'hiddenCount()',
44
+ },
45
+ })
46
+ export class KjBreadcrumbEllipsis {
47
+ /** @internal */
48
+ readonly ctx = inject(KJ_BREADCRUMB);
49
+ private readonly config = inject(KJ_BREADCRUMB_CONFIG);
50
+
51
+ /**
52
+ * Mirrors a disabled bundle (currently advisory — the ellipsis menu
53
+ * trigger composes `KjDropdownMenu` separately when wired by the
54
+ * consumer).
55
+ */
56
+ readonly kjDisabled = input<boolean, unknown>(false, { transform: booleanAttribute });
57
+
58
+ /** Number of hidden crumbs the ellipsis represents. */
59
+ readonly hiddenCount = computed(() => this.ctx.hiddenIndices().length);
60
+
61
+ /** Whether the ellipsis is in menu (interactive) mode. */
62
+ readonly isMenu = computed(() => this.ctx.overflow() === 'menu');
63
+
64
+ /** Whether the ellipsis is purely decorative (truncate mode). */
65
+ readonly isAriaHidden = computed(() => !this.isMenu());
66
+
67
+ /** `aria-label` value — null in truncate mode (the cell is decorative). */
68
+ readonly computedAriaLabel = computed(() =>
69
+ this.isMenu() ? this.config.ellipsisLabel(this.hiddenCount()) : null,
70
+ );
71
+ }
@@ -0,0 +1,41 @@
1
+ import { Directive, OnDestroy, inject } from '@angular/core';
2
+ import { KJ_BREADCRUMB, KjBreadcrumbItemContext } from './breadcrumb.context';
3
+
4
+ /**
5
+ * A single crumb cell. Registers itself with the parent breadcrumb on
6
+ * construction (capturing its index) and exposes a `current` signal derived
7
+ * from "am I last + no explicit current cell?".
8
+ *
9
+ * Selector restricted to `<li>` to keep the list semantics clean.
10
+ *
11
+ * @example
12
+ * ```html
13
+ * <li kjBreadcrumbItem>…</li>
14
+ * ```
15
+ *
16
+ * @doc-category Core/Navigation
17
+ * @doc
18
+ * @doc-name breadcrumb
19
+ */
20
+ @Directive({
21
+ selector: '[kjBreadcrumbItem]',
22
+ standalone: true,
23
+ host: {
24
+ '[attr.data-hidden]': 'context.hidden() ? "" : null',
25
+ '[attr.aria-current]': 'context.current() ? "page" : null',
26
+ },
27
+ })
28
+ export class KjBreadcrumbItem implements OnDestroy {
29
+ private readonly root = inject(KJ_BREADCRUMB);
30
+
31
+ /** Public context (index, current, hidden) for this item. */
32
+ readonly context: KjBreadcrumbItemContext;
33
+
34
+ constructor() {
35
+ this.context = this.root.registerItem();
36
+ }
37
+
38
+ ngOnDestroy(): void {
39
+ this.root.unregisterItem(this.context);
40
+ }
41
+ }
@@ -0,0 +1,44 @@
1
+ import { Directive, inject } from '@angular/core';
2
+ import { KjLink } from '../link/link';
3
+ import { KJ_BREADCRUMB } from './breadcrumb.context';
4
+
5
+ /**
6
+ * Per-crumb anchor. Composes `KjLink` via `hostDirectives` so the per-crumb
7
+ * `<a>` inherits external-link `rel` plumbing, focus-ring composition, and
8
+ * disabled-link enforcement.
9
+ *
10
+ * The directive deliberately does **not** forward `KjLink`'s own inputs onto
11
+ * its own selector — the components-package wrapper (`<kj-breadcrumb-link>`)
12
+ * is the authoring surface for those, and consumers driving the directive
13
+ * directly can apply `kjLink` inputs on the same element (since `KjLink` is
14
+ * composed via `hostDirectives`, the inputs land on it through the host).
15
+ *
16
+ * The wrapper applies breadcrumb defaults: `muted` variant, `sm` size,
17
+ * `hover` underline.
18
+ *
19
+ * @example
20
+ * ```html
21
+ * <a kjBreadcrumbLink href="/library">Library</a>
22
+ * ```
23
+ *
24
+ * @doc-category Core/Navigation
25
+ * @doc
26
+ * @doc-name breadcrumb
27
+ */
28
+ @Directive({
29
+ selector: 'a[kjBreadcrumbLink], [kjBreadcrumbLink]',
30
+ standalone: true,
31
+ hostDirectives: [
32
+ {
33
+ directive: KjLink,
34
+ inputs: ['kjUnderline', 'kjExternal', 'kjDisabled'],
35
+ },
36
+ ],
37
+ host: {
38
+ '[attr.data-breadcrumb-link]': '""',
39
+ },
40
+ })
41
+ export class KjBreadcrumbLink {
42
+ /** @internal */
43
+ readonly ctx = inject(KJ_BREADCRUMB);
44
+ }
@@ -0,0 +1,42 @@
1
+ import { Directive, inject, input } from '@angular/core';
2
+ import { KJ_BREADCRUMB } from './breadcrumb.context';
3
+
4
+ /**
5
+ * The breadcrumb's ordered list. Selector restricted to `<ol>` to enforce
6
+ * ordered-list semantics (a `<ul>` will not match).
7
+ *
8
+ * Reads the parent's `hasExplicitSeparators` and `overflow` signals to
9
+ * reflect data attributes that key the CSS layer:
10
+ * - `data-explicit-separators=""` suppresses the auto pseudo-element.
11
+ * - `data-overflow="truncate|menu|none"` mirrors the root's overflow mode.
12
+ * - `data-wrap="wrap|no-wrap|truncate"` reflects this directive's wrap input.
13
+ *
14
+ * @example
15
+ * ```html
16
+ * <ol kjBreadcrumbList>…</ol>
17
+ * ```
18
+ *
19
+ * @doc-category Core/Navigation
20
+ * @doc
21
+ * @doc-name breadcrumb
22
+ */
23
+ @Directive({
24
+ selector: '[kjBreadcrumbList]',
25
+ standalone: true,
26
+ host: {
27
+ '[attr.data-explicit-separators]': 'ctx.hasExplicitSeparators() ? "" : null',
28
+ '[attr.data-overflow]': 'ctx.overflow()',
29
+ '[attr.data-wrap]': 'kjWrap()',
30
+ },
31
+ })
32
+ export class KjBreadcrumbList {
33
+ /** @internal */
34
+ readonly ctx = inject(KJ_BREADCRUMB);
35
+
36
+ /**
37
+ * Wrapping policy. `'no-wrap'` keeps the row single-line (the truncation
38
+ * does the long-path work); `'wrap'` allows the row to break across
39
+ * lines; `'truncate'` reserved for future ellipsis-by-CSS support.
40
+ */
41
+ readonly kjWrap = input<'wrap' | 'no-wrap' | 'truncate'>('no-wrap');
42
+ }
@@ -0,0 +1,45 @@
1
+ import { Directive, OnDestroy, inject } from '@angular/core';
2
+ import { KJ_BREADCRUMB } from './breadcrumb.context';
3
+
4
+ /**
5
+ * Optional explicit separator cell. Used when a CSS pseudo-element will not
6
+ * do — typically for an icon (SVG) separator that needs `currentColor`,
7
+ * `width`, and `height` plumbing the pseudo-element cannot deliver.
8
+ *
9
+ * Registers with the parent so the auto separator (CSS `::before`) is
10
+ * suppressed via the `data-explicit-separators=""` attribute on the list.
11
+ *
12
+ * Selector restricted to `<li>` so the list semantics stay clean
13
+ * (every direct child of `<ol>` must be `<li>`); the directive sets
14
+ * `role="presentation"` and `aria-hidden="true"` so AT does not announce
15
+ * the separator as a list item.
16
+ *
17
+ * @example
18
+ * ```html
19
+ * <li kjBreadcrumbSeparator><svg>…chevron…</svg></li>
20
+ * ```
21
+ *
22
+ * @doc-category Core/Navigation
23
+ * @doc
24
+ * @doc-name breadcrumb
25
+ */
26
+ @Directive({
27
+ selector: '[kjBreadcrumbSeparator]',
28
+ standalone: true,
29
+ host: {
30
+ 'role': 'presentation',
31
+ '[attr.aria-hidden]': '"true"',
32
+ '[attr.data-breadcrumb-separator]': '""',
33
+ },
34
+ })
35
+ export class KjBreadcrumbSeparator implements OnDestroy {
36
+ private readonly root = inject(KJ_BREADCRUMB);
37
+
38
+ constructor() {
39
+ this.root.registerSeparator();
40
+ }
41
+
42
+ ngOnDestroy(): void {
43
+ this.root.unregisterSeparator();
44
+ }
45
+ }
@@ -0,0 +1,45 @@
1
+ import { InjectionToken, Signal } from '@angular/core';
2
+
3
+ /** Public-facing token interface representing a registered crumb item. */
4
+ export interface KjBreadcrumbItemContext {
5
+ /** Index of the item among registered items (0-based, document order). */
6
+ readonly index: Signal<number>;
7
+ /** Whether this item is currently the "current page" cell. */
8
+ readonly current: Signal<boolean>;
9
+ /** Whether this item is hidden by truncation. */
10
+ readonly hidden: Signal<boolean>;
11
+ }
12
+
13
+ /** Public-facing token interface representing the root breadcrumb. */
14
+ export interface KjBreadcrumbContext {
15
+ /** Configured separator glyph (or `undefined` to use the CSS default). */
16
+ readonly separator: Signal<string | undefined>;
17
+ /** `kjMaxItems` — `0` or `Infinity` disables truncation. */
18
+ readonly maxItems: Signal<number>;
19
+ /** Active overflow mode. */
20
+ readonly overflow: Signal<'truncate' | 'menu' | 'none'>;
21
+ /** Read-only count of registered items. */
22
+ readonly itemCount: Signal<number>;
23
+ /** Read-only count of registered explicit current cells. */
24
+ readonly currentCount: Signal<number>;
25
+ /** Indices that should render visibly. */
26
+ readonly visibleIndices: Signal<readonly number[]>;
27
+ /** Indices that should be hidden by truncation. */
28
+ readonly hiddenIndices: Signal<readonly number[]>;
29
+ /** Whether the consumer has rendered explicit `<li kjBreadcrumbSeparator>` cells. */
30
+ readonly hasExplicitSeparators: Signal<boolean>;
31
+
32
+ /** Register a freshly-created item directive; returns its assigned index signal. */
33
+ registerItem(): KjBreadcrumbItemContext;
34
+ /** Unregister an item directive (called from `ngOnDestroy`). */
35
+ unregisterItem(item: KjBreadcrumbItemContext): void;
36
+ /** Register / unregister an explicit current cell. */
37
+ registerCurrent(): void;
38
+ unregisterCurrent(): void;
39
+ /** Register / unregister an explicit separator cell. */
40
+ registerSeparator(): void;
41
+ unregisterSeparator(): void;
42
+ }
43
+
44
+ /** Injection token for the root `KjBreadcrumb` directive context. */
45
+ export const KJ_BREADCRUMB = new InjectionToken<KjBreadcrumbContext>('KjBreadcrumb');