@comitor/ui 2.1.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/README.md +59 -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 +8 -4
- package/dist/components/ui/action-bar-constants.js +2 -5
- package/dist/components/ui/action-bar-constants.js.map +1 -1
- package/dist/components/ui/action-bar.d.ts +5 -4
- package/dist/components/ui/action-bar.js +2 -2
- package/dist/components/ui/action-bar.js.map +1 -1
- package/dist/components/ui/alert.d.ts +1 -1
- package/dist/components/ui/badge-overflow.d.ts +2 -2
- package/dist/components/ui/badge-overflow.js +4 -2
- package/dist/components/ui/badge-overflow.js.map +1 -1
- package/dist/components/ui/badge.d.ts +1 -1
- package/dist/components/ui/banner.d.ts +6 -5
- package/dist/components/ui/banner.js +3 -1
- package/dist/components/ui/banner.js.map +1 -1
- 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.js.map +1 -1
- 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 +8 -3
- package/dist/components/ui/cropper-constants.js +2 -6
- package/dist/components/ui/cropper-constants.js.map +1 -1
- package/dist/components/ui/cropper.d.ts +2 -1
- package/dist/components/ui/cropper.js +2 -2
- package/dist/components/ui/cropper.js.map +1 -1
- 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/item.d.ts +2 -2
- package/dist/components/ui/kanban-constants.d.ts +7 -1
- package/dist/components/ui/kanban-constants.js +2 -17
- package/dist/components/ui/kanban-constants.js.map +1 -1
- package/dist/components/ui/kanban.d.ts +2 -2
- package/dist/components/ui/kanban.js +2 -2
- package/dist/components/ui/kanban.js.map +1 -1
- package/dist/components/ui/key-value-constants.d.ts +7 -3
- package/dist/components/ui/key-value-constants.js +2 -7
- package/dist/components/ui/key-value-constants.js.map +1 -1
- package/dist/components/ui/key-value.d.ts +5 -5
- package/dist/components/ui/key-value.js +2 -2
- package/dist/components/ui/key-value.js.map +1 -1
- package/dist/components/ui/mask-input-constants.d.ts +2 -3
- package/dist/components/ui/mask-input-constants.js +5 -6
- package/dist/components/ui/mask-input-constants.js.map +1 -1
- package/dist/components/ui/mask-input.d.ts +7 -4
- package/dist/components/ui/mask-input.js +4 -2
- package/dist/components/ui/mask-input.js.map +1 -1
- package/dist/components/ui/mention.d.ts +3 -2
- package/dist/components/ui/mention.js +4 -6
- package/dist/components/ui/mention.js.map +1 -1
- 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 +17 -6
- package/dist/components/ui/phone-input-constants.js +2 -5
- package/dist/components/ui/phone-input-constants.js.map +1 -1
- package/dist/components/ui/phone-input.d.ts +18 -11
- package/dist/components/ui/phone-input.js +9 -10
- package/dist/components/ui/phone-input.js.map +1 -1
- package/dist/components/ui/progress.d.ts +2 -2
- package/dist/components/ui/rating.d.ts +2 -1
- package/dist/components/ui/rating.js +4 -2
- package/dist/components/ui/rating.js.map +1 -1
- package/dist/components/ui/scroll-spy.js +3 -1
- package/dist/components/ui/scroll-spy.js.map +1 -1
- 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 +7 -2
- package/dist/components/ui/stepper-constants.js +2 -5
- package/dist/components/ui/stepper-constants.js.map +1 -1
- package/dist/components/ui/stepper.d.ts +2 -1
- package/dist/components/ui/stepper.js +2 -2
- package/dist/components/ui/stepper.js.map +1 -1
- package/dist/components/ui/tags-input.d.ts +3 -2
- package/dist/components/ui/tags-input.js +4 -2
- package/dist/components/ui/tags-input.js.map +1 -1
- package/dist/components/ui/time-picker-constants.d.ts +12 -9
- package/dist/components/ui/time-picker-constants.js +2 -10
- package/dist/components/ui/time-picker-constants.js.map +1 -1
- package/dist/components/ui/time-picker.d.ts +11 -6
- package/dist/components/ui/time-picker.js +5 -7
- package/dist/components/ui/time-picker.js.map +1 -1
- package/dist/components/ui/toggle.d.ts +1 -1
- package/dist/components/ui/tour-constants.d.ts +7 -2
- package/dist/components/ui/tour-constants.js +2 -8
- package/dist/components/ui/tour-constants.js.map +1 -1
- package/dist/components/ui/tour.d.ts +3 -2
- package/dist/components/ui/tour.js +2 -2
- package/dist/components/ui/tour.js.map +1 -1
- 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-column-header.js +1 -1
- package/dist/data-grid/data-grid-column-header.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-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-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 +2 -3
- 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 +16 -19
- 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 +2 -2
- 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 +8 -6
- 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 +32 -0
- package/dist/index.js +24 -1
- package/dist/index.js.map +1 -1
- 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 +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ui/mask-input.tsx"],"sourcesContent":["\"use client\";\n\n/*\n * Port từ Dice UI (https://diceui.com/docs/components/mask-input) — MIT, © 2024 Sadman Sakib.\n * Giữ nguyên cấu trúc thượng nguồn để còn đối chiếu ngược được; mọi chỗ đổi đều có chú thích.\n */\n\n/*\n * ⚠ Khác thượng nguồn: thượng nguồn là MỘT file. Ở đây nửa trên (bảng `MASK_PATTERNS` + mọi hàm\n * thuần) nằm ở `mask-input-constants.ts` — hằng dữ liệu export ra không được sống trong file\n * `\"use client\"` (Server Component đọc ra `undefined`, không throw). File này chỉ còn component,\n * và chỉ `import` từ đó, KHÔNG `export` lại (re-export vòng qua file client là vô hiệu).\n */\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\nimport { useComposedRefs } from \"../../lib/compose-refs.js\";\nimport {\n applyMask,\n CURRENCY_PERCENTAGE_SYMBOLS,\n DEFAULT_CURRENCY,\n DEFAULT_LOCALE,\n fromUnmaskedIndex,\n getCurrencyCaretPosition,\n getPatternCaretPosition,\n getUnmaskedValue,\n isCurrencyAtEnd,\n isCurrencyMask,\n MASK_PATTERNS,\n type MaskPattern,\n type MaskPatternKey,\n NUMERIC_MASK_PATTERNS,\n REGEX_CACHE,\n toUnmaskedIndex\n} from \"./mask-input-constants.js\";\n\ntype InputElement = React.ComponentRef<\"input\">;\n\ninterface MaskInputProps extends React.ComponentProps<\"input\"> {\n value?: string;\n defaultValue?: string;\n onValueChange?: (maskedValue: string, unmaskedValue: string) => void;\n onValidate?: (isValid: boolean, unmaskedValue: string) => void;\n validationMode?: \"onChange\" | \"onBlur\" | \"onSubmit\" | \"onTouched\" | \"all\";\n /**\n * Tên một mẫu dựng sẵn (`\"currency\"`, `\"percentage\"`, `\"time\"`, `\"creditCard\"`…) hoặc một\n * `MaskPattern` tự viết. ⚠ `\"phone\"`, `\"date\"`, `\"ssn\"`, `\"zipCode\"`, `\"ein\"` là định dạng Hoa Kỳ\n * — số điện thoại ở app Comitor dùng `PhoneInput`.\n */\n mask?: MaskPatternKey | MaskPattern;\n maskPlaceholder?: string;\n /**\n * Mã tiền tệ ISO 4217 cho `mask=\"currency\"`. Mặc định `\"VND\"`.\n *\n * ⚠ Khác thượng nguồn: thượng nguồn mặc định `\"USD\"`.\n */\n currency?: string;\n /**\n * Locale BCP 47 cho `mask=\"currency\"` — quyết định dấu nhóm, dấu thập phân và vị trí ký hiệu.\n * Mặc định `\"vi-VN\"` (`1.234.567 ₫`).\n *\n * ⚠ Khác thượng nguồn: thượng nguồn mặc định `\"en-US\"`.\n */\n locale?: string;\n asChild?: boolean;\n invalid?: boolean;\n withoutMask?: boolean;\n}\n\nfunction MaskInput(props: MaskInputProps) {\n const {\n value: valueProp,\n defaultValue,\n onValueChange: onValueChangeProp,\n onValidate,\n onBlur: onBlurProp,\n onFocus: onFocusProp,\n onKeyDown: onKeyDownProp,\n onPaste: onPasteProp,\n onCompositionStart: onCompositionStartProp,\n onCompositionEnd: onCompositionEndProp,\n validationMode = \"onChange\",\n mask,\n maskPlaceholder,\n currency = DEFAULT_CURRENCY,\n locale = DEFAULT_LOCALE,\n placeholder,\n inputMode,\n min,\n max,\n maxLength,\n asChild = false,\n disabled = false,\n invalid = false,\n readOnly = false,\n required = false,\n withoutMask = false,\n className,\n ref,\n ...inputProps\n } = props;\n\n const [internalValue, setInternalValue] = React.useState(defaultValue ?? \"\");\n const [focused, setFocused] = React.useState(false);\n const [composing, setComposing] = React.useState(false);\n const [touched, setTouched] = React.useState(false);\n const inputRef = React.useRef<HTMLInputElement>(null);\n const composedRef = useComposedRefs(ref, inputRef);\n\n const isControlled = valueProp !== undefined;\n const value = isControlled ? valueProp : internalValue;\n\n const maskPattern = React.useMemo(() => {\n if (typeof mask === \"string\") {\n return MASK_PATTERNS[mask];\n }\n return mask;\n }, [mask]);\n\n const transformOpts = React.useMemo(\n () => ({\n currency,\n locale\n }),\n [currency, locale]\n );\n\n const placeholderValue = React.useMemo(() => {\n if (withoutMask) return placeholder;\n\n if (placeholder && maskPlaceholder) {\n return focused ? maskPlaceholder : placeholder;\n }\n\n if (maskPlaceholder) {\n return focused ? maskPlaceholder : undefined;\n }\n\n return placeholder;\n }, [placeholder, maskPlaceholder, focused, withoutMask]);\n\n const displayValue = React.useMemo(() => {\n if (withoutMask || !maskPattern || !value) return value ?? \"\";\n const unmasked = getUnmaskedValue({\n value,\n transform: maskPattern.transform,\n ...transformOpts\n });\n return applyMask({\n value: unmasked,\n pattern: maskPattern.pattern,\n ...transformOpts,\n mask\n });\n }, [value, maskPattern, withoutMask, transformOpts, mask]);\n\n const tokenCount = React.useMemo(() => {\n if (!maskPattern || CURRENCY_PERCENTAGE_SYMBOLS.test(maskPattern.pattern)) return undefined;\n return maskPattern.pattern.match(REGEX_CACHE.hashPattern)?.length ?? 0;\n }, [maskPattern]);\n\n const calculatedMaxLength = tokenCount ? maskPattern?.pattern.length : maxLength;\n\n const calculatedInputMode = React.useMemo(() => {\n if (inputMode) return inputMode;\n if (!maskPattern) return undefined;\n\n if (mask === \"currency\" || mask === \"percentage\" || mask === \"ipv4\") {\n return \"decimal\";\n }\n\n if (typeof mask === \"string\" && NUMERIC_MASK_PATTERNS.test(mask)) {\n return \"numeric\";\n }\n return undefined;\n }, [maskPattern, mask, inputMode]);\n\n const shouldValidate = React.useCallback(\n (trigger: \"change\" | \"blur\") => {\n if (!onValidate || !maskPattern?.validate) return false;\n\n switch (validationMode) {\n case \"onChange\":\n return trigger === \"change\";\n case \"onBlur\":\n return trigger === \"blur\";\n case \"onSubmit\":\n return false;\n case \"onTouched\":\n return touched ? trigger === \"change\" : trigger === \"blur\";\n case \"all\":\n return true;\n default:\n return trigger === \"change\";\n }\n },\n [onValidate, maskPattern, validationMode, touched]\n );\n\n const validationOpts = React.useMemo(\n () => ({\n min: typeof min === \"string\" ? Number.parseFloat(min) : min,\n max: typeof max === \"string\" ? Number.parseFloat(max) : max\n }),\n [min, max]\n );\n\n const onInputValidate = React.useCallback(\n (unmaskedValue: string) => {\n if (onValidate && maskPattern?.validate) {\n const isValid = maskPattern.validate(unmaskedValue, validationOpts);\n onValidate(isValid, unmaskedValue);\n }\n },\n [onValidate, maskPattern?.validate, validationOpts]\n );\n\n const onValueChange = React.useCallback(\n (event: React.ChangeEvent<InputElement>) => {\n const inputValue = event.target.value;\n let newValue = inputValue;\n let unmaskedValue = inputValue;\n\n if (composing) {\n if (!isControlled) setInternalValue(inputValue);\n return;\n }\n\n if (withoutMask || !maskPattern) {\n if (!isControlled) setInternalValue(inputValue);\n if (shouldValidate(\"change\")) onValidate?.(true, inputValue);\n onValueChangeProp?.(inputValue, inputValue);\n return;\n }\n\n if (maskPattern) {\n unmaskedValue = getUnmaskedValue({\n value: inputValue,\n transform: maskPattern.transform,\n ...transformOpts\n });\n newValue = applyMask({\n value: unmaskedValue,\n pattern: maskPattern.pattern,\n ...transformOpts,\n mask\n });\n\n if (inputRef.current && newValue !== inputValue) {\n const inputElement = inputRef.current;\n if (!(inputElement instanceof HTMLInputElement)) return;\n\n const oldCursorPosition = inputElement.selectionStart ?? 0;\n\n inputElement.value = newValue;\n\n const currentUnmasked = getUnmaskedValue({\n value: newValue,\n transform: maskPattern.transform,\n ...transformOpts\n });\n\n let newCursorPosition: number;\n\n const previousUnmasked = getUnmaskedValue({\n value,\n transform: maskPattern.transform,\n ...transformOpts\n });\n\n if (CURRENCY_PERCENTAGE_SYMBOLS.test(maskPattern.pattern)) {\n newCursorPosition = getCurrencyCaretPosition({\n newValue,\n mask,\n transformOpts,\n oldCursorPosition,\n oldValue: inputValue,\n previousUnmasked\n });\n } else {\n newCursorPosition = getPatternCaretPosition({\n newValue,\n maskPattern,\n currentUnmasked,\n oldCursorPosition,\n oldValue: inputValue,\n previousUnmasked\n });\n }\n\n if (isCurrencyMask({ mask, pattern: maskPattern.pattern })) {\n if (mask === \"currency\") {\n const currencyAtEnd = isCurrencyAtEnd(transformOpts);\n if (!currencyAtEnd) {\n newCursorPosition = Math.max(1, newCursorPosition);\n }\n } else {\n newCursorPosition = Math.max(1, newCursorPosition);\n }\n } else if (maskPattern.pattern.includes(\"%\")) {\n newCursorPosition = Math.min(newValue.length - 1, newCursorPosition);\n }\n\n newCursorPosition = Math.min(newCursorPosition, newValue.length);\n\n inputElement.setSelectionRange(newCursorPosition, newCursorPosition);\n }\n }\n\n if (!isControlled) {\n setInternalValue(newValue);\n }\n\n if (shouldValidate(\"change\")) {\n onInputValidate(unmaskedValue);\n }\n\n onValueChangeProp?.(newValue, unmaskedValue);\n },\n [\n maskPattern,\n isControlled,\n onValueChangeProp,\n onValidate,\n onInputValidate,\n composing,\n shouldValidate,\n withoutMask,\n transformOpts,\n mask,\n value\n ]\n );\n\n const onFocus = React.useCallback(\n (event: React.FocusEvent<InputElement>) => {\n onFocusProp?.(event);\n if (event.defaultPrevented) return;\n\n setFocused(true);\n },\n [onFocusProp]\n );\n\n const onBlur = React.useCallback(\n (event: React.FocusEvent<InputElement>) => {\n onBlurProp?.(event);\n if (event.defaultPrevented) return;\n\n setFocused(false);\n\n if (!touched) {\n setTouched(true);\n }\n\n if (shouldValidate(\"blur\")) {\n const currentValue = event.target.value;\n const unmaskedValue = maskPattern\n ? getUnmaskedValue({\n value: currentValue,\n transform: maskPattern.transform,\n ...transformOpts\n })\n : currentValue;\n onInputValidate(unmaskedValue);\n }\n },\n [onBlurProp, touched, shouldValidate, onInputValidate, maskPattern, transformOpts]\n );\n\n const onCompositionStart = React.useCallback(\n (event: React.CompositionEvent<InputElement>) => {\n onCompositionStartProp?.(event);\n if (event.defaultPrevented) return;\n\n setComposing(true);\n },\n [onCompositionStartProp]\n );\n\n const onCompositionEnd = React.useCallback(\n (event: React.CompositionEvent<InputElement>) => {\n onCompositionEndProp?.(event);\n if (event.defaultPrevented) return;\n\n setComposing(false);\n\n const inputElement = inputRef.current;\n if (!inputElement) return;\n if (!(inputElement instanceof HTMLInputElement)) return;\n const inputValue = inputElement.value;\n\n if (!maskPattern || withoutMask) {\n if (!isControlled) setInternalValue(inputValue);\n if (shouldValidate(\"change\")) onValidate?.(true, inputValue);\n onValueChangeProp?.(inputValue, inputValue);\n return;\n }\n\n const unmasked = getUnmaskedValue({\n value: inputValue,\n transform: maskPattern.transform,\n ...transformOpts\n });\n const masked = applyMask({\n value: unmasked,\n pattern: maskPattern.pattern,\n ...transformOpts,\n mask\n });\n\n if (!isControlled) setInternalValue(masked);\n if (shouldValidate(\"change\")) onInputValidate(unmasked);\n onValueChangeProp?.(masked, unmasked);\n },\n [\n onCompositionEndProp,\n maskPattern,\n withoutMask,\n isControlled,\n shouldValidate,\n onValidate,\n onValueChangeProp,\n transformOpts,\n mask,\n onInputValidate\n ]\n );\n\n const onPaste = React.useCallback(\n (event: React.ClipboardEvent<InputElement>) => {\n onPasteProp?.(event);\n if (event.defaultPrevented) return;\n\n if (withoutMask || !maskPattern) return;\n\n if (mask === \"ipv4\") return;\n\n const target = event.target as InputElement;\n if (!(target instanceof HTMLInputElement)) return;\n\n const pastedData = event.clipboardData.getData(\"text\");\n if (!pastedData) return;\n\n event.preventDefault();\n\n const currentValue = target.value;\n const selectionStart = target.selectionStart ?? 0;\n const selectionEnd = target.selectionEnd ?? 0;\n\n const beforeSelection = currentValue.slice(0, selectionStart);\n const afterSelection = currentValue.slice(selectionEnd);\n const newInputValue = beforeSelection + pastedData + afterSelection;\n\n const unmasked = getUnmaskedValue({\n value: newInputValue,\n transform: maskPattern.transform,\n ...transformOpts\n });\n const newMaskedValue = applyMask({\n value: unmasked,\n pattern: maskPattern.pattern,\n ...transformOpts,\n mask\n });\n\n target.value = newMaskedValue;\n\n if (isCurrencyMask({ mask, pattern: maskPattern.pattern })) {\n const currencyAtEnd = isCurrencyAtEnd(transformOpts);\n const caret = currencyAtEnd ? newMaskedValue.search(/\\s*[^\\d\\s]+$/) : newMaskedValue.length;\n target.setSelectionRange(caret, caret);\n return;\n }\n\n if (maskPattern.pattern.includes(\"%\")) {\n target.setSelectionRange(newMaskedValue.length - 1, newMaskedValue.length - 1);\n return;\n }\n\n let newCursorPosition = newMaskedValue.length;\n try {\n const unmaskedCount = unmasked.length;\n let position = 0;\n let count = 0;\n\n for (let i = 0; i < maskPattern.pattern.length && i < newMaskedValue.length; i++) {\n if (maskPattern.pattern[i] === \"#\") {\n count++;\n if (count <= unmaskedCount) {\n position = i + 1;\n }\n }\n }\n newCursorPosition = position;\n } catch {\n // Lỗi thì để con trỏ ở cuối.\n }\n\n target.setSelectionRange(newCursorPosition, newCursorPosition);\n\n if (!isControlled) setInternalValue(newMaskedValue);\n if (shouldValidate(\"change\")) onInputValidate(unmasked);\n onValueChangeProp?.(newMaskedValue, unmasked);\n },\n [\n onPasteProp,\n withoutMask,\n maskPattern,\n mask,\n transformOpts,\n isControlled,\n shouldValidate,\n onInputValidate,\n onValueChangeProp\n ]\n );\n\n const onKeyDown = React.useCallback(\n (event: React.KeyboardEvent<InputElement>) => {\n onKeyDownProp?.(event);\n if (event.defaultPrevented) return;\n\n if (withoutMask || !maskPattern) return;\n\n if (mask === \"ipv4\") return;\n\n if (event.key === \"Backspace\") {\n const target = event.target as InputElement;\n if (!(target instanceof HTMLInputElement)) return;\n const cursorPosition = target.selectionStart ?? 0;\n const selectionEnd = target.selectionEnd ?? 0;\n const currentValue = target.value;\n\n if (\n mask === \"currency\" ||\n mask === \"percentage\" ||\n maskPattern.pattern.includes(\"$\") ||\n maskPattern.pattern.includes(\"€\") ||\n maskPattern.pattern.includes(\"%\")\n ) {\n return;\n }\n\n if (cursorPosition !== selectionEnd) {\n return;\n }\n\n if (cursorPosition > 0) {\n const charBeforeCursor = currentValue[cursorPosition - 1];\n\n if (charBeforeCursor) {\n event.preventDefault();\n\n const unmaskedIndex = toUnmaskedIndex({\n masked: currentValue,\n pattern: maskPattern.pattern,\n caret: cursorPosition\n });\n\n if (unmaskedIndex > 0) {\n const currentUnmasked = getUnmaskedValue({\n value: currentValue,\n transform: maskPattern.transform,\n ...transformOpts\n });\n const nextUnmasked = currentUnmasked.slice(0, unmaskedIndex - 1) + currentUnmasked.slice(unmaskedIndex);\n const nextMasked = applyMask({\n value: nextUnmasked,\n pattern: maskPattern.pattern,\n ...transformOpts,\n mask\n });\n\n target.value = nextMasked;\n const nextCaret = fromUnmaskedIndex({\n masked: nextMasked,\n pattern: maskPattern.pattern,\n unmaskedIndex: unmaskedIndex - 1\n });\n\n target.setSelectionRange(nextCaret, nextCaret);\n\n onValueChangeProp?.(nextMasked, nextUnmasked);\n }\n return;\n }\n }\n }\n\n if (event.key === \"Delete\") {\n const target = event.target as InputElement;\n if (!(target instanceof HTMLInputElement)) return;\n const cursorPosition = target.selectionStart ?? 0;\n const selectionEnd = target.selectionEnd ?? 0;\n const currentValue = target.value;\n\n if (\n mask === \"currency\" ||\n mask === \"percentage\" ||\n maskPattern.pattern.includes(\"$\") ||\n maskPattern.pattern.includes(\"€\") ||\n maskPattern.pattern.includes(\"%\")\n ) {\n return;\n }\n\n if (cursorPosition !== selectionEnd) {\n return;\n }\n\n if (cursorPosition < currentValue.length) {\n const charAtCursor = currentValue[cursorPosition];\n\n if (charAtCursor) {\n event.preventDefault();\n\n const unmaskedIndex = toUnmaskedIndex({\n masked: currentValue,\n pattern: maskPattern.pattern,\n caret: cursorPosition\n });\n\n const currentUnmasked = getUnmaskedValue({\n value: currentValue,\n transform: maskPattern.transform,\n ...transformOpts\n });\n\n if (unmaskedIndex < currentUnmasked.length) {\n const nextUnmasked = currentUnmasked.slice(0, unmaskedIndex) + currentUnmasked.slice(unmaskedIndex + 1);\n const nextMasked = applyMask({\n value: nextUnmasked,\n pattern: maskPattern.pattern,\n ...transformOpts,\n mask\n });\n\n target.value = nextMasked;\n const nextCaret = fromUnmaskedIndex({\n masked: nextMasked,\n pattern: maskPattern.pattern,\n unmaskedIndex: unmaskedIndex\n });\n\n target.setSelectionRange(nextCaret, nextCaret);\n\n onValueChangeProp?.(nextMasked, nextUnmasked);\n }\n return;\n }\n }\n }\n },\n [maskPattern, onKeyDownProp, onValueChangeProp, transformOpts, mask, withoutMask]\n );\n\n const InputPrimitive = asChild ? Slot : \"input\";\n\n return (\n <InputPrimitive\n // ⚠ Khác thượng nguồn: chỉ phát thuộc tính khi THẬT SỰ lỗi — `aria-invalid=\"false\"` hợp lệ\n // nhưng thừa, và cùng quy ước với `Input`/`Combobox` của gói. Đặt TRƯỚC spread để\n // `aria-invalid` do `<FormControl>` dán vào vẫn thắng.\n aria-invalid={invalid || undefined}\n data-disabled={disabled ? \"\" : undefined}\n data-invalid={invalid ? \"\" : undefined}\n data-readonly={readOnly ? \"\" : undefined}\n data-required={required ? \"\" : undefined}\n data-slot=\"mask-input\"\n {...inputProps}\n className={cn(\n /*\n * ⚠ Khác thượng nguồn: chuỗi lớp của `Input` Comitor thay cho của shadcn, để ô có mặt nạ\n * đứng cạnh ô nhập thường trong cùng một form không lệch nhau (cao, nền, viền, cỡ chữ,\n * focus). Số đo của từng vai trò ở chú thích đầu `input.tsx`:\n * viền nghỉ `border-input` · hover `--control-edge-strong` · focus `--primary-ink`;\n * lỗi `border-destructive-ink` (không phải `border-destructive` — token TÔ NỀN).\n * Bỏ `dark:bg-input/30` (viết thẳng thang màu — bảng tương phản cao không đổi được) và\n * `shadow-xs` (không có trong bộ bóng của gói).\n */\n \"w-full h-9 px-3 rounded-md border bg-background text-sm text-foreground placeholder:text-muted-foreground\",\n \"transition-colors duration-150 ease-out\",\n \"focus:outline-none focus:ring-2 focus:ring-ring/50 focus:border-primary-ink\",\n \"disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-muted\",\n \"border-input hover:border-control-edge-strong\",\n \"aria-invalid:border-destructive-ink aria-invalid:hover:border-destructive-ink aria-invalid:focus:border-destructive-ink aria-invalid:focus:ring-destructive/30\",\n className\n )}\n placeholder={placeholderValue}\n ref={composedRef}\n value={displayValue}\n disabled={disabled}\n maxLength={calculatedMaxLength}\n readOnly={readOnly}\n required={required}\n inputMode={calculatedInputMode}\n min={min}\n max={max}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={onKeyDown}\n onPaste={onPaste}\n onChange={onValueChange}\n onCompositionStart={onCompositionStart}\n onCompositionEnd={onCompositionEnd}\n />\n );\n}\n\nexport { MaskInput, type MaskInputProps };\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/mask-input.tsx"],"sourcesContent":["\"use client\";\n\n/*\n * Port từ Dice UI (https://diceui.com/docs/components/mask-input) — MIT, © 2024 Sadman Sakib.\n * Giữ nguyên cấu trúc thượng nguồn để còn đối chiếu ngược được; mọi chỗ đổi đều có chú thích.\n */\n\n/*\n * ⚠ Khác thượng nguồn: thượng nguồn là MỘT file. Ở đây nửa trên (bảng `MASK_PATTERNS` + mọi hàm\n * thuần) nằm ở `mask-input-constants.ts` — hằng dữ liệu export ra không được sống trong file\n * `\"use client\"` (Server Component đọc ra `undefined`, không throw). File này chỉ còn component,\n * và chỉ `import` từ đó, KHÔNG `export` lại (re-export vòng qua file client là vô hiệu).\n */\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { useComitorLocale } from \"../../i18n/locale-provider.js\";\nimport { cn } from \"../../lib/cn.js\";\nimport { useComposedRefs } from \"../../lib/compose-refs.js\";\nimport {\n applyMask,\n CURRENCY_PERCENTAGE_SYMBOLS,\n DEFAULT_CURRENCY,\n fromUnmaskedIndex,\n getCurrencyCaretPosition,\n getPatternCaretPosition,\n getUnmaskedValue,\n isCurrencyAtEnd,\n isCurrencyMask,\n MASK_PATTERNS,\n type MaskPattern,\n type MaskPatternKey,\n NUMERIC_MASK_PATTERNS,\n REGEX_CACHE,\n toUnmaskedIndex\n} from \"./mask-input-constants.js\";\n\ntype InputElement = React.ComponentRef<\"input\">;\n\ninterface MaskInputProps extends React.ComponentProps<\"input\"> {\n value?: string;\n defaultValue?: string;\n onValueChange?: (maskedValue: string, unmaskedValue: string) => void;\n onValidate?: (isValid: boolean, unmaskedValue: string) => void;\n validationMode?: \"onChange\" | \"onBlur\" | \"onSubmit\" | \"onTouched\" | \"all\";\n /**\n * Tên một mẫu dựng sẵn (`\"currency\"`, `\"percentage\"`, `\"time\"`, `\"creditCard\"`…) hoặc một\n * `MaskPattern` tự viết. ⚠ `\"phone\"`, `\"date\"`, `\"ssn\"`, `\"zipCode\"`, `\"ein\"` là định dạng Hoa Kỳ\n * — số điện thoại ở app Comitor dùng `PhoneInput`.\n */\n mask?: MaskPatternKey | MaskPattern;\n maskPlaceholder?: string;\n /**\n * Mã tiền tệ ISO 4217 cho `mask=\"currency\"`. Mặc định `\"USD\"`, như thượng nguồn.\n *\n * Tiền tệ là thiết lập VÙNG / nghiệp vụ, không suy từ ngôn ngữ: app Comitor truyền từ cài đặt\n * workspace (vd `\"VND\"`). Trước `3.0.0` mặc định cứng là `\"VND\"`.\n */\n currency?: string;\n /**\n * Locale BCP 47 cho `mask=\"currency\"` — quyết định dấu nhóm, dấu thập phân và vị trí ký hiệu.\n * Không truyền thì theo `locale` của `ComitorLocaleProvider` (không có provider → `\"en\"` →\n * `$1,234,567`; `\"vi\"` kèm `currency=\"VND\"` → `1.234.567 ₫`).\n *\n * ⚠ Khác thượng nguồn: thượng nguồn mặc định cứng `\"en-US\"`. Trước `3.0.0` mặc định cứng là\n * `\"vi-VN\"`.\n */\n locale?: string;\n asChild?: boolean;\n invalid?: boolean;\n withoutMask?: boolean;\n}\n\nfunction MaskInput(props: MaskInputProps) {\n const {\n value: valueProp,\n defaultValue,\n onValueChange: onValueChangeProp,\n onValidate,\n onBlur: onBlurProp,\n onFocus: onFocusProp,\n onKeyDown: onKeyDownProp,\n onPaste: onPasteProp,\n onCompositionStart: onCompositionStartProp,\n onCompositionEnd: onCompositionEndProp,\n validationMode = \"onChange\",\n mask,\n maskPlaceholder,\n currency = DEFAULT_CURRENCY,\n locale: localeProp,\n placeholder,\n inputMode,\n min,\n max,\n maxLength,\n asChild = false,\n disabled = false,\n invalid = false,\n readOnly = false,\n required = false,\n withoutMask = false,\n className,\n ref,\n ...inputProps\n } = props;\n\n const { locale: providerLocale } = useComitorLocale();\n const locale = localeProp ?? providerLocale;\n const [internalValue, setInternalValue] = React.useState(defaultValue ?? \"\");\n const [focused, setFocused] = React.useState(false);\n const [composing, setComposing] = React.useState(false);\n const [touched, setTouched] = React.useState(false);\n const inputRef = React.useRef<HTMLInputElement>(null);\n const composedRef = useComposedRefs(ref, inputRef);\n\n const isControlled = valueProp !== undefined;\n const value = isControlled ? valueProp : internalValue;\n\n const maskPattern = React.useMemo(() => {\n if (typeof mask === \"string\") {\n return MASK_PATTERNS[mask];\n }\n return mask;\n }, [mask]);\n\n const transformOpts = React.useMemo(\n () => ({\n currency,\n locale\n }),\n [currency, locale]\n );\n\n const placeholderValue = React.useMemo(() => {\n if (withoutMask) return placeholder;\n\n if (placeholder && maskPlaceholder) {\n return focused ? maskPlaceholder : placeholder;\n }\n\n if (maskPlaceholder) {\n return focused ? maskPlaceholder : undefined;\n }\n\n return placeholder;\n }, [placeholder, maskPlaceholder, focused, withoutMask]);\n\n const displayValue = React.useMemo(() => {\n if (withoutMask || !maskPattern || !value) return value ?? \"\";\n const unmasked = getUnmaskedValue({\n value,\n transform: maskPattern.transform,\n ...transformOpts\n });\n return applyMask({\n value: unmasked,\n pattern: maskPattern.pattern,\n ...transformOpts,\n mask\n });\n }, [value, maskPattern, withoutMask, transformOpts, mask]);\n\n const tokenCount = React.useMemo(() => {\n if (!maskPattern || CURRENCY_PERCENTAGE_SYMBOLS.test(maskPattern.pattern)) return undefined;\n return maskPattern.pattern.match(REGEX_CACHE.hashPattern)?.length ?? 0;\n }, [maskPattern]);\n\n const calculatedMaxLength = tokenCount ? maskPattern?.pattern.length : maxLength;\n\n const calculatedInputMode = React.useMemo(() => {\n if (inputMode) return inputMode;\n if (!maskPattern) return undefined;\n\n if (mask === \"currency\" || mask === \"percentage\" || mask === \"ipv4\") {\n return \"decimal\";\n }\n\n if (typeof mask === \"string\" && NUMERIC_MASK_PATTERNS.test(mask)) {\n return \"numeric\";\n }\n return undefined;\n }, [maskPattern, mask, inputMode]);\n\n const shouldValidate = React.useCallback(\n (trigger: \"change\" | \"blur\") => {\n if (!onValidate || !maskPattern?.validate) return false;\n\n switch (validationMode) {\n case \"onChange\":\n return trigger === \"change\";\n case \"onBlur\":\n return trigger === \"blur\";\n case \"onSubmit\":\n return false;\n case \"onTouched\":\n return touched ? trigger === \"change\" : trigger === \"blur\";\n case \"all\":\n return true;\n default:\n return trigger === \"change\";\n }\n },\n [onValidate, maskPattern, validationMode, touched]\n );\n\n const validationOpts = React.useMemo(\n () => ({\n min: typeof min === \"string\" ? Number.parseFloat(min) : min,\n max: typeof max === \"string\" ? Number.parseFloat(max) : max\n }),\n [min, max]\n );\n\n const onInputValidate = React.useCallback(\n (unmaskedValue: string) => {\n if (onValidate && maskPattern?.validate) {\n const isValid = maskPattern.validate(unmaskedValue, validationOpts);\n onValidate(isValid, unmaskedValue);\n }\n },\n [onValidate, maskPattern?.validate, validationOpts]\n );\n\n const onValueChange = React.useCallback(\n (event: React.ChangeEvent<InputElement>) => {\n const inputValue = event.target.value;\n let newValue = inputValue;\n let unmaskedValue = inputValue;\n\n if (composing) {\n if (!isControlled) setInternalValue(inputValue);\n return;\n }\n\n if (withoutMask || !maskPattern) {\n if (!isControlled) setInternalValue(inputValue);\n if (shouldValidate(\"change\")) onValidate?.(true, inputValue);\n onValueChangeProp?.(inputValue, inputValue);\n return;\n }\n\n if (maskPattern) {\n unmaskedValue = getUnmaskedValue({\n value: inputValue,\n transform: maskPattern.transform,\n ...transformOpts\n });\n newValue = applyMask({\n value: unmaskedValue,\n pattern: maskPattern.pattern,\n ...transformOpts,\n mask\n });\n\n if (inputRef.current && newValue !== inputValue) {\n const inputElement = inputRef.current;\n if (!(inputElement instanceof HTMLInputElement)) return;\n\n const oldCursorPosition = inputElement.selectionStart ?? 0;\n\n inputElement.value = newValue;\n\n const currentUnmasked = getUnmaskedValue({\n value: newValue,\n transform: maskPattern.transform,\n ...transformOpts\n });\n\n let newCursorPosition: number;\n\n const previousUnmasked = getUnmaskedValue({\n value,\n transform: maskPattern.transform,\n ...transformOpts\n });\n\n if (CURRENCY_PERCENTAGE_SYMBOLS.test(maskPattern.pattern)) {\n newCursorPosition = getCurrencyCaretPosition({\n newValue,\n mask,\n transformOpts,\n oldCursorPosition,\n oldValue: inputValue,\n previousUnmasked\n });\n } else {\n newCursorPosition = getPatternCaretPosition({\n newValue,\n maskPattern,\n currentUnmasked,\n oldCursorPosition,\n oldValue: inputValue,\n previousUnmasked\n });\n }\n\n if (isCurrencyMask({ mask, pattern: maskPattern.pattern })) {\n if (mask === \"currency\") {\n const currencyAtEnd = isCurrencyAtEnd(transformOpts);\n if (!currencyAtEnd) {\n newCursorPosition = Math.max(1, newCursorPosition);\n }\n } else {\n newCursorPosition = Math.max(1, newCursorPosition);\n }\n } else if (maskPattern.pattern.includes(\"%\")) {\n newCursorPosition = Math.min(newValue.length - 1, newCursorPosition);\n }\n\n newCursorPosition = Math.min(newCursorPosition, newValue.length);\n\n inputElement.setSelectionRange(newCursorPosition, newCursorPosition);\n }\n }\n\n if (!isControlled) {\n setInternalValue(newValue);\n }\n\n if (shouldValidate(\"change\")) {\n onInputValidate(unmaskedValue);\n }\n\n onValueChangeProp?.(newValue, unmaskedValue);\n },\n [\n maskPattern,\n isControlled,\n onValueChangeProp,\n onValidate,\n onInputValidate,\n composing,\n shouldValidate,\n withoutMask,\n transformOpts,\n mask,\n value\n ]\n );\n\n const onFocus = React.useCallback(\n (event: React.FocusEvent<InputElement>) => {\n onFocusProp?.(event);\n if (event.defaultPrevented) return;\n\n setFocused(true);\n },\n [onFocusProp]\n );\n\n const onBlur = React.useCallback(\n (event: React.FocusEvent<InputElement>) => {\n onBlurProp?.(event);\n if (event.defaultPrevented) return;\n\n setFocused(false);\n\n if (!touched) {\n setTouched(true);\n }\n\n if (shouldValidate(\"blur\")) {\n const currentValue = event.target.value;\n const unmaskedValue = maskPattern\n ? getUnmaskedValue({\n value: currentValue,\n transform: maskPattern.transform,\n ...transformOpts\n })\n : currentValue;\n onInputValidate(unmaskedValue);\n }\n },\n [onBlurProp, touched, shouldValidate, onInputValidate, maskPattern, transformOpts]\n );\n\n const onCompositionStart = React.useCallback(\n (event: React.CompositionEvent<InputElement>) => {\n onCompositionStartProp?.(event);\n if (event.defaultPrevented) return;\n\n setComposing(true);\n },\n [onCompositionStartProp]\n );\n\n const onCompositionEnd = React.useCallback(\n (event: React.CompositionEvent<InputElement>) => {\n onCompositionEndProp?.(event);\n if (event.defaultPrevented) return;\n\n setComposing(false);\n\n const inputElement = inputRef.current;\n if (!inputElement) return;\n if (!(inputElement instanceof HTMLInputElement)) return;\n const inputValue = inputElement.value;\n\n if (!maskPattern || withoutMask) {\n if (!isControlled) setInternalValue(inputValue);\n if (shouldValidate(\"change\")) onValidate?.(true, inputValue);\n onValueChangeProp?.(inputValue, inputValue);\n return;\n }\n\n const unmasked = getUnmaskedValue({\n value: inputValue,\n transform: maskPattern.transform,\n ...transformOpts\n });\n const masked = applyMask({\n value: unmasked,\n pattern: maskPattern.pattern,\n ...transformOpts,\n mask\n });\n\n if (!isControlled) setInternalValue(masked);\n if (shouldValidate(\"change\")) onInputValidate(unmasked);\n onValueChangeProp?.(masked, unmasked);\n },\n [\n onCompositionEndProp,\n maskPattern,\n withoutMask,\n isControlled,\n shouldValidate,\n onValidate,\n onValueChangeProp,\n transformOpts,\n mask,\n onInputValidate\n ]\n );\n\n const onPaste = React.useCallback(\n (event: React.ClipboardEvent<InputElement>) => {\n onPasteProp?.(event);\n if (event.defaultPrevented) return;\n\n if (withoutMask || !maskPattern) return;\n\n if (mask === \"ipv4\") return;\n\n const target = event.target as InputElement;\n if (!(target instanceof HTMLInputElement)) return;\n\n const pastedData = event.clipboardData.getData(\"text\");\n if (!pastedData) return;\n\n event.preventDefault();\n\n const currentValue = target.value;\n const selectionStart = target.selectionStart ?? 0;\n const selectionEnd = target.selectionEnd ?? 0;\n\n const beforeSelection = currentValue.slice(0, selectionStart);\n const afterSelection = currentValue.slice(selectionEnd);\n const newInputValue = beforeSelection + pastedData + afterSelection;\n\n const unmasked = getUnmaskedValue({\n value: newInputValue,\n transform: maskPattern.transform,\n ...transformOpts\n });\n const newMaskedValue = applyMask({\n value: unmasked,\n pattern: maskPattern.pattern,\n ...transformOpts,\n mask\n });\n\n target.value = newMaskedValue;\n\n if (isCurrencyMask({ mask, pattern: maskPattern.pattern })) {\n const currencyAtEnd = isCurrencyAtEnd(transformOpts);\n const caret = currencyAtEnd ? newMaskedValue.search(/\\s*[^\\d\\s]+$/) : newMaskedValue.length;\n target.setSelectionRange(caret, caret);\n return;\n }\n\n if (maskPattern.pattern.includes(\"%\")) {\n target.setSelectionRange(newMaskedValue.length - 1, newMaskedValue.length - 1);\n return;\n }\n\n let newCursorPosition = newMaskedValue.length;\n try {\n const unmaskedCount = unmasked.length;\n let position = 0;\n let count = 0;\n\n for (let i = 0; i < maskPattern.pattern.length && i < newMaskedValue.length; i++) {\n if (maskPattern.pattern[i] === \"#\") {\n count++;\n if (count <= unmaskedCount) {\n position = i + 1;\n }\n }\n }\n newCursorPosition = position;\n } catch {\n // Lỗi thì để con trỏ ở cuối.\n }\n\n target.setSelectionRange(newCursorPosition, newCursorPosition);\n\n if (!isControlled) setInternalValue(newMaskedValue);\n if (shouldValidate(\"change\")) onInputValidate(unmasked);\n onValueChangeProp?.(newMaskedValue, unmasked);\n },\n [\n onPasteProp,\n withoutMask,\n maskPattern,\n mask,\n transformOpts,\n isControlled,\n shouldValidate,\n onInputValidate,\n onValueChangeProp\n ]\n );\n\n const onKeyDown = React.useCallback(\n (event: React.KeyboardEvent<InputElement>) => {\n onKeyDownProp?.(event);\n if (event.defaultPrevented) return;\n\n if (withoutMask || !maskPattern) return;\n\n if (mask === \"ipv4\") return;\n\n if (event.key === \"Backspace\") {\n const target = event.target as InputElement;\n if (!(target instanceof HTMLInputElement)) return;\n const cursorPosition = target.selectionStart ?? 0;\n const selectionEnd = target.selectionEnd ?? 0;\n const currentValue = target.value;\n\n if (\n mask === \"currency\" ||\n mask === \"percentage\" ||\n maskPattern.pattern.includes(\"$\") ||\n maskPattern.pattern.includes(\"€\") ||\n maskPattern.pattern.includes(\"%\")\n ) {\n return;\n }\n\n if (cursorPosition !== selectionEnd) {\n return;\n }\n\n if (cursorPosition > 0) {\n const charBeforeCursor = currentValue[cursorPosition - 1];\n\n if (charBeforeCursor) {\n event.preventDefault();\n\n const unmaskedIndex = toUnmaskedIndex({\n masked: currentValue,\n pattern: maskPattern.pattern,\n caret: cursorPosition\n });\n\n if (unmaskedIndex > 0) {\n const currentUnmasked = getUnmaskedValue({\n value: currentValue,\n transform: maskPattern.transform,\n ...transformOpts\n });\n const nextUnmasked = currentUnmasked.slice(0, unmaskedIndex - 1) + currentUnmasked.slice(unmaskedIndex);\n const nextMasked = applyMask({\n value: nextUnmasked,\n pattern: maskPattern.pattern,\n ...transformOpts,\n mask\n });\n\n target.value = nextMasked;\n const nextCaret = fromUnmaskedIndex({\n masked: nextMasked,\n pattern: maskPattern.pattern,\n unmaskedIndex: unmaskedIndex - 1\n });\n\n target.setSelectionRange(nextCaret, nextCaret);\n\n onValueChangeProp?.(nextMasked, nextUnmasked);\n }\n return;\n }\n }\n }\n\n if (event.key === \"Delete\") {\n const target = event.target as InputElement;\n if (!(target instanceof HTMLInputElement)) return;\n const cursorPosition = target.selectionStart ?? 0;\n const selectionEnd = target.selectionEnd ?? 0;\n const currentValue = target.value;\n\n if (\n mask === \"currency\" ||\n mask === \"percentage\" ||\n maskPattern.pattern.includes(\"$\") ||\n maskPattern.pattern.includes(\"€\") ||\n maskPattern.pattern.includes(\"%\")\n ) {\n return;\n }\n\n if (cursorPosition !== selectionEnd) {\n return;\n }\n\n if (cursorPosition < currentValue.length) {\n const charAtCursor = currentValue[cursorPosition];\n\n if (charAtCursor) {\n event.preventDefault();\n\n const unmaskedIndex = toUnmaskedIndex({\n masked: currentValue,\n pattern: maskPattern.pattern,\n caret: cursorPosition\n });\n\n const currentUnmasked = getUnmaskedValue({\n value: currentValue,\n transform: maskPattern.transform,\n ...transformOpts\n });\n\n if (unmaskedIndex < currentUnmasked.length) {\n const nextUnmasked = currentUnmasked.slice(0, unmaskedIndex) + currentUnmasked.slice(unmaskedIndex + 1);\n const nextMasked = applyMask({\n value: nextUnmasked,\n pattern: maskPattern.pattern,\n ...transformOpts,\n mask\n });\n\n target.value = nextMasked;\n const nextCaret = fromUnmaskedIndex({\n masked: nextMasked,\n pattern: maskPattern.pattern,\n unmaskedIndex: unmaskedIndex\n });\n\n target.setSelectionRange(nextCaret, nextCaret);\n\n onValueChangeProp?.(nextMasked, nextUnmasked);\n }\n return;\n }\n }\n }\n },\n [maskPattern, onKeyDownProp, onValueChangeProp, transformOpts, mask, withoutMask]\n );\n\n const InputPrimitive = asChild ? Slot : \"input\";\n\n return (\n <InputPrimitive\n // ⚠ Khác thượng nguồn: chỉ phát thuộc tính khi THẬT SỰ lỗi — `aria-invalid=\"false\"` hợp lệ\n // nhưng thừa, và cùng quy ước với `Input`/`Combobox` của gói. Đặt TRƯỚC spread để\n // `aria-invalid` do `<FormControl>` dán vào vẫn thắng.\n aria-invalid={invalid || undefined}\n data-disabled={disabled ? \"\" : undefined}\n data-invalid={invalid ? \"\" : undefined}\n data-readonly={readOnly ? \"\" : undefined}\n data-required={required ? \"\" : undefined}\n data-slot=\"mask-input\"\n {...inputProps}\n className={cn(\n /*\n * ⚠ Khác thượng nguồn: chuỗi lớp của `Input` Comitor thay cho của shadcn, để ô có mặt nạ\n * đứng cạnh ô nhập thường trong cùng một form không lệch nhau (cao, nền, viền, cỡ chữ,\n * focus). Số đo của từng vai trò ở chú thích đầu `input.tsx`:\n * viền nghỉ `border-input` · hover `--control-edge-strong` · focus `--primary-ink`;\n * lỗi `border-destructive-ink` (không phải `border-destructive` — token TÔ NỀN).\n * Bỏ `dark:bg-input/30` (viết thẳng thang màu — bảng tương phản cao không đổi được) và\n * `shadow-xs` (không có trong bộ bóng của gói).\n */\n \"w-full h-9 px-3 rounded-md border bg-background text-sm text-foreground placeholder:text-muted-foreground\",\n \"transition-colors duration-150 ease-out\",\n \"focus:outline-none focus:ring-2 focus:ring-ring/50 focus:border-primary-ink\",\n \"disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-muted\",\n \"border-input hover:border-control-edge-strong\",\n \"aria-invalid:border-destructive-ink aria-invalid:hover:border-destructive-ink aria-invalid:focus:border-destructive-ink aria-invalid:focus:ring-destructive/30\",\n className\n )}\n placeholder={placeholderValue}\n ref={composedRef}\n value={displayValue}\n disabled={disabled}\n maxLength={calculatedMaxLength}\n readOnly={readOnly}\n required={required}\n inputMode={calculatedInputMode}\n min={min}\n max={max}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={onKeyDown}\n onPaste={onPaste}\n onChange={onValueChange}\n onCompositionStart={onCompositionStart}\n onCompositionEnd={onCompositionEnd}\n />\n );\n}\n\nexport { MaskInput, type MaskInputProps };\n"],"mappings":"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","names":[]}
|
|
@@ -22,9 +22,10 @@ declare function MentionInput({ className, ...props }: MentionInputProps): React
|
|
|
22
22
|
type MentionContentProps = React.ComponentProps<typeof MentionPrimitive.Content>;
|
|
23
23
|
/**
|
|
24
24
|
* Danh sách gợi ý (`role="listbox"`), render qua portal.
|
|
25
|
-
* Tên cho trình đọc màn hình mặc định
|
|
25
|
+
* Tên cho trình đọc màn hình mặc định là khoá `listLabel` của namespace `mention`
|
|
26
|
+
* (`ComitorLocaleProvider`) — đổi bằng `aria-label`.
|
|
26
27
|
*/
|
|
27
|
-
declare function MentionContent({ className, children, "aria-label":
|
|
28
|
+
declare function MentionContent({ className, children, "aria-label": ariaLabelProp, ...props }: MentionContentProps): React.JSX.Element;
|
|
28
29
|
type MentionItemProps = React.ComponentProps<typeof MentionPrimitive.Item>;
|
|
29
30
|
declare function MentionItem({ className, children, ...props }: MentionItemProps): React.JSX.Element;
|
|
30
31
|
|
|
@@ -3,6 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import * as MentionPrimitive from "@diceui/mention";
|
|
4
4
|
import { useDirection } from "@radix-ui/react-direction";
|
|
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
|
const MentionListIdContext = React.createContext(void 0);
|
|
8
9
|
function Mention({ className, dir: dirProp, ...props }) {
|
|
@@ -69,13 +70,10 @@ function MentionInput({ className, ...props }) {
|
|
|
69
70
|
}
|
|
70
71
|
);
|
|
71
72
|
}
|
|
72
|
-
function MentionContent({
|
|
73
|
-
className,
|
|
74
|
-
children,
|
|
75
|
-
"aria-label": ariaLabel = "Danh s\xE1ch g\u1EE3i \xFD",
|
|
76
|
-
...props
|
|
77
|
-
}) {
|
|
73
|
+
function MentionContent({ className, children, "aria-label": ariaLabelProp, ...props }) {
|
|
78
74
|
const listId = React.useContext(MentionListIdContext);
|
|
75
|
+
const t = useComitorMessages("mention");
|
|
76
|
+
const ariaLabel = ariaLabelProp ?? t.listLabel;
|
|
79
77
|
return /* @__PURE__ */ jsx(MentionPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
80
78
|
MentionPrimitive.Content,
|
|
81
79
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ui/mention.tsx"],"sourcesContent":["\"use client\";\n\n/*\n * Port từ Dice UI (https://diceui.com/docs/components/mention) — MIT, © 2024 Sadman Sakib.\n * Giữ nguyên cấu trúc thượng nguồn để còn đối chiếu ngược được; mọi chỗ đổi đều có chú thích.\n */\n\nimport * as MentionPrimitive from \"@diceui/mention\";\nimport { useDirection } from \"@radix-ui/react-direction\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\n\n/*\n * ⚠ Khác thượng nguồn: context RIÊNG của lớp bọc, chỉ mang một id — xem chú thích ở `MentionInput`.\n */\nconst MentionListIdContext = React.createContext<string | undefined>(undefined);\n\n/**\n * Mention — ô nhập có gợi ý `@nhắc tên`: gõ ký tự kích hoạt (mặc định `@`) là mở danh sách, chọn\n * một mục thì chèn `@Tên` vào ô và đánh dấu nó thành một khối (xoá là xoá cả khối).\n * Dùng cho ô soạn tin của Chat và bình luận trong task.\n *\n * Phần lõi (dò ký tự kích hoạt, lọc, điều hướng bàn phím, định vị danh sách theo con trỏ) là gói\n * headless `@diceui/mention`; file này chỉ phủ style theo token của Comitor.\n */\ntype MentionProps = React.ComponentProps<typeof MentionPrimitive.Root>;\n\nfunction Mention({ className, dir: dirProp, ...props }: MentionProps) {\n /*\n * ⚠ Khác thượng nguồn: `@diceui/shared` có `useDirection` RIÊNG, đọc một `DirectionContext` mà\n * gói không xuất ra — nên `DirectionProvider` của Radix (nguồn hướng chữ của mọi component khác\n * trong gói) không tới được nó. Đọc hướng từ Radix rồi truyền xuống bằng prop `dir`.\n */\n const dir = useDirection(dirProp);\n const listId = React.useId();\n\n return (\n <MentionListIdContext.Provider value={listId}>\n <MentionPrimitive.Root\n data-slot=\"mention\"\n dir={dir}\n className={cn(\n /*\n * Khối `@Tên` đã chèn. Gói vẽ nó bằng một lớp phủ (`MentionHighlighter`) định vị TUYỆT\n * ĐỐI nằm ĐÈ LÊN ô nhập: chữ thường của lớp phủ trong suốt để lộ chữ của ô bên dưới,\n * chỉ đoạn `[data-tag]` là có nền.\n *\n * ⚠ Khác thượng nguồn: bản gốc tô `bg-blue-200 text-blue-950` / `dark:bg-blue-800\n * dark:text-blue-50` (bảng màu mặc định của Tailwind). Đổi sang cặp tonal của gói\n * (`info` = teal — bậc \"xanh\" của Comitor), và CHỮ là `text-foreground` chứ không phải\n * `text-info-ink`: nền tint `/15` trong suốt nên chữ của ô nhập vẫn lộ ra dưới khối,\n * chữ khối vẽ đè đúng chỗ đó — hai lớp chữ phải CÙNG MÀU, lệch màu là thành viền răng\n * cưa quanh từng nét. (Bản gốc cũng chọn chữ gần như trùng màu chữ thường ở cả hai theme.)\n * Khối không chỉ nói bằng màu: nó luôn mang ký tự kích hoạt `@` ở đầu.\n * chữ ⇄ khối: 15,69:1 (light, trên nền trắng) · 15,15:1 (dark) · tệ nhất 13,44:1\n * (dark tương phản cao, `--teal` #2DD4BF). Khối ⇄ nền trang 1,21:1 — cố ý nhạt.\n */\n \"**:data-tag:rounded **:data-tag:bg-info/15 **:data-tag:py-px **:data-tag:text-foreground\",\n className\n )}\n {...props}\n />\n </MentionListIdContext.Provider>\n );\n}\n\ntype MentionLabelProps = React.ComponentProps<typeof MentionPrimitive.Label>;\n\nfunction MentionLabel({ className, ...props }: MentionLabelProps) {\n return (\n <MentionPrimitive.Label\n data-slot=\"mention-label\"\n className={cn(\"px-0.5 py-1.5 text-sm font-semibold\", className)}\n {...props}\n />\n );\n}\n\ntype MentionInputProps = React.ComponentProps<typeof MentionPrimitive.Input>;\n\n/**\n * Ô nhập của `Mention`. Muốn nhiều dòng (ô soạn tin) thì `asChild` với một `<textarea />`.\n * Không có `MentionLabel` thì PHẢI truyền `aria-label`.\n */\nfunction MentionInput({ className, ...props }: MentionInputProps) {\n const listId = React.useContext(MentionListIdContext);\n\n return (\n <MentionPrimitive.Input\n data-slot=\"mention-input\"\n /*\n * ⚠ Khác thượng nguồn (a11y): ô nhập là `role=\"combobox\"` và gói đặt `aria-controls` trỏ tới\n * một id sinh trong gốc — nhưng `MentionContent` của gói KHÔNG gắn id đó lên `role=\"listbox\"`,\n * nên quan hệ combobox → listbox trỏ vào hư không. Lớp bọc tự sinh một id, gắn ở CẢ HAI đầu\n * (props của ta được trải SAU props của gói nên thắng).\n */\n aria-controls={listId}\n className={cn(\n /*\n * Khuôn viền/focus của `Input`: `border-input` lúc nghỉ, `--control-edge-strong` khi rê,\n * `--primary-ink` + `ring-2 ring/50` khi focus. Nền theo `Textarea` (ô soạn tin thường là\n * `asChild` + `<textarea>`): trong suốt, ở dark tô `--input-fill` — không `bg-input/30`,\n * xem chú thích đầu textarea.tsx.\n * ⚠ Khác thượng nguồn: `focus-visible:ring-1 ring-ring` → khuôn focus của `Input`; bỏ\n * `shadow-xs` (bóng của gói chỉ đi qua `--elevation-*`, `Input` không có bóng).\n */\n \"flex w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm text-foreground transition-colors duration-150 ease-out placeholder:text-muted-foreground hover:border-control-edge-strong focus:border-primary-ink focus:outline-none focus:ring-2 focus:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-input-fill\",\n className\n )}\n {...props}\n />\n );\n}\n\ntype MentionContentProps = React.ComponentProps<typeof MentionPrimitive.Content>;\n\n/**\n * Danh sách gợi ý (`role=\"listbox\"`), render qua portal.\n * Tên cho trình đọc màn hình mặc định \"Danh sách gợi ý\" — đổi bằng `aria-label`.\n */\nfunction MentionContent({\n className,\n children,\n \"aria-label\": ariaLabel = \"Danh sách gợi ý\",\n ...props\n}: MentionContentProps) {\n const listId = React.useContext(MentionListIdContext);\n\n return (\n <MentionPrimitive.Portal>\n <MentionPrimitive.Content\n data-slot=\"mention-content\"\n // ⚠ Khác thượng nguồn (a11y): id để `aria-controls` của ô nhập trỏ tới được — xem\n // `MentionInput`. Và `role=\"listbox\"` BẮT BUỘC có tên (ARIA 1.2); bản gốc không đặt.\n id={listId}\n aria-label={ariaLabel}\n className={cn(\n /*\n * Mặt nổi cùng bộ với `PopoverContent`/`Command`: `bg-popover text-popover-foreground`,\n * bóng `shadow-overlay` (đổi theo theme qua `--elevation-*`).\n * ⚠ Khác thượng nguồn: `shadow-md` → `shadow-overlay`; thêm `origin-(--dice-transform-origin)`\n * — biến gói headless tính sẵn theo cạnh bám, để hiệu ứng `zoom-in-95` nở ra TỪ phía con\n * trỏ như `PopoverContent` (bản gốc nở từ tâm).\n */\n \"relative z-50 min-w-32 origin-(--dice-transform-origin) overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-overlay data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n className\n )}\n {...props}\n >\n {children}\n </MentionPrimitive.Content>\n </MentionPrimitive.Portal>\n );\n}\n\ntype MentionItemProps = React.ComponentProps<typeof MentionPrimitive.Item>;\n\nfunction MentionItem({ className, children, ...props }: MentionItemProps) {\n return (\n <MentionPrimitive.Item\n data-slot=\"mention-item\"\n className={cn(\n /*\n * ⚠ Khác thượng nguồn: bộ lớp của `CommandItem` (mục đang sáng `bg-accent`/`text-accent-\n * foreground`, khoảng đệm theo trục mật độ `--menu-item-py`, icon con mặc định\n * `text-muted-foreground` cỡ 4) — chỉ đổi thuộc tính trạng thái sang dạng của gói headless\n * (`data-highlighted` / `data-disabled` là thuộc tính CÓ MẶT, không phải `=\"true\"`).\n */\n \"relative mt-1 flex w-full cursor-default items-center gap-2 rounded-sm px-2 py-(--menu-item-py) text-sm outline-hidden select-none first:mt-0 data-disabled:pointer-events-none data-disabled:opacity-50 data-highlighted:bg-accent data-highlighted:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n className\n )}\n {...props}\n >\n {children}\n </MentionPrimitive.Item>\n );\n}\n\nexport {\n Mention,\n MentionContent,\n type MentionContentProps,\n MentionInput,\n type MentionInputProps,\n MentionItem,\n type MentionItemProps,\n MentionLabel,\n type MentionLabelProps,\n type MentionProps\n};\n"],"mappings":";AAsCM;AA/BN,YAAY,sBAAsB;AAClC,SAAS,oBAAoB;AAC7B,YAAY,WAAW;AACvB,SAAS,UAAU;AAKnB,MAAM,uBAAuB,MAAM,cAAkC,MAAS;AAY9E,SAAS,QAAQ,EAAE,WAAW,KAAK,SAAS,GAAG,MAAM,GAAiB;AAMpE,QAAM,MAAM,aAAa,OAAO;AAChC,QAAM,SAAS,MAAM,MAAM;AAE3B,SACE,oBAAC,qBAAqB,UAArB,EAA8B,OAAO,QACpC;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAgBT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN,GACF;AAEJ;AAIA,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAsB;AAChE,SACE;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,uCAAuC,SAAS;AAAA,MAC7D,GAAG;AAAA;AAAA,EACN;AAEJ;AAQA,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAsB;AAChE,QAAM,SAAS,MAAM,WAAW,oBAAoB;AAEpD,SACE;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MAOV,iBAAe;AAAA,MACf,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAST;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAQA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA,cAAc,YAAY;AAAA,EAC1B,GAAG;AACL,GAAwB;AACtB,QAAM,SAAS,MAAM,WAAW,oBAAoB;AAEpD,SACE,oBAAC,iBAAiB,QAAjB,EACC;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MAGV,IAAI;AAAA,MACJ,cAAY;AAAA,MACZ,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH,GACF;AAEJ;AAIA,SAAS,YAAY,EAAE,WAAW,UAAU,GAAG,MAAM,GAAqB;AACxE,SACE;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/mention.tsx"],"sourcesContent":["\"use client\";\n\n/*\n * Port từ Dice UI (https://diceui.com/docs/components/mention) — MIT, © 2024 Sadman Sakib.\n * Giữ nguyên cấu trúc thượng nguồn để còn đối chiếu ngược được; mọi chỗ đổi đều có chú thích.\n */\n\nimport * as MentionPrimitive from \"@diceui/mention\";\nimport { useDirection } from \"@radix-ui/react-direction\";\nimport * as React from \"react\";\nimport { useComitorMessages } from \"../../i18n/locale-provider.js\";\nimport { cn } from \"../../lib/cn.js\";\n\n/*\n * ⚠ Khác thượng nguồn: context RIÊNG của lớp bọc, chỉ mang một id — xem chú thích ở `MentionInput`.\n */\nconst MentionListIdContext = React.createContext<string | undefined>(undefined);\n\n/**\n * Mention — ô nhập có gợi ý `@nhắc tên`: gõ ký tự kích hoạt (mặc định `@`) là mở danh sách, chọn\n * một mục thì chèn `@Tên` vào ô và đánh dấu nó thành một khối (xoá là xoá cả khối).\n * Dùng cho ô soạn tin của Chat và bình luận trong task.\n *\n * Phần lõi (dò ký tự kích hoạt, lọc, điều hướng bàn phím, định vị danh sách theo con trỏ) là gói\n * headless `@diceui/mention`; file này chỉ phủ style theo token của Comitor.\n */\ntype MentionProps = React.ComponentProps<typeof MentionPrimitive.Root>;\n\nfunction Mention({ className, dir: dirProp, ...props }: MentionProps) {\n /*\n * ⚠ Khác thượng nguồn: `@diceui/shared` có `useDirection` RIÊNG, đọc một `DirectionContext` mà\n * gói không xuất ra — nên `DirectionProvider` của Radix (nguồn hướng chữ của mọi component khác\n * trong gói) không tới được nó. Đọc hướng từ Radix rồi truyền xuống bằng prop `dir`.\n */\n const dir = useDirection(dirProp);\n const listId = React.useId();\n\n return (\n <MentionListIdContext.Provider value={listId}>\n <MentionPrimitive.Root\n data-slot=\"mention\"\n dir={dir}\n className={cn(\n /*\n * Khối `@Tên` đã chèn. Gói vẽ nó bằng một lớp phủ (`MentionHighlighter`) định vị TUYỆT\n * ĐỐI nằm ĐÈ LÊN ô nhập: chữ thường của lớp phủ trong suốt để lộ chữ của ô bên dưới,\n * chỉ đoạn `[data-tag]` là có nền.\n *\n * ⚠ Khác thượng nguồn: bản gốc tô `bg-blue-200 text-blue-950` / `dark:bg-blue-800\n * dark:text-blue-50` (bảng màu mặc định của Tailwind). Đổi sang cặp tonal của gói\n * (`info` = teal — bậc \"xanh\" của Comitor), và CHỮ là `text-foreground` chứ không phải\n * `text-info-ink`: nền tint `/15` trong suốt nên chữ của ô nhập vẫn lộ ra dưới khối,\n * chữ khối vẽ đè đúng chỗ đó — hai lớp chữ phải CÙNG MÀU, lệch màu là thành viền răng\n * cưa quanh từng nét. (Bản gốc cũng chọn chữ gần như trùng màu chữ thường ở cả hai theme.)\n * Khối không chỉ nói bằng màu: nó luôn mang ký tự kích hoạt `@` ở đầu.\n * chữ ⇄ khối: 15,69:1 (light, trên nền trắng) · 15,15:1 (dark) · tệ nhất 13,44:1\n * (dark tương phản cao, `--teal` #2DD4BF). Khối ⇄ nền trang 1,21:1 — cố ý nhạt.\n */\n \"**:data-tag:rounded **:data-tag:bg-info/15 **:data-tag:py-px **:data-tag:text-foreground\",\n className\n )}\n {...props}\n />\n </MentionListIdContext.Provider>\n );\n}\n\ntype MentionLabelProps = React.ComponentProps<typeof MentionPrimitive.Label>;\n\nfunction MentionLabel({ className, ...props }: MentionLabelProps) {\n return (\n <MentionPrimitive.Label\n data-slot=\"mention-label\"\n className={cn(\"px-0.5 py-1.5 text-sm font-semibold\", className)}\n {...props}\n />\n );\n}\n\ntype MentionInputProps = React.ComponentProps<typeof MentionPrimitive.Input>;\n\n/**\n * Ô nhập của `Mention`. Muốn nhiều dòng (ô soạn tin) thì `asChild` với một `<textarea />`.\n * Không có `MentionLabel` thì PHẢI truyền `aria-label`.\n */\nfunction MentionInput({ className, ...props }: MentionInputProps) {\n const listId = React.useContext(MentionListIdContext);\n\n return (\n <MentionPrimitive.Input\n data-slot=\"mention-input\"\n /*\n * ⚠ Khác thượng nguồn (a11y): ô nhập là `role=\"combobox\"` và gói đặt `aria-controls` trỏ tới\n * một id sinh trong gốc — nhưng `MentionContent` của gói KHÔNG gắn id đó lên `role=\"listbox\"`,\n * nên quan hệ combobox → listbox trỏ vào hư không. Lớp bọc tự sinh một id, gắn ở CẢ HAI đầu\n * (props của ta được trải SAU props của gói nên thắng).\n */\n aria-controls={listId}\n className={cn(\n /*\n * Khuôn viền/focus của `Input`: `border-input` lúc nghỉ, `--control-edge-strong` khi rê,\n * `--primary-ink` + `ring-2 ring/50` khi focus. Nền theo `Textarea` (ô soạn tin thường là\n * `asChild` + `<textarea>`): trong suốt, ở dark tô `--input-fill` — không `bg-input/30`,\n * xem chú thích đầu textarea.tsx.\n * ⚠ Khác thượng nguồn: `focus-visible:ring-1 ring-ring` → khuôn focus của `Input`; bỏ\n * `shadow-xs` (bóng của gói chỉ đi qua `--elevation-*`, `Input` không có bóng).\n */\n \"flex w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm text-foreground transition-colors duration-150 ease-out placeholder:text-muted-foreground hover:border-control-edge-strong focus:border-primary-ink focus:outline-none focus:ring-2 focus:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-input-fill\",\n className\n )}\n {...props}\n />\n );\n}\n\ntype MentionContentProps = React.ComponentProps<typeof MentionPrimitive.Content>;\n\n/**\n * Danh sách gợi ý (`role=\"listbox\"`), render qua portal.\n * Tên cho trình đọc màn hình mặc định là khoá `listLabel` của namespace `mention`\n * (`ComitorLocaleProvider`) — đổi bằng `aria-label`.\n */\nfunction MentionContent({ className, children, \"aria-label\": ariaLabelProp, ...props }: MentionContentProps) {\n const listId = React.useContext(MentionListIdContext);\n const t = useComitorMessages(\"mention\");\n const ariaLabel = ariaLabelProp ?? t.listLabel;\n\n return (\n <MentionPrimitive.Portal>\n <MentionPrimitive.Content\n data-slot=\"mention-content\"\n // ⚠ Khác thượng nguồn (a11y): id để `aria-controls` của ô nhập trỏ tới được — xem\n // `MentionInput`. Và `role=\"listbox\"` BẮT BUỘC có tên (ARIA 1.2); bản gốc không đặt.\n id={listId}\n aria-label={ariaLabel}\n className={cn(\n /*\n * Mặt nổi cùng bộ với `PopoverContent`/`Command`: `bg-popover text-popover-foreground`,\n * bóng `shadow-overlay` (đổi theo theme qua `--elevation-*`).\n * ⚠ Khác thượng nguồn: `shadow-md` → `shadow-overlay`; thêm `origin-(--dice-transform-origin)`\n * — biến gói headless tính sẵn theo cạnh bám, để hiệu ứng `zoom-in-95` nở ra TỪ phía con\n * trỏ như `PopoverContent` (bản gốc nở từ tâm).\n */\n \"relative z-50 min-w-32 origin-(--dice-transform-origin) overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-overlay data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n className\n )}\n {...props}\n >\n {children}\n </MentionPrimitive.Content>\n </MentionPrimitive.Portal>\n );\n}\n\ntype MentionItemProps = React.ComponentProps<typeof MentionPrimitive.Item>;\n\nfunction MentionItem({ className, children, ...props }: MentionItemProps) {\n return (\n <MentionPrimitive.Item\n data-slot=\"mention-item\"\n className={cn(\n /*\n * ⚠ Khác thượng nguồn: bộ lớp của `CommandItem` (mục đang sáng `bg-accent`/`text-accent-\n * foreground`, khoảng đệm theo trục mật độ `--menu-item-py`, icon con mặc định\n * `text-muted-foreground` cỡ 4) — chỉ đổi thuộc tính trạng thái sang dạng của gói headless\n * (`data-highlighted` / `data-disabled` là thuộc tính CÓ MẶT, không phải `=\"true\"`).\n */\n \"relative mt-1 flex w-full cursor-default items-center gap-2 rounded-sm px-2 py-(--menu-item-py) text-sm outline-hidden select-none first:mt-0 data-disabled:pointer-events-none data-disabled:opacity-50 data-highlighted:bg-accent data-highlighted:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n className\n )}\n {...props}\n >\n {children}\n </MentionPrimitive.Item>\n );\n}\n\nexport {\n Mention,\n MentionContent,\n type MentionContentProps,\n MentionInput,\n type MentionInputProps,\n MentionItem,\n type MentionItemProps,\n MentionLabel,\n type MentionLabelProps,\n type MentionProps\n};\n"],"mappings":";AAuCM;AAhCN,YAAY,sBAAsB;AAClC,SAAS,oBAAoB;AAC7B,YAAY,WAAW;AACvB,SAAS,0BAA0B;AACnC,SAAS,UAAU;AAKnB,MAAM,uBAAuB,MAAM,cAAkC,MAAS;AAY9E,SAAS,QAAQ,EAAE,WAAW,KAAK,SAAS,GAAG,MAAM,GAAiB;AAMpE,QAAM,MAAM,aAAa,OAAO;AAChC,QAAM,SAAS,MAAM,MAAM;AAE3B,SACE,oBAAC,qBAAqB,UAArB,EAA8B,OAAO,QACpC;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAgBT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN,GACF;AAEJ;AAIA,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAsB;AAChE,SACE;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,uCAAuC,SAAS;AAAA,MAC7D,GAAG;AAAA;AAAA,EACN;AAEJ;AAQA,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAsB;AAChE,QAAM,SAAS,MAAM,WAAW,oBAAoB;AAEpD,SACE;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MAOV,iBAAe;AAAA,MACf,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAST;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AASA,SAAS,eAAe,EAAE,WAAW,UAAU,cAAc,eAAe,GAAG,MAAM,GAAwB;AAC3G,QAAM,SAAS,MAAM,WAAW,oBAAoB;AACpD,QAAM,IAAI,mBAAmB,SAAS;AACtC,QAAM,YAAY,iBAAiB,EAAE;AAErC,SACE,oBAAC,iBAAiB,QAAjB,EACC;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MAGV,IAAI;AAAA,MACJ,cAAY;AAAA,MACZ,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH,GACF;AAEJ;AAIA,SAAS,YAAY,EAAE,WAAW,UAAU,GAAG,MAAM,GAAqB;AACxE,SACE;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;","names":[]}
|
|
@@ -4,10 +4,14 @@ import 'class-variance-authority/types';
|
|
|
4
4
|
import 'class-variance-authority';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Pagination —
|
|
8
|
-
* Đây là bộ khung thẻ `<a>`; bản "biết đếm trang" là composite `TablePagination`.
|
|
7
|
+
* Pagination — bộ khung thẻ `<a>`; bản "biết đếm trang" là composite `TablePagination`.
|
|
9
8
|
*
|
|
10
|
-
* Chuỗi hiển thị
|
|
9
|
+
* Chuỗi hiển thị theo `ComitorLocaleProvider` (namespace `pagination`, mặc định tiếng Anh);
|
|
10
|
+
* override từng chỗ qua prop `label` / `srLabel` / `aria-label`.
|
|
11
|
+
*
|
|
12
|
+
* `"use client"` từ `3.0.0`: chữ và tên cho trình đọc màn hình đọc từ provider, mà context chỉ
|
|
13
|
+
* đọc được ở client. Trước đó file này tĩnh và ghim cứng tiếng Việt. Không prop nào là
|
|
14
|
+
* hàm/component nên Server Component vẫn render được nó.
|
|
11
15
|
* Muốn dùng `next/link`: `<PaginationLink asChild>` chưa có ở primitive này —
|
|
12
16
|
* truyền `href` trực tiếp hoặc bọc bằng composite ở tầng app.
|
|
13
17
|
*/
|
|
@@ -18,23 +22,23 @@ type PaginationLinkProps = {
|
|
|
18
22
|
isActive?: boolean;
|
|
19
23
|
} & Pick<ButtonProps, "size"> & React.ComponentProps<"a">;
|
|
20
24
|
type PaginationPreviousProps = PaginationLinkProps & {
|
|
21
|
-
/** Nhãn hiển thị (ẩn ở màn hình nhỏ). Mặc định
|
|
25
|
+
/** Nhãn hiển thị (ẩn ở màn hình nhỏ). Mặc định: khoá `previousLabel` của namespace `pagination`. */
|
|
22
26
|
label?: React.ReactNode;
|
|
23
27
|
};
|
|
24
28
|
type PaginationNextProps = PaginationLinkProps & {
|
|
25
|
-
/** Nhãn hiển thị (ẩn ở màn hình nhỏ). Mặc định
|
|
29
|
+
/** Nhãn hiển thị (ẩn ở màn hình nhỏ). Mặc định: khoá `nextLabel` của namespace `pagination`. */
|
|
26
30
|
label?: React.ReactNode;
|
|
27
31
|
};
|
|
28
32
|
type PaginationEllipsisProps = React.ComponentProps<"span"> & {
|
|
29
|
-
/** Nhãn chỉ dành cho trình đọc màn hình. */
|
|
33
|
+
/** Nhãn chỉ dành cho trình đọc màn hình. Mặc định: khoá `ellipsisLabel` của namespace `pagination`. */
|
|
30
34
|
srLabel?: string;
|
|
31
35
|
};
|
|
32
36
|
declare function Pagination({ className, ...props }: PaginationProps): React.JSX.Element;
|
|
33
37
|
declare function PaginationContent({ className, ...props }: PaginationContentProps): React.JSX.Element;
|
|
34
38
|
declare function PaginationItem({ ...props }: PaginationItemProps): React.JSX.Element;
|
|
35
39
|
declare function PaginationLink({ className, isActive, size, ...props }: PaginationLinkProps): React.JSX.Element;
|
|
36
|
-
declare function PaginationPrevious({ className, label, ...props }: PaginationPreviousProps): React.JSX.Element;
|
|
37
|
-
declare function PaginationNext({ className, label, ...props }: PaginationNextProps): React.JSX.Element;
|
|
38
|
-
declare function PaginationEllipsis({ className, srLabel, ...props }: PaginationEllipsisProps): React.JSX.Element;
|
|
40
|
+
declare function PaginationPrevious({ className, label: labelProp, ...props }: PaginationPreviousProps): React.JSX.Element;
|
|
41
|
+
declare function PaginationNext({ className, label: labelProp, ...props }: PaginationNextProps): React.JSX.Element;
|
|
42
|
+
declare function PaginationEllipsis({ className, srLabel: srLabelProp, ...props }: PaginationEllipsisProps): React.JSX.Element;
|
|
39
43
|
|
|
40
44
|
export { Pagination, PaginationContent, type PaginationContentProps, PaginationEllipsis, type PaginationEllipsisProps, PaginationItem, type PaginationItemProps, PaginationLink, type PaginationLinkProps, PaginationNext, type PaginationNextProps, PaginationPrevious, type PaginationPreviousProps, type PaginationProps };
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from "lucide-react";
|
|
4
|
+
import { useComitorMessages } from "../../i18n/locale-provider.js";
|
|
3
5
|
import { cn } from "../../lib/cn.js";
|
|
4
6
|
import { buttonVariants } from "./button.js";
|
|
5
7
|
function Pagination({ className, ...props }) {
|
|
8
|
+
const t = useComitorMessages("pagination");
|
|
6
9
|
return (
|
|
7
10
|
// Thẻ <nav> đã ngầm mang role="navigation" — bản comitor-ds khai lại là thừa, bỏ đi.
|
|
8
11
|
/* @__PURE__ */ jsx(
|
|
9
12
|
"nav",
|
|
10
13
|
{
|
|
11
|
-
"aria-label":
|
|
14
|
+
"aria-label": t.navLabel,
|
|
12
15
|
"data-slot": "pagination",
|
|
13
16
|
className: cn("mx-auto flex w-full justify-center", className),
|
|
14
17
|
...props
|
|
@@ -38,11 +41,13 @@ function PaginationLink({ className, isActive, size = "icon", ...props }) {
|
|
|
38
41
|
}
|
|
39
42
|
);
|
|
40
43
|
}
|
|
41
|
-
function PaginationPrevious({ className, label
|
|
44
|
+
function PaginationPrevious({ className, label: labelProp, ...props }) {
|
|
45
|
+
const t = useComitorMessages("pagination");
|
|
46
|
+
const label = labelProp === void 0 ? t.previousLabel : labelProp;
|
|
42
47
|
return /* @__PURE__ */ jsxs(
|
|
43
48
|
PaginationLink,
|
|
44
49
|
{
|
|
45
|
-
"aria-label":
|
|
50
|
+
"aria-label": t.previousAriaLabel,
|
|
46
51
|
size: "default",
|
|
47
52
|
className: cn("gap-1 px-2.5 sm:pl-2.5", className),
|
|
48
53
|
...props,
|
|
@@ -53,11 +58,13 @@ function PaginationPrevious({ className, label = "Tr\u01B0\u1EDBc", ...props })
|
|
|
53
58
|
}
|
|
54
59
|
);
|
|
55
60
|
}
|
|
56
|
-
function PaginationNext({ className, label
|
|
61
|
+
function PaginationNext({ className, label: labelProp, ...props }) {
|
|
62
|
+
const t = useComitorMessages("pagination");
|
|
63
|
+
const label = labelProp === void 0 ? t.nextLabel : labelProp;
|
|
57
64
|
return /* @__PURE__ */ jsxs(
|
|
58
65
|
PaginationLink,
|
|
59
66
|
{
|
|
60
|
-
"aria-label":
|
|
67
|
+
"aria-label": t.nextAriaLabel,
|
|
61
68
|
size: "default",
|
|
62
69
|
className: cn("gap-1 px-2.5 sm:pr-2.5", className),
|
|
63
70
|
...props,
|
|
@@ -68,7 +75,9 @@ function PaginationNext({ className, label = "Sau", ...props }) {
|
|
|
68
75
|
}
|
|
69
76
|
);
|
|
70
77
|
}
|
|
71
|
-
function PaginationEllipsis({ className, srLabel
|
|
78
|
+
function PaginationEllipsis({ className, srLabel: srLabelProp, ...props }) {
|
|
79
|
+
const t = useComitorMessages("pagination");
|
|
80
|
+
const srLabel = srLabelProp ?? t.ellipsisLabel;
|
|
72
81
|
return /* @__PURE__ */ jsxs(
|
|
73
82
|
"span",
|
|
74
83
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ui/pagination.tsx"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/pagination.tsx"],"sourcesContent":["\"use client\";\n\nimport { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { useComitorMessages } from \"../../i18n/locale-provider.js\";\nimport { cn } from \"../../lib/cn.js\";\nimport { type ButtonProps, buttonVariants } from \"./button.js\";\n\n/**\n * Pagination — bộ khung thẻ `<a>`; bản \"biết đếm trang\" là composite `TablePagination`.\n *\n * Chuỗi hiển thị theo `ComitorLocaleProvider` (namespace `pagination`, mặc định tiếng Anh);\n * override từng chỗ qua prop `label` / `srLabel` / `aria-label`.\n *\n * `\"use client\"` từ `3.0.0`: chữ và tên cho trình đọc màn hình đọc từ provider, mà context chỉ\n * đọc được ở client. Trước đó file này tĩnh và ghim cứng tiếng Việt. Không prop nào là\n * hàm/component nên Server Component vẫn render được nó.\n * Muốn dùng `next/link`: `<PaginationLink asChild>` chưa có ở primitive này —\n * truyền `href` trực tiếp hoặc bọc bằng composite ở tầng app.\n */\n\nexport type PaginationProps = React.ComponentProps<\"nav\">;\nexport type PaginationContentProps = React.ComponentProps<\"ul\">;\nexport type PaginationItemProps = React.ComponentProps<\"li\">;\nexport type PaginationLinkProps = {\n isActive?: boolean;\n} & Pick<ButtonProps, \"size\"> &\n React.ComponentProps<\"a\">;\nexport type PaginationPreviousProps = PaginationLinkProps & {\n /** Nhãn hiển thị (ẩn ở màn hình nhỏ). Mặc định: khoá `previousLabel` của namespace `pagination`. */\n label?: React.ReactNode;\n};\nexport type PaginationNextProps = PaginationLinkProps & {\n /** Nhãn hiển thị (ẩn ở màn hình nhỏ). Mặc định: khoá `nextLabel` của namespace `pagination`. */\n label?: React.ReactNode;\n};\nexport type PaginationEllipsisProps = 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 `pagination`. */\n srLabel?: string;\n};\n\nfunction Pagination({ className, ...props }: PaginationProps) {\n const t = useComitorMessages(\"pagination\");\n return (\n // Thẻ <nav> đã ngầm mang role=\"navigation\" — bản comitor-ds khai lại là thừa, bỏ đi.\n <nav\n aria-label={t.navLabel}\n data-slot=\"pagination\"\n className={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n />\n );\n}\n\nfunction PaginationContent({ className, ...props }: PaginationContentProps) {\n return <ul data-slot=\"pagination-content\" className={cn(\"flex flex-row items-center gap-1\", className)} {...props} />;\n}\n\nfunction PaginationItem({ ...props }: PaginationItemProps) {\n return <li data-slot=\"pagination-item\" {...props} />;\n}\n\n/*\n * Trang ĐANG XEM: viền là `border-primary-ink`, không phải `border-gold-300`. Nền `bg-gold-50`\n * chỉ 1,09:1 so với nền trang, nên VIỀN mới là thứ mang tín hiệu \"đang ở trang này\" — ngưỡng\n * 3:1. gold-300 #E8B824 trên nền trắng chỉ **1,86:1** ✗ (dark 10,19:1 nên chỉ light hỏng).\n * `--primary-ink`: 6,51:1 với nền trang · 5,96:1 với chính nền `gold-50` (light); 12,67:1 ·\n * 11,91:1 (dark) ✓. `aria-current=\"page\"` vẫn giữ nguyên cho phần trợ năng phi thị giác.\n */\nfunction PaginationLink({ className, isActive, size = \"icon\", ...props }: PaginationLinkProps) {\n return (\n <a\n aria-current={isActive ? \"page\" : undefined}\n data-slot=\"pagination-link\"\n data-active={isActive}\n className={cn(\n buttonVariants({ variant: \"ghost\", size }),\n isActive &&\n \"border-primary-ink bg-gold-50 font-semibold text-foreground hover:bg-gold-50 dark:bg-gold-500/10 dark:hover:bg-gold-500/10\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction PaginationPrevious({ className, label: labelProp, ...props }: PaginationPreviousProps) {\n const t = useComitorMessages(\"pagination\");\n // `=== undefined` chứ không `??`: `label` là ReactNode, `null` vẫn nghĩa là \"không hiện chữ\".\n const label = labelProp === undefined ? t.previousLabel : labelProp;\n return (\n <PaginationLink\n aria-label={t.previousAriaLabel}\n size=\"default\"\n className={cn(\"gap-1 px-2.5 sm:pl-2.5\", className)}\n {...props}\n >\n <ChevronLeftIcon />\n <span className=\"hidden sm:block\">{label}</span>\n </PaginationLink>\n );\n}\n\nfunction PaginationNext({ className, label: labelProp, ...props }: PaginationNextProps) {\n const t = useComitorMessages(\"pagination\");\n const label = labelProp === undefined ? t.nextLabel : labelProp;\n return (\n <PaginationLink\n aria-label={t.nextAriaLabel}\n size=\"default\"\n className={cn(\"gap-1 px-2.5 sm:pr-2.5\", className)}\n {...props}\n >\n <span className=\"hidden sm:block\">{label}</span>\n <ChevronRightIcon />\n </PaginationLink>\n );\n}\n\nfunction PaginationEllipsis({ className, srLabel: srLabelProp, ...props }: PaginationEllipsisProps) {\n const t = useComitorMessages(\"pagination\");\n const srLabel = srLabelProp ?? t.ellipsisLabel;\n return (\n <span\n aria-hidden\n data-slot=\"pagination-ellipsis\"\n className={cn(\"flex size-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontalIcon className=\"size-4\" />\n <span className=\"sr-only\">{srLabel}</span>\n </span>\n );\n}\n\nexport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious\n};\n"],"mappings":";AA6CI,cA8CA,YA9CA;AA3CJ,SAAS,iBAAiB,kBAAkB,0BAA0B;AAEtE,SAAS,0BAA0B;AACnC,SAAS,UAAU;AACnB,SAA2B,sBAAsB;AAmCjD,SAAS,WAAW,EAAE,WAAW,GAAG,MAAM,GAAoB;AAC5D,QAAM,IAAI,mBAAmB,YAAY;AACzC;AAAA;AAAA,IAEE;AAAA,MAAC;AAAA;AAAA,QACC,cAAY,EAAE;AAAA,QACd,aAAU;AAAA,QACV,WAAW,GAAG,sCAAsC,SAAS;AAAA,QAC5D,GAAG;AAAA;AAAA,IACN;AAAA;AAEJ;AAEA,SAAS,kBAAkB,EAAE,WAAW,GAAG,MAAM,GAA2B;AAC1E,SAAO,oBAAC,QAAG,aAAU,sBAAqB,WAAW,GAAG,oCAAoC,SAAS,GAAI,GAAG,OAAO;AACrH;AAEA,SAAS,eAAe,EAAE,GAAG,MAAM,GAAwB;AACzD,SAAO,oBAAC,QAAG,aAAU,mBAAmB,GAAG,OAAO;AACpD;AASA,SAAS,eAAe,EAAE,WAAW,UAAU,OAAO,QAAQ,GAAG,MAAM,GAAwB;AAC7F,SACE;AAAA,IAAC;AAAA;AAAA,MACC,gBAAc,WAAW,SAAS;AAAA,MAClC,aAAU;AAAA,MACV,eAAa;AAAA,MACb,WAAW;AAAA,QACT,eAAe,EAAE,SAAS,SAAS,KAAK,CAAC;AAAA,QACzC,YACE;AAAA,QACF;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,mBAAmB,EAAE,WAAW,OAAO,WAAW,GAAG,MAAM,GAA4B;AAC9F,QAAM,IAAI,mBAAmB,YAAY;AAEzC,QAAM,QAAQ,cAAc,SAAY,EAAE,gBAAgB;AAC1D,SACE;AAAA,IAAC;AAAA;AAAA,MACC,cAAY,EAAE;AAAA,MACd,MAAK;AAAA,MACL,WAAW,GAAG,0BAA0B,SAAS;AAAA,MAChD,GAAG;AAAA,MAEJ;AAAA,4BAAC,mBAAgB;AAAA,QACjB,oBAAC,UAAK,WAAU,mBAAmB,iBAAM;AAAA;AAAA;AAAA,EAC3C;AAEJ;AAEA,SAAS,eAAe,EAAE,WAAW,OAAO,WAAW,GAAG,MAAM,GAAwB;AACtF,QAAM,IAAI,mBAAmB,YAAY;AACzC,QAAM,QAAQ,cAAc,SAAY,EAAE,YAAY;AACtD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,cAAY,EAAE;AAAA,MACd,MAAK;AAAA,MACL,WAAW,GAAG,0BAA0B,SAAS;AAAA,MAChD,GAAG;AAAA,MAEJ;AAAA,4BAAC,UAAK,WAAU,mBAAmB,iBAAM;AAAA,QACzC,oBAAC,oBAAiB;AAAA;AAAA;AAAA,EACpB;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,eAAW;AAAA,MACX,aAAU;AAAA,MACV,WAAW,GAAG,2CAA2C,SAAS;AAAA,MACjE,GAAG;AAAA,MAEJ;AAAA,4BAAC,sBAAmB,WAAU,UAAS;AAAA,QACvC,oBAAC,UAAK,WAAU,WAAW,mBAAQ;AAAA;AAAA;AAAA,EACrC;AAEJ;","names":[]}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
interface PhoneInputCountry {
|
|
21
21
|
/** Mã ISO 3166-1 alpha-2, viết HOA — `"VN"`. */
|
|
22
22
|
code: string;
|
|
23
|
-
/** Tên hiển thị trong danh sách và trong nhãn của nút chọn — `"
|
|
23
|
+
/** Tên hiển thị trong danh sách và trong nhãn của nút chọn — `"Vietnam"` (theo `locale`). */
|
|
24
24
|
name: string;
|
|
25
25
|
/** Mã quay số quốc tế, có dấu `+` — `"+84"`. */
|
|
26
26
|
dialCode: string;
|
|
@@ -28,11 +28,12 @@ interface PhoneInputCountry {
|
|
|
28
28
|
flag?: string;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
|
-
* Chuỗi hiển thị của `PhoneInput` (kể cả chuỗi chỉ dành cho trình đọc màn hình)
|
|
32
|
-
*
|
|
31
|
+
* Chuỗi hiển thị của `PhoneInput` (kể cả chuỗi chỉ dành cho trình đọc màn hình). Theo
|
|
32
|
+
* `ComitorLocaleProvider` (mặc định tiếng Anh, bảng tiếng Việt dựng sẵn); override từng khoá qua
|
|
33
|
+
* prop `labels`.
|
|
33
34
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
35
|
+
* Tên quốc gia KHÔNG nằm ở đây — `Intl.DisplayNames` gọi theo `locale` (prop `locale` của
|
|
36
|
+
* `PhoneInput`, không truyền thì `locale` của provider).
|
|
36
37
|
*/
|
|
37
38
|
interface PhoneInputLabels {
|
|
38
39
|
/**
|
|
@@ -47,8 +48,18 @@ interface PhoneInputLabels {
|
|
|
47
48
|
searchPlaceholder: string;
|
|
48
49
|
/** Dòng báo khi không quốc gia nào khớp từ khoá. */
|
|
49
50
|
empty: string;
|
|
51
|
+
/**
|
|
52
|
+
* Placeholder của ô nhập số. Prop `placeholder` rời (tên của thượng nguồn — trên `PhoneInput`,
|
|
53
|
+
* hoặc trên chính `PhoneInputField`) thắng khoá này nếu có. Thêm ở `3.0.0`: trước đó placeholder
|
|
54
|
+
* chỉ là mặc định viết thẳng trong component.
|
|
55
|
+
*/
|
|
56
|
+
placeholder: string;
|
|
50
57
|
}
|
|
51
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* Nhãn TIẾNG ANH mặc định (từ `3.0.0`; trước đó là tiếng Việt). Bảng tiếng Việt:
|
|
60
|
+
* `comitorMessagesVi.phoneInput`. Component không đọc thẳng hằng này — nó đọc bảng của
|
|
61
|
+
* `ComitorLocaleProvider`; hằng ở đây để app trải ra khi tự dựng nhãn.
|
|
62
|
+
*/
|
|
52
63
|
declare const DEFAULT_PHONE_INPUT_LABELS: PhoneInputLabels;
|
|
53
64
|
|
|
54
65
|
export { DEFAULT_PHONE_INPUT_LABELS, type PhoneInputCountry, type PhoneInputLabels };
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
searchPlaceholder: "T\xECm qu\u1ED1c gia\u2026",
|
|
4
|
-
empty: "Kh\xF4ng t\xECm th\u1EA5y qu\u1ED1c gia."
|
|
5
|
-
};
|
|
1
|
+
import { phoneInputEn } from "../../i18n/namespaces/phone-input.js";
|
|
2
|
+
const DEFAULT_PHONE_INPUT_LABELS = { ...phoneInputEn };
|
|
6
3
|
export {
|
|
7
4
|
DEFAULT_PHONE_INPUT_LABELS
|
|
8
5
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ui/phone-input-constants.ts"],"sourcesContent":["/**\n * Kiểu quốc gia và nhãn mặc định của `PhoneInput`.\n *\n * Module **CỐ Ý không có `\"use client\"`** — xem `src/chart/chart-colors.ts` để biết lý do đầy\n * đủ: mọi export của một file `\"use client\"` đến tay Server Component dưới dạng\n * client-reference proxy, đọc ra `undefined` mà KHÔNG throw, KHÔNG warning. Hằng dữ liệu thuần\n * (nhãn mặc định) phải sống ngoài ranh giới client để app spread/override được ở cả hai phía.\n *\n * ⚠ Barrel `src/index.ts` xuất module này TRỰC TIẾP. `phone-input.tsx` chỉ được `import`,\n * KHÔNG được `export` lại (re-export qua file client là vô hiệu, và đụng tên với `export *`).\n */\n\n/**\n * Một quốc gia trong danh sách chọn của `PhoneInput` — cũng là hình dạng của prop `countries`\n * khi app muốn tự giới hạn danh sách.\n *\n * ⚠ Khác thượng nguồn: thượng nguồn khai kiểu này dưới tên `Country` và KHÔNG export (app phải\n * viết `PhoneInputProps[\"countries\"]`). Ở đây export dưới tên có tiền tố — `Country` trần là tên\n * quá chung cho entry chính.\n */\nexport interface PhoneInputCountry {\n /** Mã ISO 3166-1 alpha-2, viết HOA — `\"VN\"`. */\n code: string;\n /** Tên hiển thị trong danh sách và trong nhãn của nút chọn — `\"
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/phone-input-constants.ts"],"sourcesContent":["/**\n * Kiểu quốc gia và nhãn mặc định của `PhoneInput`.\n *\n * Module **CỐ Ý không có `\"use client\"`** — xem `src/chart/chart-colors.ts` để biết lý do đầy\n * đủ: mọi export của một file `\"use client\"` đến tay Server Component dưới dạng\n * client-reference proxy, đọc ra `undefined` mà KHÔNG throw, KHÔNG warning. Hằng dữ liệu thuần\n * (nhãn mặc định) phải sống ngoài ranh giới client để app spread/override được ở cả hai phía.\n *\n * ⚠ Barrel `src/index.ts` xuất module này TRỰC TIẾP. `phone-input.tsx` chỉ được `import`,\n * KHÔNG được `export` lại (re-export qua file client là vô hiệu, và đụng tên với `export *`).\n */\n\nimport { phoneInputEn } from \"../../i18n/namespaces/phone-input.js\";\n\n/**\n * Một quốc gia trong danh sách chọn của `PhoneInput` — cũng là hình dạng của prop `countries`\n * khi app muốn tự giới hạn danh sách.\n *\n * ⚠ Khác thượng nguồn: thượng nguồn khai kiểu này dưới tên `Country` và KHÔNG export (app phải\n * viết `PhoneInputProps[\"countries\"]`). Ở đây export dưới tên có tiền tố — `Country` trần là tên\n * quá chung cho entry chính.\n */\nexport interface PhoneInputCountry {\n /** Mã ISO 3166-1 alpha-2, viết HOA — `\"VN\"`. */\n code: string;\n /** Tên hiển thị trong danh sách và trong nhãn của nút chọn — `\"Vietnam\"` (theo `locale`). */\n name: string;\n /** Mã quay số quốc tế, có dấu `+` — `\"+84\"`. */\n dialCode: string;\n /** Cờ emoji — `\"🇻🇳\"`. Bỏ trống thì không vẽ cờ. */\n flag?: string;\n}\n\n/**\n * Chuỗi hiển thị của `PhoneInput` (kể cả chuỗi chỉ dành cho trình đọc màn hình). Theo\n * `ComitorLocaleProvider` (mặc định tiếng Anh, bảng tiếng Việt dựng sẵn); override từng khoá qua\n * prop `labels`.\n *\n * Tên quốc gia KHÔNG nằm ở đây — `Intl.DisplayNames` gọi theo `locale` (prop `locale` của\n * `PhoneInput`, không truyền thì `locale` của provider).\n */\nexport interface PhoneInputLabels {\n /**\n * Tên cho trình đọc màn hình của nút chọn quốc gia. Nhận quốc gia đang chọn (`undefined` khi\n * chưa chọn) vì tên phải nói được GIÁ TRỊ hiện tại — nút chỉ chứa một lá cờ emoji.\n *\n * ⚠ Thêm so với thượng nguồn: ở bản gốc nút này KHÔNG có tên (lá cờ + mũi tên, hoặc một ô xám\n * trống khi chưa chọn). Là HÀM chứ không phải chuỗi mẫu vì có giá trị chèn vào giữa câu.\n */\n countrySelect: (country: PhoneInputCountry | undefined) => string;\n /** Placeholder ô tìm kiếm trong danh sách quốc gia. */\n searchPlaceholder: string;\n /** Dòng báo khi không quốc gia nào khớp từ khoá. */\n empty: string;\n /**\n * Placeholder của ô nhập số. Prop `placeholder` rời (tên của thượng nguồn — trên `PhoneInput`,\n * hoặc trên chính `PhoneInputField`) thắng khoá này nếu có. Thêm ở `3.0.0`: trước đó placeholder\n * chỉ là mặc định viết thẳng trong component.\n */\n placeholder: string;\n}\n\n/**\n * Nhãn TIẾNG ANH mặc định (từ `3.0.0`; trước đó là tiếng Việt). Bảng tiếng Việt:\n * `comitorMessagesVi.phoneInput`. Component không đọc thẳng hằng này — nó đọc bảng của\n * `ComitorLocaleProvider`; hằng ở đây để app trải ra khi tự dựng nhãn.\n */\nexport const DEFAULT_PHONE_INPUT_LABELS: PhoneInputLabels = { ...phoneInputEn };\n"],"mappings":"AAYA,SAAS,oBAAoB;AAuDtB,MAAM,6BAA+C,EAAE,GAAG,aAAa;","names":[]}
|
|
@@ -26,11 +26,11 @@ declare function useStore<T>(selector: (state: StoreState) => T, ogStore?: Store
|
|
|
26
26
|
* (`PhoneInputField`). Giá trị (`value` / `onValueChange` / input ẩn khi submit form) luôn là E.164
|
|
27
27
|
* chỉ gồm chữ số: `"+84912345678"`. Người dùng gõ được theo HAI cách:
|
|
28
28
|
*
|
|
29
|
-
* - **Số nội địa** — chuỗi KHÔNG bắt đầu bằng `+`, và đang có quốc gia được chọn (
|
|
30
|
-
*
|
|
29
|
+
* - **Số nội địa** — chuỗi KHÔNG bắt đầu bằng `+`, và đang có quốc gia được chọn (`defaultCountry`
|
|
30
|
+
* / `country`, hoặc người dùng chọn): bỏ một số 0 đầu rồi ghép mã quay số của nước đang chọn. Ô hiện NGUYÊN VĂN chữ đã gõ
|
|
31
31
|
* (chỉ gạt ký tự không phải số hay `space ( ) . -`), con trỏ không nhảy; đổi quốc gia thì giá trị
|
|
32
32
|
* ghép lại theo mã mới, còn chữ trên ô giữ nguyên.
|
|
33
|
-
*
|
|
33
|
+
* Nước là Việt Nam, gõ `0912 345 678` → ô hiện `0912 345 678`, `onValueChange("+84912345678")`.
|
|
34
34
|
* ⚠ Khác thượng nguồn — bản gốc ra `+0912345678`. Ý, San Marino, Vatican giữ số 0 đầu (máy bàn
|
|
35
35
|
* `06 …` → `+39 06 …`).
|
|
36
36
|
* - **Số quốc tế** — chuỗi bắt đầu bằng `+` (như thượng nguồn): ô hiện tách nhóm
|
|
@@ -38,9 +38,10 @@ declare function useStore<T>(selector: (state: StoreState) => T, ogStore?: Store
|
|
|
38
38
|
* Gõ `+84 912 345 678` → `onValueChange("+84912345678")`, cờ chuyển sang Việt Nam.
|
|
39
39
|
*
|
|
40
40
|
* Giá trị nạp từ ngoài (`value`/`defaultValue`) luôn hiện ở dạng quốc tế. Không có quốc gia nào
|
|
41
|
-
* được chọn
|
|
41
|
+
* được chọn — MẶC ĐỊNH từ `3.0.0` — thì mọi chữ số đầu bị coi là mã quốc gia, như thượng nguồn:
|
|
42
|
+
* gõ `0912 345 678` ra `+0912345678`, gõ `84 912 345 678` ra `+84912345678` và cờ tự nhận Việt Nam.
|
|
42
43
|
*
|
|
43
|
-
* Gốc là `role="group"` chưa có tên: đặt `aria-label` (vd "
|
|
44
|
+
* Gốc là `role="group"` chưa có tên: đặt `aria-label` (vd "Phone number") hoặc `aria-labelledby`
|
|
44
45
|
* cho chính `PhoneInput`.
|
|
45
46
|
*/
|
|
46
47
|
interface PhoneInputProps extends React.ComponentProps<"div"> {
|
|
@@ -48,25 +49,31 @@ interface PhoneInputProps extends React.ComponentProps<"div"> {
|
|
|
48
49
|
value?: string;
|
|
49
50
|
onValueChange?: (value: string) => void;
|
|
50
51
|
/**
|
|
51
|
-
* Quốc gia ban đầu (mã ISO alpha-2, viết HOA). Mặc định
|
|
52
|
+
* Quốc gia ban đầu (mã ISO alpha-2, viết HOA). Mặc định: KHÔNG CÓ, như thượng nguồn — nước là
|
|
53
|
+
* thiết lập VÙNG, không suy từ ngôn ngữ; app Comitor truyền từ cài đặt workspace.
|
|
52
54
|
*
|
|
53
|
-
* ⚠
|
|
55
|
+
* ⚠ Không có quốc gia thì chế độ số NỘI ĐỊA tắt (xem JSDoc của `PhoneInput`). Trước `3.0.0`
|
|
56
|
+
* mặc định cứng là `"VN"`.
|
|
54
57
|
*/
|
|
55
58
|
defaultCountry?: string;
|
|
56
59
|
country?: string;
|
|
57
60
|
onCountryChange?: (country: string) => void;
|
|
58
61
|
countries?: PhoneInputCountry[];
|
|
59
62
|
name?: string;
|
|
60
|
-
/** Placeholder ô nhập
|
|
63
|
+
/** Placeholder ô nhập số — thắng khoá `labels.placeholder` (namespace `phoneInput`). */
|
|
61
64
|
placeholder?: string;
|
|
62
65
|
/**
|
|
63
|
-
* Locale BCP 47 để gọi tên quốc gia (`Intl.DisplayNames`) và sắp xếp danh sách.
|
|
64
|
-
*
|
|
66
|
+
* Locale BCP 47 để gọi tên quốc gia (`Intl.DisplayNames`) và sắp xếp danh sách. Không truyền thì
|
|
67
|
+
* theo `locale` của `ComitorLocaleProvider` (không có provider → `"en"`; trước `3.0.0` mặc định
|
|
68
|
+
* cứng là `"vi"`). Bỏ qua khi app truyền `countries` riêng (tên lấy nguyên từ đó).
|
|
65
69
|
*
|
|
66
70
|
* ⚠ Thêm so với thượng nguồn — bản gốc ghim tên tiếng Anh.
|
|
67
71
|
*/
|
|
68
72
|
locale?: string;
|
|
69
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* Chuỗi hiển thị/đọc màn hình (phần chọn quốc gia + placeholder ô số) — override từng khoá. Không
|
|
75
|
+
* truyền thì theo namespace `phoneInput` của `ComitorLocaleProvider` (mặc định tiếng Anh).
|
|
76
|
+
*/
|
|
70
77
|
labels?: Partial<PhoneInputLabels>;
|
|
71
78
|
asChild?: boolean;
|
|
72
79
|
disabled?: boolean;
|