@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
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { render } from '@testing-library/angular';
|
|
2
|
-
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
3
|
-
import { vi } from 'vitest';
|
|
4
|
-
import { KjLiveRegion } from './live-region';
|
|
5
|
-
|
|
6
|
-
expect.extend(toHaveNoViolations);
|
|
7
|
-
|
|
8
|
-
describe('KjLiveRegion', () => {
|
|
9
|
-
it('sets aria-live to polite by default', async () => {
|
|
10
|
-
const { container } = await render(
|
|
11
|
-
`<div kjLiveRegion></div>`,
|
|
12
|
-
{ imports: [KjLiveRegion] },
|
|
13
|
-
);
|
|
14
|
-
expect(container.querySelector('div')).toHaveAttribute('aria-live', 'polite');
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('sets aria-live to assertive when specified', async () => {
|
|
18
|
-
const { container } = await render(
|
|
19
|
-
`<div kjLiveRegion [kjPoliteness]="'assertive'"></div>`,
|
|
20
|
-
{ imports: [KjLiveRegion] },
|
|
21
|
-
);
|
|
22
|
-
expect(container.querySelector('div')).toHaveAttribute('aria-live', 'assertive');
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('sets aria-atomic to true', async () => {
|
|
26
|
-
const { container } = await render(
|
|
27
|
-
`<div kjLiveRegion></div>`,
|
|
28
|
-
{ imports: [KjLiveRegion] },
|
|
29
|
-
);
|
|
30
|
-
expect(container.querySelector('div')).toHaveAttribute('aria-atomic', 'true');
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('announces a message via DOM text content after a brief timeout', async () => {
|
|
34
|
-
vi.useFakeTimers();
|
|
35
|
-
const { container } = await render(
|
|
36
|
-
`<div kjLiveRegion></div>`,
|
|
37
|
-
{ imports: [KjLiveRegion] },
|
|
38
|
-
);
|
|
39
|
-
const div = container.querySelector('div')!;
|
|
40
|
-
|
|
41
|
-
// Simulate the announce mechanism: clear, then set after 50ms.
|
|
42
|
-
div.textContent = '';
|
|
43
|
-
setTimeout(() => { div.textContent = 'Item saved'; }, 50);
|
|
44
|
-
|
|
45
|
-
vi.advanceTimersByTime(50);
|
|
46
|
-
expect(div.textContent).toBe('Item saved');
|
|
47
|
-
|
|
48
|
-
vi.useRealTimers();
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('passes axe accessibility audit', async () => {
|
|
52
|
-
const { container } = await render(
|
|
53
|
-
`<div kjLiveRegion></div>`,
|
|
54
|
-
{ imports: [KjLiveRegion] },
|
|
55
|
-
);
|
|
56
|
-
expect(await axe(container)).toHaveNoViolations();
|
|
57
|
-
});
|
|
58
|
-
});
|
package/src/a11y/live-region.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Directive, ElementRef, inject, input } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
/** Politeness setting for ARIA live regions. */
|
|
4
|
-
export type KjLivePoliteness = 'off' | 'polite' | 'assertive';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Marks an element as an ARIA live region and exposes an `announce` method
|
|
8
|
-
* for programmatically pushing announcements to screen readers via DOM text content.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```html
|
|
12
|
-
* <div kjLiveRegion [kjPoliteness]="'polite'" #region="kjLiveRegion"></div>
|
|
13
|
-
* <button (click)="region.announce('Item saved')">Save</button>
|
|
14
|
-
* ```
|
|
15
|
-
* @doc-category Core/Accessibility
|
|
16
|
-
* @doc
|
|
17
|
-
* @doc-name a11y
|
|
18
|
-
*/
|
|
19
|
-
@Directive({
|
|
20
|
-
selector: '[kjLiveRegion]',
|
|
21
|
-
standalone: true,
|
|
22
|
-
exportAs: 'kjLiveRegion',
|
|
23
|
-
host: {
|
|
24
|
-
'[attr.aria-live]': 'kjPoliteness()',
|
|
25
|
-
'[attr.aria-atomic]': '"true"',
|
|
26
|
-
},
|
|
27
|
-
})
|
|
28
|
-
export class KjLiveRegion {
|
|
29
|
-
private readonly el = inject(ElementRef<HTMLElement>);
|
|
30
|
-
|
|
31
|
-
/** The ARIA live politeness setting. Defaults to `'polite'`. */
|
|
32
|
-
kjPoliteness = input<KjLivePoliteness>('polite');
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Announces a message to screen readers by briefly clearing and re-setting text.
|
|
36
|
-
* @param message - The message to announce.
|
|
37
|
-
* @param durationMs - Optional duration in ms before clearing the announcement.
|
|
38
|
-
*/
|
|
39
|
-
announce(message: string, durationMs?: number): void {
|
|
40
|
-
const el = this.el.nativeElement;
|
|
41
|
-
el.textContent = '';
|
|
42
|
-
// Brief timeout lets screen readers detect the content change.
|
|
43
|
-
setTimeout(() => {
|
|
44
|
-
el.textContent = message;
|
|
45
|
-
if (durationMs != null) {
|
|
46
|
-
setTimeout(() => { el.textContent = ''; }, durationMs);
|
|
47
|
-
}
|
|
48
|
-
}, 50);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import { render, fireEvent } from '@testing-library/angular';
|
|
2
|
-
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
3
|
-
import {
|
|
4
|
-
KjRovingTabindex,
|
|
5
|
-
KjRovingTabindexItemDirective,
|
|
6
|
-
} from './roving-tabindex';
|
|
7
|
-
|
|
8
|
-
expect.extend(toHaveNoViolations);
|
|
9
|
-
|
|
10
|
-
const template = `
|
|
11
|
-
<div kjRovingTabindex role="toolbar" aria-label="Formatting">
|
|
12
|
-
<button kjRovingTabindexItem>Bold</button>
|
|
13
|
-
<button kjRovingTabindexItem>Italic</button>
|
|
14
|
-
<button kjRovingTabindexItem>Underline</button>
|
|
15
|
-
</div>`;
|
|
16
|
-
const imports = [KjRovingTabindex, KjRovingTabindexItemDirective];
|
|
17
|
-
|
|
18
|
-
describe('KjRovingTabindex', () => {
|
|
19
|
-
it('renders all items', async () => {
|
|
20
|
-
const { getAllByRole } = await render(template, { imports });
|
|
21
|
-
expect(getAllByRole('button')).toHaveLength(3);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('first item has tabindex 0, others -1', async () => {
|
|
25
|
-
const { getAllByRole } = await render(template, { imports });
|
|
26
|
-
const [first, second, third] = getAllByRole('button');
|
|
27
|
-
expect(first).toHaveAttribute('tabindex', '0');
|
|
28
|
-
expect(second).toHaveAttribute('tabindex', '-1');
|
|
29
|
-
expect(third).toHaveAttribute('tabindex', '-1');
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('moves focus right on ArrowRight', async () => {
|
|
33
|
-
const { getAllByRole, container } = await render(template, { imports });
|
|
34
|
-
const [first, second] = getAllByRole('button');
|
|
35
|
-
first.focus();
|
|
36
|
-
fireEvent.keyDown(container.querySelector('[kjRovingTabindex]')!, { key: 'ArrowRight' });
|
|
37
|
-
expect(second).toHaveAttribute('tabindex', '0');
|
|
38
|
-
expect(first).toHaveAttribute('tabindex', '-1');
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('moves focus left on ArrowLeft', async () => {
|
|
42
|
-
const { getAllByRole, container } = await render(template, { imports });
|
|
43
|
-
const [first, second] = getAllByRole('button');
|
|
44
|
-
second.focus();
|
|
45
|
-
fireEvent.keyDown(container.querySelector('[kjRovingTabindex]')!, { key: 'ArrowLeft' });
|
|
46
|
-
expect(first).toHaveAttribute('tabindex', '0');
|
|
47
|
-
expect(second).toHaveAttribute('tabindex', '-1');
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('wraps to last item on ArrowLeft from first', async () => {
|
|
51
|
-
const { getAllByRole, container } = await render(template, { imports });
|
|
52
|
-
const buttons = getAllByRole('button');
|
|
53
|
-
buttons[0].focus();
|
|
54
|
-
fireEvent.keyDown(container.querySelector('[kjRovingTabindex]')!, { key: 'ArrowLeft' });
|
|
55
|
-
expect(buttons[2]).toHaveAttribute('tabindex', '0');
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('passes axe accessibility audit', async () => {
|
|
59
|
-
const { container } = await render(template, { imports });
|
|
60
|
-
expect(await axe(container)).toHaveNoViolations();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
describe('kjRovingOrientation', () => {
|
|
64
|
-
const horizontalTemplate = `
|
|
65
|
-
<div kjRovingTabindex="" kjRovingOrientation="horizontal" role="toolbar" aria-label="Formatting">
|
|
66
|
-
<button kjRovingTabindexItem>Bold</button>
|
|
67
|
-
<button kjRovingTabindexItem>Italic</button>
|
|
68
|
-
<button kjRovingTabindexItem>Underline</button>
|
|
69
|
-
</div>`;
|
|
70
|
-
|
|
71
|
-
const verticalTemplate = `
|
|
72
|
-
<div kjRovingTabindex="" kjRovingOrientation="vertical" role="toolbar" aria-label="Formatting" aria-orientation="vertical">
|
|
73
|
-
<button kjRovingTabindexItem>Bold</button>
|
|
74
|
-
<button kjRovingTabindexItem>Italic</button>
|
|
75
|
-
<button kjRovingTabindexItem>Underline</button>
|
|
76
|
-
</div>`;
|
|
77
|
-
|
|
78
|
-
const bothTemplate = `
|
|
79
|
-
<div kjRovingTabindex="" kjRovingOrientation="both" role="toolbar" aria-label="Formatting">
|
|
80
|
-
<button kjRovingTabindexItem>Bold</button>
|
|
81
|
-
<button kjRovingTabindexItem>Italic</button>
|
|
82
|
-
<button kjRovingTabindexItem>Underline</button>
|
|
83
|
-
</div>`;
|
|
84
|
-
|
|
85
|
-
it('default orientation behaves like "both" (ArrowDown moves focus)', async () => {
|
|
86
|
-
const { getAllByRole, container } = await render(template, { imports });
|
|
87
|
-
const [first, second] = getAllByRole('button');
|
|
88
|
-
first.focus();
|
|
89
|
-
fireEvent.keyDown(container.querySelector('[kjRovingTabindex]')!, { key: 'ArrowDown' });
|
|
90
|
-
expect(second).toHaveAttribute('tabindex', '0');
|
|
91
|
-
expect(first).toHaveAttribute('tabindex', '-1');
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('horizontal: ArrowRight/ArrowLeft move focus', async () => {
|
|
95
|
-
const { getAllByRole, container } = await render(horizontalTemplate, { imports });
|
|
96
|
-
const [first, second, third] = getAllByRole('button');
|
|
97
|
-
first.focus();
|
|
98
|
-
const host = container.querySelector('[kjRovingTabindex]')!;
|
|
99
|
-
|
|
100
|
-
fireEvent.keyDown(host, { key: 'ArrowRight' });
|
|
101
|
-
expect(second).toHaveAttribute('tabindex', '0');
|
|
102
|
-
|
|
103
|
-
fireEvent.keyDown(host, { key: 'ArrowRight' });
|
|
104
|
-
expect(third).toHaveAttribute('tabindex', '0');
|
|
105
|
-
|
|
106
|
-
fireEvent.keyDown(host, { key: 'ArrowLeft' });
|
|
107
|
-
expect(second).toHaveAttribute('tabindex', '0');
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('horizontal: ArrowUp / ArrowDown are ignored', async () => {
|
|
111
|
-
const { getAllByRole, container } = await render(horizontalTemplate, { imports });
|
|
112
|
-
const [first, second, third] = getAllByRole('button');
|
|
113
|
-
first.focus();
|
|
114
|
-
const host = container.querySelector('[kjRovingTabindex]')!;
|
|
115
|
-
|
|
116
|
-
fireEvent.keyDown(host, { key: 'ArrowDown' });
|
|
117
|
-
expect(first).toHaveAttribute('tabindex', '0');
|
|
118
|
-
expect(second).toHaveAttribute('tabindex', '-1');
|
|
119
|
-
expect(third).toHaveAttribute('tabindex', '-1');
|
|
120
|
-
|
|
121
|
-
fireEvent.keyDown(host, { key: 'ArrowUp' });
|
|
122
|
-
expect(first).toHaveAttribute('tabindex', '0');
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it('vertical: ArrowDown / ArrowUp move focus', async () => {
|
|
126
|
-
const { getAllByRole, container } = await render(verticalTemplate, { imports });
|
|
127
|
-
const [first, second, third] = getAllByRole('button');
|
|
128
|
-
first.focus();
|
|
129
|
-
const host = container.querySelector('[kjRovingTabindex]')!;
|
|
130
|
-
|
|
131
|
-
fireEvent.keyDown(host, { key: 'ArrowDown' });
|
|
132
|
-
expect(second).toHaveAttribute('tabindex', '0');
|
|
133
|
-
|
|
134
|
-
fireEvent.keyDown(host, { key: 'ArrowDown' });
|
|
135
|
-
expect(third).toHaveAttribute('tabindex', '0');
|
|
136
|
-
|
|
137
|
-
fireEvent.keyDown(host, { key: 'ArrowUp' });
|
|
138
|
-
expect(second).toHaveAttribute('tabindex', '0');
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it('vertical: ArrowLeft / ArrowRight are ignored', async () => {
|
|
142
|
-
const { getAllByRole, container } = await render(verticalTemplate, { imports });
|
|
143
|
-
const [first, second, third] = getAllByRole('button');
|
|
144
|
-
first.focus();
|
|
145
|
-
const host = container.querySelector('[kjRovingTabindex]')!;
|
|
146
|
-
|
|
147
|
-
fireEvent.keyDown(host, { key: 'ArrowRight' });
|
|
148
|
-
expect(first).toHaveAttribute('tabindex', '0');
|
|
149
|
-
expect(second).toHaveAttribute('tabindex', '-1');
|
|
150
|
-
expect(third).toHaveAttribute('tabindex', '-1');
|
|
151
|
-
|
|
152
|
-
fireEvent.keyDown(host, { key: 'ArrowLeft' });
|
|
153
|
-
expect(first).toHaveAttribute('tabindex', '0');
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('both: all four arrow keys move focus', async () => {
|
|
157
|
-
const { getAllByRole, container } = await render(bothTemplate, { imports });
|
|
158
|
-
const [first, second, third] = getAllByRole('button');
|
|
159
|
-
first.focus();
|
|
160
|
-
const host = container.querySelector('[kjRovingTabindex]')!;
|
|
161
|
-
|
|
162
|
-
fireEvent.keyDown(host, { key: 'ArrowRight' });
|
|
163
|
-
expect(second).toHaveAttribute('tabindex', '0');
|
|
164
|
-
|
|
165
|
-
fireEvent.keyDown(host, { key: 'ArrowDown' });
|
|
166
|
-
expect(third).toHaveAttribute('tabindex', '0');
|
|
167
|
-
|
|
168
|
-
fireEvent.keyDown(host, { key: 'ArrowLeft' });
|
|
169
|
-
expect(second).toHaveAttribute('tabindex', '0');
|
|
170
|
-
|
|
171
|
-
fireEvent.keyDown(host, { key: 'ArrowUp' });
|
|
172
|
-
expect(first).toHaveAttribute('tabindex', '0');
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it('horizontal under dir="rtl": ArrowLeft moves forward, ArrowRight moves backward', async () => {
|
|
176
|
-
const rtlTemplate = `
|
|
177
|
-
<div dir="rtl">
|
|
178
|
-
<div kjRovingTabindex="" kjRovingOrientation="horizontal" role="toolbar" aria-label="Formatting">
|
|
179
|
-
<button kjRovingTabindexItem>Bold</button>
|
|
180
|
-
<button kjRovingTabindexItem>Italic</button>
|
|
181
|
-
<button kjRovingTabindexItem>Underline</button>
|
|
182
|
-
</div>
|
|
183
|
-
</div>`;
|
|
184
|
-
|
|
185
|
-
const { getAllByRole, container } = await render(rtlTemplate, { imports });
|
|
186
|
-
const [first, second, third] = getAllByRole('button');
|
|
187
|
-
first.focus();
|
|
188
|
-
const host = container.querySelector('[kjRovingTabindex]')!;
|
|
189
|
-
|
|
190
|
-
fireEvent.keyDown(host, { key: 'ArrowLeft' });
|
|
191
|
-
expect(second).toHaveAttribute('tabindex', '0');
|
|
192
|
-
expect(first).toHaveAttribute('tabindex', '-1');
|
|
193
|
-
|
|
194
|
-
fireEvent.keyDown(host, { key: 'ArrowLeft' });
|
|
195
|
-
expect(third).toHaveAttribute('tabindex', '0');
|
|
196
|
-
|
|
197
|
-
fireEvent.keyDown(host, { key: 'ArrowRight' });
|
|
198
|
-
expect(second).toHaveAttribute('tabindex', '0');
|
|
199
|
-
});
|
|
200
|
-
});
|
|
201
|
-
});
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Directive,
|
|
3
|
-
ElementRef,
|
|
4
|
-
InjectionToken,
|
|
5
|
-
contentChildren,
|
|
6
|
-
effect,
|
|
7
|
-
forwardRef,
|
|
8
|
-
inject,
|
|
9
|
-
input,
|
|
10
|
-
signal,
|
|
11
|
-
} from '@angular/core';
|
|
12
|
-
|
|
13
|
-
/** Context token for roving tabindex coordination. */
|
|
14
|
-
export const KJ_ROVING_TABINDEX = new InjectionToken<KjRovingTabindex>(
|
|
15
|
-
'KjRovingTabindex',
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Marks an individual item within a `[kjRovingTabindex]` container.
|
|
20
|
-
* Its `tabindex` is managed automatically by the parent directive.
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```html
|
|
24
|
-
* <button kjRovingTabindexItem>Item</button>
|
|
25
|
-
* ```
|
|
26
|
-
* @doc-category Core/Accessibility
|
|
27
|
-
* @doc
|
|
28
|
-
* @doc-name a11y
|
|
29
|
-
*/
|
|
30
|
-
@Directive({
|
|
31
|
-
selector: '[kjRovingTabindexItem]',
|
|
32
|
-
standalone: true,
|
|
33
|
-
host: {
|
|
34
|
-
'[attr.tabindex]': 'active() ? "0" : "-1"',
|
|
35
|
-
},
|
|
36
|
-
})
|
|
37
|
-
export class KjRovingTabindexItemDirective {
|
|
38
|
-
/** @internal */
|
|
39
|
-
readonly el = inject(ElementRef<HTMLElement>);
|
|
40
|
-
/** @internal */
|
|
41
|
-
readonly active = signal(false);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Implements the roving tabindex pattern for composite widgets such as toolbars and tab lists.
|
|
46
|
-
* Only one item has `tabindex="0"` at a time; arrow keys move focus between items.
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```html
|
|
50
|
-
* <div kjRovingTabindex role="toolbar" aria-label="Formatting">
|
|
51
|
-
* <button kjRovingTabindexItem>Bold</button>
|
|
52
|
-
* <button kjRovingTabindexItem>Italic</button>
|
|
53
|
-
* </div>
|
|
54
|
-
* ```
|
|
55
|
-
* @doc-category Core/Accessibility
|
|
56
|
-
* @doc
|
|
57
|
-
* @doc-name a11y
|
|
58
|
-
*/
|
|
59
|
-
@Directive({
|
|
60
|
-
selector: '[kjRovingTabindex]',
|
|
61
|
-
standalone: true,
|
|
62
|
-
providers: [{ provide: KJ_ROVING_TABINDEX, useExisting: forwardRef(() => KjRovingTabindex) }],
|
|
63
|
-
host: {
|
|
64
|
-
'(keydown)': 'onKeydown($event)',
|
|
65
|
-
'(focusin)': 'onFocusIn($event)',
|
|
66
|
-
},
|
|
67
|
-
})
|
|
68
|
-
export class KjRovingTabindex {
|
|
69
|
-
private readonly host = inject(ElementRef<HTMLElement>);
|
|
70
|
-
private readonly items = contentChildren(KjRovingTabindexItemDirective, {
|
|
71
|
-
descendants: true,
|
|
72
|
-
});
|
|
73
|
-
private readonly activeIndex = signal(0);
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Restricts arrow-key navigation to a single axis.
|
|
77
|
-
* - `'horizontal'`: only ArrowLeft / ArrowRight move focus.
|
|
78
|
-
* - `'vertical'`: only ArrowUp / ArrowDown move focus.
|
|
79
|
-
* - `'both'`: all four arrow keys move focus (default — preserves prior behaviour).
|
|
80
|
-
*
|
|
81
|
-
* Under `'horizontal'`, ArrowLeft / ArrowRight are swapped when the host
|
|
82
|
-
* element resolves to `dir="rtl"`.
|
|
83
|
-
*/
|
|
84
|
-
readonly kjRovingOrientation = input<'horizontal' | 'vertical' | 'both'>('both');
|
|
85
|
-
|
|
86
|
-
constructor() {
|
|
87
|
-
effect(() => {
|
|
88
|
-
const all = this.items();
|
|
89
|
-
all.forEach((item, i) => item.active.set(i === this.activeIndex()));
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
private resolveRtl(): boolean {
|
|
94
|
-
const el = this.host.nativeElement;
|
|
95
|
-
if (typeof getComputedStyle === 'function') {
|
|
96
|
-
const direction = getComputedStyle(el).direction;
|
|
97
|
-
if (direction === 'rtl') return true;
|
|
98
|
-
if (direction === 'ltr') {
|
|
99
|
-
// Some test environments (jsdom) return the default 'ltr' even when an
|
|
100
|
-
// ancestor sets `dir="rtl"`. Fall through to attribute lookup.
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
const dirHost = el.closest('[dir]') as HTMLElement | null;
|
|
104
|
-
return dirHost?.dir.toLowerCase() === 'rtl';
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/** @internal — syncs activeIndex when focus moves into an item programmatically */
|
|
108
|
-
onFocusIn(event: FocusEvent): void {
|
|
109
|
-
const all = this.items();
|
|
110
|
-
const idx = all.findIndex((item) => item.el.nativeElement === event.target);
|
|
111
|
-
if (idx !== -1) {
|
|
112
|
-
this.activeIndex.set(idx);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/** @internal */
|
|
117
|
-
onKeydown(event: KeyboardEvent): void {
|
|
118
|
-
const all = this.items();
|
|
119
|
-
if (!all.length) return;
|
|
120
|
-
let next = this.activeIndex();
|
|
121
|
-
|
|
122
|
-
const orientation = this.kjRovingOrientation();
|
|
123
|
-
const horizontalActive = orientation === 'horizontal' || orientation === 'both';
|
|
124
|
-
const verticalActive = orientation === 'vertical' || orientation === 'both';
|
|
125
|
-
|
|
126
|
-
// Resolve directionality lazily; only matters when horizontal arrows are active.
|
|
127
|
-
// Prefer computed style; fall back to the nearest `dir` attribute (jsdom does
|
|
128
|
-
// not propagate ancestor `dir` to computed style in all cases).
|
|
129
|
-
const isRtl = horizontalActive && this.resolveRtl();
|
|
130
|
-
const forwardKey = isRtl ? 'ArrowLeft' : 'ArrowRight';
|
|
131
|
-
const backwardKey = isRtl ? 'ArrowRight' : 'ArrowLeft';
|
|
132
|
-
|
|
133
|
-
if (horizontalActive && event.key === forwardKey) {
|
|
134
|
-
next = (next + 1) % all.length;
|
|
135
|
-
} else if (horizontalActive && event.key === backwardKey) {
|
|
136
|
-
next = (next - 1 + all.length) % all.length;
|
|
137
|
-
} else if (verticalActive && event.key === 'ArrowDown') {
|
|
138
|
-
next = (next + 1) % all.length;
|
|
139
|
-
} else if (verticalActive && event.key === 'ArrowUp') {
|
|
140
|
-
next = (next - 1 + all.length) % all.length;
|
|
141
|
-
} else if (event.key === 'Home') {
|
|
142
|
-
next = 0;
|
|
143
|
-
} else if (event.key === 'End') {
|
|
144
|
-
next = all.length - 1;
|
|
145
|
-
} else {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
event.preventDefault();
|
|
150
|
-
this.activeIndex.set(next);
|
|
151
|
-
all[next].el.nativeElement.focus();
|
|
152
|
-
}
|
|
153
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { render } from '@testing-library/angular';
|
|
2
|
-
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
3
|
-
import { KjVisuallyHidden } from './visually-hidden';
|
|
4
|
-
|
|
5
|
-
expect.extend(toHaveNoViolations);
|
|
6
|
-
|
|
7
|
-
describe('KjVisuallyHidden', () => {
|
|
8
|
-
it('applies visually-hidden inline styles', async () => {
|
|
9
|
-
const { container } = await render(
|
|
10
|
-
`<span kjVisuallyHidden>Screen reader only</span>`,
|
|
11
|
-
{ imports: [KjVisuallyHidden] },
|
|
12
|
-
);
|
|
13
|
-
const el = container.querySelector('span')!;
|
|
14
|
-
const style = el.getAttribute('style') ?? '';
|
|
15
|
-
expect(style).toContain('position');
|
|
16
|
-
expect(style).toContain('absolute');
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('content remains in the DOM for screen readers', async () => {
|
|
20
|
-
const { getByText } = await render(
|
|
21
|
-
`<span kjVisuallyHidden>Screen reader only</span>`,
|
|
22
|
-
{ imports: [KjVisuallyHidden] },
|
|
23
|
-
);
|
|
24
|
-
expect(getByText('Screen reader only')).toBeInTheDocument();
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('passes axe accessibility audit', async () => {
|
|
28
|
-
const { container } = await render(
|
|
29
|
-
`<button><span kjVisuallyHidden>Close dialog</span></button>`,
|
|
30
|
-
{ imports: [KjVisuallyHidden] },
|
|
31
|
-
);
|
|
32
|
-
expect(await axe(container)).toHaveNoViolations();
|
|
33
|
-
});
|
|
34
|
-
});
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { Directive } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Visually hides an element while keeping it accessible to screen readers.
|
|
5
|
-
* Uses the standard visually-hidden CSS technique via inline styles.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```html
|
|
9
|
-
* <button>
|
|
10
|
-
* <kj-icon name="close" />
|
|
11
|
-
* <span kjVisuallyHidden>Close dialog</span>
|
|
12
|
-
* </button>
|
|
13
|
-
* ```
|
|
14
|
-
* @doc-category Core/Accessibility
|
|
15
|
-
* @doc
|
|
16
|
-
* @doc-name a11y
|
|
17
|
-
*/
|
|
18
|
-
@Directive({
|
|
19
|
-
selector: '[kjVisuallyHidden]',
|
|
20
|
-
standalone: true,
|
|
21
|
-
host: {
|
|
22
|
-
style:
|
|
23
|
-
'position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0',
|
|
24
|
-
},
|
|
25
|
-
})
|
|
26
|
-
export class KjVisuallyHidden {}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { InjectionToken, Signal } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
/** Accordion mode: `'single'` (one item open at a time) or `'multiple'` (any number open). */
|
|
4
|
-
export type KjAccordionType = 'single' | 'multiple';
|
|
5
|
-
|
|
6
|
-
/** Context interface for the root accordion directive. */
|
|
7
|
-
export interface KjAccordionContext {
|
|
8
|
-
/** Set of currently open item values. */
|
|
9
|
-
readonly openIds: Signal<ReadonlySet<string>>;
|
|
10
|
-
/** Current mode: single or multiple. */
|
|
11
|
-
readonly type: Signal<KjAccordionType>;
|
|
12
|
-
/** Whether opt-in arrow-key roving navigation is enabled. */
|
|
13
|
-
readonly arrowNavigation: Signal<boolean>;
|
|
14
|
-
/** Toggle an item by its string value. In single mode, closes others first. */
|
|
15
|
-
toggle(id: string): void;
|
|
16
|
-
/** Whether the given item value is currently open. */
|
|
17
|
-
isOpen(id: string): boolean;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** Context interface for an individual accordion item directive. */
|
|
21
|
-
export interface KjAccordionItemContext {
|
|
22
|
-
/** Stable string value identifying the item within the parent accordion. */
|
|
23
|
-
readonly value: Signal<string>;
|
|
24
|
-
/** Whether this item is currently expanded. */
|
|
25
|
-
readonly expanded: Signal<boolean>;
|
|
26
|
-
/** Whether this item is disabled (toggle is a no-op, trigger announces aria-disabled). */
|
|
27
|
-
readonly disabled: Signal<boolean>;
|
|
28
|
-
/** Stable id for the trigger element — `aria-labelledby` target on the content region. */
|
|
29
|
-
readonly headerId: Signal<string>;
|
|
30
|
-
/** Stable id for the content region — `aria-controls` target on the trigger. */
|
|
31
|
-
readonly contentId: Signal<string>;
|
|
32
|
-
/** Toggle this item's expanded state. No-op when disabled. */
|
|
33
|
-
toggle(): void;
|
|
34
|
-
/** Open this item. No-op when disabled. */
|
|
35
|
-
open(): void;
|
|
36
|
-
/** Close this item. No-op when disabled. */
|
|
37
|
-
close(): void;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** Injection token for the root accordion directive. */
|
|
41
|
-
export const KJ_ACCORDION = new InjectionToken<KjAccordionContext>('KjAccordion');
|
|
42
|
-
|
|
43
|
-
/** Injection token for an individual accordion item directive. */
|
|
44
|
-
export const KJ_ACCORDION_ITEM = new InjectionToken<KjAccordionItemContext>('KjAccordionItem');
|