@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ui/breadcrumb.tsx"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/breadcrumb.tsx"],"sourcesContent":["\"use client\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { ChevronRight, MoreHorizontal } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { useComitorMessages } from \"../../i18n/locale-provider.js\";\nimport { cn } from \"../../lib/cn.js\";\n\n/**\n * Breadcrumb — primitive dựng đường dẫn phân cấp.\n * Chuỗi cho trình đọc màn hình theo `ComitorLocaleProvider` (namespace `breadcrumb`, mặc định\n * tiếng Anh); override từng chỗ qua `aria-label` / `srLabel`.\n *\n * `\"use client\"` từ `3.0.0`: tên landmark của `<nav>` và nhãn của `BreadcrumbEllipsis` đọc từ\n * provider, mà context chỉ đọc được ở client. Trước đó file này tĩnh và ghim cứng tiếng Việt.\n * Không prop nào là hàm/component nên Server Component (vd `PageHeader`) vẫn render được nó.\n * Con của `BreadcrumbLink asChild` nay đi qua ranh giới RSC — tới dạng element lười thì `Slot`\n * (`@radix-ui/react-slot` 1.2.4) tự mở bằng `use()`.\n *\n * Điều hướng: bọc `next/link` bằng `<BreadcrumbLink asChild><Link …/></BreadcrumbLink>`\n * để primitive không phụ thuộc `next/*`.\n */\n\nexport type BreadcrumbProps = React.ComponentProps<\"nav\">;\nexport type BreadcrumbListProps = React.ComponentProps<\"ol\">;\nexport type BreadcrumbItemProps = React.ComponentProps<\"li\">;\nexport type BreadcrumbLinkProps = React.ComponentProps<\"a\"> & { asChild?: boolean };\nexport type BreadcrumbPageProps = React.ComponentProps<\"span\">;\nexport type BreadcrumbSeparatorProps = React.ComponentProps<\"li\">;\nexport type BreadcrumbEllipsisProps = React.ComponentProps<\"span\"> & {\n /** Nhãn chỉ dành cho trình đọc màn hình. Mặc định: khoá `ellipsisLabel` của namespace `breadcrumb`. */\n srLabel?: string;\n};\n\nfunction Breadcrumb({ ...props }: BreadcrumbProps) {\n const t = useComitorMessages(\"breadcrumb\");\n return <nav aria-label={t.navLabel} data-slot=\"breadcrumb\" {...props} />;\n}\n\nfunction BreadcrumbList({ className, ...props }: BreadcrumbListProps) {\n return (\n <ol\n data-slot=\"breadcrumb-list\"\n className={cn(\n \"text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbItem({ className, ...props }: BreadcrumbItemProps) {\n return <li data-slot=\"breadcrumb-item\" className={cn(\"inline-flex items-center gap-1.5\", className)} {...props} />;\n}\n\nfunction BreadcrumbLink({ asChild, className, ...props }: BreadcrumbLinkProps) {\n const Comp = asChild ? Slot : \"a\";\n\n return (\n <Comp\n data-slot=\"breadcrumb-link\"\n className={cn(\"hover:text-foreground transition-colors duration-150 ease-out\", className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbPage({ className, ...props }: BreadcrumbPageProps) {\n return (\n // biome-ignore lint/a11y/useFocusableInteractive: giữ nguyên markup shadcn — mục hiện tại cố tình KHÔNG focus được (aria-disabled), chỉ mượn role=\"link\" để trình đọc màn hình đọc đúng ngữ cảnh\n <span\n data-slot=\"breadcrumb-page\"\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn(\"text-foreground font-normal\", className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbSeparator({ children, className, ...props }: BreadcrumbSeparatorProps) {\n return (\n <li\n data-slot=\"breadcrumb-separator\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"[&>svg]:size-3.5\", className)}\n {...props}\n >\n {children ?? <ChevronRight />}\n </li>\n );\n}\n\nfunction BreadcrumbEllipsis({ className, srLabel: srLabelProp, ...props }: BreadcrumbEllipsisProps) {\n const t = useComitorMessages(\"breadcrumb\");\n const srLabel = srLabelProp ?? t.ellipsisLabel;\n return (\n <span\n data-slot=\"breadcrumb-ellipsis\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"flex size-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontal className=\"size-4\" />\n <span className=\"sr-only\">{srLabel}</span>\n </span>\n );\n}\n\nexport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator\n};\n"],"mappings":";AAoCS,cAgEL,YAhEK;AAlCT,SAAS,YAAY;AACrB,SAAS,cAAc,sBAAsB;AAE7C,SAAS,0BAA0B;AACnC,SAAS,UAAU;AA4BnB,SAAS,WAAW,EAAE,GAAG,MAAM,GAAoB;AACjD,QAAM,IAAI,mBAAmB,YAAY;AACzC,SAAO,oBAAC,SAAI,cAAY,EAAE,UAAU,aAAU,cAAc,GAAG,OAAO;AACxE;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAwB;AACpE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAwB;AACpE,SAAO,oBAAC,QAAG,aAAU,mBAAkB,WAAW,GAAG,oCAAoC,SAAS,GAAI,GAAG,OAAO;AAClH;AAEA,SAAS,eAAe,EAAE,SAAS,WAAW,GAAG,MAAM,GAAwB;AAC7E,QAAM,OAAO,UAAU,OAAO;AAE9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,iEAAiE,SAAS;AAAA,MACvF,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAwB;AACpE;AAAA;AAAA,IAEE;AAAA,MAAC;AAAA;AAAA,QACC,aAAU;AAAA,QACV,MAAK;AAAA,QACL,iBAAc;AAAA,QACd,gBAAa;AAAA,QACb,WAAW,GAAG,+BAA+B,SAAS;AAAA,QACrD,GAAG;AAAA;AAAA,IACN;AAAA;AAEJ;AAEA,SAAS,oBAAoB,EAAE,UAAU,WAAW,GAAG,MAAM,GAA6B;AACxF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,eAAY;AAAA,MACZ,WAAW,GAAG,oBAAoB,SAAS;AAAA,MAC1C,GAAG;AAAA,MAEH,sBAAY,oBAAC,gBAAa;AAAA;AAAA,EAC7B;AAEJ;AAEA,SAAS,mBAAmB,EAAE,WAAW,SAAS,aAAa,GAAG,MAAM,GAA4B;AAClG,QAAM,IAAI,mBAAmB,YAAY;AACzC,QAAM,UAAU,eAAe,EAAE;AACjC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,eAAY;AAAA,MACZ,WAAW,GAAG,2CAA2C,SAAS;AAAA,MACjE,GAAG;AAAA,MAEJ;AAAA,4BAAC,kBAAe,WAAU,UAAS;AAAA,QACnC,oBAAC,UAAK,WAAU,WAAW,mBAAQ;AAAA;AAAA;AAAA,EACrC;AAEJ;","names":[]}
|
|
@@ -3,8 +3,8 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
|
|
5
5
|
declare const buttonVariants: (props?: ({
|
|
6
|
-
variant?: "link" | "default" | "
|
|
7
|
-
size?: "
|
|
6
|
+
variant?: "link" | "default" | "destructive" | "primary" | "secondary" | "outline" | "ghost" | null | undefined;
|
|
7
|
+
size?: "default" | "sm" | "md" | "lg" | "icon" | "icon-sm" | "icon-lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface ButtonProps extends React.ComponentProps<"button">, VariantProps<typeof buttonVariants> {
|
|
10
10
|
/** Render ra chính phần tử con (Radix Slot) thay vì thẻ <button>. */
|
|
@@ -6,13 +6,20 @@ import 'class-variance-authority';
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Calendar (react-day-picker v9) — lịch trần, đã map class sang token Comitor.
|
|
9
|
-
* Bản có ô nhập
|
|
9
|
+
* Bản có ô nhập ngày + preset ("Today", "Last 7 days"…) là composite
|
|
10
10
|
* `DatePicker` / `DateRangePicker` ở Tier 2.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
12
|
+
* ─ NGÔN NGỮ ─ (từ `3.0.0` theo `ComitorLocaleProvider`)
|
|
13
|
+
* · tên thứ/tháng: prop `locale` → locale date-fns của provider (`vi` hoặc `enUS`);
|
|
14
|
+
* · nhãn trình đọc màn hình (nút chuyển tháng, tên ô ngày…): prop `labels` → bản dịch mang sẵn
|
|
15
|
+
* trong `locale` nếu đó là locale của `react-day-picker/locale` → namespace `calendar` của
|
|
16
|
+
* provider. Locale date-fns trần không mang chuỗi giao diện, nên thiếu bậc cuối thì lịch đọc
|
|
17
|
+
* tiếng Anh cứng của react-day-picker giữa app tiếng Việt.
|
|
18
|
+
* Trước `3.0.0`: không truyền `locale` thì lưới lịch là `enUS` (mặc định của react-day-picker)
|
|
19
|
+
* còn tên tháng trong dropdown lại là `vi-VN` — hai nửa một lịch hai thứ tiếng.
|
|
13
20
|
*
|
|
14
|
-
* Khác bản comitor-ds: tên tháng rút gọn trong dropdown lấy theo `
|
|
15
|
-
* (
|
|
21
|
+
* Khác bản comitor-ds: tên tháng rút gọn trong dropdown lấy theo `code` của locale ĐANG HIỆU LỰC
|
|
22
|
+
* (prop hoặc provider) thay vì `"default"` — `"default"` phụ thuộc locale của môi
|
|
16
23
|
* trường chạy nên server và trình duyệt có thể ra chuỗi khác nhau → hydration mismatch.
|
|
17
24
|
*
|
|
18
25
|
* ─ Ô NGÀY ĐANG CHỌN: `bg-control-on` + `text-control-check` ─
|
|
@@ -44,7 +51,7 @@ type CalendarProps = React.ComponentProps<typeof DayPicker> & {
|
|
|
44
51
|
buttonVariant?: ButtonProps["variant"];
|
|
45
52
|
};
|
|
46
53
|
type CalendarDayButtonProps = React.ComponentProps<typeof DayButton>;
|
|
47
|
-
declare function Calendar({ className, classNames, showOutsideDays, captionLayout, buttonVariant, formatters, components, locale, ...props }: CalendarProps): React.JSX.Element;
|
|
54
|
+
declare function Calendar({ className, classNames, showOutsideDays, captionLayout, buttonVariant, formatters, components, locale: localeProp, labels: labelsProp, ...props }: CalendarProps): React.JSX.Element;
|
|
48
55
|
/**
|
|
49
56
|
* Ô ngày.
|
|
50
57
|
*
|
|
@@ -2,9 +2,34 @@
|
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
|
|
4
4
|
import * as React from "react";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
DateLib,
|
|
7
|
+
DayPicker,
|
|
8
|
+
getDefaultClassNames
|
|
9
|
+
} from "react-day-picker";
|
|
10
|
+
import { useComitorLocale, useComitorMessages } from "../../i18n/locale-provider.js";
|
|
6
11
|
import { cn } from "../../lib/cn.js";
|
|
7
12
|
import { Button, buttonVariants } from "./button.js";
|
|
13
|
+
function toDayPickerLabels(t) {
|
|
14
|
+
return {
|
|
15
|
+
labelNav: () => t.navigation,
|
|
16
|
+
labelPrevious: () => t.previousMonth,
|
|
17
|
+
labelNext: () => t.nextMonth,
|
|
18
|
+
labelMonthDropdown: () => t.monthDropdown,
|
|
19
|
+
labelYearDropdown: () => t.yearDropdown,
|
|
20
|
+
labelDayButton: (date, modifiers, options, dateLib) => t.day((dateLib ?? new DateLib(options)).format(date, "PPPP"), {
|
|
21
|
+
today: modifiers.today === true,
|
|
22
|
+
selected: modifiers.selected === true
|
|
23
|
+
}),
|
|
24
|
+
// Ô ngày khi lịch KHÔNG tương tác được — react-day-picker không báo "đã chọn" ở đây.
|
|
25
|
+
labelGridcell: (date, modifiers, options, dateLib) => t.day((dateLib ?? new DateLib(options)).format(date, "PPPP"), {
|
|
26
|
+
today: modifiers?.today === true,
|
|
27
|
+
selected: false
|
|
28
|
+
}),
|
|
29
|
+
labelWeekNumber: (weekNumber) => t.weekNumber(weekNumber),
|
|
30
|
+
labelWeekNumberHeader: () => t.weekNumberHeader
|
|
31
|
+
};
|
|
32
|
+
}
|
|
8
33
|
function Calendar({
|
|
9
34
|
className,
|
|
10
35
|
classNames,
|
|
@@ -13,16 +38,26 @@ function Calendar({
|
|
|
13
38
|
buttonVariant = "ghost",
|
|
14
39
|
formatters,
|
|
15
40
|
components,
|
|
16
|
-
locale,
|
|
41
|
+
locale: localeProp,
|
|
42
|
+
labels: labelsProp,
|
|
17
43
|
...props
|
|
18
44
|
}) {
|
|
19
45
|
const defaultClassNames = getDefaultClassNames();
|
|
20
|
-
const
|
|
46
|
+
const { dateFnsLocale } = useComitorLocale();
|
|
47
|
+
const t = useComitorMessages("calendar");
|
|
48
|
+
const locale = localeProp ?? dateFnsLocale;
|
|
49
|
+
const localeCode = locale.code ?? dateFnsLocale.code;
|
|
50
|
+
const hasLocaleLabels = locale.labels !== void 0;
|
|
51
|
+
const labels = React.useMemo(
|
|
52
|
+
() => hasLocaleLabels ? labelsProp : { ...toDayPickerLabels(t), ...labelsProp },
|
|
53
|
+
[hasLocaleLabels, t, labelsProp]
|
|
54
|
+
);
|
|
21
55
|
return /* @__PURE__ */ jsx(
|
|
22
56
|
DayPicker,
|
|
23
57
|
{
|
|
24
58
|
showOutsideDays,
|
|
25
59
|
locale,
|
|
60
|
+
labels,
|
|
26
61
|
className: cn(
|
|
27
62
|
"bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
|
|
28
63
|
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ui/calendar.tsx"],"sourcesContent":["\"use client\";\n\nimport { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from \"lucide-react\";\nimport * as React from \"react\";\nimport { type DayButton, DayPicker, getDefaultClassNames } from \"react-day-picker\";\nimport { cn } from \"../../lib/cn.js\";\nimport { Button, type ButtonProps, buttonVariants } from \"./button.js\";\n\n/**\n * Calendar (react-day-picker v9) — lịch trần, đã map class sang token Comitor.\n * Bản có ô nhập `dd/MM/yyyy` + preset (\"Hôm nay\", \"7 ngày qua\"…) là composite\n * `DatePicker` / `DateRangePicker` ở Tier 2.\n *\n * Ngôn ngữ: truyền `locale={vi}` (date-fns/locale) để đổi tên thứ/tháng.\n *\n * Khác bản comitor-ds: tên tháng rút gọn trong dropdown lấy theo `locale.code`\n * (mặc định `vi-VN`) thay vì `\"default\"` — `\"default\"` phụ thuộc locale của môi\n * trường chạy nên server và trình duyệt có thể ra chuỗi khác nhau → hydration mismatch.\n *\n * ─ Ô NGÀY ĐANG CHỌN: `bg-control-on` + `text-control-check` ─\n * Chữ của ô ngày KHÔNG đổi màu khi được chọn (nghỉ và chọn đều là bậc mực), nên \"đang chọn\" chỉ\n * còn được kể bằng NỀN ô — thông tin thị giác, ngưỡng 3:1.\n *\n * Ô ngày đang chọn là một control ở trạng thái BẬT, y như ô Checkbox đã chọn, nên nó phải đi\n * bằng CẶP token của họ control: nền `--control-on`, chữ `--control-check`. `--control-check`\n * theo định nghĩa là \"dấu đứng trên --control-on\" — ghép nó với một nền khác là hai token trôi\n * độc lập, và sẽ có ngày lệch nhau.\n *\n * ⚠ Bản trước ghép `bg-primary-ink` + `text-control-check`. Ở MỌI bảng màu trừ một, hai token đó\n * bằng nhau (`--primary-ink: var(--primary)` = `--control-on`) nên cặp sai vẫn cho ra đúng màu —\n * lỗi ngủ yên. Đến khi bảng tương phản cao sáng riêng `--control-on` lên #B48700 mà `--primary-ink`\n * ở lại gold-500 (nó còn phải làm CHỮ, ngưỡng 4,5:1) thì mới lộ: chữ mực trên #7A5800 = 2,52:1 ✗.\n * Cổng tương phản bắt được; mắt thường thì không.\n *\n * nền ô ⇄ nền lịch : 1,86:1 (bảng duyệt — khoản đã chấp nhận, cùng nhóm với rãnh Switch BẬT)\n * 3,28:1 (bảng tương phản cao) ✓\n * chữ mực trên nền ô : 10,19:1 (bảng duyệt) · 5,77:1 (tương phản cao) ✓\n *\n * ⚠ CÒN TỒN, cố ý chưa động: `today` và `range_middle` dùng `bg-accent` — 1,09:1 (light) /\n * 1,17:1 (dark) so với nền lịch. Đưa dải giữa lên 3:1 thì cả tuần biến thành một khối đặc,\n * nên đây là quyết định THIẾT KẾ (thêm viền/gạch chân cho \"hôm nay\"?) chứ không sửa được bằng\n * đổi token — để dành cho vòng riêng.\n */\n\nexport type CalendarProps = React.ComponentProps<typeof DayPicker> & {\n /** Biến thể Button dùng cho nút điều hướng tháng. */\n buttonVariant?: ButtonProps[\"variant\"];\n};\nexport type CalendarDayButtonProps = React.ComponentProps<typeof DayButton>;\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n captionLayout = \"label\",\n buttonVariant = \"ghost\",\n formatters,\n components,\n locale,\n ...props\n}: CalendarProps) {\n const defaultClassNames = getDefaultClassNames();\n const localeCode = locale?.code ?? \"vi-VN\";\n\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n locale={locale}\n className={cn(\n \"bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent\",\n String.raw`rtl:**:[.rdp-button\\_next>svg]:rotate-180`,\n String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\n className\n )}\n captionLayout={captionLayout}\n formatters={{\n formatMonthDropdown: (date) => date.toLocaleString(localeCode, { month: \"short\" }),\n ...formatters\n }}\n classNames={{\n root: cn(\"w-fit\", defaultClassNames.root),\n months: cn(\"flex gap-4 flex-col md:flex-row relative\", defaultClassNames.months),\n month: cn(\"flex flex-col w-full gap-4\", defaultClassNames.month),\n nav: cn(\"flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between\", defaultClassNames.nav),\n button_previous: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none\",\n defaultClassNames.button_previous\n ),\n button_next: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none\",\n defaultClassNames.button_next\n ),\n month_caption: cn(\n \"flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)\",\n defaultClassNames.month_caption\n ),\n dropdowns: cn(\n \"w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5\",\n defaultClassNames.dropdowns\n ),\n dropdown_root: cn(\n \"relative has-focus:outline-none border border-input shadow-xs has-focus:ring-2 has-focus:ring-ring/50 has-focus:ring-offset-2 has-focus:ring-offset-background rounded-md\",\n defaultClassNames.dropdown_root\n ),\n dropdown: cn(\"absolute bg-popover inset-0 opacity-0\", defaultClassNames.dropdown),\n caption_label: cn(\n \"select-none font-medium\",\n captionLayout === \"label\"\n ? \"text-sm\"\n : \"rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5\",\n defaultClassNames.caption_label\n ),\n table: \"w-full border-collapse\",\n weekdays: cn(\"flex\", defaultClassNames.weekdays),\n weekday: cn(\n \"text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none\",\n defaultClassNames.weekday\n ),\n week: cn(\"flex w-full mt-2\", defaultClassNames.week),\n week_number_header: cn(\"select-none w-(--cell-size)\", defaultClassNames.week_number_header),\n week_number: cn(\"text-[0.8rem] select-none text-muted-foreground\", defaultClassNames.week_number),\n day: cn(\n \"relative w-full h-full p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none\",\n defaultClassNames.day\n ),\n range_start: cn(\"rounded-l-md bg-accent\", defaultClassNames.range_start),\n range_middle: cn(\"rounded-none\", defaultClassNames.range_middle),\n range_end: cn(\"rounded-r-md bg-accent\", defaultClassNames.range_end),\n today: cn(\n \"bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none\",\n defaultClassNames.today\n ),\n outside: cn(\"text-muted-foreground aria-selected:text-muted-foreground\", defaultClassNames.outside),\n disabled: cn(\"text-muted-foreground opacity-50\", defaultClassNames.disabled),\n hidden: cn(\"invisible\", defaultClassNames.hidden),\n ...classNames\n }}\n components={{\n Root: ({ className: rootClassName, rootRef, ...rootProps }) => {\n return <div data-slot=\"calendar\" ref={rootRef} className={cn(rootClassName)} {...rootProps} />;\n },\n Chevron: ({ className: chevronClassName, orientation, ...chevronProps }) => {\n if (orientation === \"left\") {\n return <ChevronLeftIcon className={cn(\"size-4\", chevronClassName)} {...chevronProps} />;\n }\n\n if (orientation === \"right\") {\n return <ChevronRightIcon className={cn(\"size-4\", chevronClassName)} {...chevronProps} />;\n }\n\n return <ChevronDownIcon className={cn(\"size-4\", chevronClassName)} {...chevronProps} />;\n },\n DayButton: CalendarDayButton,\n WeekNumber: ({ children, week: _week, ...weekProps }) => {\n return (\n <td {...weekProps}>\n <div className=\"flex size-(--cell-size) items-center justify-center text-center\">{children}</div>\n </td>\n );\n },\n ...components\n }}\n {...props}\n />\n );\n}\n\n/**\n * Ô ngày.\n *\n * ─ `[&>span]:opacity-90` — MỨC MỜ TỐI ĐA CÒN ĐẠT AA ─\n * `<span>` là nội dung phụ app truyền vào ô ngày (số việc, chấm sự kiện…), cỡ `text-xs` = 12px\n * nên chịu ngưỡng CHỮ 4,5:1. Nút ngày VẪN bấm được và vẫn nhận focus → `opacity-*` chồng lên nó\n * KHÔNG được miễn trừ theo 1.4.3. Ca tệ nhất là ngày ĐÃ CHỌN ở theme sáng của bảng TƯƠNG PHẢN\n * CAO — chữ mực trên `bg-control-on` #B48700:\n *\n * opacity-80 → 4,43:1 ✗ ← mức cũ, KHÔNG còn đạt\n * opacity-85 → 4,79:1 ✓\n * opacity-90 → 5,15:1 ✓ ← đang dùng, còn biên cho lần chỉnh gold sau\n *\n * ⚠ Bộ số cũ ở đây (70% → 4,12:1 · 80% → 4,85:1) đo trên MỘT CẶP KHÁC: nền #7A5800 với chữ\n * TRẮNG. Từ khi bảng tương phản cao bỏ gold-500 (nâu-ô-liu, xem khối trên) và tô control bằng\n * #B48700 thì chữ quay về MỰC, ca tệ nhất chặt lại và 80% rơi xuống dưới ngưỡng. Đây là kiểu lỗi\n * mà một lần đổi token ở styles.css kéo theo, và chỉ cổng tương phản mới thấy.\n *\n * Hai bảng còn lại rộng rãi ở 90%: bảng duyệt (mực trên #E8B824) 8,60:1, dark (mực trên #F5D060)\n * 10,43:1. Các trạng thái khác cũng thoải mái: giữa khoảng & hôm nay 9,70:1 (light) · 10,05:1\n * (dark), ngày thường 10,26:1 · 11,41:1.\n */\nfunction CalendarDayButton({ className, day, modifiers, ...props }: CalendarDayButtonProps) {\n const defaultClassNames = getDefaultClassNames();\n\n const ref = React.useRef<HTMLButtonElement>(null);\n React.useEffect(() => {\n if (modifiers.focused) ref.current?.focus();\n }, [modifiers.focused]);\n\n return (\n <Button\n ref={ref}\n variant=\"ghost\"\n size=\"icon\"\n data-day={day.date.toLocaleDateString()}\n data-selected-single={\n modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle\n }\n data-range-start={modifiers.range_start}\n data-range-end={modifiers.range_end}\n data-range-middle={modifiers.range_middle}\n className={cn(\n \"data-[selected-single=true]:bg-control-on data-[selected-single=true]:text-control-check data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-control-on data-[range-start=true]:text-control-check data-[range-end=true]:bg-control-on data-[range-end=true]:text-control-check group-data-[focused=true]/day:outline-none group-data-[focused=true]/day:ring-ring/50 group-data-[focused=true]/day:ring-offset-2 group-data-[focused=true]/day:ring-offset-background dark:hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-2 data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-90\",\n defaultClassNames.day,\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Calendar, CalendarDayButton };\n"],"mappings":";AA6IiB;AA3IjB,SAAS,iBAAiB,iBAAiB,wBAAwB;AACnE,YAAY,WAAW;AACvB,SAAyB,WAAW,4BAA4B;AAChE,SAAS,UAAU;AACnB,SAAS,QAA0B,sBAAsB;AA4CzD,SAAS,SAAS;AAAA,EAChB;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAkB;AAChB,QAAM,oBAAoB,qBAAqB;AAC/C,QAAM,aAAa,QAAQ,QAAQ;AAEnC,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA,OAAO;AAAA,QACP,OAAO;AAAA,QACP;AAAA,MACF;AAAA,MACA;AAAA,MACA,YAAY;AAAA,QACV,qBAAqB,CAAC,SAAS,KAAK,eAAe,YAAY,EAAE,OAAO,QAAQ,CAAC;AAAA,QACjF,GAAG;AAAA,MACL;AAAA,MACA,YAAY;AAAA,QACV,MAAM,GAAG,SAAS,kBAAkB,IAAI;AAAA,QACxC,QAAQ,GAAG,4CAA4C,kBAAkB,MAAM;AAAA,QAC/E,OAAO,GAAG,8BAA8B,kBAAkB,KAAK;AAAA,QAC/D,KAAK,GAAG,2EAA2E,kBAAkB,GAAG;AAAA,QACxG,iBAAiB;AAAA,UACf,eAAe,EAAE,SAAS,cAAc,CAAC;AAAA,UACzC;AAAA,UACA,kBAAkB;AAAA,QACpB;AAAA,QACA,aAAa;AAAA,UACX,eAAe,EAAE,SAAS,cAAc,CAAC;AAAA,UACzC;AAAA,UACA,kBAAkB;AAAA,QACpB;AAAA,QACA,eAAe;AAAA,UACb;AAAA,UACA,kBAAkB;AAAA,QACpB;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA,kBAAkB;AAAA,QACpB;AAAA,QACA,eAAe;AAAA,UACb;AAAA,UACA,kBAAkB;AAAA,QACpB;AAAA,QACA,UAAU,GAAG,yCAAyC,kBAAkB,QAAQ;AAAA,QAChF,eAAe;AAAA,UACb;AAAA,UACA,kBAAkB,UACd,YACA;AAAA,UACJ,kBAAkB;AAAA,QACpB;AAAA,QACA,OAAO;AAAA,QACP,UAAU,GAAG,QAAQ,kBAAkB,QAAQ;AAAA,QAC/C,SAAS;AAAA,UACP;AAAA,UACA,kBAAkB;AAAA,QACpB;AAAA,QACA,MAAM,GAAG,oBAAoB,kBAAkB,IAAI;AAAA,QACnD,oBAAoB,GAAG,+BAA+B,kBAAkB,kBAAkB;AAAA,QAC1F,aAAa,GAAG,mDAAmD,kBAAkB,WAAW;AAAA,QAChG,KAAK;AAAA,UACH;AAAA,UACA,kBAAkB;AAAA,QACpB;AAAA,QACA,aAAa,GAAG,0BAA0B,kBAAkB,WAAW;AAAA,QACvE,cAAc,GAAG,gBAAgB,kBAAkB,YAAY;AAAA,QAC/D,WAAW,GAAG,0BAA0B,kBAAkB,SAAS;AAAA,QACnE,OAAO;AAAA,UACL;AAAA,UACA,kBAAkB;AAAA,QACpB;AAAA,QACA,SAAS,GAAG,6DAA6D,kBAAkB,OAAO;AAAA,QAClG,UAAU,GAAG,oCAAoC,kBAAkB,QAAQ;AAAA,QAC3E,QAAQ,GAAG,aAAa,kBAAkB,MAAM;AAAA,QAChD,GAAG;AAAA,MACL;AAAA,MACA,YAAY;AAAA,QACV,MAAM,CAAC,EAAE,WAAW,eAAe,SAAS,GAAG,UAAU,MAAM;AAC7D,iBAAO,oBAAC,SAAI,aAAU,YAAW,KAAK,SAAS,WAAW,GAAG,aAAa,GAAI,GAAG,WAAW;AAAA,QAC9F;AAAA,QACA,SAAS,CAAC,EAAE,WAAW,kBAAkB,aAAa,GAAG,aAAa,MAAM;AAC1E,cAAI,gBAAgB,QAAQ;AAC1B,mBAAO,oBAAC,mBAAgB,WAAW,GAAG,UAAU,gBAAgB,GAAI,GAAG,cAAc;AAAA,UACvF;AAEA,cAAI,gBAAgB,SAAS;AAC3B,mBAAO,oBAAC,oBAAiB,WAAW,GAAG,UAAU,gBAAgB,GAAI,GAAG,cAAc;AAAA,UACxF;AAEA,iBAAO,oBAAC,mBAAgB,WAAW,GAAG,UAAU,gBAAgB,GAAI,GAAG,cAAc;AAAA,QACvF;AAAA,QACA,WAAW;AAAA,QACX,YAAY,CAAC,EAAE,UAAU,MAAM,OAAO,GAAG,UAAU,MAAM;AACvD,iBACE,oBAAC,QAAI,GAAG,WACN,8BAAC,SAAI,WAAU,mEAAmE,UAAS,GAC7F;AAAA,QAEJ;AAAA,QACA,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAwBA,SAAS,kBAAkB,EAAE,WAAW,KAAK,WAAW,GAAG,MAAM,GAA2B;AAC1F,QAAM,oBAAoB,qBAAqB;AAE/C,QAAM,MAAM,MAAM,OAA0B,IAAI;AAChD,QAAM,UAAU,MAAM;AACpB,QAAI,UAAU,QAAS,KAAI,SAAS,MAAM;AAAA,EAC5C,GAAG,CAAC,UAAU,OAAO,CAAC;AAEtB,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,YAAU,IAAI,KAAK,mBAAmB;AAAA,MACtC,wBACE,UAAU,YAAY,CAAC,UAAU,eAAe,CAAC,UAAU,aAAa,CAAC,UAAU;AAAA,MAErF,oBAAkB,UAAU;AAAA,MAC5B,kBAAgB,UAAU;AAAA,MAC1B,qBAAmB,UAAU;AAAA,MAC7B,WAAW;AAAA,QACT;AAAA,QACA,kBAAkB;AAAA,QAClB;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/calendar.tsx"],"sourcesContent":["\"use client\";\n\nimport { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from \"lucide-react\";\nimport * as React from \"react\";\nimport {\n DateLib,\n type DayButton,\n DayPicker,\n type DayPickerLocale,\n getDefaultClassNames,\n type Labels\n} from \"react-day-picker\";\nimport { useComitorLocale, useComitorMessages } from \"../../i18n/locale-provider.js\";\nimport type { CalendarMessages } from \"../../i18n/namespaces/calendar.js\";\nimport { cn } from \"../../lib/cn.js\";\nimport { Button, type ButtonProps, buttonVariants } from \"./button.js\";\n\n/**\n * Calendar (react-day-picker v9) — lịch trần, đã map class sang token Comitor.\n * Bản có ô nhập ngày + preset (\"Today\", \"Last 7 days\"…) là composite\n * `DatePicker` / `DateRangePicker` ở Tier 2.\n *\n * ─ NGÔN NGỮ ─ (từ `3.0.0` theo `ComitorLocaleProvider`)\n * · tên thứ/tháng: prop `locale` → locale date-fns của provider (`vi` hoặc `enUS`);\n * · nhãn trình đọc màn hình (nút chuyển tháng, tên ô ngày…): prop `labels` → bản dịch mang sẵn\n * trong `locale` nếu đó là locale của `react-day-picker/locale` → namespace `calendar` của\n * provider. Locale date-fns trần không mang chuỗi giao diện, nên thiếu bậc cuối thì lịch đọc\n * tiếng Anh cứng của react-day-picker giữa app tiếng Việt.\n * Trước `3.0.0`: không truyền `locale` thì lưới lịch là `enUS` (mặc định của react-day-picker)\n * còn tên tháng trong dropdown lại là `vi-VN` — hai nửa một lịch hai thứ tiếng.\n *\n * Khác bản comitor-ds: tên tháng rút gọn trong dropdown lấy theo `code` của locale ĐANG HIỆU LỰC\n * (prop hoặc provider) thay vì `\"default\"` — `\"default\"` phụ thuộc locale của môi\n * trường chạy nên server và trình duyệt có thể ra chuỗi khác nhau → hydration mismatch.\n *\n * ─ Ô NGÀY ĐANG CHỌN: `bg-control-on` + `text-control-check` ─\n * Chữ của ô ngày KHÔNG đổi màu khi được chọn (nghỉ và chọn đều là bậc mực), nên \"đang chọn\" chỉ\n * còn được kể bằng NỀN ô — thông tin thị giác, ngưỡng 3:1.\n *\n * Ô ngày đang chọn là một control ở trạng thái BẬT, y như ô Checkbox đã chọn, nên nó phải đi\n * bằng CẶP token của họ control: nền `--control-on`, chữ `--control-check`. `--control-check`\n * theo định nghĩa là \"dấu đứng trên --control-on\" — ghép nó với một nền khác là hai token trôi\n * độc lập, và sẽ có ngày lệch nhau.\n *\n * ⚠ Bản trước ghép `bg-primary-ink` + `text-control-check`. Ở MỌI bảng màu trừ một, hai token đó\n * bằng nhau (`--primary-ink: var(--primary)` = `--control-on`) nên cặp sai vẫn cho ra đúng màu —\n * lỗi ngủ yên. Đến khi bảng tương phản cao sáng riêng `--control-on` lên #B48700 mà `--primary-ink`\n * ở lại gold-500 (nó còn phải làm CHỮ, ngưỡng 4,5:1) thì mới lộ: chữ mực trên #7A5800 = 2,52:1 ✗.\n * Cổng tương phản bắt được; mắt thường thì không.\n *\n * nền ô ⇄ nền lịch : 1,86:1 (bảng duyệt — khoản đã chấp nhận, cùng nhóm với rãnh Switch BẬT)\n * 3,28:1 (bảng tương phản cao) ✓\n * chữ mực trên nền ô : 10,19:1 (bảng duyệt) · 5,77:1 (tương phản cao) ✓\n *\n * ⚠ CÒN TỒN, cố ý chưa động: `today` và `range_middle` dùng `bg-accent` — 1,09:1 (light) /\n * 1,17:1 (dark) so với nền lịch. Đưa dải giữa lên 3:1 thì cả tuần biến thành một khối đặc,\n * nên đây là quyết định THIẾT KẾ (thêm viền/gạch chân cho \"hôm nay\"?) chứ không sửa được bằng\n * đổi token — để dành cho vòng riêng.\n */\n\nexport type CalendarProps = React.ComponentProps<typeof DayPicker> & {\n /** Biến thể Button dùng cho nút điều hướng tháng. */\n buttonVariant?: ButtonProps[\"variant\"];\n};\nexport type CalendarDayButtonProps = React.ComponentProps<typeof DayButton>;\n\n/** Bảng chữ `calendar` → prop `labels` của react-day-picker (cùng cách định dạng ngày `PPPP` của nó). */\nfunction toDayPickerLabels(t: CalendarMessages): Partial<Labels> {\n return {\n labelNav: () => t.navigation,\n labelPrevious: () => t.previousMonth,\n labelNext: () => t.nextMonth,\n labelMonthDropdown: () => t.monthDropdown,\n labelYearDropdown: () => t.yearDropdown,\n labelDayButton: (date, modifiers, options, dateLib) =>\n t.day((dateLib ?? new DateLib(options)).format(date, \"PPPP\"), {\n today: modifiers.today === true,\n selected: modifiers.selected === true\n }),\n // Ô ngày khi lịch KHÔNG tương tác được — react-day-picker không báo \"đã chọn\" ở đây.\n labelGridcell: (date, modifiers, options, dateLib) =>\n t.day((dateLib ?? new DateLib(options)).format(date, \"PPPP\"), {\n today: modifiers?.today === true,\n selected: false\n }),\n labelWeekNumber: (weekNumber) => t.weekNumber(weekNumber),\n labelWeekNumberHeader: () => t.weekNumberHeader\n };\n}\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n captionLayout = \"label\",\n buttonVariant = \"ghost\",\n formatters,\n components,\n locale: localeProp,\n labels: labelsProp,\n ...props\n}: CalendarProps) {\n const defaultClassNames = getDefaultClassNames();\n const { dateFnsLocale } = useComitorLocale();\n const t = useComitorMessages(\"calendar\");\n const locale: Partial<DayPickerLocale> = localeProp ?? dateFnsLocale;\n const localeCode = locale.code ?? dateFnsLocale.code;\n // Locale của `react-day-picker/locale` mang sẵn bản dịch nhãn → để nó thắng bảng của provider.\n // Prop `labels` của app thì thắng cả hai (react-day-picker xếp prop trên locale).\n const hasLocaleLabels = locale.labels !== undefined;\n const labels = React.useMemo(\n () => (hasLocaleLabels ? labelsProp : { ...toDayPickerLabels(t), ...labelsProp }),\n [hasLocaleLabels, t, labelsProp]\n );\n\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n locale={locale}\n labels={labels}\n className={cn(\n \"bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent\",\n String.raw`rtl:**:[.rdp-button\\_next>svg]:rotate-180`,\n String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\n className\n )}\n captionLayout={captionLayout}\n formatters={{\n formatMonthDropdown: (date) => date.toLocaleString(localeCode, { month: \"short\" }),\n ...formatters\n }}\n classNames={{\n root: cn(\"w-fit\", defaultClassNames.root),\n months: cn(\"flex gap-4 flex-col md:flex-row relative\", defaultClassNames.months),\n month: cn(\"flex flex-col w-full gap-4\", defaultClassNames.month),\n nav: cn(\"flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between\", defaultClassNames.nav),\n button_previous: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none\",\n defaultClassNames.button_previous\n ),\n button_next: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none\",\n defaultClassNames.button_next\n ),\n month_caption: cn(\n \"flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)\",\n defaultClassNames.month_caption\n ),\n dropdowns: cn(\n \"w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5\",\n defaultClassNames.dropdowns\n ),\n dropdown_root: cn(\n \"relative has-focus:outline-none border border-input shadow-xs has-focus:ring-2 has-focus:ring-ring/50 has-focus:ring-offset-2 has-focus:ring-offset-background rounded-md\",\n defaultClassNames.dropdown_root\n ),\n dropdown: cn(\"absolute bg-popover inset-0 opacity-0\", defaultClassNames.dropdown),\n caption_label: cn(\n \"select-none font-medium\",\n captionLayout === \"label\"\n ? \"text-sm\"\n : \"rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5\",\n defaultClassNames.caption_label\n ),\n table: \"w-full border-collapse\",\n weekdays: cn(\"flex\", defaultClassNames.weekdays),\n weekday: cn(\n \"text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none\",\n defaultClassNames.weekday\n ),\n week: cn(\"flex w-full mt-2\", defaultClassNames.week),\n week_number_header: cn(\"select-none w-(--cell-size)\", defaultClassNames.week_number_header),\n week_number: cn(\"text-[0.8rem] select-none text-muted-foreground\", defaultClassNames.week_number),\n day: cn(\n \"relative w-full h-full p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none\",\n defaultClassNames.day\n ),\n range_start: cn(\"rounded-l-md bg-accent\", defaultClassNames.range_start),\n range_middle: cn(\"rounded-none\", defaultClassNames.range_middle),\n range_end: cn(\"rounded-r-md bg-accent\", defaultClassNames.range_end),\n today: cn(\n \"bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none\",\n defaultClassNames.today\n ),\n outside: cn(\"text-muted-foreground aria-selected:text-muted-foreground\", defaultClassNames.outside),\n disabled: cn(\"text-muted-foreground opacity-50\", defaultClassNames.disabled),\n hidden: cn(\"invisible\", defaultClassNames.hidden),\n ...classNames\n }}\n components={{\n Root: ({ className: rootClassName, rootRef, ...rootProps }) => {\n return <div data-slot=\"calendar\" ref={rootRef} className={cn(rootClassName)} {...rootProps} />;\n },\n Chevron: ({ className: chevronClassName, orientation, ...chevronProps }) => {\n if (orientation === \"left\") {\n return <ChevronLeftIcon className={cn(\"size-4\", chevronClassName)} {...chevronProps} />;\n }\n\n if (orientation === \"right\") {\n return <ChevronRightIcon className={cn(\"size-4\", chevronClassName)} {...chevronProps} />;\n }\n\n return <ChevronDownIcon className={cn(\"size-4\", chevronClassName)} {...chevronProps} />;\n },\n DayButton: CalendarDayButton,\n WeekNumber: ({ children, week: _week, ...weekProps }) => {\n return (\n <td {...weekProps}>\n <div className=\"flex size-(--cell-size) items-center justify-center text-center\">{children}</div>\n </td>\n );\n },\n ...components\n }}\n {...props}\n />\n );\n}\n\n/**\n * Ô ngày.\n *\n * ─ `[&>span]:opacity-90` — MỨC MỜ TỐI ĐA CÒN ĐẠT AA ─\n * `<span>` là nội dung phụ app truyền vào ô ngày (số việc, chấm sự kiện…), cỡ `text-xs` = 12px\n * nên chịu ngưỡng CHỮ 4,5:1. Nút ngày VẪN bấm được và vẫn nhận focus → `opacity-*` chồng lên nó\n * KHÔNG được miễn trừ theo 1.4.3. Ca tệ nhất là ngày ĐÃ CHỌN ở theme sáng của bảng TƯƠNG PHẢN\n * CAO — chữ mực trên `bg-control-on` #B48700:\n *\n * opacity-80 → 4,43:1 ✗ ← mức cũ, KHÔNG còn đạt\n * opacity-85 → 4,79:1 ✓\n * opacity-90 → 5,15:1 ✓ ← đang dùng, còn biên cho lần chỉnh gold sau\n *\n * ⚠ Bộ số cũ ở đây (70% → 4,12:1 · 80% → 4,85:1) đo trên MỘT CẶP KHÁC: nền #7A5800 với chữ\n * TRẮNG. Từ khi bảng tương phản cao bỏ gold-500 (nâu-ô-liu, xem khối trên) và tô control bằng\n * #B48700 thì chữ quay về MỰC, ca tệ nhất chặt lại và 80% rơi xuống dưới ngưỡng. Đây là kiểu lỗi\n * mà một lần đổi token ở styles.css kéo theo, và chỉ cổng tương phản mới thấy.\n *\n * Hai bảng còn lại rộng rãi ở 90%: bảng duyệt (mực trên #E8B824) 8,60:1, dark (mực trên #F5D060)\n * 10,43:1. Các trạng thái khác cũng thoải mái: giữa khoảng & hôm nay 9,70:1 (light) · 10,05:1\n * (dark), ngày thường 10,26:1 · 11,41:1.\n */\nfunction CalendarDayButton({ className, day, modifiers, ...props }: CalendarDayButtonProps) {\n const defaultClassNames = getDefaultClassNames();\n\n const ref = React.useRef<HTMLButtonElement>(null);\n React.useEffect(() => {\n if (modifiers.focused) ref.current?.focus();\n }, [modifiers.focused]);\n\n return (\n <Button\n ref={ref}\n variant=\"ghost\"\n size=\"icon\"\n data-day={day.date.toLocaleDateString()}\n data-selected-single={\n modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle\n }\n data-range-start={modifiers.range_start}\n data-range-end={modifiers.range_end}\n data-range-middle={modifiers.range_middle}\n className={cn(\n \"data-[selected-single=true]:bg-control-on data-[selected-single=true]:text-control-check data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-control-on data-[range-start=true]:text-control-check data-[range-end=true]:bg-control-on data-[range-end=true]:text-control-check group-data-[focused=true]/day:outline-none group-data-[focused=true]/day:ring-ring/50 group-data-[focused=true]/day:ring-offset-2 group-data-[focused=true]/day:ring-offset-background dark:hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-2 data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-90\",\n defaultClassNames.day,\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Calendar, CalendarDayButton };\n"],"mappings":"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","names":[]}
|
|
@@ -7,7 +7,8 @@ import 'class-variance-authority';
|
|
|
7
7
|
/**
|
|
8
8
|
* Carousel (embla) — băng chuyền ngang/dọc, điều hướng được bằng phím ←/→.
|
|
9
9
|
* `useCarousel()` được export để app tự dựng chấm chỉ báo hoặc nút điều khiển riêng.
|
|
10
|
-
* Chuỗi cho trình đọc màn hình
|
|
10
|
+
* Chuỗi cho trình đọc màn hình theo `ComitorLocaleProvider` (namespace `carousel`, mặc định tiếng
|
|
11
|
+
* Anh); override qua prop `srLabel` / `aria-roledescription`.
|
|
11
12
|
*/
|
|
12
13
|
type CarouselApi = UseEmblaCarouselType[1];
|
|
13
14
|
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
|
|
@@ -40,7 +41,7 @@ declare function useCarousel(): CarouselContextProps;
|
|
|
40
41
|
declare function Carousel({ orientation, opts, setApi, plugins, className, children, ...props }: CarouselProps): React.JSX.Element;
|
|
41
42
|
declare function CarouselContent({ className, ...props }: CarouselContentProps): React.JSX.Element;
|
|
42
43
|
declare function CarouselItem({ className, ...props }: CarouselItemProps): React.JSX.Element;
|
|
43
|
-
declare function CarouselPrevious({ className, variant, size, srLabel, ...props }: CarouselPreviousProps): React.JSX.Element;
|
|
44
|
-
declare function CarouselNext({ className, variant, size, srLabel, ...props }: CarouselNextProps): React.JSX.Element;
|
|
44
|
+
declare function CarouselPrevious({ className, variant, size, srLabel: srLabelProp, ...props }: CarouselPreviousProps): React.JSX.Element;
|
|
45
|
+
declare function CarouselNext({ className, variant, size, srLabel: srLabelProp, ...props }: CarouselNextProps): React.JSX.Element;
|
|
45
46
|
|
|
46
47
|
export { Carousel, type CarouselApi, CarouselContent, type CarouselContentProps, type CarouselContextProps, CarouselItem, type CarouselItemProps, CarouselNext, type CarouselNextProps, type CarouselOptions, type CarouselOwnProps, type CarouselPlugin, CarouselPrevious, type CarouselPreviousProps, type CarouselProps, useCarousel };
|
|
@@ -3,6 +3,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import useEmblaCarousel from "embla-carousel-react";
|
|
4
4
|
import { ArrowLeft, ArrowRight } from "lucide-react";
|
|
5
5
|
import * as React from "react";
|
|
6
|
+
import { useComitorMessages } from "../../i18n/locale-provider.js";
|
|
6
7
|
import { cn } from "../../lib/cn.js";
|
|
7
8
|
import { Button } from "./button.js";
|
|
8
9
|
const CarouselContext = React.createContext(null);
|
|
@@ -14,6 +15,7 @@ function useCarousel() {
|
|
|
14
15
|
return context;
|
|
15
16
|
}
|
|
16
17
|
function Carousel({ orientation = "horizontal", opts, setApi, plugins, className, children, ...props }) {
|
|
18
|
+
const t = useComitorMessages("carousel");
|
|
17
19
|
const [carouselRef, api] = useEmblaCarousel(
|
|
18
20
|
{
|
|
19
21
|
...opts,
|
|
@@ -78,7 +80,7 @@ function Carousel({ orientation = "horizontal", opts, setApi, plugins, className
|
|
|
78
80
|
onKeyDownCapture: handleKeyDown,
|
|
79
81
|
className: cn("relative", className),
|
|
80
82
|
role: "region",
|
|
81
|
-
"aria-roledescription":
|
|
83
|
+
"aria-roledescription": t.roleDescription,
|
|
82
84
|
"data-slot": "carousel",
|
|
83
85
|
...props,
|
|
84
86
|
children
|
|
@@ -93,11 +95,12 @@ function CarouselContent({ className, ...props }) {
|
|
|
93
95
|
}
|
|
94
96
|
function CarouselItem({ className, ...props }) {
|
|
95
97
|
const { orientation } = useCarousel();
|
|
98
|
+
const t = useComitorMessages("carousel");
|
|
96
99
|
return /* @__PURE__ */ jsx(
|
|
97
100
|
"div",
|
|
98
101
|
{
|
|
99
102
|
role: "group",
|
|
100
|
-
"aria-roledescription":
|
|
103
|
+
"aria-roledescription": t.slideRoleDescription,
|
|
101
104
|
"data-slot": "carousel-item",
|
|
102
105
|
className: cn("min-w-0 shrink-0 grow-0 basis-full", orientation === "horizontal" ? "pl-4" : "pt-4", className),
|
|
103
106
|
...props
|
|
@@ -108,10 +111,12 @@ function CarouselPrevious({
|
|
|
108
111
|
className,
|
|
109
112
|
variant = "outline",
|
|
110
113
|
size = "icon",
|
|
111
|
-
srLabel
|
|
114
|
+
srLabel: srLabelProp,
|
|
112
115
|
...props
|
|
113
116
|
}) {
|
|
114
117
|
const { orientation, scrollPrev, canScrollPrev } = useCarousel();
|
|
118
|
+
const t = useComitorMessages("carousel");
|
|
119
|
+
const srLabel = srLabelProp ?? t.previousLabel;
|
|
115
120
|
return /* @__PURE__ */ jsxs(
|
|
116
121
|
Button,
|
|
117
122
|
{
|
|
@@ -137,10 +142,12 @@ function CarouselNext({
|
|
|
137
142
|
className,
|
|
138
143
|
variant = "outline",
|
|
139
144
|
size = "icon",
|
|
140
|
-
srLabel
|
|
145
|
+
srLabel: srLabelProp,
|
|
141
146
|
...props
|
|
142
147
|
}) {
|
|
143
148
|
const { orientation, scrollNext, canScrollNext } = useCarousel();
|
|
149
|
+
const t = useComitorMessages("carousel");
|
|
150
|
+
const srLabel = srLabelProp ?? t.nextLabel;
|
|
144
151
|
return /* @__PURE__ */ jsxs(
|
|
145
152
|
Button,
|
|
146
153
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ui/carousel.tsx"],"sourcesContent":["\"use client\";\n\nimport useEmblaCarousel, { type UseEmblaCarouselType } from \"embla-carousel-react\";\nimport { ArrowLeft, ArrowRight } from \"lucide-react\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\nimport { Button, type ButtonProps } from \"./button.js\";\n\n/**\n * Carousel (embla) — băng chuyền ngang/dọc, điều hướng được bằng phím ←/→.\n * `useCarousel()` được export để app tự dựng chấm chỉ báo hoặc nút điều khiển riêng.\n * Chuỗi cho trình đọc màn hình mặc định tiếng Việt, override qua prop `srLabel`.\n */\n\nexport type CarouselApi = UseEmblaCarouselType[1];\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>;\nexport type CarouselOptions = UseCarouselParameters[0];\nexport type CarouselPlugin = UseCarouselParameters[1];\n\nexport type CarouselOwnProps = {\n opts?: CarouselOptions;\n plugins?: CarouselPlugin;\n orientation?: \"horizontal\" | \"vertical\";\n setApi?: (api: CarouselApi) => void;\n};\n\nexport type CarouselProps = React.ComponentProps<\"div\"> & CarouselOwnProps;\nexport type CarouselContentProps = React.ComponentProps<\"div\">;\nexport type CarouselItemProps = React.ComponentProps<\"div\">;\nexport type CarouselPreviousProps = ButtonProps & { srLabel?: string };\nexport type CarouselNextProps = ButtonProps & { srLabel?: string };\n\nexport type CarouselContextProps = {\n carouselRef: ReturnType<typeof useEmblaCarousel>[0];\n api: ReturnType<typeof useEmblaCarousel>[1];\n scrollPrev: () => void;\n scrollNext: () => void;\n canScrollPrev: boolean;\n canScrollNext: boolean;\n} & CarouselOwnProps;\n\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null);\n\nfunction useCarousel(): CarouselContextProps {\n const context = React.useContext(CarouselContext);\n\n if (!context) {\n throw new Error(\"useCarousel phải được dùng bên trong <Carousel />\");\n }\n\n return context;\n}\n\nfunction Carousel({ orientation = \"horizontal\", opts, setApi, plugins, className, children, ...props }: CarouselProps) {\n const [carouselRef, api] = useEmblaCarousel(\n {\n ...opts,\n axis: orientation === \"horizontal\" ? \"x\" : \"y\"\n },\n plugins\n );\n const [canScrollPrev, setCanScrollPrev] = React.useState(false);\n const [canScrollNext, setCanScrollNext] = React.useState(false);\n\n const onSelect = React.useCallback((emblaApi: CarouselApi) => {\n if (!emblaApi) return;\n setCanScrollPrev(emblaApi.canScrollPrev());\n setCanScrollNext(emblaApi.canScrollNext());\n }, []);\n\n const scrollPrev = React.useCallback(() => {\n api?.scrollPrev();\n }, [api]);\n\n const scrollNext = React.useCallback(() => {\n api?.scrollNext();\n }, [api]);\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n scrollPrev();\n } else if (event.key === \"ArrowRight\") {\n event.preventDefault();\n scrollNext();\n }\n },\n [scrollPrev, scrollNext]\n );\n\n React.useEffect(() => {\n if (!api || !setApi) return;\n setApi(api);\n }, [api, setApi]);\n\n React.useEffect(() => {\n if (!api) return;\n onSelect(api);\n api.on(\"reInit\", onSelect);\n api.on(\"select\", onSelect);\n\n return () => {\n api?.off(\"select\", onSelect);\n };\n }, [api, onSelect]);\n\n return (\n <CarouselContext.Provider\n value={{\n carouselRef,\n api: api,\n opts,\n orientation: orientation || (opts?.axis === \"y\" ? \"vertical\" : \"horizontal\"),\n scrollPrev,\n scrollNext,\n canScrollPrev,\n canScrollNext\n }}\n >\n <div\n onKeyDownCapture={handleKeyDown}\n className={cn(\"relative\", className)}\n role=\"region\"\n aria-roledescription=\"băng chuyền\"\n data-slot=\"carousel\"\n {...props}\n >\n {children}\n </div>\n </CarouselContext.Provider>\n );\n}\n\nfunction CarouselContent({ className, ...props }: CarouselContentProps) {\n const { carouselRef, orientation } = useCarousel();\n\n return (\n <div ref={carouselRef} className=\"overflow-hidden\" data-slot=\"carousel-content\">\n <div className={cn(\"flex\", orientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\", className)} {...props} />\n </div>\n );\n}\n\nfunction CarouselItem({ className, ...props }: CarouselItemProps) {\n const { orientation } = useCarousel();\n\n return (\n <div\n role=\"group\"\n aria-roledescription=\"trang chiếu\"\n data-slot=\"carousel-item\"\n className={cn(\"min-w-0 shrink-0 grow-0 basis-full\", orientation === \"horizontal\" ? \"pl-4\" : \"pt-4\", className)}\n {...props}\n />\n );\n}\n\nfunction CarouselPrevious({\n className,\n variant = \"outline\",\n size = \"icon\",\n srLabel = \"Trang chiếu trước\",\n ...props\n}: CarouselPreviousProps) {\n const { orientation, scrollPrev, canScrollPrev } = useCarousel();\n\n return (\n <Button\n data-slot=\"carousel-previous\"\n variant={variant}\n size={size}\n className={cn(\n \"absolute size-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"top-1/2 -left-12 -translate-y-1/2\"\n : \"-top-12 left-1/2 -translate-x-1/2 rotate-90\",\n className\n )}\n disabled={!canScrollPrev}\n onClick={scrollPrev}\n {...props}\n >\n <ArrowLeft />\n <span className=\"sr-only\">{srLabel}</span>\n </Button>\n );\n}\n\nfunction CarouselNext({\n className,\n variant = \"outline\",\n size = \"icon\",\n srLabel = \"Trang chiếu sau\",\n ...props\n}: CarouselNextProps) {\n const { orientation, scrollNext, canScrollNext } = useCarousel();\n\n return (\n <Button\n data-slot=\"carousel-next\"\n variant={variant}\n size={size}\n className={cn(\n \"absolute size-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"top-1/2 -right-12 -translate-y-1/2\"\n : \"-bottom-12 left-1/2 -translate-x-1/2 rotate-90\",\n className\n )}\n disabled={!canScrollNext}\n onClick={scrollNext}\n {...props}\n >\n <ArrowRight />\n <span className=\"sr-only\">{srLabel}</span>\n </Button>\n );\n}\n\nexport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, useCarousel };\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/carousel.tsx"],"sourcesContent":["\"use client\";\n\nimport useEmblaCarousel, { type UseEmblaCarouselType } from \"embla-carousel-react\";\nimport { ArrowLeft, ArrowRight } from \"lucide-react\";\nimport * as React from \"react\";\nimport { useComitorMessages } from \"../../i18n/locale-provider.js\";\nimport { cn } from \"../../lib/cn.js\";\nimport { Button, type ButtonProps } from \"./button.js\";\n\n/**\n * Carousel (embla) — băng chuyền ngang/dọc, điều hướng được bằng phím ←/→.\n * `useCarousel()` được export để app tự dựng chấm chỉ báo hoặc nút điều khiển riêng.\n * Chuỗi cho trình đọc màn hình theo `ComitorLocaleProvider` (namespace `carousel`, mặc định tiếng\n * Anh); override qua prop `srLabel` / `aria-roledescription`.\n */\n\nexport type CarouselApi = UseEmblaCarouselType[1];\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>;\nexport type CarouselOptions = UseCarouselParameters[0];\nexport type CarouselPlugin = UseCarouselParameters[1];\n\nexport type CarouselOwnProps = {\n opts?: CarouselOptions;\n plugins?: CarouselPlugin;\n orientation?: \"horizontal\" | \"vertical\";\n setApi?: (api: CarouselApi) => void;\n};\n\nexport type CarouselProps = React.ComponentProps<\"div\"> & CarouselOwnProps;\nexport type CarouselContentProps = React.ComponentProps<\"div\">;\nexport type CarouselItemProps = React.ComponentProps<\"div\">;\nexport type CarouselPreviousProps = ButtonProps & { srLabel?: string };\nexport type CarouselNextProps = ButtonProps & { srLabel?: string };\n\nexport type CarouselContextProps = {\n carouselRef: ReturnType<typeof useEmblaCarousel>[0];\n api: ReturnType<typeof useEmblaCarousel>[1];\n scrollPrev: () => void;\n scrollNext: () => void;\n canScrollPrev: boolean;\n canScrollNext: boolean;\n} & CarouselOwnProps;\n\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null);\n\nfunction useCarousel(): CarouselContextProps {\n const context = React.useContext(CarouselContext);\n\n if (!context) {\n throw new Error(\"useCarousel phải được dùng bên trong <Carousel />\");\n }\n\n return context;\n}\n\nfunction Carousel({ orientation = \"horizontal\", opts, setApi, plugins, className, children, ...props }: CarouselProps) {\n const t = useComitorMessages(\"carousel\");\n const [carouselRef, api] = useEmblaCarousel(\n {\n ...opts,\n axis: orientation === \"horizontal\" ? \"x\" : \"y\"\n },\n plugins\n );\n const [canScrollPrev, setCanScrollPrev] = React.useState(false);\n const [canScrollNext, setCanScrollNext] = React.useState(false);\n\n const onSelect = React.useCallback((emblaApi: CarouselApi) => {\n if (!emblaApi) return;\n setCanScrollPrev(emblaApi.canScrollPrev());\n setCanScrollNext(emblaApi.canScrollNext());\n }, []);\n\n const scrollPrev = React.useCallback(() => {\n api?.scrollPrev();\n }, [api]);\n\n const scrollNext = React.useCallback(() => {\n api?.scrollNext();\n }, [api]);\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n scrollPrev();\n } else if (event.key === \"ArrowRight\") {\n event.preventDefault();\n scrollNext();\n }\n },\n [scrollPrev, scrollNext]\n );\n\n React.useEffect(() => {\n if (!api || !setApi) return;\n setApi(api);\n }, [api, setApi]);\n\n React.useEffect(() => {\n if (!api) return;\n onSelect(api);\n api.on(\"reInit\", onSelect);\n api.on(\"select\", onSelect);\n\n return () => {\n api?.off(\"select\", onSelect);\n };\n }, [api, onSelect]);\n\n return (\n <CarouselContext.Provider\n value={{\n carouselRef,\n api: api,\n opts,\n orientation: orientation || (opts?.axis === \"y\" ? \"vertical\" : \"horizontal\"),\n scrollPrev,\n scrollNext,\n canScrollPrev,\n canScrollNext\n }}\n >\n <div\n onKeyDownCapture={handleKeyDown}\n className={cn(\"relative\", className)}\n role=\"region\"\n aria-roledescription={t.roleDescription}\n data-slot=\"carousel\"\n {...props}\n >\n {children}\n </div>\n </CarouselContext.Provider>\n );\n}\n\nfunction CarouselContent({ className, ...props }: CarouselContentProps) {\n const { carouselRef, orientation } = useCarousel();\n\n return (\n <div ref={carouselRef} className=\"overflow-hidden\" data-slot=\"carousel-content\">\n <div className={cn(\"flex\", orientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\", className)} {...props} />\n </div>\n );\n}\n\nfunction CarouselItem({ className, ...props }: CarouselItemProps) {\n const { orientation } = useCarousel();\n const t = useComitorMessages(\"carousel\");\n\n return (\n <div\n role=\"group\"\n aria-roledescription={t.slideRoleDescription}\n data-slot=\"carousel-item\"\n className={cn(\"min-w-0 shrink-0 grow-0 basis-full\", orientation === \"horizontal\" ? \"pl-4\" : \"pt-4\", className)}\n {...props}\n />\n );\n}\n\nfunction CarouselPrevious({\n className,\n variant = \"outline\",\n size = \"icon\",\n srLabel: srLabelProp,\n ...props\n}: CarouselPreviousProps) {\n const { orientation, scrollPrev, canScrollPrev } = useCarousel();\n const t = useComitorMessages(\"carousel\");\n const srLabel = srLabelProp ?? t.previousLabel;\n\n return (\n <Button\n data-slot=\"carousel-previous\"\n variant={variant}\n size={size}\n className={cn(\n \"absolute size-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"top-1/2 -left-12 -translate-y-1/2\"\n : \"-top-12 left-1/2 -translate-x-1/2 rotate-90\",\n className\n )}\n disabled={!canScrollPrev}\n onClick={scrollPrev}\n {...props}\n >\n <ArrowLeft />\n <span className=\"sr-only\">{srLabel}</span>\n </Button>\n );\n}\n\nfunction CarouselNext({\n className,\n variant = \"outline\",\n size = \"icon\",\n srLabel: srLabelProp,\n ...props\n}: CarouselNextProps) {\n const { orientation, scrollNext, canScrollNext } = useCarousel();\n const t = useComitorMessages(\"carousel\");\n const srLabel = srLabelProp ?? t.nextLabel;\n\n return (\n <Button\n data-slot=\"carousel-next\"\n variant={variant}\n size={size}\n className={cn(\n \"absolute size-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"top-1/2 -right-12 -translate-y-1/2\"\n : \"-bottom-12 left-1/2 -translate-x-1/2 rotate-90\",\n className\n )}\n disabled={!canScrollNext}\n onClick={scrollNext}\n {...props}\n >\n <ArrowRight />\n <span className=\"sr-only\">{srLabel}</span>\n </Button>\n );\n}\n\nexport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, useCarousel };\n"],"mappings":";AA2HM,cAmDF,YAnDE;AAzHN,OAAO,sBAAqD;AAC5D,SAAS,WAAW,kBAAkB;AACtC,YAAY,WAAW;AACvB,SAAS,0BAA0B;AACnC,SAAS,UAAU;AACnB,SAAS,cAAgC;AAoCzC,MAAM,kBAAkB,MAAM,cAA2C,IAAI;AAE7E,SAAS,cAAoC;AAC3C,QAAM,UAAU,MAAM,WAAW,eAAe;AAEhD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,6EAAmD;AAAA,EACrE;AAEA,SAAO;AACT;AAEA,SAAS,SAAS,EAAE,cAAc,cAAc,MAAM,QAAQ,SAAS,WAAW,UAAU,GAAG,MAAM,GAAkB;AACrH,QAAM,IAAI,mBAAmB,UAAU;AACvC,QAAM,CAAC,aAAa,GAAG,IAAI;AAAA,IACzB;AAAA,MACE,GAAG;AAAA,MACH,MAAM,gBAAgB,eAAe,MAAM;AAAA,IAC7C;AAAA,IACA;AAAA,EACF;AACA,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,KAAK;AAC9D,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,KAAK;AAE9D,QAAM,WAAW,MAAM,YAAY,CAAC,aAA0B;AAC5D,QAAI,CAAC,SAAU;AACf,qBAAiB,SAAS,cAAc,CAAC;AACzC,qBAAiB,SAAS,cAAc,CAAC;AAAA,EAC3C,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,MAAM,YAAY,MAAM;AACzC,SAAK,WAAW;AAAA,EAClB,GAAG,CAAC,GAAG,CAAC;AAER,QAAM,aAAa,MAAM,YAAY,MAAM;AACzC,SAAK,WAAW;AAAA,EAClB,GAAG,CAAC,GAAG,CAAC;AAER,QAAM,gBAAgB,MAAM;AAAA,IAC1B,CAAC,UAA+C;AAC9C,UAAI,MAAM,QAAQ,aAAa;AAC7B,cAAM,eAAe;AACrB,mBAAW;AAAA,MACb,WAAW,MAAM,QAAQ,cAAc;AACrC,cAAM,eAAe;AACrB,mBAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA,CAAC,YAAY,UAAU;AAAA,EACzB;AAEA,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,OAAO,CAAC,OAAQ;AACrB,WAAO,GAAG;AAAA,EACZ,GAAG,CAAC,KAAK,MAAM,CAAC;AAEhB,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,IAAK;AACV,aAAS,GAAG;AACZ,QAAI,GAAG,UAAU,QAAQ;AACzB,QAAI,GAAG,UAAU,QAAQ;AAEzB,WAAO,MAAM;AACX,WAAK,IAAI,UAAU,QAAQ;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,KAAK,QAAQ,CAAC;AAElB,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAa,gBAAgB,MAAM,SAAS,MAAM,aAAa;AAAA,QAC/D;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,kBAAkB;AAAA,UAClB,WAAW,GAAG,YAAY,SAAS;AAAA,UACnC,MAAK;AAAA,UACL,wBAAsB,EAAE;AAAA,UACxB,aAAU;AAAA,UACT,GAAG;AAAA,UAEH;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,MAAM,GAAyB;AACtE,QAAM,EAAE,aAAa,YAAY,IAAI,YAAY;AAEjD,SACE,oBAAC,SAAI,KAAK,aAAa,WAAU,mBAAkB,aAAU,oBAC3D,8BAAC,SAAI,WAAW,GAAG,QAAQ,gBAAgB,eAAe,UAAU,kBAAkB,SAAS,GAAI,GAAG,OAAO,GAC/G;AAEJ;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAsB;AAChE,QAAM,EAAE,YAAY,IAAI,YAAY;AACpC,QAAM,IAAI,mBAAmB,UAAU;AAEvC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,wBAAsB,EAAE;AAAA,MACxB,aAAU;AAAA,MACV,WAAW,GAAG,sCAAsC,gBAAgB,eAAe,SAAS,QAAQ,SAAS;AAAA,MAC5G,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,GAAG;AACL,GAA0B;AACxB,QAAM,EAAE,aAAa,YAAY,cAAc,IAAI,YAAY;AAC/D,QAAM,IAAI,mBAAmB,UAAU;AACvC,QAAM,UAAU,eAAe,EAAE;AAEjC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA,gBAAgB,eACZ,sCACA;AAAA,QACJ;AAAA,MACF;AAAA,MACA,UAAU,CAAC;AAAA,MACX,SAAS;AAAA,MACR,GAAG;AAAA,MAEJ;AAAA,4BAAC,aAAU;AAAA,QACX,oBAAC,UAAK,WAAU,WAAW,mBAAQ;AAAA;AAAA;AAAA,EACrC;AAEJ;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,GAAG;AACL,GAAsB;AACpB,QAAM,EAAE,aAAa,YAAY,cAAc,IAAI,YAAY;AAC/D,QAAM,IAAI,mBAAmB,UAAU;AACvC,QAAM,UAAU,eAAe,EAAE;AAEjC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA,gBAAgB,eACZ,uCACA;AAAA,QACJ;AAAA,MACF;AAAA,MACA,UAAU,CAAC;AAAA,MACX,SAAS;AAAA,MACR,GAAG;AAAA,MAEJ;AAAA,4BAAC,cAAW;AAAA,QACZ,oBAAC,UAAK,WAAU,WAAW,mBAAQ;AAAA;AAAA;AAAA,EACrC;AAEJ;","names":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
interface CircularProgressProps extends React.ComponentProps<"div"> {
|
|
4
|
+
/** Giá trị hiện tại; `null`/`undefined` = không xác định (vòng quay). */
|
|
5
|
+
value?: number | null | undefined;
|
|
6
|
+
/**
|
|
7
|
+
* Chuỗi trình đọc màn hình đọc thay cho con số (`aria-valuetext`) và chữ giữa vòng — mặc định
|
|
8
|
+
* phần trăm làm tròn, vd `"45%"`.
|
|
9
|
+
*/
|
|
10
|
+
getValueText?(value: number, min: number, max: number): string;
|
|
11
|
+
min?: number;
|
|
12
|
+
max?: number;
|
|
13
|
+
/** Đường kính, px. */
|
|
14
|
+
size?: number;
|
|
15
|
+
/** Độ dày nét, px. */
|
|
16
|
+
thickness?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Nhãn HIỆN của vòng, đồng thời là tên của `role="progressbar"`. Không đặt nhãn hiện thì PHẢI
|
|
19
|
+
* truyền `aria-label` — progressbar không tên là lỗi a11y (ARIA 1.2), gói không tự đặt tên
|
|
20
|
+
* chung chung thay app (giống `Progress`).
|
|
21
|
+
*/
|
|
22
|
+
label?: string;
|
|
23
|
+
asChild?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* CircularProgress — tiến trình dạng VÒNG, cặp với `Progress` (dạng thanh) của gói.
|
|
27
|
+
* Ráp từ các phần (`CircularProgressIndicator` › `Track` + `Range`, `CircularProgressValueText`),
|
|
28
|
+
* hoặc dùng sẵn `CircularProgressCombined`.
|
|
29
|
+
*
|
|
30
|
+
* Phần đã chạy là `text-primary-ink`, cùng bậc với thanh `Progress`; rãnh xám trung tính. Đổi tông
|
|
31
|
+
* thì truyền bậc INK cho `CircularProgressRange` (vd `className="text-success-ink"`), không phải
|
|
32
|
+
* token tô nền `text-success` — rãnh không cần đổi theo (số đo ở `CircularProgressTrack`).
|
|
33
|
+
*
|
|
34
|
+
* ⚠ Trạng thái không xác định cần `--animate-spin-around` + `@keyframes spin-around` trong
|
|
35
|
+
* styles.css; thiếu thì vòng đứng yên ở một cung 25% (không lỗi, không cảnh báo).
|
|
36
|
+
*/
|
|
37
|
+
declare function CircularProgress(props: CircularProgressProps): React.JSX.Element;
|
|
38
|
+
declare function CircularProgressIndicator(props: React.ComponentProps<"svg">): React.JSX.Element;
|
|
39
|
+
declare namespace CircularProgressIndicator {
|
|
40
|
+
var displayName: string;
|
|
41
|
+
}
|
|
42
|
+
declare function CircularProgressTrack(props: React.ComponentProps<"circle">): React.JSX.Element;
|
|
43
|
+
declare function CircularProgressRange(props: React.ComponentProps<"circle">): React.JSX.Element;
|
|
44
|
+
interface CircularProgressValueTextProps extends React.ComponentProps<"span"> {
|
|
45
|
+
asChild?: boolean;
|
|
46
|
+
}
|
|
47
|
+
declare function CircularProgressValueText(props: CircularProgressValueTextProps): React.JSX.Element;
|
|
48
|
+
declare function CircularProgressCombined(props: CircularProgressProps): React.JSX.Element;
|
|
49
|
+
|
|
50
|
+
export { CircularProgress, CircularProgressCombined, CircularProgressIndicator, type CircularProgressProps, CircularProgressRange, CircularProgressTrack, CircularProgressValueText, type CircularProgressValueTextProps };
|