vectis-ui 0.1.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -6
- package/dist/components/VAccordion/VAccordion.css +1 -1
- package/dist/components/VAccordion/VAccordion.d.ts +9 -16
- package/dist/components/VAccordion/VAccordion.js.map +1 -1
- package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VAccordion/VAccordionItem.css +1 -1
- package/dist/components/VAccordion/VAccordionItem.d.ts +33 -19
- package/dist/components/VAccordion/VAccordionItem.js.map +1 -1
- package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js +50 -38
- package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VAccordion/context.d.ts +1 -8
- package/dist/components/VAccordion/context.js.map +1 -1
- package/dist/components/VAvatar/VAvatar.css +1 -1
- package/dist/components/VAvatar/VAvatar.d.ts +44 -29
- package/dist/components/VAvatar/VAvatar.js.map +1 -1
- package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js +38 -35
- package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VAvatar/VAvatarGroup.d.ts +5 -16
- package/dist/components/VAvatar/VAvatarGroup.js.map +1 -1
- package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VAvatar/context.d.ts +6 -10
- package/dist/components/VAvatar/context.js.map +1 -1
- package/dist/components/VBadge/VBadge.css +1 -1
- package/dist/components/VBadge/VBadge.d.ts +31 -10
- package/dist/components/VBadge/VBadge.js.map +1 -1
- package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js +39 -24
- package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VBreadcrumb/VBreadcrumb.css +1 -1
- package/dist/components/VBreadcrumb/VBreadcrumb.d.ts +4 -17
- package/dist/components/VBreadcrumb/VBreadcrumb.js.map +1 -1
- package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js +23 -25
- package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VButton/VButton.css +1 -1
- package/dist/components/VButton/VButton.d.ts +30 -10
- package/dist/components/VButton/VButton.js.map +1 -1
- package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js +39 -30
- package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VButton/VButtonGroup.css +1 -1
- package/dist/components/VButton/VButtonGroup.d.ts +76 -13
- package/dist/components/VButton/VButtonGroup.js.map +1 -1
- package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js +74 -8
- package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VButton/context.d.ts +30 -0
- package/dist/components/VButton/context.js +6 -0
- package/dist/components/VButton/context.js.map +1 -0
- package/dist/components/VCalendar/VCalendar.css +1 -1
- package/dist/components/VCalendar/VCalendar.d.ts +50 -36
- package/dist/components/VCalendar/VCalendar.js.map +1 -1
- package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js +99 -85
- package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendarEvent.css +1 -1
- package/dist/components/VCalendar/VCalendarEvent.d.ts +5 -11
- package/dist/components/VCalendar/VCalendarEvent.js.map +1 -1
- package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js +7 -1
- package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendarMonth.css +1 -1
- package/dist/components/VCalendar/VCalendarMonth.d.ts +10 -13
- package/dist/components/VCalendar/VCalendarMonth.js.map +1 -1
- package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js +183 -244
- package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendarTimeGrid.css +1 -1
- package/dist/components/VCalendar/VCalendarTimeGrid.d.ts +15 -20
- package/dist/components/VCalendar/VCalendarTimeGrid.js.map +1 -1
- package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js +385 -448
- package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendarYear.css +1 -1
- package/dist/components/VCalendar/VCalendarYear.js.map +1 -1
- package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js +53 -49
- package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/gesture.d.ts +158 -0
- package/dist/components/VCalendar/gesture.js +170 -0
- package/dist/components/VCalendar/gesture.js.map +1 -0
- package/dist/components/VCalendar/keyboard.d.ts +9 -3
- package/dist/components/VCalendar/keyboard.js +2 -6
- package/dist/components/VCalendar/keyboard.js.map +1 -1
- package/dist/components/VCalendar/layout.d.ts +67 -54
- package/dist/components/VCalendar/layout.js +77 -69
- package/dist/components/VCalendar/layout.js.map +1 -1
- package/dist/components/VCalendar/timeGrid.d.ts +55 -0
- package/dist/components/VCalendar/timeGrid.js +71 -0
- package/dist/components/VCalendar/timeGrid.js.map +1 -0
- package/dist/components/VCalendar/types.d.ts +41 -16
- package/dist/components/VCarousel/VCarousel.css +1 -1
- package/dist/components/VCarousel/VCarousel.d.ts +21 -41
- package/dist/components/VCarousel/VCarousel.js.map +1 -1
- package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js +157 -129
- package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCarousel/VCarouselItem.d.ts +0 -17
- package/dist/components/VCarousel/VCarouselItem.js.map +1 -1
- package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCarousel/context.d.ts +0 -12
- package/dist/components/VCarousel/context.js.map +1 -1
- package/dist/components/VCheckbox/VCheckbox.css +1 -1
- package/dist/components/VCheckbox/VCheckbox.d.ts +31 -16
- package/dist/components/VCheckbox/VCheckbox.js.map +1 -1
- package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js +62 -29
- package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VChip/VChip.css +1 -1
- package/dist/components/VChip/VChip.d.ts +36 -26
- package/dist/components/VChip/VChip.js.map +1 -1
- package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js +57 -48
- package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCombobox/VCombobox.css +1 -1
- package/dist/components/VCombobox/VCombobox.d.ts +127 -31
- package/dist/components/VCombobox/VCombobox.js.map +1 -1
- package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +336 -247
- package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCombobox/VComboboxGroup.css +1 -1
- package/dist/components/VCombobox/VComboboxGroup.d.ts +0 -9
- package/dist/components/VCombobox/VComboboxGroup.js.map +1 -1
- package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCombobox/VComboboxOption.css +1 -1
- package/dist/components/VCombobox/VComboboxOption.d.ts +0 -15
- package/dist/components/VCombobox/VComboboxOption.js.map +1 -1
- package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCombobox/VComboboxSeparator.js.map +1 -1
- package/dist/components/VCombobox/VComboboxSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCombobox/infiniteScroll.js.map +1 -1
- package/dist/components/VDataTable/VDataTable.css +1 -1
- package/dist/components/VDataTable/VDataTable.d.ts +50 -28
- package/dist/components/VDataTable/VDataTable.js.map +1 -1
- package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +183 -194
- package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDateInput/VDateInput.css +1 -1
- package/dist/components/VDateInput/VDateInput.d.ts +90 -42
- package/dist/components/VDateInput/VDateInput.js.map +1 -1
- package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js +159 -191
- package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDatePicker/VDatePicker.css +1 -1
- package/dist/components/VDatePicker/VDatePicker.d.ts +61 -30
- package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
- package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +243 -221
- package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDialog/VDialog.css +1 -1
- package/dist/components/VDialog/VDialog.d.ts +45 -33
- package/dist/components/VDialog/VDialog.js.map +1 -1
- package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js +65 -64
- package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDialog/VDialogAlert.d.ts +24 -20
- package/dist/components/VDialog/VDialogAlert.js.map +1 -1
- package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js +36 -25
- package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VFileInput/VFileInput.css +1 -1
- package/dist/components/VFileInput/VFileInput.d.ts +78 -26
- package/dist/components/VFileInput/VFileInput.js.map +1 -1
- package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js +144 -132
- package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VFilePicker/VFilePicker.css +1 -1
- package/dist/components/VFilePicker/VFilePicker.d.ts +47 -30
- package/dist/components/VFilePicker/VFilePicker.js.map +1 -1
- package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js +166 -163
- package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VFilePicker/fileKind.d.ts +2 -27
- package/dist/components/VFilePicker/fileKind.js +9 -8
- package/dist/components/VFilePicker/fileKind.js.map +1 -1
- package/dist/components/VHotkeys/VHotkeys.css +1 -1
- package/dist/components/VHotkeys/VHotkeys.d.ts +8 -30
- package/dist/components/VHotkeys/VHotkeys.js.map +1 -1
- package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VHotkeys/platform.js.map +1 -1
- package/dist/components/VIcon/VIcon.css +1 -1
- package/dist/components/VIcon/VIcon.d.ts +15 -6
- package/dist/components/VIcon/VIcon.js.map +1 -1
- package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js +45 -37
- package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VIcon/iconProps.js.map +1 -1
- package/dist/components/VIcon/icons/index.d.ts +1 -1
- package/dist/components/VIcon/icons/index.js.map +1 -1
- package/dist/components/VIcon/icons/names.d.ts +1 -1
- package/dist/components/VIcon/icons/names.js.map +1 -1
- package/dist/components/VIcon/resolver.d.ts +3 -3
- package/dist/components/VIcon/resolver.js.map +1 -1
- package/dist/components/VIcon/types.d.ts +12 -12
- package/dist/components/VIconButton/VIconButton.css +1 -1
- package/dist/components/VIconButton/VIconButton.d.ts +28 -11
- package/dist/components/VIconButton/VIconButton.js.map +1 -1
- package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js +26 -20
- package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VInput/VInput.css +1 -1
- package/dist/components/VInput/VInput.d.ts +26 -7
- package/dist/components/VInput/VInput.js.map +1 -1
- package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js +86 -75
- package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VInput/VInputGroup.css +2 -0
- package/dist/components/VInput/VInputGroup.d.ts +47 -0
- package/dist/components/VInput/VInputGroup.js +9 -0
- package/dist/components/VInput/VInputGroup.js.map +1 -0
- package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js +80 -0
- package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VInput/context.d.ts +11 -0
- package/dist/components/VInput/context.js +6 -0
- package/dist/components/VInput/context.js.map +1 -0
- package/dist/components/VInputOTP/VInputOTP.css +1 -1
- package/dist/components/VInputOTP/VInputOTP.d.ts +37 -22
- package/dist/components/VInputOTP/VInputOTP.js.map +1 -1
- package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +98 -61
- package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/VMenu.d.ts +23 -30
- package/dist/components/VMenu/VMenu.js.map +1 -1
- package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js +31 -27
- package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/VMenuGroup.css +1 -1
- package/dist/components/VMenu/VMenuGroup.d.ts +12 -8
- package/dist/components/VMenu/VMenuGroup.js.map +1 -1
- package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js +11 -11
- package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/VMenuItem.css +1 -1
- package/dist/components/VMenu/VMenuItem.d.ts +11 -19
- package/dist/components/VMenu/VMenuItem.js.map +1 -1
- package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js +65 -57
- package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/VMenuPanel.d.ts +14 -30
- package/dist/components/VMenu/VMenuPanel.js.map +1 -1
- package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +43 -44
- package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/context.d.ts +2 -6
- package/dist/components/VMenu/context.js.map +1 -1
- package/dist/components/VPagination/VPagination.css +1 -1
- package/dist/components/VPagination/VPagination.d.ts +60 -22
- package/dist/components/VPagination/VPagination.js.map +1 -1
- package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js +113 -161
- package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VPopover/VPopover.css +1 -1
- package/dist/components/VPopover/VPopover.d.ts +26 -7
- package/dist/components/VPopover/VPopover.js.map +1 -1
- package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js +43 -37
- package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VProgressCircular/VProgressCircular.css +1 -1
- package/dist/components/VProgressCircular/VProgressCircular.d.ts +15 -4
- package/dist/components/VProgressCircular/VProgressCircular.js.map +1 -1
- package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js +32 -30
- package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.css +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.d.ts +23 -8
- package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js +34 -32
- package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VRadio/VRadio.css +1 -1
- package/dist/components/VRadio/VRadio.d.ts +36 -18
- package/dist/components/VRadio/VRadio.js.map +1 -1
- package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js +55 -26
- package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSeparator/VSeparator.d.ts +4 -2
- package/dist/components/VSeparator/VSeparator.js.map +1 -1
- package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigation.css +1 -1
- package/dist/components/VSideNavigation/VSideNavigation.d.ts +5 -19
- package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationGroup.css +1 -1
- package/dist/components/VSideNavigation/VSideNavigationGroup.d.ts +9 -17
- package/dist/components/VSideNavigation/VSideNavigationGroup.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationItem.css +1 -1
- package/dist/components/VSideNavigation/VSideNavigationItem.d.ts +22 -30
- package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js +77 -87
- package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSideNavigation/context.d.ts +0 -14
- package/dist/components/VSideNavigation/context.js.map +1 -1
- package/dist/components/VSkeletonLoader/VSkeletonLoader.css +1 -1
- package/dist/components/VSkeletonLoader/VSkeletonLoader.d.ts +9 -9
- package/dist/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -1
- package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSlider/VSlider.css +1 -1
- package/dist/components/VSlider/VSlider.d.ts +52 -27
- package/dist/components/VSlider/VSlider.js.map +1 -1
- package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js +202 -118
- package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSnackbar/VSnackbar.css +1 -1
- package/dist/components/VSnackbar/VSnackbar.d.ts +0 -23
- package/dist/components/VSnackbar/VSnackbar.js.map +1 -1
- package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js +38 -38
- package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSnackbar/state.d.ts +0 -27
- package/dist/components/VSnackbar/state.js.map +1 -1
- package/dist/components/VSpinner/VSpinner.css +1 -1
- package/dist/components/VSpinner/VSpinner.d.ts +6 -6
- package/dist/components/VSpinner/VSpinner.js.map +1 -1
- package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js +10 -9
- package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSwitch/VSwitch.css +1 -1
- package/dist/components/VSwitch/VSwitch.d.ts +35 -13
- package/dist/components/VSwitch/VSwitch.js.map +1 -1
- package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js +62 -21
- package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTabs/VTab.css +1 -1
- package/dist/components/VTabs/VTab.d.ts +12 -12
- package/dist/components/VTabs/VTab.js.map +1 -1
- package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js +36 -24
- package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTabs/VTabPanel.d.ts +2 -10
- package/dist/components/VTabs/VTabPanel.js.map +1 -1
- package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTabs/VTabs.css +1 -1
- package/dist/components/VTabs/VTabs.d.ts +27 -18
- package/dist/components/VTabs/VTabs.js.map +1 -1
- package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js +92 -81
- package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTabs/context.d.ts +9 -19
- package/dist/components/VTabs/context.js +1 -1
- package/dist/components/VTabs/context.js.map +1 -1
- package/dist/components/VTextarea/VTextarea.css +1 -1
- package/dist/components/VTextarea/VTextarea.d.ts +34 -6
- package/dist/components/VTextarea/VTextarea.js.map +1 -1
- package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js +91 -74
- package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTimeInput/VTimeInput.css +1 -1
- package/dist/components/VTimeInput/VTimeInput.d.ts +123 -33
- package/dist/components/VTimeInput/VTimeInput.js.map +1 -1
- package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js +294 -291
- package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTimeInput/search.d.ts +24 -0
- package/dist/components/VTimeInput/search.js +22 -0
- package/dist/components/VTimeInput/search.js.map +1 -0
- package/dist/components/VTimePicker/VTimePicker.css +1 -1
- package/dist/components/VTimePicker/VTimePicker.d.ts +51 -30
- package/dist/components/VTimePicker/VTimePicker.js.map +1 -1
- package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js +216 -151
- package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTimePicker/limits.d.ts +88 -0
- package/dist/components/VTimePicker/limits.js +70 -0
- package/dist/components/VTimePicker/limits.js.map +1 -0
- package/dist/components/VToast/VToast.css +1 -1
- package/dist/components/VToast/VToast.d.ts +0 -10
- package/dist/components/VToast/VToast.js.map +1 -1
- package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js +10 -10
- package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VToast/VToaster.css +1 -1
- package/dist/components/VToast/VToaster.d.ts +0 -17
- package/dist/components/VToast/VToaster.js.map +1 -1
- package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js +29 -28
- package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VToast/state.d.ts +10 -19
- package/dist/components/VToast/state.js +1 -1
- package/dist/components/VToast/state.js.map +1 -1
- package/dist/components/VToggle/VToggle.css +1 -1
- package/dist/components/VToggle/VToggle.d.ts +56 -11
- package/dist/components/VToggle/VToggle.js.map +1 -1
- package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js +80 -46
- package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VToggle/VToggleItem.d.ts +16 -2
- package/dist/components/VToggle/VToggleItem.js +0 -2
- package/dist/components/VToggle/VToggleItem.js.map +1 -1
- package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js +23 -15
- package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VToggle/context.d.ts +4 -24
- package/dist/components/VToggle/context.js.map +1 -1
- package/dist/components/VTooltip/VTooltip.css +1 -1
- package/dist/components/VTooltip/VTooltip.d.ts +9 -33
- package/dist/components/VTooltip/VTooltip.js.map +1 -1
- package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js +28 -24
- package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTypography/VTypography.js.map +1 -1
- package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/composables/useAriaLabel.d.ts +0 -17
- package/dist/composables/useAriaLabel.js.map +1 -1
- package/dist/composables/useClearable.d.ts +42 -0
- package/dist/composables/useClearable.js +19 -0
- package/dist/composables/useClearable.js.map +1 -0
- package/dist/composables/useControlShape.d.ts +22 -0
- package/dist/composables/useControlShape.js +13 -0
- package/dist/composables/useControlShape.js.map +1 -0
- package/dist/composables/useDetailsOpen.d.ts +22 -0
- package/dist/composables/useDetailsOpen.js +21 -0
- package/dist/composables/useDetailsOpen.js.map +1 -0
- package/dist/composables/useFieldIds.d.ts +0 -15
- package/dist/composables/useFieldIds.js +8 -7
- package/dist/composables/useFieldIds.js.map +1 -1
- package/dist/composables/useFieldPanel.d.ts +21 -18
- package/dist/composables/useFieldPanel.js +43 -23
- package/dist/composables/useFieldPanel.js.map +1 -1
- package/dist/composables/useFileDrop.d.ts +0 -22
- package/dist/composables/useFileDrop.js.map +1 -1
- package/dist/composables/useFileField.d.ts +45 -17
- package/dist/composables/useFileField.js +40 -20
- package/dist/composables/useFileField.js.map +1 -1
- package/dist/composables/useFocusoutDismiss.d.ts +0 -15
- package/dist/composables/useFocusoutDismiss.js.map +1 -1
- package/dist/composables/useIconClickHandlers.d.ts +29 -14
- package/dist/composables/useIconClickHandlers.js +15 -5
- package/dist/composables/useIconClickHandlers.js.map +1 -1
- package/dist/composables/useInertLink.d.ts +20 -0
- package/dist/composables/useInertLink.js +23 -0
- package/dist/composables/useInertLink.js.map +1 -0
- package/dist/composables/useMaskedField.d.ts +33 -10
- package/dist/composables/useMaskedField.js +45 -1
- package/dist/composables/useMaskedField.js.map +1 -1
- package/dist/composables/usePopover.d.ts +15 -1
- package/dist/composables/usePopover.js +23 -8
- package/dist/composables/usePopover.js.map +1 -1
- package/dist/composables/useProgressValue.d.ts +5 -8
- package/dist/composables/useProgressValue.js +6 -3
- package/dist/composables/useProgressValue.js.map +1 -1
- package/dist/composables/useRootAttrs.d.ts +12 -19
- package/dist/composables/useRootAttrs.js.map +1 -1
- package/dist/composables/useTimer.d.ts +8 -10
- package/dist/composables/useTimer.js.map +1 -1
- package/dist/i18n/en.d.ts +2 -10
- package/dist/i18n/en.js +18 -19
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/fr.d.ts +2 -18
- package/dist/i18n/fr.js +18 -19
- package/dist/i18n/fr.js.map +1 -1
- package/dist/i18n/state.d.ts +44 -47
- package/dist/i18n/state.js +20 -17
- package/dist/i18n/state.js.map +1 -1
- package/dist/i18n/types.d.ts +53 -44
- package/dist/icons.d.ts +3 -3
- package/dist/index.d.ts +43 -17
- package/dist/index.js +45 -44
- package/dist/styles.css +1 -1
- package/dist/tokens/css.js.map +1 -1
- package/dist/tokens/index.d.ts +5 -1
- package/dist/tokens/primitives.js.map +1 -1
- package/dist/tokens/semantic.d.ts +5 -1
- package/dist/tokens/semantic.js +6 -2
- package/dist/tokens/semantic.js.map +1 -1
- package/dist/tokens/themes/dark.js.map +1 -1
- package/dist/tokens/types.d.ts +7 -15
- package/dist/tokens/types.js.map +1 -1
- package/dist/tokens.json +25 -5
- package/dist/types.d.ts +24 -0
- package/dist/utils/array.d.ts +3 -6
- package/dist/utils/array.js.map +1 -1
- package/dist/utils/arrowNav.d.ts +17 -17
- package/dist/utils/arrowNav.js +5 -3
- package/dist/utils/arrowNav.js.map +1 -1
- package/dist/utils/chip.d.ts +11 -15
- package/dist/utils/chip.js.map +1 -1
- package/dist/utils/css.d.ts +22 -11
- package/dist/utils/css.js +5 -2
- package/dist/utils/css.js.map +1 -1
- package/dist/utils/date.d.ts +42 -19
- package/dist/utils/date.js +97 -98
- package/dist/utils/date.js.map +1 -1
- package/dist/utils/direction.d.ts +6 -12
- package/dist/utils/direction.js.map +1 -1
- package/dist/utils/env.d.ts +5 -6
- package/dist/utils/file.d.ts +46 -58
- package/dist/utils/file.js +43 -36
- package/dist/utils/file.js.map +1 -1
- package/dist/utils/focus.d.ts +8 -17
- package/dist/utils/focus.js.map +1 -1
- package/dist/utils/hostWarns.d.ts +12 -0
- package/dist/utils/hostWarns.js +6 -0
- package/dist/utils/hostWarns.js.map +1 -0
- package/dist/utils/ids.d.ts +10 -0
- package/dist/utils/ids.js +8 -0
- package/dist/utils/ids.js.map +1 -0
- package/dist/utils/matcher.d.ts +5 -9
- package/dist/utils/matcher.js.map +1 -1
- package/dist/utils/memo.d.ts +12 -0
- package/dist/utils/memo.js +9 -0
- package/dist/utils/memo.js.map +1 -0
- package/dist/utils/number.d.ts +3 -4
- package/dist/utils/number.js.map +1 -1
- package/dist/utils/text.d.ts +20 -9
- package/dist/utils/text.js +17 -3
- package/dist/utils/text.js.map +1 -1
- package/dist/utils/time.d.ts +53 -61
- package/dist/utils/time.js +49 -45
- package/dist/utils/time.js.map +1 -1
- package/dist/utils/vnode.d.ts +8 -15
- package/dist/utils/vnode.js.map +1 -1
- package/package.json +6 -6
- package/dist/components/VToggle/VToggleItem.css +0 -2
|
@@ -1,39 +1,59 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { NO_BUTTON_GROUP as e, buttonGroupKey as t } from "../components/VButton/context.js";
|
|
2
|
+
import { useFocusoutDismiss as n } from "./useFocusoutDismiss.js";
|
|
3
|
+
import { provide as r, ref as i, useId as a } from "vue";
|
|
3
4
|
//#region src/composables/useFieldPanel.ts
|
|
4
|
-
function
|
|
5
|
-
let
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
function o(o) {
|
|
6
|
+
let s = i(!1), c = () => o.openOnFocus?.() ?? !1, l = a();
|
|
7
|
+
r(t, e);
|
|
8
|
+
function u(e = !c()) {
|
|
9
|
+
o.disabled() || s.value || (o.onOpen?.(), o.panelRef.value?.show(), e && requestAnimationFrame(() => o.focusInPanel()));
|
|
8
10
|
}
|
|
9
|
-
function
|
|
10
|
-
|
|
11
|
+
function d() {
|
|
12
|
+
s.value && (o.panelRef.value?.close(), o.onClose?.());
|
|
11
13
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
let f = !1;
|
|
15
|
+
function p() {
|
|
16
|
+
f = !0, o.field.value?.focus(), f = !1;
|
|
14
17
|
}
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
function m() {
|
|
19
|
+
s.value && (d(), p());
|
|
20
|
+
}
|
|
21
|
+
function h() {
|
|
22
|
+
f || !c() || u(!1);
|
|
23
|
+
}
|
|
24
|
+
function g() {
|
|
25
|
+
s.value ? m() : u(!0);
|
|
26
|
+
}
|
|
27
|
+
function _(e) {
|
|
28
|
+
e.target.closest(".v-input-action") || u();
|
|
29
|
+
}
|
|
30
|
+
let v = n(o.rootEl, d);
|
|
31
|
+
function y(e) {
|
|
17
32
|
e.target?.closest("button, a, input, select, textarea, [tabindex]") || e.preventDefault();
|
|
18
33
|
}
|
|
19
|
-
function
|
|
34
|
+
function b(e) {
|
|
20
35
|
if (e.key === "Escape") {
|
|
21
|
-
|
|
36
|
+
s.value && (e.preventDefault(), m());
|
|
22
37
|
return;
|
|
23
38
|
}
|
|
24
|
-
(e.key === "ArrowDown" || e.key === "Enter") && !
|
|
39
|
+
(e.key === "ArrowDown" || e.key === "Enter") && !s.value && !e.defaultPrevented && (e.preventDefault(), u(!0));
|
|
25
40
|
}
|
|
26
41
|
return {
|
|
27
|
-
open:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
42
|
+
open: s,
|
|
43
|
+
panelId: l,
|
|
44
|
+
openPanel: u,
|
|
45
|
+
closePanel: d,
|
|
46
|
+
closeAndFocus: m,
|
|
47
|
+
focusField: p,
|
|
48
|
+
onFieldFocus: h,
|
|
49
|
+
toggleFromIcon: g,
|
|
50
|
+
onControlClick: _,
|
|
51
|
+
onFocusout: v,
|
|
52
|
+
onKeydown: b,
|
|
53
|
+
onPanelMousedown: y
|
|
34
54
|
};
|
|
35
55
|
}
|
|
36
56
|
//#endregion
|
|
37
|
-
export {
|
|
57
|
+
export { o as useFieldPanel };
|
|
38
58
|
|
|
39
59
|
//# sourceMappingURL=useFieldPanel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFieldPanel.js","names":[],"sources":["../../src/composables/useFieldPanel.ts"],"sourcesContent":["import { ref } from 'vue'\nimport type { Ref } from 'vue'\n\nimport { useFocusoutDismiss } from './useFocusoutDismiss'\n\n/** The least this needs of the field: something it can put the focus back on. */\ninterface FocusableField {\n focus: () => void\n}\n\n/** The least this needs of the panel: something it can open and close. */\ninterface PanelControl {\n show: () => void\n
|
|
1
|
+
{"version":3,"file":"useFieldPanel.js","names":[],"sources":["../../src/composables/useFieldPanel.ts"],"sourcesContent":["import { provide, ref, useId } from 'vue'\nimport type { Ref } from 'vue'\n\nimport { NO_BUTTON_GROUP, buttonGroupKey } from '../components/VButton/context'\nimport { useFocusoutDismiss } from './useFocusoutDismiss'\n\n/** The least this needs of the field: something it can put the focus back on. */\ninterface FocusableField {\n focus: () => void\n}\n\n/** The least this needs of the panel: something it can open and close. */\ninterface PanelControl {\n show: () => void\n close: () => void\n}\n\nexport interface UseFieldPanelOptions {\n /** The component's root, against which \"the focus has left\" is judged. */\n rootEl: Ref<HTMLElement | null>\n /** The panel to open and close. */\n panelRef: Ref<PanelControl | null>\n /** The field the focus returns to. */\n field: Ref<FocusableField | null>\n /**\n * Whether opening is refused. It is the SINGLE cut-off point: every route in passes\n * through it, so a component never has to repeat the condition per handler.\n */\n disabled: () => boolean\n /** Moves the focus INTO the open panel — where in it is the component's business. */\n focusInPanel: () => void\n /** What the component needs to do as the panel opens: prepare a draft, reset a step. */\n onOpen?: () => void\n /** What it needs to do as the panel closes: clear an announcement, for instance. */\n onClose?: () => void\n /**\n * Whether focusing the field opens the panel. It does not by default.\n *\n * A field one TYPES into says yes, and its panel then opens WITHOUT taking the caret, so\n * typing carries on and the down arrow remains the one explicit way in. A click on such a\n * field leaves the focus where it is for the same reason.\n */\n openOnFocus?: () => boolean\n}\n\n// @a11y @keyboard @core\n/**\n * The \"field + `VPopover` in `mode=\"manual\"`\" shell of VDateInput and VTimeInput.\n *\n * A `manual` popover does nothing on its own: no light dismiss, no focus move, no focus\n * return. This is exactly that minimum; what is particular to either component arrives\n * through `onOpen`/`onClose`.\n *\n * TRAP — the panel is WRITTEN imperatively and READ back by model. Bind `open` as\n * `v-model:open` so the DOM feeds it, but the write must stay synchronous: the `rAF` that\n * moves focus assumes the panel is already open when it is armed, and the model would put\n * a tick in between.\n */\nexport function useFieldPanel(options: UseFieldPanelOptions) {\n const open = ref(false)\n const openOnFocus = () => options.openOnFocus?.() ?? false\n\n /** The id the panel carries, for the field's `aria-controls`. */\n const panelId = useId()\n\n // @core\n // TRAP — this stops a VButtonGroup's or a VInputGroup's row context at the field's\n // boundary. The picker in the panel sizes its own buttons — VDatePicker writes `size=\"sm\"`\n // on its navigation, VTimePicker `size=\"lg\"` on its hour and minute cells — and a group\n // WINS over a button's prop: without this line a VInputGroup would resize them to its own\n // height, which only shows once the panel is open and nothing in the sheet or the template\n // would say why. It is the JS counterpart of the `.v-overlay` guard every VButtonGroup\n // selector carries — a floating panel is not a segment of the row that opened it.\n provide(buttonGroupKey, NO_BUTTON_GROUP)\n\n function openPanel(moveFocus = !openOnFocus()) {\n if (options.disabled() || open.value) return\n options.onOpen?.()\n options.panelRef.value?.show()\n // @a11y\n // A `manual` popover moves focus nowhere, so it is moved by hand — a frame later,\n // the panel not being painted yet, and nothing invisible can take focus.\n if (moveFocus) requestAnimationFrame(() => options.focusInPanel())\n }\n\n /** Closes the panel and leaves the focus where it is: the focus has already gone elsewhere. */\n function closePanel() {\n if (!open.value) return\n options.panelRef.value?.close()\n options.onClose?.()\n }\n\n // @a11y\n /*\n * TRAP — handing the focus back to the field is what makes a field that opens ON FOCUS\n * reopen the panel that was just closed: the two would chase each other and the panel\n * would never close. The lock covers the focus call, which is synchronous.\n *\n * EVERY focus this shell or a component gives the field must go through `focusField`,\n * `closeAndFocus` included. Focusing the field directly brings the loop straight back.\n */\n let refocusing = false\n\n /**\n * Puts the focus on the field without opening the panel.\n *\n * A component emptying its value calls it BEFORE the field focuses itself, and that order\n * is the point: focusing an element that already has the focus emits no event at all, so\n * the field's own call that follows is inert and the panel stays shut.\n */\n function focusField() {\n refocusing = true\n options.field.value?.focus()\n refocusing = false\n }\n\n /** Closes the panel and hands the focus back to the field, under the lock above. */\n function closeAndFocus() {\n if (!open.value) return\n closePanel()\n focusField()\n }\n\n /** The field's focus handler: opens the panel on a field that asks for it. */\n function onFieldFocus() {\n if (refocusing || !openOnFocus()) return\n openPanel(false)\n }\n\n /**\n * The icon at the end of the field. Clicking it is an explicit request for the panel, and\n * the focus has already left the field for the button — so carrying it into the panel is\n * right whatever `openOnFocus` says.\n */\n function toggleFromIcon() {\n if (open.value) closeAndFocus()\n else openPanel(true)\n }\n\n function onControlClick(event: MouseEvent) {\n // A click on one of the field's own buttons is that button's business: reacting here\n // too would open the panel the clear cross has just given a reason to close.\n if ((event.target as HTMLElement).closest('.v-input-action')) return\n openPanel()\n }\n\n // @a11y\n const onFocusout = useFocusoutDismiss(options.rootEl, closePanel)\n\n // @a11y\n /*\n * TRAP — clicking a non-focusable pixel of the panel (padding, the gutter between cells)\n * hands focus back to `<body>`. `onFocusout` above then fires with a null `relatedTarget`,\n * reads it as an exit — rightly — and closes a panel the reader has just clicked.\n *\n * The filter is essential: VCombobox's unconditional `preventDefault` is safe there\n * because focus never leaves its field, but here it would rob the days and the navigation\n * arrows of focus and desynchronize VDatePicker's roving.\n *\n * Invisible in jsdom, where clicking moves no focus — the `ClicDansLeVide` play functions\n * of both components cover it.\n */\n function onPanelMousedown(event: MouseEvent) {\n const target = event.target as HTMLElement | null\n if (!target?.closest('button, a, input, select, textarea, [tabindex]')) event.preventDefault()\n }\n\n // @keyboard @a11y\n function onKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n if (open.value) {\n event.preventDefault()\n closeAndFocus()\n }\n return\n }\n // TRAP — a key already consumed INSIDE the panel is ignored. An Enter that selected a\n // day has just CLOSED the panel, and without the guard would reopen it as it bubbles.\n if (\n (event.key === 'ArrowDown' || event.key === 'Enter') &&\n !open.value &&\n !event.defaultPrevented\n ) {\n event.preventDefault()\n // Opened from the KEYBOARD the panel always takes focus, whatever `openOnFocus` says:\n // otherwise ArrowDown opens a panel the keyboard cannot reach.\n openPanel(true)\n }\n }\n\n return {\n open,\n panelId,\n openPanel,\n closePanel,\n closeAndFocus,\n focusField,\n onFieldFocus,\n toggleFromIcon,\n onControlClick,\n onFocusout,\n onKeydown,\n onPanelMousedown,\n }\n}\n"],"mappings":";;;;AA0DA,SAAgB,EAAc,GAA+B;CAC3D,IAAM,IAAO,EAAI,EAAK,GAChB,UAAoB,EAAQ,cAAc,KAAK,IAG/C,IAAU,EAAM;CAUtB,EAAQ,GAAgB,CAAe;CAEvC,SAAS,EAAU,IAAY,CAAC,EAAY,GAAG;EACzC,EAAQ,SAAS,KAAK,EAAK,UAC/B,EAAQ,SAAS,GACjB,EAAQ,SAAS,OAAO,KAAK,GAIzB,KAAW,4BAA4B,EAAQ,aAAa,CAAC;CACnE;CAGA,SAAS,IAAa;EACf,EAAK,UACV,EAAQ,SAAS,OAAO,MAAM,GAC9B,EAAQ,UAAU;CACpB;CAWA,IAAI,IAAa;CASjB,SAAS,IAAa;EAGpB,AAFA,IAAa,IACb,EAAQ,MAAM,OAAO,MAAM,GAC3B,IAAa;CACf;CAGA,SAAS,IAAgB;EAClB,EAAK,UACV,EAAW,GACX,EAAW;CACb;CAGA,SAAS,IAAe;EAClB,KAAc,CAAC,EAAY,KAC/B,EAAU,EAAK;CACjB;CAOA,SAAS,IAAiB;EACxB,AAAI,EAAK,QAAO,EAAc,IACzB,EAAU,EAAI;CACrB;CAEA,SAAS,EAAe,GAAmB;EAGpC,EAAM,OAAuB,QAAQ,iBAAiB,KAC3D,EAAU;CACZ;CAGA,IAAM,IAAa,EAAmB,EAAQ,QAAQ,CAAU;CAehE,SAAS,EAAiB,GAAmB;EAE3C,AADe,EAAM,QACR,QAAQ,gDAAgD,KAAG,EAAM,eAAe;CAC/F;CAGA,SAAS,EAAU,GAAsB;EACvC,IAAI,EAAM,QAAQ,UAAU;GAC1B,AAAI,EAAK,UACP,EAAM,eAAe,GACrB,EAAc;GAEhB;EACF;EAGA,CACG,EAAM,QAAQ,eAAe,EAAM,QAAQ,YAC5C,CAAC,EAAK,SACN,CAAC,EAAM,qBAEP,EAAM,eAAe,GAGrB,EAAU,EAAI;CAElB;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -1,26 +1,4 @@
|
|
|
1
1
|
import { ComputedRef } from 'vue';
|
|
2
|
-
/**
|
|
3
|
-
* Everything an area needs in order to accept files dropped onto it, and to show that it
|
|
4
|
-
* is ready to receive them. Both the file field and the drop zone are built on it.
|
|
5
|
-
*
|
|
6
|
-
* Two traps live here, which is the whole reason this exists once rather than twice.
|
|
7
|
-
*
|
|
8
|
-
* The browser must be told explicitly, while the file is being dragged over the area,
|
|
9
|
-
* that a drop is welcome. Left unsaid, it refuses the drop and then NAVIGATES to the
|
|
10
|
-
* file, replacing the page the reader was on.
|
|
11
|
-
*
|
|
12
|
-
* And what is counted is a DEPTH, not a yes-or-no. The browser reports the pointer
|
|
13
|
-
* LEAVING every time it crosses into a child element — a field, a chip, a button inside
|
|
14
|
-
* the area — so a simple flag would switch off under the cursor and the highlight would
|
|
15
|
-
* flicker. A drop forces the count back to zero, because a drag that leaves the window
|
|
16
|
-
* altogether never reports the departure that would have balanced it; asking instead
|
|
17
|
-
* whether the pointer went to a descendant, the other well-known fix, is no use since
|
|
18
|
-
* there is precisely nothing to ask about in that case.
|
|
19
|
-
*
|
|
20
|
-
* Whether the area accepts anything is read at the moment of the event rather than
|
|
21
|
-
* captured once, so a component turned off in the middle of a drag stops accepting
|
|
22
|
-
* without anything being re-attached.
|
|
23
|
-
*/
|
|
24
2
|
export declare function useFileDrop(enabled: () => boolean, onFiles: (files: File[]) => void): {
|
|
25
3
|
dragging: ComputedRef<boolean>;
|
|
26
4
|
onDragEnter: (event: DragEvent) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFileDrop.js","names":[],"sources":["../../src/composables/useFileDrop.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"useFileDrop.js","names":[],"sources":["../../src/composables/useFileDrop.ts"],"sourcesContent":["// @core\n/**\n * The drop-target plumbing of VFileInput and VFilePicker. It exists once rather than twice\n * because of the two traps it carries.\n *\n * `dragover` MUST `preventDefault`, or the browser refuses the drop and then NAVIGATES to\n * the file, replacing the page.\n *\n * And the state is a depth COUNTER, never a boolean: `dragleave` fires every time the\n * pointer crosses into a child, so a flag would flicker off under the cursor. `drop` forces\n * the depth back to 0 — a drag leaving the window never sends the matching `dragleave`, and\n * `currentTarget.contains(relatedTarget)`, the other classic fix, is useless there since\n * `relatedTarget` is null in exactly that case.\n *\n * `enabled` is a getter, read at event time, so a component disabled mid-drag stops\n * accepting with nothing re-bound.\n */\n\nimport { computed, ref, type ComputedRef } from 'vue'\n\nexport function useFileDrop(\n enabled: () => boolean,\n onFiles: (files: File[]) => void,\n): {\n dragging: ComputedRef<boolean>\n onDragEnter: (event: DragEvent) => void\n onDragOver: (event: DragEvent) => void\n onDragLeave: () => void\n onDrop: (event: DragEvent) => void\n} {\n const depth = ref(0)\n\n function onDragEnter(event: DragEvent) {\n if (!enabled()) return\n event.preventDefault()\n depth.value += 1\n }\n\n function onDragOver(event: DragEvent) {\n if (!enabled()) return\n event.preventDefault()\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy'\n }\n\n function onDragLeave() {\n if (!enabled()) return\n depth.value = Math.max(0, depth.value - 1)\n }\n\n function onDrop(event: DragEvent) {\n if (!enabled()) return\n event.preventDefault()\n depth.value = 0\n onFiles([...(event.dataTransfer?.files ?? [])])\n }\n\n return {\n dragging: computed(() => depth.value > 0),\n onDragEnter,\n onDragOver,\n onDragLeave,\n onDrop,\n }\n}\n"],"mappings":";;AAoBA,SAAgB,EACd,GACA,GAOA;CACA,IAAM,IAAQ,EAAI,CAAC;CAEnB,SAAS,EAAY,GAAkB;EAChC,EAAQ,MACb,EAAM,eAAe,GACrB,EAAM,SAAS;CACjB;CAEA,SAAS,EAAW,GAAkB;EAC/B,EAAQ,MACb,EAAM,eAAe,GACjB,EAAM,iBAAc,EAAM,aAAa,aAAa;CAC1D;CAEA,SAAS,IAAc;EAChB,EAAQ,MACb,EAAM,QAAQ,KAAK,IAAI,GAAG,EAAM,QAAQ,CAAC;CAC3C;CAEA,SAAS,EAAO,GAAkB;EAC3B,EAAQ,MACb,EAAM,eAAe,GACrB,EAAM,QAAQ,GACd,EAAQ,CAAC,GAAI,EAAM,cAAc,SAAS,CAAC,CAAE,CAAC;CAChD;CAEA,OAAO;EACL,UAAU,QAAe,EAAM,QAAQ,CAAC;EACxC;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -1,36 +1,64 @@
|
|
|
1
1
|
import { ComputedRef, Ref } from 'vue';
|
|
2
|
-
import {
|
|
2
|
+
import { FileRejection } from '../utils/file.js';
|
|
3
|
+
/** The props both components declare under the same names, read at the moment they matter. */
|
|
4
|
+
export interface FileFieldProps {
|
|
5
|
+
multiple: boolean;
|
|
6
|
+
accept?: string;
|
|
7
|
+
maxSize?: number;
|
|
8
|
+
maxFiles?: number;
|
|
9
|
+
maxTotalSize?: number;
|
|
10
|
+
disabled: boolean;
|
|
11
|
+
readonly: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** The events both components declare under the same names and with the same payloads. */
|
|
14
|
+
export interface FileFieldEmit {
|
|
15
|
+
(event: 'change', files: File[]): void;
|
|
16
|
+
(event: 'reject', rejection: FileRejection): void;
|
|
17
|
+
(event: 'remove', file: File, index: number): void;
|
|
18
|
+
}
|
|
3
19
|
export interface FileFieldOptions {
|
|
4
20
|
/** The component's value — always a list of files, whether one or several are allowed. */
|
|
5
21
|
model: Ref<File[]>;
|
|
22
|
+
props: FileFieldProps;
|
|
23
|
+
emit: FileFieldEmit;
|
|
6
24
|
/** The attributes the consumer wrote, minus styling, still to be split in two. */
|
|
7
25
|
forwardedAttrs: ComputedRef<Record<string, unknown>>;
|
|
8
|
-
/** Read at the moment of the event, so a component turned off mid-way stops accepting. */
|
|
9
|
-
enabled: () => boolean;
|
|
10
|
-
multiple: () => boolean;
|
|
11
|
-
/** The limits as the consumer set them: capping a single-file field at one happens here. */
|
|
12
|
-
limits: () => FileLimits;
|
|
13
|
-
onReject: (rejection: FileRejection) => void;
|
|
14
|
-
onChange: (files: File[]) => void;
|
|
15
26
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
* Whether the component is disabled, the row it sits in taken into account. Left out, the
|
|
28
|
+
* `disabled` prop answers alone.
|
|
29
|
+
*/
|
|
30
|
+
disabled?: Ref<boolean>;
|
|
31
|
+
/**
|
|
32
|
+
* Attributes to withhold from the visible control too. VFileInput withholds
|
|
33
|
+
* `aria-describedby`, which it re-aggregates itself: a binding written after the spread
|
|
34
|
+
* would replace the consumer's rather than merge with it.
|
|
21
35
|
*/
|
|
22
36
|
excludeFromControl?: readonly string[];
|
|
37
|
+
/** Called once the selection has been emptied by `clear`, before `change` is emitted. */
|
|
38
|
+
onClear?: () => void;
|
|
39
|
+
/**
|
|
40
|
+
* The component's own development warnings, one message per condition that holds. They
|
|
41
|
+
* follow the same rule as the shared ones: each is given once per instance.
|
|
42
|
+
*/
|
|
43
|
+
warnings?: () => (string | false)[];
|
|
23
44
|
}
|
|
24
45
|
export declare function useFileField(options: FileFieldOptions): {
|
|
25
46
|
fileEl: Ref<HTMLInputElement | null, HTMLInputElement | null>;
|
|
26
|
-
|
|
27
|
-
|
|
47
|
+
enabled: ComputedRef<boolean>;
|
|
48
|
+
nativeInputAttrs: ComputedRef<{
|
|
49
|
+
type: string;
|
|
50
|
+
tabindex: number;
|
|
51
|
+
'aria-hidden': "true";
|
|
52
|
+
accept: string | undefined;
|
|
53
|
+
multiple: true | undefined;
|
|
54
|
+
disabled: true | undefined;
|
|
55
|
+
onChange: (event: Event) => void;
|
|
28
56
|
}>;
|
|
29
57
|
controlAttrs: ComputedRef<{
|
|
30
58
|
[k: string]: unknown;
|
|
31
59
|
}>;
|
|
32
60
|
acceptFiles: (incoming: File[]) => void;
|
|
33
|
-
onNativeChange: (event: Event) => void;
|
|
34
61
|
openPicker: () => void;
|
|
35
|
-
|
|
62
|
+
removeAt: (index: number) => File | undefined;
|
|
63
|
+
clear: () => void;
|
|
36
64
|
};
|
|
@@ -8,35 +8,55 @@ var r = [
|
|
|
8
8
|
"capture"
|
|
9
9
|
];
|
|
10
10
|
function i(i) {
|
|
11
|
-
let a = n(null),
|
|
11
|
+
let { model: a, props: o, emit: s } = i, c = n(null), l = () => i.disabled?.value ?? o.disabled, u = t(() => !l() && !o.readonly), d = t(() => {
|
|
12
12
|
let e = i.excludeFromControl ?? [];
|
|
13
13
|
return Object.fromEntries(Object.entries(i.forwardedAttrs.value).filter(([t]) => !r.includes(t) && !e.includes(t)));
|
|
14
14
|
});
|
|
15
|
-
function
|
|
16
|
-
|
|
15
|
+
function f() {
|
|
16
|
+
c.value && (c.value.value = "");
|
|
17
17
|
}
|
|
18
|
-
function
|
|
19
|
-
let n =
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
function p(t) {
|
|
19
|
+
let n = o.multiple ? a.value : [], { accepted: r, rejected: i } = e(t, n, {
|
|
20
|
+
accept: o.accept,
|
|
21
|
+
maxSize: o.maxSize,
|
|
22
|
+
maxFiles: o.multiple ? o.maxFiles : 1,
|
|
23
|
+
maxTotalSize: o.maxTotalSize
|
|
22
24
|
});
|
|
23
|
-
for (let e of
|
|
24
|
-
|
|
25
|
+
for (let e of i) s("reject", e);
|
|
26
|
+
f(), r.length !== 0 && (a.value = [...n, ...r], s("change", a.value));
|
|
25
27
|
}
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
+
function m(e) {
|
|
29
|
+
p([...e.target.files ?? []]);
|
|
28
30
|
}
|
|
29
|
-
|
|
30
|
-
i.
|
|
31
|
+
let h = t(() => ({
|
|
32
|
+
...Object.fromEntries(Object.entries(i.forwardedAttrs.value).filter(([e]) => r.includes(e))),
|
|
33
|
+
type: "file",
|
|
34
|
+
tabindex: -1,
|
|
35
|
+
"aria-hidden": "true",
|
|
36
|
+
accept: o.accept,
|
|
37
|
+
multiple: o.multiple || void 0,
|
|
38
|
+
disabled: l() || void 0,
|
|
39
|
+
onChange: m
|
|
40
|
+
}));
|
|
41
|
+
function g() {
|
|
42
|
+
u.value && c.value?.click();
|
|
43
|
+
}
|
|
44
|
+
function _(e) {
|
|
45
|
+
let t = a.value[e];
|
|
46
|
+
if (!(!t || !u.value)) return a.value = a.value.filter((t, n) => n !== e), f(), s("remove", t, e), s("change", a.value), t;
|
|
47
|
+
}
|
|
48
|
+
function v() {
|
|
49
|
+
a.value = [], f(), i.onClear?.(), s("change", a.value);
|
|
31
50
|
}
|
|
32
51
|
return {
|
|
33
|
-
fileEl:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
openPicker:
|
|
39
|
-
|
|
52
|
+
fileEl: c,
|
|
53
|
+
enabled: u,
|
|
54
|
+
nativeInputAttrs: h,
|
|
55
|
+
controlAttrs: d,
|
|
56
|
+
acceptFiles: p,
|
|
57
|
+
openPicker: g,
|
|
58
|
+
removeAt: _,
|
|
59
|
+
clear: v
|
|
40
60
|
};
|
|
41
61
|
}
|
|
42
62
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFileField.js","names":[],"sources":["../../src/composables/useFileField.ts"],"sourcesContent":["// @core\n/**\n * The hidden file control both file components are built around — the one that actually\n * opens the operating system's file dialog.\n *\n * The code here is imposed by the browser rather than chosen. A file dialog opens ONLY\n * from a genuine click on a file control, and the list of chosen files cannot be handed\n * to that control from a template the way any other value would be. So the thing the\n * reader sees and clicks can never BE the file control, and the file control can only\n * ever be a SOURCE of files. That is exactly the shape of what follows.\n *\n * The rules deciding which files are acceptable live apart from this, on their own; what\n * was left duplicated between the two components was the wiring around them.\n */\nimport { computed, ref, type ComputedRef, type Ref } from 'vue'\n\nimport { screenFiles, type FileLimits, type FileRejection } from '../utils/file'\n\n// @a11y\n/**\n * The attributes that belong on the hidden file control rather than on the visible one.\n *\n * The usual split assumes a single element that does the work, and there are two here, so\n * the attributes go into three piles instead of two: styling stays on the outermost\n * element, these four go to the hidden control because they are what the FORM reads —\n * the field's name, whether it is mandatory, which form it belongs to, and whether the\n * camera should open — and everything else goes to the element the READER focuses.\n *\n * The three piles never overlap, and that matters: an identifier applied twice would\n * break a label the consumer wrote for the field, and a name applied twice would have it\n * announced twice.\n */\nconst NATIVE_ONLY = ['name', 'required', 'form', 'capture']\n\nexport interface FileFieldOptions {\n /** The component's value — always a list of files, whether one or several are allowed. */\n model: Ref<File[]>\n /** The attributes the consumer wrote, minus styling, still to be split in two. */\n forwardedAttrs: ComputedRef<Record<string, unknown>>\n /** Read at the moment of the event, so a component turned off mid-way stops accepting. */\n enabled: () => boolean\n multiple: () => boolean\n /** The limits as the consumer set them: capping a single-file field at one happens here. */\n limits: () => FileLimits\n onReject: (rejection: FileRejection) => void\n onChange: (files: File[]) => void\n /**\n * Attributes to withhold from the visible control as well.\n *\n * The file field withholds the link to its descriptive text because it puts that list\n * together itself, and a binding written after the spread would silently replace the\n * consumer's rather than being merged with it.\n */\n excludeFromControl?: readonly string[]\n}\n\nexport function useFileField(options: FileFieldOptions) {\n const fileEl = ref<HTMLInputElement | null>(null)\n\n const nativeAttrs = computed(() =>\n Object.fromEntries(\n Object.entries(options.forwardedAttrs.value).filter(([key]) => NATIVE_ONLY.includes(key)),\n ),\n )\n\n const controlAttrs = computed(() => {\n const excluded = options.excludeFromControl ?? []\n return Object.fromEntries(\n Object.entries(options.forwardedAttrs.value).filter(\n ([key]) => !NATIVE_ONLY.includes(key) && !excluded.includes(key),\n ),\n )\n })\n\n /**\n * TRAP — choosing the SAME file again, after clearing the field or removing that file\n * from the list, reports nothing at all: as far as the hidden control is concerned its\n * value never changed. The file then becomes impossible to pick, with nothing to show\n * for it. Emptying the control on every path out is what keeps it selectable.\n */\n function resetNative() {\n if (fileEl.value) fileEl.value.value = ''\n }\n\n /**\n * The one way files get into the value: the operating system's dialog and a drop onto\n * the component both arrive here.\n *\n * A file the limits refuse is REFUSED outright — it never enters the value at all — and\n * every refusal is reported so the component can say why. The screening itself is a\n * plain function elsewhere, which is what makes the ORDER of the reasons testable\n * without putting a component on screen.\n */\n function acceptFiles(incoming: File[]) {\n const multiple = options.multiple()\n const current = multiple ? options.model.value : []\n const limits = options.limits()\n const { accepted, rejected } = screenFiles(incoming, current, {\n ...limits,\n // A single-file field is a list capped at one, so extra files are refused for the\n // same reason as anywhere else: too many.\n maxFiles: multiple ? limits.maxFiles : 1,\n })\n\n for (const rejection of rejected) options.onReject(rejection)\n\n resetNative()\n if (accepted.length === 0) return\n\n options.model.value = [...current, ...accepted]\n options.onChange(options.model.value)\n }\n\n function onNativeChange(event: Event) {\n acceptFiles([...((event.target as HTMLInputElement).files ?? [])])\n }\n\n // @fallback\n /**\n * The one call to the browser neither component can do without: opening the dialog.\n *\n * It clicks the hidden control rather than using the newer, more explicit request to\n * open a picker. Both require the reader to have just done something, but the explicit\n * one THROWS when they have not — and in an embedded page from another site — where a\n * click simply does nothing. On a file control there is nothing to gain in exchange.\n */\n function openPicker() {\n if (!options.enabled()) return\n fileEl.value?.click()\n }\n\n return { fileEl, nativeAttrs, controlAttrs, acceptFiles, onNativeChange, openPicker, resetNative }\n}\n"],"mappings":";;;AAgCA,IAAM,IAAc;CAAC;CAAQ;CAAY;CAAQ;AAAS;AAwB1D,SAAgB,EAAa,GAA2B;CACtD,IAAM,IAAS,EAA6B,IAAI,GAE1C,IAAc,QAClB,OAAO,YACL,OAAO,QAAQ,EAAQ,eAAe,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAS,EAAY,SAAS,CAAG,CAAC,CAC1F,CACF,GAEM,IAAe,QAAe;EAClC,IAAM,IAAW,EAAQ,sBAAsB,CAAC;EAChD,OAAO,OAAO,YACZ,OAAO,QAAQ,EAAQ,eAAe,KAAK,CAAC,CAAC,QAC1C,CAAC,OAAS,CAAC,EAAY,SAAS,CAAG,KAAK,CAAC,EAAS,SAAS,CAAG,CACjE,CACF;CACF,CAAC;CAQD,SAAS,IAAc;EACrB,AAAI,EAAO,UAAO,EAAO,MAAM,QAAQ;CACzC;CAWA,SAAS,EAAY,GAAkB;EACrC,IAAM,IAAW,EAAQ,SAAS,GAC5B,IAAU,IAAW,EAAQ,MAAM,QAAQ,CAAC,GAC5C,IAAS,EAAQ,OAAO,GACxB,EAAE,aAAU,gBAAa,EAAY,GAAU,GAAS;GAC5D,GAAG;GAGH,UAAU,IAAW,EAAO,WAAW;EACzC,CAAC;EAED,KAAK,IAAM,KAAa,GAAU,EAAQ,SAAS,CAAS;EAE5D,EAAY,GACR,EAAS,WAAW,MAExB,EAAQ,MAAM,QAAQ,CAAC,GAAG,GAAS,GAAG,CAAQ,GAC9C,EAAQ,SAAS,EAAQ,MAAM,KAAK;CACtC;CAEA,SAAS,EAAe,GAAc;EACpC,EAAY,CAAC,GAAK,EAAM,OAA4B,SAAS,CAAC,CAAE,CAAC;CACnE;CAWA,SAAS,IAAa;EACf,EAAQ,QAAQ,KACrB,EAAO,OAAO,MAAM;CACtB;CAEA,OAAO;EAAE;EAAQ;EAAa;EAAc;EAAa;EAAgB;EAAY;CAAY;AACnG"}
|
|
1
|
+
{"version":3,"file":"useFileField.js","names":[],"sources":["../../src/composables/useFileField.ts"],"sourcesContent":["// @core\n/**\n * The hidden `<input type=\"file\">` gate of VFileInput and VFilePicker.\n *\n * The JS here is imposed by the platform, not chosen: a dialog opens ONLY from a real click\n * on a file input, and a `FileList` cannot be written from a template. So what the reader\n * clicks can never BE the file input, and the file input can only ever be a SOURCE of files.\n *\n * Hence `.click()` and not `showPicker()` — both need a transient user activation, but\n * `showPicker()` THROWS without one where `.click()` is merely inert — and hence\n * `resetNative()` on every path: without it, re-picking the SAME file after a clear fires no\n * `change` at all and that file becomes unreachable.\n *\n * Everything the two components did identically lives here, so the two cannot drift: the\n * attributes of the hidden input, the screening of what comes in, the removal of one file and\n * the emptying of all of them, and the development warnings both of them owe the integrator.\n */\nimport { computed, getCurrentInstance, ref, watchEffect, type ComputedRef, type Ref } from 'vue'\n\nimport { isDev } from '../utils/env'\nimport { screenFiles, type FileRejection } from '../utils/file'\n\n// @a11y\n/**\n * The attributes belonging on the hidden file input rather than on the visible control.\n *\n * The wrapper-root pattern assumes ONE functional element and there are two here, so the\n * attrs split in three: `class`/`style` on the root, these four on the input because they\n * are what the FORM reads, everything else on the element the READER focuses. The buckets\n * must not overlap — a duplicated `id` breaks a consumer's `<label for>`, a duplicated\n * `name` gets the field announced twice.\n */\nconst NATIVE_ONLY = ['name', 'required', 'form', 'capture']\n\n/** The props both components declare under the same names, read at the moment they matter. */\nexport interface FileFieldProps {\n multiple: boolean\n accept?: string\n maxSize?: number\n maxFiles?: number\n maxTotalSize?: number\n disabled: boolean\n readonly: boolean\n}\n\n/** The events both components declare under the same names and with the same payloads. */\nexport interface FileFieldEmit {\n (event: 'change', files: File[]): void\n (event: 'reject', rejection: FileRejection): void\n (event: 'remove', file: File, index: number): void\n}\n\nexport interface FileFieldOptions {\n /** The component's value — always a list of files, whether one or several are allowed. */\n model: Ref<File[]>\n props: FileFieldProps\n emit: FileFieldEmit\n /** The attributes the consumer wrote, minus styling, still to be split in two. */\n forwardedAttrs: ComputedRef<Record<string, unknown>>\n /**\n * Whether the component is disabled, the row it sits in taken into account. Left out, the\n * `disabled` prop answers alone.\n */\n disabled?: Ref<boolean>\n /**\n * Attributes to withhold from the visible control too. VFileInput withholds\n * `aria-describedby`, which it re-aggregates itself: a binding written after the spread\n * would replace the consumer's rather than merge with it.\n */\n excludeFromControl?: readonly string[]\n /** Called once the selection has been emptied by `clear`, before `change` is emitted. */\n onClear?: () => void\n /**\n * The component's own development warnings, one message per condition that holds. They\n * follow the same rule as the shared ones: each is given once per instance.\n */\n warnings?: () => (string | false)[]\n}\n\nexport function useFileField(options: FileFieldOptions) {\n const { model, props, emit } = options\n\n const fileEl = ref<HTMLInputElement | null>(null)\n\n const disabled = () => options.disabled?.value ?? props.disabled\n\n /** Whether files may come in or go out — no dialog, no drop and no removal otherwise. */\n const enabled = computed(() => !disabled() && !props.readonly)\n\n const controlAttrs = computed(() => {\n const excluded = options.excludeFromControl ?? []\n return Object.fromEntries(\n Object.entries(options.forwardedAttrs.value).filter(\n ([key]) => !NATIVE_ONLY.includes(key) && !excluded.includes(key),\n ),\n )\n })\n\n /**\n * TRAP — picking the SAME file again after a clear or a removal fires no `change` at all:\n * as far as the input is concerned its value never changed, and that file becomes\n * unreachable with nothing to show for it. Emptying it on every path is what keeps it\n * selectable.\n */\n function resetNative() {\n if (fileEl.value) fileEl.value.value = ''\n }\n\n /**\n * The single entry into the model: the dialog and a drop both arrive here.\n *\n * A refused file never enters the model at all, and every refusal is reported so the\n * component can say why. The screening is a pure function in `utils/file`, which is what\n * makes the ORDER of the reasons testable without a mount.\n */\n function acceptFiles(incoming: File[]) {\n const current = props.multiple ? model.value : []\n const { accepted, rejected } = screenFiles(incoming, current, {\n accept: props.accept,\n maxSize: props.maxSize,\n // A single-file field is a list capped at one, so extra files are refused for the\n // same reason as anywhere else: too many.\n maxFiles: props.multiple ? props.maxFiles : 1,\n maxTotalSize: props.maxTotalSize,\n })\n\n for (const rejection of rejected) emit('reject', rejection)\n\n resetNative()\n if (accepted.length === 0) return\n\n model.value = [...current, ...accepted]\n emit('change', model.value)\n }\n\n function onNativeChange(event: Event) {\n acceptFiles([...((event.target as HTMLInputElement).files ?? [])])\n }\n\n /**\n * Everything the hidden input is bound with, the consumer's form attributes included. It\n * is taken out of the tab order and hidden from screen readers, which leaves the visible\n * control as the single stop and the single announcement; it stays disabled only when the\n * component is — a read-only one still submits what it holds.\n */\n const nativeInputAttrs = computed(() => ({\n ...Object.fromEntries(\n Object.entries(options.forwardedAttrs.value).filter(([key]) => NATIVE_ONLY.includes(key)),\n ),\n type: 'file',\n tabindex: -1,\n 'aria-hidden': 'true' as const,\n accept: props.accept,\n multiple: props.multiple || undefined,\n disabled: disabled() || undefined,\n onChange: onNativeChange,\n }))\n\n // @fallback\n /**\n * `.click()` and not `showPicker()`. Both need a transient user activation, but\n * `showPicker()` THROWS without one — and inside a cross-origin iframe — where a click is\n * simply inert. On a file input there is nothing to gain in exchange.\n */\n function openPicker() {\n if (!enabled.value) return\n fileEl.value?.click()\n }\n\n /**\n * Takes ONE file out of the selection, and says which: `remove` with the file and the\n * position it held, then `change` with what is left. It returns the file removed, or\n * `undefined` when nothing was — so the component knows whether it has a focus to catch.\n */\n function removeAt(index: number): File | undefined {\n const file = model.value[index]\n if (!file || !enabled.value) return undefined\n\n model.value = model.value.filter((_, i) => i !== index)\n resetNative()\n emit('remove', file, index)\n emit('change', model.value)\n return file\n }\n\n /** Empties the selection, and the hidden input with it. */\n function clear() {\n model.value = []\n resetNative()\n options.onClear?.()\n emit('change', model.value)\n }\n\n // @devwarn\n /*\n * Both shared guards describe something that fails SILENTLY at runtime. Each message is given\n * once per instance: they sit in an effect, which re-runs on every change of what it reads,\n * and the same sentence repeated at every keystroke is how a warning stops being read.\n */\n if (isDev) {\n // The prefix is the component's own name, read off the instance rather than passed in:\n // this whole block is dropped from a production build, and the name with it.\n const name = getCurrentInstance()?.type.__name\n const warned = new Set<string>()\n const warn = (message: string) => {\n if (warned.has(message)) return\n warned.add(message)\n console.warn(`[${name}] ${message}`)\n }\n watchEffect(() => {\n if (props.maxFiles !== undefined && !props.multiple)\n warn('`maxFiles` ignored without `multiple`: single mode already caps at one file.')\n if (options.forwardedAttrs.value.required !== undefined)\n warn(\n '`required` lands on the hidden file input, which is not focusable: the browser blocks submission with no visible message. Validate the v-model yourself and use the `invalid` prop.',\n )\n for (const message of options.warnings?.() ?? []) if (message) warn(message)\n })\n }\n\n return {\n fileEl,\n enabled,\n nativeInputAttrs,\n controlAttrs,\n acceptFiles,\n openPicker,\n removeAt,\n clear,\n }\n}\n"],"mappings":";;;AAgCA,IAAM,IAAc;CAAC;CAAQ;CAAY;CAAQ;AAAS;AA+C1D,SAAgB,EAAa,GAA2B;CACtD,IAAM,EAAE,UAAO,UAAO,YAAS,GAEzB,IAAS,EAA6B,IAAI,GAE1C,UAAiB,EAAQ,UAAU,SAAS,EAAM,UAGlD,IAAU,QAAe,CAAC,EAAS,KAAK,CAAC,EAAM,QAAQ,GAEvD,IAAe,QAAe;EAClC,IAAM,IAAW,EAAQ,sBAAsB,CAAC;EAChD,OAAO,OAAO,YACZ,OAAO,QAAQ,EAAQ,eAAe,KAAK,CAAC,CAAC,QAC1C,CAAC,OAAS,CAAC,EAAY,SAAS,CAAG,KAAK,CAAC,EAAS,SAAS,CAAG,CACjE,CACF;CACF,CAAC;CAQD,SAAS,IAAc;EACrB,AAAI,EAAO,UAAO,EAAO,MAAM,QAAQ;CACzC;CASA,SAAS,EAAY,GAAkB;EACrC,IAAM,IAAU,EAAM,WAAW,EAAM,QAAQ,CAAC,GAC1C,EAAE,aAAU,gBAAa,EAAY,GAAU,GAAS;GAC5D,QAAQ,EAAM;GACd,SAAS,EAAM;GAGf,UAAU,EAAM,WAAW,EAAM,WAAW;GAC5C,cAAc,EAAM;EACtB,CAAC;EAED,KAAK,IAAM,KAAa,GAAU,EAAK,UAAU,CAAS;EAE1D,EAAY,GACR,EAAS,WAAW,MAExB,EAAM,QAAQ,CAAC,GAAG,GAAS,GAAG,CAAQ,GACtC,EAAK,UAAU,EAAM,KAAK;CAC5B;CAEA,SAAS,EAAe,GAAc;EACpC,EAAY,CAAC,GAAK,EAAM,OAA4B,SAAS,CAAC,CAAE,CAAC;CACnE;CAQA,IAAM,IAAmB,SAAgB;EACvC,GAAG,OAAO,YACR,OAAO,QAAQ,EAAQ,eAAe,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAS,EAAY,SAAS,CAAG,CAAC,CAC1F;EACA,MAAM;EACN,UAAU;EACV,eAAe;EACf,QAAQ,EAAM;EACd,UAAU,EAAM,YAAY,KAAA;EAC5B,UAAU,EAAS,KAAK,KAAA;EACxB,UAAU;CACZ,EAAE;CAQF,SAAS,IAAa;EACf,EAAQ,SACb,EAAO,OAAO,MAAM;CACtB;CAOA,SAAS,EAAS,GAAiC;EACjD,IAAM,IAAO,EAAM,MAAM;EACrB,OAAC,KAAQ,CAAC,EAAQ,QAMtB,OAJA,EAAM,QAAQ,EAAM,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAK,GACtD,EAAY,GACZ,EAAK,UAAU,GAAM,CAAK,GAC1B,EAAK,UAAU,EAAM,KAAK,GACnB;CACT;CAGA,SAAS,IAAQ;EAIf,AAHA,EAAM,QAAQ,CAAC,GACf,EAAY,GACZ,EAAQ,UAAU,GAClB,EAAK,UAAU,EAAM,KAAK;CAC5B;CA6BA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -1,17 +1,2 @@
|
|
|
1
1
|
import { Ref } from 'vue';
|
|
2
|
-
/**
|
|
3
|
-
* Closes something as soon as the focus leaves the component — its floating panel
|
|
4
|
-
* included.
|
|
5
|
-
*
|
|
6
|
-
* That last part is what makes this so short. A panel painted above the whole page is
|
|
7
|
-
* still, in the document, a descendant of the component that owns it, so asking whether
|
|
8
|
-
* the focus went somewhere inside the component is enough; nothing has to be watched at
|
|
9
|
-
* the level of the page.
|
|
10
|
-
*
|
|
11
|
-
* The focus going nowhere in particular — out of the window, or back to the page body —
|
|
12
|
-
* counts as leaving too, and closes.
|
|
13
|
-
*
|
|
14
|
-
* This exists because a panel the browser does not dismiss on its own has to be closed
|
|
15
|
-
* by hand. The self-dismissing kind, the menu's, needs none of it.
|
|
16
|
-
*/
|
|
17
2
|
export declare function useFocusoutDismiss(root: Ref<HTMLElement | null>, close: () => void): (event: FocusEvent) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFocusoutDismiss.js","names":[],"sources":["../../src/composables/useFocusoutDismiss.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"useFocusoutDismiss.js","names":[],"sources":["../../src/composables/useFocusoutDismiss.ts"],"sourcesContent":["// @a11y\n/**\n * A `@focusout` handler closing the component when focus leaves it, panel included.\n *\n * A popover stays a DOM descendant of its owner even while painted in the top layer, so\n * `contains` is the whole test and nothing has to be watched at document level. A null\n * `relatedTarget` — focus gone to the body, or out of the window — counts as leaving.\n *\n * Only `manual` popovers need this. VMenu's `auto` panel is dismissed by the browser.\n */\n\nimport type { Ref } from 'vue'\n\nexport function useFocusoutDismiss(\n root: Ref<HTMLElement | null>,\n close: () => void,\n): (event: FocusEvent) => void {\n return (event: FocusEvent) => {\n const next = event.relatedTarget as Node | null\n if (!next || !root.value?.contains(next)) close()\n }\n}\n"],"mappings":";AAaA,SAAgB,EACd,GACA,GAC6B;CAC7B,QAAQ,MAAsB;EAC5B,IAAM,IAAO,EAAM;EACnB,CAAI,CAAC,KAAQ,CAAC,EAAK,OAAO,SAAS,CAAI,MAAG,EAAM;CAClD;AACF"}
|
|
@@ -1,22 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Whether VInput/VTextarea's icons should render as real buttons: an icon is decoration
|
|
3
|
+
* until someone listens for `@click:icon-*`, at which point it needs a tab stop and a name.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Declared emits are removed from `$attrs`, so the only place left to look is
|
|
6
|
+
* `vnode.props` — in BOTH spellings, a template writing them with dashes and a render
|
|
7
|
+
* function in camel case. Read ONCE and never revised: a listener attached later is not
|
|
8
|
+
* picked up, which is marginal enough to accept.
|
|
7
9
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
|
|
10
|
+
* The missing-name warning lives here rather than in each field: a button nothing can
|
|
11
|
+
* announce is a flaw of the arrangement, not of the component using it.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Whether the component being set up was handed a `@click:icon-start` / `@click:icon-end`
|
|
15
|
+
* listener, in either spelling.
|
|
16
|
+
*/
|
|
17
|
+
export declare function iconClickHandlers(): {
|
|
18
|
+
start: boolean;
|
|
19
|
+
end: boolean;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* The start-icon listener a field COMPOSED on top of VInput — VCombobox, VDateInput,
|
|
23
|
+
* VTimeInput, VFileInput — binds onto that inner VInput, ready to spread beside the
|
|
24
|
+
* consumer's attributes. Call it during setup: it reads the component's own vnode.
|
|
15
25
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
26
|
+
* Each of those fields declares `click:icon-start` as its own event, which puts it in the API
|
|
27
|
+
* tables and takes it out of `$attrs`, hence out of what is forwarded: the listener has to be
|
|
28
|
+
* bound by hand. And it has to follow what the consumer actually wrote — bound unconditionally,
|
|
29
|
+
* VInput would read a handler on every instance and turn a decorative icon into a focusable
|
|
30
|
+
* button nobody asked for. So it is `undefined` when there is nothing to relay.
|
|
19
31
|
*/
|
|
32
|
+
export declare function iconStartListener(relay: (event: MouseEvent) => void): {
|
|
33
|
+
'onClick:icon-start': (event: MouseEvent) => void;
|
|
34
|
+
} | undefined;
|
|
20
35
|
export declare function useIconClickHandlers(options: {
|
|
21
36
|
name: string;
|
|
22
37
|
iconStartLabel?: string;
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import { getCurrentInstance as e } from "vue";
|
|
2
2
|
//#region src/composables/useIconClickHandlers.ts
|
|
3
|
-
function t(
|
|
4
|
-
let
|
|
3
|
+
function t() {
|
|
4
|
+
let t = e()?.vnode.props ?? {};
|
|
5
5
|
return {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
start: "onClick:iconStart" in t || "onClick:icon-start" in t,
|
|
7
|
+
end: "onClick:iconEnd" in t || "onClick:icon-end" in t
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function n(e) {
|
|
11
|
+
return t().start ? { "onClick:icon-start": e } : void 0;
|
|
12
|
+
}
|
|
13
|
+
function r(e) {
|
|
14
|
+
let { start: n, end: r } = t();
|
|
15
|
+
return {
|
|
16
|
+
hasIconStartHandler: n,
|
|
17
|
+
hasIconEndHandler: r
|
|
8
18
|
};
|
|
9
19
|
}
|
|
10
20
|
//#endregion
|
|
11
|
-
export { t as useIconClickHandlers };
|
|
21
|
+
export { t as iconClickHandlers, n as iconStartListener, r as useIconClickHandlers };
|
|
12
22
|
|
|
13
23
|
//# sourceMappingURL=useIconClickHandlers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useIconClickHandlers.js","names":[],"sources":["../../src/composables/useIconClickHandlers.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"useIconClickHandlers.js","names":[],"sources":["../../src/composables/useIconClickHandlers.ts"],"sourcesContent":["// @core\n/**\n * Whether VInput/VTextarea's icons should render as real buttons: an icon is decoration\n * until someone listens for `@click:icon-*`, at which point it needs a tab stop and a name.\n *\n * Declared emits are removed from `$attrs`, so the only place left to look is\n * `vnode.props` — in BOTH spellings, a template writing them with dashes and a render\n * function in camel case. Read ONCE and never revised: a listener attached later is not\n * picked up, which is marginal enough to accept.\n *\n * The missing-name warning lives here rather than in each field: a button nothing can\n * announce is a flaw of the arrangement, not of the component using it.\n */\n\nimport { getCurrentInstance } from 'vue'\n\nimport { isDev } from '../utils/env'\n\n/**\n * Whether the component being set up was handed a `@click:icon-start` / `@click:icon-end`\n * listener, in either spelling.\n */\nexport function iconClickHandlers(): { start: boolean; end: boolean } {\n const vnodeProps = getCurrentInstance()?.vnode.props ?? {}\n return {\n start: 'onClick:iconStart' in vnodeProps || 'onClick:icon-start' in vnodeProps,\n end: 'onClick:iconEnd' in vnodeProps || 'onClick:icon-end' in vnodeProps,\n }\n}\n\n/**\n * The start-icon listener a field COMPOSED on top of VInput — VCombobox, VDateInput,\n * VTimeInput, VFileInput — binds onto that inner VInput, ready to spread beside the\n * consumer's attributes. Call it during setup: it reads the component's own vnode.\n *\n * Each of those fields declares `click:icon-start` as its own event, which puts it in the API\n * tables and takes it out of `$attrs`, hence out of what is forwarded: the listener has to be\n * bound by hand. And it has to follow what the consumer actually wrote — bound unconditionally,\n * VInput would read a handler on every instance and turn a decorative icon into a focusable\n * button nobody asked for. So it is `undefined` when there is nothing to relay.\n */\nexport function iconStartListener(\n relay: (event: MouseEvent) => void,\n): { 'onClick:icon-start': (event: MouseEvent) => void } | undefined {\n return iconClickHandlers().start ? { 'onClick:icon-start': relay } : undefined\n}\n\nexport function useIconClickHandlers(options: {\n name: string\n iconStartLabel?: string\n iconEndLabel?: string\n}): { hasIconStartHandler: boolean; hasIconEndHandler: boolean } {\n const { start: hasIconStartHandler, end: hasIconEndHandler } = iconClickHandlers()\n\n // @a11y @devwarn\n if (isDev) {\n if (hasIconStartHandler && !options.iconStartLabel)\n console.warn(\n `[${options.name}] clickable start icon without iconStartLabel — provide an accessible label.`,\n )\n if (hasIconEndHandler && !options.iconEndLabel)\n console.warn(\n `[${options.name}] clickable end icon without iconEndLabel — provide an accessible label.`,\n )\n }\n\n return { hasIconStartHandler, hasIconEndHandler }\n}\n"],"mappings":";;AAsBA,SAAgB,IAAsD;CACpE,IAAM,IAAa,EAAmB,CAAC,EAAE,MAAM,SAAS,CAAC;CACzD,OAAO;EACL,OAAO,uBAAuB,KAAc,wBAAwB;EACpE,KAAK,qBAAqB,KAAc,sBAAsB;CAChE;AACF;AAaA,SAAgB,EACd,GACmE;CACnE,OAAO,EAAkB,CAAC,CAAC,QAAQ,EAAE,sBAAsB,EAAM,IAAI,KAAA;AACvE;AAEA,SAAgB,EAAqB,GAI4B;CAC/D,IAAM,EAAE,OAAO,GAAqB,KAAK,MAAsB,EAAkB;CAcjF,OAAO;EAAE;EAAqB;CAAkB;AAClD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ComputedRef } from 'vue';
|
|
2
|
+
export interface InertLinkOptions {
|
|
3
|
+
/** The address the component would link to, or `undefined` when it is not a link. */
|
|
4
|
+
href: () => string | undefined;
|
|
5
|
+
/** Whether the component is unusable right now. */
|
|
6
|
+
inert: () => boolean;
|
|
7
|
+
/** The attributes the component forwards to the element that acts. */
|
|
8
|
+
attrs: () => Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export interface InertLink {
|
|
11
|
+
/** Whether the component renders an `<a>`. */
|
|
12
|
+
isLink: ComputedRef<boolean>;
|
|
13
|
+
/** Whether that `<a>` is inert, which is what `aria-disabled` is bound to. */
|
|
14
|
+
isInertLink: ComputedRef<boolean>;
|
|
15
|
+
/** The `href` to bind: the address, or nothing on an inert link. */
|
|
16
|
+
linkHref: ComputedRef<string | undefined>;
|
|
17
|
+
/** The attributes to bind, without the click handler on an inert link. */
|
|
18
|
+
attrs: ComputedRef<Record<string, unknown>>;
|
|
19
|
+
}
|
|
20
|
+
export declare function useInertLink(options: InertLinkOptions): InertLink;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { computed as e } from "vue";
|
|
2
|
+
//#region src/composables/useInertLink.ts
|
|
3
|
+
function t(t) {
|
|
4
|
+
let n = e(() => t.href() !== void 0), r = e(() => n.value && t.inert());
|
|
5
|
+
return {
|
|
6
|
+
isLink: n,
|
|
7
|
+
isInertLink: r,
|
|
8
|
+
linkHref: e(() => r.value ? void 0 : t.href()),
|
|
9
|
+
attrs: e(() => {
|
|
10
|
+
let e = t.attrs();
|
|
11
|
+
if (!r.value) return e;
|
|
12
|
+
let n = {
|
|
13
|
+
role: "link",
|
|
14
|
+
...e
|
|
15
|
+
};
|
|
16
|
+
return delete n.onClick, n;
|
|
17
|
+
})
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { t as useInertLink };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=useInertLink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInertLink.js","names":[],"sources":["../../src/composables/useInertLink.ts"],"sourcesContent":["// @a11y\n/**\n * The inert link of every component that may render as an `<a>`: VButton, VChip and VAvatar.\n *\n * A link has no `disabled` attribute, so the complete inertness a `<button disabled>` gets for\n * free is rebuilt by hand, in parts that only work together. The address is dropped, so the\n * link can be neither focused nor followed; `aria-disabled` tells assistive technology why; and\n * the consumer's `onClick` is filtered out of the attributes, since an `<a>` without an `href`\n * still dispatches clicks and a handler would otherwise run on a control announced as disabled.\n *\n * TRAP — the attributes also gain `role=\"link\"`. An `<a>` without `href` is no longer a link\n * but a generic element, on which an `aria-label` is PROHIBITED (axe `aria-prohibited-attr`)\n * and `aria-disabled` describes nothing: an icon-only VIconButton turned inert would lose its\n * name. The role is spread BEFORE the consumer's attributes, so a role of their own still wins —\n * which is also why it travels in the attributes and is never bound after them, where an\n * `undefined` would erase the `role=\"tab\"` a VTab hands its button.\n *\n * Each of the three decides for itself WHEN it is a link and WHEN it is inert (VChip gives\n * `selectable` precedence over `href`, VButton counts `loading` as inert), which is why both\n * arrive as getters; the consequences are the same everywhere and live here.\n */\nimport { computed } from 'vue'\nimport type { ComputedRef } from 'vue'\n\nexport interface InertLinkOptions {\n /** The address the component would link to, or `undefined` when it is not a link. */\n href: () => string | undefined\n /** Whether the component is unusable right now. */\n inert: () => boolean\n /** The attributes the component forwards to the element that acts. */\n attrs: () => Record<string, unknown>\n}\n\nexport interface InertLink {\n /** Whether the component renders an `<a>`. */\n isLink: ComputedRef<boolean>\n /** Whether that `<a>` is inert, which is what `aria-disabled` is bound to. */\n isInertLink: ComputedRef<boolean>\n /** The `href` to bind: the address, or nothing on an inert link. */\n linkHref: ComputedRef<string | undefined>\n /** The attributes to bind, without the click handler on an inert link. */\n attrs: ComputedRef<Record<string, unknown>>\n}\n\nexport function useInertLink(options: InertLinkOptions): InertLink {\n const isLink = computed(() => options.href() !== undefined)\n const isInertLink = computed(() => isLink.value && options.inert())\n return {\n isLink,\n isInertLink,\n linkHref: computed(() => (isInertLink.value ? undefined : options.href())),\n attrs: computed(() => {\n const attrs = options.attrs()\n if (!isInertLink.value) return attrs\n const rest: Record<string, unknown> = { role: 'link', ...attrs }\n delete rest.onClick\n return rest\n }),\n }\n}\n"],"mappings":";;AA4CA,SAAgB,EAAa,GAAsC;CACjE,IAAM,IAAS,QAAe,EAAQ,KAAK,MAAM,KAAA,CAAS,GACpD,IAAc,QAAe,EAAO,SAAS,EAAQ,MAAM,CAAC;CAClE,OAAO;EACL;EACA;EACA,UAAU,QAAgB,EAAY,QAAQ,KAAA,IAAY,EAAQ,KAAK,CAAE;EACzE,OAAO,QAAe;GACpB,IAAM,IAAQ,EAAQ,MAAM;GAC5B,IAAI,CAAC,EAAY,OAAO,OAAO;GAC/B,IAAM,IAAgC;IAAE,MAAM;IAAQ,GAAG;GAAM;GAE/D,OADA,OAAO,EAAK,SACL;EACT,CAAC;CACH;AACF"}
|