@comitor/ui 2.0.0 → 3.0.0
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/LICENSE +35 -0
- package/README.md +67 -24
- package/dist/chart/chart.d.ts +6 -1
- package/dist/chart/chart.js +3 -1
- package/dist/chart/chart.js.map +1 -1
- package/dist/chart/comitor-chart.d.ts +4 -1
- package/dist/chart/comitor-chart.js +3 -1
- package/dist/chart/comitor-chart.js.map +1 -1
- package/dist/components/composite/avatar-group.d.ts +9 -6
- package/dist/components/composite/avatar-group.js +6 -2
- package/dist/components/composite/avatar-group.js.map +1 -1
- package/dist/components/composite/combobox.d.ts +11 -11
- package/dist/components/composite/combobox.js +25 -11
- package/dist/components/composite/combobox.js.map +1 -1
- package/dist/components/composite/command-palette-constants.d.ts +15 -5
- package/dist/components/composite/command-palette-constants.js +3 -2
- package/dist/components/composite/command-palette-constants.js.map +1 -1
- package/dist/components/composite/command-palette.d.ts +2 -2
- package/dist/components/composite/command-palette.js +8 -5
- package/dist/components/composite/command-palette.js.map +1 -1
- package/dist/components/composite/confirm-dialog.d.ts +8 -8
- package/dist/components/composite/confirm-dialog.js +8 -3
- package/dist/components/composite/confirm-dialog.js.map +1 -1
- package/dist/components/composite/copy-button.d.ts +7 -3
- package/dist/components/composite/copy-button.js +7 -3
- package/dist/components/composite/copy-button.js.map +1 -1
- package/dist/components/composite/data-table-constants.d.ts +7 -3
- package/dist/components/composite/data-table-constants.js +2 -9
- package/dist/components/composite/data-table-constants.js.map +1 -1
- package/dist/components/composite/data-table.js +3 -3
- package/dist/components/composite/data-table.js.map +1 -1
- package/dist/components/composite/date-picker-constants.d.ts +32 -9
- package/dist/components/composite/date-picker-constants.js +16 -11
- package/dist/components/composite/date-picker-constants.js.map +1 -1
- package/dist/components/composite/date-picker.d.ts +19 -10
- package/dist/components/composite/date-picker.js +33 -9
- package/dist/components/composite/date-picker.js.map +1 -1
- package/dist/components/composite/filter-chips.d.ts +4 -3
- package/dist/components/composite/filter-chips.js +6 -2
- package/dist/components/composite/filter-chips.js.map +1 -1
- package/dist/components/composite/inline-edit.d.ts +14 -3
- package/dist/components/composite/inline-edit.js +8 -4
- package/dist/components/composite/inline-edit.js.map +1 -1
- package/dist/components/composite/relative-time.d.ts +4 -4
- package/dist/components/composite/relative-time.js +4 -2
- package/dist/components/composite/relative-time.js.map +1 -1
- package/dist/components/composite/route-tabs-nav.d.ts +9 -0
- package/dist/components/composite/route-tabs-nav.js +11 -0
- package/dist/components/composite/route-tabs-nav.js.map +1 -0
- package/dist/components/composite/route-tabs.d.ts +4 -1
- package/dist/components/composite/route-tabs.js +3 -2
- package/dist/components/composite/route-tabs.js.map +1 -1
- package/dist/components/composite/search-filter-bar-constants.d.ts +18 -8
- package/dist/components/composite/search-filter-bar-constants.js +2 -14
- package/dist/components/composite/search-filter-bar-constants.js.map +1 -1
- package/dist/components/composite/search-filter-bar.d.ts +5 -2
- package/dist/components/composite/search-filter-bar.js +2 -2
- package/dist/components/composite/search-filter-bar.js.map +1 -1
- package/dist/components/composite/stat-card.d.ts +1 -1
- package/dist/components/composite/table-pagination-constants.d.ts +16 -11
- package/dist/components/composite/table-pagination-constants.js +2 -12
- package/dist/components/composite/table-pagination-constants.js.map +1 -1
- package/dist/components/composite/table-pagination.d.ts +6 -3
- package/dist/components/composite/table-pagination.js +3 -5
- package/dist/components/composite/table-pagination.js.map +1 -1
- package/dist/components/composite/toast.d.ts +4 -2
- package/dist/components/composite/toast.js +9 -1
- package/dist/components/composite/toast.js.map +1 -1
- package/dist/components/ui/action-bar-constants.d.ts +35 -0
- package/dist/components/ui/action-bar-constants.js +6 -0
- package/dist/components/ui/action-bar-constants.js.map +1 -0
- package/dist/components/ui/action-bar.d.ts +68 -0
- package/dist/components/ui/action-bar.js +522 -0
- package/dist/components/ui/action-bar.js.map +1 -0
- package/dist/components/ui/alert.d.ts +1 -1
- package/dist/components/ui/badge-overflow.d.ts +30 -0
- package/dist/components/ui/badge-overflow.js +181 -0
- package/dist/components/ui/badge-overflow.js.map +1 -0
- package/dist/components/ui/badge.d.ts +1 -1
- package/dist/components/ui/banner.d.ts +80 -0
- package/dist/components/ui/banner.js +520 -0
- package/dist/components/ui/banner.js.map +1 -0
- package/dist/components/ui/breadcrumb.d.ts +11 -4
- package/dist/components/ui/breadcrumb.js +7 -2
- package/dist/components/ui/breadcrumb.js.map +1 -1
- package/dist/components/ui/button.d.ts +2 -2
- package/dist/components/ui/calendar.d.ts +12 -5
- package/dist/components/ui/calendar.js +38 -3
- package/dist/components/ui/calendar.js.map +1 -1
- package/dist/components/ui/carousel.d.ts +4 -3
- package/dist/components/ui/carousel.js +11 -4
- package/dist/components/ui/carousel.js.map +1 -1
- package/dist/components/ui/circular-progress.d.ts +50 -0
- package/dist/components/ui/circular-progress.js +266 -0
- package/dist/components/ui/circular-progress.js.map +1 -0
- package/dist/components/ui/command.d.ts +5 -4
- package/dist/components/ui/command.js +6 -2
- package/dist/components/ui/command.js.map +1 -1
- package/dist/components/ui/cropper-constants.d.ts +39 -0
- package/dist/components/ui/cropper-constants.js +6 -0
- package/dist/components/ui/cropper-constants.js.map +1 -0
- package/dist/components/ui/cropper.d.ts +107 -0
- package/dist/components/ui/cropper.js +1269 -0
- package/dist/components/ui/cropper.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +2 -2
- package/dist/components/ui/dialog.js +4 -1
- package/dist/components/ui/dialog.js.map +1 -1
- package/dist/components/ui/drawer.d.ts +1 -1
- package/dist/components/ui/drawer.js +2 -2
- package/dist/components/ui/drawer.js.map +1 -1
- package/dist/components/ui/item.d.ts +2 -2
- package/dist/components/ui/kanban-constants.d.ts +67 -0
- package/dist/components/ui/kanban-constants.js +6 -0
- package/dist/components/ui/kanban-constants.js.map +1 -0
- package/dist/components/ui/kanban.d.ts +72 -0
- package/dist/components/ui/kanban.js +787 -0
- package/dist/components/ui/kanban.js.map +1 -0
- package/dist/components/ui/key-value-constants.d.ts +37 -0
- package/dist/components/ui/key-value-constants.js +6 -0
- package/dist/components/ui/key-value-constants.js.map +1 -0
- package/dist/components/ui/key-value.d.ts +96 -0
- package/dist/components/ui/key-value.js +641 -0
- package/dist/components/ui/key-value.js.map +1 -0
- package/dist/components/ui/mask-input-constants.d.ts +98 -0
- package/dist/components/ui/mask-input-constants.js +600 -0
- package/dist/components/ui/mask-input-constants.js.map +1 -0
- package/dist/components/ui/mask-input.d.ts +39 -0
- package/dist/components/ui/mask-input.js +560 -0
- package/dist/components/ui/mask-input.js.map +1 -0
- package/dist/components/ui/mention.d.ts +32 -0
- package/dist/components/ui/mention.js +126 -0
- package/dist/components/ui/mention.js.map +1 -0
- package/dist/components/ui/pagination.d.ts +13 -9
- package/dist/components/ui/pagination.js +15 -6
- package/dist/components/ui/pagination.js.map +1 -1
- package/dist/components/ui/phone-input-constants.d.ts +65 -0
- package/dist/components/ui/phone-input-constants.js +6 -0
- package/dist/components/ui/phone-input-constants.js.map +1 -0
- package/dist/components/ui/phone-input.d.ts +92 -0
- package/dist/components/ui/phone-input.js +742 -0
- package/dist/components/ui/phone-input.js.map +1 -0
- package/dist/components/ui/progress.d.ts +2 -2
- package/dist/components/ui/rating.d.ts +57 -0
- package/dist/components/ui/rating.js +648 -0
- package/dist/components/ui/rating.js.map +1 -0
- package/dist/components/ui/responsive-dialog.d.ts +35 -0
- package/dist/components/ui/responsive-dialog.js +193 -0
- package/dist/components/ui/responsive-dialog.js.map +1 -0
- package/dist/components/ui/scroll-spy.d.ts +42 -0
- package/dist/components/ui/scroll-spy.js +336 -0
- package/dist/components/ui/scroll-spy.js.map +1 -0
- package/dist/components/ui/sheet.d.ts +2 -2
- package/dist/components/ui/sheet.js +10 -1
- package/dist/components/ui/sheet.js.map +1 -1
- package/dist/components/ui/spinner.js +4 -1
- package/dist/components/ui/spinner.js.map +1 -1
- package/dist/components/ui/stepper-constants.d.ts +34 -0
- package/dist/components/ui/stepper-constants.js +6 -0
- package/dist/components/ui/stepper-constants.js.map +1 -0
- package/dist/components/ui/stepper.d.ts +81 -0
- package/dist/components/ui/stepper.js +902 -0
- package/dist/components/ui/stepper.js.map +1 -0
- package/dist/components/ui/tags-input.d.ts +42 -0
- package/dist/components/ui/tags-input.js +129 -0
- package/dist/components/ui/tags-input.js.map +1 -0
- package/dist/components/ui/time-picker-constants.d.ts +51 -0
- package/dist/components/ui/time-picker-constants.js +6 -0
- package/dist/components/ui/time-picker-constants.js.map +1 -0
- package/dist/components/ui/time-picker.d.ts +120 -0
- package/dist/components/ui/time-picker.js +1618 -0
- package/dist/components/ui/time-picker.js.map +1 -0
- package/dist/components/ui/timeline.d.ts +32 -0
- package/dist/components/ui/timeline.js +559 -0
- package/dist/components/ui/timeline.js.map +1 -0
- package/dist/components/ui/toggle.d.ts +1 -1
- package/dist/components/ui/tour-constants.d.ts +44 -0
- package/dist/components/ui/tour-constants.js +6 -0
- package/dist/components/ui/tour-constants.js.map +1 -0
- package/dist/components/ui/tour.d.ts +125 -0
- package/dist/components/ui/tour.js +1207 -0
- package/dist/components/ui/tour.js.map +1 -0
- package/dist/data-grid/data-grid-cell-variants.js +4 -4
- package/dist/data-grid/data-grid-cell-variants.js.map +1 -1
- package/dist/data-grid/data-grid-cell-wrapper.js +1 -1
- package/dist/data-grid/data-grid-cell-wrapper.js.map +1 -1
- package/dist/data-grid/data-grid-column-header.js +1 -1
- package/dist/data-grid/data-grid-column-header.js.map +1 -1
- package/dist/data-grid/data-grid-context-menu.js +1 -1
- package/dist/data-grid/data-grid-context-menu.js.map +1 -1
- package/dist/data-grid/data-grid-filter-menu.d.ts +5 -4
- package/dist/data-grid/data-grid-filter-menu.js +13 -8
- package/dist/data-grid/data-grid-filter-menu.js.map +1 -1
- package/dist/data-grid/data-grid-keyboard-shortcuts.d.ts +4 -4
- package/dist/data-grid/data-grid-keyboard-shortcuts.js.map +1 -1
- package/dist/data-grid/data-grid-locale.d.ts +58 -6
- package/dist/data-grid/data-grid-locale.js +41 -9
- package/dist/data-grid/data-grid-locale.js.map +1 -1
- package/dist/data-grid/data-grid-paste-dialog.js +1 -1
- package/dist/data-grid/data-grid-paste-dialog.js.map +1 -1
- package/dist/data-grid/data-grid-row-height-menu.d.ts +4 -3
- package/dist/data-grid/data-grid-row-height-menu.js.map +1 -1
- package/dist/data-grid/data-grid-row.js +1 -1
- package/dist/data-grid/data-grid-row.js.map +1 -1
- package/dist/data-grid/data-grid-search.js +1 -1
- package/dist/data-grid/data-grid-search.js.map +1 -1
- package/dist/data-grid/data-grid-sort-menu.d.ts +4 -4
- package/dist/data-grid/data-grid-sort-menu.js +1 -1
- package/dist/data-grid/data-grid-sort-menu.js.map +1 -1
- package/dist/data-grid/data-grid-view-menu.d.ts +4 -4
- package/dist/data-grid/data-grid-view-menu.js.map +1 -1
- package/dist/data-grid/data-grid.d.ts +4 -3
- package/dist/data-grid/data-grid.js +3 -4
- package/dist/data-grid/data-grid.js.map +1 -1
- package/dist/data-grid/index.d.ts +1 -0
- package/dist/data-grid/index.js.map +1 -1
- package/dist/data-grid/messages-en.d.ts +23 -4
- package/dist/data-grid/messages-en.js +20 -0
- package/dist/data-grid/messages-en.js.map +1 -1
- package/dist/data-grid/messages-vi.d.ts +3 -1
- package/dist/data-grid/messages-vi.js +14 -0
- package/dist/data-grid/messages-vi.js.map +1 -1
- package/dist/data-grid/messages.d.ts +29 -3
- package/dist/data-grid/messages.js.map +1 -1
- package/dist/data-grid/sortable.js +17 -20
- package/dist/data-grid/sortable.js.map +1 -1
- package/dist/data-grid/types.d.ts +1 -1
- package/dist/data-grid/use-data-grid-undo-redo.d.ts +5 -4
- package/dist/data-grid/use-data-grid-undo-redo.js +4 -4
- package/dist/data-grid/use-data-grid-undo-redo.js.map +1 -1
- package/dist/data-grid/use-data-grid.d.ts +21 -6
- package/dist/data-grid/use-data-grid.js +11 -9
- package/dist/data-grid/use-data-grid.js.map +1 -1
- package/dist/data-grid/utils.d.ts +24 -4
- package/dist/data-grid/utils.js +15 -5
- package/dist/data-grid/utils.js.map +1 -1
- package/dist/i18n/locale-provider.d.ts +109 -0
- package/dist/i18n/locale-provider.js +47 -0
- package/dist/i18n/locale-provider.js.map +1 -0
- package/dist/i18n/locale.d.ts +27 -0
- package/dist/i18n/locale.js +10 -0
- package/dist/i18n/locale.js.map +1 -0
- package/dist/i18n/messages.d.ts +116 -0
- package/dist/i18n/messages.js +149 -0
- package/dist/i18n/messages.js.map +1 -0
- package/dist/i18n/namespaces/action-bar.d.ts +7 -0
- package/dist/i18n/namespaces/action-bar.js +15 -0
- package/dist/i18n/namespaces/action-bar.js.map +1 -0
- package/dist/i18n/namespaces/avatar-group.d.ts +14 -0
- package/dist/i18n/namespaces/avatar-group.js +13 -0
- package/dist/i18n/namespaces/avatar-group.js.map +1 -0
- package/dist/i18n/namespaces/badge-overflow.d.ts +12 -0
- package/dist/i18n/namespaces/badge-overflow.js +11 -0
- package/dist/i18n/namespaces/badge-overflow.js.map +1 -0
- package/dist/i18n/namespaces/banner.d.ts +9 -0
- package/dist/i18n/namespaces/banner.js +7 -0
- package/dist/i18n/namespaces/banner.js.map +1 -0
- package/dist/i18n/namespaces/breadcrumb.d.ts +11 -0
- package/dist/i18n/namespaces/breadcrumb.js +13 -0
- package/dist/i18n/namespaces/breadcrumb.js.map +1 -0
- package/dist/i18n/namespaces/calendar.d.ts +40 -0
- package/dist/i18n/namespaces/calendar.js +25 -0
- package/dist/i18n/namespaces/calendar.js.map +1 -0
- package/dist/i18n/namespaces/carousel.d.ts +15 -0
- package/dist/i18n/namespaces/carousel.js +17 -0
- package/dist/i18n/namespaces/carousel.js.map +1 -0
- package/dist/i18n/namespaces/combobox.d.ts +21 -0
- package/dist/i18n/namespaces/combobox.js +23 -0
- package/dist/i18n/namespaces/combobox.js.map +1 -0
- package/dist/i18n/namespaces/command-palette.d.ts +20 -0
- package/dist/i18n/namespaces/command-palette.js +19 -0
- package/dist/i18n/namespaces/command-palette.js.map +1 -0
- package/dist/i18n/namespaces/command.d.ts +11 -0
- package/dist/i18n/namespaces/command.js +13 -0
- package/dist/i18n/namespaces/command.js.map +1 -0
- package/dist/i18n/namespaces/confirm-dialog.d.ts +13 -0
- package/dist/i18n/namespaces/confirm-dialog.js +15 -0
- package/dist/i18n/namespaces/confirm-dialog.js.map +1 -0
- package/dist/i18n/namespaces/contrast.d.ts +7 -0
- package/dist/i18n/namespaces/contrast.js +13 -0
- package/dist/i18n/namespaces/contrast.js.map +1 -0
- package/dist/i18n/namespaces/copy-button.d.ts +11 -0
- package/dist/i18n/namespaces/copy-button.js +13 -0
- package/dist/i18n/namespaces/copy-button.js.map +1 -0
- package/dist/i18n/namespaces/cropper.d.ts +7 -0
- package/dist/i18n/namespaces/cropper.js +17 -0
- package/dist/i18n/namespaces/cropper.js.map +1 -0
- package/dist/i18n/namespaces/data-table.d.ts +7 -0
- package/dist/i18n/namespaces/data-table.js +23 -0
- package/dist/i18n/namespaces/data-table.js.map +1 -0
- package/dist/i18n/namespaces/date-picker.d.ts +42 -0
- package/dist/i18n/namespaces/date-picker.js +35 -0
- package/dist/i18n/namespaces/date-picker.js.map +1 -0
- package/dist/i18n/namespaces/dialog.d.ts +9 -0
- package/dist/i18n/namespaces/dialog.js +7 -0
- package/dist/i18n/namespaces/dialog.js.map +1 -0
- package/dist/i18n/namespaces/display-axis.d.ts +25 -0
- package/dist/i18n/namespaces/display-axis.js +21 -0
- package/dist/i18n/namespaces/display-axis.js.map +1 -0
- package/dist/i18n/namespaces/file-upload.d.ts +11 -0
- package/dist/i18n/namespaces/file-upload.js +19 -0
- package/dist/i18n/namespaces/file-upload.js.map +1 -0
- package/dist/i18n/namespaces/filter-chips.d.ts +11 -0
- package/dist/i18n/namespaces/filter-chips.js +13 -0
- package/dist/i18n/namespaces/filter-chips.js.map +1 -0
- package/dist/i18n/namespaces/image-upload-field.d.ts +12 -0
- package/dist/i18n/namespaces/image-upload-field.js +23 -0
- package/dist/i18n/namespaces/image-upload-field.js.map +1 -0
- package/dist/i18n/namespaces/inline-edit.d.ts +15 -0
- package/dist/i18n/namespaces/inline-edit.js +17 -0
- package/dist/i18n/namespaces/inline-edit.js.map +1 -0
- package/dist/i18n/namespaces/kanban.d.ts +11 -0
- package/dist/i18n/namespaces/kanban.js +39 -0
- package/dist/i18n/namespaces/kanban.js.map +1 -0
- package/dist/i18n/namespaces/key-value.d.ts +10 -0
- package/dist/i18n/namespaces/key-value.js +19 -0
- package/dist/i18n/namespaces/key-value.js.map +1 -0
- package/dist/i18n/namespaces/mention.d.ts +9 -0
- package/dist/i18n/namespaces/mention.js +7 -0
- package/dist/i18n/namespaces/mention.js.map +1 -0
- package/dist/i18n/namespaces/pagination.d.ts +19 -0
- package/dist/i18n/namespaces/pagination.js +21 -0
- package/dist/i18n/namespaces/pagination.js.map +1 -0
- package/dist/i18n/namespaces/phone-input.d.ts +10 -0
- package/dist/i18n/namespaces/phone-input.js +17 -0
- package/dist/i18n/namespaces/phone-input.js.map +1 -0
- package/dist/i18n/namespaces/rating.d.ts +12 -0
- package/dist/i18n/namespaces/rating.js +11 -0
- package/dist/i18n/namespaces/rating.js.map +1 -0
- package/dist/i18n/namespaces/route-tabs.d.ts +9 -0
- package/dist/i18n/namespaces/route-tabs.js +7 -0
- package/dist/i18n/namespaces/route-tabs.js.map +1 -0
- package/dist/i18n/namespaces/scroll-spy.d.ts +9 -0
- package/dist/i18n/namespaces/scroll-spy.js +7 -0
- package/dist/i18n/namespaces/scroll-spy.js.map +1 -0
- package/dist/i18n/namespaces/search-filter-bar.d.ts +15 -0
- package/dist/i18n/namespaces/search-filter-bar.js +32 -0
- package/dist/i18n/namespaces/search-filter-bar.js.map +1 -0
- package/dist/i18n/namespaces/sheet.d.ts +9 -0
- package/dist/i18n/namespaces/sheet.js +7 -0
- package/dist/i18n/namespaces/sheet.js.map +1 -0
- package/dist/i18n/namespaces/shell.d.ts +17 -0
- package/dist/i18n/namespaces/shell.js +75 -0
- package/dist/i18n/namespaces/shell.js.map +1 -0
- package/dist/i18n/namespaces/spinner.d.ts +9 -0
- package/dist/i18n/namespaces/spinner.js +7 -0
- package/dist/i18n/namespaces/spinner.js.map +1 -0
- package/dist/i18n/namespaces/stepper.d.ts +7 -0
- package/dist/i18n/namespaces/stepper.js +15 -0
- package/dist/i18n/namespaces/stepper.js.map +1 -0
- package/dist/i18n/namespaces/table-pagination.d.ts +7 -0
- package/dist/i18n/namespaces/table-pagination.js +29 -0
- package/dist/i18n/namespaces/table-pagination.js.map +1 -0
- package/dist/i18n/namespaces/tags-input.d.ts +12 -0
- package/dist/i18n/namespaces/tags-input.js +11 -0
- package/dist/i18n/namespaces/tags-input.js.map +1 -0
- package/dist/i18n/namespaces/time-picker.d.ts +15 -0
- package/dist/i18n/namespaces/time-picker.js +25 -0
- package/dist/i18n/namespaces/time-picker.js.map +1 -0
- package/dist/i18n/namespaces/toast.d.ts +15 -0
- package/dist/i18n/namespaces/toast.js +7 -0
- package/dist/i18n/namespaces/toast.js.map +1 -0
- package/dist/i18n/namespaces/tour.d.ts +7 -0
- package/dist/i18n/namespaces/tour.js +21 -0
- package/dist/i18n/namespaces/tour.js.map +1 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.js +66 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/compose-refs.js.map +1 -0
- package/dist/lib/use-as-ref.js.map +1 -0
- package/dist/lib/use-is-mobile.d.ts +10 -0
- package/dist/lib/use-is-mobile.js +21 -0
- package/dist/lib/use-is-mobile.js.map +1 -0
- package/dist/lib/use-isomorphic-layout-effect.js.map +1 -0
- package/dist/lib/use-lazy-ref.js.map +1 -0
- package/dist/lib/visually-hidden-input.d.ts +12 -0
- package/dist/lib/visually-hidden-input.js +105 -0
- package/dist/lib/visually-hidden-input.js.map +1 -0
- package/dist/shell/app-header.js.map +1 -1
- package/dist/shell/app-shell.d.ts +20 -2
- package/dist/shell/app-shell.js +4 -1
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/contrast-constants.d.ts +9 -1
- package/dist/shell/contrast-constants.js +2 -4
- package/dist/shell/contrast-constants.js.map +1 -1
- package/dist/shell/contrast-toggle.d.ts +4 -1
- package/dist/shell/contrast-toggle.js +2 -2
- package/dist/shell/contrast-toggle.js.map +1 -1
- package/dist/shell/display-axis-constants.d.ts +2 -1
- package/dist/shell/display-axis-constants.js.map +1 -1
- package/dist/shell/display-axis-controls.d.ts +15 -6
- package/dist/shell/display-axis-controls.js +11 -9
- package/dist/shell/display-axis-controls.js.map +1 -1
- package/dist/shell/mobile-menu.js.map +1 -1
- package/dist/shell/notifications-button.d.ts +1 -1
- package/dist/shell/notifications-button.js +3 -2
- package/dist/shell/notifications-button.js.map +1 -1
- package/dist/shell/shell-context.d.ts +4 -1
- package/dist/shell/shell-context.js +2 -4
- package/dist/shell/shell-context.js.map +1 -1
- package/dist/shell/sidebar.d.ts +1 -1
- package/dist/shell/sidebar.js.map +1 -1
- package/dist/shell/theme-toggle.d.ts +6 -3
- package/dist/shell/theme-toggle.js +2 -2
- package/dist/shell/theme-toggle.js.map +1 -1
- package/dist/shell/types.d.ts +14 -8
- package/dist/shell/types.js +2 -35
- package/dist/shell/types.js.map +1 -1
- package/dist/shell/user-menu.d.ts +6 -6
- package/dist/shell/user-menu.js.map +1 -1
- package/dist/shell/utils.d.ts +1 -1
- package/dist/shell/utils.js.map +1 -1
- package/dist/shell/workspace-switcher.js +1 -1
- package/dist/shell/workspace-switcher.js.map +1 -1
- package/dist/uploader/file-upload-constants.d.ts +13 -0
- package/dist/uploader/file-upload-constants.js +4 -16
- package/dist/uploader/file-upload-constants.js.map +1 -1
- package/dist/uploader/file-upload.d.ts +4 -1
- package/dist/uploader/file-upload.js +2 -2
- package/dist/uploader/file-upload.js.map +1 -1
- package/dist/uploader/image-upload-field.d.ts +5 -1
- package/dist/uploader/image-upload-field.js +2 -2
- package/dist/uploader/image-upload-field.js.map +1 -1
- package/dist/uploader/use-file-upload.d.ts +4 -0
- package/dist/uploader/use-file-upload.js +6 -2
- package/dist/uploader/use-file-upload.js.map +1 -1
- package/package.json +8 -3
- package/styles.css +19 -0
- package/dist/data-grid/compose-refs.js.map +0 -1
- package/dist/data-grid/use-as-ref.js.map +0 -1
- package/dist/data-grid/use-isomorphic-layout-effect.js.map +0 -1
- package/dist/data-grid/use-lazy-ref.js.map +0 -1
- /package/dist/{data-grid → lib}/compose-refs.d.ts +0 -0
- /package/dist/{data-grid → lib}/compose-refs.js +0 -0
- /package/dist/{data-grid → lib}/use-as-ref.d.ts +0 -0
- /package/dist/{data-grid → lib}/use-as-ref.js +0 -0
- /package/dist/{data-grid → lib}/use-isomorphic-layout-effect.d.ts +0 -0
- /package/dist/{data-grid → lib}/use-isomorphic-layout-effect.js +0 -0
- /package/dist/{data-grid → lib}/use-lazy-ref.d.ts +0 -0
- /package/dist/{data-grid → lib}/use-lazy-ref.js +0 -0
|
@@ -0,0 +1,902 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useDirection } from "@radix-ui/react-direction";
|
|
4
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
5
|
+
import { Check } from "lucide-react";
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { useComitorLabels } from "../../i18n/locale-provider.js";
|
|
8
|
+
import { cn } from "../../lib/cn.js";
|
|
9
|
+
import { useComposedRefs } from "../../lib/compose-refs.js";
|
|
10
|
+
import { useAsRef } from "../../lib/use-as-ref.js";
|
|
11
|
+
import { useIsomorphicLayoutEffect } from "../../lib/use-isomorphic-layout-effect.js";
|
|
12
|
+
import { useLazyRef } from "../../lib/use-lazy-ref.js";
|
|
13
|
+
const ROOT_NAME = "Stepper";
|
|
14
|
+
const LIST_NAME = "StepperList";
|
|
15
|
+
const ITEM_NAME = "StepperItem";
|
|
16
|
+
const TRIGGER_NAME = "StepperTrigger";
|
|
17
|
+
const INDICATOR_NAME = "StepperIndicator";
|
|
18
|
+
const SEPARATOR_NAME = "StepperSeparator";
|
|
19
|
+
const TITLE_NAME = "StepperTitle";
|
|
20
|
+
const DESCRIPTION_NAME = "StepperDescription";
|
|
21
|
+
const CONTENT_NAME = "StepperContent";
|
|
22
|
+
const PREV_NAME = "StepperPrev";
|
|
23
|
+
const NEXT_NAME = "StepperNext";
|
|
24
|
+
const ENTRY_FOCUS = "stepperFocusGroup.onEntryFocus";
|
|
25
|
+
const EVENT_OPTIONS = { bubbles: false, cancelable: true };
|
|
26
|
+
const ARROW_KEYS = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
|
|
27
|
+
function getId(id, variant, value) {
|
|
28
|
+
return `${id}-${variant}-${value}`;
|
|
29
|
+
}
|
|
30
|
+
const MAP_KEY_TO_FOCUS_INTENT = {
|
|
31
|
+
ArrowLeft: "prev",
|
|
32
|
+
ArrowUp: "prev",
|
|
33
|
+
ArrowRight: "next",
|
|
34
|
+
ArrowDown: "next",
|
|
35
|
+
PageUp: "first",
|
|
36
|
+
Home: "first",
|
|
37
|
+
PageDown: "last",
|
|
38
|
+
End: "last"
|
|
39
|
+
};
|
|
40
|
+
function getDirectionAwareKey(key, dir) {
|
|
41
|
+
if (dir !== "rtl") return key;
|
|
42
|
+
return key === "ArrowLeft" ? "ArrowRight" : key === "ArrowRight" ? "ArrowLeft" : key;
|
|
43
|
+
}
|
|
44
|
+
function getFocusIntent(event, dir, orientation) {
|
|
45
|
+
const key = getDirectionAwareKey(event.key, dir);
|
|
46
|
+
if (orientation === "horizontal" && ["ArrowUp", "ArrowDown"].includes(key)) return void 0;
|
|
47
|
+
if (orientation === "vertical" && ["ArrowLeft", "ArrowRight"].includes(key)) return void 0;
|
|
48
|
+
return MAP_KEY_TO_FOCUS_INTENT[key];
|
|
49
|
+
}
|
|
50
|
+
function focusFirst(candidates, preventScroll = false) {
|
|
51
|
+
const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
|
|
52
|
+
for (const candidateRef of candidates) {
|
|
53
|
+
const candidate = candidateRef.current;
|
|
54
|
+
if (!candidate) continue;
|
|
55
|
+
if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
56
|
+
candidate.focus({ preventScroll });
|
|
57
|
+
if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function wrapArray(array, startIndex) {
|
|
61
|
+
return array.map((_, index) => array[(startIndex + index) % array.length]);
|
|
62
|
+
}
|
|
63
|
+
function getDataState(value, itemValue, stepState, steps, variant = "item") {
|
|
64
|
+
const stepKeys = Array.from(steps.keys());
|
|
65
|
+
const currentIndex = stepKeys.indexOf(itemValue);
|
|
66
|
+
if (stepState?.completed) return "completed";
|
|
67
|
+
if (value === itemValue) {
|
|
68
|
+
return variant === "separator" ? "inactive" : "active";
|
|
69
|
+
}
|
|
70
|
+
if (value) {
|
|
71
|
+
const activeIndex = stepKeys.indexOf(value);
|
|
72
|
+
if (activeIndex > currentIndex) return "completed";
|
|
73
|
+
}
|
|
74
|
+
return "inactive";
|
|
75
|
+
}
|
|
76
|
+
const StoreContext = React.createContext(null);
|
|
77
|
+
function useStoreContext(consumerName) {
|
|
78
|
+
const context = React.useContext(StoreContext);
|
|
79
|
+
if (!context) {
|
|
80
|
+
throw new Error(`\`${consumerName}\` ph\u1EA3i n\u1EB1m b\xEAn trong \`${ROOT_NAME}\``);
|
|
81
|
+
}
|
|
82
|
+
return context;
|
|
83
|
+
}
|
|
84
|
+
function useStore(selector) {
|
|
85
|
+
const store = useStoreContext("useStepper");
|
|
86
|
+
const getSnapshot = React.useCallback(() => selector(store.getState()), [store, selector]);
|
|
87
|
+
return React.useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);
|
|
88
|
+
}
|
|
89
|
+
const StepperContext = React.createContext(null);
|
|
90
|
+
function useStepperContext(consumerName) {
|
|
91
|
+
const context = React.useContext(StepperContext);
|
|
92
|
+
if (!context) {
|
|
93
|
+
throw new Error(`\`${consumerName}\` ph\u1EA3i n\u1EB1m b\xEAn trong \`${ROOT_NAME}\``);
|
|
94
|
+
}
|
|
95
|
+
return context;
|
|
96
|
+
}
|
|
97
|
+
function Stepper(props) {
|
|
98
|
+
const {
|
|
99
|
+
value,
|
|
100
|
+
defaultValue,
|
|
101
|
+
onValueChange,
|
|
102
|
+
onValueComplete,
|
|
103
|
+
onValueAdd,
|
|
104
|
+
onValueRemove,
|
|
105
|
+
onValidate,
|
|
106
|
+
dir: dirProp,
|
|
107
|
+
orientation = "horizontal",
|
|
108
|
+
activationMode = "automatic",
|
|
109
|
+
asChild,
|
|
110
|
+
disabled = false,
|
|
111
|
+
nonInteractive = false,
|
|
112
|
+
loop = false,
|
|
113
|
+
labels: labelsProp,
|
|
114
|
+
className,
|
|
115
|
+
id,
|
|
116
|
+
...rootProps
|
|
117
|
+
} = props;
|
|
118
|
+
const listenersRef = useLazyRef(() => /* @__PURE__ */ new Set());
|
|
119
|
+
const stateRef = useLazyRef(() => ({
|
|
120
|
+
steps: /* @__PURE__ */ new Map(),
|
|
121
|
+
value: value ?? defaultValue ?? ""
|
|
122
|
+
}));
|
|
123
|
+
const propsRef = useAsRef({
|
|
124
|
+
onValueChange,
|
|
125
|
+
onValueComplete,
|
|
126
|
+
onValueAdd,
|
|
127
|
+
onValueRemove,
|
|
128
|
+
onValidate
|
|
129
|
+
});
|
|
130
|
+
const store = React.useMemo(() => {
|
|
131
|
+
return {
|
|
132
|
+
subscribe: (cb) => {
|
|
133
|
+
listenersRef.current.add(cb);
|
|
134
|
+
return () => listenersRef.current.delete(cb);
|
|
135
|
+
},
|
|
136
|
+
getState: () => stateRef.current,
|
|
137
|
+
setState: (key, value2) => {
|
|
138
|
+
if (Object.is(stateRef.current[key], value2)) return;
|
|
139
|
+
if (key === "value" && typeof value2 === "string") {
|
|
140
|
+
stateRef.current.value = value2;
|
|
141
|
+
propsRef.current.onValueChange?.(value2);
|
|
142
|
+
} else {
|
|
143
|
+
stateRef.current[key] = value2;
|
|
144
|
+
}
|
|
145
|
+
store.notify();
|
|
146
|
+
},
|
|
147
|
+
setStateWithValidation: async (value2, direction) => {
|
|
148
|
+
if (!propsRef.current.onValidate) {
|
|
149
|
+
store.setState("value", value2);
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
const isValid = await propsRef.current.onValidate(value2, direction);
|
|
154
|
+
if (isValid) {
|
|
155
|
+
store.setState("value", value2);
|
|
156
|
+
}
|
|
157
|
+
return isValid;
|
|
158
|
+
} catch {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
hasValidation: () => !!propsRef.current.onValidate,
|
|
163
|
+
/*
|
|
164
|
+
* ⚠ Khác thượng nguồn: mỗi lần thêm/bớt/sửa bước đều thay `steps` bằng một `Map` MỚI. Bản gốc
|
|
165
|
+
* sửa tại chỗ nên `useStore((s) => s.steps)` không bao giờ thấy tham chiếu mới — phần tử chỉ
|
|
166
|
+
* đọc `steps` (`StepperPrev`/`StepperNext`) không render lại sau khi các bước đăng ký, và
|
|
167
|
+
* nằm `disabled` cho tới lần đổi bước đầu tiên.
|
|
168
|
+
*/
|
|
169
|
+
addStep: (value2, completed, disabled2) => {
|
|
170
|
+
const newStep = { value: value2, completed, disabled: disabled2 };
|
|
171
|
+
const steps = new Map(stateRef.current.steps);
|
|
172
|
+
steps.set(value2, newStep);
|
|
173
|
+
stateRef.current.steps = steps;
|
|
174
|
+
propsRef.current.onValueAdd?.(value2);
|
|
175
|
+
store.notify();
|
|
176
|
+
},
|
|
177
|
+
removeStep: (value2) => {
|
|
178
|
+
const steps = new Map(stateRef.current.steps);
|
|
179
|
+
steps.delete(value2);
|
|
180
|
+
stateRef.current.steps = steps;
|
|
181
|
+
propsRef.current.onValueRemove?.(value2);
|
|
182
|
+
store.notify();
|
|
183
|
+
},
|
|
184
|
+
setStep: (value2, completed, disabled2) => {
|
|
185
|
+
const step = stateRef.current.steps.get(value2);
|
|
186
|
+
if (step) {
|
|
187
|
+
const updatedStep = { ...step, completed, disabled: disabled2 };
|
|
188
|
+
const steps = new Map(stateRef.current.steps);
|
|
189
|
+
steps.set(value2, updatedStep);
|
|
190
|
+
stateRef.current.steps = steps;
|
|
191
|
+
if (completed !== step.completed) {
|
|
192
|
+
propsRef.current.onValueComplete?.(value2, completed);
|
|
193
|
+
}
|
|
194
|
+
store.notify();
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
notify: () => {
|
|
198
|
+
for (const cb of listenersRef.current) {
|
|
199
|
+
cb();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}, [listenersRef, stateRef, propsRef]);
|
|
204
|
+
useIsomorphicLayoutEffect(() => {
|
|
205
|
+
if (value !== void 0) {
|
|
206
|
+
store.setState("value", value);
|
|
207
|
+
}
|
|
208
|
+
}, [value]);
|
|
209
|
+
const dir = useDirection(dirProp);
|
|
210
|
+
const instanceId = React.useId();
|
|
211
|
+
const rootId = id ?? instanceId;
|
|
212
|
+
const labels = useComitorLabels("stepper", labelsProp);
|
|
213
|
+
const contextValue = React.useMemo(
|
|
214
|
+
() => ({
|
|
215
|
+
rootId,
|
|
216
|
+
dir,
|
|
217
|
+
orientation,
|
|
218
|
+
activationMode,
|
|
219
|
+
disabled,
|
|
220
|
+
nonInteractive,
|
|
221
|
+
loop,
|
|
222
|
+
labels
|
|
223
|
+
}),
|
|
224
|
+
[rootId, dir, orientation, activationMode, disabled, nonInteractive, loop, labels]
|
|
225
|
+
);
|
|
226
|
+
const RootPrimitive = asChild ? Slot : "div";
|
|
227
|
+
return /* @__PURE__ */ jsx(StoreContext.Provider, { value: store, children: /* @__PURE__ */ jsx(StepperContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
|
|
228
|
+
RootPrimitive,
|
|
229
|
+
{
|
|
230
|
+
id: rootId,
|
|
231
|
+
"data-disabled": disabled ? "" : void 0,
|
|
232
|
+
"data-orientation": orientation,
|
|
233
|
+
"data-slot": "stepper",
|
|
234
|
+
dir,
|
|
235
|
+
...rootProps,
|
|
236
|
+
className: cn("flex gap-6", orientation === "horizontal" ? "w-full flex-col" : "flex-row", className)
|
|
237
|
+
}
|
|
238
|
+
) }) });
|
|
239
|
+
}
|
|
240
|
+
const FocusContext = React.createContext(null);
|
|
241
|
+
function useFocusContext(consumerName) {
|
|
242
|
+
const context = React.useContext(FocusContext);
|
|
243
|
+
if (!context) {
|
|
244
|
+
throw new Error(`\`${consumerName}\` ph\u1EA3i n\u1EB1m b\xEAn trong \`${LIST_NAME}\``);
|
|
245
|
+
}
|
|
246
|
+
return context;
|
|
247
|
+
}
|
|
248
|
+
function StepperList(props) {
|
|
249
|
+
const {
|
|
250
|
+
asChild,
|
|
251
|
+
onBlur: onBlurProp,
|
|
252
|
+
onFocus: onFocusProp,
|
|
253
|
+
onMouseDown: onMouseDownProp,
|
|
254
|
+
className,
|
|
255
|
+
children,
|
|
256
|
+
ref,
|
|
257
|
+
...listProps
|
|
258
|
+
} = props;
|
|
259
|
+
const context = useStepperContext(LIST_NAME);
|
|
260
|
+
const orientation = context.orientation;
|
|
261
|
+
const currentValue = useStore((state) => state.value);
|
|
262
|
+
const propsRef = useAsRef({
|
|
263
|
+
onBlur: onBlurProp,
|
|
264
|
+
onFocus: onFocusProp,
|
|
265
|
+
onMouseDown: onMouseDownProp
|
|
266
|
+
});
|
|
267
|
+
const [tabStopId, setTabStopId] = React.useState(null);
|
|
268
|
+
const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);
|
|
269
|
+
const [focusableItemCount, setFocusableItemCount] = React.useState(0);
|
|
270
|
+
const isClickFocusRef = React.useRef(false);
|
|
271
|
+
const itemsRef = React.useRef(/* @__PURE__ */ new Map());
|
|
272
|
+
const listRef = React.useRef(null);
|
|
273
|
+
const composedRef = useComposedRefs(ref, listRef);
|
|
274
|
+
const onItemFocus = React.useCallback((tabStopId2) => {
|
|
275
|
+
setTabStopId(tabStopId2);
|
|
276
|
+
}, []);
|
|
277
|
+
const onItemShiftTab = React.useCallback(() => {
|
|
278
|
+
setIsTabbingBackOut(true);
|
|
279
|
+
}, []);
|
|
280
|
+
const onFocusableItemAdd = React.useCallback(() => {
|
|
281
|
+
setFocusableItemCount((prevCount) => prevCount + 1);
|
|
282
|
+
}, []);
|
|
283
|
+
const onFocusableItemRemove = React.useCallback(() => {
|
|
284
|
+
setFocusableItemCount((prevCount) => prevCount - 1);
|
|
285
|
+
}, []);
|
|
286
|
+
const onItemRegister = React.useCallback((item) => {
|
|
287
|
+
itemsRef.current.set(item.id, item);
|
|
288
|
+
}, []);
|
|
289
|
+
const onItemUnregister = React.useCallback((id) => {
|
|
290
|
+
itemsRef.current.delete(id);
|
|
291
|
+
}, []);
|
|
292
|
+
const getItems = React.useCallback(() => {
|
|
293
|
+
return Array.from(itemsRef.current.values()).filter((item) => item.ref.current).sort((a, b) => {
|
|
294
|
+
const elementA = a.ref.current;
|
|
295
|
+
const elementB = b.ref.current;
|
|
296
|
+
if (!elementA || !elementB) return 0;
|
|
297
|
+
const position = elementA.compareDocumentPosition(elementB);
|
|
298
|
+
if (position & Node.DOCUMENT_POSITION_FOLLOWING) {
|
|
299
|
+
return -1;
|
|
300
|
+
}
|
|
301
|
+
if (position & Node.DOCUMENT_POSITION_PRECEDING) {
|
|
302
|
+
return 1;
|
|
303
|
+
}
|
|
304
|
+
return 0;
|
|
305
|
+
});
|
|
306
|
+
}, []);
|
|
307
|
+
const onBlur = React.useCallback(
|
|
308
|
+
(event) => {
|
|
309
|
+
propsRef.current.onBlur?.(event);
|
|
310
|
+
if (event.defaultPrevented) return;
|
|
311
|
+
setIsTabbingBackOut(false);
|
|
312
|
+
},
|
|
313
|
+
[propsRef]
|
|
314
|
+
);
|
|
315
|
+
const onFocus = React.useCallback(
|
|
316
|
+
(event) => {
|
|
317
|
+
propsRef.current.onFocus?.(event);
|
|
318
|
+
if (event.defaultPrevented) return;
|
|
319
|
+
const isKeyboardFocus = !isClickFocusRef.current;
|
|
320
|
+
if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
|
|
321
|
+
const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
|
|
322
|
+
event.currentTarget.dispatchEvent(entryFocusEvent);
|
|
323
|
+
if (!entryFocusEvent.defaultPrevented) {
|
|
324
|
+
const items = Array.from(itemsRef.current.values()).filter((item) => !item.disabled);
|
|
325
|
+
const selectedItem = currentValue ? items.find((item) => item.value === currentValue) : void 0;
|
|
326
|
+
const activeItem = items.find((item) => item.active);
|
|
327
|
+
const currentItem = items.find((item) => item.id === tabStopId);
|
|
328
|
+
const candidateItems = [selectedItem, activeItem, currentItem, ...items].filter(Boolean);
|
|
329
|
+
const candidateRefs = candidateItems.map((item) => item.ref);
|
|
330
|
+
focusFirst(candidateRefs, false);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
isClickFocusRef.current = false;
|
|
334
|
+
},
|
|
335
|
+
[propsRef, isTabbingBackOut, currentValue, tabStopId]
|
|
336
|
+
);
|
|
337
|
+
const onMouseDown = React.useCallback(
|
|
338
|
+
(event) => {
|
|
339
|
+
propsRef.current.onMouseDown?.(event);
|
|
340
|
+
if (event.defaultPrevented) return;
|
|
341
|
+
isClickFocusRef.current = true;
|
|
342
|
+
},
|
|
343
|
+
[propsRef]
|
|
344
|
+
);
|
|
345
|
+
const focusContextValue = React.useMemo(
|
|
346
|
+
() => ({
|
|
347
|
+
tabStopId,
|
|
348
|
+
onItemFocus,
|
|
349
|
+
onItemShiftTab,
|
|
350
|
+
onFocusableItemAdd,
|
|
351
|
+
onFocusableItemRemove,
|
|
352
|
+
onItemRegister,
|
|
353
|
+
onItemUnregister,
|
|
354
|
+
getItems
|
|
355
|
+
}),
|
|
356
|
+
[
|
|
357
|
+
tabStopId,
|
|
358
|
+
onItemFocus,
|
|
359
|
+
onItemShiftTab,
|
|
360
|
+
onFocusableItemAdd,
|
|
361
|
+
onFocusableItemRemove,
|
|
362
|
+
onItemRegister,
|
|
363
|
+
onItemUnregister,
|
|
364
|
+
getItems
|
|
365
|
+
]
|
|
366
|
+
);
|
|
367
|
+
const ListPrimitive = asChild ? Slot : "div";
|
|
368
|
+
return /* @__PURE__ */ jsx(FocusContext.Provider, { value: focusContextValue, children: /* @__PURE__ */ jsx(
|
|
369
|
+
ListPrimitive,
|
|
370
|
+
{
|
|
371
|
+
role: "tablist",
|
|
372
|
+
"aria-orientation": orientation,
|
|
373
|
+
"data-orientation": orientation,
|
|
374
|
+
"data-slot": "stepper-list",
|
|
375
|
+
dir: context.dir,
|
|
376
|
+
tabIndex: isTabbingBackOut || focusableItemCount === 0 ? -1 : 0,
|
|
377
|
+
...listProps,
|
|
378
|
+
ref: composedRef,
|
|
379
|
+
className: cn(
|
|
380
|
+
"flex outline-none",
|
|
381
|
+
orientation === "horizontal" ? "flex-row items-center" : "flex-col items-start",
|
|
382
|
+
className
|
|
383
|
+
),
|
|
384
|
+
onBlur,
|
|
385
|
+
onFocus,
|
|
386
|
+
onMouseDown,
|
|
387
|
+
children
|
|
388
|
+
}
|
|
389
|
+
) });
|
|
390
|
+
}
|
|
391
|
+
const StepperItemContext = React.createContext(null);
|
|
392
|
+
function useStepperItemContext(consumerName) {
|
|
393
|
+
const context = React.useContext(StepperItemContext);
|
|
394
|
+
if (!context) {
|
|
395
|
+
throw new Error(`\`${consumerName}\` ph\u1EA3i n\u1EB1m b\xEAn trong \`${ITEM_NAME}\``);
|
|
396
|
+
}
|
|
397
|
+
return context;
|
|
398
|
+
}
|
|
399
|
+
function StepperItem(props) {
|
|
400
|
+
const {
|
|
401
|
+
value: itemValue,
|
|
402
|
+
completed = false,
|
|
403
|
+
disabled = false,
|
|
404
|
+
asChild,
|
|
405
|
+
className,
|
|
406
|
+
children,
|
|
407
|
+
ref,
|
|
408
|
+
...itemProps
|
|
409
|
+
} = props;
|
|
410
|
+
const context = useStepperContext(ITEM_NAME);
|
|
411
|
+
const store = useStoreContext(ITEM_NAME);
|
|
412
|
+
const orientation = context.orientation;
|
|
413
|
+
const value = useStore((state) => state.value);
|
|
414
|
+
useIsomorphicLayoutEffect(() => {
|
|
415
|
+
store.addStep(itemValue, completed, disabled);
|
|
416
|
+
return () => {
|
|
417
|
+
store.removeStep(itemValue);
|
|
418
|
+
};
|
|
419
|
+
}, [itemValue]);
|
|
420
|
+
useIsomorphicLayoutEffect(() => {
|
|
421
|
+
store.setStep(itemValue, completed, disabled);
|
|
422
|
+
}, [itemValue, completed, disabled]);
|
|
423
|
+
const stepState = useStore((state) => state.steps.get(itemValue));
|
|
424
|
+
const steps = useStore((state) => state.steps);
|
|
425
|
+
const dataState = getDataState(value, itemValue, stepState, steps);
|
|
426
|
+
const itemContextValue = React.useMemo(
|
|
427
|
+
() => ({
|
|
428
|
+
value: itemValue,
|
|
429
|
+
stepState
|
|
430
|
+
}),
|
|
431
|
+
[itemValue, stepState]
|
|
432
|
+
);
|
|
433
|
+
const ItemPrimitive = asChild ? Slot : "div";
|
|
434
|
+
return /* @__PURE__ */ jsx(StepperItemContext.Provider, { value: itemContextValue, children: /* @__PURE__ */ jsx(
|
|
435
|
+
ItemPrimitive,
|
|
436
|
+
{
|
|
437
|
+
"data-disabled": stepState?.disabled ? "" : void 0,
|
|
438
|
+
"data-orientation": orientation,
|
|
439
|
+
"data-state": dataState,
|
|
440
|
+
"data-slot": "stepper-item",
|
|
441
|
+
dir: context.dir,
|
|
442
|
+
...itemProps,
|
|
443
|
+
ref,
|
|
444
|
+
className: cn(
|
|
445
|
+
"relative flex items-center not-last:flex-1",
|
|
446
|
+
orientation === "horizontal" ? "flex-row" : "flex-col",
|
|
447
|
+
className
|
|
448
|
+
),
|
|
449
|
+
children
|
|
450
|
+
}
|
|
451
|
+
) });
|
|
452
|
+
}
|
|
453
|
+
function StepperTrigger(props) {
|
|
454
|
+
const {
|
|
455
|
+
asChild,
|
|
456
|
+
onClick: onClickProp,
|
|
457
|
+
onFocus: onFocusProp,
|
|
458
|
+
onKeyDown: onKeyDownProp,
|
|
459
|
+
onMouseDown: onMouseDownProp,
|
|
460
|
+
disabled,
|
|
461
|
+
className,
|
|
462
|
+
ref,
|
|
463
|
+
...triggerProps
|
|
464
|
+
} = props;
|
|
465
|
+
const context = useStepperContext(TRIGGER_NAME);
|
|
466
|
+
const itemContext = useStepperItemContext(TRIGGER_NAME);
|
|
467
|
+
const itemValue = itemContext.value;
|
|
468
|
+
const store = useStoreContext(TRIGGER_NAME);
|
|
469
|
+
const focusContext = useFocusContext(TRIGGER_NAME);
|
|
470
|
+
const value = useStore((state) => state.value);
|
|
471
|
+
const steps = useStore((state) => state.steps);
|
|
472
|
+
const stepState = useStore((state) => state.steps.get(itemValue));
|
|
473
|
+
const propsRef = useAsRef({
|
|
474
|
+
onClick: onClickProp,
|
|
475
|
+
onFocus: onFocusProp,
|
|
476
|
+
onKeyDown: onKeyDownProp,
|
|
477
|
+
onMouseDown: onMouseDownProp
|
|
478
|
+
});
|
|
479
|
+
const activationMode = context.activationMode;
|
|
480
|
+
const orientation = context.orientation;
|
|
481
|
+
const loop = context.loop;
|
|
482
|
+
const stepIndex = Array.from(steps.keys()).indexOf(itemValue);
|
|
483
|
+
const stepPosition = stepIndex + 1;
|
|
484
|
+
const stepCount = steps.size;
|
|
485
|
+
const triggerId = getId(context.rootId, "trigger", itemValue);
|
|
486
|
+
const contentId = getId(context.rootId, "content", itemValue);
|
|
487
|
+
const titleId = getId(context.rootId, "title", itemValue);
|
|
488
|
+
const descriptionId = getId(context.rootId, "description", itemValue);
|
|
489
|
+
const isDisabled = disabled || stepState?.disabled || context.disabled;
|
|
490
|
+
const isActive = value === itemValue;
|
|
491
|
+
const isTabStop = focusContext.tabStopId === triggerId;
|
|
492
|
+
const dataState = getDataState(value, itemValue, stepState, steps);
|
|
493
|
+
const triggerRef = React.useRef(null);
|
|
494
|
+
const composedRef = useComposedRefs(ref, triggerRef);
|
|
495
|
+
const isArrowKeyPressedRef = React.useRef(false);
|
|
496
|
+
const isMouseClickRef = React.useRef(false);
|
|
497
|
+
React.useEffect(() => {
|
|
498
|
+
function onKeyDown2(event) {
|
|
499
|
+
if (ARROW_KEYS.includes(event.key)) {
|
|
500
|
+
isArrowKeyPressedRef.current = true;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
function onKeyUp() {
|
|
504
|
+
isArrowKeyPressedRef.current = false;
|
|
505
|
+
}
|
|
506
|
+
document.addEventListener("keydown", onKeyDown2);
|
|
507
|
+
document.addEventListener("keyup", onKeyUp);
|
|
508
|
+
return () => {
|
|
509
|
+
document.removeEventListener("keydown", onKeyDown2);
|
|
510
|
+
document.removeEventListener("keyup", onKeyUp);
|
|
511
|
+
};
|
|
512
|
+
}, []);
|
|
513
|
+
useIsomorphicLayoutEffect(() => {
|
|
514
|
+
focusContext.onItemRegister({
|
|
515
|
+
id: triggerId,
|
|
516
|
+
ref: triggerRef,
|
|
517
|
+
value: itemValue,
|
|
518
|
+
active: isTabStop,
|
|
519
|
+
disabled: !!isDisabled
|
|
520
|
+
});
|
|
521
|
+
if (!isDisabled) {
|
|
522
|
+
focusContext.onFocusableItemAdd();
|
|
523
|
+
}
|
|
524
|
+
return () => {
|
|
525
|
+
focusContext.onItemUnregister(triggerId);
|
|
526
|
+
if (!isDisabled) {
|
|
527
|
+
focusContext.onFocusableItemRemove();
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
}, [focusContext, triggerId, itemValue, isTabStop, isDisabled]);
|
|
531
|
+
const onClick = React.useCallback(
|
|
532
|
+
async (event) => {
|
|
533
|
+
propsRef.current.onClick?.(event);
|
|
534
|
+
if (event.defaultPrevented) return;
|
|
535
|
+
if (!isDisabled && !context.nonInteractive) {
|
|
536
|
+
const currentStepIndex = Array.from(steps.keys()).indexOf(value ?? "");
|
|
537
|
+
const targetStepIndex = Array.from(steps.keys()).indexOf(itemValue);
|
|
538
|
+
const direction = targetStepIndex > currentStepIndex ? "next" : "prev";
|
|
539
|
+
await store.setStateWithValidation(itemValue, direction);
|
|
540
|
+
}
|
|
541
|
+
},
|
|
542
|
+
[isDisabled, context.nonInteractive, store, itemValue, value, steps, propsRef]
|
|
543
|
+
);
|
|
544
|
+
const onFocus = React.useCallback(
|
|
545
|
+
async (event) => {
|
|
546
|
+
propsRef.current.onFocus?.(event);
|
|
547
|
+
if (event.defaultPrevented) return;
|
|
548
|
+
focusContext.onItemFocus(triggerId);
|
|
549
|
+
const isKeyboardFocus = !isMouseClickRef.current;
|
|
550
|
+
if (!isActive && !isDisabled && activationMode !== "manual" && !context.nonInteractive && isKeyboardFocus) {
|
|
551
|
+
const currentStepIndex = Array.from(steps.keys()).indexOf(value || "");
|
|
552
|
+
const targetStepIndex = Array.from(steps.keys()).indexOf(itemValue);
|
|
553
|
+
const direction = targetStepIndex > currentStepIndex ? "next" : "prev";
|
|
554
|
+
await store.setStateWithValidation(itemValue, direction);
|
|
555
|
+
}
|
|
556
|
+
isMouseClickRef.current = false;
|
|
557
|
+
},
|
|
558
|
+
[
|
|
559
|
+
focusContext,
|
|
560
|
+
triggerId,
|
|
561
|
+
activationMode,
|
|
562
|
+
isActive,
|
|
563
|
+
isDisabled,
|
|
564
|
+
context.nonInteractive,
|
|
565
|
+
store,
|
|
566
|
+
itemValue,
|
|
567
|
+
value,
|
|
568
|
+
steps,
|
|
569
|
+
propsRef
|
|
570
|
+
]
|
|
571
|
+
);
|
|
572
|
+
const onKeyDown = React.useCallback(
|
|
573
|
+
async (event) => {
|
|
574
|
+
propsRef.current.onKeyDown?.(event);
|
|
575
|
+
if (event.defaultPrevented) return;
|
|
576
|
+
if (event.key === "Enter" && context.nonInteractive) {
|
|
577
|
+
event.preventDefault();
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
if ((event.key === "Enter" || event.key === " ") && activationMode === "manual" && !context.nonInteractive) {
|
|
581
|
+
event.preventDefault();
|
|
582
|
+
if (!isDisabled && triggerRef.current) {
|
|
583
|
+
triggerRef.current.click();
|
|
584
|
+
}
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
if (event.key === "Tab" && event.shiftKey) {
|
|
588
|
+
focusContext.onItemShiftTab();
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
if (event.target !== event.currentTarget) return;
|
|
592
|
+
const focusIntent = getFocusIntent(event, context.dir, orientation);
|
|
593
|
+
if (focusIntent !== void 0) {
|
|
594
|
+
if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;
|
|
595
|
+
event.preventDefault();
|
|
596
|
+
const items = focusContext.getItems().filter((item) => !item.disabled);
|
|
597
|
+
let candidateRefs = items.map((item) => item.ref);
|
|
598
|
+
if (focusIntent === "last") {
|
|
599
|
+
candidateRefs.reverse();
|
|
600
|
+
} else if (focusIntent === "prev" || focusIntent === "next") {
|
|
601
|
+
if (focusIntent === "prev") candidateRefs.reverse();
|
|
602
|
+
const currentIndex = candidateRefs.findIndex((ref2) => ref2.current === event.currentTarget);
|
|
603
|
+
candidateRefs = loop ? wrapArray(candidateRefs, currentIndex + 1) : candidateRefs.slice(currentIndex + 1);
|
|
604
|
+
}
|
|
605
|
+
if (store.hasValidation() && candidateRefs.length > 0) {
|
|
606
|
+
const nextRef = candidateRefs[0];
|
|
607
|
+
const nextElement = nextRef?.current;
|
|
608
|
+
const nextItem = items.find((item) => item.ref.current === nextElement);
|
|
609
|
+
if (nextItem && nextItem.value !== itemValue) {
|
|
610
|
+
const currentStepIndex = Array.from(steps.keys()).indexOf(value || "");
|
|
611
|
+
const targetStepIndex = Array.from(steps.keys()).indexOf(nextItem.value);
|
|
612
|
+
const direction = targetStepIndex > currentStepIndex ? "next" : "prev";
|
|
613
|
+
if (direction === "next") {
|
|
614
|
+
const isValid = await store.setStateWithValidation(nextItem.value, direction);
|
|
615
|
+
if (!isValid) return;
|
|
616
|
+
} else {
|
|
617
|
+
store.setState("value", nextItem.value);
|
|
618
|
+
}
|
|
619
|
+
queueMicrotask(() => nextElement?.focus());
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
queueMicrotask(() => focusFirst(candidateRefs));
|
|
624
|
+
}
|
|
625
|
+
},
|
|
626
|
+
[
|
|
627
|
+
focusContext,
|
|
628
|
+
context.nonInteractive,
|
|
629
|
+
context.dir,
|
|
630
|
+
activationMode,
|
|
631
|
+
orientation,
|
|
632
|
+
loop,
|
|
633
|
+
isDisabled,
|
|
634
|
+
store,
|
|
635
|
+
propsRef,
|
|
636
|
+
itemValue,
|
|
637
|
+
value,
|
|
638
|
+
steps
|
|
639
|
+
]
|
|
640
|
+
);
|
|
641
|
+
const onMouseDown = React.useCallback(
|
|
642
|
+
(event) => {
|
|
643
|
+
propsRef.current.onMouseDown?.(event);
|
|
644
|
+
if (event.defaultPrevented) return;
|
|
645
|
+
isMouseClickRef.current = true;
|
|
646
|
+
if (isDisabled) {
|
|
647
|
+
event.preventDefault();
|
|
648
|
+
} else {
|
|
649
|
+
focusContext.onItemFocus(triggerId);
|
|
650
|
+
}
|
|
651
|
+
},
|
|
652
|
+
[focusContext, triggerId, isDisabled, propsRef]
|
|
653
|
+
);
|
|
654
|
+
const TriggerPrimitive = asChild ? Slot : "button";
|
|
655
|
+
return /* @__PURE__ */ jsx(
|
|
656
|
+
TriggerPrimitive,
|
|
657
|
+
{
|
|
658
|
+
id: triggerId,
|
|
659
|
+
role: "tab",
|
|
660
|
+
type: "button",
|
|
661
|
+
"aria-controls": contentId,
|
|
662
|
+
"aria-current": isActive ? "step" : void 0,
|
|
663
|
+
"aria-describedby": `${titleId} ${descriptionId}`,
|
|
664
|
+
"aria-posinset": stepPosition,
|
|
665
|
+
"aria-selected": isActive,
|
|
666
|
+
"aria-setsize": stepCount,
|
|
667
|
+
"data-disabled": isDisabled ? "" : void 0,
|
|
668
|
+
"data-state": dataState,
|
|
669
|
+
"data-slot": "stepper-trigger",
|
|
670
|
+
disabled: isDisabled,
|
|
671
|
+
tabIndex: isTabStop ? 0 : -1,
|
|
672
|
+
...triggerProps,
|
|
673
|
+
ref: composedRef,
|
|
674
|
+
className: cn(
|
|
675
|
+
/*
|
|
676
|
+
* ⚠ Khác thượng nguồn:
|
|
677
|
+
* - Vòng focus theo khuôn `Checkbox`/`RadioGroup` của gói, thay cho `ring-[3px]` của bản gốc.
|
|
678
|
+
* - Lỗi (`aria-invalid`) viền bằng `--destructive-ink` — VAI TRÒ viền trên nền trang (hợp
|
|
679
|
+
* đồng §1 của docs/hop-dong-mau.md); bản gốc dùng `border-destructive` là token TÔ NỀN.
|
|
680
|
+
*/
|
|
681
|
+
"inline-flex items-center justify-center gap-3 rounded-md text-left transition-all outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive-ink aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
682
|
+
"not-has-data-[slot=description]:rounded-full not-has-data-[slot=title]:rounded-full",
|
|
683
|
+
className
|
|
684
|
+
),
|
|
685
|
+
onClick,
|
|
686
|
+
onFocus,
|
|
687
|
+
onKeyDown,
|
|
688
|
+
onMouseDown
|
|
689
|
+
}
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
function StepperIndicator(props) {
|
|
693
|
+
const { className, children, asChild, ref, ...indicatorProps } = props;
|
|
694
|
+
const context = useStepperContext(INDICATOR_NAME);
|
|
695
|
+
const itemContext = useStepperItemContext(INDICATOR_NAME);
|
|
696
|
+
const value = useStore((state) => state.value);
|
|
697
|
+
const itemValue = itemContext.value;
|
|
698
|
+
const stepState = useStore((state) => state.steps.get(itemValue));
|
|
699
|
+
const steps = useStore((state) => state.steps);
|
|
700
|
+
const stepPosition = Array.from(steps.keys()).indexOf(itemValue) + 1;
|
|
701
|
+
const dataState = getDataState(value, itemValue, stepState, steps);
|
|
702
|
+
const IndicatorPrimitive = asChild ? Slot : "div";
|
|
703
|
+
return /* @__PURE__ */ jsx(
|
|
704
|
+
IndicatorPrimitive,
|
|
705
|
+
{
|
|
706
|
+
"data-state": dataState,
|
|
707
|
+
"data-slot": "stepper-indicator",
|
|
708
|
+
dir: context.dir,
|
|
709
|
+
...indicatorProps,
|
|
710
|
+
ref,
|
|
711
|
+
className: cn(
|
|
712
|
+
/*
|
|
713
|
+
* ⚠ Khác thượng nguồn — màu đi qua token VAI TRÒ (docs/hop-dong-mau.md §1, §3):
|
|
714
|
+
* - Lúc nghỉ: viền `--control-edge` thay `border-muted`. Ô chỉ báo là HÌNH của chính nút
|
|
715
|
+
* bước, nên viền của nó là viền control; `--muted` là token bề mặt, đem làm viền thì bảng
|
|
716
|
+
* tương phản cao không kéo lên được. Ở bảng mặc định `--control-edge` nhạt đúng như bản gốc.
|
|
717
|
+
* - Đang làm/đã xong: nền ĐẶC `bg-primary` + chữ/tick `text-primary-foreground` (giữ nguyên),
|
|
718
|
+
* nhưng viền là `--primary-ink` chứ không `border-primary`: nền vàng đặc chỉ ~1,86:1 với
|
|
719
|
+
* nền trang, nên chính VIỀN mới là dấu hiệu trạng thái đạt 3:1 (6,51:1 ở bảng tương phản cao).
|
|
720
|
+
* - Chữ lúc nghỉ viết `data-[state=inactive]:text-muted-foreground` thay cho lớp trần: CSS y
|
|
721
|
+
* hệt (ba trạng thái loại trừ nhau), nhưng cổng `lint:a11y` không ghép nhầm chữ xám với nền
|
|
722
|
+
* vàng của trạng thái đang làm — cặp đó không bao giờ cùng xuất hiện.
|
|
723
|
+
*/
|
|
724
|
+
"flex size-7 shrink-0 items-center justify-center rounded-full border-2 border-control-edge bg-background text-sm font-medium data-[state=inactive]:text-muted-foreground transition-colors data-[state=active]:border-primary-ink data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=completed]:border-primary-ink data-[state=completed]:bg-primary data-[state=completed]:text-primary-foreground",
|
|
725
|
+
className
|
|
726
|
+
),
|
|
727
|
+
children: typeof children === "function" ? children(dataState) : children ? children : dataState === "completed" ? (
|
|
728
|
+
/*
|
|
729
|
+
* ⚠ Khác thượng nguồn: bản gốc chỉ vẽ dấu tick. Trigger chỉ chứa ô chỉ báo (demo mặc định
|
|
730
|
+
* của Dice UI) thì bước đã xong thành một nút KHÔNG TÊN — con số vốn là tên nút đã bị dấu
|
|
731
|
+
* tick thay mất. Thêm chữ `sr-only` giữ lại con số và nói luôn trạng thái.
|
|
732
|
+
*/
|
|
733
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
734
|
+
/* @__PURE__ */ jsx(Check, { "aria-hidden": "true", className: "size-4" }),
|
|
735
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: context.labels.completedStep(stepPosition) })
|
|
736
|
+
] })
|
|
737
|
+
) : stepPosition
|
|
738
|
+
}
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
function StepperSeparator(props) {
|
|
742
|
+
const { className, asChild, forceMount = false, ref, ...separatorProps } = props;
|
|
743
|
+
const context = useStepperContext(SEPARATOR_NAME);
|
|
744
|
+
const itemContext = useStepperItemContext(SEPARATOR_NAME);
|
|
745
|
+
const value = useStore((state) => state.value);
|
|
746
|
+
const steps = useStore((state) => state.steps);
|
|
747
|
+
const orientation = context.orientation;
|
|
748
|
+
const stepIndex = Array.from(steps.keys()).indexOf(itemContext.value);
|
|
749
|
+
const isLastStep = stepIndex === steps.size - 1;
|
|
750
|
+
if (isLastStep && !forceMount) return null;
|
|
751
|
+
const dataState = getDataState(value, itemContext.value, itemContext.stepState, steps, "separator");
|
|
752
|
+
const SeparatorPrimitive = asChild ? Slot : "div";
|
|
753
|
+
return /* @__PURE__ */ jsx(
|
|
754
|
+
SeparatorPrimitive,
|
|
755
|
+
{
|
|
756
|
+
"aria-hidden": "true",
|
|
757
|
+
"data-orientation": orientation,
|
|
758
|
+
"data-state": dataState,
|
|
759
|
+
"data-slot": "stepper-separator",
|
|
760
|
+
dir: context.dir,
|
|
761
|
+
...separatorProps,
|
|
762
|
+
ref,
|
|
763
|
+
className: cn(
|
|
764
|
+
/*
|
|
765
|
+
* ⚠ Khác thượng nguồn: đoạn nối ĐÃ XONG mang nghĩa tiến độ (phi văn bản, 3:1) → `--primary-ink`
|
|
766
|
+
* thay `bg-primary` (token tô nền, ~1,86:1 với nền trang). Đoạn CHƯA tới giữ `bg-border`:
|
|
767
|
+
* sợi tóc 1px, thuần trang trí.
|
|
768
|
+
*/
|
|
769
|
+
"bg-border transition-colors data-[state=active]:bg-primary-ink data-[state=completed]:bg-primary-ink",
|
|
770
|
+
orientation === "horizontal" ? "h-px flex-1" : "h-10 w-px",
|
|
771
|
+
className
|
|
772
|
+
)
|
|
773
|
+
}
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
function StepperTitle(props) {
|
|
777
|
+
const { className, asChild, ref, ...titleProps } = props;
|
|
778
|
+
const context = useStepperContext(TITLE_NAME);
|
|
779
|
+
const itemContext = useStepperItemContext(TITLE_NAME);
|
|
780
|
+
const titleId = getId(context.rootId, "title", itemContext.value);
|
|
781
|
+
const TitlePrimitive = asChild ? Slot : "span";
|
|
782
|
+
return /* @__PURE__ */ jsx(
|
|
783
|
+
TitlePrimitive,
|
|
784
|
+
{
|
|
785
|
+
id: titleId,
|
|
786
|
+
"data-slot": "title",
|
|
787
|
+
dir: context.dir,
|
|
788
|
+
...titleProps,
|
|
789
|
+
ref,
|
|
790
|
+
className: cn("text-sm font-medium", className)
|
|
791
|
+
}
|
|
792
|
+
);
|
|
793
|
+
}
|
|
794
|
+
function StepperDescription(props) {
|
|
795
|
+
const { className, asChild, ref, ...descriptionProps } = props;
|
|
796
|
+
const context = useStepperContext(DESCRIPTION_NAME);
|
|
797
|
+
const itemContext = useStepperItemContext(DESCRIPTION_NAME);
|
|
798
|
+
const descriptionId = getId(context.rootId, "description", itemContext.value);
|
|
799
|
+
const DescriptionPrimitive = asChild ? Slot : "span";
|
|
800
|
+
return /* @__PURE__ */ jsx(
|
|
801
|
+
DescriptionPrimitive,
|
|
802
|
+
{
|
|
803
|
+
id: descriptionId,
|
|
804
|
+
"data-slot": "description",
|
|
805
|
+
dir: context.dir,
|
|
806
|
+
...descriptionProps,
|
|
807
|
+
ref,
|
|
808
|
+
className: cn("text-xs text-muted-foreground", className)
|
|
809
|
+
}
|
|
810
|
+
);
|
|
811
|
+
}
|
|
812
|
+
function StepperContent(props) {
|
|
813
|
+
const { value: valueProp, asChild, forceMount = false, ref, className, ...contentProps } = props;
|
|
814
|
+
const context = useStepperContext(CONTENT_NAME);
|
|
815
|
+
const value = useStore((state) => state.value);
|
|
816
|
+
const contentId = getId(context.rootId, "content", valueProp);
|
|
817
|
+
const triggerId = getId(context.rootId, "trigger", valueProp);
|
|
818
|
+
if (valueProp !== value && !forceMount) return null;
|
|
819
|
+
const ContentPrimitive = asChild ? Slot : "div";
|
|
820
|
+
return /* @__PURE__ */ jsx(
|
|
821
|
+
ContentPrimitive,
|
|
822
|
+
{
|
|
823
|
+
id: contentId,
|
|
824
|
+
role: "tabpanel",
|
|
825
|
+
"aria-labelledby": triggerId,
|
|
826
|
+
"data-slot": "stepper-content",
|
|
827
|
+
dir: context.dir,
|
|
828
|
+
...contentProps,
|
|
829
|
+
ref,
|
|
830
|
+
className: cn("flex-1 outline-none", className)
|
|
831
|
+
}
|
|
832
|
+
);
|
|
833
|
+
}
|
|
834
|
+
function StepperPrev(props) {
|
|
835
|
+
const { asChild, onClick: onClickProp, disabled, children, ...prevProps } = props;
|
|
836
|
+
const context = useStepperContext(PREV_NAME);
|
|
837
|
+
const store = useStoreContext(PREV_NAME);
|
|
838
|
+
const value = useStore((state) => state.value);
|
|
839
|
+
const steps = useStore((state) => state.steps);
|
|
840
|
+
const propsRef = useAsRef({
|
|
841
|
+
onClick: onClickProp
|
|
842
|
+
});
|
|
843
|
+
const stepKeys = Array.from(steps.keys());
|
|
844
|
+
const currentIndex = value ? stepKeys.indexOf(value) : -1;
|
|
845
|
+
const isDisabled = disabled || currentIndex <= 0;
|
|
846
|
+
const onClick = React.useCallback(
|
|
847
|
+
async (event) => {
|
|
848
|
+
propsRef.current.onClick?.(event);
|
|
849
|
+
if (event.defaultPrevented || isDisabled) return;
|
|
850
|
+
const prevIndex = Math.max(currentIndex - 1, 0);
|
|
851
|
+
const prevStepValue = stepKeys[prevIndex];
|
|
852
|
+
if (prevStepValue) {
|
|
853
|
+
store.setState("value", prevStepValue);
|
|
854
|
+
}
|
|
855
|
+
},
|
|
856
|
+
[propsRef, isDisabled, currentIndex, stepKeys, store]
|
|
857
|
+
);
|
|
858
|
+
const PrevPrimitive = asChild ? Slot : "button";
|
|
859
|
+
return /* @__PURE__ */ jsx(PrevPrimitive, { type: "button", "data-slot": "stepper-prev", disabled: isDisabled, ...prevProps, onClick, children: asChild ? children : children ?? context.labels.prev });
|
|
860
|
+
}
|
|
861
|
+
function StepperNext(props) {
|
|
862
|
+
const { asChild, onClick: onClickProp, disabled, children, ...nextProps } = props;
|
|
863
|
+
const context = useStepperContext(NEXT_NAME);
|
|
864
|
+
const store = useStoreContext(NEXT_NAME);
|
|
865
|
+
const value = useStore((state) => state.value);
|
|
866
|
+
const steps = useStore((state) => state.steps);
|
|
867
|
+
const propsRef = useAsRef({
|
|
868
|
+
onClick: onClickProp
|
|
869
|
+
});
|
|
870
|
+
const stepKeys = Array.from(steps.keys());
|
|
871
|
+
const currentIndex = value ? stepKeys.indexOf(value) : -1;
|
|
872
|
+
const isDisabled = disabled || currentIndex >= stepKeys.length - 1;
|
|
873
|
+
const onClick = React.useCallback(
|
|
874
|
+
async (event) => {
|
|
875
|
+
propsRef.current.onClick?.(event);
|
|
876
|
+
if (event.defaultPrevented || isDisabled) return;
|
|
877
|
+
const nextIndex = Math.min(currentIndex + 1, stepKeys.length - 1);
|
|
878
|
+
const nextStepValue = stepKeys[nextIndex];
|
|
879
|
+
if (nextStepValue) {
|
|
880
|
+
await store.setStateWithValidation(nextStepValue, "next");
|
|
881
|
+
}
|
|
882
|
+
},
|
|
883
|
+
[propsRef, isDisabled, currentIndex, stepKeys, store]
|
|
884
|
+
);
|
|
885
|
+
const NextPrimitive = asChild ? Slot : "button";
|
|
886
|
+
return /* @__PURE__ */ jsx(NextPrimitive, { type: "button", "data-slot": "stepper-next", disabled: isDisabled, ...nextProps, onClick, children: asChild ? children : children ?? context.labels.next });
|
|
887
|
+
}
|
|
888
|
+
export {
|
|
889
|
+
Stepper,
|
|
890
|
+
StepperContent,
|
|
891
|
+
StepperDescription,
|
|
892
|
+
StepperIndicator,
|
|
893
|
+
StepperItem,
|
|
894
|
+
StepperList,
|
|
895
|
+
StepperNext,
|
|
896
|
+
StepperPrev,
|
|
897
|
+
StepperSeparator,
|
|
898
|
+
StepperTitle,
|
|
899
|
+
StepperTrigger,
|
|
900
|
+
useStore as useStepper
|
|
901
|
+
};
|
|
902
|
+
//# sourceMappingURL=stepper.js.map
|