@kouji-ui/core 0.1.1 → 0.1.2
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.
- package/fesm2022/kouji-ui-core.mjs +26789 -0
- package/fesm2022/kouji-ui-core.mjs.map +1 -0
- package/package.json +5 -6
- package/types/kouji-ui-core.d.ts +13545 -0
- package/.turbo/turbo-build.log +0 -30
- package/CHANGELOG.md +0 -190
- package/ng-package.json +0 -11
- package/src/a11y/.gitkeep +0 -0
- package/src/a11y/aria-describedby.spec.ts +0 -55
- package/src/a11y/aria-describedby.ts +0 -37
- package/src/a11y/aria-labelledby.spec.ts +0 -55
- package/src/a11y/aria-labelledby.ts +0 -38
- package/src/a11y/focus-trap.spec.ts +0 -86
- package/src/a11y/focus-trap.ts +0 -72
- package/src/a11y/index.ts +0 -10
- package/src/a11y/live-region.spec.ts +0 -58
- package/src/a11y/live-region.ts +0 -50
- package/src/a11y/roving-tabindex.spec.ts +0 -201
- package/src/a11y/roving-tabindex.ts +0 -153
- package/src/a11y/visually-hidden.spec.ts +0 -34
- package/src/a11y/visually-hidden.ts +0 -26
- package/src/accordion/accordion.context.ts +0 -44
- package/src/accordion/accordion.spec.ts +0 -242
- package/src/accordion/accordion.ts +0 -401
- package/src/accordion/index.ts +0 -8
- package/src/alert/alert.context.ts +0 -28
- package/src/alert/alert.spec.ts +0 -217
- package/src/alert/alert.ts +0 -417
- package/src/alert/config.ts +0 -46
- package/src/alert/index.ts +0 -19
- package/src/avatar/avatar-group.context.ts +0 -45
- package/src/avatar/avatar-group.spec.ts +0 -358
- package/src/avatar/avatar-group.ts +0 -259
- package/src/avatar/avatar.spec.ts +0 -18
- package/src/avatar/avatar.ts +0 -39
- package/src/avatar/index.ts +0 -11
- package/src/badge/badge.spec.ts +0 -28
- package/src/badge/badge.ts +0 -35
- package/src/badge/index.ts +0 -1
- package/src/breadcrumb/breadcrumb-current.ts +0 -38
- package/src/breadcrumb/breadcrumb-ellipsis.ts +0 -71
- package/src/breadcrumb/breadcrumb-item.ts +0 -41
- package/src/breadcrumb/breadcrumb-link.ts +0 -44
- package/src/breadcrumb/breadcrumb-list.ts +0 -42
- package/src/breadcrumb/breadcrumb-separator.ts +0 -45
- package/src/breadcrumb/breadcrumb.context.ts +0 -45
- package/src/breadcrumb/breadcrumb.spec.ts +0 -354
- package/src/breadcrumb/breadcrumb.ts +0 -239
- package/src/breadcrumb/config.ts +0 -84
- package/src/breadcrumb/index.ts +0 -18
- package/src/button/_examples/button.example.ts +0 -71
- package/src/button/_examples/button.finance.example.ts +0 -83
- package/src/button/_examples/button.retro.example.ts +0 -91
- package/src/button/_examples/button.sizes.example.ts +0 -60
- package/src/button/_examples/index.ts +0 -6
- package/src/button/button.spec.ts +0 -163
- package/src/button/button.ts +0 -142
- package/src/button/config.spec.ts +0 -33
- package/src/button/config.ts +0 -45
- package/src/button/index.ts +0 -2
- package/src/button-group/button-group.context.ts +0 -28
- package/src/button-group/button-group.spec.ts +0 -99
- package/src/button-group/button-group.ts +0 -99
- package/src/button-group/index.ts +0 -2
- package/src/calendar/calendar-day.ts +0 -102
- package/src/calendar/calendar-grid.ts +0 -90
- package/src/calendar/calendar-header.ts +0 -65
- package/src/calendar/calendar.context.ts +0 -53
- package/src/calendar/calendar.spec.ts +0 -225
- package/src/calendar/calendar.ts +0 -233
- package/src/calendar/date-utils.ts +0 -225
- package/src/calendar/index.ts +0 -28
- package/src/carousel/carousel.context.ts +0 -81
- package/src/carousel/carousel.spec.ts +0 -337
- package/src/carousel/carousel.ts +0 -919
- package/src/carousel/index.ts +0 -22
- package/src/cascade-select/cascade-select-option.ts +0 -205
- package/src/cascade-select/cascade-select-panel.ts +0 -106
- package/src/cascade-select/cascade-select-root.ts +0 -265
- package/src/cascade-select/cascade-select-sub-panel.ts +0 -168
- package/src/cascade-select/cascade-select-trigger.ts +0 -44
- package/src/cascade-select/cascade-select.context.ts +0 -71
- package/src/cascade-select/cascade-select.spec.ts +0 -241
- package/src/cascade-select/cascade-select.ts +0 -5
- package/src/cascade-select/index.ts +0 -11
- package/src/chart/chart.spec.ts +0 -27
- package/src/chart/chart.ts +0 -52
- package/src/chart/index.ts +0 -1
- package/src/chat/chat-avatar.ts +0 -31
- package/src/chat/chat-bubble.ts +0 -49
- package/src/chat/chat-footer.ts +0 -67
- package/src/chat/chat-header.ts +0 -41
- package/src/chat/chat-log.ts +0 -43
- package/src/chat/chat.context.ts +0 -64
- package/src/chat/chat.spec.ts +0 -341
- package/src/chat/chat.ts +0 -191
- package/src/chat/config.ts +0 -53
- package/src/chat/index.ts +0 -21
- package/src/checkbox/checkbox.spec.ts +0 -35
- package/src/checkbox/checkbox.ts +0 -89
- package/src/checkbox/index.ts +0 -1
- package/src/color-picker/color-picker.context.ts +0 -74
- package/src/color-picker/color-picker.spec.ts +0 -241
- package/src/color-picker/color-picker.ts +0 -698
- package/src/color-picker/color-picker.utils.ts +0 -140
- package/src/color-picker/index.ts +0 -28
- package/src/combobox/combobox-input.ts +0 -143
- package/src/combobox/combobox-listbox.ts +0 -49
- package/src/combobox/combobox-option.ts +0 -43
- package/src/combobox/combobox-root.ts +0 -281
- package/src/combobox/combobox.spec.ts +0 -75
- package/src/combobox/combobox.ts +0 -4
- package/src/combobox/index.ts +0 -4
- package/src/command-palette/command-empty.ts +0 -36
- package/src/command-palette/command-group.ts +0 -21
- package/src/command-palette/command-input.ts +0 -70
- package/src/command-palette/command-item.ts +0 -60
- package/src/command-palette/command-list.ts +0 -25
- package/src/command-palette/command-palette-dialog.ts +0 -74
- package/src/command-palette/command-palette-trigger.ts +0 -64
- package/src/command-palette/command-palette.filters.ts +0 -53
- package/src/command-palette/command-palette.spec.ts +0 -349
- package/src/command-palette/command-palette.ts +0 -204
- package/src/command-palette/command-separator.ts +0 -18
- package/src/command-palette/index.ts +0 -15
- package/src/confirm-popup/confirm-popup-action.ts +0 -39
- package/src/confirm-popup/confirm-popup-cancel.ts +0 -38
- package/src/confirm-popup/confirm-popup-content.ts +0 -113
- package/src/confirm-popup/confirm-popup-message.ts +0 -36
- package/src/confirm-popup/confirm-popup-trigger.ts +0 -31
- package/src/confirm-popup/confirm-popup.context.ts +0 -41
- package/src/confirm-popup/confirm-popup.spec.ts +0 -337
- package/src/confirm-popup/confirm-popup.ts +0 -109
- package/src/confirm-popup/index.ts +0 -12
- package/src/date-picker/date-picker-calendar.ts +0 -65
- package/src/date-picker/date-picker-trigger.ts +0 -215
- package/src/date-picker/date-picker.context.ts +0 -50
- package/src/date-picker/date-picker.spec.ts +0 -117
- package/src/date-picker/date-picker.ts +0 -127
- package/src/date-picker/index.ts +0 -7
- package/src/dialog/_examples/dialog.confirm.example.ts +0 -145
- package/src/dialog/_examples/dialog.example.ts +0 -106
- package/src/dialog/_examples/dialog.finance.example.ts +0 -121
- package/src/dialog/_examples/dialog.retro.example.ts +0 -126
- package/src/dialog/_examples/index.ts +0 -6
- package/src/dialog/dialog.ref.ts +0 -42
- package/src/dialog/dialog.service.ts +0 -66
- package/src/dialog/dialog.spec.ts +0 -37
- package/src/dialog/dialog.ts +0 -26
- package/src/dialog/index.ts +0 -3
- package/src/divider/divider.spec.ts +0 -223
- package/src/divider/divider.ts +0 -137
- package/src/divider/index.ts +0 -5
- package/src/drawer/drawer.ref.ts +0 -63
- package/src/drawer/drawer.service.ts +0 -106
- package/src/drawer/drawer.spec.ts +0 -117
- package/src/drawer/drawer.ts +0 -122
- package/src/drawer/index.ts +0 -10
- package/src/dropdown-menu/dropdown-menu-content.ts +0 -258
- package/src/dropdown-menu/dropdown-menu-group.ts +0 -31
- package/src/dropdown-menu/dropdown-menu-item.ts +0 -51
- package/src/dropdown-menu/dropdown-menu-label.ts +0 -41
- package/src/dropdown-menu/dropdown-menu-separator.ts +0 -27
- package/src/dropdown-menu/dropdown-menu-trigger.ts +0 -140
- package/src/dropdown-menu/dropdown-menu.spec.ts +0 -265
- package/src/dropdown-menu/dropdown-menu.ts +0 -60
- package/src/dropdown-menu/index.ts +0 -15
- package/src/example-components.ts +0 -42
- package/src/field/field-error.ts +0 -49
- package/src/field/field-group.ts +0 -39
- package/src/field/field-help.ts +0 -47
- package/src/field/field-label.ts +0 -30
- package/src/field/field.context.ts +0 -28
- package/src/field/field.spec.ts +0 -179
- package/src/field/field.ts +0 -121
- package/src/field/index.ts +0 -6
- package/src/file-upload/file-upload.context.ts +0 -89
- package/src/file-upload/file-upload.spec.ts +0 -290
- package/src/file-upload/file-upload.ts +0 -639
- package/src/file-upload/file-upload.types.ts +0 -59
- package/src/file-upload/index.ts +0 -23
- package/src/form/form-error-summary.ts +0 -87
- package/src/form/form-field.context.ts +0 -3
- package/src/form/form-field.spec.ts +0 -25
- package/src/form/form-field.ts +0 -52
- package/src/form/form.context.ts +0 -53
- package/src/form/form.spec.ts +0 -162
- package/src/form/form.ts +0 -326
- package/src/form/index.ts +0 -11
- package/src/icon/E2E.md +0 -14
- package/src/icon/icon.directive.spec.ts +0 -198
- package/src/icon/icon.directive.ts +0 -113
- package/src/icon/icon.mode.spec.ts +0 -29
- package/src/icon/icon.mode.ts +0 -23
- package/src/icon/icon.providers.spec.ts +0 -63
- package/src/icon/icon.providers.ts +0 -47
- package/src/icon/icon.resolver.spec.ts +0 -96
- package/src/icon/icon.resolver.ts +0 -49
- package/src/icon/icon.tokens.ts +0 -88
- package/src/icon/icon.types.ts +0 -48
- package/src/icon/index.ts +0 -21
- package/src/input/index.ts +0 -1
- package/src/input/input.spec.ts +0 -43
- package/src/input/input.ts +0 -89
- package/src/input-group/index.ts +0 -3
- package/src/input-group/input-group-addon.ts +0 -92
- package/src/input-group/input-group.context.ts +0 -27
- package/src/input-group/input-group.spec.ts +0 -186
- package/src/input-group/input-group.ts +0 -136
- package/src/input-mask/index.ts +0 -11
- package/src/input-mask/input-mask.compile.ts +0 -69
- package/src/input-mask/input-mask.engine.ts +0 -376
- package/src/input-mask/input-mask.presets.ts +0 -24
- package/src/input-mask/input-mask.spec.ts +0 -304
- package/src/input-mask/input-mask.tokens.ts +0 -49
- package/src/input-mask/input-mask.ts +0 -280
- package/src/input-otp/index.ts +0 -2
- package/src/input-otp/input-otp.context.ts +0 -41
- package/src/input-otp/input-otp.spec.ts +0 -308
- package/src/input-otp/input-otp.ts +0 -470
- package/src/kbd/index.ts +0 -1
- package/src/kbd/kbd.spec.ts +0 -127
- package/src/kbd/kbd.ts +0 -132
- package/src/link/config.ts +0 -44
- package/src/link/index.ts +0 -2
- package/src/link/link.spec.ts +0 -246
- package/src/link/link.ts +0 -226
- package/src/list/index.ts +0 -11
- package/src/list/list.spec.ts +0 -237
- package/src/list/list.ts +0 -277
- package/src/menubar/index.ts +0 -7
- package/src/menubar/menubar-item.ts +0 -204
- package/src/menubar/menubar.context.ts +0 -43
- package/src/menubar/menubar.spec.ts +0 -433
- package/src/menubar/menubar.ts +0 -309
- package/src/number-input/index.ts +0 -4
- package/src/number-input/number-input-group.ts +0 -64
- package/src/number-input/number-input.context.ts +0 -31
- package/src/number-input/number-input.format.ts +0 -148
- package/src/number-input/number-input.spec.ts +0 -170
- package/src/number-input/number-input.ts +0 -457
- package/src/number-input/number-stepper.ts +0 -193
- package/src/overlay-badge/index.ts +0 -7
- package/src/overlay-badge/overlay-badge-content.ts +0 -73
- package/src/overlay-badge/overlay-badge.context.ts +0 -37
- package/src/overlay-badge/overlay-badge.spec.ts +0 -220
- package/src/overlay-badge/overlay-badge.ts +0 -128
- package/src/pagination/config.ts +0 -82
- package/src/pagination/index.ts +0 -19
- package/src/pagination/page-tokens.ts +0 -78
- package/src/pagination/pagination-ellipsis.ts +0 -69
- package/src/pagination/pagination-first.ts +0 -84
- package/src/pagination/pagination-info.ts +0 -70
- package/src/pagination/pagination-item.ts +0 -81
- package/src/pagination/pagination-last.ts +0 -85
- package/src/pagination/pagination-next.ts +0 -86
- package/src/pagination/pagination-previous.ts +0 -90
- package/src/pagination/pagination.context.ts +0 -52
- package/src/pagination/pagination.spec.ts +0 -388
- package/src/pagination/pagination.ts +0 -288
- package/src/password-input/index.ts +0 -15
- package/src/password-input/password-input.context.ts +0 -65
- package/src/password-input/password-input.scorer.ts +0 -34
- package/src/password-input/password-input.spec.ts +0 -274
- package/src/password-input/password-input.ts +0 -488
- package/src/popover/_examples/index.ts +0 -5
- package/src/popover/_examples/popover.example.ts +0 -92
- package/src/popover/_examples/popover.finance.example.ts +0 -106
- package/src/popover/_examples/popover.retro.example.ts +0 -103
- package/src/popover/index.ts +0 -5
- package/src/popover/popover-arrow.ts +0 -30
- package/src/popover/popover-close.ts +0 -36
- package/src/popover/popover-content.ts +0 -41
- package/src/popover/popover-title.ts +0 -39
- package/src/popover/popover-trigger.ts +0 -40
- package/src/popover/popover.spec.ts +0 -59
- package/src/popover/popover.ts +0 -5
- package/src/presets/bind-presets.spec.ts +0 -50
- package/src/presets/bind-presets.ts +0 -43
- package/src/presets/index.ts +0 -3
- package/src/presets/size.spec.ts +0 -67
- package/src/presets/size.ts +0 -59
- package/src/presets/variant.spec.ts +0 -72
- package/src/presets/variant.ts +0 -62
- package/src/primitives/.gitkeep +0 -0
- package/src/primitives/directionality/directionality.spec.ts +0 -112
- package/src/primitives/directionality/directionality.ts +0 -89
- package/src/primitives/directionality/index.ts +0 -1
- package/src/primitives/forms/form-control.spec.ts +0 -67
- package/src/primitives/forms/form-control.ts +0 -94
- package/src/primitives/forms/index.ts +0 -1
- package/src/primitives/index.ts +0 -6
- package/src/primitives/interaction/disabled.spec.ts +0 -47
- package/src/primitives/interaction/disabled.ts +0 -31
- package/src/primitives/interaction/focus-ring.spec.ts +0 -62
- package/src/primitives/interaction/focus-ring.ts +0 -59
- package/src/primitives/interaction/index.ts +0 -2
- package/src/primitives/list/filterable-list.spec.ts +0 -114
- package/src/primitives/list/filterable-list.ts +0 -126
- package/src/primitives/list/group.spec.ts +0 -99
- package/src/primitives/list/group.ts +0 -139
- package/src/primitives/list/index.ts +0 -8
- package/src/primitives/list/inject-helpers.ts +0 -8
- package/src/primitives/list/item.spec.ts +0 -173
- package/src/primitives/list/item.ts +0 -222
- package/src/primitives/list/navigator.spec.ts +0 -286
- package/src/primitives/list/navigator.ts +0 -238
- package/src/primitives/list/selection.spec.ts +0 -214
- package/src/primitives/list/selection.ts +0 -339
- package/src/primitives/list/tokens.ts +0 -106
- package/src/primitives/list/type-ahead.spec.ts +0 -58
- package/src/primitives/list/type-ahead.ts +0 -46
- package/src/primitives/overlay/backdrop.spec.ts +0 -54
- package/src/primitives/overlay/backdrop.ts +0 -31
- package/src/primitives/overlay/builder.spec.ts +0 -38
- package/src/primitives/overlay/builder.ts +0 -151
- package/src/primitives/overlay/container.ts +0 -42
- package/src/primitives/overlay/context.ts +0 -14
- package/src/primitives/overlay/controller.spec.ts +0 -86
- package/src/primitives/overlay/controller.ts +0 -190
- package/src/primitives/overlay/id.spec.ts +0 -24
- package/src/primitives/overlay/id.ts +0 -17
- package/src/primitives/overlay/index.ts +0 -18
- package/src/primitives/overlay/overlay.css +0 -42
- package/src/primitives/overlay/panel.spec.ts +0 -52
- package/src/primitives/overlay/panel.ts +0 -102
- package/src/primitives/overlay/stack.spec.ts +0 -55
- package/src/primitives/overlay/stack.ts +0 -113
- package/src/primitives/overlay/strategies/backdrop/blurred.spec.ts +0 -11
- package/src/primitives/overlay/strategies/backdrop/blurred.ts +0 -5
- package/src/primitives/overlay/strategies/backdrop/none.spec.ts +0 -10
- package/src/primitives/overlay/strategies/backdrop/none.ts +0 -9
- package/src/primitives/overlay/strategies/backdrop/solid.spec.ts +0 -18
- package/src/primitives/overlay/strategies/backdrop/solid.ts +0 -23
- package/src/primitives/overlay/strategies/focus-trap/inert-based.spec.ts +0 -28
- package/src/primitives/overlay/strategies/focus-trap/inert-based.ts +0 -38
- package/src/primitives/overlay/strategies/focus-trap/no-trap.spec.ts +0 -9
- package/src/primitives/overlay/strategies/focus-trap/no-trap.ts +0 -8
- package/src/primitives/overlay/strategies/focus-trap/tab-cycle.spec.ts +0 -49
- package/src/primitives/overlay/strategies/focus-trap/tab-cycle.ts +0 -85
- package/src/primitives/overlay/strategies/index.ts +0 -34
- package/src/primitives/overlay/strategies/live-announcer/_announce.ts +0 -35
- package/src/primitives/overlay/strategies/live-announcer/assertive.spec.ts +0 -21
- package/src/primitives/overlay/strategies/live-announcer/assertive.ts +0 -11
- package/src/primitives/overlay/strategies/live-announcer/polite.spec.ts +0 -21
- package/src/primitives/overlay/strategies/live-announcer/polite.ts +0 -11
- package/src/primitives/overlay/strategies/live-announcer/silent.spec.ts +0 -12
- package/src/primitives/overlay/strategies/live-announcer/silent.ts +0 -5
- package/src/primitives/overlay/strategies/mount/body-portal.spec.ts +0 -40
- package/src/primitives/overlay/strategies/mount/body-portal.ts +0 -91
- package/src/primitives/overlay/strategies/mount/in-container.spec.ts +0 -43
- package/src/primitives/overlay/strategies/mount/in-container.ts +0 -39
- package/src/primitives/overlay/strategies/mount/in-place.spec.ts +0 -40
- package/src/primitives/overlay/strategies/mount/in-place.ts +0 -20
- package/src/primitives/overlay/strategies/position/anchored-to.spec.ts +0 -56
- package/src/primitives/overlay/strategies/position/anchored-to.ts +0 -248
- package/src/primitives/overlay/strategies/position/corner.spec.ts +0 -36
- package/src/primitives/overlay/strategies/position/corner.ts +0 -33
- package/src/primitives/overlay/strategies/position/edge-sheet.spec.ts +0 -32
- package/src/primitives/overlay/strategies/position/edge-sheet.ts +0 -36
- package/src/primitives/overlay/strategies/position/in-place-sibling.spec.ts +0 -25
- package/src/primitives/overlay/strategies/position/in-place-sibling.ts +0 -13
- package/src/primitives/overlay/strategies/position/point-at.spec.ts +0 -40
- package/src/primitives/overlay/strategies/position/point-at.ts +0 -34
- package/src/primitives/overlay/strategies/position/viewport-centered.spec.ts +0 -31
- package/src/primitives/overlay/strategies/position/viewport-centered.ts +0 -31
- package/src/primitives/overlay/strategies/scroll-lock/css-clip.spec.ts +0 -15
- package/src/primitives/overlay/strategies/scroll-lock/css-clip.ts +0 -39
- package/src/primitives/overlay/strategies/scroll-lock/html-overflow.spec.ts +0 -21
- package/src/primitives/overlay/strategies/scroll-lock/html-overflow.ts +0 -44
- package/src/primitives/overlay/strategies/scroll-lock/none.spec.ts +0 -9
- package/src/primitives/overlay/strategies/scroll-lock/none.ts +0 -5
- package/src/primitives/overlay/strategies/trigger-event/on-click.spec.ts +0 -32
- package/src/primitives/overlay/strategies/trigger-event/on-click.ts +0 -28
- package/src/primitives/overlay/strategies/trigger-event/on-context-menu.spec.ts +0 -45
- package/src/primitives/overlay/strategies/trigger-event/on-context-menu.ts +0 -70
- package/src/primitives/overlay/strategies/trigger-event/on-focus-or-input.spec.ts +0 -35
- package/src/primitives/overlay/strategies/trigger-event/on-focus-or-input.ts +0 -34
- package/src/primitives/overlay/strategies/trigger-event/on-focus.spec.ts +0 -64
- package/src/primitives/overlay/strategies/trigger-event/on-focus.ts +0 -37
- package/src/primitives/overlay/strategies/trigger-event/on-hotkey.spec.ts +0 -37
- package/src/primitives/overlay/strategies/trigger-event/on-hotkey.ts +0 -59
- package/src/primitives/overlay/strategies/trigger-event/on-hover.spec.ts +0 -34
- package/src/primitives/overlay/strategies/trigger-event/on-hover.ts +0 -86
- package/src/primitives/overlay/strategies/trigger-event/programmatic.spec.ts +0 -16
- package/src/primitives/overlay/strategies/trigger-event/programmatic.ts +0 -12
- package/src/primitives/overlay/tokens.ts +0 -54
- package/src/primitives/overlay/trigger.spec.ts +0 -103
- package/src/primitives/overlay/trigger.ts +0 -75
- package/src/primitives/overlay/types.ts +0 -24
- package/src/primitives/overlay/wrapper.ts +0 -50
- package/src/primitives/signals/deep-signal.ts +0 -109
- package/src/primitives/signals/index.ts +0 -1
- package/src/progress-bar/config.ts +0 -48
- package/src/progress-bar/index.ts +0 -12
- package/src/progress-bar/progress-bar-fill.ts +0 -37
- package/src/progress-bar/progress-bar.context.ts +0 -34
- package/src/progress-bar/progress-bar.spec.ts +0 -423
- package/src/progress-bar/progress-bar.ts +0 -217
- package/src/public-api.ts +0 -84
- package/src/radio/index.ts +0 -2
- package/src/radio/radio.context.ts +0 -3
- package/src/radio/radio.spec.ts +0 -36
- package/src/radio/radio.ts +0 -66
- package/src/select/index.ts +0 -4
- package/src/select/select-content.ts +0 -69
- package/src/select/select-option.ts +0 -35
- package/src/select/select-root.ts +0 -129
- package/src/select/select-trigger.ts +0 -93
- package/src/select/select.spec.ts +0 -138
- package/src/select/select.ts +0 -4
- package/src/skeleton/index.ts +0 -5
- package/src/skeleton/skeleton.spec.ts +0 -115
- package/src/skeleton/skeleton.ts +0 -56
- package/src/slider/index.ts +0 -10
- package/src/slider/slider-range.ts +0 -49
- package/src/slider/slider-thumb.ts +0 -335
- package/src/slider/slider-track.ts +0 -70
- package/src/slider/slider.context.ts +0 -79
- package/src/slider/slider.geometry.ts +0 -73
- package/src/slider/slider.spec.ts +0 -216
- package/src/slider/slider.ts +0 -443
- package/src/speed-dial/index.ts +0 -10
- package/src/speed-dial/speed-dial-action.ts +0 -40
- package/src/speed-dial/speed-dial-actions.ts +0 -31
- package/src/speed-dial/speed-dial-trigger.ts +0 -55
- package/src/speed-dial/speed-dial.context.ts +0 -36
- package/src/speed-dial/speed-dial.spec.ts +0 -143
- package/src/speed-dial/speed-dial.ts +0 -127
- package/src/spinner/config.ts +0 -48
- package/src/spinner/index.ts +0 -8
- package/src/spinner/spinner.spec.ts +0 -262
- package/src/spinner/spinner.ts +0 -129
- package/src/stepper/index.ts +0 -15
- package/src/stepper/stepper.context.ts +0 -63
- package/src/stepper/stepper.spec.ts +0 -403
- package/src/stepper/stepper.ts +0 -544
- package/src/styles/docs-themes.css +0 -82
- package/src/styles.css +0 -17
- package/src/table/column-helpers.spec.ts +0 -74
- package/src/table/column-helpers.ts +0 -68
- package/src/table/filter-fns.ts +0 -230
- package/src/table/filter-models.spec.ts +0 -240
- package/src/table/filter-models.ts +0 -124
- package/src/table/filter-params.ts +0 -90
- package/src/table/grid-api-impl.ts +0 -321
- package/src/table/grid-api.spec.ts +0 -178
- package/src/table/grid-api.ts +0 -285
- package/src/table/index.ts +0 -73
- package/src/table/table-cell.spec.ts +0 -43
- package/src/table/table-cell.ts +0 -38
- package/src/table/table-filter-outlet.ts +0 -120
- package/src/table/table-header.spec.ts +0 -54
- package/src/table/table-header.ts +0 -63
- package/src/table/table-keyboard.spec.ts +0 -68
- package/src/table/table-keyboard.ts +0 -107
- package/src/table/table-resource.spec.ts +0 -37
- package/src/table/table-resource.ts +0 -36
- package/src/table/table-row.spec.ts +0 -54
- package/src/table/table-row.ts +0 -31
- package/src/table/table-storage.spec.ts +0 -67
- package/src/table/table-storage.ts +0 -76
- package/src/table/table.spec.ts +0 -172
- package/src/table/table.ts +0 -281
- package/src/table/table.types.ts +0 -83
- package/src/tabs/index.ts +0 -7
- package/src/tabs/tabs.context.ts +0 -32
- package/src/tabs/tabs.spec.ts +0 -352
- package/src/tabs/tabs.ts +0 -364
- package/src/tag/config.ts +0 -53
- package/src/tag/index.ts +0 -7
- package/src/tag/tag-list.ts +0 -76
- package/src/tag/tag-remove.ts +0 -61
- package/src/tag/tag.context.ts +0 -36
- package/src/tag/tag.spec.ts +0 -240
- package/src/tag/tag.ts +0 -203
- package/src/test-setup.ts +0 -5
- package/src/textarea/config.ts +0 -42
- package/src/textarea/index.ts +0 -8
- package/src/textarea/textarea.spec.ts +0 -176
- package/src/textarea/textarea.ts +0 -235
- package/src/time-picker/index.ts +0 -15
- package/src/time-picker/time-picker-meridiem.ts +0 -123
- package/src/time-picker/time-picker-segment.ts +0 -318
- package/src/time-picker/time-picker.context.ts +0 -38
- package/src/time-picker/time-picker.format.ts +0 -181
- package/src/time-picker/time-picker.spec.ts +0 -189
- package/src/time-picker/time-picker.ts +0 -274
- package/src/toast/_examples/index.ts +0 -5
- package/src/toast/_examples/toast.example.ts +0 -282
- package/src/toast/_examples/toast.finance.example.ts +0 -180
- package/src/toast/_examples/toast.retro.example.ts +0 -161
- package/src/toast/index.ts +0 -28
- package/src/toast/toast.ref.ts +0 -26
- package/src/toast/toast.service.ts +0 -339
- package/src/toast/toast.spec.ts +0 -247
- package/src/toast/toast.strategy.ts +0 -112
- package/src/toast/toast.ts +0 -463
- package/src/toast/toast.types.ts +0 -5
- package/src/toggle/index.ts +0 -1
- package/src/toggle/toggle.spec.ts +0 -24
- package/src/toggle/toggle.ts +0 -48
- package/src/tooltip/_examples/index.ts +0 -6
- package/src/tooltip/_examples/tooltip.example.ts +0 -82
- package/src/tooltip/_examples/tooltip.finance.example.ts +0 -97
- package/src/tooltip/_examples/tooltip.placements.example.ts +0 -83
- package/src/tooltip/_examples/tooltip.retro.example.ts +0 -107
- package/src/tooltip/index.ts +0 -4
- package/src/tooltip/tooltip-arrow.ts +0 -31
- package/src/tooltip/tooltip-content.ts +0 -38
- package/src/tooltip/tooltip-group.ts +0 -32
- package/src/tooltip/tooltip-trigger.ts +0 -47
- package/src/tooltip/tooltip.spec.ts +0 -40
- package/src/tooltip/tooltip.ts +0 -5
- package/src/tree-select/index.ts +0 -12
- package/src/tree-select/tree-select-content.ts +0 -199
- package/src/tree-select/tree-select-node.ts +0 -132
- package/src/tree-select/tree-select-root.ts +0 -272
- package/src/tree-select/tree-select-trigger.ts +0 -90
- package/src/tree-select/tree-select.context.ts +0 -63
- package/src/tree-select/tree-select.spec.ts +0 -433
- package/src/tree-select/tree-select.ts +0 -2
- package/src/typography/blockquote.ts +0 -57
- package/src/typography/code.ts +0 -53
- package/src/typography/index.ts +0 -22
- package/src/typography/lead.ts +0 -49
- package/src/typography/muted.ts +0 -29
- package/src/typography/truncate.ts +0 -99
- package/src/typography/typography.spec.ts +0 -203
- package/tsconfig.lib.json +0 -21
- package/tsconfig.lib.prod.json +0 -17
- package/tsconfig.spec.json +0 -18
- package/vite.config.ts +0 -27
- /package/{src/icon → icon}/icon.css +0 -0
- /package/{src/typography → typography}/prose.css +0 -0
package/src/presets/variant.ts
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { Directive, InjectionToken, InputSignalWithTransform, effect, inject, input, isDevMode } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Shape of the preset configuration consumed by `KjVariant`. One per consumer
|
|
5
|
-
* directive, provided via `bindPresets` from a per-component config token.
|
|
6
|
-
*
|
|
7
|
-
* @internal
|
|
8
|
-
*/
|
|
9
|
-
export interface KjVariantPreset {
|
|
10
|
-
values: string[];
|
|
11
|
-
default: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* DI token holding the variant preset for the current consumer's injector
|
|
16
|
-
* scope. Resolved by `KjVariant` at construction time.
|
|
17
|
-
*
|
|
18
|
-
* Default factory: `{ values: ['default'], default: 'default' }`.
|
|
19
|
-
*
|
|
20
|
-
* @internal
|
|
21
|
-
*/
|
|
22
|
-
export const KJ_VARIANT_PRESET = new InjectionToken<KjVariantPreset>('kj.variant.preset', {
|
|
23
|
-
factory: () => ({ values: ['default'], default: 'default' }),
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Internal preset directive composed via `hostDirectives` by every stylistic
|
|
28
|
-
* component to expose a configurable `variant` input that reflects to a
|
|
29
|
-
* `data-variant` host attribute. App code does not import this directly.
|
|
30
|
-
*
|
|
31
|
-
* @internal
|
|
32
|
-
*/
|
|
33
|
-
@Directive({
|
|
34
|
-
selector: '[kjVariant]',
|
|
35
|
-
standalone: true,
|
|
36
|
-
host: { '[attr.data-variant]': 'kjVariant()' },
|
|
37
|
-
})
|
|
38
|
-
export class KjVariant {
|
|
39
|
-
private readonly preset = inject(KJ_VARIANT_PRESET);
|
|
40
|
-
|
|
41
|
-
// Explicit field annotation pins the ng-packagr-emitted .d.ts shape —
|
|
42
|
-
// without it ng-packagr collapses the write type to `string` (dropping the
|
|
43
|
-
// `| undefined` flow-through), which trips the docs extractor and any
|
|
44
|
-
// consumer trying to bind a `string | undefined` source.
|
|
45
|
-
readonly kjVariant: InputSignalWithTransform<string, string | undefined> = input(
|
|
46
|
-
this.preset.default,
|
|
47
|
-
{ transform: (v?: string) => v || this.preset.default },
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
constructor() {
|
|
51
|
-
if (isDevMode()) {
|
|
52
|
-
effect(() => {
|
|
53
|
-
const v = this.kjVariant();
|
|
54
|
-
if (!this.preset.values.includes(v)) {
|
|
55
|
-
console.warn(
|
|
56
|
-
`[kj] unknown variant "${v}". Allowed values: ${this.preset.values.join(', ')}.`,
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
package/src/primitives/.gitkeep
DELETED
|
File without changes
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { Component, PLATFORM_ID, inject } from '@angular/core';
|
|
2
|
-
import { TestBed } from '@angular/core/testing';
|
|
3
|
-
import { render } from '@testing-library/angular';
|
|
4
|
-
import { KjDirectionality } from './directionality';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Helpers — flush microtasks + the rAF that backs afterNextRender so the
|
|
8
|
-
* service has a chance to run its initial read and attach the observer.
|
|
9
|
-
*/
|
|
10
|
-
async function flushAfterNextRender(): Promise<void> {
|
|
11
|
-
// Allow any queued afterNextRender callbacks to run, then flush
|
|
12
|
-
// microtasks twice (Angular batches signal updates).
|
|
13
|
-
await new Promise<void>((resolve) => setTimeout(resolve, 0));
|
|
14
|
-
await Promise.resolve();
|
|
15
|
-
await Promise.resolve();
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function setHtmlDir(value: string | null): void {
|
|
19
|
-
if (value === null) {
|
|
20
|
-
document.documentElement.removeAttribute('dir');
|
|
21
|
-
} else {
|
|
22
|
-
document.documentElement.setAttribute('dir', value);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
describe('KjDirectionality', () => {
|
|
27
|
-
afterEach(() => {
|
|
28
|
-
setHtmlDir(null);
|
|
29
|
-
document.body.removeAttribute('dir');
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('reads "ltr" initially when <html dir="ltr">', async () => {
|
|
33
|
-
setHtmlDir('ltr');
|
|
34
|
-
|
|
35
|
-
@Component({ standalone: true, template: '' })
|
|
36
|
-
class Host {
|
|
37
|
-
readonly dir = inject(KjDirectionality);
|
|
38
|
-
}
|
|
39
|
-
const { fixture } = await render(Host);
|
|
40
|
-
await flushAfterNextRender();
|
|
41
|
-
|
|
42
|
-
expect(fixture.componentInstance.dir.current()).toBe('ltr');
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('reads "rtl" initially when <html dir="rtl">', async () => {
|
|
46
|
-
setHtmlDir('rtl');
|
|
47
|
-
|
|
48
|
-
@Component({ standalone: true, template: '' })
|
|
49
|
-
class Host {
|
|
50
|
-
readonly dir = inject(KjDirectionality);
|
|
51
|
-
}
|
|
52
|
-
const { fixture } = await render(Host);
|
|
53
|
-
await flushAfterNextRender();
|
|
54
|
-
|
|
55
|
-
expect(fixture.componentInstance.dir.current()).toBe('rtl');
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('defaults to "ltr" when no dir attribute is set on <html> or <body>', async () => {
|
|
59
|
-
setHtmlDir(null);
|
|
60
|
-
document.body.removeAttribute('dir');
|
|
61
|
-
|
|
62
|
-
@Component({ standalone: true, template: '' })
|
|
63
|
-
class Host {
|
|
64
|
-
readonly dir = inject(KjDirectionality);
|
|
65
|
-
}
|
|
66
|
-
const { fixture } = await render(Host);
|
|
67
|
-
await flushAfterNextRender();
|
|
68
|
-
|
|
69
|
-
expect(fixture.componentInstance.dir.current()).toBe('ltr');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('updates the signal when <html dir> changes via MutationObserver', async () => {
|
|
73
|
-
setHtmlDir('ltr');
|
|
74
|
-
|
|
75
|
-
@Component({ standalone: true, template: '' })
|
|
76
|
-
class Host {
|
|
77
|
-
readonly dir = inject(KjDirectionality);
|
|
78
|
-
}
|
|
79
|
-
const { fixture } = await render(Host);
|
|
80
|
-
await flushAfterNextRender();
|
|
81
|
-
|
|
82
|
-
const svc = fixture.componentInstance.dir;
|
|
83
|
-
expect(svc.current()).toBe('ltr');
|
|
84
|
-
|
|
85
|
-
setHtmlDir('rtl');
|
|
86
|
-
// Allow MutationObserver microtask to deliver and the signal to update.
|
|
87
|
-
await flushAfterNextRender();
|
|
88
|
-
|
|
89
|
-
expect(svc.current()).toBe('rtl');
|
|
90
|
-
|
|
91
|
-
setHtmlDir('ltr');
|
|
92
|
-
await flushAfterNextRender();
|
|
93
|
-
|
|
94
|
-
expect(svc.current()).toBe('ltr');
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('returns "ltr" on the server (PLATFORM_ID="server") without DOM access', () => {
|
|
98
|
-
// Spy proves the SSR path never touches documentElement.getAttribute.
|
|
99
|
-
const getAttrSpy = vi.spyOn(document.documentElement, 'getAttribute');
|
|
100
|
-
|
|
101
|
-
TestBed.resetTestingModule();
|
|
102
|
-
TestBed.configureTestingModule({
|
|
103
|
-
providers: [{ provide: PLATFORM_ID, useValue: 'server' }],
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
const svc = TestBed.inject(KjDirectionality);
|
|
107
|
-
expect(svc.current()).toBe('ltr');
|
|
108
|
-
expect(getAttrSpy).not.toHaveBeenCalled();
|
|
109
|
-
|
|
110
|
-
getAttrSpy.mockRestore();
|
|
111
|
-
});
|
|
112
|
-
});
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DOCUMENT,
|
|
3
|
-
DestroyRef,
|
|
4
|
-
Injectable,
|
|
5
|
-
PLATFORM_ID,
|
|
6
|
-
Signal,
|
|
7
|
-
afterNextRender,
|
|
8
|
-
inject,
|
|
9
|
-
signal,
|
|
10
|
-
} from '@angular/core';
|
|
11
|
-
import { isPlatformBrowser } from '@angular/common';
|
|
12
|
-
|
|
13
|
-
/** Logical text direction. */
|
|
14
|
-
export type KjDirection = 'ltr' | 'rtl';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Reads the document's logical text direction (`<html dir>`, falling back to
|
|
18
|
-
* `<body dir>`) and exposes it as a signal that updates when the attribute
|
|
19
|
-
* changes. SSR-safe — on the server the signal returns `'ltr'` and no DOM
|
|
20
|
-
* APIs are touched.
|
|
21
|
-
*
|
|
22
|
-
* Use this for RTL-aware behaviour in directives that cannot rely on CSS
|
|
23
|
-
* (e.g. computing logical positions, emitting `[attr.data-direction]`,
|
|
24
|
-
* choosing arrow-key handlers).
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```ts
|
|
28
|
-
* private readonly dir = inject(KjDirectionality);
|
|
29
|
-
* readonly isRtl = computed(() => this.dir.current() === 'rtl');
|
|
30
|
-
* ```
|
|
31
|
-
* @doc-category Core/Primitives
|
|
32
|
-
*/
|
|
33
|
-
@Injectable({ providedIn: 'root' })
|
|
34
|
-
export class KjDirectionality {
|
|
35
|
-
private readonly platformId = inject(PLATFORM_ID);
|
|
36
|
-
private readonly destroyRef = inject(DestroyRef);
|
|
37
|
-
private readonly doc = inject(DOCUMENT, { optional: true }) as Document | null;
|
|
38
|
-
|
|
39
|
-
private readonly _current = signal<KjDirection>('ltr');
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Current document direction. `'ltr'` on the server and as the fallback
|
|
43
|
-
* when no `dir` attribute is set.
|
|
44
|
-
*/
|
|
45
|
-
readonly current: Signal<KjDirection> = this._current.asReadonly();
|
|
46
|
-
|
|
47
|
-
constructor() {
|
|
48
|
-
if (!isPlatformBrowser(this.platformId) || !this.doc) {
|
|
49
|
-
// SSR: leave the default `'ltr'` and skip all DOM access.
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Read the initial value as soon as the DOM is ready. afterNextRender
|
|
54
|
-
// guarantees a browser context and avoids reading during SSR.
|
|
55
|
-
afterNextRender(() => {
|
|
56
|
-
this._current.set(this.read());
|
|
57
|
-
|
|
58
|
-
const html = this.doc!.documentElement;
|
|
59
|
-
const observer = new MutationObserver(() => {
|
|
60
|
-
const next = this.read();
|
|
61
|
-
if (next !== this._current()) {
|
|
62
|
-
this._current.set(next);
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
observer.observe(html, {
|
|
66
|
-
attributes: true,
|
|
67
|
-
attributeFilter: ['dir'],
|
|
68
|
-
subtree: false,
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
this.destroyRef.onDestroy(() => observer.disconnect());
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Reads the effective direction from `<html dir>`, falling back to
|
|
77
|
-
* `<body dir>`, then `'ltr'`. Any value other than `'rtl'` collapses to
|
|
78
|
-
* `'ltr'` — `dir="auto"` is treated as LTR until the browser computes
|
|
79
|
-
* something more specific (which we cannot observe via attribute changes).
|
|
80
|
-
*/
|
|
81
|
-
private read(): KjDirection {
|
|
82
|
-
const doc = this.doc;
|
|
83
|
-
if (!doc) return 'ltr';
|
|
84
|
-
const htmlDir = doc.documentElement?.getAttribute('dir');
|
|
85
|
-
const bodyDir = doc.body?.getAttribute('dir');
|
|
86
|
-
const value = (htmlDir ?? bodyDir ?? '').toLowerCase();
|
|
87
|
-
return value === 'rtl' ? 'rtl' : 'ltr';
|
|
88
|
-
}
|
|
89
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { KjDirectionality, type KjDirection } from './directionality';
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
|
2
|
-
import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
|
3
|
-
import { render } from '@testing-library/angular';
|
|
4
|
-
import { toHaveNoViolations } from 'jest-axe';
|
|
5
|
-
import { KjFormControl } from './form-control';
|
|
6
|
-
|
|
7
|
-
expect.extend(toHaveNoViolations);
|
|
8
|
-
|
|
9
|
-
@Component({
|
|
10
|
-
standalone: true,
|
|
11
|
-
imports: [KjFormControl, ReactiveFormsModule],
|
|
12
|
-
changeDetection: ChangeDetectionStrategy.Eager,
|
|
13
|
-
template: `<input
|
|
14
|
-
kjFormControl
|
|
15
|
-
[formControl]="ctrl"
|
|
16
|
-
(input)="onInput($event)"
|
|
17
|
-
(blur)="onBlur()"
|
|
18
|
-
/>`,
|
|
19
|
-
})
|
|
20
|
-
class TestHostComponent {
|
|
21
|
-
ctrl = new FormControl('');
|
|
22
|
-
formCtrl!: KjFormControl;
|
|
23
|
-
onInput(_e: Event): void {
|
|
24
|
-
// will be wired by the directive consumer pattern
|
|
25
|
-
}
|
|
26
|
-
onBlur(): void {}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
describe('KjFormControl', () => {
|
|
30
|
-
it('registers as NG_VALUE_ACCESSOR so formControl binding works', async () => {
|
|
31
|
-
const { container } = await render(TestHostComponent);
|
|
32
|
-
expect(container.querySelector('input')).toBeInTheDocument();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('writeValue updates the value signal', async () => {
|
|
36
|
-
const { fixture } = await render(TestHostComponent);
|
|
37
|
-
const directive = fixture.debugElement.children[0].injector.get(KjFormControl);
|
|
38
|
-
directive.writeValue('hello');
|
|
39
|
-
expect(directive.value()).toBe('hello');
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('setDisabledState updates the disabled signal', async () => {
|
|
43
|
-
const { fixture } = await render(TestHostComponent);
|
|
44
|
-
const directive = fixture.debugElement.children[0].injector.get(KjFormControl);
|
|
45
|
-
directive.setDisabledState(true);
|
|
46
|
-
expect(directive.disabled()).toBe(true);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('notifyChange updates value and calls onChange', async () => {
|
|
50
|
-
const { fixture } = await render(TestHostComponent);
|
|
51
|
-
const directive = fixture.debugElement.children[0].injector.get(KjFormControl);
|
|
52
|
-
let emitted: unknown;
|
|
53
|
-
directive.registerOnChange((v) => {
|
|
54
|
-
emitted = v;
|
|
55
|
-
});
|
|
56
|
-
directive.notifyChange('test');
|
|
57
|
-
expect(directive.value()).toBe('test');
|
|
58
|
-
expect(emitted).toBe('test');
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('notifyTouched marks touched', async () => {
|
|
62
|
-
const { fixture } = await render(TestHostComponent);
|
|
63
|
-
const directive = fixture.debugElement.children[0].injector.get(KjFormControl);
|
|
64
|
-
directive.notifyTouched();
|
|
65
|
-
expect(directive.touched()).toBe(true);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { Directive, forwardRef, signal } from '@angular/core';
|
|
2
|
-
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Shared ControlValueAccessor primitive. Compose via `hostDirectives` on any
|
|
6
|
-
* form input directive (KjInput, KjCheckbox, etc.) to wire
|
|
7
|
-
* Angular reactive forms and template-driven forms automatically.
|
|
8
|
-
*
|
|
9
|
-
* The host directive calls `notifyChange(value)` on user input and
|
|
10
|
-
* `notifyTouched()` on blur. The directive handles all CVA plumbing.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* @Directive({
|
|
15
|
-
* selector: '[kjInput]',
|
|
16
|
-
* hostDirectives: [KjFormControl],
|
|
17
|
-
* host: {
|
|
18
|
-
* '(input)': 'formCtrl.notifyChange($event.target.value)',
|
|
19
|
-
* '(blur)': 'formCtrl.notifyTouched()',
|
|
20
|
-
* },
|
|
21
|
-
* })
|
|
22
|
-
* export class KjInput {
|
|
23
|
-
* readonly formCtrl = inject(KjFormControl);
|
|
24
|
-
* }
|
|
25
|
-
* ```
|
|
26
|
-
* @doc-category Core/Primitives
|
|
27
|
-
* @doc
|
|
28
|
-
* @doc-name forms
|
|
29
|
-
* @doc-description Wires any input directive into Angular reactive and template-driven forms.
|
|
30
|
-
* @doc-is-main
|
|
31
|
-
*/
|
|
32
|
-
@Directive({
|
|
33
|
-
selector: '[kjFormControl]',
|
|
34
|
-
standalone: true,
|
|
35
|
-
providers: [
|
|
36
|
-
{
|
|
37
|
-
provide: NG_VALUE_ACCESSOR,
|
|
38
|
-
useExisting: forwardRef(() => KjFormControl),
|
|
39
|
-
multi: true,
|
|
40
|
-
},
|
|
41
|
-
],
|
|
42
|
-
})
|
|
43
|
-
export class KjFormControl implements ControlValueAccessor {
|
|
44
|
-
/** The current form value, kept in sync with the Angular forms model. */
|
|
45
|
-
readonly value = signal<unknown>(undefined);
|
|
46
|
-
|
|
47
|
-
/** Whether the control is disabled by the Angular forms layer. */
|
|
48
|
-
readonly disabled = signal<boolean>(false);
|
|
49
|
-
|
|
50
|
-
/** Whether the control has been touched (blurred at least once). */
|
|
51
|
-
readonly touched = signal<boolean>(false);
|
|
52
|
-
|
|
53
|
-
private _onChange?: (value: unknown) => void;
|
|
54
|
-
private _onTouched?: () => void;
|
|
55
|
-
|
|
56
|
-
/** @internal — called by Angular forms */
|
|
57
|
-
writeValue(val: unknown): void {
|
|
58
|
-
this.value.set(val);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/** @internal — called by Angular forms */
|
|
62
|
-
registerOnChange(fn: (value: unknown) => void): void {
|
|
63
|
-
this._onChange = fn;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/** @internal — called by Angular forms */
|
|
67
|
-
registerOnTouched(fn: () => void): void {
|
|
68
|
-
this._onTouched = fn;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/** @internal — called by Angular forms */
|
|
72
|
-
setDisabledState(isDisabled: boolean): void {
|
|
73
|
-
this.disabled.set(isDisabled);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Call this when the user changes the control's value.
|
|
78
|
-
* Updates the value signal and notifies Angular forms.
|
|
79
|
-
* @param val - The new value.
|
|
80
|
-
*/
|
|
81
|
-
notifyChange(val: unknown): void {
|
|
82
|
-
this.value.set(val);
|
|
83
|
-
this._onChange?.(val);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Call this when the user blurs the control.
|
|
88
|
-
* Marks the control as touched.
|
|
89
|
-
*/
|
|
90
|
-
notifyTouched(): void {
|
|
91
|
-
this.touched.set(true);
|
|
92
|
-
this._onTouched?.();
|
|
93
|
-
}
|
|
94
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { KjFormControl } from './form-control';
|
package/src/primitives/index.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { render } from '@testing-library/angular';
|
|
2
|
-
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
3
|
-
import { KjDisabled } from './disabled';
|
|
4
|
-
|
|
5
|
-
expect.extend(toHaveNoViolations);
|
|
6
|
-
|
|
7
|
-
describe('KjDisabled', () => {
|
|
8
|
-
it('sets aria-disabled="true" when disabled', async () => {
|
|
9
|
-
const { container } = await render(
|
|
10
|
-
`<button kjDisabled [kjDisabled]="true">Submit</button>`,
|
|
11
|
-
{ imports: [KjDisabled] },
|
|
12
|
-
);
|
|
13
|
-
expect(container.querySelector('button')).toHaveAttribute('aria-disabled', 'true');
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('sets data-disabled attribute when disabled', async () => {
|
|
17
|
-
const { container } = await render(
|
|
18
|
-
`<button kjDisabled [kjDisabled]="true">Submit</button>`,
|
|
19
|
-
{ imports: [KjDisabled] },
|
|
20
|
-
);
|
|
21
|
-
expect(container.querySelector('button')).toHaveAttribute('data-disabled', '');
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('removes aria-disabled when not disabled', async () => {
|
|
25
|
-
const { container } = await render(
|
|
26
|
-
`<button kjDisabled [kjDisabled]="false">Submit</button>`,
|
|
27
|
-
{ imports: [KjDisabled] },
|
|
28
|
-
);
|
|
29
|
-
expect(container.querySelector('button')).not.toHaveAttribute('aria-disabled');
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('defaults to not disabled', async () => {
|
|
33
|
-
const { container } = await render(
|
|
34
|
-
`<button kjDisabled>Submit</button>`,
|
|
35
|
-
{ imports: [KjDisabled] },
|
|
36
|
-
);
|
|
37
|
-
expect(container.querySelector('button')).not.toHaveAttribute('aria-disabled');
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('passes axe accessibility audit', async () => {
|
|
41
|
-
const { container } = await render(
|
|
42
|
-
`<button kjDisabled [kjDisabled]="true">Submit</button>`,
|
|
43
|
-
{ imports: [KjDisabled] },
|
|
44
|
-
);
|
|
45
|
-
expect(await axe(container)).toHaveNoViolations();
|
|
46
|
-
});
|
|
47
|
-
});
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Directive, booleanAttribute, input } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Applies disabled state to any element via ARIA and data attributes.
|
|
5
|
-
*
|
|
6
|
-
* Compose via `hostDirectives` on other directives to add disabled behaviour.
|
|
7
|
-
* The directive reflects `aria-disabled` and `data-disabled` so consumers do
|
|
8
|
-
* not need to repeat the same host-binding pattern on every input.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```html
|
|
12
|
-
* <div kjDisabled [kjDisabled]="isLoading()">Content</div>
|
|
13
|
-
* ```
|
|
14
|
-
* @doc-category Core/Primitives
|
|
15
|
-
* @doc
|
|
16
|
-
* @doc-name interaction
|
|
17
|
-
* @doc-description Adds accessible disabled state to any element you compose it onto.
|
|
18
|
-
* @doc-is-main
|
|
19
|
-
*/
|
|
20
|
-
@Directive({
|
|
21
|
-
selector: '[kjDisabled]',
|
|
22
|
-
standalone: true,
|
|
23
|
-
host: {
|
|
24
|
-
'[attr.aria-disabled]': 'disabled() ? "true" : null',
|
|
25
|
-
'[attr.data-disabled]': 'disabled() ? "" : null',
|
|
26
|
-
},
|
|
27
|
-
})
|
|
28
|
-
export class KjDisabled {
|
|
29
|
-
/** Whether the element is disabled. Reflects via `aria-disabled` and `data-disabled`. */
|
|
30
|
-
readonly disabled = input<boolean, unknown>(false, { alias: 'kjDisabled', transform: booleanAttribute });
|
|
31
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { render, fireEvent } from '@testing-library/angular';
|
|
2
|
-
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
3
|
-
import { KjFocusRing } from './focus-ring';
|
|
4
|
-
|
|
5
|
-
expect.extend(toHaveNoViolations);
|
|
6
|
-
|
|
7
|
-
describe('KjFocusRing', () => {
|
|
8
|
-
it('adds data-focus-visible on focus when last interaction was keyboard', async () => {
|
|
9
|
-
const { container } = await render(
|
|
10
|
-
`<button kjFocusRing>Click me</button>`,
|
|
11
|
-
{ imports: [KjFocusRing] },
|
|
12
|
-
);
|
|
13
|
-
const btn = container.querySelector('button')!;
|
|
14
|
-
// No prior pointerdown — _lastWasPointer is false, so focus should be visible.
|
|
15
|
-
fireEvent.focus(btn);
|
|
16
|
-
expect(btn).toHaveAttribute('data-focus-visible', '');
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('does not add data-focus-visible on focus after pointer interaction', async () => {
|
|
20
|
-
const { container } = await render(
|
|
21
|
-
`<button kjFocusRing>Click me</button>`,
|
|
22
|
-
{ imports: [KjFocusRing] },
|
|
23
|
-
);
|
|
24
|
-
const btn = container.querySelector('button')!;
|
|
25
|
-
// Simulate pointer interaction, then focus.
|
|
26
|
-
fireEvent.pointerDown(document);
|
|
27
|
-
fireEvent.focus(btn);
|
|
28
|
-
expect(btn).not.toHaveAttribute('data-focus-visible');
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('removes data-focus-visible on blur', async () => {
|
|
32
|
-
const { container } = await render(
|
|
33
|
-
`<button kjFocusRing>Click me</button>`,
|
|
34
|
-
{ imports: [KjFocusRing] },
|
|
35
|
-
);
|
|
36
|
-
const btn = container.querySelector('button')!;
|
|
37
|
-
fireEvent.focus(btn);
|
|
38
|
-
fireEvent.blur(btn);
|
|
39
|
-
expect(btn).not.toHaveAttribute('data-focus-visible');
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('restores data-focus-visible after keydown followed by focus', async () => {
|
|
43
|
-
const { container } = await render(
|
|
44
|
-
`<button kjFocusRing>Click me</button>`,
|
|
45
|
-
{ imports: [KjFocusRing] },
|
|
46
|
-
);
|
|
47
|
-
const btn = container.querySelector('button')!;
|
|
48
|
-
// First simulate pointer (marks _lastWasPointer = true), then keyboard (resets it).
|
|
49
|
-
fireEvent.pointerDown(document);
|
|
50
|
-
fireEvent.keyDown(document);
|
|
51
|
-
fireEvent.focus(btn);
|
|
52
|
-
expect(btn).toHaveAttribute('data-focus-visible', '');
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('passes axe accessibility audit', async () => {
|
|
56
|
-
const { container } = await render(
|
|
57
|
-
`<button kjFocusRing>Click me</button>`,
|
|
58
|
-
{ imports: [KjFocusRing] },
|
|
59
|
-
);
|
|
60
|
-
expect(await axe(container)).toHaveNoViolations();
|
|
61
|
-
});
|
|
62
|
-
});
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { Directive, DestroyRef, ElementRef, afterNextRender, inject, signal } from '@angular/core';
|
|
2
|
-
import { PLATFORM_ID } from '@angular/core';
|
|
3
|
-
import { isPlatformBrowser } from '@angular/common';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Tracks focus-visible state using native PointerEvents and keyboard interaction.
|
|
7
|
-
* Sets `data-focus-visible` only when the element receives focus via keyboard.
|
|
8
|
-
* Compose via `hostDirectives` to add focus-ring behavior to interactive elements.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```html
|
|
12
|
-
* <button kjFocusRing>Focusable button</button>
|
|
13
|
-
* ```
|
|
14
|
-
* @doc-category Core/Primitives
|
|
15
|
-
* @doc
|
|
16
|
-
* @doc-name interaction
|
|
17
|
-
*/
|
|
18
|
-
@Directive({
|
|
19
|
-
selector: '[kjFocusRing]',
|
|
20
|
-
standalone: true,
|
|
21
|
-
host: {
|
|
22
|
-
'[attr.data-focus-visible]': 'focusVisible() ? "" : null',
|
|
23
|
-
},
|
|
24
|
-
})
|
|
25
|
-
export class KjFocusRing {
|
|
26
|
-
private readonly el = inject<ElementRef<HTMLElement>>(ElementRef);
|
|
27
|
-
private readonly destroyRef = inject(DestroyRef);
|
|
28
|
-
private readonly platformId = inject(PLATFORM_ID);
|
|
29
|
-
|
|
30
|
-
private readonly _focusVisible = signal(false);
|
|
31
|
-
|
|
32
|
-
/** Whether the element currently has visible focus (keyboard-initiated). */
|
|
33
|
-
readonly focusVisible = this._focusVisible.asReadonly();
|
|
34
|
-
|
|
35
|
-
private _lastWasPointer = false;
|
|
36
|
-
|
|
37
|
-
constructor() {
|
|
38
|
-
afterNextRender(() => {
|
|
39
|
-
if (!isPlatformBrowser(this.platformId)) return;
|
|
40
|
-
|
|
41
|
-
const onKeydown = () => { this._lastWasPointer = false; };
|
|
42
|
-
const onPointerdown = () => { this._lastWasPointer = true; };
|
|
43
|
-
const onFocus = () => { this._focusVisible.set(!this._lastWasPointer); };
|
|
44
|
-
const onBlur = () => { this._focusVisible.set(false); };
|
|
45
|
-
|
|
46
|
-
document.addEventListener('keydown', onKeydown, true);
|
|
47
|
-
document.addEventListener('pointerdown', onPointerdown, true);
|
|
48
|
-
this.el.nativeElement.addEventListener('focus', onFocus);
|
|
49
|
-
this.el.nativeElement.addEventListener('blur', onBlur);
|
|
50
|
-
|
|
51
|
-
this.destroyRef.onDestroy(() => {
|
|
52
|
-
document.removeEventListener('keydown', onKeydown, true);
|
|
53
|
-
document.removeEventListener('pointerdown', onPointerdown, true);
|
|
54
|
-
this.el.nativeElement.removeEventListener('focus', onFocus);
|
|
55
|
-
this.el.nativeElement.removeEventListener('blur', onBlur);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|