@kouji-ui/core 0.1.1 → 0.1.3

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 (535) hide show
  1. package/fesm2022/kouji-ui-core.mjs +26789 -0
  2. package/fesm2022/kouji-ui-core.mjs.map +1 -0
  3. package/package.json +15 -7
  4. package/types/kouji-ui-core.d.ts +13545 -0
  5. package/.turbo/turbo-build.log +0 -30
  6. package/CHANGELOG.md +0 -190
  7. package/ng-package.json +0 -11
  8. package/src/a11y/.gitkeep +0 -0
  9. package/src/a11y/aria-describedby.spec.ts +0 -55
  10. package/src/a11y/aria-describedby.ts +0 -37
  11. package/src/a11y/aria-labelledby.spec.ts +0 -55
  12. package/src/a11y/aria-labelledby.ts +0 -38
  13. package/src/a11y/focus-trap.spec.ts +0 -86
  14. package/src/a11y/focus-trap.ts +0 -72
  15. package/src/a11y/index.ts +0 -10
  16. package/src/a11y/live-region.spec.ts +0 -58
  17. package/src/a11y/live-region.ts +0 -50
  18. package/src/a11y/roving-tabindex.spec.ts +0 -201
  19. package/src/a11y/roving-tabindex.ts +0 -153
  20. package/src/a11y/visually-hidden.spec.ts +0 -34
  21. package/src/a11y/visually-hidden.ts +0 -26
  22. package/src/accordion/accordion.context.ts +0 -44
  23. package/src/accordion/accordion.spec.ts +0 -242
  24. package/src/accordion/accordion.ts +0 -401
  25. package/src/accordion/index.ts +0 -8
  26. package/src/alert/alert.context.ts +0 -28
  27. package/src/alert/alert.spec.ts +0 -217
  28. package/src/alert/alert.ts +0 -417
  29. package/src/alert/config.ts +0 -46
  30. package/src/alert/index.ts +0 -19
  31. package/src/avatar/avatar-group.context.ts +0 -45
  32. package/src/avatar/avatar-group.spec.ts +0 -358
  33. package/src/avatar/avatar-group.ts +0 -259
  34. package/src/avatar/avatar.spec.ts +0 -18
  35. package/src/avatar/avatar.ts +0 -39
  36. package/src/avatar/index.ts +0 -11
  37. package/src/badge/badge.spec.ts +0 -28
  38. package/src/badge/badge.ts +0 -35
  39. package/src/badge/index.ts +0 -1
  40. package/src/breadcrumb/breadcrumb-current.ts +0 -38
  41. package/src/breadcrumb/breadcrumb-ellipsis.ts +0 -71
  42. package/src/breadcrumb/breadcrumb-item.ts +0 -41
  43. package/src/breadcrumb/breadcrumb-link.ts +0 -44
  44. package/src/breadcrumb/breadcrumb-list.ts +0 -42
  45. package/src/breadcrumb/breadcrumb-separator.ts +0 -45
  46. package/src/breadcrumb/breadcrumb.context.ts +0 -45
  47. package/src/breadcrumb/breadcrumb.spec.ts +0 -354
  48. package/src/breadcrumb/breadcrumb.ts +0 -239
  49. package/src/breadcrumb/config.ts +0 -84
  50. package/src/breadcrumb/index.ts +0 -18
  51. package/src/button/_examples/button.example.ts +0 -71
  52. package/src/button/_examples/button.finance.example.ts +0 -83
  53. package/src/button/_examples/button.retro.example.ts +0 -91
  54. package/src/button/_examples/button.sizes.example.ts +0 -60
  55. package/src/button/_examples/index.ts +0 -6
  56. package/src/button/button.spec.ts +0 -163
  57. package/src/button/button.ts +0 -142
  58. package/src/button/config.spec.ts +0 -33
  59. package/src/button/config.ts +0 -45
  60. package/src/button/index.ts +0 -2
  61. package/src/button-group/button-group.context.ts +0 -28
  62. package/src/button-group/button-group.spec.ts +0 -99
  63. package/src/button-group/button-group.ts +0 -99
  64. package/src/button-group/index.ts +0 -2
  65. package/src/calendar/calendar-day.ts +0 -102
  66. package/src/calendar/calendar-grid.ts +0 -90
  67. package/src/calendar/calendar-header.ts +0 -65
  68. package/src/calendar/calendar.context.ts +0 -53
  69. package/src/calendar/calendar.spec.ts +0 -225
  70. package/src/calendar/calendar.ts +0 -233
  71. package/src/calendar/date-utils.ts +0 -225
  72. package/src/calendar/index.ts +0 -28
  73. package/src/carousel/carousel.context.ts +0 -81
  74. package/src/carousel/carousel.spec.ts +0 -337
  75. package/src/carousel/carousel.ts +0 -919
  76. package/src/carousel/index.ts +0 -22
  77. package/src/cascade-select/cascade-select-option.ts +0 -205
  78. package/src/cascade-select/cascade-select-panel.ts +0 -106
  79. package/src/cascade-select/cascade-select-root.ts +0 -265
  80. package/src/cascade-select/cascade-select-sub-panel.ts +0 -168
  81. package/src/cascade-select/cascade-select-trigger.ts +0 -44
  82. package/src/cascade-select/cascade-select.context.ts +0 -71
  83. package/src/cascade-select/cascade-select.spec.ts +0 -241
  84. package/src/cascade-select/cascade-select.ts +0 -5
  85. package/src/cascade-select/index.ts +0 -11
  86. package/src/chart/chart.spec.ts +0 -27
  87. package/src/chart/chart.ts +0 -52
  88. package/src/chart/index.ts +0 -1
  89. package/src/chat/chat-avatar.ts +0 -31
  90. package/src/chat/chat-bubble.ts +0 -49
  91. package/src/chat/chat-footer.ts +0 -67
  92. package/src/chat/chat-header.ts +0 -41
  93. package/src/chat/chat-log.ts +0 -43
  94. package/src/chat/chat.context.ts +0 -64
  95. package/src/chat/chat.spec.ts +0 -341
  96. package/src/chat/chat.ts +0 -191
  97. package/src/chat/config.ts +0 -53
  98. package/src/chat/index.ts +0 -21
  99. package/src/checkbox/checkbox.spec.ts +0 -35
  100. package/src/checkbox/checkbox.ts +0 -89
  101. package/src/checkbox/index.ts +0 -1
  102. package/src/color-picker/color-picker.context.ts +0 -74
  103. package/src/color-picker/color-picker.spec.ts +0 -241
  104. package/src/color-picker/color-picker.ts +0 -698
  105. package/src/color-picker/color-picker.utils.ts +0 -140
  106. package/src/color-picker/index.ts +0 -28
  107. package/src/combobox/combobox-input.ts +0 -143
  108. package/src/combobox/combobox-listbox.ts +0 -49
  109. package/src/combobox/combobox-option.ts +0 -43
  110. package/src/combobox/combobox-root.ts +0 -281
  111. package/src/combobox/combobox.spec.ts +0 -75
  112. package/src/combobox/combobox.ts +0 -4
  113. package/src/combobox/index.ts +0 -4
  114. package/src/command-palette/command-empty.ts +0 -36
  115. package/src/command-palette/command-group.ts +0 -21
  116. package/src/command-palette/command-input.ts +0 -70
  117. package/src/command-palette/command-item.ts +0 -60
  118. package/src/command-palette/command-list.ts +0 -25
  119. package/src/command-palette/command-palette-dialog.ts +0 -74
  120. package/src/command-palette/command-palette-trigger.ts +0 -64
  121. package/src/command-palette/command-palette.filters.ts +0 -53
  122. package/src/command-palette/command-palette.spec.ts +0 -349
  123. package/src/command-palette/command-palette.ts +0 -204
  124. package/src/command-palette/command-separator.ts +0 -18
  125. package/src/command-palette/index.ts +0 -15
  126. package/src/confirm-popup/confirm-popup-action.ts +0 -39
  127. package/src/confirm-popup/confirm-popup-cancel.ts +0 -38
  128. package/src/confirm-popup/confirm-popup-content.ts +0 -113
  129. package/src/confirm-popup/confirm-popup-message.ts +0 -36
  130. package/src/confirm-popup/confirm-popup-trigger.ts +0 -31
  131. package/src/confirm-popup/confirm-popup.context.ts +0 -41
  132. package/src/confirm-popup/confirm-popup.spec.ts +0 -337
  133. package/src/confirm-popup/confirm-popup.ts +0 -109
  134. package/src/confirm-popup/index.ts +0 -12
  135. package/src/date-picker/date-picker-calendar.ts +0 -65
  136. package/src/date-picker/date-picker-trigger.ts +0 -215
  137. package/src/date-picker/date-picker.context.ts +0 -50
  138. package/src/date-picker/date-picker.spec.ts +0 -117
  139. package/src/date-picker/date-picker.ts +0 -127
  140. package/src/date-picker/index.ts +0 -7
  141. package/src/dialog/_examples/dialog.confirm.example.ts +0 -145
  142. package/src/dialog/_examples/dialog.example.ts +0 -106
  143. package/src/dialog/_examples/dialog.finance.example.ts +0 -121
  144. package/src/dialog/_examples/dialog.retro.example.ts +0 -126
  145. package/src/dialog/_examples/index.ts +0 -6
  146. package/src/dialog/dialog.ref.ts +0 -42
  147. package/src/dialog/dialog.service.ts +0 -66
  148. package/src/dialog/dialog.spec.ts +0 -37
  149. package/src/dialog/dialog.ts +0 -26
  150. package/src/dialog/index.ts +0 -3
  151. package/src/divider/divider.spec.ts +0 -223
  152. package/src/divider/divider.ts +0 -137
  153. package/src/divider/index.ts +0 -5
  154. package/src/drawer/drawer.ref.ts +0 -63
  155. package/src/drawer/drawer.service.ts +0 -106
  156. package/src/drawer/drawer.spec.ts +0 -117
  157. package/src/drawer/drawer.ts +0 -122
  158. package/src/drawer/index.ts +0 -10
  159. package/src/dropdown-menu/dropdown-menu-content.ts +0 -258
  160. package/src/dropdown-menu/dropdown-menu-group.ts +0 -31
  161. package/src/dropdown-menu/dropdown-menu-item.ts +0 -51
  162. package/src/dropdown-menu/dropdown-menu-label.ts +0 -41
  163. package/src/dropdown-menu/dropdown-menu-separator.ts +0 -27
  164. package/src/dropdown-menu/dropdown-menu-trigger.ts +0 -140
  165. package/src/dropdown-menu/dropdown-menu.spec.ts +0 -265
  166. package/src/dropdown-menu/dropdown-menu.ts +0 -60
  167. package/src/dropdown-menu/index.ts +0 -15
  168. package/src/example-components.ts +0 -42
  169. package/src/field/field-error.ts +0 -49
  170. package/src/field/field-group.ts +0 -39
  171. package/src/field/field-help.ts +0 -47
  172. package/src/field/field-label.ts +0 -30
  173. package/src/field/field.context.ts +0 -28
  174. package/src/field/field.spec.ts +0 -179
  175. package/src/field/field.ts +0 -121
  176. package/src/field/index.ts +0 -6
  177. package/src/file-upload/file-upload.context.ts +0 -89
  178. package/src/file-upload/file-upload.spec.ts +0 -290
  179. package/src/file-upload/file-upload.ts +0 -639
  180. package/src/file-upload/file-upload.types.ts +0 -59
  181. package/src/file-upload/index.ts +0 -23
  182. package/src/form/form-error-summary.ts +0 -87
  183. package/src/form/form-field.context.ts +0 -3
  184. package/src/form/form-field.spec.ts +0 -25
  185. package/src/form/form-field.ts +0 -52
  186. package/src/form/form.context.ts +0 -53
  187. package/src/form/form.spec.ts +0 -162
  188. package/src/form/form.ts +0 -326
  189. package/src/form/index.ts +0 -11
  190. package/src/icon/E2E.md +0 -14
  191. package/src/icon/icon.directive.spec.ts +0 -198
  192. package/src/icon/icon.directive.ts +0 -113
  193. package/src/icon/icon.mode.spec.ts +0 -29
  194. package/src/icon/icon.mode.ts +0 -23
  195. package/src/icon/icon.providers.spec.ts +0 -63
  196. package/src/icon/icon.providers.ts +0 -47
  197. package/src/icon/icon.resolver.spec.ts +0 -96
  198. package/src/icon/icon.resolver.ts +0 -49
  199. package/src/icon/icon.tokens.ts +0 -88
  200. package/src/icon/icon.types.ts +0 -48
  201. package/src/icon/index.ts +0 -21
  202. package/src/input/index.ts +0 -1
  203. package/src/input/input.spec.ts +0 -43
  204. package/src/input/input.ts +0 -89
  205. package/src/input-group/index.ts +0 -3
  206. package/src/input-group/input-group-addon.ts +0 -92
  207. package/src/input-group/input-group.context.ts +0 -27
  208. package/src/input-group/input-group.spec.ts +0 -186
  209. package/src/input-group/input-group.ts +0 -136
  210. package/src/input-mask/index.ts +0 -11
  211. package/src/input-mask/input-mask.compile.ts +0 -69
  212. package/src/input-mask/input-mask.engine.ts +0 -376
  213. package/src/input-mask/input-mask.presets.ts +0 -24
  214. package/src/input-mask/input-mask.spec.ts +0 -304
  215. package/src/input-mask/input-mask.tokens.ts +0 -49
  216. package/src/input-mask/input-mask.ts +0 -280
  217. package/src/input-otp/index.ts +0 -2
  218. package/src/input-otp/input-otp.context.ts +0 -41
  219. package/src/input-otp/input-otp.spec.ts +0 -308
  220. package/src/input-otp/input-otp.ts +0 -470
  221. package/src/kbd/index.ts +0 -1
  222. package/src/kbd/kbd.spec.ts +0 -127
  223. package/src/kbd/kbd.ts +0 -132
  224. package/src/link/config.ts +0 -44
  225. package/src/link/index.ts +0 -2
  226. package/src/link/link.spec.ts +0 -246
  227. package/src/link/link.ts +0 -226
  228. package/src/list/index.ts +0 -11
  229. package/src/list/list.spec.ts +0 -237
  230. package/src/list/list.ts +0 -277
  231. package/src/menubar/index.ts +0 -7
  232. package/src/menubar/menubar-item.ts +0 -204
  233. package/src/menubar/menubar.context.ts +0 -43
  234. package/src/menubar/menubar.spec.ts +0 -433
  235. package/src/menubar/menubar.ts +0 -309
  236. package/src/number-input/index.ts +0 -4
  237. package/src/number-input/number-input-group.ts +0 -64
  238. package/src/number-input/number-input.context.ts +0 -31
  239. package/src/number-input/number-input.format.ts +0 -148
  240. package/src/number-input/number-input.spec.ts +0 -170
  241. package/src/number-input/number-input.ts +0 -457
  242. package/src/number-input/number-stepper.ts +0 -193
  243. package/src/overlay-badge/index.ts +0 -7
  244. package/src/overlay-badge/overlay-badge-content.ts +0 -73
  245. package/src/overlay-badge/overlay-badge.context.ts +0 -37
  246. package/src/overlay-badge/overlay-badge.spec.ts +0 -220
  247. package/src/overlay-badge/overlay-badge.ts +0 -128
  248. package/src/pagination/config.ts +0 -82
  249. package/src/pagination/index.ts +0 -19
  250. package/src/pagination/page-tokens.ts +0 -78
  251. package/src/pagination/pagination-ellipsis.ts +0 -69
  252. package/src/pagination/pagination-first.ts +0 -84
  253. package/src/pagination/pagination-info.ts +0 -70
  254. package/src/pagination/pagination-item.ts +0 -81
  255. package/src/pagination/pagination-last.ts +0 -85
  256. package/src/pagination/pagination-next.ts +0 -86
  257. package/src/pagination/pagination-previous.ts +0 -90
  258. package/src/pagination/pagination.context.ts +0 -52
  259. package/src/pagination/pagination.spec.ts +0 -388
  260. package/src/pagination/pagination.ts +0 -288
  261. package/src/password-input/index.ts +0 -15
  262. package/src/password-input/password-input.context.ts +0 -65
  263. package/src/password-input/password-input.scorer.ts +0 -34
  264. package/src/password-input/password-input.spec.ts +0 -274
  265. package/src/password-input/password-input.ts +0 -488
  266. package/src/popover/_examples/index.ts +0 -5
  267. package/src/popover/_examples/popover.example.ts +0 -92
  268. package/src/popover/_examples/popover.finance.example.ts +0 -106
  269. package/src/popover/_examples/popover.retro.example.ts +0 -103
  270. package/src/popover/index.ts +0 -5
  271. package/src/popover/popover-arrow.ts +0 -30
  272. package/src/popover/popover-close.ts +0 -36
  273. package/src/popover/popover-content.ts +0 -41
  274. package/src/popover/popover-title.ts +0 -39
  275. package/src/popover/popover-trigger.ts +0 -40
  276. package/src/popover/popover.spec.ts +0 -59
  277. package/src/popover/popover.ts +0 -5
  278. package/src/presets/bind-presets.spec.ts +0 -50
  279. package/src/presets/bind-presets.ts +0 -43
  280. package/src/presets/index.ts +0 -3
  281. package/src/presets/size.spec.ts +0 -67
  282. package/src/presets/size.ts +0 -59
  283. package/src/presets/variant.spec.ts +0 -72
  284. package/src/presets/variant.ts +0 -62
  285. package/src/primitives/.gitkeep +0 -0
  286. package/src/primitives/directionality/directionality.spec.ts +0 -112
  287. package/src/primitives/directionality/directionality.ts +0 -89
  288. package/src/primitives/directionality/index.ts +0 -1
  289. package/src/primitives/forms/form-control.spec.ts +0 -67
  290. package/src/primitives/forms/form-control.ts +0 -94
  291. package/src/primitives/forms/index.ts +0 -1
  292. package/src/primitives/index.ts +0 -6
  293. package/src/primitives/interaction/disabled.spec.ts +0 -47
  294. package/src/primitives/interaction/disabled.ts +0 -31
  295. package/src/primitives/interaction/focus-ring.spec.ts +0 -62
  296. package/src/primitives/interaction/focus-ring.ts +0 -59
  297. package/src/primitives/interaction/index.ts +0 -2
  298. package/src/primitives/list/filterable-list.spec.ts +0 -114
  299. package/src/primitives/list/filterable-list.ts +0 -126
  300. package/src/primitives/list/group.spec.ts +0 -99
  301. package/src/primitives/list/group.ts +0 -139
  302. package/src/primitives/list/index.ts +0 -8
  303. package/src/primitives/list/inject-helpers.ts +0 -8
  304. package/src/primitives/list/item.spec.ts +0 -173
  305. package/src/primitives/list/item.ts +0 -222
  306. package/src/primitives/list/navigator.spec.ts +0 -286
  307. package/src/primitives/list/navigator.ts +0 -238
  308. package/src/primitives/list/selection.spec.ts +0 -214
  309. package/src/primitives/list/selection.ts +0 -339
  310. package/src/primitives/list/tokens.ts +0 -106
  311. package/src/primitives/list/type-ahead.spec.ts +0 -58
  312. package/src/primitives/list/type-ahead.ts +0 -46
  313. package/src/primitives/overlay/backdrop.spec.ts +0 -54
  314. package/src/primitives/overlay/backdrop.ts +0 -31
  315. package/src/primitives/overlay/builder.spec.ts +0 -38
  316. package/src/primitives/overlay/builder.ts +0 -151
  317. package/src/primitives/overlay/container.ts +0 -42
  318. package/src/primitives/overlay/context.ts +0 -14
  319. package/src/primitives/overlay/controller.spec.ts +0 -86
  320. package/src/primitives/overlay/controller.ts +0 -190
  321. package/src/primitives/overlay/id.spec.ts +0 -24
  322. package/src/primitives/overlay/id.ts +0 -17
  323. package/src/primitives/overlay/index.ts +0 -18
  324. package/src/primitives/overlay/overlay.css +0 -42
  325. package/src/primitives/overlay/panel.spec.ts +0 -52
  326. package/src/primitives/overlay/panel.ts +0 -102
  327. package/src/primitives/overlay/stack.spec.ts +0 -55
  328. package/src/primitives/overlay/stack.ts +0 -113
  329. package/src/primitives/overlay/strategies/backdrop/blurred.spec.ts +0 -11
  330. package/src/primitives/overlay/strategies/backdrop/blurred.ts +0 -5
  331. package/src/primitives/overlay/strategies/backdrop/none.spec.ts +0 -10
  332. package/src/primitives/overlay/strategies/backdrop/none.ts +0 -9
  333. package/src/primitives/overlay/strategies/backdrop/solid.spec.ts +0 -18
  334. package/src/primitives/overlay/strategies/backdrop/solid.ts +0 -23
  335. package/src/primitives/overlay/strategies/focus-trap/inert-based.spec.ts +0 -28
  336. package/src/primitives/overlay/strategies/focus-trap/inert-based.ts +0 -38
  337. package/src/primitives/overlay/strategies/focus-trap/no-trap.spec.ts +0 -9
  338. package/src/primitives/overlay/strategies/focus-trap/no-trap.ts +0 -8
  339. package/src/primitives/overlay/strategies/focus-trap/tab-cycle.spec.ts +0 -49
  340. package/src/primitives/overlay/strategies/focus-trap/tab-cycle.ts +0 -85
  341. package/src/primitives/overlay/strategies/index.ts +0 -34
  342. package/src/primitives/overlay/strategies/live-announcer/_announce.ts +0 -35
  343. package/src/primitives/overlay/strategies/live-announcer/assertive.spec.ts +0 -21
  344. package/src/primitives/overlay/strategies/live-announcer/assertive.ts +0 -11
  345. package/src/primitives/overlay/strategies/live-announcer/polite.spec.ts +0 -21
  346. package/src/primitives/overlay/strategies/live-announcer/polite.ts +0 -11
  347. package/src/primitives/overlay/strategies/live-announcer/silent.spec.ts +0 -12
  348. package/src/primitives/overlay/strategies/live-announcer/silent.ts +0 -5
  349. package/src/primitives/overlay/strategies/mount/body-portal.spec.ts +0 -40
  350. package/src/primitives/overlay/strategies/mount/body-portal.ts +0 -91
  351. package/src/primitives/overlay/strategies/mount/in-container.spec.ts +0 -43
  352. package/src/primitives/overlay/strategies/mount/in-container.ts +0 -39
  353. package/src/primitives/overlay/strategies/mount/in-place.spec.ts +0 -40
  354. package/src/primitives/overlay/strategies/mount/in-place.ts +0 -20
  355. package/src/primitives/overlay/strategies/position/anchored-to.spec.ts +0 -56
  356. package/src/primitives/overlay/strategies/position/anchored-to.ts +0 -248
  357. package/src/primitives/overlay/strategies/position/corner.spec.ts +0 -36
  358. package/src/primitives/overlay/strategies/position/corner.ts +0 -33
  359. package/src/primitives/overlay/strategies/position/edge-sheet.spec.ts +0 -32
  360. package/src/primitives/overlay/strategies/position/edge-sheet.ts +0 -36
  361. package/src/primitives/overlay/strategies/position/in-place-sibling.spec.ts +0 -25
  362. package/src/primitives/overlay/strategies/position/in-place-sibling.ts +0 -13
  363. package/src/primitives/overlay/strategies/position/point-at.spec.ts +0 -40
  364. package/src/primitives/overlay/strategies/position/point-at.ts +0 -34
  365. package/src/primitives/overlay/strategies/position/viewport-centered.spec.ts +0 -31
  366. package/src/primitives/overlay/strategies/position/viewport-centered.ts +0 -31
  367. package/src/primitives/overlay/strategies/scroll-lock/css-clip.spec.ts +0 -15
  368. package/src/primitives/overlay/strategies/scroll-lock/css-clip.ts +0 -39
  369. package/src/primitives/overlay/strategies/scroll-lock/html-overflow.spec.ts +0 -21
  370. package/src/primitives/overlay/strategies/scroll-lock/html-overflow.ts +0 -44
  371. package/src/primitives/overlay/strategies/scroll-lock/none.spec.ts +0 -9
  372. package/src/primitives/overlay/strategies/scroll-lock/none.ts +0 -5
  373. package/src/primitives/overlay/strategies/trigger-event/on-click.spec.ts +0 -32
  374. package/src/primitives/overlay/strategies/trigger-event/on-click.ts +0 -28
  375. package/src/primitives/overlay/strategies/trigger-event/on-context-menu.spec.ts +0 -45
  376. package/src/primitives/overlay/strategies/trigger-event/on-context-menu.ts +0 -70
  377. package/src/primitives/overlay/strategies/trigger-event/on-focus-or-input.spec.ts +0 -35
  378. package/src/primitives/overlay/strategies/trigger-event/on-focus-or-input.ts +0 -34
  379. package/src/primitives/overlay/strategies/trigger-event/on-focus.spec.ts +0 -64
  380. package/src/primitives/overlay/strategies/trigger-event/on-focus.ts +0 -37
  381. package/src/primitives/overlay/strategies/trigger-event/on-hotkey.spec.ts +0 -37
  382. package/src/primitives/overlay/strategies/trigger-event/on-hotkey.ts +0 -59
  383. package/src/primitives/overlay/strategies/trigger-event/on-hover.spec.ts +0 -34
  384. package/src/primitives/overlay/strategies/trigger-event/on-hover.ts +0 -86
  385. package/src/primitives/overlay/strategies/trigger-event/programmatic.spec.ts +0 -16
  386. package/src/primitives/overlay/strategies/trigger-event/programmatic.ts +0 -12
  387. package/src/primitives/overlay/tokens.ts +0 -54
  388. package/src/primitives/overlay/trigger.spec.ts +0 -103
  389. package/src/primitives/overlay/trigger.ts +0 -75
  390. package/src/primitives/overlay/types.ts +0 -24
  391. package/src/primitives/overlay/wrapper.ts +0 -50
  392. package/src/primitives/signals/deep-signal.ts +0 -109
  393. package/src/primitives/signals/index.ts +0 -1
  394. package/src/progress-bar/config.ts +0 -48
  395. package/src/progress-bar/index.ts +0 -12
  396. package/src/progress-bar/progress-bar-fill.ts +0 -37
  397. package/src/progress-bar/progress-bar.context.ts +0 -34
  398. package/src/progress-bar/progress-bar.spec.ts +0 -423
  399. package/src/progress-bar/progress-bar.ts +0 -217
  400. package/src/public-api.ts +0 -84
  401. package/src/radio/index.ts +0 -2
  402. package/src/radio/radio.context.ts +0 -3
  403. package/src/radio/radio.spec.ts +0 -36
  404. package/src/radio/radio.ts +0 -66
  405. package/src/select/index.ts +0 -4
  406. package/src/select/select-content.ts +0 -69
  407. package/src/select/select-option.ts +0 -35
  408. package/src/select/select-root.ts +0 -129
  409. package/src/select/select-trigger.ts +0 -93
  410. package/src/select/select.spec.ts +0 -138
  411. package/src/select/select.ts +0 -4
  412. package/src/skeleton/index.ts +0 -5
  413. package/src/skeleton/skeleton.spec.ts +0 -115
  414. package/src/skeleton/skeleton.ts +0 -56
  415. package/src/slider/index.ts +0 -10
  416. package/src/slider/slider-range.ts +0 -49
  417. package/src/slider/slider-thumb.ts +0 -335
  418. package/src/slider/slider-track.ts +0 -70
  419. package/src/slider/slider.context.ts +0 -79
  420. package/src/slider/slider.geometry.ts +0 -73
  421. package/src/slider/slider.spec.ts +0 -216
  422. package/src/slider/slider.ts +0 -443
  423. package/src/speed-dial/index.ts +0 -10
  424. package/src/speed-dial/speed-dial-action.ts +0 -40
  425. package/src/speed-dial/speed-dial-actions.ts +0 -31
  426. package/src/speed-dial/speed-dial-trigger.ts +0 -55
  427. package/src/speed-dial/speed-dial.context.ts +0 -36
  428. package/src/speed-dial/speed-dial.spec.ts +0 -143
  429. package/src/speed-dial/speed-dial.ts +0 -127
  430. package/src/spinner/config.ts +0 -48
  431. package/src/spinner/index.ts +0 -8
  432. package/src/spinner/spinner.spec.ts +0 -262
  433. package/src/spinner/spinner.ts +0 -129
  434. package/src/stepper/index.ts +0 -15
  435. package/src/stepper/stepper.context.ts +0 -63
  436. package/src/stepper/stepper.spec.ts +0 -403
  437. package/src/stepper/stepper.ts +0 -544
  438. package/src/styles/docs-themes.css +0 -82
  439. package/src/styles.css +0 -17
  440. package/src/table/column-helpers.spec.ts +0 -74
  441. package/src/table/column-helpers.ts +0 -68
  442. package/src/table/filter-fns.ts +0 -230
  443. package/src/table/filter-models.spec.ts +0 -240
  444. package/src/table/filter-models.ts +0 -124
  445. package/src/table/filter-params.ts +0 -90
  446. package/src/table/grid-api-impl.ts +0 -321
  447. package/src/table/grid-api.spec.ts +0 -178
  448. package/src/table/grid-api.ts +0 -285
  449. package/src/table/index.ts +0 -73
  450. package/src/table/table-cell.spec.ts +0 -43
  451. package/src/table/table-cell.ts +0 -38
  452. package/src/table/table-filter-outlet.ts +0 -120
  453. package/src/table/table-header.spec.ts +0 -54
  454. package/src/table/table-header.ts +0 -63
  455. package/src/table/table-keyboard.spec.ts +0 -68
  456. package/src/table/table-keyboard.ts +0 -107
  457. package/src/table/table-resource.spec.ts +0 -37
  458. package/src/table/table-resource.ts +0 -36
  459. package/src/table/table-row.spec.ts +0 -54
  460. package/src/table/table-row.ts +0 -31
  461. package/src/table/table-storage.spec.ts +0 -67
  462. package/src/table/table-storage.ts +0 -76
  463. package/src/table/table.spec.ts +0 -172
  464. package/src/table/table.ts +0 -281
  465. package/src/table/table.types.ts +0 -83
  466. package/src/tabs/index.ts +0 -7
  467. package/src/tabs/tabs.context.ts +0 -32
  468. package/src/tabs/tabs.spec.ts +0 -352
  469. package/src/tabs/tabs.ts +0 -364
  470. package/src/tag/config.ts +0 -53
  471. package/src/tag/index.ts +0 -7
  472. package/src/tag/tag-list.ts +0 -76
  473. package/src/tag/tag-remove.ts +0 -61
  474. package/src/tag/tag.context.ts +0 -36
  475. package/src/tag/tag.spec.ts +0 -240
  476. package/src/tag/tag.ts +0 -203
  477. package/src/test-setup.ts +0 -5
  478. package/src/textarea/config.ts +0 -42
  479. package/src/textarea/index.ts +0 -8
  480. package/src/textarea/textarea.spec.ts +0 -176
  481. package/src/textarea/textarea.ts +0 -235
  482. package/src/time-picker/index.ts +0 -15
  483. package/src/time-picker/time-picker-meridiem.ts +0 -123
  484. package/src/time-picker/time-picker-segment.ts +0 -318
  485. package/src/time-picker/time-picker.context.ts +0 -38
  486. package/src/time-picker/time-picker.format.ts +0 -181
  487. package/src/time-picker/time-picker.spec.ts +0 -189
  488. package/src/time-picker/time-picker.ts +0 -274
  489. package/src/toast/_examples/index.ts +0 -5
  490. package/src/toast/_examples/toast.example.ts +0 -282
  491. package/src/toast/_examples/toast.finance.example.ts +0 -180
  492. package/src/toast/_examples/toast.retro.example.ts +0 -161
  493. package/src/toast/index.ts +0 -28
  494. package/src/toast/toast.ref.ts +0 -26
  495. package/src/toast/toast.service.ts +0 -339
  496. package/src/toast/toast.spec.ts +0 -247
  497. package/src/toast/toast.strategy.ts +0 -112
  498. package/src/toast/toast.ts +0 -463
  499. package/src/toast/toast.types.ts +0 -5
  500. package/src/toggle/index.ts +0 -1
  501. package/src/toggle/toggle.spec.ts +0 -24
  502. package/src/toggle/toggle.ts +0 -48
  503. package/src/tooltip/_examples/index.ts +0 -6
  504. package/src/tooltip/_examples/tooltip.example.ts +0 -82
  505. package/src/tooltip/_examples/tooltip.finance.example.ts +0 -97
  506. package/src/tooltip/_examples/tooltip.placements.example.ts +0 -83
  507. package/src/tooltip/_examples/tooltip.retro.example.ts +0 -107
  508. package/src/tooltip/index.ts +0 -4
  509. package/src/tooltip/tooltip-arrow.ts +0 -31
  510. package/src/tooltip/tooltip-content.ts +0 -38
  511. package/src/tooltip/tooltip-group.ts +0 -32
  512. package/src/tooltip/tooltip-trigger.ts +0 -47
  513. package/src/tooltip/tooltip.spec.ts +0 -40
  514. package/src/tooltip/tooltip.ts +0 -5
  515. package/src/tree-select/index.ts +0 -12
  516. package/src/tree-select/tree-select-content.ts +0 -199
  517. package/src/tree-select/tree-select-node.ts +0 -132
  518. package/src/tree-select/tree-select-root.ts +0 -272
  519. package/src/tree-select/tree-select-trigger.ts +0 -90
  520. package/src/tree-select/tree-select.context.ts +0 -63
  521. package/src/tree-select/tree-select.spec.ts +0 -433
  522. package/src/tree-select/tree-select.ts +0 -2
  523. package/src/typography/blockquote.ts +0 -57
  524. package/src/typography/code.ts +0 -53
  525. package/src/typography/index.ts +0 -22
  526. package/src/typography/lead.ts +0 -49
  527. package/src/typography/muted.ts +0 -29
  528. package/src/typography/truncate.ts +0 -99
  529. package/src/typography/typography.spec.ts +0 -203
  530. package/tsconfig.lib.json +0 -21
  531. package/tsconfig.lib.prod.json +0 -17
  532. package/tsconfig.spec.json +0 -18
  533. package/vite.config.ts +0 -27
  534. /package/{src/icon → icon}/icon.css +0 -0
  535. /package/{src/typography → typography}/prose.css +0 -0
@@ -1,470 +0,0 @@
1
- import {
2
- Directive,
3
- ElementRef,
4
- OnDestroy,
5
- OnInit,
6
- Signal,
7
- booleanAttribute,
8
- computed,
9
- effect,
10
- forwardRef,
11
- inject,
12
- input,
13
- output,
14
- signal,
15
- } from '@angular/core';
16
- import { KjDisabled } from '../primitives/interaction/disabled';
17
- import { KjFormControl } from '../primitives/forms/form-control';
18
- import { KjLiveRegion } from '../a11y/live-region';
19
- import { KjFocusRing } from '../primitives/interaction/focus-ring';
20
- import { KJ_INPUT_OTP, KjInputOtpContext } from './input-otp.context';
21
-
22
- /**
23
- * Root headless directive for the OTP input widget.
24
- *
25
- * Owns the concatenated value, cell count, character-set filtering, paste
26
- * distribution, auto-advance, completion announcement, and the
27
- * `KJ_INPUT_OTP` context that every `KjInputOtpCell` reads from.
28
- *
29
- * Composes `KjFormControl` via `hostDirectives` so the **whole widget** is a
30
- * single Angular form control — `[(ngModel)]` and `[formControl]` bind to the
31
- * concatenated string.
32
- *
33
- * @example
34
- * ```html
35
- * <div kjInputOtp [kjLength]="6" [(ngModel)]="code">
36
- * @for (i of cells; track i) {
37
- * <input kjInputOtpCell [kjIndex]="i" />
38
- * }
39
- * </div>
40
- * ```
41
- *
42
- * @doc-category Core/Data input
43
- * @doc
44
- * @doc-name input-otp
45
- * @doc-description Unstyled multi-cell one-time-password root that exposes the whole widget as a single form control.
46
- * @doc-is-main
47
- */
48
- @Directive({
49
- selector: '[kjInputOtp]',
50
- standalone: true,
51
- exportAs: 'kjInputOtp',
52
- hostDirectives: [
53
- { directive: KjDisabled, inputs: ['kjDisabled'] },
54
- KjFormControl,
55
- KjLiveRegion,
56
- ],
57
- providers: [
58
- { provide: KJ_INPUT_OTP, useExisting: forwardRef(() => KjInputOtp) },
59
- ],
60
- host: {
61
- 'role': 'group',
62
- '[attr.aria-label]': 'kjAriaLabel() ?? null',
63
- '[attr.aria-invalid]': 'formCtrl.touched() && kjInvalid() ? "true" : null',
64
- '[attr.data-invalid]': 'formCtrl.touched() && kjInvalid() ? "" : null',
65
- },
66
- })
67
- export class KjInputOtp implements KjInputOtpContext, OnInit, OnDestroy {
68
- readonly formCtrl = inject(KjFormControl);
69
- private readonly disabled$ = inject(KjDisabled);
70
- private readonly liveRegion = inject(KjLiveRegion);
71
-
72
- // ── Inputs ──────────────────────────────────────────────────────────────────
73
-
74
- /** Number of OTP cells. Common values: 4, 6, 8. */
75
- readonly kjLength = input<number>(6);
76
-
77
- /** Character-set restriction. Drives `inputmode`, `pattern`, and input/paste filtering. */
78
- readonly kjCharSet = input<'digits' | 'alphanumeric' | RegExp>('digits');
79
-
80
- /** When `true`, cells render with `type="password"`. */
81
- readonly kjMask = input(false, { transform: booleanAttribute });
82
-
83
- /** When `true`, emits `kjComplete` once the value reaches `kjLength`. */
84
- readonly kjAutoSubmit = input(false, { transform: booleanAttribute });
85
-
86
- /** Reflects an invalid state via `aria-invalid` (touched-gated). */
87
- readonly kjInvalid = input(false, { transform: booleanAttribute });
88
-
89
- /** Sets all cells to `readonly`. */
90
- readonly kjReadonly = input(false, { transform: booleanAttribute });
91
-
92
- /**
93
- * Accessible label for the widget when there is no parent `KjFormField`
94
- * supplying an `aria-labelledby`.
95
- */
96
- readonly kjAriaLabel = input<string | undefined>(undefined);
97
-
98
- // ── Outputs ─────────────────────────────────────────────────────────────────
99
-
100
- /** Emitted when the full code is entered (value.length === kjLength). */
101
- readonly kjComplete = output<string>();
102
-
103
- /** Emitted after a paste distributes characters across cells. */
104
- readonly kjPasted = output<string>();
105
-
106
- // ── Internal state ───────────────────────────────────────────────────────────
107
-
108
- /** Per-cell character array; resized lazily by setCellValue. */
109
- private readonly _chars = signal<string[]>([]);
110
-
111
- /** Cell element registry for programmatic focus management. */
112
- readonly _cells = new Map<number, HTMLInputElement>();
113
-
114
- /** Focused cell index, or -1. */
115
- private readonly _focusedIndex = signal<number>(-1);
116
-
117
- /** Whether the code was already complete on the previous notification cycle. */
118
- private _wasComplete = false;
119
-
120
- // ── Context signals (KjInputOtpContext) ──────────────────────────────────────
121
-
122
- /** Full concatenated OTP value (public, read-only signal). */
123
- readonly value: Signal<string> = computed(() =>
124
- this._chars().slice(0, this.kjLength()).join(''),
125
- );
126
-
127
- readonly length: Signal<number> = computed(() => this.kjLength());
128
-
129
- readonly disabled: Signal<boolean> = computed(
130
- () => this.disabled$.disabled() || this.formCtrl.disabled(),
131
- );
132
-
133
- readonly readonly: Signal<boolean> = computed(() => this.kjReadonly());
134
-
135
- readonly masked: Signal<boolean> = computed(() => this.kjMask());
136
-
137
- readonly charSet: Signal<'digits' | 'alphanumeric' | RegExp> = computed(
138
- () => this.kjCharSet(),
139
- );
140
-
141
- readonly focusedIndex: Signal<number> = this._focusedIndex.asReadonly();
142
-
143
- // ── Lifecycle ────────────────────────────────────────────────────────────────
144
-
145
- constructor() {
146
- // Reflect CVA value writes to internal char array (e.g. programmatic setValue).
147
- effect(() => {
148
- const incoming = this.formCtrl.value();
149
- if (incoming == null) return;
150
- const str = String(incoming);
151
- const chars = str.split('').slice(0, this.kjLength());
152
- this._chars.set(chars);
153
- });
154
-
155
- // Notify forms layer whenever the value signal changes.
156
- effect(() => {
157
- const val = this.value();
158
- this.formCtrl.notifyChange(val);
159
- this._checkCompletion(val);
160
- });
161
- }
162
-
163
- ngOnInit(): void {
164
- // Initialise the char array to the correct length on first render.
165
- if (this._chars().length === 0) {
166
- this._chars.set(Array(this.kjLength()).fill(''));
167
- }
168
- }
169
-
170
- ngOnDestroy(): void {
171
- this._cells.clear();
172
- }
173
-
174
- // ── KjInputOtpContext methods ────────────────────────────────────────────────
175
-
176
- /** Update a single cell's character and notify forms. */
177
- setCellValue(index: number, char: string): void {
178
- const current = [...this._chars()];
179
- // Ensure the array is long enough.
180
- while (current.length <= index) current.push('');
181
- current[index] = char;
182
- this._chars.set(current);
183
- }
184
-
185
- /** Move focus by delta (+1 / -1), clamped to valid range. */
186
- moveFocus(delta: number): void {
187
- const current = this._focusedIndex();
188
- const next = Math.max(0, Math.min(this.kjLength() - 1, current + delta));
189
- this._cells.get(next)?.focus();
190
- }
191
-
192
- /** Focus a specific cell index (clamped to valid range). */
193
- focusIndex(index: number): void {
194
- const clamped = Math.max(0, Math.min(this.kjLength() - 1, index));
195
- this._focusedIndex.set(clamped);
196
- this._cells.get(clamped)?.focus();
197
- }
198
-
199
- /**
200
- * Distribute pasted text across cells starting from `fromIndex`.
201
- * Filters the pasted text through the current charSet before distributing.
202
- */
203
- handlePaste(event: ClipboardEvent, fromIndex: number): void {
204
- event.preventDefault();
205
- const raw = event.clipboardData?.getData('text') ?? '';
206
- this.distributeText(raw, fromIndex);
207
- const filtered = this._filterChars(raw);
208
- if (filtered) {
209
- this.kjPasted.emit(filtered);
210
- }
211
- }
212
-
213
- /** Intercept copy and write the full OTP value to the clipboard. */
214
- handleCopy(event: ClipboardEvent): void {
215
- event.preventDefault();
216
- event.clipboardData?.setData('text/plain', this.value());
217
- }
218
-
219
- /** Register a cell's native input element for programmatic focus. */
220
- registerCell(index: number, el: HTMLInputElement): void {
221
- this._cells.set(index, el);
222
- }
223
-
224
- /** Deregister a cell element on destroy. */
225
- unregisterCell(index: number): void {
226
- this._cells.delete(index);
227
- }
228
-
229
- /**
230
- * Distribute raw text across cells starting from `fromIndex`, filtering
231
- * through the current charSet. Called by `KjInputOtpCell` for both
232
- * iOS-autofill over-length writes and as the internal paste helper.
233
- * @internal
234
- */
235
- distributeText(text: string, fromIndex: number): void {
236
- const filtered = this._filterChars(text);
237
- if (!filtered) return;
238
-
239
- const current = [...this._chars()];
240
- while (current.length < this.kjLength()) current.push('');
241
-
242
- let cellIndex = fromIndex;
243
- for (const ch of filtered) {
244
- if (cellIndex >= this.kjLength()) break;
245
- current[cellIndex] = ch;
246
- cellIndex++;
247
- }
248
- this._chars.set(current);
249
-
250
- // Focus the first empty cell after distribution, or the last cell.
251
- const firstEmpty = current.findIndex((c, i) => i >= fromIndex && !c);
252
- const focusTarget = firstEmpty !== -1 ? firstEmpty : this.kjLength() - 1;
253
- this._cells.get(focusTarget)?.focus();
254
- }
255
-
256
- // ── Private helpers ──────────────────────────────────────────────────────────
257
-
258
- private _checkCompletion(val: string): void {
259
- const complete = val.length >= this.kjLength() && !val.includes('');
260
- if (complete && !this._wasComplete) {
261
- this._wasComplete = true;
262
- this.liveRegion.announce('Code complete');
263
- // Always emit kjComplete so consumers can react regardless of
264
- // kjAutoSubmit. kjAutoSubmit is a UX hint for consumers, not a gate.
265
- this.kjComplete.emit(val);
266
- } else if (!complete) {
267
- this._wasComplete = false;
268
- }
269
- }
270
-
271
- /** Filter a string to only characters allowed by the current charSet. */
272
- private _filterChars(input: string): string {
273
- const cs = this.kjCharSet();
274
- if (cs === 'digits') return input.replace(/[^0-9]/g, '');
275
- if (cs === 'alphanumeric') return input.replace(/[^A-Za-z0-9]/g, '');
276
- // Custom RegExp — apply per character.
277
- return input.split('').filter(ch => (cs as RegExp).test(ch)).join('');
278
- }
279
- }
280
-
281
- // ────────────────────────────────────────────────────────────────────────────
282
- // KjInputOtpCell
283
- // ────────────────────────────────────────────────────────────────────────────
284
-
285
- /**
286
- * Leaf directive applied to each `<input>` inside a `[kjInputOtp]` group.
287
- *
288
- * Reads its character from the parent context signal keyed by `kjIndex`.
289
- * Owns per-cell keyboard handling (Backspace, ArrowLeft/Right, Home/End)
290
- * and delegates paste/copy and focus tracking back to the root directive.
291
- *
292
- * @example
293
- * ```html
294
- * <input kjInputOtpCell [kjIndex]="i" />
295
- * ```
296
- *
297
- * @doc-category Core/Data input
298
- * @doc
299
- * @doc-name input-otp
300
- */
301
- @Directive({
302
- selector: 'input[kjInputOtpCell]',
303
- standalone: true,
304
- hostDirectives: [KjFocusRing],
305
- host: {
306
- 'type': 'text',
307
- 'maxlength': '1',
308
- 'autocapitalize': 'off',
309
- 'autocorrect': 'off',
310
- 'spellcheck': 'false',
311
- '[attr.inputmode]': 'inputmode()',
312
- '[attr.pattern]': 'pattern()',
313
- '[attr.autocomplete]': 'kjIndex() === 0 ? "one-time-code" : "off"',
314
- '[attr.aria-label]': 'ariaLabel()',
315
- '[attr.tabindex]': 'isTabStop() ? "0" : "-1"',
316
- '[attr.disabled]': 'ctx.disabled() ? "" : null',
317
- '[attr.readonly]': 'ctx.readonly() ? "" : null',
318
- '[attr.type]': 'ctx.masked() ? "password" : "text"',
319
- '[value]': 'ctx.value()[kjIndex()] ?? ""',
320
- '(input)': 'onInput($event)',
321
- '(keydown)': 'onKeydown($event)',
322
- '(paste)': 'ctx.handlePaste($event, kjIndex())',
323
- '(copy)': 'ctx.handleCopy($event)',
324
- '(focus)': 'ctx.focusIndex(kjIndex())',
325
- '(blur)': 'onBlur()',
326
- },
327
- })
328
- export class KjInputOtpCell implements OnInit, OnDestroy {
329
- /** The context provided by the parent `KjInputOtp`. */
330
- readonly ctx = inject(KJ_INPUT_OTP);
331
-
332
- /** Zero-based index of this cell within the OTP group. Required. */
333
- readonly kjIndex = input.required<number>();
334
-
335
- /** Whether this cell is the roving tab stop. */
336
- protected readonly isTabStop = computed(() => {
337
- const chars = this.ctx.value();
338
- const len = this.ctx.length();
339
- // Tab stop is the first empty cell, or cell 0 when all are filled.
340
- const firstEmpty = Array.from({ length: len }, (_, i) => chars[i] ?? '').findIndex(c => !c);
341
- const tabStopIndex = firstEmpty === -1 ? 0 : firstEmpty;
342
- return this.kjIndex() === tabStopIndex;
343
- });
344
-
345
- protected readonly inputmode = computed(() =>
346
- this.ctx.charSet() === 'digits' ? 'numeric' : 'text',
347
- );
348
-
349
- protected readonly pattern = computed(() =>
350
- this.ctx.charSet() === 'digits' ? '[0-9]*' : null,
351
- );
352
-
353
- protected readonly ariaLabel = computed(
354
- () => `Code digit ${this.kjIndex() + 1} of ${this.ctx.length()}`,
355
- );
356
-
357
- // ── Lifecycle ────────────────────────────────────────────────────────────────
358
-
359
- private readonly _elRef = inject<ElementRef<HTMLInputElement>>(ElementRef);
360
-
361
- ngOnInit(): void {
362
- this.ctx.registerCell(this.kjIndex(), this._elRef.nativeElement);
363
- }
364
-
365
- ngOnDestroy(): void {
366
- this.ctx.unregisterCell(this.kjIndex());
367
- }
368
-
369
- // ── Event handlers ───────────────────────────────────────────────────────────
370
-
371
- /** Handle character input from the user (or iOS autofill writing a full code). */
372
- protected onInput(event: Event): void {
373
- const target = event.target as HTMLInputElement;
374
- const raw = target.value;
375
-
376
- if (raw.length > 1) {
377
- // iOS autofill or paste-via-input: treat as a paste from this index.
378
- // We call distributeText directly on the root to avoid constructing
379
- // ClipboardEvent/DataTransfer which are unavailable in some environments.
380
- (this.ctx as KjInputOtp).distributeText(raw, this.kjIndex());
381
- return;
382
- }
383
-
384
- const cs = this.ctx.charSet();
385
- const filtered = this._filterChar(raw, cs);
386
-
387
- if (filtered === '' && raw !== '') {
388
- // Character rejected — restore original value.
389
- target.value = this.ctx.value()[this.kjIndex()] ?? '';
390
- return;
391
- }
392
-
393
- this.ctx.setCellValue(this.kjIndex(), filtered);
394
-
395
- if (filtered !== '') {
396
- // Advance focus only if a valid character was entered.
397
- this.ctx.moveFocus(1);
398
- }
399
- }
400
-
401
- /** Handle keyboard navigation within the OTP group. */
402
- protected onKeydown(event: KeyboardEvent): void {
403
- const { key } = event;
404
-
405
- if (key === 'Backspace') {
406
- event.preventDefault();
407
- const currentChar = this.ctx.value()[this.kjIndex()] ?? '';
408
- if (currentChar !== '') {
409
- // Filled cell: clear it and move focus back.
410
- this.ctx.setCellValue(this.kjIndex(), '');
411
- this.ctx.moveFocus(-1);
412
- } else {
413
- // Empty cell: move to previous and clear that cell.
414
- const prevIndex = this.kjIndex() - 1;
415
- if (prevIndex >= 0) {
416
- this.ctx.setCellValue(prevIndex, '');
417
- this.ctx.moveFocus(-1);
418
- }
419
- }
420
- return;
421
- }
422
-
423
- if (key === 'Delete') {
424
- event.preventDefault();
425
- this.ctx.setCellValue(this.kjIndex(), '');
426
- return;
427
- }
428
-
429
- if (key === 'ArrowLeft') {
430
- event.preventDefault();
431
- this.ctx.moveFocus(-1);
432
- return;
433
- }
434
-
435
- if (key === 'ArrowRight') {
436
- event.preventDefault();
437
- this.ctx.moveFocus(1);
438
- return;
439
- }
440
-
441
- if (key === 'Home') {
442
- event.preventDefault();
443
- this.ctx.focusIndex(0);
444
- return;
445
- }
446
-
447
- if (key === 'End') {
448
- event.preventDefault();
449
- this.ctx.focusIndex(this.ctx.length() - 1);
450
- return;
451
- }
452
- }
453
-
454
- protected onBlur(): void {
455
- // Notify the form control as touched when any cell blurs
456
- // (the form control is on the root, cells delegate).
457
- // We reach the root's formCtrl through the context cast.
458
- const root = this.ctx as KjInputOtp;
459
- root.formCtrl?.notifyTouched?.();
460
- }
461
-
462
- // ── Private helpers ──────────────────────────────────────────────────────────
463
-
464
- private _filterChar(ch: string, cs: 'digits' | 'alphanumeric' | RegExp): string {
465
- if (!ch) return '';
466
- if (cs === 'digits') return /^[0-9]$/.test(ch) ? ch : '';
467
- if (cs === 'alphanumeric') return /^[A-Za-z0-9]$/.test(ch) ? ch : '';
468
- return (cs as RegExp).test(ch) ? ch : '';
469
- }
470
- }
package/src/kbd/index.ts DELETED
@@ -1 +0,0 @@
1
- export { KjKbd, KJ_KBD_SIZE_PRESET } from './kbd';
@@ -1,127 +0,0 @@
1
- import { Component, ChangeDetectionStrategy } from '@angular/core';
2
- import { TestBed } from '@angular/core/testing';
3
- import { render } from '@testing-library/angular';
4
- import { afterEach, describe, expect, it, vi } from 'vitest';
5
- import { KJ_SIZE_PRESET } from '../presets';
6
- import { KJ_KBD_SIZE_PRESET, KjKbd } from './kbd';
7
-
8
- /**
9
- * Flush microtasks + the rAF that backs `afterNextRender` so the directive's
10
- * dev-mode host inspection has a chance to run.
11
- */
12
- async function flushAfterNextRender(): Promise<void> {
13
- await new Promise<void>((resolve) => setTimeout(resolve, 0));
14
- await Promise.resolve();
15
- await Promise.resolve();
16
- }
17
-
18
- @Component({
19
- standalone: true,
20
- imports: [KjKbd],
21
- changeDetection: ChangeDetectionStrategy.Eager,
22
- template: `<kbd kjKbd [kjSize]="size">{{ label }}</kbd>`,
23
- })
24
- class HostComponent {
25
- size: string | undefined = undefined;
26
- label = 'Enter';
27
- }
28
-
29
- describe('KjKbd', () => {
30
- afterEach(() => vi.restoreAllMocks());
31
-
32
- describe('size composition (KjSize via hostDirectives)', () => {
33
- it('reflects default kjSize as data-size="md" on the host', async () => {
34
- const { container } = await render(`<kbd kjKbd>Enter</kbd>`, { imports: [KjKbd] });
35
- await flushAfterNextRender();
36
- // Built-in KJ_SIZE_PRESET factory default is 'md'.
37
- expect(container.querySelector('kbd')).toHaveAttribute('data-size', 'md');
38
- });
39
-
40
- it('reflects kjSize input as data-size on the host', async () => {
41
- const { container } = await render(`<kbd kjKbd [kjSize]="'lg'">Enter</kbd>`, {
42
- imports: [KjKbd],
43
- providers: [
44
- {
45
- provide: KJ_SIZE_PRESET,
46
- useValue: { values: ['xs', 'sm', 'md', 'lg'], default: 'md' },
47
- },
48
- ],
49
- });
50
- await flushAfterNextRender();
51
- expect(container.querySelector('kbd')).toHaveAttribute('data-size', 'lg');
52
- });
53
-
54
- it('honours the KJ_KBD_SIZE_PRESET re-export (xs / sm / md / lg, default md)', async () => {
55
- TestBed.configureTestingModule({
56
- providers: [{ provide: KJ_SIZE_PRESET, useValue: KJ_KBD_SIZE_PRESET }],
57
- });
58
- const fixture = TestBed.createComponent(HostComponent);
59
- fixture.componentInstance.size = 'xs';
60
- fixture.detectChanges();
61
- const host = fixture.nativeElement.querySelector('kbd');
62
- expect(host.getAttribute('data-size')).toBe('xs');
63
- });
64
-
65
- it('warns in dev mode when kjSize is outside the preset (size validation flows through)', async () => {
66
- const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
67
- TestBed.configureTestingModule({
68
- providers: [{ provide: KJ_SIZE_PRESET, useValue: KJ_KBD_SIZE_PRESET }],
69
- });
70
- const fixture = TestBed.createComponent(HostComponent);
71
- fixture.componentInstance.size = 'huge';
72
- fixture.detectChanges();
73
- // `KjSize` warns synchronously via `effect`; element-tag warning is
74
- // deferred to `afterNextRender`. Either way both have already fired by
75
- // here; we just need *some* call matching the size message.
76
- const matched = warn.mock.calls.some((c) => /unknown size/i.test(String(c[0])));
77
- expect(matched).toBe(true);
78
- });
79
- });
80
-
81
- describe('host element discipline (dev-mode warning)', () => {
82
- it('does not warn when host is <kbd>', async () => {
83
- const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
84
- await render(`<kbd kjKbd>Enter</kbd>`, { imports: [KjKbd] });
85
- await flushAfterNextRender();
86
- const matched = warn.mock.calls.some((c) => /applied to <\w+>/i.test(String(c[0])));
87
- expect(matched).toBe(false);
88
- });
89
-
90
- it('warns when host is not <kbd> (e.g. <span>)', async () => {
91
- const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
92
- await render(`<span kjKbd>Enter</span>`, { imports: [KjKbd] });
93
- await flushAfterNextRender();
94
- const matched = warn.mock.calls.some((c) => {
95
- const msg = String(c[0]);
96
- return /kjKbd applied to <span>/i.test(msg) && /<kbd>/i.test(msg);
97
- });
98
- expect(matched).toBe(true);
99
- });
100
- });
101
-
102
- describe('focusable-descendant discipline (dev-mode warning)', () => {
103
- it('warns when a focusable descendant exists', async () => {
104
- const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
105
- await render(`<kbd kjKbd><button>?</button></kbd>`, { imports: [KjKbd] });
106
- await flushAfterNextRender();
107
- const matched = warn.mock.calls.some((c) => /focusable descendant/i.test(String(c[0])));
108
- expect(matched).toBe(true);
109
- });
110
-
111
- it('does not warn for plain text content', async () => {
112
- const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
113
- await render(`<kbd kjKbd>Enter</kbd>`, { imports: [KjKbd] });
114
- await flushAfterNextRender();
115
- const matched = warn.mock.calls.some((c) => /focusable descendant/i.test(String(c[0])));
116
- expect(matched).toBe(false);
117
- });
118
-
119
- it('does not warn for non-focusable element children', async () => {
120
- const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
121
- await render(`<kbd kjKbd><span>Enter</span></kbd>`, { imports: [KjKbd] });
122
- await flushAfterNextRender();
123
- const matched = warn.mock.calls.some((c) => /focusable descendant/i.test(String(c[0])));
124
- expect(matched).toBe(false);
125
- });
126
- });
127
- });