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,5 +1,8 @@
|
|
|
1
1
|
import { ButtonHTMLAttributes } from 'vue';
|
|
2
|
+
import { ButtonSize, ButtonTone, ButtonVariant } from '../VButton/VButton.js';
|
|
2
3
|
import { IconSource } from '../VIcon/types.js';
|
|
4
|
+
/** The silhouette. The box is square either way; only the corners change. */
|
|
5
|
+
export type IconButtonShape = 'square' | 'circular';
|
|
3
6
|
interface IconButtonProps {
|
|
4
7
|
/**
|
|
5
8
|
* What the button does, in words. It becomes the `aria-label` and is the only
|
|
@@ -7,22 +10,35 @@ interface IconButtonProps {
|
|
|
7
10
|
* month") rather than the picture.
|
|
8
11
|
*/
|
|
9
12
|
label: string;
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* How much visual weight the button carries — the VButton variants. `ghost` by default,
|
|
15
|
+
* and inside a VButtonGroup the group's own variant wins over it.
|
|
16
|
+
*/
|
|
17
|
+
variant?: ButtonVariant;
|
|
18
|
+
/**
|
|
19
|
+
* What the action means, in colour — the VButton tones. An icon-only button is usually
|
|
20
|
+
* secondary, which is why it starts neutral where VButton starts accent. Left out inside
|
|
21
|
+
* a VButtonGroup it takes the group's tone; on its own it is `neutral`.
|
|
22
|
+
*/
|
|
23
|
+
tone?: ButtonTone;
|
|
14
24
|
/** Raises the button with a shadow, and a raised surface on ghost and outline. */
|
|
15
25
|
elevated?: boolean;
|
|
16
26
|
/** The size of the square, taken from the scale shared by every control. */
|
|
17
|
-
size?:
|
|
27
|
+
size?: ButtonSize;
|
|
18
28
|
/** Takes 4px off both sides of the square, which stays square. */
|
|
19
29
|
compact?: boolean;
|
|
20
30
|
/**
|
|
21
31
|
* The silhouette: a square carrying the corner radius every control shares, or a
|
|
22
32
|
* circle. The box itself is square either way — only the corners change.
|
|
23
33
|
*/
|
|
24
|
-
shape?:
|
|
25
|
-
/**
|
|
34
|
+
shape?: IconButtonShape;
|
|
35
|
+
/**
|
|
36
|
+
* Turns the button into an `<a>` pointing at this address, on VButton's terms: a disabled
|
|
37
|
+
* or loading link becomes inert, the address dropped so it can be neither focused nor
|
|
38
|
+
* followed.
|
|
39
|
+
*/
|
|
40
|
+
href?: string;
|
|
41
|
+
/** The native type of the button, `button` by default. Ignored once `href` makes it a link. */
|
|
26
42
|
type?: ButtonHTMLAttributes['type'];
|
|
27
43
|
/** Makes the button unusable, greyed out through the colour tokens. */
|
|
28
44
|
disabled?: boolean;
|
|
@@ -45,15 +61,16 @@ type __VLS_Slots = {
|
|
|
45
61
|
};
|
|
46
62
|
declare const __VLS_base: import('vue').DefineComponent<IconButtonProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<IconButtonProps> & Readonly<{}>, {
|
|
47
63
|
loading: boolean;
|
|
48
|
-
size:
|
|
64
|
+
size: ButtonSize;
|
|
49
65
|
type: "button" | "submit" | "reset";
|
|
50
|
-
variant:
|
|
51
|
-
tone:
|
|
66
|
+
variant: ButtonVariant;
|
|
67
|
+
tone: ButtonTone;
|
|
52
68
|
elevated: boolean;
|
|
53
69
|
compact: boolean;
|
|
70
|
+
href: string;
|
|
54
71
|
disabled: boolean;
|
|
55
72
|
iconFilled: boolean;
|
|
56
|
-
shape:
|
|
73
|
+
shape: IconButtonShape;
|
|
57
74
|
icon: IconSource;
|
|
58
75
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
59
76
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VIconButton.js","names":[],"sources":["../../../src/components/VIconButton/VIconButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y — the MANDATORY label is the component's whole reason to exist alongside\n// VButton: an icon on its own gives assistive technology no accessible name.\n/**\n * A button showing an icon and nothing else, square rather than oblong. It offers\n * the same appearance options as VButton and forwards them to it.\n *\n * The one difference that matters is the `label` prop, which is REQUIRED here. A\n * picture says nothing to a screen reader, so the label is what names the action —\n * without it the button would be announced as just \"button\".\n */\nimport type { ButtonHTMLAttributes } from 'vue'\n\nimport VButton from '../VButton/VButton.vue'\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\n\ninterface IconButtonProps {\n /**\n * What the button does, in words. It becomes the `aria-label` and is the only\n * thing a screen reader has to go on, so it names the action (\"Close\", \"Next\n * month\") rather than the picture.\n */\n label: string\n
|
|
1
|
+
{"version":3,"file":"VIconButton.js","names":[],"sources":["../../../src/components/VIconButton/VIconButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y — the MANDATORY label is the component's whole reason to exist alongside\n// VButton: an icon on its own gives assistive technology no accessible name.\n/**\n * A button showing an icon and nothing else, square rather than oblong. It offers\n * the same appearance options as VButton and forwards them to it.\n *\n * The one difference that matters is the `label` prop, which is REQUIRED here. A\n * picture says nothing to a screen reader, so the label is what names the action —\n * without it the button would be announced as just \"button\".\n */\nimport { computed, inject } from 'vue'\nimport type { ButtonHTMLAttributes } from 'vue'\n\nimport VButton from '../VButton/VButton.vue'\nimport type { ButtonSize, ButtonTone, ButtonVariant } from '../VButton/VButton.vue'\nimport { buttonGroupKey } from '../VButton/context'\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\n\n/** The silhouette. The box is square either way; only the corners change. */\nexport type IconButtonShape = 'square' | 'circular'\n\ninterface IconButtonProps {\n /**\n * What the button does, in words. It becomes the `aria-label` and is the only\n * thing a screen reader has to go on, so it names the action (\"Close\", \"Next\n * month\") rather than the picture.\n */\n label: string\n /**\n * How much visual weight the button carries — the VButton variants. `ghost` by default,\n * and inside a VButtonGroup the group's own variant wins over it.\n */\n variant?: ButtonVariant\n /**\n * What the action means, in colour — the VButton tones. An icon-only button is usually\n * secondary, which is why it starts neutral where VButton starts accent. Left out inside\n * a VButtonGroup it takes the group's tone; on its own it is `neutral`.\n */\n tone?: ButtonTone\n /** Raises the button with a shadow, and a raised surface on ghost and outline. */\n elevated?: boolean\n /** The size of the square, taken from the scale shared by every control. */\n size?: ButtonSize\n /** Takes 4px off both sides of the square, which stays square. */\n compact?: boolean\n /**\n * The silhouette: a square carrying the corner radius every control shares, or a\n * circle. The box itself is square either way — only the corners change.\n */\n shape?: IconButtonShape\n /**\n * Turns the button into an `<a>` pointing at this address, on VButton's terms: a disabled\n * or loading link becomes inert, the address dropped so it can be neither focused nor\n * followed.\n */\n href?: string\n /** The native type of the button, `button` by default. Ignored once `href` makes it a link. */\n type?: ButtonHTMLAttributes['type']\n /** Makes the button unusable, greyed out through the colour tokens. */\n disabled?: boolean\n /** Replaces the icon with a spinner and disables the button while it turns. */\n loading?: boolean\n /**\n * The icon to show: an icon name, or an explicit render. The default slot is the\n * way to supply one this prop cannot express.\n */\n icon?: IconSource\n /** Renders the icon in its filled form (the font's `FILL` axis). */\n iconFilled?: boolean\n}\n\nconst props = withDefaults(defineProps<IconButtonProps>(), {\n variant: 'ghost',\n // No default, so that an absent tone stays distinguishable from an explicit one (see\n // the resolution below and VButton's own `tone`).\n tone: undefined,\n elevated: false,\n size: 'md',\n compact: false,\n shape: 'square',\n href: undefined,\n type: 'button',\n disabled: false,\n loading: false,\n icon: undefined,\n iconFilled: false,\n})\n\ndefineSlots<{\n /**\n * The icon, when the `icon` prop cannot express it: a VIcon, or an inline SVG\n * marked `aria-hidden=\"true\"` — the button is already named by its `label`.\n */\n default(): unknown\n}>()\n\n/*\n * The ONE prop a VButtonGroup cannot arbitrate on its own. The four others are handed\n * to VButton as they are and the group wins there over whatever arrives, so nothing has\n * to be resolved here; the tone goes the other way, the button's own answer first, and\n * VButton would take `accent` as its last resort where an icon-only button takes\n * `neutral`. Resolving it here is what keeps that difference.\n */\nconst group = inject(buttonGroupKey, null)\nconst resolvedTone = computed<ButtonTone>(() => props.tone ?? group?.tone ?? 'neutral')\n</script>\n\n<template>\n <!--\n `shape` is ours alone: VButton knows nothing about it, so the attribute travels\n through its $attrs down to the element it renders — the same route the\n v-icon-button class and `data-icon-only` take, the latter picked up by VButton's own\n square rule. Everything else is a real VButton prop and has to be forwarded by hand,\n an unforwarded one never reaching its data attribute.\n -->\n <VButton\n class=\"v-icon-button\"\n :data-shape=\"shape\"\n data-icon-only\n :variant=\"variant\"\n :tone=\"resolvedTone\"\n :elevated=\"elevated\"\n :size=\"size\"\n :compact=\"compact\"\n :href=\"href\"\n :type=\"type\"\n :disabled=\"disabled\"\n :loading=\"loading\"\n :aria-label=\"label\"\n >\n <!--\n TRAP — the icon goes in VButton's `start` slot and NOT in its default one. The\n spinner replaces the start slot alone, the default slot being the label, which a\n loading button keeps. Rendered in the default slot the icon would sit BESIDE the\n spinner, both of them in a box only wide enough for one.\n -->\n <template #start>\n <VIcon v-if=\"icon\" v-bind=\"iconProps(icon)\" :filled=\"iconFilled\" />\n <slot v-else />\n </template>\n </VButton>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The square itself is VButton's `[data-icon-only]` rule, which this component opts\n * into; what is left here is the silhouette. [data-shape] takes the selector to (0,2,0),\n * which beats the border-radius VButton sets on that very element at (0,1,0) whatever the\n * consumer's bundler decides about the order of the two sheets.\n *\n * The `square` value writes nothing — it IS the radius VButton already applies, so a\n * consumer overriding --vectis-radius-interactive keeps a single place to change.\n */\n .v-icon-button[data-shape='circular'] {\n border-radius: var(--vectis-radius-pill);\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import e from "../VIcon/
|
|
2
|
-
import
|
|
3
|
-
import n from "../VButton/
|
|
4
|
-
import
|
|
1
|
+
import { iconProps as e } from "../VIcon/iconProps.js";
|
|
2
|
+
import t from "../VIcon/VIcon.js";
|
|
3
|
+
import { buttonGroupKey as n } from "../VButton/context.js";
|
|
4
|
+
import r from "../VButton/VButton.js";
|
|
5
|
+
import { computed as i, createBlock as a, defineComponent as o, inject as s, mergeProps as c, openBlock as l, renderSlot as u, unref as d, withCtx as f } from "vue";
|
|
5
6
|
//#region src/components/VIconButton/VIconButton.vue?vue&type=script&setup=true&lang.ts
|
|
6
|
-
var
|
|
7
|
+
var p = /*@__PURE__*/ o({
|
|
7
8
|
__name: "VIconButton",
|
|
8
9
|
props: {
|
|
9
10
|
label: {},
|
|
10
11
|
variant: { default: "ghost" },
|
|
11
|
-
tone: { default:
|
|
12
|
+
tone: { default: void 0 },
|
|
12
13
|
elevated: {
|
|
13
14
|
type: Boolean,
|
|
14
15
|
default: !1
|
|
@@ -19,6 +20,7 @@ var u = /*@__PURE__*/ i({
|
|
|
19
20
|
default: !1
|
|
20
21
|
},
|
|
21
22
|
shape: { default: "square" },
|
|
23
|
+
href: { default: void 0 },
|
|
22
24
|
type: { default: "button" },
|
|
23
25
|
disabled: {
|
|
24
26
|
type: Boolean,
|
|
@@ -34,21 +36,24 @@ var u = /*@__PURE__*/ i({
|
|
|
34
36
|
default: !1
|
|
35
37
|
}
|
|
36
38
|
},
|
|
37
|
-
setup(
|
|
38
|
-
|
|
39
|
+
setup(o) {
|
|
40
|
+
let p = o, m = s(n, null), h = i(() => p.tone ?? m?.tone ?? "neutral");
|
|
41
|
+
return (n, i) => (l(), a(r, {
|
|
39
42
|
class: "v-icon-button",
|
|
40
|
-
"data-shape":
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
"data-shape": o.shape,
|
|
44
|
+
"data-icon-only": "",
|
|
45
|
+
variant: o.variant,
|
|
46
|
+
tone: h.value,
|
|
47
|
+
elevated: o.elevated,
|
|
48
|
+
size: o.size,
|
|
49
|
+
compact: o.compact,
|
|
50
|
+
href: o.href,
|
|
51
|
+
type: o.type,
|
|
52
|
+
disabled: o.disabled,
|
|
53
|
+
loading: o.loading,
|
|
54
|
+
"aria-label": o.label
|
|
50
55
|
}, {
|
|
51
|
-
|
|
56
|
+
start: f(() => [o.icon ? (l(), a(t, c({ key: 0 }, d(e)(o.icon), { filled: o.iconFilled }), null, 16, ["filled"])) : u(n.$slots, "default", {}, void 0, void 0, 1)]),
|
|
52
57
|
_: 3
|
|
53
58
|
}, 8, [
|
|
54
59
|
"data-shape",
|
|
@@ -57,6 +62,7 @@ var u = /*@__PURE__*/ i({
|
|
|
57
62
|
"elevated",
|
|
58
63
|
"size",
|
|
59
64
|
"compact",
|
|
65
|
+
"href",
|
|
60
66
|
"type",
|
|
61
67
|
"disabled",
|
|
62
68
|
"loading",
|
|
@@ -65,6 +71,6 @@ var u = /*@__PURE__*/ i({
|
|
|
65
71
|
}
|
|
66
72
|
});
|
|
67
73
|
//#endregion
|
|
68
|
-
export {
|
|
74
|
+
export { p as default };
|
|
69
75
|
|
|
70
76
|
//# sourceMappingURL=VIconButton.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VIconButton.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VIconButton/VIconButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y — the MANDATORY label is the component's whole reason to exist alongside\n// VButton: an icon on its own gives assistive technology no accessible name.\n/**\n * A button showing an icon and nothing else, square rather than oblong. It offers\n * the same appearance options as VButton and forwards them to it.\n *\n * The one difference that matters is the `label` prop, which is REQUIRED here. A\n * picture says nothing to a screen reader, so the label is what names the action —\n * without it the button would be announced as just \"button\".\n */\nimport type { ButtonHTMLAttributes } from 'vue'\n\nimport VButton from '../VButton/VButton.vue'\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\n\ninterface IconButtonProps {\n /**\n * What the button does, in words. It becomes the `aria-label` and is the only\n * thing a screen reader has to go on, so it names the action (\"Close\", \"Next\n * month\") rather than the picture.\n */\n label: string\n
|
|
1
|
+
{"version":3,"file":"VIconButton.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VIconButton/VIconButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y — the MANDATORY label is the component's whole reason to exist alongside\n// VButton: an icon on its own gives assistive technology no accessible name.\n/**\n * A button showing an icon and nothing else, square rather than oblong. It offers\n * the same appearance options as VButton and forwards them to it.\n *\n * The one difference that matters is the `label` prop, which is REQUIRED here. A\n * picture says nothing to a screen reader, so the label is what names the action —\n * without it the button would be announced as just \"button\".\n */\nimport { computed, inject } from 'vue'\nimport type { ButtonHTMLAttributes } from 'vue'\n\nimport VButton from '../VButton/VButton.vue'\nimport type { ButtonSize, ButtonTone, ButtonVariant } from '../VButton/VButton.vue'\nimport { buttonGroupKey } from '../VButton/context'\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\n\n/** The silhouette. The box is square either way; only the corners change. */\nexport type IconButtonShape = 'square' | 'circular'\n\ninterface IconButtonProps {\n /**\n * What the button does, in words. It becomes the `aria-label` and is the only\n * thing a screen reader has to go on, so it names the action (\"Close\", \"Next\n * month\") rather than the picture.\n */\n label: string\n /**\n * How much visual weight the button carries — the VButton variants. `ghost` by default,\n * and inside a VButtonGroup the group's own variant wins over it.\n */\n variant?: ButtonVariant\n /**\n * What the action means, in colour — the VButton tones. An icon-only button is usually\n * secondary, which is why it starts neutral where VButton starts accent. Left out inside\n * a VButtonGroup it takes the group's tone; on its own it is `neutral`.\n */\n tone?: ButtonTone\n /** Raises the button with a shadow, and a raised surface on ghost and outline. */\n elevated?: boolean\n /** The size of the square, taken from the scale shared by every control. */\n size?: ButtonSize\n /** Takes 4px off both sides of the square, which stays square. */\n compact?: boolean\n /**\n * The silhouette: a square carrying the corner radius every control shares, or a\n * circle. The box itself is square either way — only the corners change.\n */\n shape?: IconButtonShape\n /**\n * Turns the button into an `<a>` pointing at this address, on VButton's terms: a disabled\n * or loading link becomes inert, the address dropped so it can be neither focused nor\n * followed.\n */\n href?: string\n /** The native type of the button, `button` by default. Ignored once `href` makes it a link. */\n type?: ButtonHTMLAttributes['type']\n /** Makes the button unusable, greyed out through the colour tokens. */\n disabled?: boolean\n /** Replaces the icon with a spinner and disables the button while it turns. */\n loading?: boolean\n /**\n * The icon to show: an icon name, or an explicit render. The default slot is the\n * way to supply one this prop cannot express.\n */\n icon?: IconSource\n /** Renders the icon in its filled form (the font's `FILL` axis). */\n iconFilled?: boolean\n}\n\nconst props = withDefaults(defineProps<IconButtonProps>(), {\n variant: 'ghost',\n // No default, so that an absent tone stays distinguishable from an explicit one (see\n // the resolution below and VButton's own `tone`).\n tone: undefined,\n elevated: false,\n size: 'md',\n compact: false,\n shape: 'square',\n href: undefined,\n type: 'button',\n disabled: false,\n loading: false,\n icon: undefined,\n iconFilled: false,\n})\n\ndefineSlots<{\n /**\n * The icon, when the `icon` prop cannot express it: a VIcon, or an inline SVG\n * marked `aria-hidden=\"true\"` — the button is already named by its `label`.\n */\n default(): unknown\n}>()\n\n/*\n * The ONE prop a VButtonGroup cannot arbitrate on its own. The four others are handed\n * to VButton as they are and the group wins there over whatever arrives, so nothing has\n * to be resolved here; the tone goes the other way, the button's own answer first, and\n * VButton would take `accent` as its last resort where an icon-only button takes\n * `neutral`. Resolving it here is what keeps that difference.\n */\nconst group = inject(buttonGroupKey, null)\nconst resolvedTone = computed<ButtonTone>(() => props.tone ?? group?.tone ?? 'neutral')\n</script>\n\n<template>\n <!--\n `shape` is ours alone: VButton knows nothing about it, so the attribute travels\n through its $attrs down to the element it renders — the same route the\n v-icon-button class and `data-icon-only` take, the latter picked up by VButton's own\n square rule. Everything else is a real VButton prop and has to be forwarded by hand,\n an unforwarded one never reaching its data attribute.\n -->\n <VButton\n class=\"v-icon-button\"\n :data-shape=\"shape\"\n data-icon-only\n :variant=\"variant\"\n :tone=\"resolvedTone\"\n :elevated=\"elevated\"\n :size=\"size\"\n :compact=\"compact\"\n :href=\"href\"\n :type=\"type\"\n :disabled=\"disabled\"\n :loading=\"loading\"\n :aria-label=\"label\"\n >\n <!--\n TRAP — the icon goes in VButton's `start` slot and NOT in its default one. The\n spinner replaces the start slot alone, the default slot being the label, which a\n loading button keeps. Rendered in the default slot the icon would sit BESIDE the\n spinner, both of them in a box only wide enough for one.\n -->\n <template #start>\n <VIcon v-if=\"icon\" v-bind=\"iconProps(icon)\" :filled=\"iconFilled\" />\n <slot v-else />\n </template>\n </VButton>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The square itself is VButton's `[data-icon-only]` rule, which this component opts\n * into; what is left here is the silhouette. [data-shape] takes the selector to (0,2,0),\n * which beats the border-radius VButton sets on that very element at (0,1,0) whatever the\n * consumer's bundler decides about the order of the two sheets.\n *\n * The `square` value writes nothing — it IS the radius VButton already applies, so a\n * consumer overriding --vectis-radius-interactive keeps a single place to change.\n */\n .v-icon-button[data-shape='circular'] {\n border-radius: var(--vectis-radius-pill);\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0EA,IAAM,IAAQ,GAgCR,IAAQ,EAAO,GAAgB,IAAI,GACnC,IAAe,QAA2B,EAAM,QAAQ,GAAO,QAAQ,SAAS;yBAWpF,EAyBU,GAAA;GAxBR,OAAM;GACL,cAAY,EAAA;GACb,kBAAA;GACC,SAAS,EAAA;GACT,MAAM,EAAA;GACN,UAAU,EAAA;GACV,MAAM,EAAA;GACN,SAAS,EAAA;GACT,MAAM,EAAA;GACN,MAAM,EAAA;GACN,UAAU,EAAA;GACV,SAAS,EAAA;GACT,cAAY,EAAA;;GAQF,OAAK,QAnBZ,CAoBW,EAAA,QAAA,EAAA,GAAb,EAAmE,GAAnE,EAAmE,EAAA,KAAA,EAAA,GAAxC,EAAA,CAAA,CAAS,CAAC,EAAA,IAAI,GAAA,EAAI,QAAQ,EAAA,WAAU,CAAA,GAAA,MAAA,IAAA,CAAA,QAAA,CAAA,KAC/D,EAAe,EAAA,QAAA,WAAA,CAAA,GAAA,KAAA,GAAA,KAAA,GAAA,CAAA,CAAA,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
@layer vectis.reset, vectis.tokens, vectis.components, vectis.utilities;
|
|
2
|
-
@layer vectis.components{.v-input{gap:var(--vectis-space-1);width:100%;font-family:var(--vectis-text-family);flex-direction:column;display:flex}.v-input-field{--field-border-color:var(--vectis-color-border-strong);align-items:center;gap:var(--control-gap);height:var(--control-height);padding-inline:var(--control-padding-inline-field);background:var(--vectis-color-surface);color:var(--vectis-color-text);border:1px solid var(--field-border-color);border-radius:var(--vectis-radius-interactive);font-size:var(--control-font-size);transition:border-color var(--vectis-duration-fast) var(--vectis-ease-default), background-color var(--vectis-duration-fast) var(--vectis-ease-default), box-shadow var(--vectis-duration-fast) var(--vectis-ease-default);display:flex}.v-input-control{min-width:0;height:100%;color:inherit;font:inherit;background:0 0;border:none;outline:none;flex:1;padding:0}.v-input-control::placeholder{color:var(--vectis-color-text-subtle)}.v-input-control::-webkit-search-cancel-button{appearance:none}.v-input-control::-webkit-search-decoration{appearance:none}.v-input-control::-webkit-search-results-button{appearance:none}.v-input-control::-webkit-search-results-decoration{appearance:none}.v-input-control::-webkit-inner-spin-button{appearance:none}.v-input-control::-webkit-outer-spin-button{appearance:none}.v-input-control[type=number]{appearance:textfield}.v-input-control::-ms-reveal{display:none}.v-input-control:-webkit-autofill{border-radius:var(--vectis-radius-interactive)}.v-input[data-readonly] .v-input-field{--field-border-color:var(--vectis-color-border);background:var(--vectis-color-surface-sunken)}.v-input-field:hover:not(:has(.v-input-control:focus)):not(:has(.v-input-control:disabled,.v-input-control:user-invalid,.v-input-control[aria-invalid=true])){--field-border-color:color-mix(in oklab, var(--vectis-color-border-strong), var(--vectis-color-text) 15%)}.v-input-field:has(.v-input-control:focus){--field-border-color:var(--vectis-color-accent);box-shadow:0 0 0 1px var(--field-border-color);outline:var(--vectis-focus-ring-width) solid transparent}:is(.v-input-field:has(.v-input-control:user-invalid),.v-input-field:has(.v-input-control[aria-invalid=true])){--field-border-color:var(--vectis-color-danger)}.v-input-counter{
|
|
2
|
+
@layer vectis.components{.v-input{gap:var(--vectis-space-1);width:100%;font-family:var(--vectis-text-family);flex-direction:column;display:flex}.v-input-field{--field-border-color:var(--vectis-color-border-strong);align-items:center;gap:var(--control-gap);height:var(--control-height);padding-inline:var(--control-padding-inline-field);background:var(--vectis-color-surface);color:var(--vectis-color-text);border:1px solid var(--field-border-color);border-radius:var(--vectis-radius-interactive);font-size:var(--control-font-size);transition:border-color var(--vectis-duration-fast) var(--vectis-ease-default), background-color var(--vectis-duration-fast) var(--vectis-ease-default), box-shadow var(--vectis-duration-fast) var(--vectis-ease-default);display:flex}.v-input-control{min-width:0;height:100%;color:inherit;font:inherit;background:0 0;border:none;outline:none;flex:1;padding:0}.v-input-control::placeholder{color:var(--vectis-color-text-subtle)}.v-input-control::-webkit-search-cancel-button{appearance:none}.v-input-control::-webkit-search-decoration{appearance:none}.v-input-control::-webkit-search-results-button{appearance:none}.v-input-control::-webkit-search-results-decoration{appearance:none}.v-input-control::-webkit-inner-spin-button{appearance:none}.v-input-control::-webkit-outer-spin-button{appearance:none}.v-input-control[type=number]{appearance:textfield}.v-input-control::-ms-reveal{display:none}.v-input-control:-webkit-autofill{border-radius:var(--vectis-radius-interactive)}.v-input[data-readonly] .v-input-field{--field-border-color:var(--vectis-color-border);background:var(--vectis-color-surface-sunken)}.v-input-field:hover:not(:has(.v-input-control:focus)):not(:has(.v-input-control:disabled,.v-input-control:user-invalid,.v-input-control[aria-invalid=true])){--field-border-color:color-mix(in oklab, var(--vectis-color-border-strong), var(--vectis-color-text) 15%)}.v-input-field:has(.v-input-control:focus){--field-border-color:var(--vectis-color-accent);box-shadow:0 0 0 1px var(--field-border-color);outline:var(--vectis-focus-ring-width) solid transparent}:is(.v-input-field:has(.v-input-control:user-invalid),.v-input-field:has(.v-input-control[aria-invalid=true])){--field-border-color:var(--vectis-color-danger)}.v-input-counter{flex:none}.v-input-field>.v-icon{color:var(--vectis-color-text-muted)}.v-input-field>.v-spinner{font-size:var(--vectis-icon-size)}.v-input[data-disabled] .v-input-field{--field-border-color:var(--vectis-color-border);background:var(--vectis-color-surface-muted);color:var(--vectis-color-text-muted);cursor:not-allowed}.v-input[data-disabled] .v-input-label,.v-input[data-disabled] .v-input-hint,.v-input[data-disabled] .v-input-counter{color:var(--vectis-color-text-subtle)}.v-input[data-disabled] .v-input-action,.v-input[data-disabled] .v-input-field>.v-icon{color:inherit;cursor:not-allowed}.v-input-control:disabled{cursor:not-allowed}.v-input-end-pinned .v-input-field{padding-inline-end:calc(var(--control-padding-inline-field) + var(--vectis-icon-size) + var(--control-gap));position:relative}.v-input-end-pinned .v-input-field:has(>.v-input-clear){padding-inline-end:calc(var(--control-padding-inline-field) + 2 * var(--vectis-icon-size) + 2 * var(--control-gap))}.v-input-end-pinned :is(.v-input-clear,.v-input-icon-end){inset-inline-end:var(--control-padding-inline-field);position:absolute;top:50%;translate:0 -50%}.v-input-end-pinned .v-input-clear{inset-inline-end:calc(var(--control-padding-inline-field) + var(--vectis-icon-size) + var(--control-gap))}.v-input-chips .v-input-field{height:auto;min-height:var(--control-height);padding-block:var(--vectis-space-1);flex-wrap:wrap}.v-input-chips .v-input-control{height:var(--chip-height)}@media (prefers-reduced-motion:reduce){.v-input-field{transition:none}}}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { IconSource } from '../VIcon/types.js';
|
|
2
|
+
/** The height of the field: 32, 40 or 48 pixels. */
|
|
3
|
+
export type InputSize = 'sm' | 'md' | 'lg';
|
|
4
|
+
/** The native type of the input, which also decides the keyboard a phone offers. */
|
|
5
|
+
export type InputType = 'text' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'url';
|
|
2
6
|
interface InputProps {
|
|
3
7
|
/** The height of the field: 32, 40 or 48 pixels. */
|
|
4
|
-
size?:
|
|
8
|
+
size?: InputSize;
|
|
5
9
|
/** Takes 4px off the height, leaving the padding, the text and the icons as they are. */
|
|
6
10
|
compact?: boolean;
|
|
7
11
|
/**
|
|
8
12
|
* The native type of the input, which is also what tells a phone which keyboard to
|
|
9
13
|
* offer — a numeric pad for `number`, an @ key for `email`.
|
|
10
14
|
*/
|
|
11
|
-
type?:
|
|
15
|
+
type?: InputType;
|
|
12
16
|
/**
|
|
13
17
|
* Marks the field as invalid whatever the browser thinks. This is the route for a
|
|
14
18
|
* rule only the server can check; anything the browser can validate on its own
|
|
@@ -33,7 +37,8 @@ interface InputProps {
|
|
|
33
37
|
/**
|
|
34
38
|
* An icon inside the field, at the start. It is decorative by default and becomes
|
|
35
39
|
* a real button as soon as a `@click:icon-start` listener is attached — in which
|
|
36
|
-
* case it needs `iconStartLabel`. The `#start` slot
|
|
40
|
+
* case it needs `iconStartLabel`. The `#start` slot is rendered after it, so a
|
|
41
|
+
* field composed on top of this one can show both.
|
|
37
42
|
*/
|
|
38
43
|
iconStart?: IconSource;
|
|
39
44
|
/**
|
|
@@ -88,8 +93,19 @@ interface InputProps {
|
|
|
88
93
|
}
|
|
89
94
|
type __VLS_Props = InputProps;
|
|
90
95
|
type __VLS_Slots = {
|
|
91
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* Content at the start of the field, rendered after `iconStart` rather than in its
|
|
98
|
+
* place — which is what lets a field composed on top of this one put the chips
|
|
99
|
+
* standing for its values here beside an icon it still wants drawn.
|
|
100
|
+
*/
|
|
92
101
|
start?(): unknown;
|
|
102
|
+
/**
|
|
103
|
+
* Controls of your own inside the field, placed before the field's own — the clear
|
|
104
|
+
* cross and the end icon. It is the slot for something that acts on the VALUE, such
|
|
105
|
+
* as the AM/PM button of a 12-hour time field, which belongs beside the text rather
|
|
106
|
+
* than past the controls that clear and open.
|
|
107
|
+
*/
|
|
108
|
+
'value-end'?(): unknown;
|
|
93
109
|
/**
|
|
94
110
|
* Content at the end of the field, which replaces `iconEnd`. It is hidden while
|
|
95
111
|
* the field is loading, the spinner taking that place.
|
|
@@ -107,8 +123,11 @@ type __VLS_ModelProps = {
|
|
|
107
123
|
};
|
|
108
124
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
109
125
|
declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {
|
|
126
|
+
/** Moves the focus to the real input. */
|
|
110
127
|
focus: (options?: FocusOptions) => void | undefined;
|
|
128
|
+
/** Selects everything in the field, as VCombobox does when it reopens its panel. */
|
|
111
129
|
select: () => void | undefined;
|
|
130
|
+
/** The real `<input>`, for what neither of the two above covers. */
|
|
112
131
|
el: import('vue').Ref<HTMLInputElement | null, HTMLInputElement | null>;
|
|
113
132
|
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
114
133
|
clear: () => any;
|
|
@@ -123,15 +142,15 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {
|
|
|
123
142
|
}>, {
|
|
124
143
|
loading: boolean;
|
|
125
144
|
label: string;
|
|
126
|
-
size:
|
|
127
|
-
type:
|
|
145
|
+
size: InputSize;
|
|
146
|
+
type: InputType;
|
|
128
147
|
compact: boolean;
|
|
129
148
|
disabled: boolean;
|
|
130
149
|
iconStart: IconSource;
|
|
131
150
|
iconEnd: IconSource;
|
|
132
151
|
invalid: boolean;
|
|
133
|
-
readonly: boolean;
|
|
134
152
|
hint: string;
|
|
153
|
+
readonly: boolean;
|
|
135
154
|
iconStartLabel: string;
|
|
136
155
|
iconEndLabel: string;
|
|
137
156
|
loadingLabel: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VInput.js","names":[],"sources":["../../../src/components/VInput/VInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * A complete text field: a label above, a hint below, icons inside — clickable ones\n * included — a character counter, a clear button and a loading state, all arranged\n * around a real `<input>`.\n *\n * The component is a wrapper around that input, so the attributes it is given are\n * split: `class` and `style` stay on the outer element, where a consumer expects to\n * style the field, and everything else is forwarded to the input, where `name`,\n * `required` and the aria-* actually do something.\n *\n * Validation stays the browser's. The field turns red through `:user-invalid`, which\n * only reacts once the reader has left it, and even the soft limit is reported by\n * marking the input invalid rather than by emitting an event of our own — so a\n * consumer's `<form>` sees exactly what it would see with a bare input.\n *\n * The behavioural JavaScript is limited to the v-model and to the clear button,\n * which has to move focus back to the field: it disappears the moment it is clicked,\n * and focus would otherwise fall back to the page.\n */\nimport { computed, ref } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconName, iconProps } from '../VIcon/iconProps'\nimport { close as closeIcon } from '../VIcon/icons/close'\nimport type { IconSource } from '../VIcon/types'\nimport VSpinner from '../VSpinner/VSpinner.vue'\nimport VTypography from '../VTypography/VTypography.vue'\n\nimport { useFieldIds } from '../../composables/useFieldIds'\nimport { useIconClickHandlers } from '../../composables/useIconClickHandlers'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useTextLimit } from '../../composables/useTextLimit'\nimport { useMessages } from '../../i18n/state'\n\ninterface InputProps {\n /** The height of the field: 32, 40 or 48 pixels. */\n size?: 'sm' | 'md' | 'lg'\n /** Takes 4px off the height, leaving the padding, the text and the icons as they are. */\n compact?: boolean\n /**\n * The native type of the input, which is also what tells a phone which keyboard to\n * offer — a numeric pad for `number`, an @ key for `email`.\n */\n type?: 'text' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'url'\n /**\n * Marks the field as invalid whatever the browser thinks. This is the route for a\n * rule only the server can check; anything the browser can validate on its own\n * already colours the field without this prop.\n */\n invalid?: boolean\n /** Makes the field unusable, greyed out through the colour tokens. */\n disabled?: boolean\n /**\n * Shows the value without allowing it to be changed. The field can still be\n * focused and copied from, and it hides the clear button — unless `clearVisible`\n * answers that question explicitly.\n */\n readonly?: boolean\n /** The label above the field, tied to it so that clicking it focuses the field. */\n label?: string\n /**\n * A line of help under the field. It is tied to the input for assistive\n * technology, so it is read out along with the label.\n */\n hint?: string\n /**\n * An icon inside the field, at the start. It is decorative by default and becomes\n * a real button as soon as a `@click:icon-start` listener is attached — in which\n * case it needs `iconStartLabel`. The `#start` slot replaces it.\n */\n iconStart?: IconSource\n /**\n * The same at the end of the field. The `#end` slot replaces it, and the loading\n * spinner takes its place while it turns.\n */\n iconEnd?: IconSource\n /** What the start icon does, in words, once it is clickable. */\n iconStartLabel?: string\n /** What the end icon does, in words, once it is clickable. */\n iconEndLabel?: string\n /** Shows a spinner at the end of the field, in place of the end icon or slot. */\n loading?: boolean\n /**\n * What screen readers announce while the spinner turns. It falls back to the\n * design system dictionary.\n */\n loadingLabel?: string\n /**\n * Offers a cross that empties the field. It appears when there is something to\n * clear and the field can be edited.\n */\n clearable?: boolean\n /**\n * Decides whether the cross is shown, instead of letting the field work it out\n * from its own content — a read-only field included.\n *\n * It exists for the components built on top of this one, where what there is to\n * clear is not the text: VCombobox holds its selection as chips beside the field,\n * and a read-only date or time picker changes its value through a panel rather\n * than by typing.\n */\n clearVisible?: boolean\n /** What the clear button does, in words. It falls back to the design system dictionary. */\n clearLabel?: string\n /**\n * The maximum number of characters. By default this is the browser's own limit,\n * which simply refuses anything beyond it.\n */\n maxlength?: number\n /**\n * Turns that limit into a soft one: the reader may type past it, and the field\n * goes into error instead of silently refusing the keystrokes. It is reported\n * through the native validity, so a form cannot be submitted over the limit.\n */\n softLimit?: boolean\n /**\n * Shows how much has been typed, at the end of the field: \"12/80\" against a limit,\n * or just \"12\" without one.\n */\n counter?: boolean\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<InputProps>(), {\n size: 'md',\n compact: false,\n type: 'text',\n invalid: false,\n disabled: false,\n readonly: false,\n label: undefined,\n hint: undefined,\n iconStart: undefined,\n iconEnd: undefined,\n iconStartLabel: undefined,\n iconEndLabel: undefined,\n loading: false,\n loadingLabel: undefined,\n clearable: false,\n clearVisible: undefined,\n clearLabel: undefined,\n maxlength: undefined,\n softLimit: false,\n counter: false,\n})\n\nconst emit = defineEmits<{\n /** The start icon was clicked. Attaching this listener is what makes it a button. */\n 'click:icon-start': [event: MouseEvent]\n /** The end icon was clicked. Attaching this listener is what makes it a button. */\n 'click:icon-end': [event: MouseEvent]\n /** The clear button was pressed. The field has already been emptied. */\n clear: []\n}>()\n\ndefineSlots<{\n /** Content at the start of the field, which replaces `iconStart`. */\n start?(): unknown\n /**\n * Content at the end of the field, which replaces `iconEnd`. It is hidden while\n * the field is loading, the spinner taking that place.\n */\n end?(): unknown\n}>()\n\n/**\n * The value, typed as text OR a number rather than text alone. On an\n * `<input type=\"number\">` Vue converts the value to a number by itself, so a\n * string-only model would hand a number back to a consumer who passed a string in,\n * and Vue would report an invalid prop.\n */\nconst model = defineModel<string | number>({ default: '' })\n\n/**\n * The value seen as text. Every measurement of its length — the counter, the soft\n * limit, whether the clear cross has anything to clear — goes through this, since a\n * number has no length of its own.\n */\nconst modelText = computed(() => String(model.value ?? ''))\n\nconst { attrs, rootClass, rootStyle, forwardedAttrs: restAttrs } = useRootAttrs()\n\n// The prop keeps priority; what it falls back to is the dictionary, so the default\n// wording follows the language the design system is set to.\nconst m = useMessages()\nconst resolvedLoadingLabel = computed(() => props.loadingLabel ?? m.value.common.loading)\nconst resolvedClearLabel = computed(() => props.clearLabel ?? m.value.common.clear)\n\nconst { fieldId, hintId, describedBy } = useFieldIds(attrs, () => !!props.hint)\n\nconst { hasIconStartHandler, hasIconEndHandler } = useIconClickHandlers({\n name: 'VInput',\n iconStartLabel: props.iconStartLabel,\n iconEndLabel: props.iconEndLabel,\n})\n\nconst controlEl = ref<HTMLInputElement | null>(null)\n\nconst showClear = computed(() => {\n if (!props.clearable || props.disabled) return false\n // When `clearVisible` is supplied it is the consumer's EXPLICIT answer to \"is\n // there anything to clear?\", and it holds even on a read-only field: the value of\n // a read-only date or time picker changes through its panel rather than by typing.\n // Left out, the field answers for itself — it has text, and it can be edited.\n return props.clearVisible ?? (!props.readonly && modelText.value.length > 0)\n})\n\n// @a11y @core — moving the focus back is the accessibility half of this handler.\n// The cross vanishes the instant it empties the field, so without that call focus\n// falls back to the page body and a keyboard user loses their place in the form.\nfunction onClear() {\n model.value = ''\n emit('clear')\n controlEl.value?.focus()\n}\n\n// The counter and the soft limit both measure `modelText` rather than the model\n// itself, a number having no length.\nconst { counterText, over } = useTextLimit({\n el: controlEl,\n text: () => modelText.value,\n maxlength: () => props.maxlength,\n softLimit: () => props.softLimit,\n})\n\n// The real input is buried inside the wrapper, out of reach of whoever renders this\n// component. These three exposed members are how the components built on top of it\n// reach it — VCombobox refocuses the field and selects its text this way.\ndefineExpose({\n focus: (options?: FocusOptions) => controlEl.value?.focus(options),\n select: () => controlEl.value?.select(),\n el: controlEl,\n})\n</script>\n\n<template>\n <div\n class=\"v-input v-control\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :data-size=\"size\"\n :data-compact=\"compact ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n :data-readonly=\"readonly ? '' : undefined\"\n >\n <VTypography v-if=\"label\" as=\"label\" variant=\"label\" class=\"v-input-label\" :for=\"fieldId\">\n {{ label }}\n </VTypography>\n\n <div class=\"v-input-field\">\n <slot name=\"start\">\n <button\n v-if=\"iconStart && hasIconStartHandler\"\n type=\"button\"\n class=\"v-input-action\"\n :aria-label=\"iconStartLabel ?? iconName(iconStart)\"\n :disabled=\"disabled\"\n @click=\"emit('click:icon-start', $event)\"\n >\n <VIcon v-bind=\"iconProps(iconStart)\" />\n </button>\n <VIcon v-else-if=\"iconStart\" v-bind=\"iconProps(iconStart)\" />\n </slot>\n\n <input\n v-bind=\"restAttrs\"\n :id=\"fieldId\"\n ref=\"controlEl\"\n v-model=\"model\"\n class=\"v-input-control\"\n :type=\"type\"\n :maxlength=\"softLimit ? undefined : maxlength\"\n :disabled=\"disabled\"\n :readonly=\"readonly || undefined\"\n :aria-invalid=\"invalid || undefined\"\n :aria-describedby=\"describedBy\"\n />\n\n <span v-if=\"counter\" class=\"v-input-counter\" :data-over=\"over ? '' : undefined\">\n {{ counterText }}\n </span>\n\n <button\n v-if=\"showClear\"\n type=\"button\"\n class=\"v-input-action v-input-clear\"\n :aria-label=\"resolvedClearLabel\"\n @click=\"onClear\"\n >\n <VIcon :name=\"closeIcon\" />\n </button>\n\n <VSpinner v-if=\"loading\" :label=\"resolvedLoadingLabel\" />\n <slot v-else name=\"end\">\n <button\n v-if=\"iconEnd && hasIconEndHandler\"\n type=\"button\"\n class=\"v-input-action\"\n :aria-label=\"iconEndLabel ?? iconName(iconEnd)\"\n :disabled=\"disabled\"\n @click=\"emit('click:icon-end', $event)\"\n >\n <VIcon v-bind=\"iconProps(iconEnd)\" />\n </button>\n <VIcon v-else-if=\"iconEnd\" v-bind=\"iconProps(iconEnd)\" />\n </slot>\n </div>\n\n <VTypography v-if=\"hint\" :id=\"hintId\" variant=\"caption\" tone=\"muted\" class=\"v-input-hint\">\n {{ hint }}\n </VTypography>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-input {\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-1);\n width: 100%;\n font-family: var(--vectis-text-family);\n }\n\n /* The label and the hint are rendered by VTypography, which carries their type. The\n .v-input-label and .v-input-hint classes remain as hooks: a consumer overrides\n through them, and the disabled state below reaches them that way. */\n\n /* This is the box that carries the border, the background and the focus ring.\n `--field-border-color` is the single source of truth for its colour, and the\n hover, error and disabled states do nothing but redefine it.\n\n Nothing here restates the size scale: the `--control-*` variables are inherited\n from the v-control root (styles/control-size.css), the icon context included. */\n .v-input-field {\n --field-border-color: var(--vectis-color-border-strong);\n\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n height: var(--control-height);\n padding-inline: var(--control-padding-inline-field);\n background: var(--vectis-color-surface);\n color: var(--vectis-color-text);\n border: 1px solid var(--field-border-color);\n border-radius: var(--vectis-radius-interactive);\n font-size: var(--control-font-size);\n transition:\n border-color var(--vectis-duration-fast) var(--vectis-ease-default),\n background-color var(--vectis-duration-fast) var(--vectis-ease-default),\n box-shadow var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-input-control {\n flex: 1;\n min-width: 0;\n height: 100%;\n padding: 0;\n border: none;\n background: none;\n color: inherit;\n font: inherit;\n outline: none; /* the focus ring is drawn by the field around it, not here */\n }\n\n .v-input-control::placeholder {\n color: var(--vectis-color-text-subtle);\n }\n\n /* The browsers' own in-field controls are removed, because the design system draws\n its own: WebKit's search cross would sit beside the `clearable` one, the number\n spinners and Edge's password-reveal eye would clash with the icons. */\n .v-input-control::-webkit-search-cancel-button,\n .v-input-control::-webkit-search-decoration,\n .v-input-control::-webkit-search-results-button,\n .v-input-control::-webkit-search-results-decoration,\n .v-input-control::-webkit-inner-spin-button,\n .v-input-control::-webkit-outer-spin-button {\n -webkit-appearance: none;\n appearance: none;\n }\n\n .v-input-control[type='number'] {\n appearance: textfield;\n }\n\n .v-input-control::-ms-reveal {\n display: none;\n }\n\n /* The yellow autofill background is painted by the browser on the input itself,\n inside our field. Its colour cannot be changed, but matching the field's radius\n at least stops it from showing square corners inside a rounded box. */\n .v-input-control:-webkit-autofill {\n border-radius: var(--vectis-radius-interactive);\n }\n\n /* A read-only field sinks slightly into the page but keeps its text at full\n strength — the value is there to be read — and still shows the accent focus ring.\n The state is read from [data-readonly] and never from `:read-only`, which the\n browser also matches on a disabled field.\n\n TRAP — this block must stay FIRST in the sequence of states: read-only, then\n hover, focus, invalid and disabled. Every one of these selectors weighs (0,3,0),\n `:has()` taking the specificity of what it contains, so nothing but the source\n order arbitrates between them. Moved further down, this rule would repaint the\n error border and the accent focus ring grey, with no error anywhere. What\n belongs to a read-only field is its BASE colour alone. */\n .v-input[data-readonly] .v-input-field {\n --field-border-color: var(--vectis-color-border);\n\n background: var(--vectis-color-surface-sunken);\n }\n\n .v-input-field:hover:not(:has(.v-input-control:focus)):not(\n :has(\n .v-input-control:disabled,\n .v-input-control:user-invalid,\n .v-input-control[aria-invalid='true']\n )\n ) {\n --field-border-color: color-mix(\n in oklab,\n var(--vectis-color-border-strong),\n var(--vectis-color-text) 15%\n );\n }\n\n /* The focused field appears to have a two-pixel border: it is really its own 1px\n border plus a 1px shadow of the same colour just outside it, which costs no\n layout and therefore makes nothing jump.\n\n The selector watches the CONTROL's focus and not `:focus-within`, so that when\n one of the field's own buttons — the cross, a clickable icon — takes keyboard\n focus, only that button's outline lights up: two indicators at once would be\n unreadable. And it is `:focus` rather than `:focus-visible`, because a text field\n shows its focus even when it was reached with the mouse.\n\n The transparent outline is the safety net for Windows forced colours, which drop\n box-shadows entirely; an outline survives and keeps the field marked. */\n .v-input-field:has(.v-input-control:focus) {\n --field-border-color: var(--vectis-color-accent);\n\n box-shadow: 0 0 0 1px var(--field-border-color);\n outline: var(--vectis-focus-ring-width) solid transparent;\n }\n\n /* The invalid state, from the browser's own verdict first and from the `invalid`\n prop second. Only the colour variable is changed, which is why the border AND\n the focus ring both turn red without either being restated. */\n .v-input-field:has(.v-input-control:user-invalid),\n .v-input-field:has(.v-input-control[aria-invalid='true']) {\n --field-border-color: var(--vectis-color-danger);\n }\n\n /* The counter keeps its own local styling rather than going through VTypography:\n figures of equal width, so the number does not shift as it counts, and a colour\n that marks the overflow — neither of which is a typographic role. */\n .v-input-counter {\n flex: none;\n font-size: var(--vectis-text-caption-size);\n color: var(--vectis-color-text-muted);\n font-variant-numeric: tabular-nums;\n }\n\n .v-input-counter[data-over] {\n color: var(--vectis-color-danger-text);\n }\n\n /* A decorative icon is drawn in a muted grey, so it stays quieter than the text\n being typed beside it. */\n .v-input-field > .v-icon {\n color: var(--vectis-color-text-muted);\n }\n\n .v-input-field > .v-spinner {\n font-size: var(--vectis-icon-size);\n }\n\n /* The field's own buttons — the clear cross, a clickable icon — go from muted grey\n to full strength on hover, and take VButton's radius so their focus ring has the\n same rounded corners as everything else.\n\n The negative margin is DERIVED and never written as a number: it is exactly half\n the difference between the icon and the wider box holding it. Subtracting it\n cancels that inset, so the glyph lands precisely where a decorative icon would\n have — against the field's padding, one --control-gap from its neighbour. */\n .v-input-action {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--control-action-size);\n height: var(--control-action-size);\n margin-inline: calc((var(--vectis-icon-size) - var(--control-action-size)) / 2);\n padding: 0;\n border: none;\n background: transparent;\n color: var(--vectis-color-text-muted);\n border-radius: var(--vectis-radius-interactive);\n cursor: pointer;\n flex: none;\n transition: color var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-input-action:hover:not(:disabled) {\n color: var(--vectis-color-text);\n }\n\n .v-input-action:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: calc(var(--vectis-focus-ring-offset) * -1);\n }\n\n /* A disabled field greys out through the colour tokens, the same ones VCheckbox and\n VRadio use, and never through opacity. It comes LAST in the sequence of states,\n which at equal specificity is what makes it win over all of them, the error\n included: a disabled field is not submitted, so it has nothing to report.\n\n The text here is `text-muted` and not the `text-subtle` used by the label and the\n hint below, because those sit on the page surface where this sits on\n `surface-muted` — against which subtle falls to a 4.4:1 contrast. The control\n itself is exempt from that rule, being natively disabled, but the icons the field\n CONTAINS are not, and they inherit this colour. */\n .v-input[data-disabled] .v-input-field {\n --field-border-color: var(--vectis-color-border);\n\n background: var(--vectis-color-surface-muted);\n color: var(--vectis-color-text-muted);\n cursor: not-allowed;\n }\n\n .v-input[data-disabled] .v-input-label,\n .v-input[data-disabled] .v-input-hint,\n .v-input[data-disabled] .v-input-counter {\n color: var(--vectis-color-text-subtle);\n }\n\n .v-input[data-disabled] .v-input-action,\n .v-input[data-disabled] .v-input-field > .v-icon {\n color: inherit;\n cursor: not-allowed;\n }\n\n .v-input-control:disabled {\n cursor: not-allowed;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-input-field,\n .v-input-action {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"VInput.js","names":[],"sources":["../../../src/components/VInput/VInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * A complete text field: label above, hint below, icons inside (clickable ones included), a\n * counter, a clear cross and a loading state, all arranged around a real `<input>`.\n *\n * Wrapper-root, so the attrs split: `class`/`style` stay on the root, where a consumer\n * expects to style the field, and everything else is forwarded to the input, where `name`,\n * `required` and the `aria-*` actually do something.\n *\n * Validation stays the browser's. The field turns red through `:user-invalid`, which only\n * reacts once the reader has left it, and even the soft limit is reported by\n * `setCustomValidity` rather than an event of our own — so a consumer's `<form>` sees\n * exactly what a bare input would give it.\n *\n * The behavioural JS is the v-model and the clear cross, which has to move focus back to the\n * field: it disappears the moment it is clicked, and focus would otherwise fall to the page.\n */\nimport { computed, inject, ref } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconName, iconProps } from '../VIcon/iconProps'\nimport { close as closeIcon } from '../VIcon/icons/close'\nimport type { IconSource } from '../VIcon/types'\nimport VSpinner from '../VSpinner/VSpinner.vue'\nimport VTypography from '../VTypography/VTypography.vue'\n\nimport { useFieldIds } from '../../composables/useFieldIds'\nimport { useIconClickHandlers } from '../../composables/useIconClickHandlers'\nimport { useClearable } from '../../composables/useClearable'\nimport { useControlShape } from '../../composables/useControlShape'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useTextLimit } from '../../composables/useTextLimit'\nimport { useMessages } from '../../i18n/state'\n\nimport { inputGroupKey } from './context'\n\n/** The height of the field: 32, 40 or 48 pixels. */\nexport type InputSize = 'sm' | 'md' | 'lg'\n\n/** The native type of the input, which also decides the keyboard a phone offers. */\nexport type InputType = 'text' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'url'\n\ninterface InputProps {\n /** The height of the field: 32, 40 or 48 pixels. */\n size?: InputSize\n /** Takes 4px off the height, leaving the padding, the text and the icons as they are. */\n compact?: boolean\n /**\n * The native type of the input, which is also what tells a phone which keyboard to\n * offer — a numeric pad for `number`, an @ key for `email`.\n */\n type?: InputType\n /**\n * Marks the field as invalid whatever the browser thinks. This is the route for a\n * rule only the server can check; anything the browser can validate on its own\n * already colours the field without this prop.\n */\n invalid?: boolean\n /** Makes the field unusable, greyed out through the colour tokens. */\n disabled?: boolean\n /**\n * Shows the value without allowing it to be changed. The field can still be\n * focused and copied from, and it hides the clear button — unless `clearVisible`\n * answers that question explicitly.\n */\n readonly?: boolean\n /** The label above the field, tied to it so that clicking it focuses the field. */\n label?: string\n /**\n * A line of help under the field. It is tied to the input for assistive\n * technology, so it is read out along with the label.\n */\n hint?: string\n /**\n * An icon inside the field, at the start. It is decorative by default and becomes\n * a real button as soon as a `@click:icon-start` listener is attached — in which\n * case it needs `iconStartLabel`. The `#start` slot is rendered after it, so a\n * field composed on top of this one can show both.\n */\n iconStart?: IconSource\n /**\n * The same at the end of the field. The `#end` slot replaces it, and the loading\n * spinner takes its place while it turns.\n */\n iconEnd?: IconSource\n /** What the start icon does, in words, once it is clickable. */\n iconStartLabel?: string\n /** What the end icon does, in words, once it is clickable. */\n iconEndLabel?: string\n /** Shows a spinner at the end of the field, in place of the end icon or slot. */\n loading?: boolean\n /**\n * What screen readers announce while the spinner turns. It falls back to the\n * design system dictionary.\n */\n loadingLabel?: string\n /**\n * Offers a cross that empties the field. It appears when there is something to\n * clear and the field can be edited.\n */\n clearable?: boolean\n /**\n * Decides whether the cross is shown, instead of letting the field work it out\n * from its own content — a read-only field included.\n *\n * It exists for the components built on top of this one, where what there is to\n * clear is not the text: VCombobox holds its selection as chips beside the field,\n * and a read-only date or time picker changes its value through a panel rather\n * than by typing.\n */\n clearVisible?: boolean\n /** What the clear button does, in words. It falls back to the design system dictionary. */\n clearLabel?: string\n /**\n * The maximum number of characters. By default this is the browser's own limit,\n * which simply refuses anything beyond it.\n */\n maxlength?: number\n /**\n * Turns that limit into a soft one: the reader may type past it, and the field\n * goes into error instead of silently refusing the keystrokes. It is reported\n * through the native validity, so a form cannot be submitted over the limit.\n */\n softLimit?: boolean\n /**\n * Shows how much has been typed, at the end of the field: \"12/80\" against a limit,\n * or just \"12\" without one.\n */\n counter?: boolean\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<InputProps>(), {\n size: 'md',\n compact: false,\n type: 'text',\n invalid: false,\n disabled: false,\n readonly: false,\n label: undefined,\n hint: undefined,\n iconStart: undefined,\n iconEnd: undefined,\n iconStartLabel: undefined,\n iconEndLabel: undefined,\n loading: false,\n loadingLabel: undefined,\n clearable: false,\n clearVisible: undefined,\n clearLabel: undefined,\n maxlength: undefined,\n softLimit: false,\n counter: false,\n})\n\nconst emit = defineEmits<{\n /** The start icon was clicked. Attaching this listener is what makes it a button. */\n 'click:icon-start': [event: MouseEvent]\n /** The end icon was clicked. Attaching this listener is what makes it a button. */\n 'click:icon-end': [event: MouseEvent]\n /** The clear button was pressed. The field has already been emptied. */\n clear: []\n}>()\n\ndefineSlots<{\n /**\n * Content at the start of the field, rendered after `iconStart` rather than in its\n * place — which is what lets a field composed on top of this one put the chips\n * standing for its values here beside an icon it still wants drawn.\n */\n start?(): unknown\n /**\n * Controls of your own inside the field, placed before the field's own — the clear\n * cross and the end icon. It is the slot for something that acts on the VALUE, such\n * as the AM/PM button of a 12-hour time field, which belongs beside the text rather\n * than past the controls that clear and open.\n */\n 'value-end'?(): unknown\n /**\n * Content at the end of the field, which replaces `iconEnd`. It is hidden while\n * the field is loading, the spinner taking that place.\n */\n end?(): unknown\n}>()\n\n/**\n * The value, typed as text OR a number rather than text alone. On an\n * `<input type=\"number\">` Vue converts the value to a number by itself, so a\n * string-only model would hand a number back to a consumer who passed a string in,\n * and Vue would report an invalid prop.\n */\nconst model = defineModel<string | number>({ default: '' })\n\n/**\n * The value seen as text. Every measurement of its length — the counter, the soft\n * limit, whether the clear cross has anything to clear — goes through this, since a\n * number has no length of its own.\n */\nconst modelText = computed(() => String(model.value ?? ''))\n\nconst { attrs, rootClass, rootStyle, forwardedAttrs: restAttrs } = useRootAttrs()\n\n// A VInputGroup joins several controls into one object, so the shape of this field is the\n// row's decision rather than its own: a segment of another height stops lining up with its\n// neighbours and the merged border no longer reads as a single box. `disabled` is the one\n// read as an OR, the two answers being cumulative (VInput/context.ts).\nconst group = inject(inputGroupKey, null)\nconst {\n size: resolvedSize,\n compact: resolvedCompact,\n disabled: resolvedDisabled,\n} = useControlShape(props, group)\n\n// The prop keeps priority; what it falls back to is the dictionary, so the default\n// wording follows the language the design system is set to.\nconst m = useMessages()\nconst resolvedClearLabel = computed(() => props.clearLabel ?? m.value.common.clear)\n\nconst { fieldId, hintId, describedBy } = useFieldIds(attrs, () => !!props.hint)\n\nconst { hasIconStartHandler, hasIconEndHandler } = useIconClickHandlers({\n name: 'VInput',\n iconStartLabel: props.iconStartLabel,\n iconEndLabel: props.iconEndLabel,\n})\n\nconst controlEl = ref<HTMLInputElement | null>(null)\n\nconst { showClear, onClear } = useClearable({\n clearable: () => props.clearable,\n clearVisible: () => props.clearVisible,\n disabled: () => resolvedDisabled.value,\n readonly: () => props.readonly,\n text: () => modelText.value,\n controlEl,\n onCleared: () => {\n model.value = ''\n emit('clear')\n },\n})\n\n// The counter and the soft limit both measure `modelText` rather than the model\n// itself, a number having no length.\nconst { counterText, over } = useTextLimit({\n el: controlEl,\n text: () => modelText.value,\n maxlength: () => props.maxlength,\n softLimit: () => props.softLimit,\n})\n\n// The real input sits inside the wrapper, out of reach of whoever renders this component.\n// These three are how the components built on it get there — VCombobox refocuses the field\n// and selects its text this way.\ndefineExpose({\n /** Moves the focus to the real input. */\n focus: (options?: FocusOptions) => controlEl.value?.focus(options),\n /** Selects everything in the field, as VCombobox does when it reopens its panel. */\n select: () => controlEl.value?.select(),\n /** The real `<input>`, for what neither of the two above covers. */\n el: controlEl,\n})\n</script>\n\n<template>\n <div\n class=\"v-input v-control\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :data-size=\"resolvedSize\"\n :data-compact=\"resolvedCompact ? '' : undefined\"\n :data-disabled=\"resolvedDisabled ? '' : undefined\"\n :data-readonly=\"readonly ? '' : undefined\"\n >\n <VTypography v-if=\"label\" as=\"label\" variant=\"label\" class=\"v-input-label\" :for=\"fieldId\">\n {{ label }}\n </VTypography>\n\n <div class=\"v-input-field\">\n <!-- TRAP — the start icon is rendered BEFORE the slot, where the end icon is the\n slot's own fallback. That asymmetry is what the composed fields need: VCombobox\n and VFileInput fill `#start` with the chips standing for their values, which is\n OTHER content in the same zone rather than another way of drawing the icon. As a\n fallback the icon would vanish the moment a value was chosen — silently, and the\n clickable variant with it. The end zone has no such consumer: what is put there\n really does replace the icon. -->\n <button\n v-if=\"iconStart && hasIconStartHandler\"\n type=\"button\"\n class=\"v-input-action v-field-action v-input-icon-start\"\n :aria-label=\"iconStartLabel ?? iconName(iconStart)\"\n :disabled=\"resolvedDisabled\"\n @click=\"emit('click:icon-start', $event)\"\n >\n <VIcon v-bind=\"iconProps(iconStart)\" />\n </button>\n <VIcon v-else-if=\"iconStart\" v-bind=\"iconProps(iconStart)\" class=\"v-input-icon-start\" />\n <slot name=\"start\" />\n\n <input\n v-bind=\"restAttrs\"\n :id=\"fieldId\"\n ref=\"controlEl\"\n v-model=\"model\"\n class=\"v-input-control\"\n :type=\"type\"\n :maxlength=\"softLimit ? undefined : maxlength\"\n :disabled=\"resolvedDisabled\"\n :readonly=\"readonly || undefined\"\n :aria-invalid=\"invalid || undefined\"\n :aria-describedby=\"describedBy\"\n />\n\n <span\n v-if=\"counter\"\n class=\"v-input-counter v-field-counter\"\n :data-over=\"over ? '' : undefined\"\n >\n {{ counterText }}\n </span>\n\n <!-- Before the clear cross rather than after it, so that a consumer's control reads\n and tabs in the same order: what acts on the value sits next to the value, and\n the field's own controls stay together at the end. -->\n <slot name=\"value-end\" />\n\n <button\n v-if=\"showClear\"\n type=\"button\"\n class=\"v-input-action v-field-action v-input-clear\"\n :aria-label=\"resolvedClearLabel\"\n @click=\"onClear\"\n >\n <VIcon :name=\"closeIcon\" />\n </button>\n\n <VSpinner v-if=\"loading\" :label=\"loadingLabel\" />\n <slot v-else name=\"end\">\n <button\n v-if=\"iconEnd && hasIconEndHandler\"\n type=\"button\"\n class=\"v-input-action v-field-action v-input-icon-end\"\n :aria-label=\"iconEndLabel ?? iconName(iconEnd)\"\n :disabled=\"resolvedDisabled\"\n @click=\"emit('click:icon-end', $event)\"\n >\n <VIcon v-bind=\"iconProps(iconEnd)\" />\n </button>\n <VIcon v-else-if=\"iconEnd\" v-bind=\"iconProps(iconEnd)\" class=\"v-input-icon-end\" />\n </slot>\n </div>\n\n <VTypography v-if=\"hint\" :id=\"hintId\" variant=\"caption\" tone=\"muted\" class=\"v-input-hint\">\n {{ hint }}\n </VTypography>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-input {\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-1);\n width: 100%;\n font-family: var(--vectis-text-family);\n }\n\n /* The label and the hint are rendered by VTypography, which carries their type. The\n .v-input-label and .v-input-hint classes remain as hooks: a consumer overrides\n through them, and the disabled state below reaches them that way. */\n\n /* This is the box that carries the border, the background and the focus ring.\n `--field-border-color` is the single source of truth for its colour, and the\n hover, error and disabled states do nothing but redefine it.\n\n Nothing here restates the size scale: the `--control-*` variables are inherited\n from the v-control root (styles/control-size.css), the icon context included. */\n .v-input-field {\n --field-border-color: var(--vectis-color-border-strong);\n\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n height: var(--control-height);\n padding-inline: var(--control-padding-inline-field);\n background: var(--vectis-color-surface);\n color: var(--vectis-color-text);\n border: 1px solid var(--field-border-color);\n border-radius: var(--vectis-radius-interactive);\n font-size: var(--control-font-size);\n transition:\n border-color var(--vectis-duration-fast) var(--vectis-ease-default),\n background-color var(--vectis-duration-fast) var(--vectis-ease-default),\n box-shadow var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-input-control {\n flex: 1;\n min-width: 0;\n height: 100%;\n padding: 0;\n border: none;\n background: none;\n color: inherit;\n font: inherit;\n outline: none; /* the focus ring is drawn by the field around it, not here */\n }\n\n .v-input-control::placeholder {\n color: var(--vectis-color-text-subtle);\n }\n\n /* The browsers' own in-field controls are removed, because the design system draws\n its own: WebKit's search cross would sit beside the `clearable` one, the number\n spinners and Edge's password-reveal eye would clash with the icons. */\n .v-input-control::-webkit-search-cancel-button,\n .v-input-control::-webkit-search-decoration,\n .v-input-control::-webkit-search-results-button,\n .v-input-control::-webkit-search-results-decoration,\n .v-input-control::-webkit-inner-spin-button,\n .v-input-control::-webkit-outer-spin-button {\n -webkit-appearance: none;\n appearance: none;\n }\n\n .v-input-control[type='number'] {\n appearance: textfield;\n }\n\n .v-input-control::-ms-reveal {\n display: none;\n }\n\n /* The yellow autofill background is painted by the browser on the input itself,\n inside our field. Its colour cannot be changed, but matching the field's radius\n at least stops it from showing square corners inside a rounded box. */\n .v-input-control:-webkit-autofill {\n border-radius: var(--vectis-radius-interactive);\n }\n\n /* A read-only field sinks slightly into the page but keeps its text at full\n strength — the value is there to be read — and still shows the accent focus ring.\n The state is read from [data-readonly] and never from `:read-only`, which the\n browser also matches on a disabled field.\n\n TRAP — this block must stay FIRST in the sequence of states: read-only, then\n hover, focus, invalid and disabled. Every one of these selectors weighs (0,3,0),\n `:has()` taking the specificity of what it contains, so nothing but the source\n order arbitrates between them. Moved further down, this rule would repaint the\n error border and the accent focus ring grey, with no error anywhere. What\n belongs to a read-only field is its BASE colour alone. */\n .v-input[data-readonly] .v-input-field {\n --field-border-color: var(--vectis-color-border);\n\n background: var(--vectis-color-surface-sunken);\n }\n\n .v-input-field:hover:not(:has(.v-input-control:focus)):not(\n :has(\n .v-input-control:disabled,\n .v-input-control:user-invalid,\n .v-input-control[aria-invalid='true']\n )\n ) {\n --field-border-color: color-mix(\n in oklab,\n var(--vectis-color-border-strong),\n var(--vectis-color-text) 15%\n );\n }\n\n /* The focused field appears to have a two-pixel border: it is really its own 1px\n border plus a 1px shadow of the same colour just outside it, which costs no\n layout and therefore makes nothing jump.\n\n The selector watches the CONTROL's focus and not `:focus-within`, so that when\n one of the field's own buttons — the cross, a clickable icon — takes keyboard\n focus, only that button's outline lights up: two indicators at once would be\n unreadable. And it is `:focus` rather than `:focus-visible`, because a text field\n shows its focus even when it was reached with the mouse.\n\n The transparent outline is the safety net for Windows forced colours, which drop\n box-shadows entirely; an outline survives and keeps the field marked. */\n .v-input-field:has(.v-input-control:focus) {\n --field-border-color: var(--vectis-color-accent);\n\n box-shadow: 0 0 0 1px var(--field-border-color);\n outline: var(--vectis-focus-ring-width) solid transparent;\n }\n\n /* The invalid state, from the browser's own verdict first and from the `invalid`\n prop second. Only the colour variable is changed, which is why the border AND\n the focus ring both turn red without either being restated. */\n .v-input-field:has(.v-input-control:user-invalid),\n .v-input-field:has(.v-input-control[aria-invalid='true']) {\n --field-border-color: var(--vectis-color-danger);\n }\n\n /* The counter's type and its overflow colour are `.v-field-counter`'s (styles/field.css),\n shared with the counters VTextarea and VFileInput draw under their field. Inside the\n box it must not shrink, or a long value would squeeze its figures. */\n .v-input-counter {\n flex: none;\n }\n\n /* A decorative icon is drawn in a muted grey, so it stays quieter than the text\n being typed beside it. */\n .v-input-field > .v-icon {\n color: var(--vectis-color-text-muted);\n }\n\n .v-input-field > .v-spinner {\n font-size: var(--vectis-icon-size);\n }\n\n /* A disabled field greys out through the colour tokens, the same ones VCheckbox and\n VRadio use, and never through opacity. It comes LAST in the sequence of states,\n which at equal specificity is what makes it win over all of them, the error\n included: a disabled field is not submitted, so it has nothing to report.\n\n The text here is `text-muted` and not the `text-subtle` used by the label and the\n hint below, because those sit on the page surface where this sits on\n `surface-muted` — against which subtle falls to a 4.4:1 contrast. The control\n itself is exempt from that rule, being natively disabled, but the icons the field\n CONTAINS are not, and they inherit this colour. */\n .v-input[data-disabled] .v-input-field {\n --field-border-color: var(--vectis-color-border);\n\n background: var(--vectis-color-surface-muted);\n color: var(--vectis-color-text-muted);\n cursor: not-allowed;\n }\n\n .v-input[data-disabled] .v-input-label,\n .v-input[data-disabled] .v-input-hint,\n .v-input[data-disabled] .v-input-counter {\n color: var(--vectis-color-text-subtle);\n }\n\n .v-input[data-disabled] .v-input-action,\n .v-input[data-disabled] .v-input-field > .v-icon {\n color: inherit;\n cursor: not-allowed;\n }\n\n .v-input-control:disabled {\n cursor: not-allowed;\n }\n\n /* Two arrangements a field composed on top of this one opts into with a class on this\n root: VCombobox and VFileInput, the two that put chips inside the field. They live in\n THIS sheet because it is the one both are guaranteed to load, being built on VInput —\n the core sheet would charge every consumer for them.\n\n `.v-input-end-pinned` lifts the clear cross and whatever carries `.v-input-icon-end` —\n the end icon, or a composed field's own chevron and spinner — out of the flow, so they\n stay pinned to the end of the field and vertically centred whatever the chips do. The\n room they occupy is then reserved with padding, or the text and the chips would run\n underneath. That reservation is written as exactly what the flow would have produced\n with them left in place — one glyph's width each from the field's padding, one gap\n between two of them — and reads the same two variables as the insets below, so the room\n reserved and the glyphs it protects cannot drift apart.\n\n Whether the cross takes its room is read off the markup (`:has`): the cross is rendered\n exactly when there is something to clear, so the padding cannot disagree with it.\n\n The centring is a translation kept SEPARATE from `rotate`, which VCombobox's chevron\n turns when its panel opens. */\n .v-input-end-pinned .v-input-field {\n position: relative;\n padding-inline-end: calc(\n var(--control-padding-inline-field) + var(--vectis-icon-size) + var(--control-gap)\n );\n }\n\n .v-input-end-pinned .v-input-field:has(> .v-input-clear) {\n padding-inline-end: calc(\n var(--control-padding-inline-field) + 2 * var(--vectis-icon-size) + 2 * var(--control-gap)\n );\n }\n\n .v-input-end-pinned :is(.v-input-clear, .v-input-icon-end) {\n position: absolute;\n inset-inline-end: var(--control-padding-inline-field);\n top: 50%;\n translate: 0 -50%;\n }\n\n /* TRAP — this inset reads in GLYPHS and not in buttons. The cross is one of the field's\n buttons, whose negative margin — half the difference between icon and button — already\n cancels its own overhang, so an inset lands on the glyph's edge. Measured in button\n widths instead, it pushes the cross a whole gap too far, with nothing to signal it.\n It overrides the rule above at the same weight, so it has to stay after it. */\n .v-input-end-pinned .v-input-clear {\n inset-inline-end: calc(\n var(--control-padding-inline-field) + var(--vectis-icon-size) + var(--control-gap)\n );\n }\n\n /* `.v-input-chips` lets the chips WRAP onto several rows, the field growing instead of\n scrolling but never shrinking below an ordinary control.\n\n The input is forced to the chips' height rather than the full height it inherits: its\n natural height is greater than a chip's, and the field would grow the moment it was\n focused. That height is `--chip-height`, written inline on the composed field's root\n by the helper that also picks the chips' size (utils/chip.ts), so the two cannot drift.\n\n TRAP — the control rule must stay at (0,2,0). VCombobox folds its search input away\n with a (0,3,0) rule that zeroes this height, and at equal weight the winner would be\n whichever of the two sheets a bundler put last. */\n .v-input-chips .v-input-field {\n flex-wrap: wrap;\n height: auto;\n min-height: var(--control-height);\n padding-block: var(--vectis-space-1);\n }\n\n .v-input-chips .v-input-control {\n height: var(--chip-height);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-input-field {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":""}
|