@rotki/ui-library 2.21.0 → 2.22.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/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/avatars/avatar-props.js +1 -1
- package/dist/components/avatars/avatar-props.js.map +1 -1
- package/dist/components/avatars/use-avatar-group.js.map +1 -1
- package/dist/components/buttons/button/RuiButton.js.map +1 -1
- package/dist/components/buttons/button/RuiButton.vue.d.ts +2 -2
- package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/buttons/button/button-props.js.map +1 -1
- package/dist/components/buttons/button/button-styles.js.map +1 -1
- package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/state.js.map +1 -1
- package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chips/chip-props.js.map +1 -1
- package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorDisplay.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/color-picker/RuiColorDisplay.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/utils.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/date-time-picker-styles.js.map +1 -1
- package/dist/components/date-time-picker/dayjs-setup.js.map +1 -1
- package/dist/components/date-time-picker/segment-config.js.map +1 -1
- package/dist/components/date-time-picker/segment-utils.js.map +1 -1
- package/dist/components/date-time-picker/timezones.js.map +1 -1
- package/dist/components/date-time-picker/types.js +1 -1
- package/dist/components/date-time-picker/types.js.map +1 -1
- package/dist/components/date-time-picker/use-date-time-selection.js +2 -2
- package/dist/components/date-time-picker/use-date-time-selection.js.map +1 -1
- package/dist/components/date-time-picker/use-input-handler.js.map +1 -1
- package/dist/components/date-time-picker/use-keyboard-handler.js.map +1 -1
- package/dist/components/date-time-picker/utils.js.map +1 -1
- package/dist/components/divider/RuiDivider.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/divider/RuiDivider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue.d.ts +14 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +15 -5
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/auto-complete-styles.js.map +1 -1
- package/dist/components/forms/category-picker/RuiCategoryPicker.js +7 -0
- package/dist/components/forms/category-picker/RuiCategoryPicker.js.map +1 -0
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue.d.ts +134 -0
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js +561 -0
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/forms/category-picker/category-picker-styles.d.ts +432 -0
- package/dist/components/forms/category-picker/category-picker-styles.js +59 -0
- package/dist/components/forms/category-picker/category-picker-styles.js.map +1 -0
- package/dist/components/forms/check-control-styles.js.map +1 -1
- package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/checkbox/checkbox-group/context.js.map +1 -1
- package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -1
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/select/menu-select-styles.js.map +1 -1
- package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/slider/slider-styles.js.map +1 -1
- package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/text-area/text-area-styles.js.map +1 -1
- package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/text-field/text-field-styles.js.map +1 -1
- package/dist/components/forms/text-input-styles.js.map +1 -1
- package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/index.d.ts +3 -2
- package/dist/components/index.js +3 -2
- package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/loaders/skeleton-type.js.map +1 -1
- package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/logos/use-logo-sources.js.map +1 -1
- package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/badge/badge-props.js.map +1 -1
- package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/tooltip/tooltip-styles.js.map +1 -1
- package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/progress/progress-props.js.map +1 -1
- package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/RuiStepperCustomIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/steppers/RuiStepperCustomIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/footer-stepper-variant.js.map +1 -1
- package/dist/components/tables/RuiDataTable.js.map +1 -1
- package/dist/components/tables/RuiDataTable.vue.d.ts +23 -2
- package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js +186 -217
- package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTableHead.js.map +1 -1
- package/dist/components/tables/RuiTableHead.vue.d.ts +11 -1
- package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js +1 -2
- package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTablePagination.js.map +1 -1
- package/dist/components/tables/RuiTablePagination.vue.d.ts +5 -0
- package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js +24 -8
- package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableBody.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableBody.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableBody.vue.d.ts +55 -0
- package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js +78 -0
- package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableCell.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableCell.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableCell.vue.d.ts +30 -0
- package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js +54 -0
- package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableEmptyRow.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableEmptyRow.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue.d.ts +19 -0
- package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue_vue_type_script_setup_true_lang.js +43 -0
- package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue.d.ts +26 -0
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js +31 -0
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableGroupRow.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableGroupRow.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableGroupRow.vue.d.ts +32 -0
- package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js +85 -0
- package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableLoadingRow.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableLoadingRow.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue.d.ts +3 -0
- package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue_vue_type_script_setup_true_lang.js +26 -0
- package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableMobileSort.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableMobileSort.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableMobileSort.vue.d.ts +33 -0
- package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js +101 -0
- package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableRow.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableRow.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableRow.vue.d.ts +31 -0
- package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js +142 -0
- package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/context.d.ts +73 -0
- package/dist/components/tables/data-table/context.js +100 -0
- package/dist/components/tables/data-table/context.js.map +1 -0
- package/dist/components/tables/data-table-styles.d.ts +30 -1
- package/dist/components/tables/data-table-styles.js +9 -2
- package/dist/components/tables/data-table-styles.js.map +1 -1
- package/dist/components/tables/table-props.d.ts +5 -0
- package/dist/components/tables/table-props.js +5 -1
- package/dist/components/tables/table-props.js.map +1 -1
- package/dist/components/tables/use-pagination-navigation.js.map +1 -1
- package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tab/use-tab-link.js.map +1 -1
- package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tab-items/RuiTabItems.js.map +1 -1
- package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tab-props.js.map +1 -1
- package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tabs/use-tab-routing.js +1 -1
- package/dist/components/tabs/tabs/use-tab-routing.js.map +1 -1
- package/dist/components/tabs/tabs/use-tab-scroll.js.map +1 -1
- package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/time-picker/time-picker-styles.js.map +1 -1
- package/dist/composables/breakpoint.js.map +1 -1
- package/dist/composables/defaults/table.d.ts +12 -0
- package/dist/composables/defaults/table.js.map +1 -1
- package/dist/composables/dropdown-menu.js.map +1 -1
- package/dist/composables/floating.js +1 -1
- package/dist/composables/floating.js.map +1 -1
- package/dist/composables/forms/auto-complete/focus.js.map +1 -1
- package/dist/composables/forms/auto-complete/index.js +5 -4
- package/dist/composables/forms/auto-complete/keyboard-navigation.js.map +1 -1
- package/dist/composables/forms/auto-complete/search.d.ts +6 -1
- package/dist/composables/forms/auto-complete/search.js +12 -1
- package/dist/composables/forms/auto-complete/search.js.map +1 -1
- package/dist/composables/forms/auto-complete/value.js.map +1 -1
- package/dist/composables/forms/category-picker/use-category-picker.d.ts +76 -0
- package/dist/composables/forms/category-picker/use-category-picker.js +141 -0
- package/dist/composables/forms/category-picker/use-category-picker.js.map +1 -0
- package/dist/composables/forms/use-prepend-append-width.js.map +1 -1
- package/dist/composables/icons.js.map +1 -1
- package/dist/composables/popper.js.map +1 -1
- package/dist/composables/sticky-header.js.map +1 -1
- package/dist/composables/tables/data-table/columns.d.ts +7 -1
- package/dist/composables/tables/data-table/columns.js +18 -10
- package/dist/composables/tables/data-table/columns.js.map +1 -1
- package/dist/composables/tables/data-table/expansion.js.map +1 -1
- package/dist/composables/tables/data-table/grouping.d.ts +4 -6
- package/dist/composables/tables/data-table/grouping.js +38 -24
- package/dist/composables/tables/data-table/grouping.js.map +1 -1
- package/dist/composables/tables/data-table/pagination.d.ts +4 -4
- package/dist/composables/tables/data-table/pagination.js +63 -21
- package/dist/composables/tables/data-table/pagination.js.map +1 -1
- package/dist/composables/tables/data-table/selection.js +16 -6
- package/dist/composables/tables/data-table/selection.js.map +1 -1
- package/dist/composables/tables/data-table/sort.d.ts +4 -3
- package/dist/composables/tables/data-table/sort.js +78 -40
- package/dist/composables/tables/data-table/sort.js.map +1 -1
- package/dist/composables/tables/data-table/types.d.ts +3 -1
- package/dist/composables/tables/data-table/types.js +6 -2
- package/dist/composables/tables/data-table/types.js.map +1 -1
- package/dist/composables/theme.js.map +1 -1
- package/dist/composables/timeout-manager.js.map +1 -1
- package/dist/composables/use-rui-i18n.js.map +1 -1
- package/dist/consts/colors.js.map +1 -1
- package/dist/consts/time-accuracy.js.map +1 -1
- package/dist/i18n/keys.js.map +1 -1
- package/dist/icons/icons_1.d.ts +12 -12
- package/dist/icons/icons_1.js +140 -157
- package/dist/icons/icons_1.js.map +1 -1
- package/dist/icons/icons_2.d.ts +13 -13
- package/dist/icons/icons_2.js +128 -149
- package/dist/icons/icons_2.js.map +1 -1
- package/dist/icons/icons_3.d.ts +18 -18
- package/dist/icons/icons_3.js +244 -282
- package/dist/icons/icons_3.js.map +1 -1
- package/dist/icons/icons_4.d.ts +251 -6
- package/dist/icons/icons_4.js +3016 -75
- package/dist/icons/icons_4.js.map +1 -1
- package/dist/icons/icons_5.d.ts +20 -0
- package/dist/icons/icons_5.js +221 -0
- package/dist/icons/icons_5.js.map +1 -0
- package/dist/icons/index.d.ts +2 -1
- package/dist/icons/index.js +297 -32
- package/dist/icons/index.js.map +1 -1
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/dist/library-icons.json +1 -0
- package/dist/style.css +152 -0
- package/dist/theme/index.js.map +1 -1
- package/dist/types/stepper.js.map +1 -1
- package/dist/types/theme.js.map +1 -1
- package/dist/utils/assert.js.map +1 -1
- package/dist/utils/blockie.js.map +1 -1
- package/dist/utils/form-text-detail.js.map +1 -1
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/is-equal.js.map +1 -1
- package/dist/utils/tv.js.map +1 -1
- package/dist/vite-plugin/index.js +6 -5
- package/dist/vite-plugin/index.js.map +1 -1
- package/dist/vite-plugin/scanner.d.ts +1 -1
- package/dist/vite-plugin/scanner.js +10 -7
- package/dist/vite-plugin/scanner.js.map +1 -1
- package/dist/vite-plugin/types.d.ts +9 -0
- package/dist/web-types.json +2042 -1108
- package/package.json +35 -35
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../../src/components/date-time-picker/types.ts"],"sourcesContent":["import type { Ref } from 'vue';\n\nexport const DATE_TIME_SEGMENT_TYPES = [\n 'DD',\n 'MM',\n 'YYYY',\n 'HH',\n 'mm',\n 'ss',\n 'SSS',\n] as const;\n\nexport type DateTimeSegmentType = typeof DATE_TIME_SEGMENT_TYPES[number];\n\nexport function isDateTimeSegmentType(value: string): value is DateTimeSegmentType {\n return (DATE_TIME_SEGMENT_TYPES as readonly string[]).includes(value);\n}\n\nexport type SegmentData = Record<DateTimeSegmentType, Ref<number | undefined>>;\n"],"mappings":";AAEA,IAAa,0BAA0B;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../../src/components/date-time-picker/types.ts"],"sourcesContent":["import type { Ref } from 'vue';\n\nexport const DATE_TIME_SEGMENT_TYPES = [\n 'DD',\n 'MM',\n 'YYYY',\n 'HH',\n 'mm',\n 'ss',\n 'SSS',\n] as const;\n\nexport type DateTimeSegmentType = typeof DATE_TIME_SEGMENT_TYPES[number];\n\nexport function isDateTimeSegmentType(value: string): value is DateTimeSegmentType {\n return (DATE_TIME_SEGMENT_TYPES as readonly string[]).includes(value);\n}\n\nexport type SegmentData = Record<DateTimeSegmentType, Ref<number | undefined>>;\n"],"mappings":";AAEA,IAAa,0BAA0B;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAIA,SAAgB,sBAAsB,OAA6C;CACjF,OAAQ,wBAA8C,SAAS,KAAK;AACtE"}
|
|
@@ -23,13 +23,13 @@ function useDateTimeSelection(options) {
|
|
|
23
23
|
const now = ref(dayjs.tz(void 0, guessTimezone()));
|
|
24
24
|
const minAllowedDate = computed(() => {
|
|
25
25
|
if (minDate === void 0) return new Date(1970, 0, 1);
|
|
26
|
-
if (type === "epoch" && typeof minDate === "number") return new Date(minDate * MILLISECONDS);
|
|
26
|
+
if (type === "epoch" && typeof minDate === "number") return /* @__PURE__ */ new Date(minDate * MILLISECONDS);
|
|
27
27
|
return new Date(minDate);
|
|
28
28
|
});
|
|
29
29
|
const maxAllowedDate = computed(() => {
|
|
30
30
|
if (maxDate === void 0) return;
|
|
31
31
|
if (maxDate === "now") return get$1(now).toDate();
|
|
32
|
-
if (type === "epoch" && typeof maxDate === "number") return new Date(maxDate * MILLISECONDS);
|
|
32
|
+
if (type === "epoch" && typeof maxDate === "number") return /* @__PURE__ */ new Date(maxDate * MILLISECONDS);
|
|
33
33
|
return new Date(maxDate);
|
|
34
34
|
});
|
|
35
35
|
const segmentData = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-date-time-selection.js","names":[],"sources":["../../../src/components/date-time-picker/use-date-time-selection.ts"],"sourcesContent":["import type { ComputedRef, Ref, WritableComputedRef } from 'vue';\nimport type { SegmentData } from '@/components/date-time-picker/types';\nimport type { TimeAccuracy } from '@/consts/time-accuracy';\nimport dayjs, { type Dayjs } from 'dayjs';\nimport { guessTimezone, includeMilliseconds, includeSeconds } from '@/components/date-time-picker/utils';\nimport { useRuiI8n } from '@/composables/use-rui-i18n';\nimport { RUI_I18N_KEYS } from '@/i18n/keys';\nimport '@/components/date-time-picker/dayjs-setup';\n\ntype DateTimeModelType = 'date' | 'epoch-ms' | 'epoch';\n\ntype ModelValueType<T extends DateTimeModelType> =\n T extends 'date' ? Date | undefined :\n T extends 'epoch-ms' ? number | undefined :\n T extends 'epoch' ? number | undefined :\n Date | number | undefined;\n\ninterface DateTimeSelectionOptions<T extends DateTimeModelType> {\n modelValue: Ref<ModelValueType<T>>;\n type: T;\n accuracy: TimeAccuracy;\n minDate: Date | number | undefined;\n maxDate: Date | number | 'now' | undefined;\n allowEmpty: boolean;\n}\n\ninterface DateTimeSelectionReturn {\n selectedYear: Ref<number | undefined>;\n selectedMonth: Ref<number | undefined>;\n selectedDay: Ref<number | undefined>;\n selectedHour: Ref<number | undefined>;\n selectedMinute: Ref<number | undefined>;\n selectedSecond: Ref<number | undefined>;\n selectedMillisecond: Ref<number | undefined>;\n selectedTimezone: Ref<string | undefined>;\n selectedDate: WritableComputedRef<Date | undefined>;\n selectedTime: WritableComputedRef<Date | undefined>;\n valueSet: ComputedRef<boolean>;\n internalErrorMessages: Ref<string[]>;\n now: Ref<Dayjs>;\n segmentData: SegmentData;\n minAllowedDate: ComputedRef<Date>;\n maxAllowedDate: ComputedRef<Date | undefined>;\n getDateTime: () => Dayjs;\n setNow: () => void;\n clear: () => void;\n isDateValid: (date: Dayjs) => boolean;\n}\n\nconst MILLISECONDS = 1000;\n\nexport function useDateTimeSelection<T extends DateTimeModelType>(\n options: DateTimeSelectionOptions<T>,\n): DateTimeSelectionReturn {\n const {\n accuracy,\n allowEmpty,\n maxDate,\n minDate,\n modelValue,\n type,\n } = options;\n\n const { t } = useRuiI8n();\n\n const selectedYear = ref<number | undefined>();\n const selectedMonth = ref<number | undefined>();\n const selectedDay = ref<number | undefined>();\n\n const selectedHour = ref<number | undefined>();\n const selectedMinute = ref<number | undefined>();\n const selectedSecond = ref<number | undefined>();\n const selectedMillisecond = ref<number | undefined>();\n const selectedTimezone = ref<string | undefined>(guessTimezone());\n\n const internalErrorMessages = ref<string[]>([]);\n const now = ref<Dayjs>(dayjs.tz(undefined, guessTimezone()));\n\n const minAllowedDate = computed<Date>(() => {\n if (minDate === undefined) {\n return new Date(1970, 0, 1);\n }\n\n if (type === 'epoch' && typeof minDate === 'number') {\n return new Date(minDate * MILLISECONDS);\n }\n\n return new Date(minDate);\n });\n\n const maxAllowedDate = computed<Date | undefined>(() => {\n if (maxDate === undefined) {\n return undefined;\n }\n if (maxDate === 'now') {\n return get(now).toDate();\n }\n if (type === 'epoch' && typeof maxDate === 'number') {\n return new Date(maxDate * MILLISECONDS);\n }\n return new Date(maxDate);\n });\n\n const segmentData: SegmentData = {\n DD: selectedDay,\n HH: selectedHour,\n MM: selectedMonth,\n SSS: selectedMillisecond,\n YYYY: selectedYear,\n mm: selectedMinute,\n ss: selectedSecond,\n };\n\n const selectedDate = computed<Date | undefined>({\n get() {\n if (!(isDefined(selectedYear) && isDefined(selectedMonth) && isDefined(selectedDay))) {\n return undefined;\n }\n const date = new Date();\n date.setFullYear(get(selectedYear));\n // Set day to 1 first to prevent month overflow when today's day > days in target month\n // e.g., if today is Dec 30 and we set month to Feb, day 30 would overflow to March\n date.setDate(1);\n date.setMonth(get(selectedMonth) - 1);\n date.setDate(get(selectedDay));\n return date;\n },\n set(value?: Date) {\n set(selectedYear, value?.getFullYear());\n set(selectedMonth, value ? value.getMonth() + 1 : undefined);\n set(selectedDay, value?.getDate());\n },\n });\n\n const selectedTime = computed<Date | undefined>({\n get() {\n if (!(isDefined(selectedHour) && isDefined(selectedMinute))) {\n return undefined;\n }\n const date = new Date();\n date.setHours(\n get(selectedHour),\n get(selectedMinute),\n get(selectedSecond) ?? 0,\n get(selectedMillisecond) ?? 0,\n );\n return date;\n },\n set(value?: Date) {\n set(selectedHour, value?.getHours());\n set(selectedMinute, value?.getMinutes());\n set(selectedSecond, value?.getSeconds());\n set(selectedMillisecond, value?.getMilliseconds());\n },\n });\n\n const valueSet = computed<boolean>(() => isDefined(selectedDate) && isDefined(selectedTime));\n\n function getDateTime(): Dayjs {\n let dateTime = dayjs();\n\n if (isDefined(selectedYear)) {\n dateTime = dateTime.year(get(selectedYear));\n }\n\n if (isDefined(selectedMonth)) {\n dateTime = dateTime.month(get(selectedMonth) - 1);\n }\n\n if (isDefined(selectedDay)) {\n const daysInMonth = dateTime.daysInMonth();\n const day = Math.min(get(selectedDay), daysInMonth);\n dateTime = dateTime.date(day);\n }\n\n if (isDefined(selectedHour)) {\n dateTime = dateTime.hour(get(selectedHour));\n }\n\n if (isDefined(selectedMinute)) {\n dateTime = dateTime.minute(get(selectedMinute));\n }\n\n if (isDefined(selectedSecond)) {\n dateTime = dateTime.second(get(selectedSecond));\n }\n\n if (isDefined(selectedMillisecond)) {\n dateTime = dateTime.millisecond(get(selectedMillisecond));\n }\n\n return dateTime;\n }\n\n function isDateValid(date: Dayjs): boolean {\n const min = get(minAllowedDate);\n const max = get(maxAllowedDate);\n\n set(internalErrorMessages, []);\n\n if (min && date.isBefore(min)) {\n const errorMessage = t(RUI_I18N_KEYS.dateTimePicker.dateBeforeMin, {\n date: min.toLocaleDateString(),\n }, `Date cannot be before ${min.toLocaleDateString()}`);\n set(internalErrorMessages, [...get(internalErrorMessages), errorMessage]);\n return false;\n }\n\n if (max && date.isAfter(max)) {\n const nowError = t(RUI_I18N_KEYS.dateTimePicker.dateInFuture, 'The selected date cannot be in the future');\n const maxError = t(RUI_I18N_KEYS.dateTimePicker.dateAfterMax, { date: max.toLocaleDateString() }, `Date cannot be after ${max.toLocaleDateString()}`);\n const errorMessage = maxDate === 'now' ? nowError : maxError;\n set(internalErrorMessages, [...get(internalErrorMessages), errorMessage]);\n return false;\n }\n\n return true;\n }\n\n function emitUpdate(updatedModel: Dayjs): void {\n const typeMap = {\n 'date': () => updatedModel.toDate(),\n 'epoch': () => updatedModel.valueOf() / MILLISECONDS,\n 'epoch-ms': () => updatedModel.valueOf(),\n } as const;\n\n set(modelValue, typeMap[type]() as ModelValueType<T>);\n }\n\n function updateModelValue(): void {\n if (!isDefined(selectedDate) || !isDefined(selectedTime)) {\n return;\n }\n\n if (!(isDefined(selectedDate) && isDefined(selectedTime))) {\n set(modelValue, undefined as ModelValueType<T>);\n }\n else {\n const date = get(selectedDate);\n const time = get(selectedTime);\n\n const updatedModel = dayjs.tz(isDefined(modelValue) ? get(modelValue) : undefined, get(selectedTimezone))\n .year(date.getFullYear())\n .month(date.getMonth())\n .date(date.getDate())\n .hour(time.getHours())\n .minute(time.getMinutes())\n .second(includeSeconds(accuracy) ? time.getSeconds() : 0)\n .millisecond(includeMilliseconds(accuracy) ? time.getMilliseconds() : 0);\n\n if (!isDateValid(updatedModel)) {\n return;\n }\n\n emitUpdate(updatedModel);\n }\n }\n\n function clear(): void {\n set(internalErrorMessages, []);\n set(selectedYear, undefined);\n set(selectedMonth, undefined);\n set(selectedDay, undefined);\n set(selectedHour, undefined);\n set(selectedMinute, undefined);\n set(selectedSecond, undefined);\n set(selectedMillisecond, undefined);\n set(modelValue, undefined as ModelValueType<T>);\n }\n\n function setNow(): void {\n set(internalErrorMessages, []);\n\n const date = dayjs();\n set(now, date);\n set(selectedYear, date.year());\n set(selectedMonth, date.month() + 1);\n set(selectedDay, date.date());\n set(selectedHour, date.hour());\n set(selectedMinute, date.minute());\n set(selectedSecond, includeSeconds(accuracy) ? date.second() : 0);\n set(selectedMillisecond, includeMilliseconds(accuracy) ? date.millisecond() : 0);\n\n nextTick(() => {\n updateModelValue();\n });\n }\n\n function updateSegments(date: Dayjs): void {\n const year = date.year();\n const month = date.month() + 1;\n const day = date.date();\n const hour = date.hour();\n const minute = date.minute();\n const second = includeSeconds(accuracy) ? date.second() : undefined;\n const millisecond = includeMilliseconds(accuracy) ? date.millisecond() : undefined;\n\n if (get(selectedYear) !== year)\n set(selectedYear, year);\n if (get(selectedMonth) !== month)\n set(selectedMonth, month);\n if (get(selectedDay) !== day)\n set(selectedDay, day);\n if (get(selectedHour) !== hour)\n set(selectedHour, hour);\n if (get(selectedMinute) !== minute)\n set(selectedMinute, minute);\n if (get(selectedSecond) !== second)\n set(selectedSecond, second);\n if (get(selectedMillisecond) !== millisecond)\n set(selectedMillisecond, millisecond);\n }\n\n const { ignoreUpdates } = watchIgnorable([selectedDate, selectedTime], ([newSelectedDate, newSelectedTime], [prevSelectedDate, prevSelectedTime]) => {\n const currentTimezone = get(selectedTimezone);\n const newDate = dayjs.tz(newSelectedDate, currentTimezone);\n const oldDate = dayjs.tz(prevSelectedDate, currentTimezone);\n const newTime = dayjs.tz(newSelectedTime, currentTimezone);\n const oldTime = dayjs.tz(prevSelectedTime, currentTimezone);\n\n if (newDate.isSame(oldDate) && newTime.isSame(oldTime)) {\n return;\n }\n\n set(now, dayjs());\n updateModelValue();\n });\n\n function updateInternalModel(value: ModelValueType<T>): void {\n ignoreUpdates(() => {\n const updatedValue = type === 'epoch' && typeof value === 'number'\n ? value * MILLISECONDS\n : value;\n const date = dayjs.tz(updatedValue, get(selectedTimezone));\n isDateValid(date);\n updateSegments(date);\n });\n }\n\n watch(selectedTimezone, (newTimezone: string | undefined) => {\n if (newTimezone && isDefined(selectedDate) && isDefined(selectedTime)) {\n set(now, dayjs());\n updateModelValue();\n }\n });\n\n watch(modelValue, (value) => {\n set(now, dayjs());\n if (value === undefined) {\n clear();\n }\n else {\n updateInternalModel(value);\n }\n });\n\n onMounted(() => {\n if (isDefined(modelValue)) {\n updateInternalModel(get(modelValue));\n }\n else if (!allowEmpty) {\n setNow();\n }\n });\n\n return {\n clear,\n getDateTime,\n internalErrorMessages,\n isDateValid,\n maxAllowedDate,\n minAllowedDate,\n now,\n segmentData,\n selectedDate,\n selectedDay,\n selectedHour,\n selectedMillisecond,\n selectedMinute,\n selectedMonth,\n selectedSecond,\n selectedTime,\n selectedTimezone,\n selectedYear,\n setNow,\n valueSet,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-date-time-selection.js","names":[],"sources":["../../../src/components/date-time-picker/use-date-time-selection.ts"],"sourcesContent":["import type { ComputedRef, Ref, WritableComputedRef } from 'vue';\nimport type { SegmentData } from '@/components/date-time-picker/types';\nimport type { TimeAccuracy } from '@/consts/time-accuracy';\nimport dayjs, { type Dayjs } from 'dayjs';\nimport { guessTimezone, includeMilliseconds, includeSeconds } from '@/components/date-time-picker/utils';\nimport { useRuiI8n } from '@/composables/use-rui-i18n';\nimport { RUI_I18N_KEYS } from '@/i18n/keys';\nimport '@/components/date-time-picker/dayjs-setup';\n\ntype DateTimeModelType = 'date' | 'epoch-ms' | 'epoch';\n\ntype ModelValueType<T extends DateTimeModelType> =\n T extends 'date' ? Date | undefined :\n T extends 'epoch-ms' ? number | undefined :\n T extends 'epoch' ? number | undefined :\n Date | number | undefined;\n\ninterface DateTimeSelectionOptions<T extends DateTimeModelType> {\n modelValue: Ref<ModelValueType<T>>;\n type: T;\n accuracy: TimeAccuracy;\n minDate: Date | number | undefined;\n maxDate: Date | number | 'now' | undefined;\n allowEmpty: boolean;\n}\n\ninterface DateTimeSelectionReturn {\n selectedYear: Ref<number | undefined>;\n selectedMonth: Ref<number | undefined>;\n selectedDay: Ref<number | undefined>;\n selectedHour: Ref<number | undefined>;\n selectedMinute: Ref<number | undefined>;\n selectedSecond: Ref<number | undefined>;\n selectedMillisecond: Ref<number | undefined>;\n selectedTimezone: Ref<string | undefined>;\n selectedDate: WritableComputedRef<Date | undefined>;\n selectedTime: WritableComputedRef<Date | undefined>;\n valueSet: ComputedRef<boolean>;\n internalErrorMessages: Ref<string[]>;\n now: Ref<Dayjs>;\n segmentData: SegmentData;\n minAllowedDate: ComputedRef<Date>;\n maxAllowedDate: ComputedRef<Date | undefined>;\n getDateTime: () => Dayjs;\n setNow: () => void;\n clear: () => void;\n isDateValid: (date: Dayjs) => boolean;\n}\n\nconst MILLISECONDS = 1000;\n\nexport function useDateTimeSelection<T extends DateTimeModelType>(\n options: DateTimeSelectionOptions<T>,\n): DateTimeSelectionReturn {\n const {\n accuracy,\n allowEmpty,\n maxDate,\n minDate,\n modelValue,\n type,\n } = options;\n\n const { t } = useRuiI8n();\n\n const selectedYear = ref<number | undefined>();\n const selectedMonth = ref<number | undefined>();\n const selectedDay = ref<number | undefined>();\n\n const selectedHour = ref<number | undefined>();\n const selectedMinute = ref<number | undefined>();\n const selectedSecond = ref<number | undefined>();\n const selectedMillisecond = ref<number | undefined>();\n const selectedTimezone = ref<string | undefined>(guessTimezone());\n\n const internalErrorMessages = ref<string[]>([]);\n const now = ref<Dayjs>(dayjs.tz(undefined, guessTimezone()));\n\n const minAllowedDate = computed<Date>(() => {\n if (minDate === undefined) {\n return new Date(1970, 0, 1);\n }\n\n if (type === 'epoch' && typeof minDate === 'number') {\n return new Date(minDate * MILLISECONDS);\n }\n\n return new Date(minDate);\n });\n\n const maxAllowedDate = computed<Date | undefined>(() => {\n if (maxDate === undefined) {\n return undefined;\n }\n if (maxDate === 'now') {\n return get(now).toDate();\n }\n if (type === 'epoch' && typeof maxDate === 'number') {\n return new Date(maxDate * MILLISECONDS);\n }\n return new Date(maxDate);\n });\n\n const segmentData: SegmentData = {\n DD: selectedDay,\n HH: selectedHour,\n MM: selectedMonth,\n SSS: selectedMillisecond,\n YYYY: selectedYear,\n mm: selectedMinute,\n ss: selectedSecond,\n };\n\n const selectedDate = computed<Date | undefined>({\n get() {\n if (!(isDefined(selectedYear) && isDefined(selectedMonth) && isDefined(selectedDay))) {\n return undefined;\n }\n const date = new Date();\n date.setFullYear(get(selectedYear));\n // Set day to 1 first to prevent month overflow when today's day > days in target month\n // e.g., if today is Dec 30 and we set month to Feb, day 30 would overflow to March\n date.setDate(1);\n date.setMonth(get(selectedMonth) - 1);\n date.setDate(get(selectedDay));\n return date;\n },\n set(value?: Date) {\n set(selectedYear, value?.getFullYear());\n set(selectedMonth, value ? value.getMonth() + 1 : undefined);\n set(selectedDay, value?.getDate());\n },\n });\n\n const selectedTime = computed<Date | undefined>({\n get() {\n if (!(isDefined(selectedHour) && isDefined(selectedMinute))) {\n return undefined;\n }\n const date = new Date();\n date.setHours(\n get(selectedHour),\n get(selectedMinute),\n get(selectedSecond) ?? 0,\n get(selectedMillisecond) ?? 0,\n );\n return date;\n },\n set(value?: Date) {\n set(selectedHour, value?.getHours());\n set(selectedMinute, value?.getMinutes());\n set(selectedSecond, value?.getSeconds());\n set(selectedMillisecond, value?.getMilliseconds());\n },\n });\n\n const valueSet = computed<boolean>(() => isDefined(selectedDate) && isDefined(selectedTime));\n\n function getDateTime(): Dayjs {\n let dateTime = dayjs();\n\n if (isDefined(selectedYear)) {\n dateTime = dateTime.year(get(selectedYear));\n }\n\n if (isDefined(selectedMonth)) {\n dateTime = dateTime.month(get(selectedMonth) - 1);\n }\n\n if (isDefined(selectedDay)) {\n const daysInMonth = dateTime.daysInMonth();\n const day = Math.min(get(selectedDay), daysInMonth);\n dateTime = dateTime.date(day);\n }\n\n if (isDefined(selectedHour)) {\n dateTime = dateTime.hour(get(selectedHour));\n }\n\n if (isDefined(selectedMinute)) {\n dateTime = dateTime.minute(get(selectedMinute));\n }\n\n if (isDefined(selectedSecond)) {\n dateTime = dateTime.second(get(selectedSecond));\n }\n\n if (isDefined(selectedMillisecond)) {\n dateTime = dateTime.millisecond(get(selectedMillisecond));\n }\n\n return dateTime;\n }\n\n function isDateValid(date: Dayjs): boolean {\n const min = get(minAllowedDate);\n const max = get(maxAllowedDate);\n\n set(internalErrorMessages, []);\n\n if (min && date.isBefore(min)) {\n const errorMessage = t(RUI_I18N_KEYS.dateTimePicker.dateBeforeMin, {\n date: min.toLocaleDateString(),\n }, `Date cannot be before ${min.toLocaleDateString()}`);\n set(internalErrorMessages, [...get(internalErrorMessages), errorMessage]);\n return false;\n }\n\n if (max && date.isAfter(max)) {\n const nowError = t(RUI_I18N_KEYS.dateTimePicker.dateInFuture, 'The selected date cannot be in the future');\n const maxError = t(RUI_I18N_KEYS.dateTimePicker.dateAfterMax, { date: max.toLocaleDateString() }, `Date cannot be after ${max.toLocaleDateString()}`);\n const errorMessage = maxDate === 'now' ? nowError : maxError;\n set(internalErrorMessages, [...get(internalErrorMessages), errorMessage]);\n return false;\n }\n\n return true;\n }\n\n function emitUpdate(updatedModel: Dayjs): void {\n const typeMap = {\n 'date': () => updatedModel.toDate(),\n 'epoch': () => updatedModel.valueOf() / MILLISECONDS,\n 'epoch-ms': () => updatedModel.valueOf(),\n } as const;\n\n set(modelValue, typeMap[type]() as ModelValueType<T>);\n }\n\n function updateModelValue(): void {\n if (!isDefined(selectedDate) || !isDefined(selectedTime)) {\n return;\n }\n\n if (!(isDefined(selectedDate) && isDefined(selectedTime))) {\n set(modelValue, undefined as ModelValueType<T>);\n }\n else {\n const date = get(selectedDate);\n const time = get(selectedTime);\n\n const updatedModel = dayjs.tz(isDefined(modelValue) ? get(modelValue) : undefined, get(selectedTimezone))\n .year(date.getFullYear())\n .month(date.getMonth())\n .date(date.getDate())\n .hour(time.getHours())\n .minute(time.getMinutes())\n .second(includeSeconds(accuracy) ? time.getSeconds() : 0)\n .millisecond(includeMilliseconds(accuracy) ? time.getMilliseconds() : 0);\n\n if (!isDateValid(updatedModel)) {\n return;\n }\n\n emitUpdate(updatedModel);\n }\n }\n\n function clear(): void {\n set(internalErrorMessages, []);\n set(selectedYear, undefined);\n set(selectedMonth, undefined);\n set(selectedDay, undefined);\n set(selectedHour, undefined);\n set(selectedMinute, undefined);\n set(selectedSecond, undefined);\n set(selectedMillisecond, undefined);\n set(modelValue, undefined as ModelValueType<T>);\n }\n\n function setNow(): void {\n set(internalErrorMessages, []);\n\n const date = dayjs();\n set(now, date);\n set(selectedYear, date.year());\n set(selectedMonth, date.month() + 1);\n set(selectedDay, date.date());\n set(selectedHour, date.hour());\n set(selectedMinute, date.minute());\n set(selectedSecond, includeSeconds(accuracy) ? date.second() : 0);\n set(selectedMillisecond, includeMilliseconds(accuracy) ? date.millisecond() : 0);\n\n nextTick(() => {\n updateModelValue();\n });\n }\n\n function updateSegments(date: Dayjs): void {\n const year = date.year();\n const month = date.month() + 1;\n const day = date.date();\n const hour = date.hour();\n const minute = date.minute();\n const second = includeSeconds(accuracy) ? date.second() : undefined;\n const millisecond = includeMilliseconds(accuracy) ? date.millisecond() : undefined;\n\n if (get(selectedYear) !== year)\n set(selectedYear, year);\n if (get(selectedMonth) !== month)\n set(selectedMonth, month);\n if (get(selectedDay) !== day)\n set(selectedDay, day);\n if (get(selectedHour) !== hour)\n set(selectedHour, hour);\n if (get(selectedMinute) !== minute)\n set(selectedMinute, minute);\n if (get(selectedSecond) !== second)\n set(selectedSecond, second);\n if (get(selectedMillisecond) !== millisecond)\n set(selectedMillisecond, millisecond);\n }\n\n const { ignoreUpdates } = watchIgnorable([selectedDate, selectedTime], ([newSelectedDate, newSelectedTime], [prevSelectedDate, prevSelectedTime]) => {\n const currentTimezone = get(selectedTimezone);\n const newDate = dayjs.tz(newSelectedDate, currentTimezone);\n const oldDate = dayjs.tz(prevSelectedDate, currentTimezone);\n const newTime = dayjs.tz(newSelectedTime, currentTimezone);\n const oldTime = dayjs.tz(prevSelectedTime, currentTimezone);\n\n if (newDate.isSame(oldDate) && newTime.isSame(oldTime)) {\n return;\n }\n\n set(now, dayjs());\n updateModelValue();\n });\n\n function updateInternalModel(value: ModelValueType<T>): void {\n ignoreUpdates(() => {\n const updatedValue = type === 'epoch' && typeof value === 'number'\n ? value * MILLISECONDS\n : value;\n const date = dayjs.tz(updatedValue, get(selectedTimezone));\n isDateValid(date);\n updateSegments(date);\n });\n }\n\n watch(selectedTimezone, (newTimezone: string | undefined) => {\n if (newTimezone && isDefined(selectedDate) && isDefined(selectedTime)) {\n set(now, dayjs());\n updateModelValue();\n }\n });\n\n watch(modelValue, (value) => {\n set(now, dayjs());\n if (value === undefined) {\n clear();\n }\n else {\n updateInternalModel(value);\n }\n });\n\n onMounted(() => {\n if (isDefined(modelValue)) {\n updateInternalModel(get(modelValue));\n }\n else if (!allowEmpty) {\n setNow();\n }\n });\n\n return {\n clear,\n getDateTime,\n internalErrorMessages,\n isDateValid,\n maxAllowedDate,\n minAllowedDate,\n now,\n segmentData,\n selectedDate,\n selectedDay,\n selectedHour,\n selectedMillisecond,\n selectedMinute,\n selectedMonth,\n selectedSecond,\n selectedTime,\n selectedTimezone,\n selectedYear,\n setNow,\n valueSet,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-input-handler.js","names":[],"sources":["../../../src/components/date-time-picker/use-input-handler.ts"],"sourcesContent":["import type { Dayjs } from 'dayjs';\nimport type { Ref } from 'vue';\nimport type { DateTimeSegmentType, SegmentData } from '@/components/date-time-picker/types';\nimport type { TimeAccuracy } from '@/consts/time-accuracy';\nimport { includeMilliseconds, includeSeconds } from '@/components/date-time-picker/utils';\n\nexport function useInputHandler(data: SegmentData, currentValue: Ref<number | undefined>) {\n function setValue(segment: DateTimeSegmentType, value?: number) {\n if (get(data[segment]) !== value)\n set(data[segment], value);\n\n set(currentValue, value);\n }\n\n function onlySet(segment: DateTimeSegmentType, value?: number): void {\n if (get(data[segment]) === value)\n return;\n\n set(data[segment], value);\n }\n\n function update(date: Dayjs, accuracy: TimeAccuracy) {\n onlySet('YYYY', date.year());\n onlySet('MM', date.month() + 1);\n onlySet('DD', date.date());\n onlySet('HH', date.hour());\n onlySet('mm', date.minute());\n onlySet('ss', includeSeconds(accuracy) ? date.second() : undefined);\n onlySet('SSS', includeMilliseconds(accuracy) ? date.millisecond() : undefined);\n }\n\n function getCurrent(segment: DateTimeSegmentType): number | undefined {\n return get(data[segment]);\n }\n\n return { getCurrent, setValue, update };\n}\n"],"mappings":";;;AAMA,SAAgB,gBAAgB,MAAmB,cAAuC;CACxF,SAAS,SAAS,SAA8B,OAAgB;
|
|
1
|
+
{"version":3,"file":"use-input-handler.js","names":[],"sources":["../../../src/components/date-time-picker/use-input-handler.ts"],"sourcesContent":["import type { Dayjs } from 'dayjs';\nimport type { Ref } from 'vue';\nimport type { DateTimeSegmentType, SegmentData } from '@/components/date-time-picker/types';\nimport type { TimeAccuracy } from '@/consts/time-accuracy';\nimport { includeMilliseconds, includeSeconds } from '@/components/date-time-picker/utils';\n\nexport function useInputHandler(data: SegmentData, currentValue: Ref<number | undefined>) {\n function setValue(segment: DateTimeSegmentType, value?: number) {\n if (get(data[segment]) !== value)\n set(data[segment], value);\n\n set(currentValue, value);\n }\n\n function onlySet(segment: DateTimeSegmentType, value?: number): void {\n if (get(data[segment]) === value)\n return;\n\n set(data[segment], value);\n }\n\n function update(date: Dayjs, accuracy: TimeAccuracy) {\n onlySet('YYYY', date.year());\n onlySet('MM', date.month() + 1);\n onlySet('DD', date.date());\n onlySet('HH', date.hour());\n onlySet('mm', date.minute());\n onlySet('ss', includeSeconds(accuracy) ? date.second() : undefined);\n onlySet('SSS', includeMilliseconds(accuracy) ? date.millisecond() : undefined);\n }\n\n function getCurrent(segment: DateTimeSegmentType): number | undefined {\n return get(data[segment]);\n }\n\n return { getCurrent, setValue, update };\n}\n"],"mappings":";;;AAMA,SAAgB,gBAAgB,MAAmB,cAAuC;CACxF,SAAS,SAAS,SAA8B,OAAgB;EAC9D,IAAI,IAAI,KAAK,QAAQ,MAAM,OACzB,IAAI,KAAK,UAAU,KAAK;EAE1B,IAAI,cAAc,KAAK;CACzB;CAEA,SAAS,QAAQ,SAA8B,OAAsB;EACnE,IAAI,IAAI,KAAK,QAAQ,MAAM,OACzB;EAEF,IAAI,KAAK,UAAU,KAAK;CAC1B;CAEA,SAAS,OAAO,MAAa,UAAwB;EACnD,QAAQ,QAAQ,KAAK,KAAK,CAAC;EAC3B,QAAQ,MAAM,KAAK,MAAM,IAAI,CAAC;EAC9B,QAAQ,MAAM,KAAK,KAAK,CAAC;EACzB,QAAQ,MAAM,KAAK,KAAK,CAAC;EACzB,QAAQ,MAAM,KAAK,OAAO,CAAC;EAC3B,QAAQ,MAAM,eAAe,QAAQ,IAAI,KAAK,OAAO,IAAI,KAAA,CAAS;EAClE,QAAQ,OAAO,oBAAoB,QAAQ,IAAI,KAAK,YAAY,IAAI,KAAA,CAAS;CAC/E;CAEA,SAAS,WAAW,SAAkD;EACpE,OAAO,IAAI,KAAK,QAAQ;CAC1B;CAEA,OAAO;EAAE;EAAY;EAAU;CAAO;AACxC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-keyboard-handler.js","names":[],"sources":["../../../src/components/date-time-picker/use-keyboard-handler.ts"],"sourcesContent":["import type { Dayjs } from 'dayjs';\nimport type { Ref, ShallowRef } from 'vue';\nimport type { TimeAccuracy } from '@/consts/time-accuracy';\nimport { type Segment, SEGMENT_CONFIG, SEGMENT_METHODS } from '@/components/date-time-picker/segment-config';\nimport { getClickPosition, parseAndSetDateValues } from '@/components/date-time-picker/segment-utils';\nimport {\n type DateTimeSegmentType,\n isDateTimeSegmentType,\n} from '@/components/date-time-picker/types';\nimport { assert } from '@/utils/assert';\n\ninterface KeyboardHandlerOptions {\n dateFormat: Ref<string>;\n cursorPosition: Ref<number>;\n currentValue: Ref<number | undefined>;\n textInput: Readonly<ShallowRef<HTMLInputElement | null>> | Ref<HTMLInputElement | undefined>;\n setValue: (segment: DateTimeSegmentType, value?: number) => void;\n getCurrent: (segment: DateTimeSegmentType) => number | undefined;\n getDateTime: () => Dayjs;\n disabled: boolean;\n readonly: boolean;\n accuracy: TimeAccuracy;\n}\n\nexport function useKeyboardHandler(options: KeyboardHandlerOptions) {\n const {\n accuracy,\n currentValue,\n cursorPosition,\n dateFormat,\n disabled,\n getCurrent,\n getDateTime,\n readonly,\n setValue,\n textInput,\n } = options;\n\n const formatSegments = computed<string[]>(() => {\n const format = get(dateFormat);\n return format.split(/([\\s./:])/g).filter(Boolean);\n });\n\n const segmentPositions = computed<Segment[]>(() => {\n const segments = get(formatSegments);\n const positions: Segment[] = [];\n let currentPosition = 0;\n\n segments.forEach((segment) => {\n if (!/[\\s./:]/.test(segment)) {\n assert(isDateTimeSegmentType(segment), `Invalid date format segment: ${segment}`);\n positions.push({\n end: currentPosition + segment.length,\n start: currentPosition,\n type: segment,\n });\n }\n currentPosition += segment.length;\n });\n\n return positions;\n });\n\n function getCurrentSegment(position: number = get(cursorPosition)) {\n const segments = get(segmentPositions);\n return segments.find(segment => position >= segment.start && position <= segment.end);\n }\n\n function setCursorPosition(segment: Segment): void {\n set(cursorPosition, segment.end);\n\n nextTick(() => {\n if (isDefined(textInput)) {\n const input = get(textInput);\n input.setSelectionRange(segment.start, segment.end);\n input.focus();\n }\n });\n }\n\n function setSegment(segmentType: DateTimeSegmentType): void {\n const segments = get(segmentPositions).find(segment => segment.type === segmentType);\n if (segments) {\n set(currentValue, undefined);\n setCursorPosition(segments);\n }\n }\n\n function clear(segmentType?: string): void {\n const currentSegment = getCurrentSegment();\n if (!segmentType && !currentSegment) {\n return;\n }\n\n const typeToUse = segmentType ?? currentSegment?.type;\n if (!typeToUse) {\n return;\n }\n\n setValue(typeToUse as DateTimeSegmentType, undefined);\n\n if (currentSegment) {\n setCursorPosition(currentSegment);\n }\n }\n\n function changeSegmentValue(increment: boolean): void {\n if (!isDefined(textInput))\n return;\n const currentSegment = getCurrentSegment();\n if (!currentSegment)\n return;\n const segmentType = currentSegment.type;\n const method = SEGMENT_METHODS[segmentType];\n const selectedDate = getDateTime();\n const updatedDate = selectedDate.set(method, selectedDate.get(method) + (increment ? 1 : -1));\n if (updatedDate.year() >= 1970) {\n setValue(\n segmentType,\n segmentType === 'MM' ? updatedDate.get(method) + 1 : updatedDate.get(method),\n );\n setCursorPosition(currentSegment);\n }\n }\n\n function navigateSegments(key: string) {\n const position = get(cursorPosition);\n const positions = get(segmentPositions);\n const currentSegmentIndex = positions.findIndex(\n segment => position >= segment.start && position <= segment.end,\n );\n\n if (currentSegmentIndex === -1) {\n return;\n }\n\n set(currentValue, undefined);\n\n let nextSegmentIndex: number;\n if (key === 'ArrowRight') {\n nextSegmentIndex = currentSegmentIndex + 1;\n if (nextSegmentIndex < positions.length) {\n const nextSegment = positions[nextSegmentIndex];\n assert(nextSegment);\n setCursorPosition(nextSegment);\n }\n }\n else {\n nextSegmentIndex = currentSegmentIndex - 1;\n if (nextSegmentIndex >= 0) {\n const nextSegment = positions[nextSegmentIndex];\n assert(nextSegment);\n setCursorPosition(nextSegment);\n }\n }\n }\n\n function handleDigitPressed(event: KeyboardEvent, digit: string): void {\n if (!(event.target instanceof HTMLInputElement))\n return;\n const position = event.target.selectionStart ?? 0;\n const currentSegment = getCurrentSegment(position);\n if (!currentSegment || isNaN(parseInt(digit)))\n return;\n const segmentType = currentSegment.type;\n if (!isDateTimeSegmentType(segmentType))\n return;\n\n const config = SEGMENT_CONFIG[segmentType];\n const value = get(currentValue) ?? '';\n const combinedStr = `${value}${digit}`;\n const combinedValue = parseInt(combinedStr);\n const maxLength = segmentType.length;\n const minValue = config.minValue ?? 0;\n\n if (combinedValue >= minValue && combinedValue <= config.maxValue) {\n setValue(segmentType, combinedValue);\n setCursorPosition(currentSegment);\n }\n else if (combinedValue < minValue && combinedStr.length < maxLength) {\n // Track digit even if below minValue, so next digit can combine (e.g., \"0\" allows \"01\")\n set(currentValue, combinedValue);\n }\n\n const willExceedMax = parseInt(`${combinedStr}0`) > config.maxValue;\n // Use string length of typed digits, not parsed number length (e.g., \"01\" has length 2)\n if (willExceedMax || combinedStr.length >= maxLength)\n navigateSegments('ArrowRight');\n }\n\n function handleKeyboardNavigation(event: KeyboardEvent): void {\n if (event.key === 'ArrowUp')\n changeSegmentValue(true);\n else if (event.key === 'ArrowDown')\n changeSegmentValue(false);\n }\n\n function handleBackspace(event: KeyboardEvent): void {\n if (!(event.target instanceof HTMLInputElement))\n return;\n const currentSegment = getCurrentSegment(event.target.selectionStart ?? 0);\n if (!currentSegment)\n return;\n const value = get(currentValue) ?? getCurrent(currentSegment.type) ?? '';\n const updatedValue = value.toString().slice(0, -1);\n setValue(currentSegment.type, updatedValue.length === 0 ? undefined : parseInt(updatedValue));\n setCursorPosition(currentSegment);\n }\n\n function onInputDeletePressed(event: KeyboardEvent): void {\n if (!(event.target instanceof HTMLInputElement))\n return;\n const segment = getCurrentSegment(event.target.selectionStart ?? 0);\n if (segment) {\n clear(segment.type);\n setCursorPosition(segment);\n }\n }\n\n function handleKeyDown(event: KeyboardEvent): void {\n if (disabled || readonly)\n return;\n const { key } = event;\n if (key === 'Tab')\n return;\n event.preventDefault();\n if (key === 'ArrowRight' || key === 'ArrowLeft')\n navigateSegments(key);\n else if (key === 'ArrowUp' || key === 'ArrowDown')\n handleKeyboardNavigation(event);\n else if (key === 'Backspace')\n handleBackspace(event);\n else if (key === 'Delete')\n onInputDeletePressed(event);\n else if (/^\\d$/.test(key))\n handleDigitPressed(event, key);\n }\n\n // Track the segment that was clicked, so handleFocus can restore it after DOM updates\n let clickedSegment: Segment | undefined;\n\n // Capture clicked segment on mousedown (fires before focus event)\n function handleMouseDown(event: MouseEvent): void {\n if (disabled || readonly || !(event.target instanceof HTMLInputElement))\n return;\n const currentSegment = getCurrentSegment(getClickPosition(event, event.target, true));\n if (currentSegment) {\n // Reset in-progress digit buffer: switching segments must not carry typed digits over,\n // otherwise a leftover digit from another segment combines with the next keystroke\n // (e.g. type \"1\" in HH, click mm, type \"3\" → mm becomes 13 instead of 3).\n set(currentValue, undefined);\n clickedSegment = currentSegment;\n }\n }\n\n function handleClick(event: MouseEvent): void {\n if (disabled || readonly || !(event.target instanceof HTMLInputElement))\n return;\n const currentSegment = getCurrentSegment(getClickPosition(event, event.target, true));\n if (currentSegment) {\n set(currentValue, undefined);\n clickedSegment = currentSegment;\n set(cursorPosition, currentSegment.end);\n event.target.setSelectionRange(currentSegment.start, currentSegment.end);\n }\n }\n\n function handleInputSelection(event: Event): void {\n const target = event.target as HTMLInputElement;\n set(cursorPosition, target.selectionStart ?? 0);\n }\n\n function handleFocus(): void {\n // If we just clicked on a segment, restore that selection\n // (the selection may have been lost due to menu opening/DOM updates)\n if (clickedSegment) {\n setCursorPosition(clickedSegment);\n clickedSegment = undefined;\n return;\n }\n\n // Only select first segment if no text is currently selected in the input\n const input = get(textInput);\n if (input && input.selectionStart !== input.selectionEnd)\n return;\n const firstSegment = get(segmentPositions)[0];\n if (firstSegment)\n setCursorPosition(firstSegment);\n }\n\n function handleBlur(): void {\n // Reset cursor position and clicked segment when input loses focus\n // This prevents \"blinking\" when re-focusing on a different segment\n set(cursorPosition, 0);\n set(currentValue, undefined);\n clickedSegment = undefined;\n }\n\n function handlePaste(event: ClipboardEvent): void {\n if (disabled || readonly)\n return;\n\n if (!(event.target instanceof HTMLInputElement)) {\n return;\n }\n\n event.preventDefault();\n\n const pastedText = event.clipboardData?.getData('text');\n if (!pastedText) {\n return;\n }\n parseAndSetDateValues(pastedText, get(dateFormat), accuracy, setValue);\n }\n\n function handleInput(event: Event): void {\n if (disabled || readonly)\n return;\n\n if (!(event.target instanceof HTMLInputElement)) {\n return;\n }\n\n const inputText = event.target.value;\n if (!inputText) {\n return;\n }\n\n parseAndSetDateValues(inputText, get(dateFormat), accuracy, setValue);\n }\n\n return {\n clear,\n getCurrentSegment,\n handleBlur,\n handleClick,\n handleFocus,\n handleInput,\n handleInputSelection,\n handleKeyDown,\n handleMouseDown,\n handlePaste,\n setSegment,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-keyboard-handler.js","names":[],"sources":["../../../src/components/date-time-picker/use-keyboard-handler.ts"],"sourcesContent":["import type { Dayjs } from 'dayjs';\nimport type { Ref, ShallowRef } from 'vue';\nimport type { TimeAccuracy } from '@/consts/time-accuracy';\nimport { type Segment, SEGMENT_CONFIG, SEGMENT_METHODS } from '@/components/date-time-picker/segment-config';\nimport { getClickPosition, parseAndSetDateValues } from '@/components/date-time-picker/segment-utils';\nimport {\n type DateTimeSegmentType,\n isDateTimeSegmentType,\n} from '@/components/date-time-picker/types';\nimport { assert } from '@/utils/assert';\n\ninterface KeyboardHandlerOptions {\n dateFormat: Ref<string>;\n cursorPosition: Ref<number>;\n currentValue: Ref<number | undefined>;\n textInput: Readonly<ShallowRef<HTMLInputElement | null>> | Ref<HTMLInputElement | undefined>;\n setValue: (segment: DateTimeSegmentType, value?: number) => void;\n getCurrent: (segment: DateTimeSegmentType) => number | undefined;\n getDateTime: () => Dayjs;\n disabled: boolean;\n readonly: boolean;\n accuracy: TimeAccuracy;\n}\n\nexport function useKeyboardHandler(options: KeyboardHandlerOptions) {\n const {\n accuracy,\n currentValue,\n cursorPosition,\n dateFormat,\n disabled,\n getCurrent,\n getDateTime,\n readonly,\n setValue,\n textInput,\n } = options;\n\n const formatSegments = computed<string[]>(() => {\n const format = get(dateFormat);\n return format.split(/([\\s./:])/g).filter(Boolean);\n });\n\n const segmentPositions = computed<Segment[]>(() => {\n const segments = get(formatSegments);\n const positions: Segment[] = [];\n let currentPosition = 0;\n\n segments.forEach((segment) => {\n if (!/[\\s./:]/.test(segment)) {\n assert(isDateTimeSegmentType(segment), `Invalid date format segment: ${segment}`);\n positions.push({\n end: currentPosition + segment.length,\n start: currentPosition,\n type: segment,\n });\n }\n currentPosition += segment.length;\n });\n\n return positions;\n });\n\n function getCurrentSegment(position: number = get(cursorPosition)) {\n const segments = get(segmentPositions);\n return segments.find(segment => position >= segment.start && position <= segment.end);\n }\n\n function setCursorPosition(segment: Segment): void {\n set(cursorPosition, segment.end);\n\n nextTick(() => {\n if (isDefined(textInput)) {\n const input = get(textInput);\n input.setSelectionRange(segment.start, segment.end);\n input.focus();\n }\n });\n }\n\n function setSegment(segmentType: DateTimeSegmentType): void {\n const segments = get(segmentPositions).find(segment => segment.type === segmentType);\n if (segments) {\n set(currentValue, undefined);\n setCursorPosition(segments);\n }\n }\n\n function clear(segmentType?: string): void {\n const currentSegment = getCurrentSegment();\n if (!segmentType && !currentSegment) {\n return;\n }\n\n const typeToUse = segmentType ?? currentSegment?.type;\n if (!typeToUse) {\n return;\n }\n\n setValue(typeToUse as DateTimeSegmentType, undefined);\n\n if (currentSegment) {\n setCursorPosition(currentSegment);\n }\n }\n\n function changeSegmentValue(increment: boolean): void {\n if (!isDefined(textInput))\n return;\n const currentSegment = getCurrentSegment();\n if (!currentSegment)\n return;\n const segmentType = currentSegment.type;\n const method = SEGMENT_METHODS[segmentType];\n const selectedDate = getDateTime();\n const updatedDate = selectedDate.set(method, selectedDate.get(method) + (increment ? 1 : -1));\n if (updatedDate.year() >= 1970) {\n setValue(\n segmentType,\n segmentType === 'MM' ? updatedDate.get(method) + 1 : updatedDate.get(method),\n );\n setCursorPosition(currentSegment);\n }\n }\n\n function navigateSegments(key: string) {\n const position = get(cursorPosition);\n const positions = get(segmentPositions);\n const currentSegmentIndex = positions.findIndex(\n segment => position >= segment.start && position <= segment.end,\n );\n\n if (currentSegmentIndex === -1) {\n return;\n }\n\n set(currentValue, undefined);\n\n let nextSegmentIndex: number;\n if (key === 'ArrowRight') {\n nextSegmentIndex = currentSegmentIndex + 1;\n if (nextSegmentIndex < positions.length) {\n const nextSegment = positions[nextSegmentIndex];\n assert(nextSegment);\n setCursorPosition(nextSegment);\n }\n }\n else {\n nextSegmentIndex = currentSegmentIndex - 1;\n if (nextSegmentIndex >= 0) {\n const nextSegment = positions[nextSegmentIndex];\n assert(nextSegment);\n setCursorPosition(nextSegment);\n }\n }\n }\n\n function handleDigitPressed(event: KeyboardEvent, digit: string): void {\n if (!(event.target instanceof HTMLInputElement))\n return;\n const position = event.target.selectionStart ?? 0;\n const currentSegment = getCurrentSegment(position);\n if (!currentSegment || isNaN(parseInt(digit)))\n return;\n const segmentType = currentSegment.type;\n if (!isDateTimeSegmentType(segmentType))\n return;\n\n const config = SEGMENT_CONFIG[segmentType];\n const value = get(currentValue) ?? '';\n const combinedStr = `${value}${digit}`;\n const combinedValue = parseInt(combinedStr);\n const maxLength = segmentType.length;\n const minValue = config.minValue ?? 0;\n\n if (combinedValue >= minValue && combinedValue <= config.maxValue) {\n setValue(segmentType, combinedValue);\n setCursorPosition(currentSegment);\n }\n else if (combinedValue < minValue && combinedStr.length < maxLength) {\n // Track digit even if below minValue, so next digit can combine (e.g., \"0\" allows \"01\")\n set(currentValue, combinedValue);\n }\n\n const willExceedMax = parseInt(`${combinedStr}0`) > config.maxValue;\n // Use string length of typed digits, not parsed number length (e.g., \"01\" has length 2)\n if (willExceedMax || combinedStr.length >= maxLength)\n navigateSegments('ArrowRight');\n }\n\n function handleKeyboardNavigation(event: KeyboardEvent): void {\n if (event.key === 'ArrowUp')\n changeSegmentValue(true);\n else if (event.key === 'ArrowDown')\n changeSegmentValue(false);\n }\n\n function handleBackspace(event: KeyboardEvent): void {\n if (!(event.target instanceof HTMLInputElement))\n return;\n const currentSegment = getCurrentSegment(event.target.selectionStart ?? 0);\n if (!currentSegment)\n return;\n const value = get(currentValue) ?? getCurrent(currentSegment.type) ?? '';\n const updatedValue = value.toString().slice(0, -1);\n setValue(currentSegment.type, updatedValue.length === 0 ? undefined : parseInt(updatedValue));\n setCursorPosition(currentSegment);\n }\n\n function onInputDeletePressed(event: KeyboardEvent): void {\n if (!(event.target instanceof HTMLInputElement))\n return;\n const segment = getCurrentSegment(event.target.selectionStart ?? 0);\n if (segment) {\n clear(segment.type);\n setCursorPosition(segment);\n }\n }\n\n function handleKeyDown(event: KeyboardEvent): void {\n if (disabled || readonly)\n return;\n const { key } = event;\n if (key === 'Tab')\n return;\n event.preventDefault();\n if (key === 'ArrowRight' || key === 'ArrowLeft')\n navigateSegments(key);\n else if (key === 'ArrowUp' || key === 'ArrowDown')\n handleKeyboardNavigation(event);\n else if (key === 'Backspace')\n handleBackspace(event);\n else if (key === 'Delete')\n onInputDeletePressed(event);\n else if (/^\\d$/.test(key))\n handleDigitPressed(event, key);\n }\n\n // Track the segment that was clicked, so handleFocus can restore it after DOM updates\n let clickedSegment: Segment | undefined;\n\n // Capture clicked segment on mousedown (fires before focus event)\n function handleMouseDown(event: MouseEvent): void {\n if (disabled || readonly || !(event.target instanceof HTMLInputElement))\n return;\n const currentSegment = getCurrentSegment(getClickPosition(event, event.target, true));\n if (currentSegment) {\n // Reset in-progress digit buffer: switching segments must not carry typed digits over,\n // otherwise a leftover digit from another segment combines with the next keystroke\n // (e.g. type \"1\" in HH, click mm, type \"3\" → mm becomes 13 instead of 3).\n set(currentValue, undefined);\n clickedSegment = currentSegment;\n }\n }\n\n function handleClick(event: MouseEvent): void {\n if (disabled || readonly || !(event.target instanceof HTMLInputElement))\n return;\n const currentSegment = getCurrentSegment(getClickPosition(event, event.target, true));\n if (currentSegment) {\n set(currentValue, undefined);\n clickedSegment = currentSegment;\n set(cursorPosition, currentSegment.end);\n event.target.setSelectionRange(currentSegment.start, currentSegment.end);\n }\n }\n\n function handleInputSelection(event: Event): void {\n const target = event.target as HTMLInputElement;\n set(cursorPosition, target.selectionStart ?? 0);\n }\n\n function handleFocus(): void {\n // If we just clicked on a segment, restore that selection\n // (the selection may have been lost due to menu opening/DOM updates)\n if (clickedSegment) {\n setCursorPosition(clickedSegment);\n clickedSegment = undefined;\n return;\n }\n\n // Only select first segment if no text is currently selected in the input\n const input = get(textInput);\n if (input && input.selectionStart !== input.selectionEnd)\n return;\n const firstSegment = get(segmentPositions)[0];\n if (firstSegment)\n setCursorPosition(firstSegment);\n }\n\n function handleBlur(): void {\n // Reset cursor position and clicked segment when input loses focus\n // This prevents \"blinking\" when re-focusing on a different segment\n set(cursorPosition, 0);\n set(currentValue, undefined);\n clickedSegment = undefined;\n }\n\n function handlePaste(event: ClipboardEvent): void {\n if (disabled || readonly)\n return;\n\n if (!(event.target instanceof HTMLInputElement)) {\n return;\n }\n\n event.preventDefault();\n\n const pastedText = event.clipboardData?.getData('text');\n if (!pastedText) {\n return;\n }\n parseAndSetDateValues(pastedText, get(dateFormat), accuracy, setValue);\n }\n\n function handleInput(event: Event): void {\n if (disabled || readonly)\n return;\n\n if (!(event.target instanceof HTMLInputElement)) {\n return;\n }\n\n const inputText = event.target.value;\n if (!inputText) {\n return;\n }\n\n parseAndSetDateValues(inputText, get(dateFormat), accuracy, setValue);\n }\n\n return {\n clear,\n getCurrentSegment,\n handleBlur,\n handleClick,\n handleFocus,\n handleInput,\n handleInputSelection,\n handleKeyDown,\n handleMouseDown,\n handlePaste,\n setSegment,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/components/date-time-picker/utils.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport { timezones } from '@/components/date-time-picker/timezones';\nimport { TimeAccuracy } from '@/consts/time-accuracy';\nimport '@/components/date-time-picker/dayjs-setup';\n\nexport function guessTimezone() {\n const timezone = dayjs.tz.guess();\n return timezones.find(tz => tz === timezone);\n}\n\nexport function includeSeconds(accuracy: TimeAccuracy): boolean {\n return accuracy === TimeAccuracy.SECOND || accuracy === TimeAccuracy.MILLISECOND;\n}\n\nexport function includeMilliseconds(accuracy: TimeAccuracy): boolean {\n return accuracy === TimeAccuracy.MILLISECOND;\n}\n"],"mappings":";;;;;AAKA,SAAgB,gBAAgB;CAC9B,MAAM,WAAW,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/components/date-time-picker/utils.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport { timezones } from '@/components/date-time-picker/timezones';\nimport { TimeAccuracy } from '@/consts/time-accuracy';\nimport '@/components/date-time-picker/dayjs-setup';\n\nexport function guessTimezone() {\n const timezone = dayjs.tz.guess();\n return timezones.find(tz => tz === timezone);\n}\n\nexport function includeSeconds(accuracy: TimeAccuracy): boolean {\n return accuracy === TimeAccuracy.SECOND || accuracy === TimeAccuracy.MILLISECOND;\n}\n\nexport function includeMilliseconds(accuracy: TimeAccuracy): boolean {\n return accuracy === TimeAccuracy.MILLISECOND;\n}\n"],"mappings":";;;;;AAKA,SAAgB,gBAAgB;CAC9B,MAAM,WAAW,MAAM,GAAG,MAAM;CAChC,OAAO,UAAU,MAAK,OAAM,OAAO,QAAQ;AAC7C;AAEA,SAAgB,eAAe,UAAiC;CAC9D,OAAO,aAAa,aAAa,UAAU,aAAa,aAAa;AACvE;AAEA,SAAgB,oBAAoB,UAAiC;CACnE,OAAO,aAAa,aAAa;AACnC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createElementBlock, defineComponent, mergeProps, openBlock } from "vue";
|
|
2
2
|
//#region src/components/divider/RuiDivider.vue?vue&type=script&setup=true&lang.ts
|
|
3
3
|
var _hoisted_1 = ["aria-orientation"];
|
|
4
|
-
var RuiDivider_vue_vue_type_script_setup_true_lang_default =
|
|
4
|
+
var RuiDivider_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
5
5
|
name: "RuiDivider",
|
|
6
6
|
inheritAttrs: false,
|
|
7
7
|
__name: "RuiDivider",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiDivider.vue_vue_type_script_setup_true_lang.js","names":["$attrs"],"sources":["../../../src/components/divider/RuiDivider.vue"],"sourcesContent":["<script setup lang=\"ts\">\nexport interface Props {\n vertical?: boolean;\n}\n\ndefineOptions({\n name: 'RuiDivider',\n inheritAttrs: false,\n});\n\nconst { vertical = false } = defineProps<Props>();\n</script>\n\n<template>\n <div\n :class=\"vertical ? 'border-l' : 'border-t'\"\n class=\"border-default\"\n role=\"separator\"\n :aria-orientation=\"vertical ? 'vertical' : 'horizontal'\"\n v-bind=\"$attrs\"\n />\n</template>\n"],"mappings":";;;;;;;;;;;;;uBAcE,mBAME,OANF,WAME;IALC,OAAK,CAAE,QAAA,WAAQ,aAAA,YACV,
|
|
1
|
+
{"version":3,"file":"RuiDivider.vue_vue_type_script_setup_true_lang.js","names":["$attrs"],"sources":["../../../src/components/divider/RuiDivider.vue"],"sourcesContent":["<script setup lang=\"ts\">\nexport interface Props {\n vertical?: boolean;\n}\n\ndefineOptions({\n name: 'RuiDivider',\n inheritAttrs: false,\n});\n\nconst { vertical = false } = defineProps<Props>();\n</script>\n\n<template>\n <div\n :class=\"vertical ? 'border-l' : 'border-t'\"\n class=\"border-default\"\n role=\"separator\"\n :aria-orientation=\"vertical ? 'vertical' : 'horizontal'\"\n v-bind=\"$attrs\"\n />\n</template>\n"],"mappings":";;;;;;;;;;;;;uBAcE,mBAME,OANF,WAME;IALC,OAAK,CAAE,QAAA,WAAQ,aAAA,YACV,gBAAgB;IACtB,MAAK;IACJ,oBAAkB,QAAA,WAAQ,aAAA;MACnBA,KAAAA,MAAM,GAAA,MAAA,IAAA,UAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiAutoComplete.js","names":[],"sources":["../../../../src/components/forms/auto-complete/RuiAutoComplete.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue, TItem\">\nimport type { VueClassValue } from '@/types/class-value';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiChip from '@/components/chips/RuiChip.vue';\nimport { autoCompleteStyles, type AutoCompleteVariant } from '@/components/forms/auto-complete/auto-complete-styles';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiMenu, { type MenuProps } from '@/components/overlays/menu/RuiMenu.vue';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport {\n type GroupBy,\n type ItemDisabled,\n type KeyOfType,\n useDropdownMenu,\n useDropdownOptionProperty,\n} from '@/composables/dropdown-menu';\nimport { type FloatingOptions, Placement } from '@/composables/floating';\nimport {\n useAutoCompleteFocus,\n useAutoCompleteKeyboardNavigation,\n useAutoCompleteSearch,\n useAutoCompleteValue,\n} from '@/composables/forms/auto-complete';\nimport { useFormTextDetail } from '@/utils/form-text-detail';\nimport { getNonRootAttrs, getRootAttrs, getTextToken } from '@/utils/helpers';\nimport { isEqual } from '@/utils/is-equal';\nimport { cn } from '@/utils/tv';\n\nexport type AutoCompleteModelValue<TValue> =\n TValue extends Array<infer U> ? U[] : TValue | undefined;\n\nexport interface RuiAutoCompleteClassNames {\n root?: VueClassValue;\n label?: VueClassValue;\n menu?: VueClassValue;\n}\n\nexport interface AutoCompleteProps<TValue, TItem> {\n options?: TItem[];\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem;\n disabled?: boolean;\n loading?: boolean;\n readOnly?: boolean;\n dense?: boolean;\n clearable?: boolean;\n label?: string;\n menuOptions?: MenuProps;\n classNames?: RuiAutoCompleteClassNames;\n /** @deprecated Use `classNames.label` instead */\n labelClass?: string;\n /** @deprecated Use `classNames.menu` instead */\n menuClass?: string;\n prependWidth?: number;\n appendWidth?: number;\n itemHeight?: number;\n variant?: AutoCompleteVariant;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n hideDetails?: boolean;\n autoSelectFirst?: boolean;\n chips?: boolean;\n noFilter?: boolean;\n hideNoData?: boolean;\n noDataText?: string;\n filter?: (item: TItem, queryText: string) => boolean;\n hideSelected?: boolean;\n placeholder?: string;\n returnObject?: boolean;\n customValue?: boolean;\n hideCustomValue?: boolean;\n required?: boolean;\n hideSearchInput?: boolean;\n hideSelectionWrapper?: boolean;\n groupBy?: GroupBy<TItem>;\n itemDisabled?: ItemDisabled<TItem>;\n}\n\ndefineOptions({\n name: 'RuiAutoComplete',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<AutoCompleteModelValue<TValue>>({ required: true });\n\nconst searchInputModel = defineModel<string>('searchInput', { default: '' });\n\nconst {\n options = [],\n disabled = false,\n loading = false,\n readOnly = false,\n dense = false,\n clearable = false,\n hideDetails = false,\n chips = false,\n label = 'Select',\n menuOptions,\n classNames,\n labelClass,\n menuClass,\n variant = 'default',\n hint,\n keyAttr,\n textAttr,\n itemHeight,\n errorMessages = [],\n successMessages = [],\n autoSelectFirst = false,\n noFilter = false,\n hideNoData = false,\n noDataText = 'No data available',\n filter,\n hideSelected = false,\n placeholder = '',\n returnObject = false,\n customValue = false,\n hideCustomValue = false,\n required = false,\n hideSearchInput = false,\n hideSelectionWrapper = false,\n groupBy,\n itemDisabled,\n} = defineProps<AutoCompleteProps<TValue, TItem>>();\n\nconst slots = defineSlots<{\n 'activator'?: (props: {\n disabled: boolean;\n value: TItem[];\n variant: string;\n readOnly: boolean;\n attrs: Record<string, unknown>;\n open: boolean;\n hasError: boolean;\n hasSuccess: boolean;\n }) => any;\n 'activator.label'?: (props: { value: TItem[] }) => any;\n 'selection.prepend'?: (props: { index: number; item: TItem }) => any;\n 'selection'?: (props: { index: number; item: TItem; chipAttrs: Record<string, unknown> }) => any;\n 'item.prepend'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'item'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'item.append'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'group-header'?: (props: { group: string; items: TItem[] }) => any;\n 'no-data'?: () => any;\n 'placeholder'?: (props: { disabled: boolean; readOnly: boolean }) => any;\n 'footer'?: () => any;\n}>();\n\nconst { getText, getIdentifier } = useDropdownOptionProperty<TValue, TItem>({\n keyAttr,\n textAttr,\n});\n\nconst textInput = useTemplateRef<HTMLInputElement>('textInput');\nconst activator = useTemplateRef<HTMLDivElement>('activator');\nconst menuRef = useTemplateRef<HTMLDivElement>('menuRef');\nconst menuWrapperRef = useTemplateRef<HTMLDivElement>('menuWrapperRef');\n\nconst { focused: activatorFocusedWithin } = useFocusWithin(activator);\nconst { focused: menuWrapperFocusedWithin } = useFocusWithin(menuWrapperRef);\nconst { focused: searchInputFocused } = useFocus(textInput);\nconst { focused: activatorFocused } = useFocus(activator);\n\nconst {\n internalSearch,\n filteredOptions,\n justOpened,\n updateInternalSearch,\n textValueToProperValue,\n} = useAutoCompleteSearch<TItem>(\n () => options,\n searchInputModel,\n {\n keyAttr: () => keyAttr,\n textAttr: () => textAttr,\n noFilter: () => noFilter,\n filter: () => filter,\n customValue: () => customValue,\n hideCustomValue: () => hideCustomValue,\n returnObject: () => returnObject,\n },\n);\n\nconst isOpen = ref<boolean>(false);\nconst isHovered = ref<boolean>(false);\n\n// Calculate multiple from modelValue directly to avoid circular dependency\nconst multiple = computed<boolean>(() => Array.isArray(get(modelValue)));\n\nconst shouldApplyValueAsSearch = computed<boolean>(\n () => !(slots.selection || get(multiple) || chips),\n);\n\nconst { value, setSelected } = useAutoCompleteValue<AutoCompleteModelValue<TValue>, TItem>(\n modelValue,\n () => options,\n {\n keyAttr: () => keyAttr,\n returnObject: () => returnObject,\n customValue: () => customValue,\n },\n {\n getIdentifier,\n getText,\n textValueToProperValue,\n shouldApplyValueAsSearch,\n isOpen,\n multiple,\n updateInternalSearch,\n },\n);\n\nconst resolvedItemHeight = itemHeight ?? (dense ? 30 : 48);\n\nconst {\n containerProps,\n wrapperProps,\n renderedData,\n menuWidth,\n isActiveItem,\n itemIndexInValue,\n highlightedIndex,\n moveHighlight,\n applyHighlighted,\n optionsWithSelectedHidden,\n userNavigated,\n groupedOptions,\n isGrouped,\n isItemDisabled,\n} = useDropdownMenu<TValue, TItem>({\n itemHeight: resolvedItemHeight,\n keyAttr,\n textAttr,\n options: filteredOptions,\n dense: () => dense,\n value,\n menuRef,\n setValue,\n autoSelectFirst,\n hideSelected,\n isOpen,\n getText,\n getIdentifier,\n groupBy: () => groupBy,\n itemDisabled: () => itemDisabled,\n});\n\nconst {\n focusedValueIndex,\n moveSelectedValueHighlight,\n onEnter,\n onInputDeletePressed,\n onTab,\n setValueFocus,\n} = useAutoCompleteKeyboardNavigation<TItem>(\n {\n chips: () => chips,\n customValue: () => customValue,\n multiple,\n },\n {\n activator,\n applyHighlighted,\n clear,\n filteredOptions,\n getText,\n highlightedIndex,\n internalSearch,\n isOpen,\n removeValue: (item: TItem): void => { setValue(item); },\n searchInputFocused,\n setSearchAsValue,\n userNavigated,\n value,\n },\n);\n\nconst {\n anyFocused: focusAnyFocused,\n inputClass: focusInputClass,\n onActivatorFocused: focusOnActivatorFocused,\n onInputFocused: focusOnInputFocused,\n setInputFocus: focusSetInputFocus,\n} = useAutoCompleteFocus(\n {\n customValue: () => customValue,\n disabled: () => disabled,\n shouldApplyValueAsSearch,\n },\n {\n activatorFocused,\n activatorFocusedWithin,\n focusedValueIndex,\n internalSearch,\n isOpen,\n justOpened,\n menuWrapperFocusedWithin,\n searchInputFocused,\n setSearchAsValue,\n textInput,\n updateInternalSearch,\n },\n);\n\nconst menuMinHeight = computed<number>(\n () => Math.min(5, get(optionsWithSelectedHidden).length) * resolvedItemHeight,\n);\n\nconst { hasError, hasSuccess } = useFormTextDetail(\n () => errorMessages,\n () => successMessages,\n);\n\nconst valueSet = computed<boolean>(() => get(value).length > 0);\n\n// True when the consumer's #placeholder slot is taking over the resting\n// content area, so the outlined/resting label must hide to avoid overlapping\n// the slot content.\nconst placeholderSlotActive = computed<boolean>(() => Boolean(slots.placeholder) && !get(valueSet) && !get(searchInputFocused));\n\nconst usedPlaceholder = computed<string>(() => {\n if (get(searchInputFocused))\n return placeholder;\n return '';\n});\n\nconst outlined = computed<boolean>(() => variant === 'outlined');\nconst float = computed<boolean>(() => (get(isOpen) || get(valueSet) || get(searchInputFocused)) && get(outlined));\n\nconst legendText = computed<string>(() => {\n if (!get(float) || !label)\n return '';\n return required ? `${label} ﹡` : label;\n});\n\nconst ui = computed<ReturnType<typeof autoCompleteStyles>>(() => autoCompleteStyles({\n filled: variant === 'filled',\n outlined: get(outlined),\n float: get(float),\n opened: get(isOpen),\n hovered: get(isHovered),\n dense,\n disabled,\n readonly: readOnly,\n hasError: get(hasError),\n hasSuccess: get(hasSuccess) && !get(hasError),\n}));\n\nconst highlightedClass = autoCompleteStyles({}).highlighted();\n\nfunction updateSearchInput(event: Event): void {\n const target = event.target;\n if (!(target instanceof HTMLInputElement))\n return;\n\n const value = target.value;\n set(isOpen, true);\n updateInternalSearch(value);\n set(justOpened, false);\n}\n\nasync function setValue(val: TItem, skipRefocused = false): Promise<void> {\n const isMultiple = get(multiple);\n\n if (isMultiple) {\n const newValue = [...get(value)];\n const indexInValue = itemIndexInValue(val);\n if (indexInValue === -1) {\n updateInternalSearch();\n newValue.push(val);\n }\n else {\n newValue.splice(indexInValue, 1);\n }\n set(value, newValue);\n }\n else {\n if (get(shouldApplyValueAsSearch))\n updateInternalSearch(getText(val));\n else updateInternalSearch();\n\n set(value, [val]);\n }\n\n if (!isMultiple) {\n if (!skipRefocused) {\n set(activatorFocused, true);\n get(activator)?.focus();\n await nextTick(() => {\n set(isOpen, false);\n });\n }\n else {\n set(isOpen, false);\n }\n }\n else if (!skipRefocused) {\n set(searchInputFocused, true);\n }\n}\n\nfunction setSearchAsValue(): void {\n const searchToBeValue = get(internalSearch);\n if (!searchToBeValue)\n return;\n\n const newValue: TItem = textValueToProperValue(searchToBeValue);\n setValue(newValue, true);\n}\n\nfunction clear(): void {\n updateInternalSearch();\n set(modelValue, (Array.isArray(get(modelValue)) ? [] : undefined) as AutoCompleteModelValue<TValue>);\n}\n\nfunction chipAttrs(item: TItem, index: number): Record<string, unknown> {\n return {\n 'data-index': index,\n 'data-value': getIdentifier(item),\n 'onKeydown': (event: KeyboardEvent): void => {\n const { key } = event;\n if (['Backspace', 'Delete'].includes(key)) {\n event.stopPropagation();\n event.preventDefault();\n setValue(item);\n }\n },\n 'onClick': (e: MouseEvent): void => {\n e.stopPropagation();\n setValueFocus(index);\n },\n 'onClick:close': (): void => {\n setValue(item);\n },\n };\n}\n\nfunction setSelectionRange(start: number, end: number): void {\n set(searchInputFocused, true);\n get(textInput)?.setSelectionRange?.(start, end);\n}\n\nfunction arrowClicked(event: MouseEvent): void {\n if (get(isOpen)) {\n set(isOpen, false);\n event.stopPropagation();\n }\n}\n\nfunction openMenu(): void {\n set(isOpen, true);\n}\n\nfunction closeMenu(): void {\n set(isOpen, false);\n}\n\n// Optimize options watcher with shallow comparison first\nwatch(() => options, (curr, old) => {\n if (curr === old || customValue)\n return;\n\n // Only do deep comparison if reference changed\n if (isEqual(curr, old))\n return;\n\n setSelected(get(value));\n});\n\nconst menuFloatingOptions = computed<FloatingOptions>(() => ({\n placement: Placement.bottomStart,\n ...menuOptions?.options,\n}));\n\ndefineExpose({\n closeMenu,\n focus: focusSetInputFocus,\n openMenu,\n setSelectionRange,\n});\n</script>\n\n<template>\n <RuiMenu\n v-model=\"isOpen\"\n v-bind=\"{ ...getRootAttrs($attrs, []), ...menuOptions }\"\n :class=\"ui.wrapper({ class: cn($attrs.class) })\"\n :options=\"menuFloatingOptions\"\n :close-on-content-click=\"false\"\n :full-width=\"true\"\n :persist-on-activator-click=\"true\"\n :menu-class=\"[\n { hidden: optionsWithSelectedHidden.length === 0 && customValue && !slots['no-data'] },\n menuOptions?.menuClass,\n ]\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n :dense=\"dense\"\n :show-details=\"!hideDetails\"\n :disabled=\"disabled\"\n disable-auto-focus\n >\n <template #activator=\"{ attrs, open, hasError: slotHasError, hasSuccess: slotHasSuccess }\">\n <slot\n name=\"activator\"\n v-bind=\"{ disabled, value, variant, readOnly, attrs, open, hasError: slotHasError, hasSuccess: slotHasSuccess }\"\n >\n <div\n ref=\"activator\"\n :class=\"ui.activator({ class: cn(classNames?.label) ?? labelClass })\"\n v-bind=\"{\n ...getNonRootAttrs($attrs, ['onClick', 'class']),\n ...(readOnly ? {} : attrs),\n }\"\n role=\"combobox\"\n :aria-expanded=\"open\"\n :aria-disabled=\"disabled || undefined\"\n :aria-readonly=\"readOnly || undefined\"\n :aria-required=\"required || undefined\"\n :aria-busy=\"loading || undefined\"\n data-id=\"activator\"\n :aria-invalid=\"hasError\"\n :tabindex=\"disabled || readOnly ? -1 : 0\"\n @mouseenter=\"isHovered = true\"\n @mouseleave=\"isHovered = false\"\n @click=\"focusSetInputFocus()\"\n @focus=\"focusOnActivatorFocused()\"\n @keydown.enter=\"onEnter($event)\"\n @keydown.tab=\"onTab($event)\"\n @keydown.left=\"moveSelectedValueHighlight($event, false)\"\n @keydown.right=\"moveSelectedValueHighlight($event, true)\"\n @keydown.up.prevent=\"moveHighlight(true)\"\n @keydown.down.prevent=\"moveHighlight(false)\"\n @keydown.home.prevent=\"highlightedIndex = 0\"\n @keydown.end.prevent=\"highlightedIndex = optionsWithSelectedHidden.length - 1\"\n >\n <span\n v-if=\"(outlined || (!valueSet && !searchInputFocused)) && !placeholderSlotActive\"\n :class=\"[\n ui.label(),\n { 'pr-2': !valueSet && !open && outlined },\n ]\"\n >\n <slot\n name=\"activator.label\"\n v-bind=\"{ value }\"\n >\n {{ label }}\n </slot>\n <span\n v-if=\"required\"\n :class=\"ui.required()\"\n >\n ﹡\n </span>\n </span>\n <div\n data-id=\"value\"\n :class=\"ui.value()\"\n >\n <!--\n Placeholder slot occupies the same flex space the input takes\n when focused, so transitioning into the focused state doesn't\n shift the activator's content. pointer-events-none is required\n so clicks pass through to the activator (otherwise the slot\n swallows the first click and the menu needs two taps to open).\n -->\n <div\n v-if=\"!valueSet && !searchInputFocused && slots.placeholder\"\n data-id=\"placeholder\"\n class=\"flex-1 min-w-0 pointer-events-none\"\n >\n <slot\n name=\"placeholder\"\n v-bind=\"{ disabled, readOnly }\"\n />\n </div>\n <template\n v-for=\"(item, i) in value\"\n :key=\"getIdentifier(item)\"\n >\n <RuiChip\n v-if=\"chips\"\n :key=\"getTextToken(getIdentifier(item))\"\n tabindex=\"-1\"\n :size=\"dense ? 'sm' : 'md'\"\n closeable\n :class=\"{ 'leading-3': dense }\"\n clickable\n v-bind=\"chipAttrs(item, i)\"\n >\n <div class=\"flex\">\n <slot\n name=\"selection.prepend\"\n :index=\"i\"\n v-bind=\"{ item }\"\n />\n <slot\n :index=\"i\"\n name=\"selection\"\n v-bind=\"{ item, chipAttrs: chipAttrs(item, i) }\"\n >\n {{ getText(item) }}\n </slot>\n </div>\n </RuiChip>\n <div\n v-else-if=\"\n multiple\n || (!searchInputFocused && (slots['selection.prepend'] || slots.selection))\n \"\n :class=\"hideSelectionWrapper ? 'contents' : 'flex'\"\n >\n <slot\n name=\"selection.prepend\"\n :index=\"i\"\n v-bind=\"{ item }\"\n />\n <slot\n v-if=\"multiple || slots.selection\"\n :index=\"i\"\n name=\"selection\"\n v-bind=\"{ item, chipAttrs: chipAttrs(item, i) }\"\n >\n {{ getText(item) }}\n </slot>\n </div>\n </template>\n <input\n ref=\"textInput\"\n :disabled=\"disabled\"\n :value=\"internalSearch\"\n class=\"bg-transparent outline-none\"\n type=\"text\"\n :placeholder=\"usedPlaceholder\"\n :class=\"[focusInputClass, { hidden: hideSearchInput }]\"\n :aria-invalid=\"hasError\"\n aria-autocomplete=\"list\"\n @keydown.delete=\"onInputDeletePressed()\"\n @input.stop=\"updateSearchInput($event)\"\n @focus=\"focusOnInputFocused()\"\n />\n </div>\n\n <RuiButton\n v-if=\"clearable && valueSet && !disabled\"\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n color=\"error\"\n data-id=\"clear\"\n :class=\"[\n ui.clear(),\n focusAnyFocused && '!visible',\n { 'mr-2': !dense },\n ]\"\n @click.stop.prevent=\"clear()\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"18\"\n />\n </RuiButton>\n\n <span\n :class=\"ui.iconWrapper()\"\n @click=\"arrowClicked($event)\"\n >\n <RuiIcon\n :class=\"ui.icon()\"\n :size=\"dense ? 16 : 24\"\n name=\"lu-chevron-down\"\n />\n </span>\n\n <RuiProgress\n v-if=\"loading\"\n :class=\"ui.progress()\"\n color=\"primary\"\n thickness=\"3\"\n variant=\"indeterminate\"\n />\n </div>\n <fieldset\n v-if=\"outlined\"\n :class=\"ui.fieldset()\"\n >\n <legend :class=\"ui.legend()\">\n {{ legendText }}\n </legend>\n </fieldset>\n </slot>\n </template>\n <template #default=\"{ width }\">\n <div ref=\"menuWrapperRef\">\n <div\n v-if=\"optionsWithSelectedHidden.length > 0\"\n :ref=\"containerProps.ref\"\n :class=\"ui.menu({ class: cn(classNames?.menu) ?? menuClass })\"\n :style=\"[containerProps.style, { width: `${width}px`, minWidth: menuWidth, minHeight: `${menuMinHeight}px` }]\"\n @scroll=\"containerProps.onScroll\"\n @keydown.up.prevent=\"moveHighlight(true)\"\n @keydown.down.prevent=\"moveHighlight(false)\"\n >\n <div\n v-if=\"isGrouped\"\n ref=\"menuRef\"\n >\n <template\n v-for=\"(bucket, bucketIndex) in groupedOptions\"\n :key=\"bucket.group || `group-${bucketIndex}`\"\n >\n <div\n class=\"sticky top-0 z-10 bg-white dark:bg-rui-grey-900\"\n data-id=\"group-header\"\n >\n <slot\n name=\"group-header\"\n v-bind=\"{ group: bucket.group, items: bucket.items }\"\n >\n <div class=\"px-3 py-1 text-xs uppercase tracking-wide text-rui-text-secondary\">\n {{ bucket.group }}\n </div>\n </slot>\n </div>\n <RuiButton\n v-for=\"item in bucket.items\"\n :key=\"getIdentifier(item)?.toString()\"\n :active=\"isActiveItem(item)\"\n :aria-selected=\"isActiveItem(item)\"\n :size=\"dense ? 'sm' : undefined\"\n :disabled=\"isItemDisabled(item)\"\n tabindex=\"0\"\n variant=\"list\"\n :data-highlighted=\"optionsWithSelectedHidden.indexOf(item) === highlightedIndex\"\n :data-disabled=\"isItemDisabled(item) || undefined\"\n :class=\"{\n [highlightedClass]: !isActiveItem(item) && optionsWithSelectedHidden.indexOf(item) === highlightedIndex,\n }\"\n @click=\"!isItemDisabled(item) && setValue(item)\"\n >\n <template #prepend>\n <slot\n name=\"item.prepend\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n />\n </template>\n <slot\n name=\"item\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n >\n {{ getText(item) }}\n </slot>\n <template #append>\n <slot\n name=\"item.append\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n />\n </template>\n </RuiButton>\n </template>\n </div>\n <div\n v-else\n v-bind=\"wrapperProps\"\n ref=\"menuRef\"\n >\n <RuiButton\n v-for=\"{ item, _index } in renderedData\"\n :key=\"getIdentifier(item)?.toString()\"\n :active=\"isActiveItem(item)\"\n :aria-selected=\"isActiveItem(item)\"\n :size=\"dense ? 'sm' : undefined\"\n :disabled=\"isItemDisabled(item)\"\n tabindex=\"0\"\n variant=\"list\"\n :data-highlighted=\"highlightedIndex === _index\"\n :data-disabled=\"isItemDisabled(item) || undefined\"\n :class=\"{\n [highlightedClass]: !isActiveItem(item) && highlightedIndex === _index,\n }\"\n @click=\"!isItemDisabled(item) && setValue(item)\"\n >\n <template #prepend>\n <slot\n name=\"item.prepend\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n />\n </template>\n <slot\n name=\"item\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n >\n {{ getText(item) }}\n </slot>\n <template #append>\n <slot\n name=\"item.append\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n />\n </template>\n </RuiButton>\n </div>\n </div>\n\n <div\n v-else-if=\"!hideNoData\"\n :style=\"{ width: `${width}px`, minWidth: menuWidth }\"\n :class=\"classNames?.menu ?? menuClass\"\n >\n <slot name=\"no-data\">\n <div\n v-if=\"!customValue\"\n class=\"p-4\"\n data-id=\"no-data\"\n >\n {{ noDataText }}\n </div>\n </slot>\n </div>\n <!--\n The scroll container above reserves ~15px on the right for the\n scrollbar gutter. We render an equivalent right-padding here so the\n footer's content aligns with the option rows' content rather than\n the menu's outer edge. `pr-[var(--rui-scrollbar-gutter,15px)]`\n lets consumers override if their theme reserves a different width.\n -->\n <div\n v-if=\"slots.footer\"\n class=\"bg-white dark:bg-rui-grey-900 border-t border-black/[0.12] dark:border-white/[0.12] pr-[var(--rui-scrollbar-gutter,15px)] -mb-2\"\n data-id=\"footer\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n </template>\n </RuiMenu>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"RuiAutoComplete.js","names":[],"sources":["../../../../src/components/forms/auto-complete/RuiAutoComplete.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue, TItem\">\nimport type { VueClassValue } from '@/types/class-value';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiChip from '@/components/chips/RuiChip.vue';\nimport { autoCompleteStyles, type AutoCompleteVariant } from '@/components/forms/auto-complete/auto-complete-styles';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiMenu, { type MenuProps } from '@/components/overlays/menu/RuiMenu.vue';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport {\n type GroupBy,\n type ItemDisabled,\n type KeyOfType,\n useDropdownMenu,\n useDropdownOptionProperty,\n} from '@/composables/dropdown-menu';\nimport { type FloatingOptions, Placement } from '@/composables/floating';\nimport {\n useAutoCompleteFocus,\n useAutoCompleteKeyboardNavigation,\n useAutoCompleteSearch,\n useAutoCompleteValue,\n} from '@/composables/forms/auto-complete';\nimport { useFormTextDetail } from '@/utils/form-text-detail';\nimport { getNonRootAttrs, getRootAttrs, getTextToken } from '@/utils/helpers';\nimport { isEqual } from '@/utils/is-equal';\nimport { cn } from '@/utils/tv';\n\nexport type AutoCompleteModelValue<TValue> =\n TValue extends Array<infer U> ? U[] : TValue | undefined;\n\nexport interface RuiAutoCompleteClassNames {\n root?: VueClassValue;\n label?: VueClassValue;\n menu?: VueClassValue;\n}\n\nexport interface AutoCompleteProps<TValue, TItem> {\n options?: TItem[];\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem;\n disabled?: boolean;\n loading?: boolean;\n readOnly?: boolean;\n dense?: boolean;\n clearable?: boolean;\n label?: string;\n menuOptions?: MenuProps;\n classNames?: RuiAutoCompleteClassNames;\n /** @deprecated Use `classNames.label` instead */\n labelClass?: string;\n /** @deprecated Use `classNames.menu` instead */\n menuClass?: string;\n prependWidth?: number;\n appendWidth?: number;\n itemHeight?: number;\n variant?: AutoCompleteVariant;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n hideDetails?: boolean;\n autoSelectFirst?: boolean;\n chips?: boolean;\n noFilter?: boolean;\n hideNoData?: boolean;\n noDataText?: string;\n /**\n * Custom search predicate. Receives the resolved group label as a third\n * argument when `groupBy` is set, so callers don't have to re-run the\n * `groupBy` resolver themselves.\n */\n filter?: (item: TItem, queryText: string, group?: string) => boolean;\n hideSelected?: boolean;\n placeholder?: string;\n returnObject?: boolean;\n customValue?: boolean;\n hideCustomValue?: boolean;\n required?: boolean;\n hideSearchInput?: boolean;\n hideSelectionWrapper?: boolean;\n groupBy?: GroupBy<TItem>;\n itemDisabled?: ItemDisabled<TItem>;\n /**\n * When true and `groupBy` is set, the default search predicate also matches\n * against the resolved group label. Items belonging to a group whose label\n * matches the query stay visible (group header included), even when the\n * items themselves don't match. No effect when a custom `filter` is supplied\n * or when `groupBy` is undefined.\n */\n searchIncludesGroupLabel?: boolean;\n}\n\ndefineOptions({\n name: 'RuiAutoComplete',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<AutoCompleteModelValue<TValue>>({ required: true });\n\nconst searchInputModel = defineModel<string>('searchInput', { default: '' });\n\nconst {\n options = [],\n disabled = false,\n loading = false,\n readOnly = false,\n dense = false,\n clearable = false,\n hideDetails = false,\n chips = false,\n label = 'Select',\n menuOptions,\n classNames,\n labelClass,\n menuClass,\n variant = 'default',\n hint,\n keyAttr,\n textAttr,\n itemHeight,\n errorMessages = [],\n successMessages = [],\n autoSelectFirst = false,\n noFilter = false,\n hideNoData = false,\n noDataText = 'No data available',\n filter,\n hideSelected = false,\n placeholder = '',\n returnObject = false,\n customValue = false,\n hideCustomValue = false,\n required = false,\n hideSearchInput = false,\n hideSelectionWrapper = false,\n groupBy,\n itemDisabled,\n searchIncludesGroupLabel = false,\n} = defineProps<AutoCompleteProps<TValue, TItem>>();\n\nconst slots = defineSlots<{\n 'activator'?: (props: {\n disabled: boolean;\n value: TItem[];\n variant: string;\n readOnly: boolean;\n attrs: Record<string, unknown>;\n open: boolean;\n hasError: boolean;\n hasSuccess: boolean;\n }) => any;\n 'activator.label'?: (props: { value: TItem[] }) => any;\n 'selection.prepend'?: (props: { index: number; item: TItem }) => any;\n 'selection'?: (props: { index: number; item: TItem; chipAttrs: Record<string, unknown> }) => any;\n 'item.prepend'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'item'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'item.append'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'group-header'?: (props: { group: string; items: TItem[] }) => any;\n 'no-data'?: () => any;\n 'placeholder'?: (props: { disabled: boolean; readOnly: boolean }) => any;\n 'footer'?: () => any;\n}>();\n\nconst { getText, getIdentifier } = useDropdownOptionProperty<TValue, TItem>({\n keyAttr,\n textAttr,\n});\n\nconst textInput = useTemplateRef<HTMLInputElement>('textInput');\nconst activator = useTemplateRef<HTMLDivElement>('activator');\nconst menuRef = useTemplateRef<HTMLDivElement>('menuRef');\nconst menuWrapperRef = useTemplateRef<HTMLDivElement>('menuWrapperRef');\n\nconst { focused: activatorFocusedWithin } = useFocusWithin(activator);\nconst { focused: menuWrapperFocusedWithin } = useFocusWithin(menuWrapperRef);\nconst { focused: searchInputFocused } = useFocus(textInput);\nconst { focused: activatorFocused } = useFocus(activator);\n\nconst {\n internalSearch,\n filteredOptions,\n justOpened,\n updateInternalSearch,\n textValueToProperValue,\n} = useAutoCompleteSearch<TItem>(\n () => options,\n searchInputModel,\n {\n keyAttr: () => keyAttr,\n textAttr: () => textAttr,\n noFilter: () => noFilter,\n filter: () => filter,\n customValue: () => customValue,\n hideCustomValue: () => hideCustomValue,\n returnObject: () => returnObject,\n groupBy: () => groupBy,\n searchIncludesGroupLabel: () => searchIncludesGroupLabel,\n },\n);\n\nconst isOpen = ref<boolean>(false);\nconst isHovered = ref<boolean>(false);\n\n// Calculate multiple from modelValue directly to avoid circular dependency\nconst multiple = computed<boolean>(() => Array.isArray(get(modelValue)));\n\nconst shouldApplyValueAsSearch = computed<boolean>(\n () => !(slots.selection || get(multiple) || chips),\n);\n\nconst { value, setSelected } = useAutoCompleteValue<AutoCompleteModelValue<TValue>, TItem>(\n modelValue,\n () => options,\n {\n keyAttr: () => keyAttr,\n returnObject: () => returnObject,\n customValue: () => customValue,\n },\n {\n getIdentifier,\n getText,\n textValueToProperValue,\n shouldApplyValueAsSearch,\n isOpen,\n multiple,\n updateInternalSearch,\n },\n);\n\nconst resolvedItemHeight = itemHeight ?? (dense ? 30 : 48);\n\nconst {\n containerProps,\n wrapperProps,\n renderedData,\n menuWidth,\n isActiveItem,\n itemIndexInValue,\n highlightedIndex,\n moveHighlight,\n applyHighlighted,\n optionsWithSelectedHidden,\n userNavigated,\n groupedOptions,\n isGrouped,\n isItemDisabled,\n} = useDropdownMenu<TValue, TItem>({\n itemHeight: resolvedItemHeight,\n keyAttr,\n textAttr,\n options: filteredOptions,\n dense: () => dense,\n value,\n menuRef,\n setValue,\n autoSelectFirst,\n hideSelected,\n isOpen,\n getText,\n getIdentifier,\n groupBy: () => groupBy,\n itemDisabled: () => itemDisabled,\n});\n\nconst {\n focusedValueIndex,\n moveSelectedValueHighlight,\n onEnter,\n onInputDeletePressed,\n onTab,\n setValueFocus,\n} = useAutoCompleteKeyboardNavigation<TItem>(\n {\n chips: () => chips,\n customValue: () => customValue,\n multiple,\n },\n {\n activator,\n applyHighlighted,\n clear,\n filteredOptions,\n getText,\n highlightedIndex,\n internalSearch,\n isOpen,\n removeValue: (item: TItem): void => { setValue(item); },\n searchInputFocused,\n setSearchAsValue,\n userNavigated,\n value,\n },\n);\n\nconst {\n anyFocused: focusAnyFocused,\n inputClass: focusInputClass,\n onActivatorFocused: focusOnActivatorFocused,\n onInputFocused: focusOnInputFocused,\n setInputFocus: focusSetInputFocus,\n} = useAutoCompleteFocus(\n {\n customValue: () => customValue,\n disabled: () => disabled,\n shouldApplyValueAsSearch,\n },\n {\n activatorFocused,\n activatorFocusedWithin,\n focusedValueIndex,\n internalSearch,\n isOpen,\n justOpened,\n menuWrapperFocusedWithin,\n searchInputFocused,\n setSearchAsValue,\n textInput,\n updateInternalSearch,\n },\n);\n\nconst menuMinHeight = computed<number>(\n () => Math.min(5, get(optionsWithSelectedHidden).length) * resolvedItemHeight,\n);\n\nconst { hasError, hasSuccess } = useFormTextDetail(\n () => errorMessages,\n () => successMessages,\n);\n\nconst valueSet = computed<boolean>(() => get(value).length > 0);\n\n// True when the consumer's #placeholder slot is taking over the resting\n// content area, so the outlined/resting label must hide to avoid overlapping\n// the slot content.\nconst placeholderSlotActive = computed<boolean>(() => Boolean(slots.placeholder) && !get(valueSet) && !get(searchInputFocused));\n\nconst usedPlaceholder = computed<string>(() => {\n if (get(searchInputFocused))\n return placeholder;\n return '';\n});\n\nconst outlined = computed<boolean>(() => variant === 'outlined');\nconst float = computed<boolean>(() => (get(isOpen) || get(valueSet) || get(searchInputFocused)) && get(outlined));\n\nconst legendText = computed<string>(() => {\n if (!get(float) || !label)\n return '';\n return required ? `${label} ﹡` : label;\n});\n\nconst ui = computed<ReturnType<typeof autoCompleteStyles>>(() => autoCompleteStyles({\n filled: variant === 'filled',\n outlined: get(outlined),\n float: get(float),\n opened: get(isOpen),\n hovered: get(isHovered),\n dense,\n disabled,\n readonly: readOnly,\n hasError: get(hasError),\n hasSuccess: get(hasSuccess) && !get(hasError),\n}));\n\nconst highlightedClass = autoCompleteStyles({}).highlighted();\n\nfunction updateSearchInput(event: Event): void {\n const target = event.target;\n if (!(target instanceof HTMLInputElement))\n return;\n\n const value = target.value;\n set(isOpen, true);\n updateInternalSearch(value);\n set(justOpened, false);\n}\n\nasync function setValue(val: TItem, skipRefocused = false): Promise<void> {\n const isMultiple = get(multiple);\n\n if (isMultiple) {\n const newValue = [...get(value)];\n const indexInValue = itemIndexInValue(val);\n if (indexInValue === -1) {\n updateInternalSearch();\n newValue.push(val);\n }\n else {\n newValue.splice(indexInValue, 1);\n }\n set(value, newValue);\n }\n else {\n if (get(shouldApplyValueAsSearch))\n updateInternalSearch(getText(val));\n else updateInternalSearch();\n\n set(value, [val]);\n }\n\n if (!isMultiple) {\n if (!skipRefocused) {\n set(activatorFocused, true);\n get(activator)?.focus();\n await nextTick(() => {\n set(isOpen, false);\n });\n }\n else {\n set(isOpen, false);\n }\n }\n else if (!skipRefocused) {\n set(searchInputFocused, true);\n }\n}\n\nfunction setSearchAsValue(): void {\n const searchToBeValue = get(internalSearch);\n if (!searchToBeValue)\n return;\n\n const newValue: TItem = textValueToProperValue(searchToBeValue);\n setValue(newValue, true);\n}\n\nfunction clear(): void {\n updateInternalSearch();\n set(modelValue, (Array.isArray(get(modelValue)) ? [] : undefined) as AutoCompleteModelValue<TValue>);\n}\n\nfunction chipAttrs(item: TItem, index: number): Record<string, unknown> {\n return {\n 'data-index': index,\n 'data-value': getIdentifier(item),\n 'onKeydown': (event: KeyboardEvent): void => {\n const { key } = event;\n if (['Backspace', 'Delete'].includes(key)) {\n event.stopPropagation();\n event.preventDefault();\n // Alt/Option + delete converts the chip back into editable search text\n // instead of removing it outright. Only meaningful when custom values\n // are accepted, since the restored text has to be re-selectable.\n if (event.altKey && customValue) {\n const text = getText(item) ?? '';\n setValue(item);\n updateInternalSearch(text);\n }\n else {\n setValue(item);\n }\n }\n },\n 'onClick': (e: MouseEvent): void => {\n e.stopPropagation();\n setValueFocus(index);\n },\n 'onClick:close': (): void => {\n setValue(item);\n },\n };\n}\n\nfunction setSelectionRange(start: number, end: number): void {\n set(searchInputFocused, true);\n get(textInput)?.setSelectionRange?.(start, end);\n}\n\nfunction arrowClicked(event: MouseEvent): void {\n if (get(isOpen)) {\n set(isOpen, false);\n event.stopPropagation();\n }\n}\n\nfunction openMenu(): void {\n set(isOpen, true);\n}\n\nfunction closeMenu(): void {\n set(isOpen, false);\n}\n\n// Optimize options watcher with shallow comparison first\nwatch(() => options, (curr, old) => {\n if (curr === old || customValue)\n return;\n\n // Only do deep comparison if reference changed\n if (isEqual(curr, old))\n return;\n\n setSelected(get(value));\n});\n\nconst menuFloatingOptions = computed<FloatingOptions>(() => ({\n placement: Placement.bottomStart,\n ...menuOptions?.options,\n}));\n\ndefineExpose({\n closeMenu,\n focus: focusSetInputFocus,\n openMenu,\n setSelectionRange,\n});\n</script>\n\n<template>\n <RuiMenu\n v-model=\"isOpen\"\n v-bind=\"{ ...getRootAttrs($attrs, []), ...menuOptions }\"\n :class=\"ui.wrapper({ class: cn($attrs.class) })\"\n :options=\"menuFloatingOptions\"\n :close-on-content-click=\"false\"\n :full-width=\"true\"\n :persist-on-activator-click=\"true\"\n :menu-class=\"[\n { hidden: optionsWithSelectedHidden.length === 0 && customValue && !slots['no-data'] },\n menuOptions?.menuClass,\n ]\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n :dense=\"dense\"\n :show-details=\"!hideDetails\"\n :disabled=\"disabled\"\n disable-auto-focus\n >\n <template #activator=\"{ attrs, open, hasError: slotHasError, hasSuccess: slotHasSuccess }\">\n <slot\n name=\"activator\"\n v-bind=\"{ disabled, value, variant, readOnly, attrs, open, hasError: slotHasError, hasSuccess: slotHasSuccess }\"\n >\n <div\n ref=\"activator\"\n :class=\"ui.activator({ class: cn(classNames?.label) ?? labelClass })\"\n v-bind=\"{\n ...getNonRootAttrs($attrs, ['onClick', 'class']),\n ...(readOnly ? {} : attrs),\n }\"\n role=\"combobox\"\n :aria-expanded=\"open\"\n :aria-disabled=\"disabled || undefined\"\n :aria-readonly=\"readOnly || undefined\"\n :aria-required=\"required || undefined\"\n :aria-busy=\"loading || undefined\"\n data-id=\"activator\"\n :aria-invalid=\"hasError\"\n :tabindex=\"disabled || readOnly ? -1 : 0\"\n @mouseenter=\"isHovered = true\"\n @mouseleave=\"isHovered = false\"\n @click=\"focusSetInputFocus()\"\n @focus=\"focusOnActivatorFocused()\"\n @keydown.enter=\"onEnter($event)\"\n @keydown.tab=\"onTab($event)\"\n @keydown.left=\"moveSelectedValueHighlight($event, false)\"\n @keydown.right=\"moveSelectedValueHighlight($event, true)\"\n @keydown.up.prevent=\"moveHighlight(true)\"\n @keydown.down.prevent=\"moveHighlight(false)\"\n @keydown.home.prevent=\"highlightedIndex = 0\"\n @keydown.end.prevent=\"highlightedIndex = optionsWithSelectedHidden.length - 1\"\n >\n <span\n v-if=\"(outlined || (!valueSet && !searchInputFocused)) && !placeholderSlotActive\"\n :class=\"[\n ui.label(),\n { 'pr-2': !valueSet && !open && outlined },\n ]\"\n >\n <slot\n name=\"activator.label\"\n v-bind=\"{ value }\"\n >\n {{ label }}\n </slot>\n <span\n v-if=\"required\"\n :class=\"ui.required()\"\n >\n ﹡\n </span>\n </span>\n <div\n data-id=\"value\"\n :class=\"ui.value()\"\n >\n <!--\n Placeholder slot occupies the same flex space the input takes\n when focused, so transitioning into the focused state doesn't\n shift the activator's content. pointer-events-none is required\n so clicks pass through to the activator (otherwise the slot\n swallows the first click and the menu needs two taps to open).\n -->\n <div\n v-if=\"!valueSet && !searchInputFocused && slots.placeholder\"\n data-id=\"placeholder\"\n class=\"flex-1 min-w-0 pointer-events-none\"\n >\n <slot\n name=\"placeholder\"\n v-bind=\"{ disabled, readOnly }\"\n />\n </div>\n <template\n v-for=\"(item, i) in value\"\n :key=\"getIdentifier(item)\"\n >\n <RuiChip\n v-if=\"chips\"\n :key=\"getTextToken(getIdentifier(item))\"\n tabindex=\"-1\"\n :size=\"dense ? 'sm' : 'md'\"\n closeable\n :class=\"{ 'leading-3': dense }\"\n clickable\n v-bind=\"chipAttrs(item, i)\"\n >\n <div class=\"flex\">\n <slot\n name=\"selection.prepend\"\n :index=\"i\"\n v-bind=\"{ item }\"\n />\n <slot\n :index=\"i\"\n name=\"selection\"\n v-bind=\"{ item, chipAttrs: chipAttrs(item, i) }\"\n >\n {{ getText(item) }}\n </slot>\n </div>\n </RuiChip>\n <div\n v-else-if=\"\n multiple\n || (!searchInputFocused && (slots['selection.prepend'] || slots.selection))\n \"\n :class=\"hideSelectionWrapper ? 'contents' : 'flex'\"\n >\n <slot\n name=\"selection.prepend\"\n :index=\"i\"\n v-bind=\"{ item }\"\n />\n <slot\n v-if=\"multiple || slots.selection\"\n :index=\"i\"\n name=\"selection\"\n v-bind=\"{ item, chipAttrs: chipAttrs(item, i) }\"\n >\n {{ getText(item) }}\n </slot>\n </div>\n </template>\n <input\n ref=\"textInput\"\n :disabled=\"disabled\"\n :value=\"internalSearch\"\n class=\"bg-transparent outline-none\"\n type=\"text\"\n :placeholder=\"usedPlaceholder\"\n :class=\"[focusInputClass, { hidden: hideSearchInput }]\"\n :aria-invalid=\"hasError\"\n aria-autocomplete=\"list\"\n @keydown.delete=\"onInputDeletePressed()\"\n @input.stop=\"updateSearchInput($event)\"\n @focus=\"focusOnInputFocused()\"\n />\n </div>\n\n <RuiButton\n v-if=\"clearable && valueSet && !disabled\"\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n color=\"error\"\n data-id=\"clear\"\n :class=\"[\n ui.clear(),\n focusAnyFocused && '!visible',\n { 'mr-2': !dense },\n ]\"\n @click.stop.prevent=\"clear()\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"18\"\n />\n </RuiButton>\n\n <span\n :class=\"ui.iconWrapper()\"\n @click=\"arrowClicked($event)\"\n >\n <RuiIcon\n :class=\"ui.icon()\"\n :size=\"dense ? 16 : 24\"\n name=\"lu-chevron-down\"\n />\n </span>\n\n <RuiProgress\n v-if=\"loading\"\n :class=\"ui.progress()\"\n color=\"primary\"\n thickness=\"3\"\n variant=\"indeterminate\"\n />\n </div>\n <fieldset\n v-if=\"outlined\"\n :class=\"ui.fieldset()\"\n >\n <legend :class=\"ui.legend()\">\n {{ legendText }}\n </legend>\n </fieldset>\n </slot>\n </template>\n <template #default=\"{ width }\">\n <div ref=\"menuWrapperRef\">\n <div\n v-if=\"optionsWithSelectedHidden.length > 0\"\n :ref=\"containerProps.ref\"\n :class=\"ui.menu({ class: cn(classNames?.menu) ?? menuClass })\"\n :style=\"[containerProps.style, { width: `${width}px`, minWidth: menuWidth, minHeight: `${menuMinHeight}px` }]\"\n @scroll=\"containerProps.onScroll\"\n @keydown.up.prevent=\"moveHighlight(true)\"\n @keydown.down.prevent=\"moveHighlight(false)\"\n >\n <div\n v-if=\"isGrouped\"\n ref=\"menuRef\"\n >\n <template\n v-for=\"(bucket, bucketIndex) in groupedOptions\"\n :key=\"bucket.group || `group-${bucketIndex}`\"\n >\n <div\n class=\"sticky top-0 z-10 bg-white dark:bg-rui-grey-900\"\n data-id=\"group-header\"\n >\n <slot\n name=\"group-header\"\n v-bind=\"{ group: bucket.group, items: bucket.items }\"\n >\n <div class=\"px-3 py-1 text-xs uppercase tracking-wide text-rui-text-secondary\">\n {{ bucket.group }}\n </div>\n </slot>\n </div>\n <RuiButton\n v-for=\"item in bucket.items\"\n :key=\"getIdentifier(item)?.toString()\"\n :active=\"isActiveItem(item)\"\n :aria-selected=\"isActiveItem(item)\"\n :size=\"dense ? 'sm' : undefined\"\n :disabled=\"isItemDisabled(item)\"\n tabindex=\"0\"\n variant=\"list\"\n :data-highlighted=\"optionsWithSelectedHidden.indexOf(item) === highlightedIndex\"\n :data-disabled=\"isItemDisabled(item) || undefined\"\n :class=\"{\n [highlightedClass]: !isActiveItem(item) && optionsWithSelectedHidden.indexOf(item) === highlightedIndex,\n }\"\n @click=\"!isItemDisabled(item) && setValue(item)\"\n >\n <template #prepend>\n <slot\n name=\"item.prepend\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n />\n </template>\n <slot\n name=\"item\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n >\n {{ getText(item) }}\n </slot>\n <template #append>\n <slot\n name=\"item.append\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n />\n </template>\n </RuiButton>\n </template>\n </div>\n <div\n v-else\n v-bind=\"wrapperProps\"\n ref=\"menuRef\"\n >\n <RuiButton\n v-for=\"{ item, _index } in renderedData\"\n :key=\"getIdentifier(item)?.toString()\"\n :active=\"isActiveItem(item)\"\n :aria-selected=\"isActiveItem(item)\"\n :size=\"dense ? 'sm' : undefined\"\n :disabled=\"isItemDisabled(item)\"\n tabindex=\"0\"\n variant=\"list\"\n :data-highlighted=\"highlightedIndex === _index\"\n :data-disabled=\"isItemDisabled(item) || undefined\"\n :class=\"{\n [highlightedClass]: !isActiveItem(item) && highlightedIndex === _index,\n }\"\n @click=\"!isItemDisabled(item) && setValue(item)\"\n >\n <template #prepend>\n <slot\n name=\"item.prepend\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n />\n </template>\n <slot\n name=\"item\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n >\n {{ getText(item) }}\n </slot>\n <template #append>\n <slot\n name=\"item.append\"\n v-bind=\"{ disabled: isItemDisabled(item), item, active: isActiveItem(item) }\"\n />\n </template>\n </RuiButton>\n </div>\n </div>\n\n <div\n v-else-if=\"!hideNoData\"\n :style=\"{ width: `${width}px`, minWidth: menuWidth }\"\n :class=\"classNames?.menu ?? menuClass\"\n >\n <slot name=\"no-data\">\n <div\n v-if=\"!customValue\"\n class=\"p-4\"\n data-id=\"no-data\"\n >\n {{ noDataText }}\n </div>\n </slot>\n </div>\n <!--\n The scroll container above reserves ~15px on the right for the\n scrollbar gutter. We render an equivalent right-padding here so the\n footer's content aligns with the option rows' content rather than\n the menu's outer edge. `pr-[var(--rui-scrollbar-gutter,15px)]`\n lets consumers override if their theme reserves a different width.\n -->\n <div\n v-if=\"slots.footer\"\n class=\"bg-white dark:bg-rui-grey-900 border-t border-black/[0.12] dark:border-white/[0.12] pr-[var(--rui-scrollbar-gutter,15px)] -mb-2\"\n data-id=\"footer\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n </template>\n </RuiMenu>\n</template>\n"],"mappings":""}
|
|
@@ -37,7 +37,12 @@ export interface AutoCompleteProps<TValue, TItem> {
|
|
|
37
37
|
noFilter?: boolean;
|
|
38
38
|
hideNoData?: boolean;
|
|
39
39
|
noDataText?: string;
|
|
40
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Custom search predicate. Receives the resolved group label as a third
|
|
42
|
+
* argument when `groupBy` is set, so callers don't have to re-run the
|
|
43
|
+
* `groupBy` resolver themselves.
|
|
44
|
+
*/
|
|
45
|
+
filter?: (item: TItem, queryText: string, group?: string) => boolean;
|
|
41
46
|
hideSelected?: boolean;
|
|
42
47
|
placeholder?: string;
|
|
43
48
|
returnObject?: boolean;
|
|
@@ -48,6 +53,14 @@ export interface AutoCompleteProps<TValue, TItem> {
|
|
|
48
53
|
hideSelectionWrapper?: boolean;
|
|
49
54
|
groupBy?: GroupBy<TItem>;
|
|
50
55
|
itemDisabled?: ItemDisabled<TItem>;
|
|
56
|
+
/**
|
|
57
|
+
* When true and `groupBy` is set, the default search predicate also matches
|
|
58
|
+
* against the resolved group label. Items belonging to a group whose label
|
|
59
|
+
* matches the query stay visible (group header included), even when the
|
|
60
|
+
* items themselves don't match. No effect when a custom `filter` is supplied
|
|
61
|
+
* or when `groupBy` is undefined.
|
|
62
|
+
*/
|
|
63
|
+
searchIncludesGroupLabel?: boolean;
|
|
51
64
|
}
|
|
52
65
|
declare const __VLS_export: <TValue, TItem>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
53
66
|
props: import("vue").PublicProps & __VLS_PrettifyLocal<(AutoCompleteProps<TValue, TItem> & {
|
package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -55,11 +55,11 @@ var _hoisted_8 = {
|
|
|
55
55
|
class: "bg-white dark:bg-rui-grey-900 border-t border-black/[0.12] dark:border-white/[0.12] pr-[var(--rui-scrollbar-gutter,15px)] -mb-2",
|
|
56
56
|
"data-id": "footer"
|
|
57
57
|
};
|
|
58
|
-
var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default =
|
|
58
|
+
var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
59
59
|
name: "RuiAutoComplete",
|
|
60
60
|
inheritAttrs: false,
|
|
61
61
|
__name: "RuiAutoComplete",
|
|
62
|
-
props:
|
|
62
|
+
props: /*@__PURE__*/ mergeModels({
|
|
63
63
|
options: { default: () => [] },
|
|
64
64
|
keyAttr: {},
|
|
65
65
|
textAttr: {},
|
|
@@ -147,7 +147,11 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
147
147
|
default: false
|
|
148
148
|
},
|
|
149
149
|
groupBy: { type: Function },
|
|
150
|
-
itemDisabled: { type: Function }
|
|
150
|
+
itemDisabled: { type: Function },
|
|
151
|
+
searchIncludesGroupLabel: {
|
|
152
|
+
type: Boolean,
|
|
153
|
+
default: false
|
|
154
|
+
}
|
|
151
155
|
}, {
|
|
152
156
|
"modelValue": { required: true },
|
|
153
157
|
"modelModifiers": {},
|
|
@@ -178,7 +182,9 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
178
182
|
filter: () => __props.filter,
|
|
179
183
|
customValue: () => __props.customValue,
|
|
180
184
|
hideCustomValue: () => __props.hideCustomValue,
|
|
181
|
-
returnObject: () => __props.returnObject
|
|
185
|
+
returnObject: () => __props.returnObject,
|
|
186
|
+
groupBy: () => __props.groupBy,
|
|
187
|
+
searchIncludesGroupLabel: () => __props.searchIncludesGroupLabel
|
|
182
188
|
});
|
|
183
189
|
const isOpen = ref(false);
|
|
184
190
|
const isHovered = ref(false);
|
|
@@ -330,7 +336,11 @@ var RuiAutoComplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ *
|
|
|
330
336
|
if (["Backspace", "Delete"].includes(key)) {
|
|
331
337
|
event.stopPropagation();
|
|
332
338
|
event.preventDefault();
|
|
333
|
-
|
|
339
|
+
if (event.altKey && __props.customValue) {
|
|
340
|
+
const text = getText(item) ?? "";
|
|
341
|
+
setValue(item);
|
|
342
|
+
updateInternalSearch(text);
|
|
343
|
+
} else setValue(item);
|
|
334
344
|
}
|
|
335
345
|
},
|
|
336
346
|
"onClick": (e) => {
|