@rotki/ui-library 2.20.2 → 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/__test__/options.d.ts +7 -0
- 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.js.map +1 -1
- package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js +6 -4
- 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.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +5 -3
- 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 +26 -2
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +150 -54
- 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 +7 -0
- package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -0
- package/dist/components/forms/file-upload/RuiFileUpload.vue.d.ts +61 -0
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +269 -0
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -0
- 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.js.map +1 -1
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +9 -3
- 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 +4 -2
- package/dist/components/index.js +4 -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.js.map +1 -1
- package/dist/components/overlays/menu/RuiMenu.vue.d.ts +6 -0
- package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js +5 -4
- 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.d.ts +12 -1
- package/dist/composables/dropdown-menu.js +46 -7
- 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 +9 -6
- package/dist/index.js.map +1 -1
- package/dist/library-icons.json +3 -0
- package/dist/style.css +200 -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.d.ts +4 -0
- package/dist/utils/helpers.js +21 -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 +2283 -1088
- package/package.json +35 -35
package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiTimePicker.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/time-picker/RuiTimePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref, type StyleValue, watch } from 'vue';\nimport { timePickerStyles } from '@/components/time-picker/time-picker-styles';\nimport { TimeAccuracy } from '@/consts/time-accuracy';\nimport { assert } from '@/utils/assert';\n\nexport type TimePickerSelection = 'hour' | 'minute' | 'second' | 'millisecond';\n\nexport interface RuiTimePickerProps {\n accuracy?: TimeAccuracy;\n borderless?: boolean;\n}\n\nconst modelValue = defineModel<Date | undefined>({ required: true });\n\nconst selectedHour = defineModel<number | undefined>('hour');\nconst selectedMinute = defineModel<number | undefined>('minute');\nconst selectedSecond = defineModel<number | undefined>('second');\nconst selectedMillisecond = defineModel<number | undefined>('millisecond');\nconst editMode = defineModel<TimePickerSelection>('selection', { default: 'hour' });\n\nconst { accuracy = TimeAccuracy.MINUTE, borderless = false } = defineProps<RuiTimePickerProps>();\n\nconst ui = timePickerStyles();\n\nconst FULL_CIRCLE = 360;\nconst TWELVE_HOURS = 12;\n\nconst totalItemsPerMode: Record<TimePickerSelection, number> = {\n hour: 12,\n minute: 60,\n second: 60,\n millisecond: 1000,\n};\n\nconst intervals: Record<TimePickerSelection, number> = {\n hour: 1,\n minute: 5,\n second: 5,\n millisecond: 100,\n};\n\nconst isDragging = ref<boolean>(false);\nconst clockFace = useTemplateRef<InstanceType<typeof HTMLDivElement>>('clockFace');\n\nconst showSecond = computed<boolean>(\n () => accuracy === TimeAccuracy.SECOND || accuracy === TimeAccuracy.MILLISECOND,\n);\nconst showMillisecond = computed<boolean>(() => accuracy === TimeAccuracy.MILLISECOND);\n\nconst period = computed<'PM' | 'AM'>(() =>\n isDefined(selectedHour) && get(selectedHour) >= TWELVE_HOURS ? 'PM' : 'AM',\n);\n\nconst displayHour = computed<number | undefined>(() => {\n if (!isDefined(selectedHour)) {\n return undefined;\n }\n const hourValue = get(selectedHour);\n const hour = hourValue % TWELVE_HOURS;\n return hour === 0 ? TWELVE_HOURS : hour;\n});\n\nconst editedValue = computed<number | undefined>(() => {\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour);\n }\n else if (mode === 'minute') {\n return get(selectedMinute);\n }\n else if (mode === 'second') {\n return get(selectedSecond);\n }\n else {\n return get(selectedMillisecond);\n }\n});\n\nconst displayClockHandCircle = computed<boolean>(() => {\n const mode = get(editMode);\n if (mode === 'hour' || !isDefined(editedValue)) {\n return false;\n }\n else {\n const interval = intervals[mode];\n const value = get(editedValue);\n return value % interval !== 0;\n }\n});\n\nconst dotStyle = computed<StyleValue>(() => ({\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n}));\n\nconst clockHandStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n return {\n height: '36%',\n top: '14%',\n left: '50%',\n transformOrigin: 'bottom center',\n transform: `translateX(-50%) rotate(${angle}deg)`,\n zIndex: 10,\n };\n});\n\nconst clockHandCircleStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const radius = '38%';\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n const radians = (angle * Math.PI) / 180;\n\n const x = 50 + parseFloat(radius) * Math.cos(radians - Math.PI / 2);\n const y = 50 + parseFloat(radius) * Math.sin(radians - Math.PI / 2);\n\n return {\n position: 'absolute',\n top: `${y}%`,\n left: `${x}%`,\n width: '10px',\n height: '10px',\n borderRadius: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: 11,\n };\n});\n\nconst clockNumbers = computed<number[]>(() => {\n const mode = get(editMode);\n const interval = intervals[mode];\n const total = totalItemsPerMode[mode];\n const numbers = generateNumbers(total, interval);\n if (mode === 'hour') {\n numbers[0] = 12;\n }\n return numbers;\n});\n\nfunction getModelHours(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getHours() : undefined;\n}\n\nfunction getModelMinutes(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getMinutes() : undefined;\n}\n\nfunction getModelSeconds(): number | undefined {\n const acceptedAccuracy: TimeAccuracy[] = [TimeAccuracy.SECOND, TimeAccuracy.MILLISECOND];\n return acceptedAccuracy.includes(accuracy) && isDefined(modelValue)\n ? new Date(get(modelValue)).getSeconds()\n : undefined;\n}\n\nfunction getModelMilliseconds(): number | undefined {\n return accuracy === TimeAccuracy.MILLISECOND && isDefined(modelValue)\n ? new Date(get(modelValue)).getMilliseconds()\n : undefined;\n}\n\nfunction generateNumbers(total: number, interval: number): number[] {\n const numbers: number[] = [];\n for (let i = 0; i < total; i += interval) {\n numbers.push(i);\n }\n return numbers;\n}\n\nfunction formatValue(value?: number, padding = 2): string {\n return value !== undefined ? value.toString().padStart(padding, '0') : '-'.repeat(padding);\n}\n\nfunction numberStyle(num: number): StyleValue {\n const radius = '38%';\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = num * (FULL_CIRCLE / totalItems) - 90;\n\n const radians = (angle * Math.PI) / 180;\n const x = 50 + parseFloat(radius) * Math.cos(radians);\n const y = 50 + parseFloat(radius) * Math.sin(radians);\n\n return {\n top: `${y}%`,\n left: `${x}%`,\n transform: 'translate(-50%, -50%)',\n };\n}\n\nfunction isSelectedNumber(num: number): boolean {\n if (!isDefined(editedValue)) {\n return false;\n }\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour) === num;\n }\n else {\n const value = get(editedValue);\n const interval = intervals[mode];\n return value === num || (value % interval === 0 && value === num);\n }\n}\n\nfunction toggleAmPm(): void {\n if (!isDefined(selectedHour)) {\n return;\n }\n if (get(selectedHour) < TWELVE_HOURS) {\n set(selectedHour, get(selectedHour) + TWELVE_HOURS);\n }\n else {\n set(selectedHour, get(selectedHour) - TWELVE_HOURS);\n }\n\n updateModelValue();\n}\n\nfunction startDrag(event: MouseEvent | TouchEvent): void {\n event.preventDefault();\n set(isDragging, true);\n\n if (!isDefined(clockFace))\n return;\n\n const rect = get(clockFace).getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n let rafId: number | null = null;\n\n const applyMove = (clientX: number, clientY: number): void => {\n const x = clientX - centerX;\n const y = clientY - centerY;\n\n let angle = Math.atan2(y, x) * (180 / Math.PI) + 90;\n if (angle < 0)\n angle += FULL_CIRCLE;\n\n const mode = get(editMode);\n const unit =\n Math.round(angle / (FULL_CIRCLE / totalItemsPerMode[mode])) % totalItemsPerMode[mode];\n if (mode === 'hour') {\n let hour = unit;\n if (hour === 0)\n hour = TWELVE_HOURS;\n\n if (get(period) === 'PM' && hour < TWELVE_HOURS) {\n hour += TWELVE_HOURS;\n }\n else if (get(period) === 'AM' && hour === TWELVE_HOURS) {\n hour = 0;\n }\n\n set(selectedHour, hour);\n }\n else if (mode === 'minute') {\n set(selectedMinute, unit);\n }\n else if (mode === 'second') {\n set(selectedSecond, unit);\n }\n else {\n set(selectedMillisecond, unit);\n }\n\n updateModelValue();\n };\n\n const handleMove = (moveEvent: MouseEvent | TouchEvent): void => {\n if (!get(isDragging))\n return;\n\n if (rafId !== null)\n return;\n\n let clientX: number;\n let clientY: number;\n\n if ('touches' in moveEvent) {\n const touch = moveEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = moveEvent.clientX;\n clientY = moveEvent.clientY;\n }\n\n rafId = requestAnimationFrame(() => {\n applyMove(clientX, clientY);\n rafId = null;\n });\n };\n\n const handleEnd = (): void => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n set(isDragging, false);\n document.removeEventListener('mousemove', handleMove);\n document.removeEventListener('touchmove', handleMove);\n document.removeEventListener('mouseup', handleEnd);\n document.removeEventListener('touchend', handleEnd);\n\n if (get(editMode) === 'hour') {\n set(editMode, 'minute');\n }\n else if (get(showSecond) && get(editMode) === 'minute') {\n set(editMode, 'second');\n }\n else if (get(showMillisecond) && get(editMode) === 'second') {\n set(editMode, 'millisecond');\n }\n };\n\n document.addEventListener('mousemove', handleMove);\n document.addEventListener('touchmove', handleMove);\n document.addEventListener('mouseup', handleEnd);\n document.addEventListener('touchend', handleEnd);\n\n // Apply initial position synchronously for immediate feedback\n const initialEvent = event;\n let clientX: number;\n let clientY: number;\n if ('touches' in initialEvent) {\n const touch = initialEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = initialEvent.clientX;\n clientY = initialEvent.clientY;\n }\n applyMove(clientX, clientY);\n}\n\nfunction selectByClick(num: number): void {\n const mode = get(editMode);\n if (mode === 'hour') {\n let newHour = num;\n\n if (get(period) === 'PM' && newHour < TWELVE_HOURS) {\n newHour += TWELVE_HOURS;\n }\n\n set(selectedHour, newHour);\n set(editMode, 'minute');\n }\n else if (mode === 'minute') {\n set(selectedMinute, num);\n if (get(showSecond))\n set(editMode, 'second');\n }\n else if (mode === 'second') {\n set(selectedSecond, num);\n if (get(showMillisecond)) {\n set(editMode, 'millisecond');\n }\n }\n else if (mode === 'millisecond') {\n set(selectedMillisecond, num);\n }\n\n updateModelValue();\n}\n\nfunction updateModelValue(): void {\n if (!(isDefined(selectedHour) && isDefined(selectedMinute))) {\n return;\n }\n nextTick(() => {\n const date = isDefined(modelValue) ? new Date(get(modelValue)) : new Date();\n date.setHours(get(selectedHour));\n date.setMinutes(get(selectedMinute));\n date.setSeconds(get(selectedSecond) ?? 0);\n date.setMilliseconds(get(selectedMillisecond) ?? 0);\n set(modelValue, date);\n });\n}\n\nwatch(\n modelValue,\n () => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n },\n);\n\nonMounted(() => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n});\n</script>\n\n<template>\n <div\n role=\"group\"\n aria-label=\"Time picker\"\n :class=\"ui.root({ bordered: !borderless })\"\n >\n <div :class=\"ui.digitalDisplay()\">\n <div class=\"flex justify-center items-center gap-1\">\n <div\n role=\"button\"\n aria-label=\"Select hours\"\n :class=\"ui.digit({ active: editMode === 'hour' })\"\n @click=\"editMode = 'hour'\"\n >\n {{ formatValue(displayHour) }}\n </div>\n <div class=\"text-2xl font-semibold\">\n :\n </div>\n <div\n role=\"button\"\n aria-label=\"Select minutes\"\n :class=\"ui.digit({ active: editMode === 'minute' })\"\n @click=\"editMode = 'minute'\"\n >\n {{ formatValue(selectedMinute) }}\n </div>\n <div\n v-if=\"showSecond\"\n class=\"text-2xl font-semibold\"\n >\n :\n </div>\n <div\n v-if=\"showSecond\"\n role=\"button\"\n aria-label=\"Select seconds\"\n :class=\"ui.digit({ active: editMode === 'second' })\"\n @click=\"editMode = 'second'\"\n >\n {{ formatValue(selectedSecond) }}\n </div>\n\n <div\n v-if=\"showMillisecond\"\n class=\"text-lg font-semibold\"\n >\n .\n </div>\n\n <div\n v-if=\"showMillisecond\"\n role=\"button\"\n aria-label=\"Select milliseconds\"\n :class=\"ui.digit({ active: editMode === 'millisecond', class: '!text-lg' })\"\n @click=\"editMode = 'millisecond'\"\n >\n {{ formatValue(selectedMillisecond, 3) }}\n </div>\n <div class=\"text-xl\">\n <div\n role=\"button\"\n aria-label=\"Toggle AM/PM\"\n class=\"rui-time-picker-period cursor-pointer\"\n @click=\"toggleAmPm()\"\n >\n {{ period }}\n </div>\n </div>\n </div>\n </div>\n\n <div\n ref=\"clockFace\"\n role=\"listbox\"\n :aria-label=\"`Select ${editMode}`\"\n :class=\"ui.clockFace()\"\n @mousedown=\"startDrag($event)\"\n @touchstart=\"startDrag($event)\"\n >\n <div\n :class=\"ui.centerDot()\"\n :style=\"dotStyle\"\n />\n\n <div\n :class=\"ui.clockHand()\"\n :style=\"clockHandStyle\"\n />\n\n <div\n v-if=\"displayClockHandCircle\"\n :class=\"ui.clockHandCircle()\"\n :style=\"clockHandCircleStyle\"\n />\n\n <div\n v-for=\"num in clockNumbers\"\n :key=\"`num-${num}`\"\n role=\"option\"\n :aria-selected=\"isSelectedNumber(num)\"\n :class=\"[\n ui.clockNumber({ selected: isSelectedNumber(num) }),\n `rui-${editMode}-${num.toString().padStart(2, '0')}`,\n ]\"\n :style=\"numberStyle(num)\"\n @click=\"selectByClick(num)\"\n >\n {{ num }}\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RuiTimePicker.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/time-picker/RuiTimePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref, type StyleValue, watch } from 'vue';\nimport { timePickerStyles } from '@/components/time-picker/time-picker-styles';\nimport { TimeAccuracy } from '@/consts/time-accuracy';\nimport { assert } from '@/utils/assert';\n\nexport type TimePickerSelection = 'hour' | 'minute' | 'second' | 'millisecond';\n\nexport interface RuiTimePickerProps {\n accuracy?: TimeAccuracy;\n borderless?: boolean;\n}\n\nconst modelValue = defineModel<Date | undefined>({ required: true });\n\nconst selectedHour = defineModel<number | undefined>('hour');\nconst selectedMinute = defineModel<number | undefined>('minute');\nconst selectedSecond = defineModel<number | undefined>('second');\nconst selectedMillisecond = defineModel<number | undefined>('millisecond');\nconst editMode = defineModel<TimePickerSelection>('selection', { default: 'hour' });\n\nconst { accuracy = TimeAccuracy.MINUTE, borderless = false } = defineProps<RuiTimePickerProps>();\n\nconst ui = timePickerStyles();\n\nconst FULL_CIRCLE = 360;\nconst TWELVE_HOURS = 12;\n\nconst totalItemsPerMode: Record<TimePickerSelection, number> = {\n hour: 12,\n minute: 60,\n second: 60,\n millisecond: 1000,\n};\n\nconst intervals: Record<TimePickerSelection, number> = {\n hour: 1,\n minute: 5,\n second: 5,\n millisecond: 100,\n};\n\nconst isDragging = ref<boolean>(false);\nconst clockFace = useTemplateRef<InstanceType<typeof HTMLDivElement>>('clockFace');\n\nconst showSecond = computed<boolean>(\n () => accuracy === TimeAccuracy.SECOND || accuracy === TimeAccuracy.MILLISECOND,\n);\nconst showMillisecond = computed<boolean>(() => accuracy === TimeAccuracy.MILLISECOND);\n\nconst period = computed<'PM' | 'AM'>(() =>\n isDefined(selectedHour) && get(selectedHour) >= TWELVE_HOURS ? 'PM' : 'AM',\n);\n\nconst displayHour = computed<number | undefined>(() => {\n if (!isDefined(selectedHour)) {\n return undefined;\n }\n const hourValue = get(selectedHour);\n const hour = hourValue % TWELVE_HOURS;\n return hour === 0 ? TWELVE_HOURS : hour;\n});\n\nconst editedValue = computed<number | undefined>(() => {\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour);\n }\n else if (mode === 'minute') {\n return get(selectedMinute);\n }\n else if (mode === 'second') {\n return get(selectedSecond);\n }\n else {\n return get(selectedMillisecond);\n }\n});\n\nconst displayClockHandCircle = computed<boolean>(() => {\n const mode = get(editMode);\n if (mode === 'hour' || !isDefined(editedValue)) {\n return false;\n }\n else {\n const interval = intervals[mode];\n const value = get(editedValue);\n return value % interval !== 0;\n }\n});\n\nconst dotStyle = computed<StyleValue>(() => ({\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n}));\n\nconst clockHandStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n return {\n height: '36%',\n top: '14%',\n left: '50%',\n transformOrigin: 'bottom center',\n transform: `translateX(-50%) rotate(${angle}deg)`,\n zIndex: 10,\n };\n});\n\nconst clockHandCircleStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const radius = '38%';\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n const radians = (angle * Math.PI) / 180;\n\n const x = 50 + parseFloat(radius) * Math.cos(radians - Math.PI / 2);\n const y = 50 + parseFloat(radius) * Math.sin(radians - Math.PI / 2);\n\n return {\n position: 'absolute',\n top: `${y}%`,\n left: `${x}%`,\n width: '10px',\n height: '10px',\n borderRadius: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: 11,\n };\n});\n\nconst clockNumbers = computed<number[]>(() => {\n const mode = get(editMode);\n const interval = intervals[mode];\n const total = totalItemsPerMode[mode];\n const numbers = generateNumbers(total, interval);\n if (mode === 'hour') {\n numbers[0] = 12;\n }\n return numbers;\n});\n\nfunction getModelHours(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getHours() : undefined;\n}\n\nfunction getModelMinutes(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getMinutes() : undefined;\n}\n\nfunction getModelSeconds(): number | undefined {\n const acceptedAccuracy: TimeAccuracy[] = [TimeAccuracy.SECOND, TimeAccuracy.MILLISECOND];\n return acceptedAccuracy.includes(accuracy) && isDefined(modelValue)\n ? new Date(get(modelValue)).getSeconds()\n : undefined;\n}\n\nfunction getModelMilliseconds(): number | undefined {\n return accuracy === TimeAccuracy.MILLISECOND && isDefined(modelValue)\n ? new Date(get(modelValue)).getMilliseconds()\n : undefined;\n}\n\nfunction generateNumbers(total: number, interval: number): number[] {\n const numbers: number[] = [];\n for (let i = 0; i < total; i += interval) {\n numbers.push(i);\n }\n return numbers;\n}\n\nfunction formatValue(value?: number, padding = 2): string {\n return value !== undefined ? value.toString().padStart(padding, '0') : '-'.repeat(padding);\n}\n\nfunction numberStyle(num: number): StyleValue {\n const radius = '38%';\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = num * (FULL_CIRCLE / totalItems) - 90;\n\n const radians = (angle * Math.PI) / 180;\n const x = 50 + parseFloat(radius) * Math.cos(radians);\n const y = 50 + parseFloat(radius) * Math.sin(radians);\n\n return {\n top: `${y}%`,\n left: `${x}%`,\n transform: 'translate(-50%, -50%)',\n };\n}\n\nfunction isSelectedNumber(num: number): boolean {\n if (!isDefined(editedValue)) {\n return false;\n }\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour) === num;\n }\n else {\n const value = get(editedValue);\n const interval = intervals[mode];\n return value === num || (value % interval === 0 && value === num);\n }\n}\n\nfunction toggleAmPm(): void {\n if (!isDefined(selectedHour)) {\n return;\n }\n if (get(selectedHour) < TWELVE_HOURS) {\n set(selectedHour, get(selectedHour) + TWELVE_HOURS);\n }\n else {\n set(selectedHour, get(selectedHour) - TWELVE_HOURS);\n }\n\n updateModelValue();\n}\n\nfunction startDrag(event: MouseEvent | TouchEvent): void {\n event.preventDefault();\n set(isDragging, true);\n\n if (!isDefined(clockFace))\n return;\n\n const rect = get(clockFace).getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n let rafId: number | null = null;\n\n const applyMove = (clientX: number, clientY: number): void => {\n const x = clientX - centerX;\n const y = clientY - centerY;\n\n let angle = Math.atan2(y, x) * (180 / Math.PI) + 90;\n if (angle < 0)\n angle += FULL_CIRCLE;\n\n const mode = get(editMode);\n const unit =\n Math.round(angle / (FULL_CIRCLE / totalItemsPerMode[mode])) % totalItemsPerMode[mode];\n if (mode === 'hour') {\n let hour = unit;\n if (hour === 0)\n hour = TWELVE_HOURS;\n\n if (get(period) === 'PM' && hour < TWELVE_HOURS) {\n hour += TWELVE_HOURS;\n }\n else if (get(period) === 'AM' && hour === TWELVE_HOURS) {\n hour = 0;\n }\n\n set(selectedHour, hour);\n }\n else if (mode === 'minute') {\n set(selectedMinute, unit);\n }\n else if (mode === 'second') {\n set(selectedSecond, unit);\n }\n else {\n set(selectedMillisecond, unit);\n }\n\n updateModelValue();\n };\n\n const handleMove = (moveEvent: MouseEvent | TouchEvent): void => {\n if (!get(isDragging))\n return;\n\n if (rafId !== null)\n return;\n\n let clientX: number;\n let clientY: number;\n\n if ('touches' in moveEvent) {\n const touch = moveEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = moveEvent.clientX;\n clientY = moveEvent.clientY;\n }\n\n rafId = requestAnimationFrame(() => {\n applyMove(clientX, clientY);\n rafId = null;\n });\n };\n\n const handleEnd = (): void => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n set(isDragging, false);\n document.removeEventListener('mousemove', handleMove);\n document.removeEventListener('touchmove', handleMove);\n document.removeEventListener('mouseup', handleEnd);\n document.removeEventListener('touchend', handleEnd);\n\n if (get(editMode) === 'hour') {\n set(editMode, 'minute');\n }\n else if (get(showSecond) && get(editMode) === 'minute') {\n set(editMode, 'second');\n }\n else if (get(showMillisecond) && get(editMode) === 'second') {\n set(editMode, 'millisecond');\n }\n };\n\n document.addEventListener('mousemove', handleMove);\n document.addEventListener('touchmove', handleMove);\n document.addEventListener('mouseup', handleEnd);\n document.addEventListener('touchend', handleEnd);\n\n // Apply initial position synchronously for immediate feedback\n const initialEvent = event;\n let clientX: number;\n let clientY: number;\n if ('touches' in initialEvent) {\n const touch = initialEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = initialEvent.clientX;\n clientY = initialEvent.clientY;\n }\n applyMove(clientX, clientY);\n}\n\nfunction selectByClick(num: number): void {\n const mode = get(editMode);\n if (mode === 'hour') {\n let newHour = num;\n\n if (get(period) === 'PM' && newHour < TWELVE_HOURS) {\n newHour += TWELVE_HOURS;\n }\n\n set(selectedHour, newHour);\n set(editMode, 'minute');\n }\n else if (mode === 'minute') {\n set(selectedMinute, num);\n if (get(showSecond))\n set(editMode, 'second');\n }\n else if (mode === 'second') {\n set(selectedSecond, num);\n if (get(showMillisecond)) {\n set(editMode, 'millisecond');\n }\n }\n else if (mode === 'millisecond') {\n set(selectedMillisecond, num);\n }\n\n updateModelValue();\n}\n\nfunction updateModelValue(): void {\n if (!(isDefined(selectedHour) && isDefined(selectedMinute))) {\n return;\n }\n nextTick(() => {\n const date = isDefined(modelValue) ? new Date(get(modelValue)) : new Date();\n date.setHours(get(selectedHour));\n date.setMinutes(get(selectedMinute));\n date.setSeconds(get(selectedSecond) ?? 0);\n date.setMilliseconds(get(selectedMillisecond) ?? 0);\n set(modelValue, date);\n });\n}\n\nwatch(\n modelValue,\n () => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n },\n);\n\nonMounted(() => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n});\n</script>\n\n<template>\n <div\n role=\"group\"\n aria-label=\"Time picker\"\n :class=\"ui.root({ bordered: !borderless })\"\n >\n <div :class=\"ui.digitalDisplay()\">\n <div class=\"flex justify-center items-center gap-1\">\n <div\n role=\"button\"\n aria-label=\"Select hours\"\n :class=\"ui.digit({ active: editMode === 'hour' })\"\n @click=\"editMode = 'hour'\"\n >\n {{ formatValue(displayHour) }}\n </div>\n <div class=\"text-2xl font-semibold\">\n :\n </div>\n <div\n role=\"button\"\n aria-label=\"Select minutes\"\n :class=\"ui.digit({ active: editMode === 'minute' })\"\n @click=\"editMode = 'minute'\"\n >\n {{ formatValue(selectedMinute) }}\n </div>\n <div\n v-if=\"showSecond\"\n class=\"text-2xl font-semibold\"\n >\n :\n </div>\n <div\n v-if=\"showSecond\"\n role=\"button\"\n aria-label=\"Select seconds\"\n :class=\"ui.digit({ active: editMode === 'second' })\"\n @click=\"editMode = 'second'\"\n >\n {{ formatValue(selectedSecond) }}\n </div>\n\n <div\n v-if=\"showMillisecond\"\n class=\"text-lg font-semibold\"\n >\n .\n </div>\n\n <div\n v-if=\"showMillisecond\"\n role=\"button\"\n aria-label=\"Select milliseconds\"\n :class=\"ui.digit({ active: editMode === 'millisecond', class: '!text-lg' })\"\n @click=\"editMode = 'millisecond'\"\n >\n {{ formatValue(selectedMillisecond, 3) }}\n </div>\n <div class=\"text-xl\">\n <div\n role=\"button\"\n aria-label=\"Toggle AM/PM\"\n class=\"rui-time-picker-period cursor-pointer\"\n @click=\"toggleAmPm()\"\n >\n {{ period }}\n </div>\n </div>\n </div>\n </div>\n\n <div\n ref=\"clockFace\"\n role=\"listbox\"\n :aria-label=\"`Select ${editMode}`\"\n :class=\"ui.clockFace()\"\n @mousedown=\"startDrag($event)\"\n @touchstart=\"startDrag($event)\"\n >\n <div\n :class=\"ui.centerDot()\"\n :style=\"dotStyle\"\n />\n\n <div\n :class=\"ui.clockHand()\"\n :style=\"clockHandStyle\"\n />\n\n <div\n v-if=\"displayClockHandCircle\"\n :class=\"ui.clockHandCircle()\"\n :style=\"clockHandCircleStyle\"\n />\n\n <div\n v-for=\"num in clockNumbers\"\n :key=\"`num-${num}`\"\n role=\"option\"\n :aria-selected=\"isSelectedNumber(num)\"\n :class=\"[\n ui.clockNumber({ selected: isSelectedNumber(num) }),\n `rui-${editMode}-${num.toString().padStart(2, '0')}`,\n ]\"\n :style=\"numberStyle(num)\"\n @click=\"selectByClick(num)\"\n >\n {{ num }}\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time-picker-styles.js","names":[],"sources":["../../../src/components/time-picker/time-picker-styles.ts"],"sourcesContent":["import { tv } from '@/utils/tv';\n\nexport const timePickerStyles = tv({\n slots: {\n root: 'bg-white overflow-hidden text-rui-text p-3 dark:bg-rui-grey-900',\n digitalDisplay: 'mb-2 text-center',\n digit: 'text-2xl font-semibold cursor-pointer',\n clockFace: 'relative rounded-full w-64 h-64 mx-auto border border-rui-grey-200 dark:border-rui-grey-800',\n centerDot: 'absolute rounded-full bg-rui-primary w-3 h-3',\n clockHand: 'absolute w-[1.5px] bg-rui-primary rounded-full',\n clockHandCircle: 'absolute border-2 border-rui-primary',\n clockNumber: [\n 'absolute text-center text-sm font-medium w-8 h-8',\n 'flex items-center justify-center',\n 'hover:bg-rui-primary-lighter cursor-pointer rounded-full',\n ].join(' '),\n },\n variants: {\n bordered: {\n true: {\n root: 'rounded-md shadow-sm border border-rui-grey-200 dark:border-rui-grey-800',\n },\n },\n active: {\n true: {\n digit: 'text-rui-primary',\n },\n },\n selected: {\n true: {\n clockNumber: 'bg-rui-primary text-rui-dark-text dark:text-rui-light-text z-10 font-bold',\n },\n },\n },\n});\n"],"mappings":";;AAEA,IAAa,mBAAmB,GAAG;CACjC,OAAO;EACL,MAAM;EACN,gBAAgB;EAChB,OAAO;EACP,WAAW;EACX,WAAW;EACX,WAAW;EACX,iBAAiB;EACjB,aAAa;GACX;GACA;GACA;
|
|
1
|
+
{"version":3,"file":"time-picker-styles.js","names":[],"sources":["../../../src/components/time-picker/time-picker-styles.ts"],"sourcesContent":["import { tv } from '@/utils/tv';\n\nexport const timePickerStyles = tv({\n slots: {\n root: 'bg-white overflow-hidden text-rui-text p-3 dark:bg-rui-grey-900',\n digitalDisplay: 'mb-2 text-center',\n digit: 'text-2xl font-semibold cursor-pointer',\n clockFace: 'relative rounded-full w-64 h-64 mx-auto border border-rui-grey-200 dark:border-rui-grey-800',\n centerDot: 'absolute rounded-full bg-rui-primary w-3 h-3',\n clockHand: 'absolute w-[1.5px] bg-rui-primary rounded-full',\n clockHandCircle: 'absolute border-2 border-rui-primary',\n clockNumber: [\n 'absolute text-center text-sm font-medium w-8 h-8',\n 'flex items-center justify-center',\n 'hover:bg-rui-primary-lighter cursor-pointer rounded-full',\n ].join(' '),\n },\n variants: {\n bordered: {\n true: {\n root: 'rounded-md shadow-sm border border-rui-grey-200 dark:border-rui-grey-800',\n },\n },\n active: {\n true: {\n digit: 'text-rui-primary',\n },\n },\n selected: {\n true: {\n clockNumber: 'bg-rui-primary text-rui-dark-text dark:text-rui-light-text z-10 font-bold',\n },\n },\n },\n});\n"],"mappings":";;AAEA,IAAa,mBAAmB,GAAG;CACjC,OAAO;EACL,MAAM;EACN,gBAAgB;EAChB,OAAO;EACP,WAAW;EACX,WAAW;EACX,WAAW;EACX,iBAAiB;EACjB,aAAa;GACX;GACA;GACA;EACF,CAAC,CAAC,KAAK,GAAG;CACZ;CACA,UAAU;EACR,UAAU,EACR,MAAM,EACJ,MAAM,2EACR,EACF;EACA,QAAQ,EACN,MAAM,EACJ,OAAO,mBACT,EACF;EACA,UAAU,EACR,MAAM,EACJ,aAAa,4EACf,EACF;CACF;AACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"breakpoint.js","names":[],"sources":["../../src/composables/breakpoint.ts"],"sourcesContent":["import type { Ref } from 'vue';\nimport { breakpointsTailwind } from '@vueuse/core';\nimport { camelCase } from 'scule';\nimport { assert } from '@/utils/assert';\n\nexport function useBreakpoint() {\n const { width } = useWindowSize();\n\n const breakpointList = {\n xs: 0,\n ...breakpointsTailwind,\n } as const;\n\n type Breakpoint = keyof typeof breakpointList;\n\n const breakpoints = useBreakpoints(breakpointList);\n\n const getKeys = Object.keys as <T extends object>(obj: T) => Array<keyof T>;\n\n const list = getKeys(breakpointList);\n\n const rawSizes: [Breakpoint, Ref<boolean>][] = list.map((breakpoint, index) => {\n if (index < list.length - 1) {\n const nextBreakpoint = list[index + 1];\n assert(nextBreakpoint);\n return [breakpoint, breakpoints.between(breakpoint, nextBreakpoint)];\n }\n return [breakpoint, breakpoints[breakpoint]];\n });\n\n const sizes = rawSizes.map(([breakpoint, value]) => [camelCase(`is_${breakpoint}`), value]);\n\n const sizesUp = list.map(breakpoint => [\n camelCase(`is_${breakpoint}_and_up`),\n breakpoints.greaterOrEqual(breakpoint),\n ]);\n\n const sizesDown = list.map(breakpoint => [\n camelCase(`is_${breakpoint}_and_down`),\n breakpoints.smaller(breakpoint),\n ]);\n\n const name = computed<string>(() => rawSizes.find(item => get(item[1]))?.[0] || '');\n\n return {\n ...Object.fromEntries(sizes),\n ...Object.fromEntries(sizesUp),\n ...Object.fromEntries(sizesDown),\n name,\n width,\n };\n}\n"],"mappings":";;;;;;AAKA,SAAgB,gBAAgB;CAC9B,MAAM,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"breakpoint.js","names":[],"sources":["../../src/composables/breakpoint.ts"],"sourcesContent":["import type { Ref } from 'vue';\nimport { breakpointsTailwind } from '@vueuse/core';\nimport { camelCase } from 'scule';\nimport { assert } from '@/utils/assert';\n\nexport function useBreakpoint() {\n const { width } = useWindowSize();\n\n const breakpointList = {\n xs: 0,\n ...breakpointsTailwind,\n } as const;\n\n type Breakpoint = keyof typeof breakpointList;\n\n const breakpoints = useBreakpoints(breakpointList);\n\n const getKeys = Object.keys as <T extends object>(obj: T) => Array<keyof T>;\n\n const list = getKeys(breakpointList);\n\n const rawSizes: [Breakpoint, Ref<boolean>][] = list.map((breakpoint, index) => {\n if (index < list.length - 1) {\n const nextBreakpoint = list[index + 1];\n assert(nextBreakpoint);\n return [breakpoint, breakpoints.between(breakpoint, nextBreakpoint)];\n }\n return [breakpoint, breakpoints[breakpoint]];\n });\n\n const sizes = rawSizes.map(([breakpoint, value]) => [camelCase(`is_${breakpoint}`), value]);\n\n const sizesUp = list.map(breakpoint => [\n camelCase(`is_${breakpoint}_and_up`),\n breakpoints.greaterOrEqual(breakpoint),\n ]);\n\n const sizesDown = list.map(breakpoint => [\n camelCase(`is_${breakpoint}_and_down`),\n breakpoints.smaller(breakpoint),\n ]);\n\n const name = computed<string>(() => rawSizes.find(item => get(item[1]))?.[0] || '');\n\n return {\n ...Object.fromEntries(sizes),\n ...Object.fromEntries(sizesUp),\n ...Object.fromEntries(sizesDown),\n name,\n width,\n };\n}\n"],"mappings":";;;;;;AAKA,SAAgB,gBAAgB;CAC9B,MAAM,EAAE,UAAU,cAAc;CAEhC,MAAM,iBAAiB;EACrB,IAAI;EACJ,GAAG;CACL;CAIA,MAAM,cAAc,eAAe,cAAc;CAEjD,MAAM,UAAU,OAAO;CAEvB,MAAM,OAAO,QAAQ,cAAc;CAEnC,MAAM,WAAyC,KAAK,KAAK,YAAY,UAAU;EAC7E,IAAI,QAAQ,KAAK,SAAS,GAAG;GAC3B,MAAM,iBAAiB,KAAK,QAAQ;GACpC,OAAO,cAAc;GACrB,OAAO,CAAC,YAAY,YAAY,QAAQ,YAAY,cAAc,CAAC;EACrE;EACA,OAAO,CAAC,YAAY,YAAY,WAAW;CAC7C,CAAC;CAED,MAAM,QAAQ,SAAS,KAAK,CAAC,YAAY,WAAW,CAAC,UAAU,MAAM,YAAY,GAAG,KAAK,CAAC;CAE1F,MAAM,UAAU,KAAK,KAAI,eAAc,CACrC,UAAU,MAAM,WAAW,QAAQ,GACnC,YAAY,eAAe,UAAU,CACvC,CAAC;CAED,MAAM,YAAY,KAAK,KAAI,eAAc,CACvC,UAAU,MAAM,WAAW,UAAU,GACrC,YAAY,QAAQ,UAAU,CAChC,CAAC;CAED,MAAM,OAAO,eAAuB,SAAS,MAAK,SAAQ,MAAI,KAAK,EAAE,CAAC,CAAC,GAAG,MAAM,EAAE;CAElF,OAAO;EACL,GAAG,OAAO,YAAY,KAAK;EAC3B,GAAG,OAAO,YAAY,OAAO;EAC7B,GAAG,OAAO,YAAY,SAAS;EAC/B;EACA;CACF;AACF"}
|
|
@@ -4,6 +4,18 @@ export interface TableOptions {
|
|
|
4
4
|
globalItemsPerPage: MaybeRef<boolean>;
|
|
5
5
|
limits: MaybeRef<number[]>;
|
|
6
6
|
stickyOffset: MaybeRef<number>;
|
|
7
|
+
/**
|
|
8
|
+
* Global default width (px) below which every table switches to its stacked
|
|
9
|
+
* mobile card layout. A table's own `mobileBreakpoint` prop overrides this.
|
|
10
|
+
* Leave unset to keep the mobile layout opt-in per table.
|
|
11
|
+
*/
|
|
12
|
+
mobileBreakpoint?: MaybeRef<number>;
|
|
13
|
+
/**
|
|
14
|
+
* Whether the mobile breakpoint is measured against the browser viewport
|
|
15
|
+
* (`viewport`, default) or each table's own container width (`container`).
|
|
16
|
+
* A table's own `mobileBreakpointBasis` prop overrides this.
|
|
17
|
+
*/
|
|
18
|
+
mobileBreakpointBasis?: MaybeRef<'viewport' | 'container'>;
|
|
7
19
|
}
|
|
8
20
|
export declare const TableSymbol: InjectionKey<TableOptions>;
|
|
9
21
|
export declare function createTableDefaults(options?: Partial<TableOptions>): TableOptions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.js","names":[],"sources":["../../../src/composables/defaults/table.ts"],"sourcesContent":["import type { InjectionKey, MaybeRef, Ref } from 'vue';\n\nexport interface TableOptions {\n itemsPerPage: Ref<number>;\n globalItemsPerPage: MaybeRef<boolean>;\n limits: MaybeRef<number[]>;\n stickyOffset: MaybeRef<number>;\n}\n\nexport const TableSymbol: InjectionKey<TableOptions> = Symbol.for('rui:table');\n\nexport function createTableDefaults(options?: Partial<TableOptions>): TableOptions {\n return {\n globalItemsPerPage: false,\n itemsPerPage: ref(10),\n limits: [10, 25, 50, 100],\n stickyOffset: ref(0),\n ...options,\n };\n}\n\nexport function useTable() {\n const options = inject(TableSymbol);\n\n if (!options)\n throw new Error('Could not find rui table options injection');\n\n return options;\n}\n"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"table.js","names":[],"sources":["../../../src/composables/defaults/table.ts"],"sourcesContent":["import type { InjectionKey, MaybeRef, Ref } from 'vue';\n\nexport interface TableOptions {\n itemsPerPage: Ref<number>;\n globalItemsPerPage: MaybeRef<boolean>;\n limits: MaybeRef<number[]>;\n stickyOffset: MaybeRef<number>;\n /**\n * Global default width (px) below which every table switches to its stacked\n * mobile card layout. A table's own `mobileBreakpoint` prop overrides this.\n * Leave unset to keep the mobile layout opt-in per table.\n */\n mobileBreakpoint?: MaybeRef<number>;\n /**\n * Whether the mobile breakpoint is measured against the browser viewport\n * (`viewport`, default) or each table's own container width (`container`).\n * A table's own `mobileBreakpointBasis` prop overrides this.\n */\n mobileBreakpointBasis?: MaybeRef<'viewport' | 'container'>;\n}\n\nexport const TableSymbol: InjectionKey<TableOptions> = Symbol.for('rui:table');\n\nexport function createTableDefaults(options?: Partial<TableOptions>): TableOptions {\n return {\n globalItemsPerPage: false,\n itemsPerPage: ref(10),\n limits: [10, 25, 50, 100],\n stickyOffset: ref(0),\n ...options,\n };\n}\n\nexport function useTable() {\n const options = inject(TableSymbol);\n\n if (!options)\n throw new Error('Could not find rui table options injection');\n\n return options;\n}\n"],"mappings":";;AAqBA,IAAa,cAA0C,OAAO,IAAI,WAAW;AAE7E,SAAgB,oBAAoB,SAA+C;CACjF,OAAO;EACL,oBAAoB;EACpB,cAAc,IAAI,EAAE;EACpB,QAAQ;GAAC;GAAI;GAAI;GAAI;EAAG;EACxB,cAAc,IAAI,CAAC;EACnB,GAAG;CACL;AACF;AAEA,SAAgB,WAAW;CACzB,MAAM,UAAU,OAAO,WAAW;CAElC,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,4CAA4C;CAE9D,OAAO;AACT"}
|
|
@@ -6,6 +6,12 @@ export interface DropdownItemAttr<TValue, TItem> {
|
|
|
6
6
|
keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;
|
|
7
7
|
textAttr?: keyof TItem | ((item: TItem) => string);
|
|
8
8
|
}
|
|
9
|
+
export type GroupBy<TItem> = keyof TItem | ((item: TItem) => string);
|
|
10
|
+
export type ItemDisabled<TItem> = keyof TItem | ((item: TItem) => boolean);
|
|
11
|
+
export interface DropdownOptionGroup<TItem> {
|
|
12
|
+
group: string;
|
|
13
|
+
items: TItem[];
|
|
14
|
+
}
|
|
9
15
|
export interface DropdownOptions<TValue, TItem> {
|
|
10
16
|
options: MaybeRefOrGetter<TItem[]>;
|
|
11
17
|
dense?: MaybeRefOrGetter<boolean>;
|
|
@@ -24,12 +30,14 @@ export interface DropdownOptions<TValue, TItem> {
|
|
|
24
30
|
isOpen?: Ref<boolean>;
|
|
25
31
|
getText?: (item: TItem) => string | undefined;
|
|
26
32
|
getIdentifier?: (item: TItem) => any;
|
|
33
|
+
groupBy?: MaybeRefOrGetter<GroupBy<TItem> | undefined>;
|
|
34
|
+
itemDisabled?: MaybeRefOrGetter<ItemDisabled<TItem> | undefined>;
|
|
27
35
|
}
|
|
28
36
|
export declare function useDropdownOptionProperty<TValue, TItem>({ keyAttr, textAttr, }: DropdownItemAttr<TValue, TItem>): {
|
|
29
37
|
getIdentifier: (item: TItem) => TItem | TItem[KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>];
|
|
30
38
|
getText: (item: TItem) => string | undefined;
|
|
31
39
|
};
|
|
32
|
-
export declare function useDropdownMenu<TValue, TItem>({ appendWidth, autoSelectFirst, dense, disabled, getIdentifier: externalGetIdentifier, getText: externalGetText, hideSelected, isOpen: externalIsOpen, itemHeight, keyAttr, menuRef: _menuRef, options: allOptions, overscan, prependWidth, setValue, textAttr, value, }: DropdownOptions<TValue, TItem>): {
|
|
40
|
+
export declare function useDropdownMenu<TValue, TItem>({ appendWidth, autoSelectFirst, dense, disabled, getIdentifier: externalGetIdentifier, getText: externalGetText, hideSelected, isOpen: externalIsOpen, itemHeight, keyAttr, menuRef: _menuRef, options: allOptions, overscan, prependWidth, setValue, textAttr, value, groupBy, itemDisabled, }: DropdownOptions<TValue, TItem>): {
|
|
33
41
|
applyHighlighted: () => void;
|
|
34
42
|
containerProps: {
|
|
35
43
|
ref: Ref<HTMLElement | null>;
|
|
@@ -38,8 +46,11 @@ export declare function useDropdownMenu<TValue, TItem>({ appendWidth, autoSelect
|
|
|
38
46
|
};
|
|
39
47
|
getIdentifier: (item: TItem) => any;
|
|
40
48
|
getText: (item: TItem) => string | undefined;
|
|
49
|
+
groupedOptions: globalThis.ComputedRef<DropdownOptionGroup<TItem>[]>;
|
|
41
50
|
highlightedIndex: Ref<number, number>;
|
|
42
51
|
isActiveItem: (item: TItem) => boolean;
|
|
52
|
+
isGrouped: globalThis.ComputedRef<boolean>;
|
|
53
|
+
isItemDisabled: (item: TItem) => boolean;
|
|
43
54
|
isOpen: Ref<boolean, boolean>;
|
|
44
55
|
itemIndexInValue: (item: TItem) => number;
|
|
45
56
|
menuWidth: globalThis.ComputedRef<string>;
|
|
@@ -22,7 +22,7 @@ function toSelectedArray(val) {
|
|
|
22
22
|
if (val !== null && val !== void 0) return [val];
|
|
23
23
|
return [];
|
|
24
24
|
}
|
|
25
|
-
function useDropdownMenu({ appendWidth, autoSelectFirst, dense, disabled = false, getIdentifier: externalGetIdentifier, getText: externalGetText, hideSelected, isOpen: externalIsOpen, itemHeight = 48, keyAttr, menuRef: _menuRef, options: allOptions, overscan = 5, prependWidth, setValue, textAttr, value }) {
|
|
25
|
+
function useDropdownMenu({ appendWidth, autoSelectFirst, dense, disabled = false, getIdentifier: externalGetIdentifier, getText: externalGetText, hideSelected, isOpen: externalIsOpen, itemHeight = 48, keyAttr, menuRef: _menuRef, options: allOptions, overscan = 5, prependWidth, setValue, textAttr, value, groupBy, itemDisabled }) {
|
|
26
26
|
const { getIdentifier: defaultGetIdentifier, getText: defaultGetText } = useDropdownOptionProperty({
|
|
27
27
|
keyAttr,
|
|
28
28
|
textAttr
|
|
@@ -43,6 +43,33 @@ function useDropdownMenu({ appendWidth, autoSelectFirst, dense, disabled = false
|
|
|
43
43
|
if (!hideSelected) return options;
|
|
44
44
|
return options.filter((item) => !isActiveItem(item));
|
|
45
45
|
});
|
|
46
|
+
function getGroupKey(item) {
|
|
47
|
+
const group = toValue(groupBy);
|
|
48
|
+
if (!group) return "";
|
|
49
|
+
if (typeof group === "function") return group(item);
|
|
50
|
+
return String(item[group] ?? "");
|
|
51
|
+
}
|
|
52
|
+
function isItemDisabled(item) {
|
|
53
|
+
const itemDisabledValue = toValue(itemDisabled);
|
|
54
|
+
if (!itemDisabledValue) return false;
|
|
55
|
+
if (typeof itemDisabledValue === "function") return itemDisabledValue(item);
|
|
56
|
+
return Boolean(item[itemDisabledValue]);
|
|
57
|
+
}
|
|
58
|
+
const isGrouped = computed(() => toValue(groupBy) !== void 0);
|
|
59
|
+
const groupedOptions = computed(() => {
|
|
60
|
+
if (!get$1(isGrouped)) return [];
|
|
61
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
62
|
+
for (const item of get$1(options)) {
|
|
63
|
+
const key = getGroupKey(item);
|
|
64
|
+
const list = buckets.get(key);
|
|
65
|
+
if (list) list.push(item);
|
|
66
|
+
else buckets.set(key, [item]);
|
|
67
|
+
}
|
|
68
|
+
return Array.from(buckets.entries()).map(([group, items]) => ({
|
|
69
|
+
group,
|
|
70
|
+
items
|
|
71
|
+
}));
|
|
72
|
+
});
|
|
46
73
|
const { containerProps, list, scrollTo, wrapperProps } = useVirtualList(options, {
|
|
47
74
|
itemHeight,
|
|
48
75
|
overscan
|
|
@@ -147,27 +174,39 @@ function useDropdownMenu({ appendWidth, autoSelectFirst, dense, disabled = false
|
|
|
147
174
|
return;
|
|
148
175
|
}
|
|
149
176
|
set$1(userNavigated, true);
|
|
177
|
+
const items = get$1(options);
|
|
178
|
+
const total = items.length;
|
|
179
|
+
if (total === 0) return;
|
|
180
|
+
const move = up ? -1 : 1;
|
|
150
181
|
let position = get$1(highlightedIndex);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
182
|
+
for (let step = 0; step < total; step++) {
|
|
183
|
+
position += move;
|
|
184
|
+
if (position >= total) position = 0;
|
|
185
|
+
else if (position < 0) position = total - 1;
|
|
186
|
+
const candidate = items[position];
|
|
187
|
+
if (candidate !== void 0 && !isItemDisabled(candidate)) {
|
|
188
|
+
set$1(highlightedIndex, position);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
156
192
|
};
|
|
157
193
|
const applyHighlighted = () => {
|
|
158
194
|
if (!setValue || !get$1(isOpen)) return;
|
|
159
195
|
const highlightedIndexVal = get$1(highlightedIndex);
|
|
160
196
|
if (highlightedIndexVal === -1) return;
|
|
161
197
|
const entry = get$1(options)[highlightedIndexVal];
|
|
162
|
-
if (entry !== void 0) setValue(entry);
|
|
198
|
+
if (entry !== void 0 && !isItemDisabled(entry)) setValue(entry);
|
|
163
199
|
};
|
|
164
200
|
return {
|
|
165
201
|
applyHighlighted,
|
|
166
202
|
containerProps,
|
|
167
203
|
getIdentifier,
|
|
168
204
|
getText,
|
|
205
|
+
groupedOptions,
|
|
169
206
|
highlightedIndex,
|
|
170
207
|
isActiveItem,
|
|
208
|
+
isGrouped,
|
|
209
|
+
isItemDisabled,
|
|
171
210
|
isOpen,
|
|
172
211
|
itemIndexInValue,
|
|
173
212
|
menuWidth,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown-menu.js","names":[],"sources":["../../src/composables/dropdown-menu.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\n\nexport type KeyOfType<T, V> = T extends string | number | boolean | symbol | null | undefined\n ? never\n : V extends object\n ? keyof T\n : keyof {\n [P in keyof T as T[P] extends V ? P : V extends T[P] ? P : never]: any;\n };\n\nexport interface DropdownItemAttr<TValue, TItem> {\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem | ((item: TItem) => string);\n}\n\nexport interface DropdownOptions<TValue, TItem> {\n options: MaybeRefOrGetter<TItem[]>;\n dense?: MaybeRefOrGetter<boolean>;\n disabled?: MaybeRefOrGetter<boolean>;\n value: Ref<TItem | TItem[] | undefined>;\n menuRef: Ref<HTMLElement> | TemplateRef<HTMLElement>;\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem | ((item: TItem) => string);\n appendWidth?: number;\n prependWidth?: number;\n itemHeight?: number;\n overscan?: number;\n autoSelectFirst?: boolean;\n setValue?: (val: TItem) => void;\n hideSelected?: boolean;\n isOpen?: Ref<boolean>;\n getText?: (item: TItem) => string | undefined;\n getIdentifier?: (item: TItem) => any;\n}\n\nexport function useDropdownOptionProperty<TValue, TItem>({\n keyAttr,\n textAttr,\n}: DropdownItemAttr<TValue, TItem>) {\n function getText(item: TItem): string | undefined {\n if (textAttr) {\n if (typeof textAttr === 'function')\n return textAttr(item);\n else return item[textAttr]?.toString();\n }\n\n return item?.toString();\n }\n\n function getIdentifier(\n item: TItem,\n ): TItem | TItem[KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>] {\n if (keyAttr)\n return item[keyAttr];\n\n return item;\n }\n\n return {\n getIdentifier,\n getText,\n };\n}\n\nfunction toSelectedArray<TItem>(val: TItem | TItem[] | undefined): TItem[] {\n if (Array.isArray(val))\n return val;\n if (val !== null && val !== undefined)\n return [val];\n return [];\n}\n\nexport function useDropdownMenu<TValue, TItem>({\n appendWidth,\n autoSelectFirst,\n dense,\n disabled = false,\n getIdentifier: externalGetIdentifier,\n getText: externalGetText,\n hideSelected,\n isOpen: externalIsOpen,\n itemHeight = 48,\n keyAttr,\n menuRef: _menuRef,\n options: allOptions,\n overscan = 5,\n prependWidth,\n setValue,\n textAttr,\n value,\n}: DropdownOptions<TValue, TItem>) {\n const { getIdentifier: defaultGetIdentifier, getText: defaultGetText } = useDropdownOptionProperty({\n keyAttr,\n textAttr,\n });\n\n const getIdentifier = externalGetIdentifier ?? defaultGetIdentifier;\n const getText = externalGetText ?? defaultGetText;\n\n const activeIdentifiers = computed<Set<any>>(() => {\n const val = get(value);\n const selected: TItem[] = toSelectedArray(val);\n const identifiers = new Set<any>();\n for (const item of selected) {\n identifiers.add(getIdentifier(item));\n }\n return identifiers;\n });\n\n function isActiveItem(item: TItem): boolean {\n return get(activeIdentifiers).has(getIdentifier(item));\n }\n\n const options = computed<TItem[]>(() => {\n const options = toValue(allOptions);\n if (!hideSelected)\n return options;\n\n return options.filter(item => !isActiveItem(item));\n });\n\n const { containerProps, list, scrollTo, wrapperProps } = useVirtualList<TItem>(options, {\n itemHeight,\n overscan,\n });\n\n const renderedData = useArrayMap(list, ({ data, index: _index }) => ({ _index, item: data }));\n\n const isOpen = externalIsOpen ?? shallowRef<boolean>(false);\n\n const valueKey = computed(() => {\n const selected = get(value);\n if (!keyAttr || !selected)\n return selected;\n return Array.isArray(selected) ? selected.map(item => item[keyAttr]) : selected[keyAttr];\n });\n\n const highlightedIndex: Ref<number> = ref(get(autoSelectFirst) ? 0 : -1);\n const userNavigated = shallowRef<boolean>(false);\n\n const optionWidthBounds = computed<{ min: number; max: number }>(() => {\n let min = 0;\n let max = 0;\n for (const option of get(options)) {\n const length = getText(option)?.toString()?.length ?? 0;\n if (min === 0 && max === 0) {\n min = length;\n max = length;\n }\n else if (length < min) {\n min = length;\n }\n else if (length > max) {\n max = length;\n }\n }\n return { min, max };\n });\n\n const menuWidth = computed<string>(() => {\n const { min, max } = get(optionWidthBounds);\n const maxWidth = 30;\n const paddingX = 1.5;\n const fontMultiplier = toValue(dense) ? 12 : 13;\n const difference = max - min;\n\n function computeValue(width: number): string {\n const additionalWidths =\n (prependWidth ? prependWidth + 0.5 : 0) + (appendWidth ? appendWidth + 0.5 : 0);\n return `${Math.min((width * fontMultiplier) / 16 + paddingX + additionalWidths, maxWidth)}rem`;\n }\n\n if (difference <= 5)\n return computeValue(max);\n\n return computeValue(min + difference / 2);\n });\n\n function toggle(state: boolean = false): void {\n set(isOpen, state);\n }\n\n function itemIndexInValue(item: TItem): number {\n const val = get(value);\n const selected: TItem[] = toSelectedArray(val);\n\n if (selected.length === 0)\n return -1;\n\n const itemId = getIdentifier(item);\n return selected.findIndex(selectedItem => getIdentifier(selectedItem) === itemId);\n }\n\n function scrollHighlightedIntoView(): void {\n get(_menuRef)\n ?.querySelector<HTMLElement>('[data-highlighted=\"true\"]')\n ?.scrollIntoView({ block: 'nearest' });\n }\n\n async function adjustScrollByHighlightedIndex(): Promise<void> {\n const index = get(highlightedIndex);\n if (index === -1)\n return;\n\n await nextTick();\n if (get(_menuRef)?.querySelector('[data-highlighted=\"true\"]')) {\n scrollHighlightedIntoView();\n return;\n }\n\n // Highlighted item is outside the virtual list's rendered window —\n // kick the virtual scroll to render it, then nudge it fully into view.\n scrollTo(index);\n await nextTick();\n scrollHighlightedIntoView();\n }\n\n async function updateOpen(open: boolean): Promise<void> {\n if (!open)\n return;\n\n const val = get(value);\n\n // Set highlighted index to active item\n if ((Array.isArray(val) && val.length > 0) || (val !== null && val !== undefined)) {\n const index = get(options).findIndex(isActiveItem);\n if (index > -1)\n set(highlightedIndex, index);\n }\n\n await adjustScrollByHighlightedIndex();\n }\n\n watch([isOpen, () => toValue(disabled)], async ([open, _]) => {\n await updateOpen(open);\n });\n\n watch(highlightedIndex, async () => {\n await adjustScrollByHighlightedIndex();\n });\n\n watch(options, async () => {\n set(userNavigated, false);\n if (get(highlightedIndex) !== -1) {\n if (get(autoSelectFirst)) {\n set(highlightedIndex, 0);\n await adjustScrollByHighlightedIndex();\n }\n else {\n set(highlightedIndex, -1);\n scrollTo(0);\n }\n }\n else {\n scrollTo(0);\n }\n });\n\n watch(isOpen, (open) => {\n if (!open)\n set(userNavigated, false);\n });\n\n const moveHighlight = (up: boolean): void => {\n if (!get(isOpen)) {\n toggle(true);\n return;\n }\n\n set(userNavigated, true);\n\n let position = get(highlightedIndex);\n const move = up ? -1 : 1;\n\n position += move;\n\n const total = get(options).length;\n\n if (position >= total)\n set(highlightedIndex, 0);\n else if (position < 0)\n set(highlightedIndex, total - 1);\n else set(highlightedIndex, position);\n };\n\n const applyHighlighted = (): void => {\n if (!setValue || !get(isOpen))\n return;\n\n const highlightedIndexVal = get(highlightedIndex);\n if (highlightedIndexVal === -1)\n return;\n\n const entry = get(options)[highlightedIndexVal];\n if (entry !== undefined)\n setValue(entry);\n };\n\n return {\n applyHighlighted,\n containerProps,\n getIdentifier,\n getText,\n highlightedIndex,\n isActiveItem,\n isOpen,\n itemIndexInValue,\n menuWidth,\n moveHighlight,\n optionsWithSelectedHidden: options,\n renderedData,\n toggle,\n userNavigated,\n valueKey,\n wrapperProps,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dropdown-menu.js","names":[],"sources":["../../src/composables/dropdown-menu.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\n\nexport type KeyOfType<T, V> = T extends string | number | boolean | symbol | null | undefined\n ? never\n : V extends object\n ? keyof T\n : keyof {\n [P in keyof T as T[P] extends V ? P : V extends T[P] ? P : never]: any;\n };\n\nexport interface DropdownItemAttr<TValue, TItem> {\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem | ((item: TItem) => string);\n}\n\nexport type GroupBy<TItem> = keyof TItem | ((item: TItem) => string);\n\nexport type ItemDisabled<TItem> = keyof TItem | ((item: TItem) => boolean);\n\nexport interface DropdownOptionGroup<TItem> {\n group: string;\n items: TItem[];\n}\n\nexport interface DropdownOptions<TValue, TItem> {\n options: MaybeRefOrGetter<TItem[]>;\n dense?: MaybeRefOrGetter<boolean>;\n disabled?: MaybeRefOrGetter<boolean>;\n value: Ref<TItem | TItem[] | undefined>;\n menuRef: Ref<HTMLElement> | TemplateRef<HTMLElement>;\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem | ((item: TItem) => string);\n appendWidth?: number;\n prependWidth?: number;\n itemHeight?: number;\n overscan?: number;\n autoSelectFirst?: boolean;\n setValue?: (val: TItem) => void;\n hideSelected?: boolean;\n isOpen?: Ref<boolean>;\n getText?: (item: TItem) => string | undefined;\n getIdentifier?: (item: TItem) => any;\n groupBy?: MaybeRefOrGetter<GroupBy<TItem> | undefined>;\n itemDisabled?: MaybeRefOrGetter<ItemDisabled<TItem> | undefined>;\n}\n\nexport function useDropdownOptionProperty<TValue, TItem>({\n keyAttr,\n textAttr,\n}: DropdownItemAttr<TValue, TItem>) {\n function getText(item: TItem): string | undefined {\n if (textAttr) {\n if (typeof textAttr === 'function')\n return textAttr(item);\n else return item[textAttr]?.toString();\n }\n\n return item?.toString();\n }\n\n function getIdentifier(\n item: TItem,\n ): TItem | TItem[KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>] {\n if (keyAttr)\n return item[keyAttr];\n\n return item;\n }\n\n return {\n getIdentifier,\n getText,\n };\n}\n\nfunction toSelectedArray<TItem>(val: TItem | TItem[] | undefined): TItem[] {\n if (Array.isArray(val))\n return val;\n if (val !== null && val !== undefined)\n return [val];\n return [];\n}\n\nexport function useDropdownMenu<TValue, TItem>({\n appendWidth,\n autoSelectFirst,\n dense,\n disabled = false,\n getIdentifier: externalGetIdentifier,\n getText: externalGetText,\n hideSelected,\n isOpen: externalIsOpen,\n itemHeight = 48,\n keyAttr,\n menuRef: _menuRef,\n options: allOptions,\n overscan = 5,\n prependWidth,\n setValue,\n textAttr,\n value,\n groupBy,\n itemDisabled,\n}: DropdownOptions<TValue, TItem>) {\n const { getIdentifier: defaultGetIdentifier, getText: defaultGetText } = useDropdownOptionProperty({\n keyAttr,\n textAttr,\n });\n\n const getIdentifier = externalGetIdentifier ?? defaultGetIdentifier;\n const getText = externalGetText ?? defaultGetText;\n\n const activeIdentifiers = computed<Set<any>>(() => {\n const val = get(value);\n const selected: TItem[] = toSelectedArray(val);\n const identifiers = new Set<any>();\n for (const item of selected) {\n identifiers.add(getIdentifier(item));\n }\n return identifiers;\n });\n\n function isActiveItem(item: TItem): boolean {\n return get(activeIdentifiers).has(getIdentifier(item));\n }\n\n const options = computed<TItem[]>(() => {\n const options = toValue(allOptions);\n if (!hideSelected)\n return options;\n\n return options.filter(item => !isActiveItem(item));\n });\n\n function getGroupKey(item: TItem): string {\n const group = toValue(groupBy);\n if (!group)\n return '';\n\n if (typeof group === 'function')\n return group(item);\n\n return String(item[group] ?? '');\n }\n\n function isItemDisabled(item: TItem): boolean {\n const itemDisabledValue = toValue(itemDisabled);\n if (!itemDisabledValue)\n return false;\n\n if (typeof itemDisabledValue === 'function')\n return itemDisabledValue(item);\n\n return Boolean(item[itemDisabledValue]);\n }\n\n const isGrouped = computed<boolean>(() => toValue(groupBy) !== undefined);\n\n const groupedOptions = computed<DropdownOptionGroup<TItem>[]>(() => {\n if (!get(isGrouped))\n return [];\n\n const buckets = new Map<string, TItem[]>();\n for (const item of get(options)) {\n const key = getGroupKey(item);\n const list = buckets.get(key);\n if (list)\n list.push(item);\n else\n buckets.set(key, [item]);\n }\n\n return Array.from(buckets.entries()).map(([group, items]) => ({ group, items }));\n });\n\n const { containerProps, list, scrollTo, wrapperProps } = useVirtualList<TItem>(options, {\n itemHeight,\n overscan,\n });\n\n const renderedData = useArrayMap(list, ({ data, index: _index }) => ({ _index, item: data }));\n\n const isOpen = externalIsOpen ?? shallowRef<boolean>(false);\n\n const valueKey = computed(() => {\n const selected = get(value);\n if (!keyAttr || !selected)\n return selected;\n return Array.isArray(selected) ? selected.map(item => item[keyAttr]) : selected[keyAttr];\n });\n\n const highlightedIndex: Ref<number> = ref(get(autoSelectFirst) ? 0 : -1);\n const userNavigated = shallowRef<boolean>(false);\n\n const optionWidthBounds = computed<{ min: number; max: number }>(() => {\n let min = 0;\n let max = 0;\n for (const option of get(options)) {\n const length = getText(option)?.toString()?.length ?? 0;\n if (min === 0 && max === 0) {\n min = length;\n max = length;\n }\n else if (length < min) {\n min = length;\n }\n else if (length > max) {\n max = length;\n }\n }\n return { min, max };\n });\n\n const menuWidth = computed<string>(() => {\n const { min, max } = get(optionWidthBounds);\n const maxWidth = 30;\n const paddingX = 1.5;\n const fontMultiplier = toValue(dense) ? 12 : 13;\n const difference = max - min;\n\n function computeValue(width: number): string {\n const additionalWidths =\n (prependWidth ? prependWidth + 0.5 : 0) + (appendWidth ? appendWidth + 0.5 : 0);\n return `${Math.min((width * fontMultiplier) / 16 + paddingX + additionalWidths, maxWidth)}rem`;\n }\n\n if (difference <= 5)\n return computeValue(max);\n\n return computeValue(min + difference / 2);\n });\n\n function toggle(state: boolean = false): void {\n set(isOpen, state);\n }\n\n function itemIndexInValue(item: TItem): number {\n const val = get(value);\n const selected: TItem[] = toSelectedArray(val);\n\n if (selected.length === 0)\n return -1;\n\n const itemId = getIdentifier(item);\n return selected.findIndex(selectedItem => getIdentifier(selectedItem) === itemId);\n }\n\n function scrollHighlightedIntoView(): void {\n get(_menuRef)\n ?.querySelector<HTMLElement>('[data-highlighted=\"true\"]')\n ?.scrollIntoView({ block: 'nearest' });\n }\n\n async function adjustScrollByHighlightedIndex(): Promise<void> {\n const index = get(highlightedIndex);\n if (index === -1)\n return;\n\n await nextTick();\n if (get(_menuRef)?.querySelector('[data-highlighted=\"true\"]')) {\n scrollHighlightedIntoView();\n return;\n }\n\n // Highlighted item is outside the virtual list's rendered window —\n // kick the virtual scroll to render it, then nudge it fully into view.\n scrollTo(index);\n await nextTick();\n scrollHighlightedIntoView();\n }\n\n async function updateOpen(open: boolean): Promise<void> {\n if (!open)\n return;\n\n const val = get(value);\n\n // Set highlighted index to active item\n if ((Array.isArray(val) && val.length > 0) || (val !== null && val !== undefined)) {\n const index = get(options).findIndex(isActiveItem);\n if (index > -1)\n set(highlightedIndex, index);\n }\n\n await adjustScrollByHighlightedIndex();\n }\n\n watch([isOpen, () => toValue(disabled)], async ([open, _]) => {\n await updateOpen(open);\n });\n\n watch(highlightedIndex, async () => {\n await adjustScrollByHighlightedIndex();\n });\n\n watch(options, async () => {\n set(userNavigated, false);\n if (get(highlightedIndex) !== -1) {\n if (get(autoSelectFirst)) {\n set(highlightedIndex, 0);\n await adjustScrollByHighlightedIndex();\n }\n else {\n set(highlightedIndex, -1);\n scrollTo(0);\n }\n }\n else {\n scrollTo(0);\n }\n });\n\n watch(isOpen, (open) => {\n if (!open)\n set(userNavigated, false);\n });\n\n const moveHighlight = (up: boolean): void => {\n if (!get(isOpen)) {\n toggle(true);\n return;\n }\n\n set(userNavigated, true);\n\n const items = get(options);\n const total = items.length;\n if (total === 0)\n return;\n\n const move = up ? -1 : 1;\n let position = get(highlightedIndex);\n\n for (let step = 0; step < total; step++) {\n position += move;\n if (position >= total)\n position = 0;\n else if (position < 0)\n position = total - 1;\n\n const candidate = items[position];\n if (candidate !== undefined && !isItemDisabled(candidate)) {\n set(highlightedIndex, position);\n return;\n }\n }\n };\n\n const applyHighlighted = (): void => {\n if (!setValue || !get(isOpen))\n return;\n\n const highlightedIndexVal = get(highlightedIndex);\n if (highlightedIndexVal === -1)\n return;\n\n const entry = get(options)[highlightedIndexVal];\n if (entry !== undefined && !isItemDisabled(entry))\n setValue(entry);\n };\n\n return {\n applyHighlighted,\n containerProps,\n getIdentifier,\n getText,\n groupedOptions,\n highlightedIndex,\n isActiveItem,\n isGrouped,\n isItemDisabled,\n isOpen,\n itemIndexInValue,\n menuWidth,\n moveHighlight,\n optionsWithSelectedHidden: options,\n renderedData,\n toggle,\n userNavigated,\n valueKey,\n wrapperProps,\n };\n}\n"],"mappings":"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"}
|
|
@@ -162,6 +162,6 @@ function useFloating(options, disabled = false, openDelay = 0, closeDelay = 0, v
|
|
|
162
162
|
};
|
|
163
163
|
}
|
|
164
164
|
//#endregion
|
|
165
|
-
export { Placement, Strategy, useFloating };
|
|
165
|
+
export { DEFAULT_FLOATING_OPTIONS, Placement, Strategy, useFloating };
|
|
166
166
|
|
|
167
167
|
//# sourceMappingURL=floating.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floating.js","names":[],"sources":["../../src/composables/floating.ts"],"sourcesContent":["import {\n arrow,\n autoUpdate,\n computePosition,\n type ComputePositionReturn,\n flip,\n type VirtualElement as FloatingVirtualElement,\n type Middleware,\n offset,\n shift,\n} from '@floating-ui/dom';\nimport { type MaybeElement, unrefElement } from '@vueuse/core';\nimport { type MaybeRefOrGetter, onMounted, type Ref, ref, watchEffect } from 'vue';\nimport { useTimeoutManager } from './timeout-manager';\n\ntype VirtualElement = FloatingVirtualElement;\n\nexport const Placement = {\n bottom: 'bottom',\n bottomEnd: 'bottom-end',\n bottomStart: 'bottom-start',\n left: 'left',\n leftEnd: 'left-end',\n leftStart: 'left-start',\n right: 'right',\n rightEnd: 'right-end',\n rightStart: 'right-start',\n top: 'top',\n topEnd: 'top-end',\n topStart: 'top-start',\n} as const;\n\nexport type Placement = (typeof Placement)[keyof typeof Placement];\n\nexport const Strategy = {\n absolute: 'absolute',\n fixed: 'fixed',\n} as const;\n\nexport type Strategy = (typeof Strategy)[keyof typeof Strategy];\n\nexport interface FloatingOptions {\n /** Preferred placement relative to the reference element. @default Placement.bottom */\n placement?: Placement;\n /** CSS positioning strategy. @default Strategy.absolute */\n strategy?: Strategy;\n /** Main-axis and/or cross-axis offset from the reference element. @default 2 */\n offset?: number | { mainAxis?: number; crossAxis?: number };\n /** Whether to flip to the opposite side when overflowing. @default true */\n flip?: boolean;\n /** Padding from viewport edges for shift middleware. @default 8 */\n shiftPadding?: number;\n /** Whether to auto-update position on scroll/resize. @default true */\n autoUpdate?: boolean | { scroll?: boolean; resize?: boolean };\n}\n\nexport const DEFAULT_FLOATING_OPTIONS: Required<FloatingOptions> = {\n autoUpdate: true,\n flip: true,\n offset: 2,\n placement: Placement.bottom,\n shiftPadding: 8,\n strategy: Strategy.absolute,\n};\n\nexport interface UseFloatingReturn {\n currentPlacement: Readonly<Ref<Placement>>;\n leavePending: Ref<boolean>;\n onClose: (immediate?: boolean) => void;\n onLeaveComplete: () => void;\n onLeavePending: () => void;\n onOpen: (immediate?: boolean) => void;\n open: Ref<boolean>;\n popover: Ref<MaybeElement>;\n reference: Ref<HTMLElement | undefined>;\n updatePosition: () => Promise<void>;\n visible: Ref<boolean>;\n}\n\nfunction buildMiddleware(opts: FloatingOptions, arrowEl: HTMLElement | null): Middleware[] {\n const mw: Middleware[] = [];\n\n const off = opts.offset ?? DEFAULT_FLOATING_OPTIONS.offset;\n if (typeof off === 'number') {\n mw.push(offset(off));\n }\n else {\n const defaultOffset = typeof DEFAULT_FLOATING_OPTIONS.offset === 'number' ? DEFAULT_FLOATING_OPTIONS.offset : 0;\n mw.push(offset({ mainAxis: off.mainAxis ?? defaultOffset, crossAxis: off.crossAxis ?? 0 }));\n }\n\n if (opts.flip !== false)\n mw.push(flip());\n\n mw.push(shift({ padding: opts.shiftPadding ?? DEFAULT_FLOATING_OPTIONS.shiftPadding }));\n\n if (arrowEl)\n mw.push(arrow({ element: arrowEl, padding: 4 }));\n\n return mw;\n}\n\nfunction applyArrowStyles(arrowEl: HTMLElement | null, result: ComputePositionReturn): void {\n const arrowData = result.middlewareData.arrow;\n if (!arrowEl || !arrowData)\n return;\n\n Object.assign(arrowEl.style, {\n left: arrowData.x != null ? `${arrowData.x}px` : '',\n top: arrowData.y != null ? `${arrowData.y}px` : '',\n });\n}\n\nexport function useFloating(\n options: MaybeRefOrGetter<FloatingOptions>,\n disabled: MaybeRefOrGetter<boolean> = false,\n openDelay: MaybeRefOrGetter<number> = 0,\n closeDelay: MaybeRefOrGetter<number> = 0,\n virtualReference?: MaybeRefOrGetter<Element | VirtualElement | undefined>,\n): UseFloatingReturn {\n const reference = ref<HTMLElement>();\n const popover = ref<MaybeElement>();\n const open = shallowRef<boolean>(false);\n const visible = shallowRef<boolean>(false);\n const leavePending = shallowRef<boolean>(false);\n const currentPlacement = shallowRef<Placement>(toValue(options).placement ?? DEFAULT_FLOATING_OPTIONS.placement);\n\n let cleanupAutoUpdate: (() => void) | null = null;\n\n const openTimeoutManager = useTimeoutManager();\n const closeTimeoutManager = useTimeoutManager();\n\n function onLeaveComplete(): void {\n set(visible, false);\n }\n\n function onOpen(immediate: boolean = false): void {\n if (toValue(disabled))\n return;\n\n closeTimeoutManager.clear();\n\n set(leavePending, false);\n if (!openTimeoutManager.isActive()) {\n set(visible, true);\n\n openTimeoutManager.create(\n () => {\n set(open, true);\n },\n immediate ? 0 : toValue(openDelay),\n );\n }\n }\n\n function onClose(immediate: boolean = false): void {\n if (toValue(disabled))\n return;\n\n openTimeoutManager.clear();\n\n if (!closeTimeoutManager.isActive()) {\n closeTimeoutManager.create(\n () => {\n if (!get(open))\n onLeaveComplete();\n\n set(open, false);\n },\n immediate ? 0 : toValue(closeDelay),\n );\n }\n }\n\n function onLeavePending(): void {\n set(leavePending, true);\n }\n\n function getValidElements(): { popoverEl: HTMLElement; referenceEl: Element | VirtualElement } | null {\n if (!get(popover) || (!get(reference) && !toValue(virtualReference)))\n return null;\n\n const popoverEl = unrefElement(popover);\n const referenceEl = toValue(virtualReference) || unrefElement(reference);\n\n if (!(popoverEl instanceof HTMLElement) || !referenceEl)\n return null;\n\n return { popoverEl, referenceEl };\n }\n\n async function updatePosition(): Promise<void> {\n const elements = getValidElements();\n if (!elements)\n return;\n\n const { popoverEl, referenceEl } = elements;\n const opts = toValue(options);\n const arrowEl = popoverEl.querySelector<HTMLElement>('[data-id=\"arrow\"]');\n const strategy = opts.strategy ?? DEFAULT_FLOATING_OPTIONS.strategy;\n\n const result = await computePosition(referenceEl, popoverEl, {\n middleware: buildMiddleware(opts, arrowEl),\n placement: opts.placement ?? DEFAULT_FLOATING_OPTIONS.placement,\n strategy,\n });\n\n Object.assign(popoverEl.style, {\n left: `${result.x}px`,\n position: strategy,\n top: `${result.y}px`,\n });\n\n set(currentPlacement, result.placement);\n applyArrowStyles(arrowEl, result);\n }\n\n function startAutoUpdate(): void {\n stopAutoUpdate();\n const elements = getValidElements();\n if (!elements)\n return;\n\n const { popoverEl, referenceEl } = elements;\n const opts = toValue(options);\n const autoUpdateOpt = opts.autoUpdate ?? DEFAULT_FLOATING_OPTIONS.autoUpdate;\n\n if (autoUpdateOpt === false)\n return;\n\n const autoUpdateOptions = typeof autoUpdateOpt === 'object'\n ? {\n ancestorResize: autoUpdateOpt.resize ?? true,\n ancestorScroll: autoUpdateOpt.scroll ?? true,\n elementResize: true,\n }\n : undefined;\n\n cleanupAutoUpdate = autoUpdate(\n referenceEl,\n popoverEl,\n () => { updatePosition().catch(() => {}); },\n autoUpdateOptions,\n );\n }\n\n function stopAutoUpdate(): void {\n cleanupAutoUpdate?.();\n cleanupAutoUpdate = null;\n }\n\n onMounted(() => {\n watchEffect((onCleanup) => {\n startAutoUpdate();\n onCleanup(stopAutoUpdate);\n });\n });\n\n return {\n currentPlacement: readonly(currentPlacement),\n leavePending, // eslint-disable-line @rotki/composable-return-readonly -- written by consumer transition hooks\n onClose,\n onLeaveComplete,\n onLeavePending,\n onOpen,\n open, // eslint-disable-line @rotki/composable-return-readonly -- v-model bound by consumers\n popover, // eslint-disable-line @rotki/composable-return-readonly -- template ref bound by consumers\n reference, // eslint-disable-line @rotki/composable-return-readonly -- template ref bound by consumers\n updatePosition,\n visible, // eslint-disable-line @rotki/composable-return-readonly -- used as v-if condition by consumers\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"floating.js","names":[],"sources":["../../src/composables/floating.ts"],"sourcesContent":["import {\n arrow,\n autoUpdate,\n computePosition,\n type ComputePositionReturn,\n flip,\n type VirtualElement as FloatingVirtualElement,\n type Middleware,\n offset,\n shift,\n} from '@floating-ui/dom';\nimport { type MaybeElement, unrefElement } from '@vueuse/core';\nimport { type MaybeRefOrGetter, onMounted, type Ref, ref, watchEffect } from 'vue';\nimport { useTimeoutManager } from './timeout-manager';\n\ntype VirtualElement = FloatingVirtualElement;\n\nexport const Placement = {\n bottom: 'bottom',\n bottomEnd: 'bottom-end',\n bottomStart: 'bottom-start',\n left: 'left',\n leftEnd: 'left-end',\n leftStart: 'left-start',\n right: 'right',\n rightEnd: 'right-end',\n rightStart: 'right-start',\n top: 'top',\n topEnd: 'top-end',\n topStart: 'top-start',\n} as const;\n\nexport type Placement = (typeof Placement)[keyof typeof Placement];\n\nexport const Strategy = {\n absolute: 'absolute',\n fixed: 'fixed',\n} as const;\n\nexport type Strategy = (typeof Strategy)[keyof typeof Strategy];\n\nexport interface FloatingOptions {\n /** Preferred placement relative to the reference element. @default Placement.bottom */\n placement?: Placement;\n /** CSS positioning strategy. @default Strategy.absolute */\n strategy?: Strategy;\n /** Main-axis and/or cross-axis offset from the reference element. @default 2 */\n offset?: number | { mainAxis?: number; crossAxis?: number };\n /** Whether to flip to the opposite side when overflowing. @default true */\n flip?: boolean;\n /** Padding from viewport edges for shift middleware. @default 8 */\n shiftPadding?: number;\n /** Whether to auto-update position on scroll/resize. @default true */\n autoUpdate?: boolean | { scroll?: boolean; resize?: boolean };\n}\n\nexport const DEFAULT_FLOATING_OPTIONS: Required<FloatingOptions> = {\n autoUpdate: true,\n flip: true,\n offset: 2,\n placement: Placement.bottom,\n shiftPadding: 8,\n strategy: Strategy.absolute,\n};\n\nexport interface UseFloatingReturn {\n currentPlacement: Readonly<Ref<Placement>>;\n leavePending: Ref<boolean>;\n onClose: (immediate?: boolean) => void;\n onLeaveComplete: () => void;\n onLeavePending: () => void;\n onOpen: (immediate?: boolean) => void;\n open: Ref<boolean>;\n popover: Ref<MaybeElement>;\n reference: Ref<HTMLElement | undefined>;\n updatePosition: () => Promise<void>;\n visible: Ref<boolean>;\n}\n\nfunction buildMiddleware(opts: FloatingOptions, arrowEl: HTMLElement | null): Middleware[] {\n const mw: Middleware[] = [];\n\n const off = opts.offset ?? DEFAULT_FLOATING_OPTIONS.offset;\n if (typeof off === 'number') {\n mw.push(offset(off));\n }\n else {\n const defaultOffset = typeof DEFAULT_FLOATING_OPTIONS.offset === 'number' ? DEFAULT_FLOATING_OPTIONS.offset : 0;\n mw.push(offset({ mainAxis: off.mainAxis ?? defaultOffset, crossAxis: off.crossAxis ?? 0 }));\n }\n\n if (opts.flip !== false)\n mw.push(flip());\n\n mw.push(shift({ padding: opts.shiftPadding ?? DEFAULT_FLOATING_OPTIONS.shiftPadding }));\n\n if (arrowEl)\n mw.push(arrow({ element: arrowEl, padding: 4 }));\n\n return mw;\n}\n\nfunction applyArrowStyles(arrowEl: HTMLElement | null, result: ComputePositionReturn): void {\n const arrowData = result.middlewareData.arrow;\n if (!arrowEl || !arrowData)\n return;\n\n Object.assign(arrowEl.style, {\n left: arrowData.x != null ? `${arrowData.x}px` : '',\n top: arrowData.y != null ? `${arrowData.y}px` : '',\n });\n}\n\nexport function useFloating(\n options: MaybeRefOrGetter<FloatingOptions>,\n disabled: MaybeRefOrGetter<boolean> = false,\n openDelay: MaybeRefOrGetter<number> = 0,\n closeDelay: MaybeRefOrGetter<number> = 0,\n virtualReference?: MaybeRefOrGetter<Element | VirtualElement | undefined>,\n): UseFloatingReturn {\n const reference = ref<HTMLElement>();\n const popover = ref<MaybeElement>();\n const open = shallowRef<boolean>(false);\n const visible = shallowRef<boolean>(false);\n const leavePending = shallowRef<boolean>(false);\n const currentPlacement = shallowRef<Placement>(toValue(options).placement ?? DEFAULT_FLOATING_OPTIONS.placement);\n\n let cleanupAutoUpdate: (() => void) | null = null;\n\n const openTimeoutManager = useTimeoutManager();\n const closeTimeoutManager = useTimeoutManager();\n\n function onLeaveComplete(): void {\n set(visible, false);\n }\n\n function onOpen(immediate: boolean = false): void {\n if (toValue(disabled))\n return;\n\n closeTimeoutManager.clear();\n\n set(leavePending, false);\n if (!openTimeoutManager.isActive()) {\n set(visible, true);\n\n openTimeoutManager.create(\n () => {\n set(open, true);\n },\n immediate ? 0 : toValue(openDelay),\n );\n }\n }\n\n function onClose(immediate: boolean = false): void {\n if (toValue(disabled))\n return;\n\n openTimeoutManager.clear();\n\n if (!closeTimeoutManager.isActive()) {\n closeTimeoutManager.create(\n () => {\n if (!get(open))\n onLeaveComplete();\n\n set(open, false);\n },\n immediate ? 0 : toValue(closeDelay),\n );\n }\n }\n\n function onLeavePending(): void {\n set(leavePending, true);\n }\n\n function getValidElements(): { popoverEl: HTMLElement; referenceEl: Element | VirtualElement } | null {\n if (!get(popover) || (!get(reference) && !toValue(virtualReference)))\n return null;\n\n const popoverEl = unrefElement(popover);\n const referenceEl = toValue(virtualReference) || unrefElement(reference);\n\n if (!(popoverEl instanceof HTMLElement) || !referenceEl)\n return null;\n\n return { popoverEl, referenceEl };\n }\n\n async function updatePosition(): Promise<void> {\n const elements = getValidElements();\n if (!elements)\n return;\n\n const { popoverEl, referenceEl } = elements;\n const opts = toValue(options);\n const arrowEl = popoverEl.querySelector<HTMLElement>('[data-id=\"arrow\"]');\n const strategy = opts.strategy ?? DEFAULT_FLOATING_OPTIONS.strategy;\n\n const result = await computePosition(referenceEl, popoverEl, {\n middleware: buildMiddleware(opts, arrowEl),\n placement: opts.placement ?? DEFAULT_FLOATING_OPTIONS.placement,\n strategy,\n });\n\n Object.assign(popoverEl.style, {\n left: `${result.x}px`,\n position: strategy,\n top: `${result.y}px`,\n });\n\n set(currentPlacement, result.placement);\n applyArrowStyles(arrowEl, result);\n }\n\n function startAutoUpdate(): void {\n stopAutoUpdate();\n const elements = getValidElements();\n if (!elements)\n return;\n\n const { popoverEl, referenceEl } = elements;\n const opts = toValue(options);\n const autoUpdateOpt = opts.autoUpdate ?? DEFAULT_FLOATING_OPTIONS.autoUpdate;\n\n if (autoUpdateOpt === false)\n return;\n\n const autoUpdateOptions = typeof autoUpdateOpt === 'object'\n ? {\n ancestorResize: autoUpdateOpt.resize ?? true,\n ancestorScroll: autoUpdateOpt.scroll ?? true,\n elementResize: true,\n }\n : undefined;\n\n cleanupAutoUpdate = autoUpdate(\n referenceEl,\n popoverEl,\n () => { updatePosition().catch(() => {}); },\n autoUpdateOptions,\n );\n }\n\n function stopAutoUpdate(): void {\n cleanupAutoUpdate?.();\n cleanupAutoUpdate = null;\n }\n\n onMounted(() => {\n watchEffect((onCleanup) => {\n startAutoUpdate();\n onCleanup(stopAutoUpdate);\n });\n });\n\n return {\n currentPlacement: readonly(currentPlacement),\n leavePending, // eslint-disable-line @rotki/composable-return-readonly -- written by consumer transition hooks\n onClose,\n onLeaveComplete,\n onLeavePending,\n onOpen,\n open, // eslint-disable-line @rotki/composable-return-readonly -- v-model bound by consumers\n popover, // eslint-disable-line @rotki/composable-return-readonly -- template ref bound by consumers\n reference, // eslint-disable-line @rotki/composable-return-readonly -- template ref bound by consumers\n updatePosition,\n visible, // eslint-disable-line @rotki/composable-return-readonly -- used as v-if condition by consumers\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"focus.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/focus.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\n\nexport interface UseAutoCompleteFocusOptions {\n /** Whether custom (free-text) values are allowed. */\n customValue: MaybeRefOrGetter<boolean>;\n /** Whether to apply the current value as the search text when focused. */\n shouldApplyValueAsSearch: MaybeRefOrGetter<boolean>;\n /** Whether the autocomplete is disabled. */\n disabled: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteFocusDeps {\n activatorFocused: Ref<boolean>;\n activatorFocusedWithin: Ref<boolean>;\n focusedValueIndex: Ref<number>;\n internalSearch: Ref<string>;\n isOpen: Ref<boolean>;\n justOpened: Ref<boolean>;\n menuWrapperFocusedWithin: Ref<boolean>;\n searchInputFocused: Ref<boolean>;\n textInput: Ref<HTMLInputElement | undefined> | TemplateRef<HTMLInputElement>;\n setSearchAsValue: () => void;\n updateInternalSearch: (value?: string) => void;\n}\n\nexport interface UseAutoCompleteFocusReturn {\n anyFocused: ComputedRef<boolean>;\n inputClass: ComputedRef<string>;\n onActivatorFocused: () => Promise<void>;\n onInputFocused: () => void;\n setInputFocus: () => Promise<void>;\n}\n\nexport function useAutoCompleteFocus(\n options: UseAutoCompleteFocusOptions,\n deps: UseAutoCompleteFocusDeps,\n): UseAutoCompleteFocusReturn {\n const anyFocused = computed<boolean>(\n () => get(deps.activatorFocusedWithin) || get(deps.menuWrapperFocusedWithin),\n );\n\n const inputClass = computed<string>(() => {\n const isFocused = get(anyFocused);\n const isDisabled = toValue(options.disabled);\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n const hasSearch = get(deps.internalSearch);\n\n if ((!isFocused || isDisabled) && !shouldApply)\n return 'w-0 h-0';\n if (hasSearch)\n return 'flex-1 min-w-[4rem]';\n return 'flex-1 min-w-0';\n });\n\n async function setInputFocus(): Promise<void> {\n await nextTick(() => {\n set(deps.searchInputFocused, true);\n });\n }\n\n async function onActivatorFocused(): Promise<void> {\n await nextTick(() => {\n if (!get(deps.activatorFocused)) {\n set(deps.searchInputFocused, true);\n }\n });\n }\n\n function onInputFocused(): void {\n set(deps.focusedValueIndex, -1);\n\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n if (shouldApply) {\n const textInput = get(deps.textInput);\n textInput?.select();\n }\n\n if (!get(deps.isOpen)) {\n set(deps.justOpened, true);\n }\n }\n\n // Capture the search value immediately when focus is lost, before the debounced\n // handler fires. Other watchers (value.ts) may clear internalSearch when isOpen\n // changes, so we need to preserve it for the custom value blur flow.\n let pendingCustomSearch = '';\n\n watch(anyFocused, (focused) => {\n if (!focused && toValue(options.customValue)) {\n pendingCustomSearch = get(deps.internalSearch);\n }\n });\n\n // Close menu if the activator is not focused anymore\n // Using debounced to avoid the menu closing momentarily while focus switches.\n watchDebounced(\n anyFocused,\n (focused) => {\n if (!focused) {\n set(deps.isOpen, false);\n\n const customValue = toValue(options.customValue);\n const searchToUse = pendingCustomSearch;\n pendingCustomSearch = '';\n\n if (customValue && searchToUse) {\n deps.updateInternalSearch(searchToUse);\n deps.setSearchAsValue();\n }\n\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n if (!shouldApply) {\n deps.updateInternalSearch();\n }\n }\n },\n {\n debounce: 100,\n maxWait: 200,\n },\n );\n\n return {\n anyFocused,\n inputClass,\n onActivatorFocused,\n onInputFocused,\n setInputFocus,\n };\n}\n"],"mappings":";;;;AAiCA,SAAgB,qBACd,SACA,MAC4B;CAC5B,MAAM,aAAa,eACX,MAAI,KAAK,
|
|
1
|
+
{"version":3,"file":"focus.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/focus.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\n\nexport interface UseAutoCompleteFocusOptions {\n /** Whether custom (free-text) values are allowed. */\n customValue: MaybeRefOrGetter<boolean>;\n /** Whether to apply the current value as the search text when focused. */\n shouldApplyValueAsSearch: MaybeRefOrGetter<boolean>;\n /** Whether the autocomplete is disabled. */\n disabled: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteFocusDeps {\n activatorFocused: Ref<boolean>;\n activatorFocusedWithin: Ref<boolean>;\n focusedValueIndex: Ref<number>;\n internalSearch: Ref<string>;\n isOpen: Ref<boolean>;\n justOpened: Ref<boolean>;\n menuWrapperFocusedWithin: Ref<boolean>;\n searchInputFocused: Ref<boolean>;\n textInput: Ref<HTMLInputElement | undefined> | TemplateRef<HTMLInputElement>;\n setSearchAsValue: () => void;\n updateInternalSearch: (value?: string) => void;\n}\n\nexport interface UseAutoCompleteFocusReturn {\n anyFocused: ComputedRef<boolean>;\n inputClass: ComputedRef<string>;\n onActivatorFocused: () => Promise<void>;\n onInputFocused: () => void;\n setInputFocus: () => Promise<void>;\n}\n\nexport function useAutoCompleteFocus(\n options: UseAutoCompleteFocusOptions,\n deps: UseAutoCompleteFocusDeps,\n): UseAutoCompleteFocusReturn {\n const anyFocused = computed<boolean>(\n () => get(deps.activatorFocusedWithin) || get(deps.menuWrapperFocusedWithin),\n );\n\n const inputClass = computed<string>(() => {\n const isFocused = get(anyFocused);\n const isDisabled = toValue(options.disabled);\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n const hasSearch = get(deps.internalSearch);\n\n if ((!isFocused || isDisabled) && !shouldApply)\n return 'w-0 h-0';\n if (hasSearch)\n return 'flex-1 min-w-[4rem]';\n return 'flex-1 min-w-0';\n });\n\n async function setInputFocus(): Promise<void> {\n await nextTick(() => {\n set(deps.searchInputFocused, true);\n });\n }\n\n async function onActivatorFocused(): Promise<void> {\n await nextTick(() => {\n if (!get(deps.activatorFocused)) {\n set(deps.searchInputFocused, true);\n }\n });\n }\n\n function onInputFocused(): void {\n set(deps.focusedValueIndex, -1);\n\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n if (shouldApply) {\n const textInput = get(deps.textInput);\n textInput?.select();\n }\n\n if (!get(deps.isOpen)) {\n set(deps.justOpened, true);\n }\n }\n\n // Capture the search value immediately when focus is lost, before the debounced\n // handler fires. Other watchers (value.ts) may clear internalSearch when isOpen\n // changes, so we need to preserve it for the custom value blur flow.\n let pendingCustomSearch = '';\n\n watch(anyFocused, (focused) => {\n if (!focused && toValue(options.customValue)) {\n pendingCustomSearch = get(deps.internalSearch);\n }\n });\n\n // Close menu if the activator is not focused anymore\n // Using debounced to avoid the menu closing momentarily while focus switches.\n watchDebounced(\n anyFocused,\n (focused) => {\n if (!focused) {\n set(deps.isOpen, false);\n\n const customValue = toValue(options.customValue);\n const searchToUse = pendingCustomSearch;\n pendingCustomSearch = '';\n\n if (customValue && searchToUse) {\n deps.updateInternalSearch(searchToUse);\n deps.setSearchAsValue();\n }\n\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n if (!shouldApply) {\n deps.updateInternalSearch();\n }\n }\n },\n {\n debounce: 100,\n maxWait: 200,\n },\n );\n\n return {\n anyFocused,\n inputClass,\n onActivatorFocused,\n onInputFocused,\n setInputFocus,\n };\n}\n"],"mappings":";;;;AAiCA,SAAgB,qBACd,SACA,MAC4B;CAC5B,MAAM,aAAa,eACX,MAAI,KAAK,sBAAsB,KAAK,MAAI,KAAK,wBAAwB,CAC7E;CAEA,MAAM,aAAa,eAAuB;EACxC,MAAM,YAAY,MAAI,UAAU;EAChC,MAAM,aAAa,QAAQ,QAAQ,QAAQ;EAC3C,MAAM,cAAc,QAAQ,QAAQ,wBAAwB;EAC5D,MAAM,YAAY,MAAI,KAAK,cAAc;EAEzC,KAAK,CAAC,aAAa,eAAe,CAAC,aACjC,OAAO;EACT,IAAI,WACF,OAAO;EACT,OAAO;CACT,CAAC;CAED,eAAe,gBAA+B;EAC5C,MAAM,eAAe;GACnB,MAAI,KAAK,oBAAoB,IAAI;EACnC,CAAC;CACH;CAEA,eAAe,qBAAoC;EACjD,MAAM,eAAe;GACnB,IAAI,CAAC,MAAI,KAAK,gBAAgB,GAC5B,MAAI,KAAK,oBAAoB,IAAI;EAErC,CAAC;CACH;CAEA,SAAS,iBAAuB;EAC9B,MAAI,KAAK,mBAAmB,EAAE;EAG9B,IADoB,QAAQ,QAAQ,wBAChC,GAEF,MADsB,KAAK,SAC3B,CAAA,EAAW,OAAO;EAGpB,IAAI,CAAC,MAAI,KAAK,MAAM,GAClB,MAAI,KAAK,YAAY,IAAI;CAE7B;CAKA,IAAI,sBAAsB;CAE1B,MAAM,aAAa,YAAY;EAC7B,IAAI,CAAC,WAAW,QAAQ,QAAQ,WAAW,GACzC,sBAAsB,MAAI,KAAK,cAAc;CAEjD,CAAC;CAID,eACE,aACC,YAAY;EACX,IAAI,CAAC,SAAS;GACZ,MAAI,KAAK,QAAQ,KAAK;GAEtB,MAAM,cAAc,QAAQ,QAAQ,WAAW;GAC/C,MAAM,cAAc;GACpB,sBAAsB;GAEtB,IAAI,eAAe,aAAa;IAC9B,KAAK,qBAAqB,WAAW;IACrC,KAAK,iBAAiB;GACxB;GAGA,IAAI,CADgB,QAAQ,QAAQ,wBAC/B,GACH,KAAK,qBAAqB;EAE9B;CACF,GACA;EACE,UAAU;EACV,SAAS;CACX,CACF;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import "./focus.js";
|
|
2
|
-
import "./keyboard-navigation.js";
|
|
3
|
-
import "./search.js";
|
|
4
|
-
import "./value.js";
|
|
1
|
+
import { useAutoCompleteFocus } from "./focus.js";
|
|
2
|
+
import { useAutoCompleteKeyboardNavigation } from "./keyboard-navigation.js";
|
|
3
|
+
import { useAutoCompleteSearch } from "./search.js";
|
|
4
|
+
import { useAutoCompleteValue } from "./value.js";
|
|
5
|
+
export { useAutoCompleteFocus, useAutoCompleteKeyboardNavigation, useAutoCompleteSearch, useAutoCompleteValue };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyboard-navigation.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/keyboard-navigation.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\nimport { get, set } from '@vueuse/shared';\n\nexport interface UseAutoCompleteKeyboardNavigationOptions {\n /** Whether multiple items can be selected. */\n multiple: MaybeRefOrGetter<boolean>;\n /** Whether custom (free-text) values are allowed. */\n customValue: MaybeRefOrGetter<boolean>;\n /** Whether selected values are displayed as chips. */\n chips: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteKeyboardNavigationDeps<TItem> {\n internalSearch: Ref<string>;\n value: Ref<TItem[]>;\n filteredOptions: Ref<TItem[]>;\n isOpen: Ref<boolean>;\n highlightedIndex: Ref<number>;\n userNavigated: Ref<boolean>;\n searchInputFocused: Ref<boolean>;\n applyHighlighted: () => void;\n clear: () => void;\n removeValue: (item: TItem) => void;\n setSearchAsValue: () => void;\n getText: (item: TItem) => string | undefined;\n activator: Ref<HTMLElement | undefined> | TemplateRef<HTMLElement>;\n}\n\nexport interface UseAutoCompleteKeyboardNavigationReturn {\n focusedValueIndex: Ref<number>;\n moveSelectedValueHighlight: (event: KeyboardEvent, next: boolean) => void;\n onEnter: (event: KeyboardEvent) => void;\n onTab: (event: KeyboardEvent) => void;\n onInputDeletePressed: () => void;\n setValueFocus: (index: number) => void;\n}\n\nexport function useAutoCompleteKeyboardNavigation<TItem>(\n options: UseAutoCompleteKeyboardNavigationOptions,\n deps: UseAutoCompleteKeyboardNavigationDeps<TItem>,\n): UseAutoCompleteKeyboardNavigationReturn {\n const focusedValueIndex = ref<number>(-1);\n\n function setValueFocus(index: number): void {\n set(focusedValueIndex, index);\n }\n\n function moveSelectedValueHighlight(event: KeyboardEvent, next: boolean): void {\n const multiple = toValue(options.multiple);\n const internalSearchValue = get(deps.internalSearch);\n\n if (!multiple || internalSearchValue.length > 0)\n return;\n\n event.preventDefault();\n const total = get(deps.value).length;\n\n let current = get(focusedValueIndex);\n\n if (current === -1) {\n set(focusedValueIndex, next ? 0 : total - 1);\n return;\n }\n\n const move = next ? 1 : -1;\n current += move;\n\n if (current < 0 || current >= total) {\n set(focusedValueIndex, -1);\n set(deps.searchInputFocused, true);\n }\n else {\n set(focusedValueIndex, current);\n }\n }\n\n function highlightedMatchesSearch(filteredOptions: TItem[], highlightedIndex: number, search: string): boolean {\n if (highlightedIndex < 0 || highlightedIndex >= filteredOptions.length)\n return false;\n\n const option = filteredOptions[highlightedIndex];\n if (typeof option === 'string')\n return option === search;\n\n if (option && typeof option === 'object')\n return (deps.getText(option) ?? '') === search;\n\n return false;\n }\n\n function applyCustomValue(event: KeyboardEvent, multiple: boolean): void {\n deps.setSearchAsValue();\n if (!multiple)\n set(deps.isOpen, false);\n event.preventDefault();\n }\n\n function submitClosestForm(): void {\n const activator = get(deps.activator);\n const form = activator?.closest('form');\n form?.dispatchEvent(new Event('submit'));\n }\n\n function tryApplyHighlight(event: KeyboardEvent): boolean {\n const filteredOptions = get(deps.filteredOptions);\n const highlightedIndex = get(deps.highlightedIndex);\n if (highlightedIndex <= -1 || filteredOptions.length === 0)\n return false;\n\n deps.applyHighlighted();\n event.preventDefault();\n return true;\n }\n\n function tryApplyCustom(event: KeyboardEvent, requireEmptyOptions: boolean): boolean {\n const customValue = toValue(options.customValue);\n const internalSearch = get(deps.internalSearch);\n if (!customValue || !internalSearch)\n return false;\n\n const filteredOptions = get(deps.filteredOptions);\n if (requireEmptyOptions) {\n if (filteredOptions.length > 0)\n return false;\n }\n else {\n const highlightedIndex = get(deps.highlightedIndex);\n if (highlightedMatchesSearch(filteredOptions, highlightedIndex, internalSearch))\n return false;\n }\n\n applyCustomValue(event, toValue(options.multiple));\n return true;\n }\n\n function handleOpenMenuEnter(event: KeyboardEvent): boolean {\n // Prefer the user's explicit navigation.\n if (get(deps.userNavigated) && tryApplyHighlight(event))\n return true;\n\n // Fall back to a typed custom value when it differs from the highlight.\n if (tryApplyCustom(event, false))\n return true;\n\n // Use the (auto-)highlighted option if there is one.\n if (tryApplyHighlight(event))\n return true;\n\n // No options matched but custom values are allowed — accept the typed text.\n return tryApplyCustom(event, true);\n }\n\n function onEnter(event: KeyboardEvent): void {\n if (get(deps.isOpen)) {\n if (handleOpenMenuEnter(event))\n return;\n\n // Menu is open but no actionable selection (e.g. typed text with no\n // matches and customValue=false, or no highlighted option). Swallow\n // Enter so it does not bubble up and submit a surrounding form.\n event.preventDefault();\n return;\n }\n\n // Nothing selected, menu closed: open menu\n if (get(deps.value).length === 0) {\n set(deps.isOpen, true);\n return event.preventDefault();\n }\n\n // Menu closed with a value selected: let Enter submit the parent form.\n submitClosestForm();\n }\n\n function onTab(event: KeyboardEvent): void {\n const isOpen = get(deps.isOpen);\n const filteredOptions = get(deps.filteredOptions);\n const highlightedIndex = get(deps.highlightedIndex);\n const multiple = toValue(options.multiple);\n\n if (isOpen && filteredOptions.length > 0 && highlightedIndex > -1 && !multiple) {\n deps.applyHighlighted();\n event.preventDefault();\n }\n }\n\n function onInputDeletePressed(): void {\n const internalSearch = get(deps.internalSearch);\n const value = get(deps.value);\n const total = value.length;\n const multiple = toValue(options.multiple);\n\n if (!internalSearch && total > 0) {\n if (multiple) {\n if (toValue(options.chips)) {\n set(focusedValueIndex, total - 1);\n }\n else {\n const lastItem = value[total - 1];\n if (lastItem !== undefined)\n deps.removeValue(lastItem);\n }\n }\n else {\n deps.clear();\n }\n }\n }\n\n // Watch value changes to reset focused index\n watch(deps.value, () => {\n setValueFocus(-1);\n });\n\n // Watch focused value index to handle chip focus\n watch(focusedValueIndex, async (index) => {\n const multiple = toValue(options.multiple);\n if (index === -1 || !multiple)\n return;\n\n await nextTick(() => {\n const activator = get(deps.activator);\n const element = activator?.querySelector<HTMLElement>(`[data-index=\"${index}\"]`);\n element?.focus();\n });\n });\n\n return {\n // eslint-disable-next-line @rotki/composable-return-readonly -- written by focus.ts onInputFocused\n focusedValueIndex,\n moveSelectedValueHighlight,\n onEnter,\n onInputDeletePressed,\n onTab,\n setValueFocus,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"keyboard-navigation.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/keyboard-navigation.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\nimport { get, set } from '@vueuse/shared';\n\nexport interface UseAutoCompleteKeyboardNavigationOptions {\n /** Whether multiple items can be selected. */\n multiple: MaybeRefOrGetter<boolean>;\n /** Whether custom (free-text) values are allowed. */\n customValue: MaybeRefOrGetter<boolean>;\n /** Whether selected values are displayed as chips. */\n chips: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteKeyboardNavigationDeps<TItem> {\n internalSearch: Ref<string>;\n value: Ref<TItem[]>;\n filteredOptions: Ref<TItem[]>;\n isOpen: Ref<boolean>;\n highlightedIndex: Ref<number>;\n userNavigated: Ref<boolean>;\n searchInputFocused: Ref<boolean>;\n applyHighlighted: () => void;\n clear: () => void;\n removeValue: (item: TItem) => void;\n setSearchAsValue: () => void;\n getText: (item: TItem) => string | undefined;\n activator: Ref<HTMLElement | undefined> | TemplateRef<HTMLElement>;\n}\n\nexport interface UseAutoCompleteKeyboardNavigationReturn {\n focusedValueIndex: Ref<number>;\n moveSelectedValueHighlight: (event: KeyboardEvent, next: boolean) => void;\n onEnter: (event: KeyboardEvent) => void;\n onTab: (event: KeyboardEvent) => void;\n onInputDeletePressed: () => void;\n setValueFocus: (index: number) => void;\n}\n\nexport function useAutoCompleteKeyboardNavigation<TItem>(\n options: UseAutoCompleteKeyboardNavigationOptions,\n deps: UseAutoCompleteKeyboardNavigationDeps<TItem>,\n): UseAutoCompleteKeyboardNavigationReturn {\n const focusedValueIndex = ref<number>(-1);\n\n function setValueFocus(index: number): void {\n set(focusedValueIndex, index);\n }\n\n function moveSelectedValueHighlight(event: KeyboardEvent, next: boolean): void {\n const multiple = toValue(options.multiple);\n const internalSearchValue = get(deps.internalSearch);\n\n if (!multiple || internalSearchValue.length > 0)\n return;\n\n event.preventDefault();\n const total = get(deps.value).length;\n\n let current = get(focusedValueIndex);\n\n if (current === -1) {\n set(focusedValueIndex, next ? 0 : total - 1);\n return;\n }\n\n const move = next ? 1 : -1;\n current += move;\n\n if (current < 0 || current >= total) {\n set(focusedValueIndex, -1);\n set(deps.searchInputFocused, true);\n }\n else {\n set(focusedValueIndex, current);\n }\n }\n\n function highlightedMatchesSearch(filteredOptions: TItem[], highlightedIndex: number, search: string): boolean {\n if (highlightedIndex < 0 || highlightedIndex >= filteredOptions.length)\n return false;\n\n const option = filteredOptions[highlightedIndex];\n if (typeof option === 'string')\n return option === search;\n\n if (option && typeof option === 'object')\n return (deps.getText(option) ?? '') === search;\n\n return false;\n }\n\n function applyCustomValue(event: KeyboardEvent, multiple: boolean): void {\n deps.setSearchAsValue();\n if (!multiple)\n set(deps.isOpen, false);\n event.preventDefault();\n }\n\n function submitClosestForm(): void {\n const activator = get(deps.activator);\n const form = activator?.closest('form');\n form?.dispatchEvent(new Event('submit'));\n }\n\n function tryApplyHighlight(event: KeyboardEvent): boolean {\n const filteredOptions = get(deps.filteredOptions);\n const highlightedIndex = get(deps.highlightedIndex);\n if (highlightedIndex <= -1 || filteredOptions.length === 0)\n return false;\n\n deps.applyHighlighted();\n event.preventDefault();\n return true;\n }\n\n function tryApplyCustom(event: KeyboardEvent, requireEmptyOptions: boolean): boolean {\n const customValue = toValue(options.customValue);\n const internalSearch = get(deps.internalSearch);\n if (!customValue || !internalSearch)\n return false;\n\n const filteredOptions = get(deps.filteredOptions);\n if (requireEmptyOptions) {\n if (filteredOptions.length > 0)\n return false;\n }\n else {\n const highlightedIndex = get(deps.highlightedIndex);\n if (highlightedMatchesSearch(filteredOptions, highlightedIndex, internalSearch))\n return false;\n }\n\n applyCustomValue(event, toValue(options.multiple));\n return true;\n }\n\n function handleOpenMenuEnter(event: KeyboardEvent): boolean {\n // Prefer the user's explicit navigation.\n if (get(deps.userNavigated) && tryApplyHighlight(event))\n return true;\n\n // Fall back to a typed custom value when it differs from the highlight.\n if (tryApplyCustom(event, false))\n return true;\n\n // Use the (auto-)highlighted option if there is one.\n if (tryApplyHighlight(event))\n return true;\n\n // No options matched but custom values are allowed — accept the typed text.\n return tryApplyCustom(event, true);\n }\n\n function onEnter(event: KeyboardEvent): void {\n if (get(deps.isOpen)) {\n if (handleOpenMenuEnter(event))\n return;\n\n // Menu is open but no actionable selection (e.g. typed text with no\n // matches and customValue=false, or no highlighted option). Swallow\n // Enter so it does not bubble up and submit a surrounding form.\n event.preventDefault();\n return;\n }\n\n // Nothing selected, menu closed: open menu\n if (get(deps.value).length === 0) {\n set(deps.isOpen, true);\n return event.preventDefault();\n }\n\n // Menu closed with a value selected: let Enter submit the parent form.\n submitClosestForm();\n }\n\n function onTab(event: KeyboardEvent): void {\n const isOpen = get(deps.isOpen);\n const filteredOptions = get(deps.filteredOptions);\n const highlightedIndex = get(deps.highlightedIndex);\n const multiple = toValue(options.multiple);\n\n if (isOpen && filteredOptions.length > 0 && highlightedIndex > -1 && !multiple) {\n deps.applyHighlighted();\n event.preventDefault();\n }\n }\n\n function onInputDeletePressed(): void {\n const internalSearch = get(deps.internalSearch);\n const value = get(deps.value);\n const total = value.length;\n const multiple = toValue(options.multiple);\n\n if (!internalSearch && total > 0) {\n if (multiple) {\n if (toValue(options.chips)) {\n set(focusedValueIndex, total - 1);\n }\n else {\n const lastItem = value[total - 1];\n if (lastItem !== undefined)\n deps.removeValue(lastItem);\n }\n }\n else {\n deps.clear();\n }\n }\n }\n\n // Watch value changes to reset focused index\n watch(deps.value, () => {\n setValueFocus(-1);\n });\n\n // Watch focused value index to handle chip focus\n watch(focusedValueIndex, async (index) => {\n const multiple = toValue(options.multiple);\n if (index === -1 || !multiple)\n return;\n\n await nextTick(() => {\n const activator = get(deps.activator);\n const element = activator?.querySelector<HTMLElement>(`[data-index=\"${index}\"]`);\n element?.focus();\n });\n });\n\n return {\n // eslint-disable-next-line @rotki/composable-return-readonly -- written by focus.ts onInputFocused\n focusedValueIndex,\n moveSelectedValueHighlight,\n onEnter,\n onInputDeletePressed,\n onTab,\n setValueFocus,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { MaybeRefOrGetter, Ref } from 'vue';
|
|
2
|
+
import type { GroupBy } from '../../../composables/dropdown-menu.js';
|
|
2
3
|
export interface UseAutoCompleteSearchOptions<TItem> {
|
|
3
4
|
/** The property used as the unique identifier for each item. */
|
|
4
5
|
keyAttr?: MaybeRefOrGetter<keyof TItem | undefined>;
|
|
@@ -7,13 +8,17 @@ export interface UseAutoCompleteSearchOptions<TItem> {
|
|
|
7
8
|
/** Whether to disable client-side filtering of options. */
|
|
8
9
|
noFilter?: MaybeRefOrGetter<boolean>;
|
|
9
10
|
/** Custom filter function to match items against the search query. */
|
|
10
|
-
filter?: MaybeRefOrGetter<((item: TItem, queryText: string) => boolean) | undefined>;
|
|
11
|
+
filter?: MaybeRefOrGetter<((item: TItem, queryText: string, group?: string) => boolean) | undefined>;
|
|
11
12
|
/** Whether custom (free-text) values are allowed. */
|
|
12
13
|
customValue?: MaybeRefOrGetter<boolean>;
|
|
13
14
|
/** Whether to hide the custom value option from the dropdown. */
|
|
14
15
|
hideCustomValue?: MaybeRefOrGetter<boolean>;
|
|
15
16
|
/** Whether to return the full item object instead of just the key. */
|
|
16
17
|
returnObject?: MaybeRefOrGetter<boolean>;
|
|
18
|
+
/** How items are grouped, used to resolve group labels for filtering. */
|
|
19
|
+
groupBy?: MaybeRefOrGetter<GroupBy<TItem> | undefined>;
|
|
20
|
+
/** When true and `groupBy` is set, the default filter also matches the resolved group label. */
|
|
21
|
+
searchIncludesGroupLabel?: MaybeRefOrGetter<boolean>;
|
|
17
22
|
}
|
|
18
23
|
export interface UseAutoCompleteSearchReturn<TItem> {
|
|
19
24
|
internalSearch: Readonly<Ref<string>>;
|
|
@@ -20,6 +20,11 @@ function useAutoCompleteSearch(options, searchModel, opts) {
|
|
|
20
20
|
tokenCache.set(text, token);
|
|
21
21
|
return token;
|
|
22
22
|
};
|
|
23
|
+
const resolveGroup = (item, groupBy) => {
|
|
24
|
+
if (!groupBy) return void 0;
|
|
25
|
+
if (typeof groupBy === "function") return groupBy(item);
|
|
26
|
+
return String(item?.[groupBy] ?? "");
|
|
27
|
+
};
|
|
23
28
|
const filteredOptions = computed(() => {
|
|
24
29
|
const search = get$1(debouncedInternalSearch);
|
|
25
30
|
const optionsValue = toValue(options);
|
|
@@ -27,11 +32,17 @@ function useAutoCompleteSearch(options, searchModel, opts) {
|
|
|
27
32
|
const keyAttr = toValue(opts.keyAttr);
|
|
28
33
|
const textAttr = toValue(opts.textAttr);
|
|
29
34
|
const filter = toValue(opts.filter);
|
|
35
|
+
const groupBy = toValue(opts.groupBy);
|
|
36
|
+
const searchIncludesGroupLabel = toValue(opts.searchIncludesGroupLabel);
|
|
30
37
|
const searchToken = getCachedTextToken(search);
|
|
31
|
-
const filtered = filter ? optionsValue.filter((item) => filter(item, search)) : optionsValue.filter((item) => {
|
|
38
|
+
const filtered = filter ? optionsValue.filter((item) => filter(item, search, resolveGroup(item, groupBy))) : optionsValue.filter((item) => {
|
|
32
39
|
if (!item) return false;
|
|
33
40
|
const keywords = [getCachedTextToken(keyAttr ? String(item[keyAttr]) : item.toString())];
|
|
34
41
|
if (textAttr && typeof item === "object") keywords.push(getCachedTextToken(String(item[textAttr])));
|
|
42
|
+
if (searchIncludesGroupLabel && groupBy) {
|
|
43
|
+
const group = resolveGroup(item, groupBy);
|
|
44
|
+
if (group) keywords.push(getCachedTextToken(group));
|
|
45
|
+
}
|
|
35
46
|
return keywords.some((keyword) => keyword.includes(searchToken));
|
|
36
47
|
});
|
|
37
48
|
const customValue = toValue(opts.customValue);
|