@rotki/ui-library 2.27.0 → 3.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -15
- package/dist/components/accordions/accordion/RuiAccordion.js.map +1 -1
- package/dist/components/accordions/accordion/RuiAccordion.vue.d.ts +0 -4
- package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js +9 -10
- package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/accordions/accordions/RuiAccordions.js.map +1 -1
- package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js +16 -3
- package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/alerts/RuiAlert.js.map +1 -1
- package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js +43 -212
- package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/avatars/RuiAvatar.js.map +1 -1
- package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js +22 -32
- package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/avatars/RuiAvatarGroup.js.map +1 -1
- package/dist/components/avatars/RuiAvatarGroup.vue.d.ts +6 -0
- package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js +17 -13
- package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/avatars/avatar-props.d.ts +16 -3
- package/dist/components/avatars/avatar-props.js +42 -5
- package/dist/components/avatars/avatar-props.js.map +1 -1
- package/dist/components/buttons/button/RuiButton.js.map +1 -1
- package/dist/components/buttons/button/RuiButton.vue.d.ts +0 -1
- package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js +39 -26
- package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/buttons/button/button-props.d.ts +0 -2
- package/dist/components/buttons/button/button-props.js +5 -5
- package/dist/components/buttons/button/button-props.js.map +1 -1
- package/dist/components/buttons/button/button-styles.d.ts +4 -1
- package/dist/components/buttons/button/button-styles.js +136 -55
- package/dist/components/buttons/button/button-styles.js.map +1 -1
- package/dist/components/buttons/button-group/RuiButtonGroup.js.map +1 -1
- package/dist/components/buttons/button-group/RuiButtonGroup.vue.d.ts +8 -2
- package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js +66 -97
- package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/buttons/button-group/button-group-context.d.ts +28 -0
- package/dist/components/buttons/button-group/button-group-context.js +22 -0
- package/dist/components/buttons/button-group/button-group-context.js.map +1 -0
- package/dist/components/calendar/RuiCalendar.js.map +1 -1
- package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js +6 -3
- package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendarGrid.js.map +1 -1
- package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js +12 -8
- package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendarHeader.js.map +1 -1
- package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js +21 -22
- 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 +17 -21
- package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/cards/RuiCard.js.map +1 -1
- package/dist/components/cards/RuiCard.vue.d.ts +0 -3
- package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js +31 -19
- package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/cards/RuiCardHeader.js.map +1 -1
- package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js +13 -25
- package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chips/RuiChip.js.map +1 -1
- package/dist/components/chips/RuiChip.vue.d.ts +5 -2
- package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js +127 -78
- package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chips/chip-props.d.ts +2 -0
- package/dist/components/chips/chip-props.js +5 -3
- package/dist/components/chips/chip-props.js.map +1 -1
- package/dist/components/color-picker/RuiColorBoard.js.map +1 -1
- package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js +5 -5
- 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/RuiColorHue.js.map +1 -1
- package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorInput.js.map +1 -1
- package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js +46 -36
- package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorPicker.js.map +1 -1
- package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js +4 -5
- package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.vue.d.ts +3 -2
- package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +81 -80
- 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.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js +2 -2
- 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.js.map +1 -1
- package/dist/components/date-time-picker/RuiTimezoneSelect.vue.d.ts +4 -3
- package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js +3 -3
- 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.d.ts +128 -219
- package/dist/components/date-time-picker/date-time-picker-styles.js +1 -2
- package/dist/components/date-time-picker/date-time-picker-styles.js.map +1 -1
- package/dist/components/date-time-picker/use-date-bounds.js +1 -1
- package/dist/components/date-time-picker/use-date-time-selection.js +65 -66
- package/dist/components/date-time-picker/use-date-time-selection.js.map +1 -1
- package/dist/components/date-time-picker/use-input-handler.js +1 -1
- package/dist/components/date-time-picker/use-keyboard-handler.js +29 -30
- package/dist/components/date-time-picker/use-keyboard-handler.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 +1 -68
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +203 -198
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoCompleteOption.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoCompleteOption.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/components/forms/auto-complete/RuiAutoCompleteOption.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue.d.ts +2 -0
- package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue_vue_type_script_setup_true_lang.js +8 -3
- package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.vue.d.ts +4 -0
- package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.vue_vue_type_script_setup_true_lang.js +24 -10
- package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/auto-complete-props.d.ts +66 -0
- package/dist/components/forms/auto-complete/auto-complete-styles.d.ts +128 -218
- package/dist/components/forms/auto-complete/auto-complete-styles.js +4 -2
- package/dist/components/forms/auto-complete/auto-complete-styles.js.map +1 -1
- package/dist/components/forms/category-picker/RuiCategoryPicker.js.map +1 -1
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue.d.ts +3 -6
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js +154 -154
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/category-picker/category-picker-styles.d.ts +83 -232
- package/dist/components/forms/category-picker/category-picker-styles.js +20 -26
- package/dist/components/forms/category-picker/category-picker-styles.js.map +1 -1
- package/dist/components/forms/check-control-styles.d.ts +61 -2
- package/dist/components/forms/check-control-styles.js +53 -46
- package/dist/components/forms/check-control-styles.js.map +1 -1
- package/dist/components/forms/checkbox/RuiCheckbox.js.map +1 -1
- package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js +32 -19
- 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.js.map +1 -1
- package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/field-defaults/RuiFieldDefaults.js +7 -0
- package/dist/components/forms/field-defaults/RuiFieldDefaults.js.map +1 -0
- package/dist/components/forms/field-defaults/RuiFieldDefaults.vue.d.ts +16 -0
- package/dist/components/forms/field-defaults/RuiFieldDefaults.vue_vue_type_script_setup_true_lang.js +18 -0
- package/dist/components/forms/field-defaults/RuiFieldDefaults.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/forms/field-label/RuiFieldLabel.js +7 -0
- package/dist/components/forms/field-label/RuiFieldLabel.js.map +1 -0
- package/dist/components/forms/field-label/RuiFieldLabel.vue.d.ts +17 -0
- package/dist/components/forms/field-label/RuiFieldLabel.vue_vue_type_script_setup_true_lang.js +57 -0
- package/dist/components/forms/field-label/RuiFieldLabel.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -1
- package/dist/components/forms/file-upload/RuiFileUpload.vue.d.ts +1 -1
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +56 -35
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/radio-button/radio/RuiRadio.js.map +1 -1
- package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js +14 -15
- 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.js.map +1 -1
- package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js +3 -3
- 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.js.map +1 -1
- package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js +6 -6
- 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.d.ts +3 -12
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +61 -56
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/select/RuiSimpleSelect.js.map +1 -1
- package/dist/components/forms/select/RuiSimpleSelect.vue.d.ts +0 -1
- package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js +13 -20
- 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.d.ts +99 -221
- package/dist/components/forms/select/menu-select-styles.js +1 -4
- package/dist/components/forms/select/menu-select-styles.js.map +1 -1
- package/dist/components/forms/slider/RuiSlider.js.map +1 -1
- package/dist/components/forms/slider/RuiSlider.vue.d.ts +0 -4
- package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js +129 -106
- package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/slider/slider-styles.d.ts +40 -40
- package/dist/components/forms/slider/slider-styles.js +67 -109
- package/dist/components/forms/slider/slider-styles.js.map +1 -1
- package/dist/components/forms/switch/RuiSwitch.js.map +1 -1
- package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js +33 -45
- package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/text-area/RuiTextArea.js.map +1 -1
- package/dist/components/forms/text-area/RuiTextArea.vue.d.ts +3 -2
- package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js +138 -117
- 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.d.ts +41 -115
- package/dist/components/forms/text-area/text-area-styles.js +34 -194
- package/dist/components/forms/text-area/text-area-styles.js.map +1 -1
- package/dist/components/forms/text-field/RuiTextField.js.map +1 -1
- package/dist/components/forms/text-field/RuiTextField.vue.d.ts +5 -2
- package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js +112 -105
- 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.d.ts +37 -145
- package/dist/components/forms/text-field/text-field-styles.js +24 -267
- package/dist/components/forms/text-field/text-field-styles.js.map +1 -1
- package/dist/components/forms/text-input-styles.d.ts +98 -229
- package/dist/components/forms/text-input-styles.js +63 -193
- package/dist/components/forms/text-input-styles.js.map +1 -1
- package/dist/components/helpers/RuiFormTextDetail.js.map +1 -1
- package/dist/components/helpers/RuiFormTextDetail.vue.d.ts +11 -1
- package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/icons/RuiIcon.js.map +1 -1
- package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js +7 -4
- package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/index.d.ts +5 -3
- package/dist/components/index.js +4 -3
- package/dist/components/loaders/RuiSkeletonBase.js.map +1 -1
- package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js +6 -5
- package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/loaders/RuiSkeletonLoader.js.map +1 -1
- package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js +8 -8
- package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/logos/RuiLogo.js.map +1 -1
- package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/badge/RuiBadge.js.map +1 -1
- package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js +76 -48
- package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/dialog/RuiDialog.js.map +1 -1
- package/dist/components/overlays/dialog/RuiDialog.vue.d.ts +3 -2
- package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js +17 -13
- 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 +9 -7
- package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js +33 -29
- package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.js.map +1 -1
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue.d.ts +6 -2
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js +49 -25
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/notification/RuiNotification.js.map +1 -1
- package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js +7 -8
- package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/tooltip/RuiTooltip.js.map +1 -1
- package/dist/components/overlays/tooltip/RuiTooltip.vue.d.ts +0 -5
- package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js +17 -11
- package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/tooltip/tooltip-styles.d.ts +5 -12
- package/dist/components/overlays/tooltip/tooltip-styles.js +11 -18
- package/dist/components/overlays/tooltip/tooltip-styles.js.map +1 -1
- package/dist/components/progress/RuiProgress.js.map +1 -1
- package/dist/components/progress/RuiProgress.vue.d.ts +4 -0
- package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js +73 -47
- package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/RuiFooterStepper.js.map +1 -1
- package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js +28 -29
- package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/RuiStepper.js.map +1 -1
- package/dist/components/steppers/RuiStepper.vue.d.ts +0 -4
- package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js +36 -29
- package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/RuiStepperIcon.js.map +1 -1
- package/dist/components/steppers/RuiStepperIcon.vue.d.ts +2 -0
- package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js +47 -47
- package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiDataTable.js.map +1 -1
- package/dist/components/tables/RuiDataTable.vue.d.ts +3 -6
- package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js +85 -67
- package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiExpandButton.js.map +1 -1
- package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTable.js.map +1 -1
- package/dist/components/tables/RuiTable.vue_vue_type_script_setup_true_lang.js +8 -5
- package/dist/components/tables/RuiTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTableEmptyState.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_vue_type_script_setup_true_lang.js +89 -67
- 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_vue_type_script_setup_true_lang.js +9 -12
- package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableGroupRow.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js +8 -4
- package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableMobileSort.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableRow.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js +47 -8
- package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table-styles.d.ts +24 -0
- package/dist/components/tables/data-table-styles.js +35 -20
- package/dist/components/tables/data-table-styles.js.map +1 -1
- package/dist/components/tables/table_no_data_placeholder.js +1 -1
- package/dist/components/tables/table_no_data_placeholder.js.map +1 -1
- package/dist/components/tables/table_no_data_placeholder_dark.js +1 -1
- package/dist/components/tables/table_no_data_placeholder_dark.js.map +1 -1
- package/dist/components/tables/use-pagination-navigation.js +1 -1
- package/dist/components/tabs/tab/RuiTab.js.map +1 -1
- package/dist/components/tabs/tab/RuiTab.vue.d.ts +2 -5
- package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js +95 -69
- 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 +1 -1
- package/dist/components/tabs/tab-item/RuiTabItem.js.map +1 -1
- package/dist/components/tabs/tab-item/RuiTabItem.vue.d.ts +0 -1
- package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js +5 -11
- 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 +8 -13
- package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tab-props.d.ts +7 -1
- package/dist/components/tabs/tab-props.js +7 -1
- package/dist/components/tabs/tab-props.js.map +1 -1
- package/dist/components/tabs/tabs/RuiTabs.js.map +1 -1
- package/dist/components/tabs/tabs/RuiTabs.vue.d.ts +2 -1
- package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js +188 -43
- package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tabs/use-tab-indicator.d.ts +27 -0
- package/dist/components/tabs/tabs/use-tab-indicator.js +67 -0
- package/dist/components/tabs/tabs/use-tab-indicator.js.map +1 -0
- package/dist/components/tabs/tabs/use-tab-keyboard.d.ts +17 -0
- package/dist/components/tabs/tabs/use-tab-keyboard.js +57 -0
- package/dist/components/tabs/tabs/use-tab-keyboard.js.map +1 -0
- package/dist/components/tabs/tabs/use-tab-routing.js +1 -2
- package/dist/components/tabs/tabs/use-tab-routing.js.map +1 -1
- package/dist/components/tabs/tabs/use-tab-scroll.js +15 -15
- package/dist/components/tabs/tabs/use-tab-scroll.js.map +1 -1
- package/dist/components/time-picker/RuiTimePicker.js.map +1 -1
- package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js +95 -93
- 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.d.ts +18 -0
- package/dist/components/time-picker/time-picker-styles.js +16 -10
- package/dist/components/time-picker/time-picker-styles.js.map +1 -1
- package/dist/composables/breakpoint.js +3 -3
- package/dist/composables/breakpoint.js.map +1 -1
- package/dist/composables/defaults/field.d.ts +22 -0
- package/dist/composables/defaults/field.js +29 -0
- package/dist/composables/defaults/field.js.map +1 -0
- package/dist/composables/dropdown-menu.d.ts +23 -11
- package/dist/composables/dropdown-menu.js +44 -34
- package/dist/composables/dropdown-menu.js.map +1 -1
- package/dist/composables/floating.d.ts +1 -3
- package/dist/composables/floating.js +16 -13
- package/dist/composables/floating.js.map +1 -1
- package/dist/composables/forms/auto-complete/chips.d.ts +22 -0
- package/dist/composables/forms/auto-complete/chips.js +42 -0
- package/dist/composables/forms/auto-complete/chips.js.map +1 -0
- package/dist/composables/forms/auto-complete/combobox.d.ts +25 -0
- package/dist/composables/forms/auto-complete/combobox.js +35 -0
- package/dist/composables/forms/auto-complete/combobox.js.map +1 -0
- package/dist/composables/forms/auto-complete/focus.d.ts +5 -2
- package/dist/composables/forms/auto-complete/focus.js +44 -19
- package/dist/composables/forms/auto-complete/focus.js.map +1 -1
- package/dist/composables/forms/auto-complete/index.d.ts +3 -0
- package/dist/composables/forms/auto-complete/keyboard-navigation.d.ts +8 -1
- package/dist/composables/forms/auto-complete/keyboard-navigation.js +49 -21
- package/dist/composables/forms/auto-complete/keyboard-navigation.js.map +1 -1
- package/dist/composables/forms/auto-complete/search.js +6 -7
- package/dist/composables/forms/auto-complete/search.js.map +1 -1
- package/dist/composables/forms/auto-complete/selection.d.ts +37 -0
- package/dist/composables/forms/auto-complete/selection.js +60 -0
- package/dist/composables/forms/auto-complete/selection.js.map +1 -0
- package/dist/composables/forms/auto-complete/value.js +20 -1
- package/dist/composables/forms/auto-complete/value.js.map +1 -1
- package/dist/composables/forms/category-picker/use-category-picker.js +1 -1
- package/dist/composables/forms/use-prepend-append-width.js +6 -6
- package/dist/composables/forms/use-prepend-append-width.js.map +1 -1
- package/dist/composables/keyboard-scroll.d.ts +17 -0
- package/dist/composables/keyboard-scroll.js +58 -0
- package/dist/composables/keyboard-scroll.js.map +1 -0
- package/dist/composables/overlay-stack.js +1 -1
- package/dist/composables/sticky-header.d.ts +8 -0
- package/dist/composables/sticky-header.js +21 -10
- package/dist/composables/sticky-header.js.map +1 -1
- package/dist/composables/tables/data-table/columns.js +1 -1
- package/dist/composables/tables/data-table/expansion.js +1 -1
- package/dist/composables/tables/data-table/grouping.js +27 -28
- package/dist/composables/tables/data-table/grouping.js.map +1 -1
- package/dist/composables/tables/data-table/page-scroll.d.ts +32 -0
- package/dist/composables/tables/data-table/page-scroll.js +144 -0
- package/dist/composables/tables/data-table/page-scroll.js.map +1 -0
- package/dist/composables/tables/data-table/pagination.js +1 -1
- package/dist/composables/tables/data-table/selection.js +37 -38
- package/dist/composables/tables/data-table/selection.js.map +1 -1
- package/dist/composables/tables/data-table/sort.js +1 -1
- package/dist/composables/theme.js +12 -12
- package/dist/composables/theme.js.map +1 -1
- package/dist/composables/timeout-manager.js +1 -1
- package/dist/consts/colors.d.ts +4 -0
- package/dist/consts/colors.js +1 -37
- package/dist/consts/colors.js.map +1 -1
- package/dist/consts/tokens.d.ts +56 -0
- package/dist/consts/tokens.js +46 -0
- package/dist/consts/tokens.js.map +1 -0
- package/dist/consts/typography.d.ts +51 -18
- package/dist/index.d.ts +7 -2
- package/dist/index.js +10 -6
- package/dist/index.js.map +1 -1
- package/dist/library-icons.json +0 -10
- package/dist/style.css +5629 -4678
- package/dist/styles/colors.css +315 -0
- package/dist/styles/tokens.css +50 -0
- package/dist/tailwind.css +145 -0
- package/dist/theme/theme.css +403 -0
- package/dist/theme.css +403 -0
- package/dist/types/dom.d.ts +9 -0
- package/dist/types/theme.d.ts +2 -3
- package/dist/types/theme.js.map +1 -1
- package/dist/utils/form-text-detail.js +1 -1
- package/dist/utils/helpers.d.ts +0 -8
- package/dist/utils/helpers.js +1 -2
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/tv.js +13 -21
- package/dist/utils/tv.js.map +1 -1
- package/dist/vendor/@vueuse/core/dist/index.js +1577 -0
- package/dist/vendor/@vueuse/core/dist/index.js.map +1 -0
- package/dist/vendor/@vueuse/shared/dist/index.js +563 -0
- package/dist/vendor/@vueuse/shared/dist/index.js.map +1 -0
- package/dist/vite-plugin/index.js +5 -6
- package/dist/vite-plugin/index.js.map +1 -1
- package/dist/web-types.json +278 -403
- package/package.json +17 -19
- package/dist/components/icons/LazyIcon.vue.d.ts +0 -8
- package/dist/components/steppers/RuiStepperCustomIcon.js +0 -7
- package/dist/components/steppers/RuiStepperCustomIcon.js.map +0 -1
- package/dist/components/steppers/RuiStepperCustomIcon.vue.d.ts +0 -8
- package/dist/components/steppers/RuiStepperCustomIcon.vue_vue_type_script_setup_true_lang.js +0 -43
- package/dist/components/steppers/RuiStepperCustomIcon.vue_vue_type_script_setup_true_lang.js.map +0 -1
- package/dist/composables/colors/common.d.ts +0 -20
- package/dist/composables/colors/index.d.ts +0 -3
- package/dist/composables/colors/text-input.d.ts +0 -27
- package/dist/composables/forms/use-label-with-quote.d.ts +0 -2
- package/dist/composables/popper.d.ts +0 -16
- package/dist/composables/popper.js +0 -23
- package/dist/composables/popper.js.map +0 -1
- package/dist/consts/forms/auto-complete/index.d.ts +0 -4
- package/dist/theme/index.d.ts +0 -5
- package/dist/theme/index.js +0 -162
- package/dist/theme/index.js.map +0 -1
- package/dist/utils/forms/auto-complete/index.d.ts +0 -2
|
@@ -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 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 modelHighlightedIndex: Ref<number> = ref(get(autoSelectFirst) ? 0 : -1);\n const modelUserNavigated = 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(modelHighlightedIndex);\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 // Outside the virtual list's rendered window, so render it first, 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(modelHighlightedIndex, index);\n }\n\n await adjustScrollByHighlightedIndex();\n }\n\n watch([isOpen, () => toValue(disabled)], async ([open, _]) => {\n await updateOpen(open);\n });\n\n watch(modelHighlightedIndex, async () => {\n await adjustScrollByHighlightedIndex();\n });\n\n watch(options, async () => {\n set(modelUserNavigated, false);\n if (get(modelHighlightedIndex) !== -1) {\n if (get(autoSelectFirst)) {\n set(modelHighlightedIndex, 0);\n await adjustScrollByHighlightedIndex();\n }\n else {\n set(modelHighlightedIndex, -1);\n scrollTo(0);\n }\n }\n else {\n scrollTo(0);\n }\n });\n\n watch(isOpen, (open) => {\n if (!open)\n set(modelUserNavigated, false);\n });\n\n const moveHighlight = (up: boolean): void => {\n if (!get(isOpen)) {\n toggle(true);\n return;\n }\n\n set(modelUserNavigated, 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(modelHighlightedIndex);\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(modelHighlightedIndex, position);\n return;\n }\n }\n };\n\n const applyHighlighted = (): void => {\n if (!setValue || !get(isOpen))\n return;\n\n const highlightedIndexVal = get(modelHighlightedIndex);\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 modelHighlightedIndex,\n isActiveItem,\n isGrouped,\n isItemDisabled,\n isOpen,\n itemIndexInValue,\n menuWidth,\n moveHighlight,\n optionsWithSelectedHidden: options,\n renderedData,\n toggle,\n modelUserNavigated,\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 { ComputedRef, 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\n/**\n * An item key or a resolver. `& string` lets Vue's compiler infer a String runtime type for the key\n * form; a bare generic `keyof` compiles to Function only, and a consumer's runtime warns.\n */\nexport type GroupBy<TItem> = (keyof TItem & string) | ((item: TItem) => string);\n\nexport type ItemDisabled<TItem> = (keyof TItem & string) | ((item: TItem) => boolean);\n\n/**\n * The rendered height of a default option row, a `list` button at its default or `sm` size.\n * The virtual list reserves this much per row, so a mismatch leaves a gap under the last option.\n *\n * @param dense - whether the options render at the dense size\n * @returns the row height in pixels\n */\nexport function getOptionHeight(dense: boolean | undefined): number {\n return dense ? 32 : 40;\n}\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 = getOptionHeight(false),\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 // typed as a plain ComputedRef so the published return type names nothing from VueUse\n const renderedData: ComputedRef<{ _index: number; item: TItem }[]> = 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 modelHighlightedIndex: Ref<number> = ref(get(autoSelectFirst) ? 0 : -1);\n const modelUserNavigated = 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(modelHighlightedIndex);\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 // Outside the virtual list's rendered window, so render it first, 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(modelHighlightedIndex, index);\n }\n\n await adjustScrollByHighlightedIndex();\n }\n\n watch([isOpen, () => toValue(disabled)], async ([open, _]) => {\n await updateOpen(open);\n });\n\n watch(modelHighlightedIndex, async () => {\n await adjustScrollByHighlightedIndex();\n });\n\n watch(options, async () => {\n set(modelUserNavigated, false);\n if (get(modelHighlightedIndex) !== -1) {\n if (get(autoSelectFirst)) {\n set(modelHighlightedIndex, 0);\n await adjustScrollByHighlightedIndex();\n }\n else {\n set(modelHighlightedIndex, -1);\n scrollTo(0);\n }\n }\n else {\n scrollTo(0);\n }\n });\n\n watch(isOpen, (open) => {\n if (!open)\n set(modelUserNavigated, false);\n });\n\n const moveHighlight = (up: boolean): void => {\n if (!get(isOpen)) {\n toggle(true);\n return;\n }\n\n set(modelUserNavigated, 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(modelHighlightedIndex);\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(modelHighlightedIndex, position);\n return;\n }\n }\n };\n\n const applyHighlighted = (): void => {\n if (!setValue || !get(isOpen))\n return;\n\n const highlightedIndexVal = get(modelHighlightedIndex);\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 modelHighlightedIndex,\n isActiveItem,\n isGrouped,\n isItemDisabled,\n isOpen,\n itemIndexInValue,\n menuWidth,\n moveHighlight,\n optionsWithSelectedHidden: options,\n renderedData,\n toggle,\n modelUserNavigated,\n valueKey,\n wrapperProps,\n };\n}\n"],"mappings":";;;;;;;;;;;AA8BA,SAAgB,gBAAgB,OAAoC;CAClE,OAAO,QAAQ,KAAK;AACtB;AA6BA,SAAgB,0BAAyC,EACvD,SACA,YACkC;CAClC,SAAS,QAAQ,MAAiC;EAChD,IAAI,UAAU;GACZ,IAAI,OAAO,aAAa,YACtB,OAAO,SAAS,IAAI;QACjB,OAAO,KAAK,SAAS,EAAE,SAAS;EACvC;EAEA,OAAO,MAAM,SAAS;CACxB;CAEA,SAAS,cACP,MAC6E;EAC7E,IAAI,SACF,OAAO,KAAK;EAEd,OAAO;CACT;CAEA,OAAO;EACL;EACA;CACF;AACF;AAEA,SAAS,gBAAuB,KAA2C;CACzE,IAAI,MAAM,QAAQ,GAAG,GACnB,OAAO;CACT,IAAI,QAAQ,QAAQ,QAAQ,KAAA,GAC1B,OAAO,CAAC,GAAG;CACb,OAAO,CAAC;AACV;AAEA,SAAgB,gBAA+B,EAC7C,aACA,iBACA,OACA,WAAW,OACX,eAAe,uBACf,SAAS,iBACT,cACA,QAAQ,gBACR,aAAa,gBAAgB,KAAK,GAClC,SACA,SAAS,UACT,SAAS,YACT,WAAW,GACX,cACA,UACA,UACA,OACA,SACA,gBACiC;CACjC,MAAM,EAAE,eAAe,sBAAsB,SAAS,mBAAmB,0BAA0B;EACjG;EACA;CACF,CAAC;CAED,MAAM,gBAAgB,yBAAyB;CAC/C,MAAM,UAAU,mBAAmB;CAEnC,MAAM,oBAAoB,eAAyB;EAEjD,MAAM,WAAoB,gBADd,IAAI,KAC0B,CAAG;EAC7C,MAAM,8BAAc,IAAI,IAAS;EACjC,KAAK,MAAM,QAAQ,UACjB,YAAY,IAAI,cAAc,IAAI,CAAC;EAErC,OAAO;CACT,CAAC;CAED,SAAS,aAAa,MAAsB;EAC1C,OAAO,IAAI,iBAAiB,CAAC,CAAC,IAAI,cAAc,IAAI,CAAC;CACvD;CAEA,MAAM,UAAU,eAAwB;EACtC,MAAM,UAAU,QAAQ,UAAU;EAClC,IAAI,CAAC,cACH,OAAO;EAET,OAAO,QAAQ,QAAO,SAAQ,CAAC,aAAa,IAAI,CAAC;CACnD,CAAC;CAED,SAAS,YAAY,MAAqB;EACxC,MAAM,QAAQ,QAAQ,OAAO;EAC7B,IAAI,CAAC,OACH,OAAO;EAET,IAAI,OAAO,UAAU,YACnB,OAAO,MAAM,IAAI;EAEnB,OAAO,OAAO,KAAK,UAAU,EAAE;CACjC;CAEA,SAAS,eAAe,MAAsB;EAC5C,MAAM,oBAAoB,QAAQ,YAAY;EAC9C,IAAI,CAAC,mBACH,OAAO;EAET,IAAI,OAAO,sBAAsB,YAC/B,OAAO,kBAAkB,IAAI;EAE/B,OAAO,QAAQ,KAAK,kBAAkB;CACxC;CAEA,MAAM,YAAY,eAAwB,QAAQ,OAAO,MAAM,KAAA,CAAS;CAExE,MAAM,iBAAiB,eAA6C;EAClE,IAAI,CAAC,IAAI,SAAS,GAChB,OAAO,CAAC;EAEV,MAAM,0BAAU,IAAI,IAAqB;EACzC,KAAK,MAAM,QAAQ,IAAI,OAAO,GAAG;GAC/B,MAAM,MAAM,YAAY,IAAI;GAC5B,MAAM,OAAO,QAAQ,IAAI,GAAG;GAC5B,IAAI,MACF,KAAK,KAAK,IAAI;QAEd,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC;EAC3B;EAEA,OAAO,MAAM,KAAK,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY;GAAE;GAAO;EAAM,EAAE;CACjF,CAAC;CAED,MAAM,EAAE,gBAAgB,MAAM,UAAU,iBAAiB,eAAsB,SAAS;EACtF;EACA;CACF,CAAC;CAGD,MAAM,eAA+D,YAAY,OAAO,EAAE,MAAM,OAAO,cAAc;EAAE;EAAQ,MAAM;CAAK,EAAE;CAE5I,MAAM,SAAS,kBAAkB,WAAoB,KAAK;CAE1D,MAAM,WAAW,eAAe;EAC9B,MAAM,WAAW,IAAI,KAAK;EAC1B,IAAI,CAAC,WAAW,CAAC,UACf,OAAO;EACT,OAAO,MAAM,QAAQ,QAAQ,IAAI,SAAS,KAAI,SAAQ,KAAK,QAAQ,IAAI,SAAS;CAClF,CAAC;CAED,MAAM,wBAAqC,IAAI,IAAI,eAAe,IAAI,IAAI,EAAE;CAC5E,MAAM,qBAAqB,WAAoB,KAAK;CAEpD,MAAM,oBAAoB,eAA6C;EACrE,IAAI,MAAM;EACV,IAAI,MAAM;EACV,KAAK,MAAM,UAAU,IAAI,OAAO,GAAG;GACjC,MAAM,SAAS,QAAQ,MAAM,CAAC,EAAE,SAAS,CAAC,EAAE,UAAU;GACtD,IAAI,QAAQ,KAAK,QAAQ,GAAG;IAC1B,MAAM;IACN,MAAM;GACR,OACK,IAAI,SAAS,KAChB,MAAM;QAEH,IAAI,SAAS,KAChB,MAAM;EAEV;EACA,OAAO;GAAE;GAAK;EAAI;CACpB,CAAC;CAED,MAAM,YAAY,eAAuB;EACvC,MAAM,EAAE,KAAK,QAAQ,IAAI,iBAAiB;EAC1C,MAAM,WAAW;EACjB,MAAM,WAAW;EACjB,MAAM,iBAAiB,QAAQ,KAAK,IAAI,KAAK;EAC7C,MAAM,aAAa,MAAM;EAEzB,SAAS,aAAa,OAAuB;GAC3C,MAAM,oBACH,eAAe,eAAe,KAAM,MAAM,cAAc,cAAc,KAAM;GAC/E,OAAO,GAAG,KAAK,IAAK,QAAQ,iBAAkB,KAAK,WAAW,kBAAkB,QAAQ,EAAE;EAC5F;EAEA,IAAI,cAAc,GAChB,OAAO,aAAa,GAAG;EAEzB,OAAO,aAAa,MAAM,aAAa,CAAC;CAC1C,CAAC;CAED,SAAS,OAAO,QAAiB,OAAa;EAC5C,IAAI,QAAQ,KAAK;CACnB;CAEA,SAAS,iBAAiB,MAAqB;EAE7C,MAAM,WAAoB,gBADd,IAAI,KAC0B,CAAG;EAE7C,IAAI,SAAS,WAAW,GACtB,OAAO;EAET,MAAM,SAAS,cAAc,IAAI;EACjC,OAAO,SAAS,WAAU,iBAAgB,cAAc,YAAY,MAAM,MAAM;CAClF;CAEA,SAAS,4BAAkC;EACzC,IAAI,QAAQ,CAAC,EACT,cAA2B,6BAA2B,CAAC,EACvD,eAAe,EAAE,OAAO,UAAU,CAAC;CACzC;CAEA,eAAe,iCAAgD;EAC7D,MAAM,QAAQ,IAAI,qBAAqB;EACvC,IAAI,UAAU,IACZ;EAEF,MAAM,SAAS;EACf,IAAI,IAAI,QAAQ,CAAC,EAAE,cAAc,6BAA2B,GAAG;GAC7D,0BAA0B;GAC1B;EACF;EAGA,SAAS,KAAK;EACd,MAAM,SAAS;EACf,0BAA0B;CAC5B;CAEA,eAAe,WAAW,MAA8B;EACtD,IAAI,CAAC,MACH;EAEF,MAAM,MAAM,IAAI,KAAK;EAGrB,IAAK,MAAM,QAAQ,GAAG,KAAK,IAAI,SAAS,KAAO,QAAQ,QAAQ,QAAQ,KAAA,GAAY;GACjF,MAAM,QAAQ,IAAI,OAAO,CAAC,CAAC,UAAU,YAAY;GACjD,IAAI,QAAQ,IACV,IAAI,uBAAuB,KAAK;EACpC;EAEA,MAAM,+BAA+B;CACvC;CAEA,MAAM,CAAC,cAAc,QAAQ,QAAQ,CAAC,GAAG,OAAO,CAAC,MAAM,OAAO;EAC5D,MAAM,WAAW,IAAI;CACvB,CAAC;CAED,MAAM,uBAAuB,YAAY;EACvC,MAAM,+BAA+B;CACvC,CAAC;CAED,MAAM,SAAS,YAAY;EACzB,IAAI,oBAAoB,KAAK;EAC7B,IAAI,IAAI,qBAAqB,MAAM,IAAI;GACrC,IAAI,IAAI,eAAe,GAAG;IACxB,IAAI,uBAAuB,CAAC;IAC5B,MAAM,+BAA+B;GACvC,OACK;IACH,IAAI,uBAAuB,EAAE;IAC7B,SAAS,CAAC;GACZ;EACF,OAEE,SAAS,CAAC;CAEd,CAAC;CAED,MAAM,SAAS,SAAS;EACtB,IAAI,CAAC,MACH,IAAI,oBAAoB,KAAK;CACjC,CAAC;CAED,MAAM,iBAAiB,OAAsB;EAC3C,IAAI,CAAC,IAAI,MAAM,GAAG;GAChB,OAAO,IAAI;GACX;EACF;EAEA,IAAI,oBAAoB,IAAI;EAE5B,MAAM,QAAQ,IAAI,OAAO;EACzB,MAAM,QAAQ,MAAM;EACpB,IAAI,UAAU,GACZ;EAEF,MAAM,OAAO,KAAK,KAAK;EACvB,IAAI,WAAW,IAAI,qBAAqB;EAExC,KAAK,IAAI,OAAO,GAAG,OAAO,OAAO,QAAQ;GACvC,YAAY;GACZ,IAAI,YAAY,OACd,WAAW;QACR,IAAI,WAAW,GAClB,WAAW,QAAQ;GAErB,MAAM,YAAY,MAAM;GACxB,IAAI,cAAc,KAAA,KAAa,CAAC,eAAe,SAAS,GAAG;IACzD,IAAI,uBAAuB,QAAQ;IACnC;GACF;EACF;CACF;CAEA,MAAM,yBAA+B;EACnC,IAAI,CAAC,YAAY,CAAC,IAAI,MAAM,GAC1B;EAEF,MAAM,sBAAsB,IAAI,qBAAqB;EACrD,IAAI,wBAAwB,IAC1B;EAEF,MAAM,QAAQ,IAAI,OAAO,CAAC,CAAC;EAC3B,IAAI,UAAU,KAAA,KAAa,CAAC,eAAe,KAAK,GAC9C,SAAS,KAAK;CAClB;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,2BAA2B;EAC3B;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { MaybeElement } from '../types/dom';
|
|
1
2
|
import { type VirtualElement as FloatingVirtualElement } from '@floating-ui/dom';
|
|
2
|
-
import { type MaybeElement } from '@vueuse/core';
|
|
3
3
|
import { type MaybeRefOrGetter, type Ref } from 'vue';
|
|
4
4
|
type VirtualElement = FloatingVirtualElement;
|
|
5
5
|
export declare const Placement: {
|
|
@@ -50,8 +50,6 @@ export interface FloatingOptions {
|
|
|
50
50
|
*/
|
|
51
51
|
size?: boolean;
|
|
52
52
|
}
|
|
53
|
-
/** Custom property carrying the space-aware max height set by the size middleware. */
|
|
54
|
-
export declare const FLOATING_MAX_HEIGHT_VAR = "--rui-floating-max-height";
|
|
55
53
|
export declare const DEFAULT_FLOATING_OPTIONS: Required<FloatingOptions>;
|
|
56
54
|
export interface UseFloatingReturn {
|
|
57
55
|
currentPlacement: Readonly<Ref<Placement>>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { get, set } from "../vendor/@vueuse/shared/dist/index.js";
|
|
2
|
+
import { unrefElement } from "../vendor/@vueuse/core/dist/index.js";
|
|
1
3
|
import { useTimeoutManager } from "./timeout-manager.js";
|
|
2
4
|
import { onMounted, readonly, ref, shallowRef, toValue, watchEffect } from "vue";
|
|
3
|
-
import { unrefElement } from "@vueuse/core";
|
|
4
|
-
import { get as get$1, set as set$1 } from "@vueuse/shared";
|
|
5
5
|
import { arrow, autoUpdate, computePosition, flip, offset, shift, size } from "@floating-ui/dom";
|
|
6
6
|
//#region src/composables/floating.ts
|
|
7
7
|
var Placement = {
|
|
@@ -64,7 +64,10 @@ function buildOffsetMiddleware(opts) {
|
|
|
64
64
|
function buildMiddleware(opts, arrowEl) {
|
|
65
65
|
const mw = [buildOffsetMiddleware(opts)];
|
|
66
66
|
if (opts.flip !== false) mw.push(flip());
|
|
67
|
-
mw.push(shift({
|
|
67
|
+
mw.push(shift({
|
|
68
|
+
padding: opts.shiftPadding ?? DEFAULT_FLOATING_OPTIONS.shiftPadding,
|
|
69
|
+
crossAxis: true
|
|
70
|
+
}));
|
|
68
71
|
if (arrowEl) mw.push(arrow({
|
|
69
72
|
element: arrowEl,
|
|
70
73
|
padding: 4
|
|
@@ -91,16 +94,16 @@ function useFloating(options, disabled = false, openDelay = 0, closeDelay = 0, v
|
|
|
91
94
|
const openTimeoutManager = useTimeoutManager();
|
|
92
95
|
const closeTimeoutManager = useTimeoutManager();
|
|
93
96
|
function onLeaveComplete() {
|
|
94
|
-
set
|
|
97
|
+
set(visible, false);
|
|
95
98
|
}
|
|
96
99
|
function onOpen(immediate = false) {
|
|
97
100
|
if (toValue(disabled)) return;
|
|
98
101
|
closeTimeoutManager.clear();
|
|
99
|
-
set
|
|
102
|
+
set(leavePending, false);
|
|
100
103
|
if (!openTimeoutManager.isActive()) {
|
|
101
|
-
set
|
|
104
|
+
set(visible, true);
|
|
102
105
|
openTimeoutManager.create(() => {
|
|
103
|
-
set
|
|
106
|
+
set(open, true);
|
|
104
107
|
}, immediate ? 0 : toValue(openDelay));
|
|
105
108
|
}
|
|
106
109
|
}
|
|
@@ -108,15 +111,15 @@ function useFloating(options, disabled = false, openDelay = 0, closeDelay = 0, v
|
|
|
108
111
|
if (toValue(disabled)) return;
|
|
109
112
|
openTimeoutManager.clear();
|
|
110
113
|
if (!closeTimeoutManager.isActive()) closeTimeoutManager.create(() => {
|
|
111
|
-
if (!get
|
|
112
|
-
set
|
|
114
|
+
if (!get(open)) onLeaveComplete();
|
|
115
|
+
set(open, false);
|
|
113
116
|
}, immediate ? 0 : toValue(closeDelay));
|
|
114
117
|
}
|
|
115
118
|
function onLeavePending() {
|
|
116
|
-
set
|
|
119
|
+
set(leavePending, true);
|
|
117
120
|
}
|
|
118
121
|
function getValidElements() {
|
|
119
|
-
if (!get
|
|
122
|
+
if (!get(popover) || !get(reference) && !toValue(virtualReference)) return null;
|
|
120
123
|
const popoverEl = unrefElement(popover);
|
|
121
124
|
const referenceEl = toValue(virtualReference) || unrefElement(reference);
|
|
122
125
|
if (!(popoverEl instanceof HTMLElement) || !referenceEl) return null;
|
|
@@ -142,7 +145,7 @@ function useFloating(options, disabled = false, openDelay = 0, closeDelay = 0, v
|
|
|
142
145
|
position: strategy,
|
|
143
146
|
top: `${result.y}px`
|
|
144
147
|
});
|
|
145
|
-
set
|
|
148
|
+
set(currentPlacement, result.placement);
|
|
146
149
|
applyArrowStyles(arrowEl, result);
|
|
147
150
|
}
|
|
148
151
|
function startAutoUpdate() {
|
|
@@ -186,6 +189,6 @@ function useFloating(options, disabled = false, openDelay = 0, closeDelay = 0, v
|
|
|
186
189
|
};
|
|
187
190
|
}
|
|
188
191
|
//#endregion
|
|
189
|
-
export { DEFAULT_FLOATING_OPTIONS,
|
|
192
|
+
export { DEFAULT_FLOATING_OPTIONS, Placement, Strategy, useFloating };
|
|
190
193
|
|
|
191
194
|
//# 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 size,\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; defaults to `Placement.bottom`. */\n placement?: Placement;\n /** CSS positioning strategy; defaults to `Strategy.absolute`. */\n strategy?: Strategy;\n /** Main-axis and/or cross-axis offset from the reference element; defaults to 2. */\n offset?: number | { mainAxis?: number; crossAxis?: number };\n /** Whether to flip to the opposite side when overflowing; defaults to true. */\n flip?: boolean;\n /** Padding from viewport edges for shift middleware; defaults to 8. */\n shiftPadding?: number;\n /** Whether to auto-update position on scroll/resize; defaults to true. */\n autoUpdate?: boolean | { scroll?: boolean; resize?: boolean };\n /**\n * Cap the floating element to the space available toward the viewport edge so\n * it never overflows the window. Exposes the measured space as the\n * `--rui-floating-max-height` custom property on the floating element; the\n * content is responsible for consuming it by capping its own max-height to\n * that variable and scrolling internally. Defaults to false.\n */\n size?: boolean;\n}\n\n/** Custom property carrying the space-aware max height set by the size middleware. */\nexport const FLOATING_MAX_HEIGHT_VAR = '--rui-floating-max-height';\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 size: false,\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\n/**\n * Cap the floating element to the space available toward the viewport edge and\n * expose it as {@link FLOATING_MAX_HEIGHT_VAR}. The content decides how to use\n * it (cap its own height and scroll internally); writing a custom property\n * instead of a hard max-height keeps this non-invasive for elements that opt in\n * but size themselves differently.\n */\nfunction buildSizeMiddleware(padding: number): Middleware {\n return size({\n padding,\n apply({ availableHeight, elements }) {\n elements.floating.style.setProperty(FLOATING_MAX_HEIGHT_VAR, `${Math.max(0, Math.floor(availableHeight))}px`);\n },\n });\n}\n\n/**\n * The offset middleware, from either the shorthand distance or the per-axis\n * form, falling back to the default distance on the main axis.\n */\nfunction buildOffsetMiddleware(opts: FloatingOptions): Middleware {\n const off = opts.offset ?? DEFAULT_FLOATING_OPTIONS.offset;\n\n if (typeof off === 'number')\n return offset(off);\n\n const defaultOffset = typeof DEFAULT_FLOATING_OPTIONS.offset === 'number' ? DEFAULT_FLOATING_OPTIONS.offset : 0;\n return offset({ mainAxis: off.mainAxis ?? defaultOffset, crossAxis: off.crossAxis ?? 0 });\n}\n\nfunction buildMiddleware(opts: FloatingOptions, arrowEl: HTMLElement | null): Middleware[] {\n const mw: Middleware[] = [buildOffsetMiddleware(opts)];\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 if (opts.size === true)\n mw.push(buildSizeMiddleware(opts.shiftPadding ?? DEFAULT_FLOATING_OPTIONS.shiftPadding));\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 type { MaybeElement } from '@/types/dom';\nimport {\n arrow,\n autoUpdate,\n computePosition,\n type ComputePositionReturn,\n flip,\n type VirtualElement as FloatingVirtualElement,\n type Middleware,\n offset,\n shift,\n size,\n} from '@floating-ui/dom';\nimport { 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; defaults to `Placement.bottom`. */\n placement?: Placement;\n /** CSS positioning strategy; defaults to `Strategy.absolute`. */\n strategy?: Strategy;\n /** Main-axis and/or cross-axis offset from the reference element; defaults to 2. */\n offset?: number | { mainAxis?: number; crossAxis?: number };\n /** Whether to flip to the opposite side when overflowing; defaults to true. */\n flip?: boolean;\n /** Padding from viewport edges for shift middleware; defaults to 8. */\n shiftPadding?: number;\n /** Whether to auto-update position on scroll/resize; defaults to true. */\n autoUpdate?: boolean | { scroll?: boolean; resize?: boolean };\n /**\n * Cap the floating element to the space available toward the viewport edge so\n * it never overflows the window. Exposes the measured space as the\n * `--rui-floating-max-height` custom property on the floating element; the\n * content is responsible for consuming it by capping its own max-height to\n * that variable and scrolling internally. Defaults to false.\n */\n size?: boolean;\n}\n\n/** Custom property carrying the space-aware max height set by the size middleware. */\nconst FLOATING_MAX_HEIGHT_VAR = '--rui-floating-max-height';\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 size: false,\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\n/**\n * Cap the floating element to the space available toward the viewport edge and\n * expose it as {@link FLOATING_MAX_HEIGHT_VAR}. The content decides how to use\n * it (cap its own height and scroll internally); writing a custom property\n * instead of a hard max-height keeps this non-invasive for elements that opt in\n * but size themselves differently.\n */\nfunction buildSizeMiddleware(padding: number): Middleware {\n return size({\n padding,\n apply({ availableHeight, elements }) {\n elements.floating.style.setProperty(FLOATING_MAX_HEIGHT_VAR, `${Math.max(0, Math.floor(availableHeight))}px`);\n },\n });\n}\n\n/**\n * The offset middleware, from either the shorthand distance or the per-axis\n * form, falling back to the default distance on the main axis.\n */\nfunction buildOffsetMiddleware(opts: FloatingOptions): Middleware {\n const off = opts.offset ?? DEFAULT_FLOATING_OPTIONS.offset;\n\n if (typeof off === 'number')\n return offset(off);\n\n const defaultOffset = typeof DEFAULT_FLOATING_OPTIONS.offset === 'number' ? DEFAULT_FLOATING_OPTIONS.offset : 0;\n return offset({ mainAxis: off.mainAxis ?? defaultOffset, crossAxis: off.crossAxis ?? 0 });\n}\n\nfunction buildMiddleware(opts: FloatingOptions, arrowEl: HTMLElement | null): Middleware[] {\n const mw: Middleware[] = [buildOffsetMiddleware(opts)];\n\n if (opts.flip !== false)\n mw.push(flip());\n\n // `crossAxis`: when neither side fits, overlap the activator rather than open past the viewport edge\n mw.push(shift({ padding: opts.shiftPadding ?? DEFAULT_FLOATING_OPTIONS.shiftPadding, crossAxis: true }));\n\n if (arrowEl)\n mw.push(arrow({ element: arrowEl, padding: 4 }));\n\n if (opts.size === true)\n mw.push(buildSizeMiddleware(opts.shiftPadding ?? DEFAULT_FLOATING_OPTIONS.shiftPadding));\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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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface UseAutoCompleteChipsDeps<TItem> {
|
|
2
|
+
/** Moves focus to the search input, which keeps it while a chip is selected. */
|
|
3
|
+
focusInput: () => void;
|
|
4
|
+
getIdentifier: (item: TItem) => unknown;
|
|
5
|
+
/** Toggles an item in the selection, which removes a chip's item. */
|
|
6
|
+
setValue: (item: TItem) => void;
|
|
7
|
+
setValueFocus: (index: number) => void;
|
|
8
|
+
}
|
|
9
|
+
export interface UseAutoCompleteChipsReturn<TItem> {
|
|
10
|
+
chipAttrs: (item: TItem, index: number) => Record<string, unknown>;
|
|
11
|
+
/** Selects a clicked chip for Backspace and the arrow keys, with focus left in the input. */
|
|
12
|
+
selectChip: (index: number) => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The attributes and handlers each selected chip takes. A chip never takes focus: the input keeps
|
|
16
|
+
* it, where no browser shortcut can claim Backspace, and the chip the keys act on is only drawn as
|
|
17
|
+
* selected. A click selects a chip and its close button removes it.
|
|
18
|
+
*
|
|
19
|
+
* @param deps - the selection operations the handlers call
|
|
20
|
+
* @returns a function building one chip's attributes, and the click selection
|
|
21
|
+
*/
|
|
22
|
+
export declare function useAutoCompleteChips<TItem>(deps: UseAutoCompleteChipsDeps<TItem>): UseAutoCompleteChipsReturn<TItem>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//#region src/composables/forms/auto-complete/chips.ts
|
|
2
|
+
/**
|
|
3
|
+
* The attributes and handlers each selected chip takes. A chip never takes focus: the input keeps
|
|
4
|
+
* it, where no browser shortcut can claim Backspace, and the chip the keys act on is only drawn as
|
|
5
|
+
* selected. A click selects a chip and its close button removes it.
|
|
6
|
+
*
|
|
7
|
+
* @param deps - the selection operations the handlers call
|
|
8
|
+
* @returns a function building one chip's attributes, and the click selection
|
|
9
|
+
*/
|
|
10
|
+
function useAutoCompleteChips(deps) {
|
|
11
|
+
/**
|
|
12
|
+
* Focuses the input before selecting, since the input's focus handler clears any selection.
|
|
13
|
+
*
|
|
14
|
+
* @param index - the clicked chip's place among the values
|
|
15
|
+
*/
|
|
16
|
+
function selectChip(index) {
|
|
17
|
+
deps.focusInput();
|
|
18
|
+
deps.setValueFocus(index);
|
|
19
|
+
}
|
|
20
|
+
function chipAttrs(item, index) {
|
|
21
|
+
return {
|
|
22
|
+
"data-index": index,
|
|
23
|
+
"data-value": deps.getIdentifier(item),
|
|
24
|
+
"onClick": (event) => {
|
|
25
|
+
event.stopPropagation();
|
|
26
|
+
selectChip(index);
|
|
27
|
+
},
|
|
28
|
+
"onClick:close": () => {
|
|
29
|
+
deps.focusInput();
|
|
30
|
+
deps.setValue(item);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
chipAttrs,
|
|
36
|
+
selectChip
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { useAutoCompleteChips };
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=chips.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chips.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/chips.ts"],"sourcesContent":["export interface UseAutoCompleteChipsDeps<TItem> {\n /** Moves focus to the search input, which keeps it while a chip is selected. */\n focusInput: () => void;\n getIdentifier: (item: TItem) => unknown;\n /** Toggles an item in the selection, which removes a chip's item. */\n setValue: (item: TItem) => void;\n setValueFocus: (index: number) => void;\n}\n\nexport interface UseAutoCompleteChipsReturn<TItem> {\n chipAttrs: (item: TItem, index: number) => Record<string, unknown>;\n /** Selects a clicked chip for Backspace and the arrow keys, with focus left in the input. */\n selectChip: (index: number) => void;\n}\n\n/**\n * The attributes and handlers each selected chip takes. A chip never takes focus: the input keeps\n * it, where no browser shortcut can claim Backspace, and the chip the keys act on is only drawn as\n * selected. A click selects a chip and its close button removes it.\n *\n * @param deps - the selection operations the handlers call\n * @returns a function building one chip's attributes, and the click selection\n */\nexport function useAutoCompleteChips<TItem>(deps: UseAutoCompleteChipsDeps<TItem>): UseAutoCompleteChipsReturn<TItem> {\n /**\n * Focuses the input before selecting, since the input's focus handler clears any selection.\n *\n * @param index - the clicked chip's place among the values\n */\n function selectChip(index: number): void {\n deps.focusInput();\n deps.setValueFocus(index);\n }\n\n function chipAttrs(item: TItem, index: number): Record<string, unknown> {\n return {\n 'data-index': index,\n 'data-value': deps.getIdentifier(item),\n 'onClick': (event: MouseEvent): void => {\n event.stopPropagation();\n selectChip(index);\n },\n 'onClick:close': (): void => {\n deps.focusInput();\n deps.setValue(item);\n },\n };\n }\n\n return { chipAttrs, selectChip };\n}\n"],"mappings":";;;;;;;;;AAuBA,SAAgB,qBAA4B,MAA0E;;;;;;CAMpH,SAAS,WAAW,OAAqB;EACvC,KAAK,WAAW;EAChB,KAAK,cAAc,KAAK;CAC1B;CAEA,SAAS,UAAU,MAAa,OAAwC;EACtE,OAAO;GACL,cAAc;GACd,cAAc,KAAK,cAAc,IAAI;GACrC,YAAY,UAA4B;IACtC,MAAM,gBAAgB;IACtB,WAAW,KAAK;GAClB;GACA,uBAA6B;IAC3B,KAAK,WAAW;IAChB,KAAK,SAAS,IAAI;GACpB;EACF;CACF;CAEA,OAAO;EAAE;EAAW;CAAW;AACjC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ComputedRef, MaybeRefOrGetter } from 'vue';
|
|
2
|
+
export interface UseAutoCompleteComboboxReturn {
|
|
3
|
+
/** Prefix of each option's id, an option's id being `${prefix}-${index}` in the flat option list. */
|
|
4
|
+
optionIdPrefix: string;
|
|
5
|
+
/** The highlighted option, which a screen reader announces while focus stays in the input. */
|
|
6
|
+
activeDescendant: ComputedRef<string | undefined>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The ARIA 1.2 combobox wiring of the auto-complete: the input is the combobox, and since focus
|
|
10
|
+
* never leaves it while the user arrows through the list, it names the highlighted option.
|
|
11
|
+
*
|
|
12
|
+
* @param isOpen - whether the listbox is open
|
|
13
|
+
* @param highlightedIndex - the highlighted option's place in the flat option list, -1 for none
|
|
14
|
+
* @returns the option id prefix and the active descendant to bind on the input
|
|
15
|
+
*/
|
|
16
|
+
export declare function useAutoCompleteCombobox(isOpen: MaybeRefOrGetter<boolean>, highlightedIndex: MaybeRefOrGetter<number>): UseAutoCompleteComboboxReturn;
|
|
17
|
+
/**
|
|
18
|
+
* Splits a caller's attributes between the visual box and the input, which is the combobox: an
|
|
19
|
+
* `aria-label` or `aria-describedby` passed to the component has to name the combobox.
|
|
20
|
+
*
|
|
21
|
+
* @param attrs - the attributes passed to the component
|
|
22
|
+
* @param aria - true for the `aria-*` ones, false for the rest
|
|
23
|
+
* @returns the matching attributes
|
|
24
|
+
*/
|
|
25
|
+
export declare function splitAriaAttrs(attrs: Record<string, unknown>, aria: boolean): Record<string, unknown>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { computed, toValue, useId } from "vue";
|
|
2
|
+
//#region src/composables/forms/auto-complete/combobox.ts
|
|
3
|
+
/**
|
|
4
|
+
* The ARIA 1.2 combobox wiring of the auto-complete: the input is the combobox, and since focus
|
|
5
|
+
* never leaves it while the user arrows through the list, it names the highlighted option.
|
|
6
|
+
*
|
|
7
|
+
* @param isOpen - whether the listbox is open
|
|
8
|
+
* @param highlightedIndex - the highlighted option's place in the flat option list, -1 for none
|
|
9
|
+
* @returns the option id prefix and the active descendant to bind on the input
|
|
10
|
+
*/
|
|
11
|
+
function useAutoCompleteCombobox(isOpen, highlightedIndex) {
|
|
12
|
+
const optionIdPrefix = useId();
|
|
13
|
+
return {
|
|
14
|
+
activeDescendant: computed(() => {
|
|
15
|
+
const index = toValue(highlightedIndex);
|
|
16
|
+
return toValue(isOpen) && index > -1 ? `${optionIdPrefix}-${index}` : void 0;
|
|
17
|
+
}),
|
|
18
|
+
optionIdPrefix
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Splits a caller's attributes between the visual box and the input, which is the combobox: an
|
|
23
|
+
* `aria-label` or `aria-describedby` passed to the component has to name the combobox.
|
|
24
|
+
*
|
|
25
|
+
* @param attrs - the attributes passed to the component
|
|
26
|
+
* @param aria - true for the `aria-*` ones, false for the rest
|
|
27
|
+
* @returns the matching attributes
|
|
28
|
+
*/
|
|
29
|
+
function splitAriaAttrs(attrs, aria) {
|
|
30
|
+
return Object.fromEntries(Object.entries(attrs).filter(([key]) => key.startsWith("aria-") === aria));
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { splitAriaAttrs, useAutoCompleteCombobox };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=combobox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combobox.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/combobox.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter } from 'vue';\n\nexport interface UseAutoCompleteComboboxReturn {\n /** Prefix of each option's id, an option's id being `${prefix}-${index}` in the flat option list. */\n optionIdPrefix: string;\n /** The highlighted option, which a screen reader announces while focus stays in the input. */\n activeDescendant: ComputedRef<string | undefined>;\n}\n\n/**\n * The ARIA 1.2 combobox wiring of the auto-complete: the input is the combobox, and since focus\n * never leaves it while the user arrows through the list, it names the highlighted option.\n *\n * @param isOpen - whether the listbox is open\n * @param highlightedIndex - the highlighted option's place in the flat option list, -1 for none\n * @returns the option id prefix and the active descendant to bind on the input\n */\nexport function useAutoCompleteCombobox(\n isOpen: MaybeRefOrGetter<boolean>,\n highlightedIndex: MaybeRefOrGetter<number>,\n): UseAutoCompleteComboboxReturn {\n const optionIdPrefix = useId();\n\n const activeDescendant = computed<string | undefined>(() => {\n const index = toValue(highlightedIndex);\n return toValue(isOpen) && index > -1 ? `${optionIdPrefix}-${index}` : undefined;\n });\n\n return { activeDescendant, optionIdPrefix };\n}\n\n/**\n * Splits a caller's attributes between the visual box and the input, which is the combobox: an\n * `aria-label` or `aria-describedby` passed to the component has to name the combobox.\n *\n * @param attrs - the attributes passed to the component\n * @param aria - true for the `aria-*` ones, false for the rest\n * @returns the matching attributes\n */\nexport function splitAriaAttrs(attrs: Record<string, unknown>, aria: boolean): Record<string, unknown> {\n return Object.fromEntries(Object.entries(attrs).filter(([key]) => key.startsWith('aria-') === aria));\n}\n"],"mappings":";;;;;;;;;;AAiBA,SAAgB,wBACd,QACA,kBAC+B;CAC/B,MAAM,iBAAiB,MAAM;CAO7B,OAAO;EAAE,kBALgB,eAAmC;GAC1D,MAAM,QAAQ,QAAQ,gBAAgB;GACtC,OAAO,QAAQ,MAAM,KAAK,QAAQ,KAAK,GAAG,eAAe,GAAG,UAAU,KAAA;EACxE,CAES;EAAkB;CAAe;AAC5C;;;;;;;;;AAUA,SAAgB,eAAe,OAAgC,MAAwC;CACrG,OAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,CAAC,CAAC,QAAQ,CAAC,SAAS,IAAI,WAAW,OAAO,MAAM,IAAI,CAAC;AACrG"}
|
|
@@ -8,7 +8,6 @@ export interface UseAutoCompleteFocusOptions {
|
|
|
8
8
|
disabled: MaybeRefOrGetter<boolean>;
|
|
9
9
|
}
|
|
10
10
|
export interface UseAutoCompleteFocusDeps {
|
|
11
|
-
activatorFocused: Ref<boolean>;
|
|
12
11
|
activatorFocusedWithin: Ref<boolean>;
|
|
13
12
|
focusedValueIndex: Ref<number>;
|
|
14
13
|
internalSearch: Ref<string>;
|
|
@@ -22,9 +21,13 @@ export interface UseAutoCompleteFocusDeps {
|
|
|
22
21
|
}
|
|
23
22
|
export interface UseAutoCompleteFocusReturn {
|
|
24
23
|
anyFocused: ComputedRef<boolean>;
|
|
24
|
+
/** Whether the user is searching: the input has focus and is not just showing a picked value. */
|
|
25
|
+
editing: ComputedRef<boolean>;
|
|
25
26
|
inputClass: ComputedRef<string>;
|
|
26
|
-
onActivatorFocused: () => Promise<void>;
|
|
27
27
|
onInputFocused: () => void;
|
|
28
|
+
onSettledKeydown: (event: KeyboardEvent) => void;
|
|
28
29
|
setInputFocus: () => Promise<void>;
|
|
30
|
+
settleOnInput: () => void;
|
|
31
|
+
unsettle: () => void;
|
|
29
32
|
}
|
|
30
33
|
export declare function useAutoCompleteFocus(options: UseAutoCompleteFocusOptions, deps: UseAutoCompleteFocusDeps): UseAutoCompleteFocusReturn;
|
|
@@ -1,32 +1,52 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { get as get$1, set as set$1 } from "@vueuse/shared";
|
|
1
|
+
import { get, set, watchDebounced } from "../../../vendor/@vueuse/shared/dist/index.js";
|
|
2
|
+
import { computed, nextTick, shallowRef, toValue, watch } from "vue";
|
|
4
3
|
//#region src/composables/forms/auto-complete/focus.ts
|
|
5
4
|
function useAutoCompleteFocus(options, deps) {
|
|
6
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The input holds focus after a pick, as the combobox, but shows the picked value rather than an
|
|
7
|
+
* empty search until the user types, clicks or opens the list again.
|
|
8
|
+
*/
|
|
9
|
+
const settled = shallowRef(false);
|
|
10
|
+
const anyFocused = computed(() => get(deps.activatorFocusedWithin) || get(deps.menuWrapperFocusedWithin));
|
|
11
|
+
const editing = computed(() => get(deps.searchInputFocused) && !get(settled));
|
|
7
12
|
const inputClass = computed(() => {
|
|
8
|
-
const isFocused = get
|
|
13
|
+
const isFocused = get(anyFocused);
|
|
9
14
|
const isDisabled = toValue(options.disabled);
|
|
10
15
|
const shouldApply = toValue(options.shouldApplyValueAsSearch);
|
|
11
|
-
const hasSearch = get
|
|
16
|
+
const hasSearch = get(deps.internalSearch);
|
|
12
17
|
if ((!isFocused || isDisabled) && !shouldApply) return "w-0 h-0";
|
|
13
18
|
if (hasSearch) return "flex-1 min-w-[4rem]";
|
|
14
19
|
return "flex-1 min-w-0";
|
|
15
20
|
});
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
set$1(deps.searchInputFocused, true);
|
|
19
|
-
});
|
|
21
|
+
function unsettle() {
|
|
22
|
+
set(settled, false);
|
|
20
23
|
}
|
|
21
|
-
|
|
24
|
+
/** Puts focus on the input, as the combobox, while it keeps showing the value just picked. */
|
|
25
|
+
function settleOnInput() {
|
|
26
|
+
set(settled, true);
|
|
27
|
+
set(deps.searchInputFocused, true);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The first character typed after a pick replaces the shown value, as it would after tabbing in,
|
|
31
|
+
* rather than adding to it.
|
|
32
|
+
*
|
|
33
|
+
* @param event - the key press on the input
|
|
34
|
+
*/
|
|
35
|
+
function onSettledKeydown(event) {
|
|
36
|
+
if (!get(settled) || event.key.length !== 1 || event.ctrlKey || event.metaKey || event.altKey) return;
|
|
37
|
+
get(deps.textInput)?.select();
|
|
38
|
+
unsettle();
|
|
39
|
+
}
|
|
40
|
+
async function setInputFocus() {
|
|
41
|
+
unsettle();
|
|
22
42
|
await nextTick(() => {
|
|
23
|
-
|
|
43
|
+
set(deps.searchInputFocused, true);
|
|
24
44
|
});
|
|
25
45
|
}
|
|
26
46
|
function onInputFocused() {
|
|
27
|
-
set
|
|
28
|
-
if (toValue(options.shouldApplyValueAsSearch)) get
|
|
29
|
-
if (!get
|
|
47
|
+
set(deps.focusedValueIndex, -1);
|
|
48
|
+
if (toValue(options.shouldApplyValueAsSearch) && !get(settled)) get(deps.textInput)?.select();
|
|
49
|
+
if (!get(deps.isOpen)) set(deps.justOpened, true);
|
|
30
50
|
}
|
|
31
51
|
/**
|
|
32
52
|
* The search text as it stood when focus was lost, kept for the custom-value
|
|
@@ -35,11 +55,13 @@ function useAutoCompleteFocus(options, deps) {
|
|
|
35
55
|
*/
|
|
36
56
|
let pendingCustomSearch = "";
|
|
37
57
|
watch(anyFocused, (focused) => {
|
|
38
|
-
if (
|
|
58
|
+
if (focused) return;
|
|
59
|
+
unsettle();
|
|
60
|
+
if (toValue(options.customValue)) pendingCustomSearch = get(deps.internalSearch);
|
|
39
61
|
});
|
|
40
62
|
watchDebounced(anyFocused, (focused) => {
|
|
41
63
|
if (!focused) {
|
|
42
|
-
set
|
|
64
|
+
set(deps.isOpen, false);
|
|
43
65
|
const customValue = toValue(options.customValue);
|
|
44
66
|
const searchToUse = pendingCustomSearch;
|
|
45
67
|
pendingCustomSearch = "";
|
|
@@ -55,10 +77,13 @@ function useAutoCompleteFocus(options, deps) {
|
|
|
55
77
|
});
|
|
56
78
|
return {
|
|
57
79
|
anyFocused,
|
|
80
|
+
editing,
|
|
58
81
|
inputClass,
|
|
59
|
-
onActivatorFocused,
|
|
60
82
|
onInputFocused,
|
|
61
|
-
|
|
83
|
+
onSettledKeydown,
|
|
84
|
+
setInputFocus,
|
|
85
|
+
settleOnInput,
|
|
86
|
+
unsettle
|
|
62
87
|
};
|
|
63
88
|
}
|
|
64
89
|
//#endregion
|
|
@@ -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
|
|
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 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 /** Whether the user is searching: the input has focus and is not just showing a picked value. */\n editing: ComputedRef<boolean>;\n inputClass: ComputedRef<string>;\n onInputFocused: () => void;\n onSettledKeydown: (event: KeyboardEvent) => void;\n setInputFocus: () => Promise<void>;\n settleOnInput: () => void;\n unsettle: () => void;\n}\n\nexport function useAutoCompleteFocus(\n options: UseAutoCompleteFocusOptions,\n deps: UseAutoCompleteFocusDeps,\n): UseAutoCompleteFocusReturn {\n /**\n * The input holds focus after a pick, as the combobox, but shows the picked value rather than an\n * empty search until the user types, clicks or opens the list again.\n */\n const settled = shallowRef<boolean>(false);\n\n const anyFocused = computed<boolean>(\n () => get(deps.activatorFocusedWithin) || get(deps.menuWrapperFocusedWithin),\n );\n\n const editing = computed<boolean>(() => get(deps.searchInputFocused) && !get(settled));\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 function unsettle(): void {\n set(settled, false);\n }\n\n /** Puts focus on the input, as the combobox, while it keeps showing the value just picked. */\n function settleOnInput(): void {\n set(settled, true);\n set(deps.searchInputFocused, true);\n }\n\n /**\n * The first character typed after a pick replaces the shown value, as it would after tabbing in,\n * rather than adding to it.\n *\n * @param event - the key press on the input\n */\n function onSettledKeydown(event: KeyboardEvent): void {\n if (!get(settled) || event.key.length !== 1 || event.ctrlKey || event.metaKey || event.altKey)\n return;\n get(deps.textInput)?.select();\n unsettle();\n }\n\n async function setInputFocus(): Promise<void> {\n unsettle();\n await nextTick(() => {\n set(deps.searchInputFocused, true);\n });\n }\n\n function onInputFocused(): void {\n set(deps.focusedValueIndex, -1);\n\n // focus coming back after a pick keeps the value as it is, unselected\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n if (shouldApply && !get(settled)) {\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 /**\n * The search text as it stood when focus was lost, kept for the custom-value\n * blur flow: it is captured before the debounced handler runs, because the\n * watchers in value.ts clear the search when the menu closes.\n */\n let pendingCustomSearch = '';\n\n watch(anyFocused, (focused) => {\n if (focused)\n return;\n unsettle();\n if (toValue(options.customValue))\n pendingCustomSearch = get(deps.internalSearch);\n });\n\n // Debounced, so the menu does not close for a moment while focus moves between its own elements\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 editing,\n inputClass,\n onInputFocused,\n onSettledKeydown,\n setInputFocus,\n settleOnInput,\n unsettle,\n };\n}\n"],"mappings":";;;AAoCA,SAAgB,qBACd,SACA,MAC4B;;;;;CAK5B,MAAM,UAAU,WAAoB,KAAK;CAEzC,MAAM,aAAa,eACX,IAAI,KAAK,sBAAsB,KAAK,IAAI,KAAK,wBAAwB,CAC7E;CAEA,MAAM,UAAU,eAAwB,IAAI,KAAK,kBAAkB,KAAK,CAAC,IAAI,OAAO,CAAC;CAErF,MAAM,aAAa,eAAuB;EACxC,MAAM,YAAY,IAAI,UAAU;EAChC,MAAM,aAAa,QAAQ,QAAQ,QAAQ;EAC3C,MAAM,cAAc,QAAQ,QAAQ,wBAAwB;EAC5D,MAAM,YAAY,IAAI,KAAK,cAAc;EAEzC,KAAK,CAAC,aAAa,eAAe,CAAC,aACjC,OAAO;EACT,IAAI,WACF,OAAO;EACT,OAAO;CACT,CAAC;CAED,SAAS,WAAiB;EACxB,IAAI,SAAS,KAAK;CACpB;;CAGA,SAAS,gBAAsB;EAC7B,IAAI,SAAS,IAAI;EACjB,IAAI,KAAK,oBAAoB,IAAI;CACnC;;;;;;;CAQA,SAAS,iBAAiB,OAA4B;EACpD,IAAI,CAAC,IAAI,OAAO,KAAK,MAAM,IAAI,WAAW,KAAK,MAAM,WAAW,MAAM,WAAW,MAAM,QACrF;EACF,IAAI,KAAK,SAAS,CAAC,EAAE,OAAO;EAC5B,SAAS;CACX;CAEA,eAAe,gBAA+B;EAC5C,SAAS;EACT,MAAM,eAAe;GACnB,IAAI,KAAK,oBAAoB,IAAI;EACnC,CAAC;CACH;CAEA,SAAS,iBAAuB;EAC9B,IAAI,KAAK,mBAAmB,EAAE;EAI9B,IADoB,QAAQ,QAAQ,wBAChC,KAAe,CAAC,IAAI,OAAO,GAE7B,IADsB,KAAK,SAC3B,CAAA,EAAW,OAAO;EAGpB,IAAI,CAAC,IAAI,KAAK,MAAM,GAClB,IAAI,KAAK,YAAY,IAAI;CAE7B;;;;;;CAOA,IAAI,sBAAsB;CAE1B,MAAM,aAAa,YAAY;EAC7B,IAAI,SACF;EACF,SAAS;EACT,IAAI,QAAQ,QAAQ,WAAW,GAC7B,sBAAsB,IAAI,KAAK,cAAc;CACjD,CAAC;CAGD,eACE,aACC,YAAY;EACX,IAAI,CAAC,SAAS;GACZ,IAAI,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;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -20,14 +20,21 @@ export interface UseAutoCompleteKeyboardNavigationDeps<TItem> {
|
|
|
20
20
|
removeValue: (item: TItem) => void;
|
|
21
21
|
setSearchAsValue: () => void;
|
|
22
22
|
getText: (item: TItem) => string | undefined;
|
|
23
|
+
updateInternalSearch: (value?: string) => void;
|
|
23
24
|
activator: Ref<HTMLElement | undefined> | TemplateRef<HTMLElement>;
|
|
24
25
|
}
|
|
25
26
|
export interface UseAutoCompleteKeyboardNavigationReturn {
|
|
27
|
+
/**
|
|
28
|
+
* The selected value (a chip) that Backspace or Delete would remove, -1 for none. It is only
|
|
29
|
+
* drawn as selected: focus stays in the input, where no browser shortcut takes the key.
|
|
30
|
+
*/
|
|
26
31
|
focusedValueIndex: Ref<number>;
|
|
27
32
|
moveSelectedValueHighlight: (event: KeyboardEvent, next: boolean) => void;
|
|
28
33
|
onEnter: (event: KeyboardEvent) => void;
|
|
29
34
|
onTab: (event: KeyboardEvent) => void;
|
|
30
|
-
onInputDeletePressed: () => void;
|
|
35
|
+
onInputDeletePressed: (event: KeyboardEvent) => void;
|
|
36
|
+
/** Drops the value selection on any key that does not act on it. */
|
|
37
|
+
onInputKeydown: (event: KeyboardEvent) => void;
|
|
31
38
|
setValueFocus: (index: number) => void;
|
|
32
39
|
}
|
|
33
40
|
export declare function useAutoCompleteKeyboardNavigation<TItem>(options: UseAutoCompleteKeyboardNavigationOptions, deps: UseAutoCompleteKeyboardNavigationDeps<TItem>): UseAutoCompleteKeyboardNavigationReturn;
|