@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,90 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Directive,
|
|
3
|
-
ElementRef,
|
|
4
|
-
afterNextRender,
|
|
5
|
-
computed,
|
|
6
|
-
inject,
|
|
7
|
-
} from '@angular/core';
|
|
8
|
-
import { KjFocusRing } from '../primitives';
|
|
9
|
-
import { KjVariant, KjSize } from '../presets';
|
|
10
|
-
import { KJ_PAGINATION } from './pagination.context';
|
|
11
|
-
import { KJ_PAGINATION_CONFIG } from './config';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Boundary control that retreats one page. Disabled (via `aria-disabled`,
|
|
15
|
-
* not the native `disabled` attribute) when the parent is on the first
|
|
16
|
-
* page or the dataset is empty. Stays in the focus ring even when
|
|
17
|
-
* disabled (`tabindex="0"`) — matches Button's `disabledInteractive`
|
|
18
|
-
* stance so AT users discover the control and learn it is currently
|
|
19
|
-
* inactive (kouji's WCAG 2.1 AAA stance).
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```html
|
|
23
|
-
* <button kjButton kjPaginationPrevious>Previous</button>
|
|
24
|
-
* ```
|
|
25
|
-
*
|
|
26
|
-
* @doc-category Core/Navigation
|
|
27
|
-
* @doc
|
|
28
|
-
* @doc-name pagination
|
|
29
|
-
*/
|
|
30
|
-
@Directive({
|
|
31
|
-
selector: '[kjPaginationPrevious]',
|
|
32
|
-
standalone: true,
|
|
33
|
-
hostDirectives: [
|
|
34
|
-
{ directive: KjVariant, inputs: ['kjVariant'] },
|
|
35
|
-
{ directive: KjSize, inputs: ['kjSize'] },
|
|
36
|
-
KjFocusRing,
|
|
37
|
-
],
|
|
38
|
-
host: {
|
|
39
|
-
'[attr.aria-label]': 'config.previousLabel',
|
|
40
|
-
'[attr.aria-disabled]': 'isDisabled() ? "true" : null',
|
|
41
|
-
'[attr.data-disabled]': 'isDisabled() ? "" : null',
|
|
42
|
-
'[attr.tabindex]': '"0"',
|
|
43
|
-
'[attr.data-pagination-action]': '"previous"',
|
|
44
|
-
'(click)': 'onClick($event)',
|
|
45
|
-
},
|
|
46
|
-
})
|
|
47
|
-
export class KjPaginationPrevious {
|
|
48
|
-
/** @internal */
|
|
49
|
-
readonly pagination = inject(KJ_PAGINATION);
|
|
50
|
-
/** @internal */
|
|
51
|
-
readonly config = inject(KJ_PAGINATION_CONFIG);
|
|
52
|
-
private readonly el = inject<ElementRef<HTMLElement>>(ElementRef);
|
|
53
|
-
|
|
54
|
-
/** True when the parent is on page 1 or the dataset is empty. */
|
|
55
|
-
readonly isDisabled = computed(() => this.pagination.isFirstPage());
|
|
56
|
-
|
|
57
|
-
constructor() {
|
|
58
|
-
// Capture-phase listeners fire before any consumer template-bound
|
|
59
|
-
// (click) / (keydown) handler and before native button activation,
|
|
60
|
-
// so the suppression actually prevents downstream navigation.
|
|
61
|
-
afterNextRender(() => {
|
|
62
|
-
const node = this.el.nativeElement;
|
|
63
|
-
const block = (event: Event) => {
|
|
64
|
-
if (this.isDisabled()) {
|
|
65
|
-
event.preventDefault();
|
|
66
|
-
event.stopImmediatePropagation();
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
const blockKey = (event: KeyboardEvent) => {
|
|
70
|
-
if (!this.isDisabled()) return;
|
|
71
|
-
if (event.key === 'Enter' || event.key === ' ' || event.key === 'Spacebar') {
|
|
72
|
-
event.preventDefault();
|
|
73
|
-
event.stopImmediatePropagation();
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
node.addEventListener('click', block, { capture: true });
|
|
77
|
-
node.addEventListener('keydown', blockKey, { capture: true });
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** @internal */
|
|
82
|
-
onClick(event: Event): void {
|
|
83
|
-
if (this.isDisabled()) {
|
|
84
|
-
event.preventDefault();
|
|
85
|
-
event.stopImmediatePropagation();
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
this.pagination.goToPrevious();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { InjectionToken, Signal } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* A single token in the windowed page list produced by the page-token
|
|
5
|
-
* algorithm. Numeric tokens render as page buttons (`KjPaginationItem`);
|
|
6
|
-
* the two `'ellipsis-*'` variants are rendered as a `KjPaginationEllipsis`
|
|
7
|
-
* gap indicator. The two ellipsis variants are kept distinct so Angular's
|
|
8
|
-
* `@for (… ; track token)` can build stable, collision-free tracks.
|
|
9
|
-
*/
|
|
10
|
-
export type KjPageToken = number | 'ellipsis-left' | 'ellipsis-right';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Context exposed by `KjPagination` to its child directives
|
|
14
|
-
* (`KjPaginationItem`, `KjPaginationPrevious`, `KjPaginationNext`,
|
|
15
|
-
* `KjPaginationFirst`, `KjPaginationLast`, `KjPaginationEllipsis`,
|
|
16
|
-
* `KjPaginationInfo`). Holds the page state, the algorithm output, the
|
|
17
|
-
* boundary computeds, and the imperative navigation methods.
|
|
18
|
-
*
|
|
19
|
-
* Children are stateless reflectors of the root's state — every
|
|
20
|
-
* derivation lives here so a single source of truth drives ARIA wiring,
|
|
21
|
-
* `data-current` / `data-disabled` reflection, and the live-region
|
|
22
|
-
* announcement.
|
|
23
|
-
*/
|
|
24
|
-
export interface KjPaginationContext {
|
|
25
|
-
/** Current page (1-indexed). */
|
|
26
|
-
readonly page: Signal<number>;
|
|
27
|
-
/** Total number of pages. May be `0` (empty dataset). */
|
|
28
|
-
readonly totalPages: Signal<number>;
|
|
29
|
-
/** Output of the windowed page-token algorithm. */
|
|
30
|
-
readonly pages: Signal<readonly KjPageToken[]>;
|
|
31
|
-
/** True when the current page is `1` or the dataset is empty. */
|
|
32
|
-
readonly isFirstPage: Signal<boolean>;
|
|
33
|
-
/** True when the current page is `totalPages` or the dataset is empty. */
|
|
34
|
-
readonly isLastPage: Signal<boolean>;
|
|
35
|
-
/** Cascaded variant for children that did not set their own. */
|
|
36
|
-
readonly variant: Signal<string>;
|
|
37
|
-
/** Cascaded size for children that did not set their own. */
|
|
38
|
-
readonly size: Signal<string>;
|
|
39
|
-
/** Jump to a specific page (1-indexed); clamps to `[1, totalPages]`. */
|
|
40
|
-
goToPage(page: number): void;
|
|
41
|
-
/** Jump to page 1. No-op when already on page 1 / empty dataset. */
|
|
42
|
-
goToFirst(): void;
|
|
43
|
-
/** Jump to the last page. No-op when already there / empty dataset. */
|
|
44
|
-
goToLast(): void;
|
|
45
|
-
/** Advance one page. No-op when on the last page. */
|
|
46
|
-
goToNext(): void;
|
|
47
|
-
/** Retreat one page. No-op when on the first page. */
|
|
48
|
-
goToPrevious(): void;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** Injection token for the root `KjPagination` directive context. */
|
|
52
|
-
export const KJ_PAGINATION = new InjectionToken<KjPaginationContext>('KjPagination');
|
|
@@ -1,388 +0,0 @@
|
|
|
1
|
-
import { Component, signal, ChangeDetectionStrategy } from '@angular/core';
|
|
2
|
-
import { fireEvent, render } from '@testing-library/angular';
|
|
3
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
4
|
-
import { KjPagination } from './pagination';
|
|
5
|
-
import { KjPaginationItem } from './pagination-item';
|
|
6
|
-
import { KjPaginationPrevious } from './pagination-previous';
|
|
7
|
-
import { KjPaginationNext } from './pagination-next';
|
|
8
|
-
import { KjPaginationFirst } from './pagination-first';
|
|
9
|
-
import { KjPaginationLast } from './pagination-last';
|
|
10
|
-
import { KjPaginationEllipsis } from './pagination-ellipsis';
|
|
11
|
-
import { KjPaginationInfo } from './pagination-info';
|
|
12
|
-
import { computePageTokens } from './page-tokens';
|
|
13
|
-
|
|
14
|
-
const imports = [
|
|
15
|
-
KjPagination,
|
|
16
|
-
KjPaginationItem,
|
|
17
|
-
KjPaginationPrevious,
|
|
18
|
-
KjPaginationNext,
|
|
19
|
-
KjPaginationFirst,
|
|
20
|
-
KjPaginationLast,
|
|
21
|
-
KjPaginationEllipsis,
|
|
22
|
-
KjPaginationInfo,
|
|
23
|
-
];
|
|
24
|
-
|
|
25
|
-
@Component({
|
|
26
|
-
standalone: true,
|
|
27
|
-
imports,
|
|
28
|
-
changeDetection: ChangeDetectionStrategy.Eager,
|
|
29
|
-
template: `
|
|
30
|
-
<nav kjPagination [(kjPage)]="page" [kjTotalPages]="totalPages()" #p="kjPagination">
|
|
31
|
-
<button kjPaginationFirst>«</button>
|
|
32
|
-
<button kjPaginationPrevious>‹</button>
|
|
33
|
-
@for (token of p.pages(); track token) {
|
|
34
|
-
@if (token === 'ellipsis-left' || token === 'ellipsis-right') {
|
|
35
|
-
<span kjPaginationEllipsis>…</span>
|
|
36
|
-
} @else {
|
|
37
|
-
<button kjPaginationItem [kjPage]="token">{{ token }}</button>
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
<button kjPaginationNext>›</button>
|
|
41
|
-
<button kjPaginationLast>»</button>
|
|
42
|
-
<span kjPaginationInfo></span>
|
|
43
|
-
</nav>
|
|
44
|
-
`,
|
|
45
|
-
})
|
|
46
|
-
class PaginationHost {
|
|
47
|
-
readonly page = signal(1);
|
|
48
|
-
readonly totalPages = signal(10);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
@Component({
|
|
52
|
-
standalone: true,
|
|
53
|
-
imports,
|
|
54
|
-
changeDetection: ChangeDetectionStrategy.Eager,
|
|
55
|
-
template: `
|
|
56
|
-
<nav kjPagination [(kjPage)]="page" [kjTotalPages]="totalPages()" #p="kjPagination">
|
|
57
|
-
@for (token of p.pages(); track token) {
|
|
58
|
-
@if (token !== 'ellipsis-left' && token !== 'ellipsis-right') {
|
|
59
|
-
<button kjPaginationItem [kjPage]="token">{{ token }}</button>
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
</nav>
|
|
63
|
-
`,
|
|
64
|
-
})
|
|
65
|
-
class SmallPaginationHost {
|
|
66
|
-
readonly page = signal(1);
|
|
67
|
-
readonly totalPages = signal(3);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
describe('computePageTokens (algorithm)', () => {
|
|
71
|
-
describe('edge cases', () => {
|
|
72
|
-
it('returns [] when total <= 0', () => {
|
|
73
|
-
expect(computePageTokens(1, 0, 1, 1)).toEqual([]);
|
|
74
|
-
expect(computePageTokens(1, -5, 1, 1)).toEqual([]);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('renders all pages with no ellipses when total fits in the window', () => {
|
|
78
|
-
// boundary*2 + siblings*2 + 3 = 1*2 + 1*2 + 3 = 7 — total <= 7 fits.
|
|
79
|
-
expect(computePageTokens(1, 1, 1, 1)).toEqual([1]);
|
|
80
|
-
expect(computePageTokens(2, 5, 1, 1)).toEqual([1, 2, 3, 4, 5]);
|
|
81
|
-
expect(computePageTokens(4, 7, 1, 1)).toEqual([1, 2, 3, 4, 5, 6, 7]);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
describe('large datasets — current near start', () => {
|
|
86
|
-
it('total=10, current=1: only right ellipsis (sibling window collapses to filler)', () => {
|
|
87
|
-
// With current=1 and siblings=1, the sibling window would span [0,2]
|
|
88
|
-
// but is clamped at the boundary anchor (page 1) — only `2` is added
|
|
89
|
-
// by the !showLeftEllipsis filler branch. The right ellipsis bridges
|
|
90
|
-
// to the right boundary.
|
|
91
|
-
expect(computePageTokens(1, 10, 1, 1)).toEqual([1, 2, 'ellipsis-right', 10]);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('total=10, current=2: only right ellipsis', () => {
|
|
95
|
-
expect(computePageTokens(2, 10, 1, 1)).toEqual([1, 2, 3, 'ellipsis-right', 10]);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('total=10, current=3: only right ellipsis', () => {
|
|
99
|
-
expect(computePageTokens(3, 10, 1, 1)).toEqual([1, 2, 3, 4, 'ellipsis-right', 10]);
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
describe('large datasets — current near end', () => {
|
|
104
|
-
it('total=10, current=10: only left ellipsis (sibling window clamps at boundary)', () => {
|
|
105
|
-
// Mirror of the current=1 case — the sibling window is clamped at
|
|
106
|
-
// the right boundary anchor, leaving the !showRightEllipsis filler
|
|
107
|
-
// branch to push `9` and the left ellipsis to bridge.
|
|
108
|
-
expect(computePageTokens(10, 10, 1, 1)).toEqual([1, 'ellipsis-left', 9, 10]);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('total=10, current=9: only left ellipsis', () => {
|
|
112
|
-
expect(computePageTokens(9, 10, 1, 1)).toEqual([1, 'ellipsis-left', 8, 9, 10]);
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it('total=10, current=8: only left ellipsis', () => {
|
|
116
|
-
expect(computePageTokens(8, 10, 1, 1)).toEqual([1, 'ellipsis-left', 7, 8, 9, 10]);
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
describe('large datasets — current in the middle', () => {
|
|
121
|
-
it('total=10, current=5: both ellipses', () => {
|
|
122
|
-
expect(computePageTokens(5, 10, 1, 1)).toEqual([
|
|
123
|
-
1,
|
|
124
|
-
'ellipsis-left',
|
|
125
|
-
4,
|
|
126
|
-
5,
|
|
127
|
-
6,
|
|
128
|
-
'ellipsis-right',
|
|
129
|
-
10,
|
|
130
|
-
]);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it('total=20, current=10, siblings=2, boundary=2: both ellipses', () => {
|
|
134
|
-
expect(computePageTokens(10, 20, 2, 2)).toEqual([
|
|
135
|
-
1,
|
|
136
|
-
2,
|
|
137
|
-
'ellipsis-left',
|
|
138
|
-
8,
|
|
139
|
-
9,
|
|
140
|
-
10,
|
|
141
|
-
11,
|
|
142
|
-
12,
|
|
143
|
-
'ellipsis-right',
|
|
144
|
-
19,
|
|
145
|
-
20,
|
|
146
|
-
]);
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
describe('off-by-one sweep across totals 7–11', () => {
|
|
151
|
-
it.each([7, 8, 9, 10, 11])(
|
|
152
|
-
'total=%i: every current 1..total produces a stable, well-formed token list',
|
|
153
|
-
(total) => {
|
|
154
|
-
for (let current = 1; current <= total; current++) {
|
|
155
|
-
const tokens = computePageTokens(current, total, 1, 1);
|
|
156
|
-
// Always starts with 1 when boundary>=1.
|
|
157
|
-
expect(tokens[0]).toBe(1);
|
|
158
|
-
// Always ends with total when boundary>=1.
|
|
159
|
-
expect(tokens[tokens.length - 1]).toBe(total);
|
|
160
|
-
// The current page number always appears as a numeric token.
|
|
161
|
-
expect(tokens.includes(current)).toBe(true);
|
|
162
|
-
// Numeric tokens are strictly ascending.
|
|
163
|
-
const numerics = tokens.filter((t): t is number => typeof t === 'number');
|
|
164
|
-
for (let i = 1; i < numerics.length; i++) {
|
|
165
|
-
expect(numerics[i]).toBeGreaterThan(numerics[i - 1]);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
},
|
|
169
|
-
);
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
describe('degenerate inputs', () => {
|
|
173
|
-
it('siblings=0, boundary=0, total=10, current=5: collapses to current only', () => {
|
|
174
|
-
// No boundary anchors, no sibling neighbors — just the current with
|
|
175
|
-
// ellipses bridging on each side.
|
|
176
|
-
const tokens = computePageTokens(5, 10, 0, 0);
|
|
177
|
-
expect(tokens).toContain(5);
|
|
178
|
-
// No `1` or `10` because boundary=0.
|
|
179
|
-
expect(tokens.includes(1)).toBe(false);
|
|
180
|
-
expect(tokens.includes(10)).toBe(false);
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
describe('KjPagination — directive integration', () => {
|
|
186
|
-
describe('host wiring', () => {
|
|
187
|
-
it('hosts <nav> with aria-label="Pagination" by default', async () => {
|
|
188
|
-
const { container } = await render(PaginationHost);
|
|
189
|
-
const nav = container.querySelector('[kjPagination]')!;
|
|
190
|
-
expect(nav.tagName).toBe('NAV');
|
|
191
|
-
expect(nav).toHaveAttribute('aria-label', 'Pagination');
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it('reflects current page and total via data attributes', async () => {
|
|
195
|
-
const { container } = await render(PaginationHost);
|
|
196
|
-
const nav = container.querySelector('[kjPagination]')!;
|
|
197
|
-
expect(nav).toHaveAttribute('data-page', '1');
|
|
198
|
-
expect(nav).toHaveAttribute('data-total-pages', '10');
|
|
199
|
-
});
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
describe('aria-current on the active item', () => {
|
|
203
|
-
it('marks the current page item with aria-current="page" and data-current="true"', async () => {
|
|
204
|
-
const { container, fixture } = await render(PaginationHost);
|
|
205
|
-
// Initial page = 1.
|
|
206
|
-
const items = container.querySelectorAll<HTMLElement>('[kjPaginationItem]');
|
|
207
|
-
const first = Array.from(items).find((b) => b.textContent?.trim() === '1')!;
|
|
208
|
-
expect(first).toHaveAttribute('aria-current', 'page');
|
|
209
|
-
expect(first).toHaveAttribute('data-current', 'true');
|
|
210
|
-
|
|
211
|
-
// Move to page 3. With totalPages=10, siblings=1, boundary=1, current=3
|
|
212
|
-
// the window is [1, 2, 3, 4, 'ellipsis-right', 10] — page 3 is rendered.
|
|
213
|
-
(fixture.componentInstance as PaginationHost).page.set(3);
|
|
214
|
-
fixture.detectChanges();
|
|
215
|
-
const updated = container.querySelectorAll<HTMLElement>('[kjPaginationItem]');
|
|
216
|
-
const three = Array.from(updated).find((b) => b.textContent?.trim() === '3')!;
|
|
217
|
-
expect(three).toHaveAttribute('aria-current', 'page');
|
|
218
|
-
expect(three).toHaveAttribute('data-current', 'true');
|
|
219
|
-
// The previously-current item is no longer aria-current.
|
|
220
|
-
const one = Array.from(updated).find((b) => b.textContent?.trim() === '1')!;
|
|
221
|
-
expect(one).not.toHaveAttribute('aria-current');
|
|
222
|
-
expect(one).toHaveAttribute('data-current', 'false');
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
it('stamps a configured aria-label on each item', async () => {
|
|
226
|
-
const { container } = await render(PaginationHost);
|
|
227
|
-
const items = container.querySelectorAll<HTMLElement>('[kjPaginationItem]');
|
|
228
|
-
const first = Array.from(items).find((b) => b.textContent?.trim() === '1')!;
|
|
229
|
-
expect(first).toHaveAttribute('aria-label', 'Page 1');
|
|
230
|
-
});
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
describe('boundary controls — disabled state at edges, focus-preserving', () => {
|
|
234
|
-
it('Previous and First are aria-disabled on page 1, but stay focusable (tabindex="0")', async () => {
|
|
235
|
-
const { container } = await render(PaginationHost);
|
|
236
|
-
const prev = container.querySelector<HTMLElement>('[kjPaginationPrevious]')!;
|
|
237
|
-
const first = container.querySelector<HTMLElement>('[kjPaginationFirst]')!;
|
|
238
|
-
expect(prev).toHaveAttribute('aria-disabled', 'true');
|
|
239
|
-
expect(prev).toHaveAttribute('tabindex', '0');
|
|
240
|
-
expect(first).toHaveAttribute('aria-disabled', 'true');
|
|
241
|
-
expect(first).toHaveAttribute('tabindex', '0');
|
|
242
|
-
// Native disabled is NOT used.
|
|
243
|
-
expect(prev).not.toHaveAttribute('disabled');
|
|
244
|
-
expect(first).not.toHaveAttribute('disabled');
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
it('Next and Last are aria-disabled on the last page, but stay focusable', async () => {
|
|
248
|
-
const { fixture, container } = await render(PaginationHost);
|
|
249
|
-
(fixture.componentInstance as PaginationHost).page.set(10);
|
|
250
|
-
fixture.detectChanges();
|
|
251
|
-
const next = container.querySelector<HTMLElement>('[kjPaginationNext]')!;
|
|
252
|
-
const last = container.querySelector<HTMLElement>('[kjPaginationLast]')!;
|
|
253
|
-
expect(next).toHaveAttribute('aria-disabled', 'true');
|
|
254
|
-
expect(next).toHaveAttribute('tabindex', '0');
|
|
255
|
-
expect(last).toHaveAttribute('aria-disabled', 'true');
|
|
256
|
-
expect(last).toHaveAttribute('tabindex', '0');
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
it('Previous click is suppressed at the first-page boundary (capture-phase)', async () => {
|
|
260
|
-
const { fixture, container } = await render(PaginationHost);
|
|
261
|
-
const host = fixture.componentInstance as PaginationHost;
|
|
262
|
-
const prev = container.querySelector<HTMLElement>('[kjPaginationPrevious]')!;
|
|
263
|
-
fireEvent.click(prev);
|
|
264
|
-
fixture.detectChanges();
|
|
265
|
-
expect(host.page()).toBe(1);
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
it('Next click is suppressed at the last-page boundary', async () => {
|
|
269
|
-
const { fixture, container } = await render(PaginationHost);
|
|
270
|
-
const host = fixture.componentInstance as PaginationHost;
|
|
271
|
-
host.page.set(10);
|
|
272
|
-
fixture.detectChanges();
|
|
273
|
-
const next = container.querySelector<HTMLElement>('[kjPaginationNext]')!;
|
|
274
|
-
fireEvent.click(next);
|
|
275
|
-
fixture.detectChanges();
|
|
276
|
-
expect(host.page()).toBe(10);
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
it('Next click advances the page when not at the boundary', async () => {
|
|
280
|
-
const { fixture, container } = await render(PaginationHost);
|
|
281
|
-
const host = fixture.componentInstance as PaginationHost;
|
|
282
|
-
host.page.set(3);
|
|
283
|
-
fixture.detectChanges();
|
|
284
|
-
const next = container.querySelector<HTMLElement>('[kjPaginationNext]')!;
|
|
285
|
-
fireEvent.click(next);
|
|
286
|
-
fixture.detectChanges();
|
|
287
|
-
expect(host.page()).toBe(4);
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
it('First / Last jump to the corresponding boundary', async () => {
|
|
291
|
-
const { fixture, container } = await render(PaginationHost);
|
|
292
|
-
const host = fixture.componentInstance as PaginationHost;
|
|
293
|
-
host.page.set(5);
|
|
294
|
-
fixture.detectChanges();
|
|
295
|
-
const last = container.querySelector<HTMLElement>('[kjPaginationLast]')!;
|
|
296
|
-
fireEvent.click(last);
|
|
297
|
-
fixture.detectChanges();
|
|
298
|
-
expect(host.page()).toBe(10);
|
|
299
|
-
const first = container.querySelector<HTMLElement>('[kjPaginationFirst]')!;
|
|
300
|
-
fireEvent.click(first);
|
|
301
|
-
fixture.detectChanges();
|
|
302
|
-
expect(host.page()).toBe(1);
|
|
303
|
-
});
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
describe('kjPage two-way model', () => {
|
|
307
|
-
it('clicking a page item updates the consumer signal', async () => {
|
|
308
|
-
const { fixture, container } = await render(PaginationHost);
|
|
309
|
-
const host = fixture.componentInstance as PaginationHost;
|
|
310
|
-
const items = container.querySelectorAll<HTMLElement>('[kjPaginationItem]');
|
|
311
|
-
const two = Array.from(items).find((b) => b.textContent?.trim() === '2')!;
|
|
312
|
-
fireEvent.click(two);
|
|
313
|
-
fixture.detectChanges();
|
|
314
|
-
expect(host.page()).toBe(2);
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
it('writing the consumer signal flows to the directive (current item updates)', async () => {
|
|
318
|
-
const { fixture, container } = await render(PaginationHost);
|
|
319
|
-
(fixture.componentInstance as PaginationHost).page.set(2);
|
|
320
|
-
fixture.detectChanges();
|
|
321
|
-
const items = container.querySelectorAll<HTMLElement>('[kjPaginationItem]');
|
|
322
|
-
const two = Array.from(items).find((b) => b.textContent?.trim() === '2')!;
|
|
323
|
-
expect(two).toHaveAttribute('aria-current', 'page');
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
it('out-of-range writes are clamped and a warning is issued', async () => {
|
|
327
|
-
const warn = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
|
|
328
|
-
const { fixture } = await render(PaginationHost);
|
|
329
|
-
const host = fixture.componentInstance as PaginationHost;
|
|
330
|
-
host.page.set(99);
|
|
331
|
-
fixture.detectChanges();
|
|
332
|
-
// Two ticks — the clamp effect re-runs on the second.
|
|
333
|
-
await Promise.resolve();
|
|
334
|
-
fixture.detectChanges();
|
|
335
|
-
expect(host.page()).toBe(10);
|
|
336
|
-
expect(warn).toHaveBeenCalled();
|
|
337
|
-
warn.mockRestore();
|
|
338
|
-
});
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
describe('live-region announcement', () => {
|
|
342
|
-
it('appends a polite, atomic, visually-hidden live region inside the nav', async () => {
|
|
343
|
-
const { container } = await render(PaginationHost);
|
|
344
|
-
// afterNextRender is asynchronous in jsdom — wait a tick.
|
|
345
|
-
await new Promise<void>((resolve) => setTimeout(resolve, 0));
|
|
346
|
-
const nav = container.querySelector('[kjPagination]')!;
|
|
347
|
-
const region = nav.querySelector('[data-kj-pagination-live]') as HTMLElement | null;
|
|
348
|
-
expect(region).toBeTruthy();
|
|
349
|
-
expect(region!).toHaveAttribute('aria-live', 'polite');
|
|
350
|
-
expect(region!).toHaveAttribute('aria-atomic', 'true');
|
|
351
|
-
expect(region!.getAttribute('style') ?? '').toContain('clip:rect(0,0,0,0)');
|
|
352
|
-
});
|
|
353
|
-
|
|
354
|
-
it('writes the configured announcement template on page change', async () => {
|
|
355
|
-
const { fixture, container } = await render(PaginationHost);
|
|
356
|
-
const host = fixture.componentInstance as PaginationHost;
|
|
357
|
-
// Wait for the live region to attach.
|
|
358
|
-
await new Promise<void>((resolve) => setTimeout(resolve, 0));
|
|
359
|
-
host.page.set(4);
|
|
360
|
-
fixture.detectChanges();
|
|
361
|
-
// The directive uses queueMicrotask to clear-then-set; flush it.
|
|
362
|
-
await Promise.resolve();
|
|
363
|
-
await new Promise<void>((resolve) => queueMicrotask(() => resolve()));
|
|
364
|
-
const region = container.querySelector('[data-kj-pagination-live]') as HTMLElement;
|
|
365
|
-
expect(region.textContent).toBe('Page 4 of 10');
|
|
366
|
-
});
|
|
367
|
-
});
|
|
368
|
-
|
|
369
|
-
describe('small dataset', () => {
|
|
370
|
-
it('renders every page with no ellipses', async () => {
|
|
371
|
-
const { container } = await render(SmallPaginationHost);
|
|
372
|
-
const items = container.querySelectorAll<HTMLElement>('[kjPaginationItem]');
|
|
373
|
-
expect(items).toHaveLength(3);
|
|
374
|
-
const ellipses = container.querySelectorAll('[kjPaginationEllipsis]');
|
|
375
|
-
expect(ellipses).toHaveLength(0);
|
|
376
|
-
});
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
describe('info directive', () => {
|
|
380
|
-
it('renders the "Page N of M" string into an empty host', async () => {
|
|
381
|
-
const { container, fixture } = await render(PaginationHost);
|
|
382
|
-
await new Promise<void>((resolve) => setTimeout(resolve, 0));
|
|
383
|
-
fixture.detectChanges();
|
|
384
|
-
const info = container.querySelector('[kjPaginationInfo]')!;
|
|
385
|
-
expect(info.textContent).toContain('Page 1 of 10');
|
|
386
|
-
});
|
|
387
|
-
});
|
|
388
|
-
});
|