vectis-ui 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/VAccordion/VAccordion.css +1 -1
- package/dist/components/VAccordion/VAccordion.d.ts +6 -5
- package/dist/components/VAccordion/VAccordion.js.map +1 -1
- 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 +1 -1
- package/dist/components/VAccordion/VAccordionItem.js.map +1 -1
- package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VAlert/VAlert.css +2 -0
- package/dist/components/VAlert/VAlert.d.ts +73 -0
- package/dist/components/VAlert/VAlert.js +9 -0
- package/dist/components/VAlert/VAlert.js.map +1 -0
- package/dist/components/VAlert/VAlert.vue_vue_type_script_setup_true_lang.js +96 -0
- package/dist/components/VAlert/VAlert.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VAvatar/VAvatar.d.ts +2 -2
- package/dist/components/VAvatar/VAvatarGroup.d.ts +1 -1
- package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js +8 -8
- package/dist/components/VBadge/VBadge.d.ts +3 -3
- package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js +9 -9
- package/dist/components/VButton/VButton.d.ts +4 -4
- package/dist/components/VButton/VButtonGroup.css +1 -1
- package/dist/components/VButton/VButtonGroup.d.ts +2 -2
- package/dist/components/VButton/VButtonGroup.js.map +1 -1
- package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendar.css +1 -1
- package/dist/components/VCalendar/VCalendar.d.ts +7 -1
- package/dist/components/VCalendar/VCalendar.js.map +1 -1
- package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js +20 -18
- package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendarEvent.js.map +1 -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 +2 -2
- package/dist/components/VCalendar/VCalendarMonth.js.map +1 -1
- 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 +3 -3
- package/dist/components/VCalendar/VCalendarTimeGrid.js.map +1 -1
- 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.map +1 -1
- package/dist/components/VCalendar/gesture.d.ts +1 -16
- package/dist/components/VCalendar/gesture.js +1 -1
- package/dist/components/VCalendar/gesture.js.map +1 -1
- package/dist/components/VCalendar/types.d.ts +2 -0
- package/dist/components/VCard/VCard.css +2 -0
- package/dist/components/VCard/VCard.d.ts +87 -0
- package/dist/components/VCard/VCard.js +9 -0
- package/dist/components/VCard/VCard.js.map +1 -0
- package/dist/components/VCard/VCard.vue_vue_type_script_setup_true_lang.js +103 -0
- package/dist/components/VCard/VCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCarousel/VCarousel.d.ts +1 -1
- package/dist/components/VCarousel/VCarousel.js.map +1 -1
- package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js +18 -18
- package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCheckbox/VCheckMark.css +2 -0
- package/dist/components/VCheckbox/VCheckMark.js +9 -0
- package/dist/components/VCheckbox/VCheckMark.js.map +1 -0
- package/dist/components/VCheckbox/VCheckMark.vue_vue_type_script_setup_true_lang.js +33 -0
- package/dist/components/VCheckbox/VCheckMark.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCheckbox/VCheckbox.css +1 -1
- package/dist/components/VCheckbox/VCheckbox.d.ts +8 -3
- package/dist/components/VCheckbox/VCheckbox.js.map +1 -1
- package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js +54 -69
- package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VChip/VChip.d.ts +6 -6
- package/dist/components/VChip/VChip.js.map +1 -1
- package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js +26 -26
- package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VColorInput/VColorInput.css +2 -0
- package/dist/components/VColorInput/VColorInput.d.ts +113 -0
- package/dist/components/VColorInput/VColorInput.js +9 -0
- package/dist/components/VColorInput/VColorInput.js.map +1 -0
- package/dist/components/VColorInput/VColorInput.vue_vue_type_script_setup_true_lang.js +230 -0
- package/dist/components/VColorInput/VColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VColorPicker/VColorPicker.css +2 -0
- package/dist/components/VColorPicker/VColorPicker.d.ts +67 -0
- package/dist/components/VColorPicker/VColorPicker.js +9 -0
- package/dist/components/VColorPicker/VColorPicker.js.map +1 -0
- package/dist/components/VColorPicker/VColorPicker.vue_vue_type_script_setup_true_lang.js +390 -0
- package/dist/components/VColorPicker/VColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VColorPicker/color.d.ts +42 -0
- package/dist/components/VColorPicker/color.js +158 -0
- package/dist/components/VColorPicker/color.js.map +1 -0
- package/dist/components/VCombobox/VCombobox.css +1 -1
- package/dist/components/VCombobox/VCombobox.d.ts +46 -60
- package/dist/components/VCombobox/VCombobox.js.map +1 -1
- package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +271 -372
- package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCommandPalette/VCommandPalette.css +2 -0
- package/dist/components/VCommandPalette/VCommandPalette.d.ts +163 -0
- package/dist/components/VCommandPalette/VCommandPalette.js +9 -0
- package/dist/components/VCommandPalette/VCommandPalette.js.map +1 -0
- package/dist/components/VCommandPalette/VCommandPalette.vue_vue_type_script_setup_true_lang.js +321 -0
- package/dist/components/VCommandPalette/VCommandPalette.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCommandPalette/VCommandPaletteItem.css +2 -0
- package/dist/components/VCommandPalette/VCommandPaletteItem.d.ts +38 -0
- package/dist/components/VCommandPalette/VCommandPaletteItem.js +9 -0
- package/dist/components/VCommandPalette/VCommandPaletteItem.js.map +1 -0
- package/dist/components/VCommandPalette/VCommandPaletteItem.vue_vue_type_script_setup_true_lang.js +69 -0
- package/dist/components/VCommandPalette/VCommandPaletteItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VContextMenu/VContextMenu.css +2 -0
- package/dist/components/VContextMenu/VContextMenu.d.ts +66 -0
- package/dist/components/VContextMenu/VContextMenu.js +9 -0
- package/dist/components/VContextMenu/VContextMenu.js.map +1 -0
- package/dist/components/VContextMenu/VContextMenu.vue_vue_type_script_setup_true_lang.js +148 -0
- package/dist/components/VContextMenu/VContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VDataTable/VDataTable.css +1 -1
- package/dist/components/VDataTable/VDataTable.d.ts +41 -16
- package/dist/components/VDataTable/VDataTable.js.map +1 -1
- package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +307 -194
- package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDateInput/VDateInput.d.ts +27 -7
- package/dist/components/VDateInput/VDateInput.js.map +1 -1
- package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js +170 -162
- package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDatePicker/VDatePicker.d.ts +3 -3
- package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
- package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +228 -227
- package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDatePicker/keyboard.d.ts +7 -7
- package/dist/components/VDatePicker/keyboard.js +8 -6
- package/dist/components/VDatePicker/keyboard.js.map +1 -1
- package/dist/components/VDatePicker/names.js +16 -20
- package/dist/components/VDatePicker/names.js.map +1 -1
- package/dist/components/VDialog/VDialog.d.ts +2 -4
- package/dist/components/VDialog/VDialog.js.map +1 -1
- package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js +46 -77
- package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDrawer/VDrawer.css +2 -0
- package/dist/components/VDrawer/VDrawer.d.ts +102 -0
- package/dist/components/VDrawer/VDrawer.js +9 -0
- package/dist/components/VDrawer/VDrawer.js.map +1 -0
- package/dist/components/VDrawer/VDrawer.vue_vue_type_script_setup_true_lang.js +128 -0
- package/dist/components/VDrawer/VDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VEmptyState/VEmptyState.css +2 -0
- package/dist/components/VEmptyState/VEmptyState.d.ts +43 -0
- package/dist/components/VEmptyState/VEmptyState.js +9 -0
- package/dist/components/VEmptyState/VEmptyState.js.map +1 -0
- package/dist/components/VEmptyState/VEmptyState.vue_vue_type_script_setup_true_lang.js +48 -0
- package/dist/components/VEmptyState/VEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VField/VField.css +2 -0
- package/dist/components/VField/VField.d.ts +84 -0
- package/dist/components/VField/VField.js +9 -0
- package/dist/components/VField/VField.js.map +1 -0
- package/dist/components/VField/VField.vue_vue_type_script_setup_true_lang.js +99 -0
- package/dist/components/VField/VField.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VField/VFieldAnnouncer.d.ts +7 -0
- package/dist/components/VField/VFieldAnnouncer.js +7 -0
- package/dist/components/VField/VFieldAnnouncer.js.map +1 -0
- package/dist/components/VField/VFieldAnnouncer.vue_vue_type_script_setup_true_lang.js +19 -0
- package/dist/components/VField/VFieldAnnouncer.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VField/VFieldMessage.d.ts +11 -0
- package/dist/components/VField/VFieldMessage.js +7 -0
- package/dist/components/VField/VFieldMessage.js.map +1 -0
- package/dist/components/VField/VFieldMessage.vue_vue_type_script_setup_true_lang.js +32 -0
- package/dist/components/VField/VFieldMessage.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VFieldset/VFieldset.css +2 -0
- package/dist/components/VFieldset/VFieldset.d.ts +52 -0
- package/dist/components/VFieldset/VFieldset.js +9 -0
- package/dist/components/VFieldset/VFieldset.js.map +1 -0
- package/dist/components/VFieldset/VFieldset.vue_vue_type_script_setup_true_lang.js +63 -0
- package/dist/components/VFieldset/VFieldset.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VFileInput/VFileInput.css +1 -1
- package/dist/components/VFileInput/VFileInput.d.ts +31 -7
- package/dist/components/VFileInput/VFileInput.js.map +1 -1
- package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js +168 -161
- package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VFilePicker/VFilePicker.d.ts +4 -4
- package/dist/components/VHotkeys/VHotkeys.css +1 -1
- package/dist/components/VHotkeys/VHotkeys.js.map +1 -1
- package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js +27 -30
- package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VHotkeys/platform.d.ts +2 -0
- package/dist/components/VHotkeys/platform.js +24 -5
- package/dist/components/VHotkeys/platform.js.map +1 -1
- package/dist/components/VHoverCard/VHoverCard.css +2 -0
- package/dist/components/VHoverCard/VHoverCard.d.ts +62 -0
- package/dist/components/VHoverCard/VHoverCard.js +9 -0
- package/dist/components/VHoverCard/VHoverCard.js.map +1 -0
- package/dist/components/VHoverCard/VHoverCard.vue_vue_type_script_setup_true_lang.js +97 -0
- package/dist/components/VHoverCard/VHoverCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VIcon/icons/add.d.ts +5 -0
- package/dist/components/VIcon/icons/add.js +9 -0
- package/dist/components/VIcon/icons/add.js.map +1 -0
- package/dist/components/VIcon/icons/colorize.d.ts +5 -0
- package/dist/components/VIcon/icons/colorize.js +9 -0
- package/dist/components/VIcon/icons/colorize.js.map +1 -0
- package/dist/components/VIcon/icons/inbox.d.ts +5 -0
- package/dist/components/VIcon/icons/inbox.js +9 -0
- package/dist/components/VIcon/icons/inbox.js.map +1 -0
- package/dist/components/VIcon/icons/index.d.ts +42 -2
- package/dist/components/VIcon/icons/index.js +88 -72
- package/dist/components/VIcon/icons/index.js.map +1 -1
- package/dist/components/VIcon/icons/names.d.ts +2 -2
- package/dist/components/VIcon/icons/names.js +1 -1
- package/dist/components/VIcon/icons/names.js.map +1 -1
- package/dist/components/VIcon/icons/open_in_new.d.ts +5 -0
- package/dist/components/VIcon/icons/open_in_new.js +9 -0
- package/dist/components/VIcon/icons/open_in_new.js.map +1 -0
- package/dist/components/VIcon/icons/priority_high.d.ts +5 -0
- package/dist/components/VIcon/icons/priority_high.js +9 -0
- package/dist/components/VIcon/icons/priority_high.js.map +1 -0
- package/dist/components/VIcon/icons/remove.d.ts +5 -0
- package/dist/components/VIcon/icons/remove.js +9 -0
- package/dist/components/VIcon/icons/remove.js.map +1 -0
- package/dist/components/VIcon/icons/search_off.d.ts +5 -0
- package/dist/components/VIcon/icons/search_off.js +9 -0
- package/dist/components/VIcon/icons/search_off.js.map +1 -0
- package/dist/components/VIcon/icons/star.d.ts +5 -0
- package/dist/components/VIcon/icons/star.js +9 -0
- package/dist/components/VIcon/icons/star.js.map +1 -0
- package/dist/components/VIconButton/VIconButton.d.ts +4 -4
- package/dist/components/VInput/VInput.css +1 -1
- package/dist/components/VInput/VInput.d.ts +51 -2
- package/dist/components/VInput/VInput.js.map +1 -1
- package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js +129 -106
- package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VInput/VInputGroup.css +1 -1
- package/dist/components/VInput/VInputGroup.d.ts +20 -0
- package/dist/components/VInput/VInputGroup.js.map +1 -1
- package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js +50 -51
- package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VInputOTP/VInputOTP.css +1 -1
- package/dist/components/VInputOTP/VInputOTP.d.ts +27 -4
- package/dist/components/VInputOTP/VInputOTP.js.map +1 -1
- package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +131 -113
- package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VLink/VLink.css +2 -0
- package/dist/components/VLink/VLink.d.ts +53 -0
- package/dist/components/VLink/VLink.js +9 -0
- package/dist/components/VLink/VLink.js.map +1 -0
- package/dist/components/VLink/VLink.vue_vue_type_script_setup_true_lang.js +58 -0
- package/dist/components/VLink/VLink.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VListbox/VListboxChevron.css +2 -0
- package/dist/components/VListbox/VListboxChevron.d.ts +12 -0
- package/dist/components/VListbox/VListboxChevron.js +9 -0
- package/dist/components/VListbox/VListboxChevron.js.map +1 -0
- package/dist/components/VListbox/VListboxChevron.vue_vue_type_script_setup_true_lang.js +25 -0
- package/dist/components/VListbox/VListboxChevron.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VListbox/VListboxGroup.css +2 -0
- package/dist/components/VListbox/VListboxGroup.d.ts +27 -0
- package/dist/components/VListbox/VListboxGroup.js +9 -0
- package/dist/components/VListbox/VListboxGroup.js.map +1 -0
- package/dist/components/VListbox/VListboxGroup.vue_vue_type_script_setup_true_lang.js +21 -0
- package/dist/components/VListbox/VListboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VListbox/VListboxOption.css +2 -0
- package/dist/components/{VCombobox/VComboboxOption.d.ts → VListbox/VListboxOption.d.ts} +4 -4
- package/dist/components/VListbox/VListboxOption.js +9 -0
- package/dist/components/VListbox/VListboxOption.js.map +1 -0
- package/dist/components/{VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js → VListbox/VListboxOption.vue_vue_type_script_setup_true_lang.js} +6 -6
- package/dist/components/VListbox/VListboxOption.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VListbox/VListboxPanel.css +2 -0
- package/dist/components/VListbox/VListboxPanel.d.ts +59 -0
- package/dist/components/VListbox/VListboxPanel.js +9 -0
- package/dist/components/VListbox/VListboxPanel.js.map +1 -0
- package/dist/components/VListbox/VListboxPanel.vue_vue_type_script_setup_true_lang.js +123 -0
- package/dist/components/VListbox/VListboxPanel.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VListbox/VListboxSeparator.css +2 -0
- package/dist/components/VListbox/VListboxSeparator.d.ts +3 -0
- package/dist/components/VListbox/VListboxSeparator.js +9 -0
- package/dist/components/VListbox/VListboxSeparator.js.map +1 -0
- package/dist/components/{VCombobox/VComboboxSeparator.vue_vue_type_script_setup_true_lang.js → VListbox/VListboxSeparator.vue_vue_type_script_setup_true_lang.js} +4 -4
- package/dist/components/VListbox/VListboxSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VListbox/VListboxValues.css +2 -0
- package/dist/components/VListbox/VListboxValues.d.ts +52 -0
- package/dist/components/VListbox/VListboxValues.js +9 -0
- package/dist/components/VListbox/VListboxValues.js.map +1 -0
- package/dist/components/VListbox/VListboxValues.vue_vue_type_script_setup_true_lang.js +103 -0
- package/dist/components/VListbox/VListboxValues.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VMenu/VMenu.d.ts +1 -1
- package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js +9 -9
- package/dist/components/VMenu/VMenuItem.d.ts +1 -1
- package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js +16 -16
- package/dist/components/VMenu/VMenuPanel.d.ts +2 -2
- package/dist/components/VMenu/VMenuPanel.js.map +1 -1
- package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMeter/VMeter.css +2 -0
- package/dist/components/VMeter/VMeter.d.ts +77 -0
- package/dist/components/VMeter/VMeter.js +9 -0
- package/dist/components/VMeter/VMeter.js.map +1 -0
- package/dist/components/VMeter/VMeter.vue_vue_type_script_setup_true_lang.js +113 -0
- package/dist/components/VMeter/VMeter.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VNumberInput/VNumberInput.css +2 -0
- package/dist/components/VNumberInput/VNumberInput.d.ts +114 -0
- package/dist/components/VNumberInput/VNumberInput.js +9 -0
- package/dist/components/VNumberInput/VNumberInput.js.map +1 -0
- package/dist/components/VNumberInput/VNumberInput.vue_vue_type_script_setup_true_lang.js +251 -0
- package/dist/components/VNumberInput/VNumberInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VNumberInput/number.d.ts +30 -0
- package/dist/components/VNumberInput/number.js +38 -0
- package/dist/components/VNumberInput/number.js.map +1 -0
- package/dist/components/VPagination/VPagination.d.ts +1 -1
- package/dist/components/VPagination/VPagination.js.map +1 -1
- package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js +77 -77
- package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VProgressCircular/VProgressCircular.d.ts +2 -2
- package/dist/components/VProgressLinear/VProgressLinear.css +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.d.ts +10 -7
- package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js +52 -34
- package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VRadio/VRadio.d.ts +8 -3
- package/dist/components/VRadio/VRadio.js.map +1 -1
- package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js +52 -46
- package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VRating/VRating.css +2 -0
- package/dist/components/VRating/VRating.d.ts +92 -0
- package/dist/components/VRating/VRating.js +9 -0
- package/dist/components/VRating/VRating.js.map +1 -0
- package/dist/components/VRating/VRating.vue_vue_type_script_setup_true_lang.js +158 -0
- package/dist/components/VRating/VRating.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VResizable/VResizable.css +2 -0
- package/dist/components/VResizable/VResizable.d.ts +50 -0
- package/dist/components/VResizable/VResizable.js +9 -0
- package/dist/components/VResizable/VResizable.js.map +1 -0
- package/dist/components/VResizable/VResizable.vue_vue_type_script_setup_true_lang.js +225 -0
- package/dist/components/VResizable/VResizable.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VResizable/VResizablePanel.css +2 -0
- package/dist/components/VResizable/VResizablePanel.d.ts +60 -0
- package/dist/components/VResizable/VResizablePanel.js +9 -0
- package/dist/components/VResizable/VResizablePanel.js.map +1 -0
- package/dist/components/VResizable/VResizablePanel.vue_vue_type_script_setup_true_lang.js +83 -0
- package/dist/components/VResizable/VResizablePanel.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VResizable/context.d.ts +24 -0
- package/dist/components/VResizable/context.js +6 -0
- package/dist/components/VResizable/context.js.map +1 -0
- package/dist/components/VResizable/layout.d.ts +28 -0
- package/dist/components/VResizable/layout.js +41 -0
- package/dist/components/VResizable/layout.js.map +1 -0
- package/dist/components/VSelect/VSelect.css +2 -0
- package/dist/components/VSelect/VSelect.d.ts +193 -0
- package/dist/components/VSelect/VSelect.js +9 -0
- package/dist/components/VSelect/VSelect.js.map +1 -0
- package/dist/components/VSelect/VSelect.vue_vue_type_script_setup_true_lang.js +418 -0
- package/dist/components/VSelect/VSelect.vue_vue_type_script_setup_true_lang.js.map +1 -0
- 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.vue_vue_type_script_setup_true_lang.js +8 -8
- package/dist/components/VSideNavigation/VSideNavigationItem.d.ts +2 -2
- package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSkeletonLoader/VSkeletonLoader.d.ts +3 -3
- package/dist/components/VSlider/VSlider.css +1 -1
- package/dist/components/VSlider/VSlider.d.ts +34 -8
- package/dist/components/VSlider/VSlider.js.map +1 -1
- package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js +236 -215
- package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/VSnackbar/state.js.map +1 -1
- package/dist/components/VSplitButton/VSplitButton.css +2 -0
- package/dist/components/VSplitButton/VSplitButton.d.ts +114 -0
- package/dist/components/VSplitButton/VSplitButton.js +9 -0
- package/dist/components/VSplitButton/VSplitButton.js.map +1 -0
- package/dist/components/VSplitButton/VSplitButton.vue_vue_type_script_setup_true_lang.js +148 -0
- package/dist/components/VSplitButton/VSplitButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VStepper/VStepper.css +2 -0
- package/dist/components/VStepper/VStepper.d.ts +73 -0
- package/dist/components/VStepper/VStepper.js +9 -0
- package/dist/components/VStepper/VStepper.js.map +1 -0
- package/dist/components/VStepper/VStepper.vue_vue_type_script_setup_true_lang.js +96 -0
- package/dist/components/VStepper/VStepper.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VSwitch/VSwitch.d.ts +8 -3
- package/dist/components/VSwitch/VSwitch.js.map +1 -1
- package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js +53 -47
- 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 +1 -1
- package/dist/components/VTabs/VTab.js.map +1 -1
- package/dist/components/VTabs/VTab.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 +13 -5
- package/dist/components/VTabs/VTabs.js.map +1 -1
- package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js +20 -20
- package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTextarea/VTextarea.css +1 -1
- package/dist/components/VTextarea/VTextarea.d.ts +22 -2
- package/dist/components/VTextarea/VTextarea.js.map +1 -1
- package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js +108 -100
- package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTimeInput/VTimeInput.d.ts +27 -7
- package/dist/components/VTimeInput/VTimeInput.js.map +1 -1
- package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js +187 -171
- package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTimePicker/VTimePicker.d.ts +2 -2
- package/dist/components/VTimePicker/VTimePicker.js.map +1 -1
- package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js +16 -16
- package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTimeline/VTimeline.css +2 -0
- package/dist/components/VTimeline/VTimeline.d.ts +59 -0
- package/dist/components/VTimeline/VTimeline.js +9 -0
- package/dist/components/VTimeline/VTimeline.js.map +1 -0
- package/dist/components/VTimeline/VTimeline.vue_vue_type_script_setup_true_lang.js +53 -0
- package/dist/components/VTimeline/VTimeline.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VTimeline/VTimelineItem.css +2 -0
- package/dist/components/VTimeline/VTimelineItem.d.ts +48 -0
- package/dist/components/VTimeline/VTimelineItem.js +9 -0
- package/dist/components/VTimeline/VTimelineItem.js.map +1 -0
- package/dist/components/VTimeline/VTimelineItem.vue_vue_type_script_setup_true_lang.js +70 -0
- package/dist/components/VTimeline/VTimelineItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VTimeline/context.d.ts +11 -0
- package/dist/components/VTimeline/context.js +6 -0
- package/dist/components/VTimeline/context.js.map +1 -0
- package/dist/components/VTimeline/datetime.d.ts +8 -0
- package/dist/components/VTimeline/datetime.js +36 -0
- package/dist/components/VTimeline/datetime.js.map +1 -0
- package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js +8 -8
- package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js +12 -12
- package/dist/components/VToggle/VToggle.d.ts +4 -4
- package/dist/components/VToggle/VToggle.js.map +1 -1
- package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VToggle/VToggleItem.d.ts +1 -1
- package/dist/components/VTooltip/VTooltip.d.ts +8 -2
- package/dist/components/VTooltip/VTooltip.js.map +1 -1
- package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js +45 -43
- package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTreeView/VTreeView.css +2 -0
- package/dist/components/VTreeView/VTreeView.d.ts +112 -0
- package/dist/components/VTreeView/VTreeView.js +9 -0
- package/dist/components/VTreeView/VTreeView.js.map +1 -0
- package/dist/components/VTreeView/VTreeView.vue_vue_type_script_setup_true_lang.js +317 -0
- package/dist/components/VTreeView/VTreeView.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VTypography/VTypography.d.ts +1 -1
- package/dist/components/VVirtualList/VVirtualList.css +2 -0
- package/dist/components/VVirtualList/VVirtualList.d.ts +78 -0
- package/dist/components/VVirtualList/VVirtualList.js +9 -0
- package/dist/components/VVirtualList/VVirtualList.js.map +1 -0
- package/dist/components/VVirtualList/VVirtualList.vue_vue_type_script_setup_true_lang.js +114 -0
- package/dist/components/VVirtualList/VVirtualList.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/composables/useChoice.d.ts +28 -0
- package/dist/composables/useChoice.js +28 -0
- package/dist/composables/useChoice.js.map +1 -0
- package/dist/composables/useDebouncedSearch.d.ts +17 -0
- package/dist/composables/useDebouncedSearch.js +18 -0
- package/dist/composables/useDebouncedSearch.js.map +1 -0
- package/dist/composables/useEscapeDismiss.d.ts +8 -0
- package/dist/composables/useEscapeDismiss.js +16 -0
- package/dist/composables/useEscapeDismiss.js.map +1 -0
- package/dist/composables/useFieldIds.d.ts +2 -1
- package/dist/composables/useFieldIds.js +7 -6
- package/dist/composables/useFieldIds.js.map +1 -1
- package/dist/composables/useFieldPanel.d.ts +1 -0
- package/dist/composables/useFieldPanel.js +52 -42
- package/dist/composables/useFieldPanel.js.map +1 -1
- package/dist/composables/useFileField.d.ts +1 -3
- package/dist/composables/useFileField.js +48 -50
- package/dist/composables/useFileField.js.map +1 -1
- package/dist/composables/useHotkeyListener.d.ts +17 -0
- package/dist/composables/useHotkeyListener.js +29 -0
- package/dist/composables/useHotkeyListener.js.map +1 -0
- package/dist/composables/useIconClickHandlers.d.ts +2 -10
- package/dist/composables/useIconClickHandlers.js +1 -1
- package/dist/composables/useIconClickHandlers.js.map +1 -1
- package/dist/{components/VCombobox/infiniteScroll.d.ts → composables/useInfiniteScroll.d.ts} +6 -0
- package/dist/{components/VCombobox/infiniteScroll.js → composables/useInfiniteScroll.js} +9 -9
- package/dist/composables/useInfiniteScroll.js.map +1 -0
- package/dist/composables/useListbox.d.ts +132 -0
- package/dist/composables/useListbox.js +227 -0
- package/dist/composables/useListbox.js.map +1 -0
- package/dist/composables/useModalDialog.d.ts +28 -0
- package/dist/composables/useModalDialog.js +60 -0
- package/dist/composables/useModalDialog.js.map +1 -0
- package/dist/composables/useRootAttrs.d.ts +2 -3
- package/dist/composables/useRootAttrs.js.map +1 -1
- package/dist/composables/useTypeahead.d.ts +13 -0
- package/dist/composables/useTypeahead.js +23 -0
- package/dist/composables/useTypeahead.js.map +1 -0
- package/dist/composables/useVirtualList.d.ts +46 -0
- package/dist/composables/useVirtualList.js +145 -0
- package/dist/composables/useVirtualList.js.map +1 -0
- package/dist/i18n/en.js +50 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/fr.js +50 -0
- package/dist/i18n/fr.js.map +1 -1
- package/dist/i18n/state.d.ts +1 -1
- package/dist/i18n/state.js +17 -6
- package/dist/i18n/state.js.map +1 -1
- package/dist/i18n/types.d.ts +103 -2
- package/dist/icons.js +45 -37
- package/dist/index.d.ts +49 -3
- package/dist/index.js +80 -56
- package/dist/styles.css +1 -1
- package/dist/tokens/index.d.ts +43 -0
- package/dist/tokens/semantic.d.ts +42 -0
- package/dist/tokens/semantic.js +43 -1
- package/dist/tokens/semantic.js.map +1 -1
- package/dist/tokens/themes/dark.d.ts +1 -0
- package/dist/tokens/themes/dark.js +1 -0
- package/dist/tokens/themes/dark.js.map +1 -1
- package/dist/tokens.json +215 -1
- package/dist/types.d.ts +57 -4
- package/dist/utils/arrowNav.js.map +1 -1
- package/dist/utils/attrs.d.ts +9 -0
- package/dist/utils/attrs.js +14 -0
- package/dist/utils/attrs.js.map +1 -0
- package/dist/utils/date.d.ts +1 -0
- package/dist/utils/date.js +5 -4
- package/dist/utils/date.js.map +1 -1
- package/package.json +1 -1
- package/dist/components/VCombobox/VComboboxGroup.css +0 -2
- package/dist/components/VCombobox/VComboboxGroup.d.ts +0 -17
- package/dist/components/VCombobox/VComboboxGroup.js +0 -9
- package/dist/components/VCombobox/VComboboxGroup.js.map +0 -1
- package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js +0 -21
- package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js.map +0 -1
- package/dist/components/VCombobox/VComboboxOption.css +0 -2
- package/dist/components/VCombobox/VComboboxOption.js +0 -9
- package/dist/components/VCombobox/VComboboxOption.js.map +0 -1
- package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js.map +0 -1
- package/dist/components/VCombobox/VComboboxSeparator.css +0 -2
- package/dist/components/VCombobox/VComboboxSeparator.js +0 -9
- package/dist/components/VCombobox/VComboboxSeparator.js.map +0 -1
- package/dist/components/VCombobox/VComboboxSeparator.vue_vue_type_script_setup_true_lang.js.map +0 -1
- package/dist/components/VCombobox/infiniteScroll.js.map +0 -1
- /package/dist/components/{VCombobox/VComboboxSeparator.d.ts → VCheckbox/VCheckMark.d.ts} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FieldLabelPosition } from '../VField/VField.js';
|
|
1
2
|
import { IconSource } from '../VIcon/types.js';
|
|
2
3
|
/** The height of one line: 32, 40 or 48 pixels. */
|
|
3
4
|
export type TextareaSize = 'sm' | 'md' | 'lg';
|
|
@@ -38,6 +39,21 @@ interface TextareaProps {
|
|
|
38
39
|
* that it is read out along with the label.
|
|
39
40
|
*/
|
|
40
41
|
hint?: string;
|
|
42
|
+
/**
|
|
43
|
+
* A message saying what is wrong with the value, shown in place of the hint so that the field
|
|
44
|
+
* does not grow. It marks the field invalid, is read along with it, and is announced when it
|
|
45
|
+
* appears or changes.
|
|
46
|
+
*/
|
|
47
|
+
error?: string;
|
|
48
|
+
/** Marks the field as required: an asterisk follows the label, and the textarea is `required`. */
|
|
49
|
+
required?: boolean;
|
|
50
|
+
/** Hides the label visually. It still names the field for assistive technology. */
|
|
51
|
+
hideLabel?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Where the label sits: above the field (`top`, the default), or at its start, in a column of
|
|
54
|
+
* its own, moving back above when there is not room for both.
|
|
55
|
+
*/
|
|
56
|
+
labelPosition?: FieldLabelPosition;
|
|
41
57
|
/**
|
|
42
58
|
* An icon inside the field, at the start. It is decorative by default and becomes a real
|
|
43
59
|
* button as soon as a `@click:icon-start` listener is attached, in which case it needs
|
|
@@ -131,13 +147,18 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {
|
|
|
131
147
|
}>, {
|
|
132
148
|
loading: boolean;
|
|
133
149
|
label: string;
|
|
150
|
+
error: string;
|
|
134
151
|
size: TextareaSize;
|
|
135
152
|
compact: boolean;
|
|
136
|
-
disabled: boolean;
|
|
137
153
|
iconStart: IconSource;
|
|
138
154
|
iconEnd: IconSource;
|
|
155
|
+
disabled: boolean;
|
|
156
|
+
required: boolean;
|
|
139
157
|
invalid: boolean;
|
|
158
|
+
rows: number;
|
|
140
159
|
hint: string;
|
|
160
|
+
hideLabel: boolean;
|
|
161
|
+
labelPosition: FieldLabelPosition;
|
|
141
162
|
readonly: boolean;
|
|
142
163
|
iconStartLabel: string;
|
|
143
164
|
iconEndLabel: string;
|
|
@@ -148,7 +169,6 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {
|
|
|
148
169
|
maxlength: number;
|
|
149
170
|
softLimit: boolean;
|
|
150
171
|
counter: boolean;
|
|
151
|
-
rows: number;
|
|
152
172
|
autoGrow: boolean;
|
|
153
173
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
154
174
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VTextarea.js","names":[],"sources":["../../../src/components/VTextarea/VTextarea.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * Native textarea owns editing and validity. JavaScript bridges the model, text limits and\n * clear-button focus; CSS controls optional content-based height.\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 { useClearable } from '../../composables/useClearable'\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\n/** The height of one line: 32, 40 or 48 pixels. */\nexport type TextareaSize = 'sm' | 'md' | 'lg'\n\ninterface TextareaProps {\n /** The size of the field, which sets its padding, its type scale and its icons. */\n size?: TextareaSize\n /**\n * Takes 4px off the field by tightening its padding, leaving the number of lines,\n * the type and the icons alone.\n */\n compact?: boolean\n /**\n * How many lines of text the field shows: the native `rows` attribute, which gives the field\n * its height.\n */\n rows?: number\n /**\n * Lets the field grow as the text is typed, instead of scrolling inside the height `rows`\n * gives it, which stays its starting height.\n */\n autoGrow?: boolean\n /**\n * Marks the field as invalid whatever the browser thinks: the route for a rule\n * only the server can check.\n */\n invalid?: boolean\n /** Makes the field unusable, greyed out through the colour tokens. */\n disabled?: boolean\n /**\n * Shows the text without allowing it to be changed. The field can still be focused\n * and copied from, and the clear button is hidden.\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, tied to the textarea for assistive technology so\n * that 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 a real\n * button as soon as a `@click:icon-start` listener is attached, in which case it needs\n * `iconStartLabel`.\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 design\n * system dictionary.\n */\n loadingText?: 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 from its own\n * content (a read-only field included).\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 goes into\n * error instead of silently refusing the keystrokes.\n */\n softLimit?: boolean\n /**\n * Shows how much has been typed, under the field: \"12/80\" against a limit, or just\n * \"12\" without one.\n */\n counter?: boolean\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<TextareaProps>(), {\n size: 'md',\n compact: false,\n rows: 5,\n autoGrow: false,\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 loadingText: 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, as in VInput.\n */\n start?(): unknown\n /**\n * Content at the end of the field, which replaces `iconEnd`. It is hidden while the\n * field is loading, the spinner taking that place.\n */\n end?(): unknown\n /**\n * Controls of your own inside the field, placed before the field's own: the clear cross and\n * the end icon.\n */\n 'value-end'?(): unknown\n}>()\n\n/** The text in the field, empty to begin with. */\nconst model = defineModel<string>({ default: '' })\n\n// HTML wants `rows` to be a positive integer, and it drops anything else on the floor:\n// a 0, a negative or a fractional value would leave the browser falling back to its own\n// default of two rows, which is neither what was asked for nor this component's default.\n// Rounding and flooring here is what keeps the prop's contract out of the parser's hands.\nconst resolvedRows = computed(() => Math.max(1, Math.round(props.rows)))\n\n// `class` and `style` stay on the wrapper, where a consumer expects to style the\n// field; every other attribute goes to the textarea, where it does something.\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 resolvedClearLabel = computed(() => props.clearLabel ?? m.value.common.clear)\n\nconst { fieldId, hintId, counterId, describedBy } = useFieldIds(\n attrs,\n () => !!props.hint,\n () => props.counter,\n)\n\n// Every length measurement goes through this projection: a value straight from an API or\n// a database is often `null`, and reading `.length` on it would throw at mount.\nconst modelText = computed(() => model.value ?? '')\n\nconst { hasIconStartHandler, hasIconEndHandler } = useIconClickHandlers({\n name: 'VTextarea',\n iconStartLabel: props.iconStartLabel,\n iconEndLabel: props.iconEndLabel,\n})\n\nconst controlEl = ref<HTMLTextAreaElement | null>(null)\n\nconst { showClear, onClear } = useClearable({\n clearable: () => props.clearable,\n clearVisible: () => props.clearVisible,\n disabled: () => props.disabled,\n readonly: () => props.readonly,\n text: () => modelText.value,\n controlEl,\n onCleared: () => {\n model.value = ''\n emit('clear')\n },\n})\n\nconst { counterText, over } = useTextLimit({\n el: controlEl,\n text: () => modelText.value,\n maxlength: () => props.maxlength,\n softLimit: () => props.softLimit,\n})\n\ndefineExpose({\n /** Moves the focus to the real textarea. */\n focus: (options?: FocusOptions) => controlEl.value?.focus(options),\n /** Selects everything in the field. */\n select: () => controlEl.value?.select(),\n /** The real `<textarea>`, for what neither of the two above covers. */\n el: controlEl,\n})\n</script>\n\n<template>\n <div\n class=\"v-textarea 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-textarea-label\" :for=\"fieldId\">\n {{ label }}\n </VTypography>\n\n <div\n class=\"v-textarea-field\"\n :style=\"{ '--textarea-rows': resolvedRows }\"\n :data-auto-grow=\"autoGrow ? '' : undefined\"\n >\n <!--\n The start icon is rendered before the slot, where the end icon is the slot's own\n fallback. The asymmetry is VInput's, mirrored here so the two fields answer the same\n way: what a composed field puts in that zone is OTHER content beside the icon, not\n another way of drawing it.\n -->\n <button\n v-if=\"iconStart && hasIconStartHandler\"\n type=\"button\"\n class=\"v-textarea-action v-field-action v-textarea-icon-start\"\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)\" class=\"v-textarea-icon-start\" />\n <slot name=\"start\" />\n\n <textarea\n :id=\"fieldId\"\n ref=\"controlEl\"\n v-model=\"model\"\n :aria-invalid=\"invalid || undefined\"\n v-bind=\"restAttrs\"\n class=\"v-textarea-control\"\n :rows=\"resolvedRows\"\n :maxlength=\"softLimit ? undefined : maxlength\"\n :disabled=\"disabled\"\n :readonly=\"readonly || undefined\"\n :aria-describedby=\"describedBy\"\n />\n\n <slot name=\"value-end\" />\n\n <button\n v-if=\"showClear\"\n type=\"button\"\n class=\"v-textarea-action v-field-action v-textarea-clear\"\n :aria-label=\"resolvedClearLabel\"\n @click=\"onClear\"\n >\n <VIcon :name=\"closeIcon\" />\n </button>\n\n <VSpinner v-if=\"loading\" :label=\"loadingText\" />\n <slot v-else name=\"end\">\n <button\n v-if=\"iconEnd && hasIconEndHandler\"\n type=\"button\"\n class=\"v-textarea-action v-field-action v-textarea-icon-end\"\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)\" class=\"v-textarea-icon-end\" />\n </slot>\n </div>\n\n <div v-if=\"hint || counter\" class=\"v-textarea-meta v-field-meta\">\n <VTypography v-if=\"hint\" :id=\"hintId\" variant=\"caption\" tone=\"muted\" class=\"v-textarea-hint\">\n {{ hint }}\n </VTypography>\n <span\n v-if=\"counter\"\n :id=\"counterId\"\n class=\"v-textarea-counter v-field-counter\"\n :data-over=\"over ? '' : undefined\"\n >\n {{ counterText }}\n </span>\n </div>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-textarea {\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 /*\n * The .v-textarea-label and .v-textarea-hint classes remain as hooks: a consumer overrides\n * through them, and the disabled state below reaches them that way.\n */\n\n /*\n * This is the box that carries the border, the background, the focus ring and the resize\n * handle; which is why it also hides its overflow, `resize` having no effect on a box whose\n * overflow is visible. `--field-border-color` is the single source of truth for its colour,\n * and the hover, error and disabled states do nothing but redefine it.\n */\n .v-textarea-field {\n --field-border-color: var(--vectis-color-border-strong);\n\n /*\n * Nothing here restates the size scale: the `--control-*` variables are inherited from the\n * v-control root (styles/control-size.css), the icon context included. The field carries no\n * height of its own: it is the `rows` attribute on the textarea that sets one, and the\n * field is simply as tall as the control it wraps.\n */\n\n /*\n * The leading is named once and feeds two things that have to agree by construction: the\n * field's own `line-height`, and the first line box below, against which everything sitting\n * beside the text is offset.\n */\n --textarea-leading: var(--vectis-text-body-md-leading);\n\n /*\n * It is DERIVED and must never be written as `1lh`. The buttons happened to be right only\n * because the reset gives them `font: inherit`.\n */\n --textarea-line: calc(var(--control-font-size) * var(--textarea-leading));\n\n display: flex;\n align-items: flex-start;\n gap: var(--control-gap);\n padding-inline: var(--control-padding-inline-field);\n /*\n * Derive padding from control height minus borders and one line. Read the compact-adjusted\n * height so rows=1 matches VInput and each additional row adds one line.\n */\n padding-block: calc((var(--control-height) - 2px - var(--textarea-line)) / 2);\n background: var(--vectis-color-surface);\n color: var(--vectis-color-text);\n border: 1px solid var(--field-border-color);\n /*\n * The cap is what carries the VInput identity above into the OTHER row counts, and it has\n * to stay derived from --control-height. A browser scales down any radius it cannot fit, so\n * on a one-row field a pill override is already painted as half the control height; min()\n * applies that same reduction to a field that is taller.\n */\n border-radius: min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));\n font-size: var(--control-font-size);\n /* Text running over several lines takes the body line height. The `control` type\n role, whose lines are set tight against one another, only makes sense for a\n single-line label. */\n line-height: var(--textarea-leading);\n resize: vertical;\n overflow: hidden;\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-textarea-control {\n flex: 1;\n min-width: 0;\n align-self: stretch;\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 resize: none;\n }\n\n .v-textarea-control::placeholder {\n color: var(--vectis-color-text-subtle);\n }\n\n /*\n * The margin is SYMMETRIC, the VToast rule. It looks redundant under\n * `align-items: flex-start`, where only the start side moves anything, but the end side is\n * what keeps the item's OUTER box down to one line box.\n */\n .v-textarea-field > .v-icon,\n .v-textarea-field > .v-spinner {\n margin-block: calc((var(--textarea-line) - var(--vectis-icon-size)) / 2);\n }\n\n .v-textarea-field > .v-textarea-action {\n margin-block: calc((var(--textarea-line) - var(--control-action-size)) / 2);\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-textarea-field > .v-icon {\n color: var(--vectis-color-text-muted);\n }\n\n .v-textarea-field > .v-spinner {\n font-size: var(--vectis-icon-size);\n }\n\n /*\n * This block must stay first in the sequence of states: read-only, then hover, focus, invalid\n * and disabled. The read-only, focus, invalid and disabled selectors all weigh (0,3,0),\n * `:has()` taking the specificity of what it contains, so nothing but the source order\n * arbitrates between them.\n */\n .v-textarea[data-readonly] .v-textarea-field {\n --field-border-color: var(--vectis-color-border);\n\n background: var(--vectis-color-surface-sunken);\n }\n\n .v-textarea-field:hover:not(:has(.v-textarea-control:focus)):not(\n :has(\n .v-textarea-control:disabled,\n .v-textarea-control:user-invalid,\n .v-textarea-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 /*\n * The selector watches the control's focus and not `:focus-within`, so that when one of the\n * field's own buttons takes keyboard focus, only that button's outline lights up: two\n * indicators at once would be unreadable. And it is `:focus` rather than `:focus-visible`,\n * because a text field shows its focus even when it was reached with the mouse.\n */\n .v-textarea-field:has(.v-textarea-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 /*\n * Only the colour variable is changed, which is why the border and the focus ring both turn\n * red without either being restated.\n */\n .v-textarea-field:has(.v-textarea-control:user-invalid),\n .v-textarea-field:has(.v-textarea-control[aria-invalid='true']) {\n --field-border-color: var(--vectis-color-danger);\n }\n\n /*\n * A disabled field greys out through the colour tokens, the same ones VCheckbox and VRadio\n * use, and never through opacity. It comes last in the sequence of states, which at equal\n * specificity is what makes it win over all of them, the error included: a disabled field is\n * not submitted, so it has nothing to report.\n */\n .v-textarea[data-disabled] .v-textarea-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 resize: none;\n }\n\n .v-textarea[data-disabled] .v-textarea-label,\n .v-textarea[data-disabled] .v-textarea-hint,\n .v-textarea[data-disabled] .v-textarea-counter {\n color: var(--vectis-color-text-subtle);\n }\n\n .v-textarea[data-disabled] .v-textarea-action,\n .v-textarea[data-disabled] .v-textarea-field > .v-icon {\n color: inherit;\n cursor: not-allowed;\n }\n\n .v-textarea-control:disabled {\n cursor: not-allowed;\n }\n\n /*\n * A browser without support keeps the fixed height and its scrollbar, which is the intended\n * fallback.\n */\n .v-textarea-field[data-auto-grow] {\n resize: none;\n }\n\n /*\n * It is scoped to this branch and must not be lifted onto the control at large: a floor there\n * would stop the control shrinking with the resize handle, and the field, which hides its\n * overflow, would clip it instead of scrolling.\n */\n .v-textarea-field[data-auto-grow] .v-textarea-control {\n field-sizing: content;\n min-block-size: calc(var(--textarea-rows) * var(--textarea-line));\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-textarea-field {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"VTextarea.js","names":[],"sources":["../../../src/components/VTextarea/VTextarea.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * Native textarea owns editing and validity. JavaScript bridges the model, text limits and\n * clear-button focus; CSS controls optional content-based height.\n */\nimport { computed, ref } from 'vue'\n\nimport VField from '../VField/VField.vue'\nimport type { FieldControlProps, FieldLabelPosition } from '../VField/VField.vue'\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'\n\nimport { useClearable } from '../../composables/useClearable'\nimport { useIconClickHandlers } from '../../composables/useIconClickHandlers'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useTextLimit } from '../../composables/useTextLimit'\nimport { useMessages } from '../../i18n/state'\n\n/** The height of one line: 32, 40 or 48 pixels. */\nexport type TextareaSize = 'sm' | 'md' | 'lg'\n\ninterface TextareaProps {\n /** The size of the field, which sets its padding, its type scale and its icons. */\n size?: TextareaSize\n /**\n * Takes 4px off the field by tightening its padding, leaving the number of lines,\n * the type and the icons alone.\n */\n compact?: boolean\n /**\n * How many lines of text the field shows: the native `rows` attribute, which gives the field\n * its height.\n */\n rows?: number\n /**\n * Lets the field grow as the text is typed, instead of scrolling inside the height `rows`\n * gives it, which stays its starting height.\n */\n autoGrow?: boolean\n /**\n * Marks the field as invalid whatever the browser thinks: the route for a rule\n * only the server can check.\n */\n invalid?: boolean\n /** Makes the field unusable, greyed out through the colour tokens. */\n disabled?: boolean\n /**\n * Shows the text without allowing it to be changed. The field can still be focused\n * and copied from, and the clear button is hidden.\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, tied to the textarea for assistive technology so\n * that it is read out along with the label.\n */\n hint?: string\n /**\n * A message saying what is wrong with the value, shown in place of the hint so that the field\n * does not grow. It marks the field invalid, is read along with it, and is announced when it\n * appears or changes.\n */\n error?: string\n /** Marks the field as required: an asterisk follows the label, and the textarea is `required`. */\n required?: boolean\n /** Hides the label visually. It still names the field for assistive technology. */\n hideLabel?: boolean\n /**\n * Where the label sits: above the field (`top`, the default), or at its start, in a column of\n * its own, moving back above when there is not room for both.\n */\n labelPosition?: FieldLabelPosition\n /**\n * An icon inside the field, at the start. It is decorative by default and becomes a real\n * button as soon as a `@click:icon-start` listener is attached, in which case it needs\n * `iconStartLabel`.\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 design\n * system dictionary.\n */\n loadingText?: 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 from its own\n * content (a read-only field included).\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 goes into\n * error instead of silently refusing the keystrokes.\n */\n softLimit?: boolean\n /**\n * Shows how much has been typed, under the field: \"12/80\" against a limit, or just\n * \"12\" without one.\n */\n counter?: boolean\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<TextareaProps>(), {\n size: 'md',\n compact: false,\n rows: 5,\n autoGrow: false,\n invalid: false,\n disabled: false,\n readonly: false,\n label: undefined,\n hint: undefined,\n error: undefined,\n required: false,\n hideLabel: false,\n labelPosition: 'top',\n iconStart: undefined,\n iconEnd: undefined,\n iconStartLabel: undefined,\n iconEndLabel: undefined,\n loading: false,\n loadingText: 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, as in VInput.\n */\n start?(): unknown\n /**\n * Content at the end of the field, which replaces `iconEnd`. It is hidden while the\n * field is loading, the spinner taking that place.\n */\n end?(): unknown\n /**\n * Controls of your own inside the field, placed before the field's own: the clear cross and\n * the end icon.\n */\n 'value-end'?(): unknown\n}>()\n\n/** The text in the field, empty to begin with. */\nconst model = defineModel<string>({ default: '' })\n\n// HTML wants `rows` to be a positive integer, and it drops anything else on the floor:\n// a 0, a negative or a fractional value would leave the browser falling back to its own\n// default of two rows, which is neither what was asked for nor this component's default.\n// Rounding and flooring here is what keeps the prop's contract out of the parser's hands.\nconst resolvedRows = computed(() => Math.max(1, Math.round(props.rows)))\n\n// `class` and `style` stay on the wrapper, where a consumer expects to style the\n// field; every other attribute goes to the textarea, where it does something.\nconst { 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 resolvedClearLabel = computed(() => props.clearLabel ?? m.value.common.clear)\n\n// Every length measurement goes through this projection: a value straight from an API or\n// a database is often `null`, and reading `.length` on it would throw at mount.\nconst modelText = computed(() => model.value ?? '')\n\nconst { hasIconStartHandler, hasIconEndHandler } = useIconClickHandlers({\n name: 'VTextarea',\n iconStartLabel: props.iconStartLabel,\n iconEndLabel: props.iconEndLabel,\n})\n\nconst controlEl = ref<HTMLTextAreaElement | null>(null)\n\nconst { showClear, onClear } = useClearable({\n clearable: () => props.clearable,\n clearVisible: () => props.clearVisible,\n disabled: () => props.disabled,\n readonly: () => props.readonly,\n text: () => modelText.value,\n controlEl,\n onCleared: () => {\n model.value = ''\n emit('clear')\n },\n})\n\nconst { counterText, over } = useTextLimit({\n el: controlEl,\n text: () => modelText.value,\n maxlength: () => props.maxlength,\n softLimit: () => props.softLimit,\n})\n\n/** The attributes of the textarea, built on VField's: the consumer's win over `invalid`. */\nfunction textareaAttrs(fieldProps: FieldControlProps): FieldControlProps {\n return { 'aria-invalid': props.invalid ? 'true' : undefined, ...fieldProps }\n}\n\ndefineExpose({\n /** Moves the focus to the real textarea. */\n focus: (options?: FocusOptions) => controlEl.value?.focus(options),\n /** Selects everything in the field. */\n select: () => controlEl.value?.select(),\n /** The real `<textarea>`, for what neither of the two above covers. */\n el: controlEl,\n})\n</script>\n\n<template>\n <VField\n v-bind=\"restAttrs\"\n class=\"v-textarea\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :label=\"label\"\n :hint=\"hint\"\n :error=\"error\"\n :required=\"required\"\n :disabled=\"disabled\"\n :hide-label=\"hideLabel\"\n :label-position=\"labelPosition\"\n >\n <template #default=\"{ fieldProps }\">\n <div\n class=\"v-textarea-field v-control\"\n :style=\"{ '--textarea-rows': resolvedRows }\"\n :data-size=\"size\"\n :data-compact=\"compact ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n :data-readonly=\"readonly ? '' : undefined\"\n :data-auto-grow=\"autoGrow ? '' : undefined\"\n >\n <!--\n The start icon is rendered before the slot, where the end icon is the slot's own\n fallback. The asymmetry is VInput's, mirrored here so the two fields answer the same\n way: what a composed field puts in that zone is OTHER content beside the icon, not\n another way of drawing it.\n -->\n <button\n v-if=\"iconStart && hasIconStartHandler\"\n type=\"button\"\n class=\"v-textarea-action v-field-action v-textarea-icon-start\"\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)\" class=\"v-textarea-icon-start\" />\n <slot name=\"start\" />\n\n <!-- The label's `for` matches the id inside fieldProps, which the rule cannot follow. -->\n <!-- eslint-disable-next-line vuejs-accessibility/form-control-has-label -->\n <textarea\n ref=\"controlEl\"\n v-model=\"model\"\n v-bind=\"textareaAttrs(fieldProps)\"\n class=\"v-textarea-control\"\n :rows=\"resolvedRows\"\n :maxlength=\"softLimit ? undefined : maxlength\"\n :disabled=\"disabled\"\n :readonly=\"readonly || undefined\"\n />\n\n <slot name=\"value-end\" />\n\n <button\n v-if=\"showClear\"\n type=\"button\"\n class=\"v-textarea-action v-field-action v-textarea-clear\"\n :aria-label=\"resolvedClearLabel\"\n @click=\"onClear\"\n >\n <VIcon :name=\"closeIcon\" />\n </button>\n\n <VSpinner v-if=\"loading\" :label=\"loadingText\" />\n <slot v-else name=\"end\">\n <button\n v-if=\"iconEnd && hasIconEndHandler\"\n type=\"button\"\n class=\"v-textarea-action v-field-action v-textarea-icon-end\"\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)\" class=\"v-textarea-icon-end\" />\n </slot>\n </div>\n </template>\n <template v-if=\"counter\" #meta=\"{ id }\">\n <span :id=\"id\" class=\"v-textarea-counter v-field-counter\" :data-over=\"over ? '' : undefined\">\n {{ counterText }}\n </span>\n </template>\n </VField>\n</template>\n\n<style>\n@layer vectis.components {\n /* The root is a VField, which lays out the label, the hint and the error. */\n .v-textarea {\n width: 100%;\n }\n\n /*\n * This is the box that carries the border, the background, the focus ring and the resize\n * handle; which is why it also hides its overflow, `resize` having no effect on a box whose\n * overflow is visible. `--field-border-color` is the single source of truth for its colour,\n * and the hover, error and disabled states do nothing but redefine it.\n */\n .v-textarea-field {\n --field-border-color: var(--vectis-color-border-strong);\n\n /*\n * Nothing here restates the size scale: the `--control-*` variables come from the v-control\n * class on this box (styles/control-size.css), the icon context included. The field carries no\n * height of its own: it is the `rows` attribute on the textarea that sets one, and the\n * field is simply as tall as the control it wraps.\n */\n\n /*\n * The leading is named once and feeds two things that have to agree by construction: the\n * field's own `line-height`, and the first line box below, against which everything sitting\n * beside the text is offset.\n */\n --textarea-leading: var(--vectis-text-body-md-leading);\n\n /*\n * Derived rather than written as `1lh`: a custom property resolves `lh` where it is used, so\n * the icons and buttons beside the text would each measure their own line height.\n */\n --textarea-line: calc(var(--control-font-size) * var(--textarea-leading));\n\n display: flex;\n align-items: flex-start;\n gap: var(--control-gap);\n padding-inline: var(--control-padding-inline-field);\n /*\n * Derive padding from control height minus borders and one line. Read the compact-adjusted\n * height so rows=1 matches VInput and each additional row adds one line.\n */\n padding-block: calc((var(--control-height) - 2px - var(--textarea-line)) / 2);\n background: var(--vectis-color-surface);\n color: var(--vectis-color-text);\n border: 1px solid var(--field-border-color);\n /*\n * The cap is what carries the VInput identity above into the OTHER row counts, and it has\n * to stay derived from --control-height. A browser scales down any radius it cannot fit, so\n * on a one-row field a pill override is already painted as half the control height; min()\n * applies that same reduction to a field that is taller.\n */\n border-radius: min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));\n font-size: var(--control-font-size);\n /* Text running over several lines takes the body line height. The `control` type\n role, whose lines are set tight against one another, only makes sense for a\n single-line label. */\n line-height: var(--textarea-leading);\n resize: vertical;\n overflow: hidden;\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-textarea-control {\n flex: 1;\n min-width: 0;\n align-self: stretch;\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 resize: none;\n }\n\n .v-textarea-control::placeholder {\n color: var(--vectis-color-text-subtle);\n }\n\n /*\n * The margin is SYMMETRIC, the VToast rule. It looks redundant under\n * `align-items: flex-start`, where only the start side moves anything, but the end side is\n * what keeps the item's OUTER box down to one line box.\n */\n .v-textarea-field > .v-icon,\n .v-textarea-field > .v-spinner {\n margin-block: calc((var(--textarea-line) - var(--vectis-icon-size)) / 2);\n }\n\n .v-textarea-field > .v-textarea-action {\n margin-block: calc((var(--textarea-line) - var(--control-action-size)) / 2);\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-textarea-field > .v-icon {\n color: var(--vectis-color-text-muted);\n }\n\n .v-textarea-field > .v-spinner {\n font-size: var(--vectis-icon-size);\n }\n\n /*\n * This block must stay first in the sequence of states: read-only, then hover, focus, invalid\n * and disabled. The read-only, focus, invalid and disabled selectors all weigh (0,3,0),\n * `:has()` taking the specificity of what it contains, so nothing but the source order\n * arbitrates between them.\n */\n .v-textarea .v-textarea-field[data-readonly] {\n --field-border-color: var(--vectis-color-border);\n\n background: var(--vectis-color-surface-sunken);\n }\n\n .v-textarea-field:hover:not(:has(.v-textarea-control:focus)):not(\n :has(\n .v-textarea-control:disabled,\n .v-textarea-control:user-invalid,\n .v-textarea-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 /*\n * The selector watches the control's focus and not `:focus-within`, so that when one of the\n * field's own buttons takes keyboard focus, only that button's outline lights up: two\n * indicators at once would be unreadable. And it is `:focus` rather than `:focus-visible`,\n * because a text field shows its focus even when it was reached with the mouse.\n */\n .v-textarea-field:has(.v-textarea-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 /*\n * Only the colour variable is changed, which is why the border and the focus ring both turn\n * red without either being restated.\n */\n .v-textarea-field:has(.v-textarea-control:user-invalid),\n .v-textarea-field:has(.v-textarea-control[aria-invalid='true']) {\n --field-border-color: var(--vectis-color-danger);\n }\n\n /*\n * A disabled field greys out through the colour tokens, the same ones VCheckbox and VRadio\n * use, and never through opacity. It comes last in the sequence of states, which at equal\n * specificity is what makes it win over all of them, the error included: a disabled field is\n * not submitted, so it has nothing to report.\n */\n .v-textarea .v-textarea-field[data-disabled] {\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 resize: none;\n }\n\n .v-textarea[data-disabled] .v-textarea-counter {\n color: var(--vectis-color-text-subtle);\n }\n\n .v-textarea-field[data-disabled] .v-textarea-action,\n .v-textarea-field[data-disabled] > .v-icon {\n color: inherit;\n cursor: not-allowed;\n }\n\n .v-textarea-control:disabled {\n cursor: not-allowed;\n }\n\n /*\n * A browser without support keeps the fixed height and its scrollbar, which is the intended\n * fallback.\n */\n .v-textarea-field[data-auto-grow] {\n resize: none;\n }\n\n /*\n * It is scoped to this branch and must not be lifted onto the control at large: a floor there\n * would stop the control shrinking with the resize handle, and the field, which hides its\n * overflow, would clip it instead of scrolling.\n */\n .v-textarea-field[data-auto-grow] .v-textarea-control {\n field-sizing: content;\n min-block-size: calc(var(--textarea-rows) * var(--textarea-line));\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-textarea-field {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -1,36 +1,30 @@
|
|
|
1
1
|
import { useMessages as e } from "../../i18n/state.js";
|
|
2
2
|
import { iconName as t, iconProps as n } from "../VIcon/iconProps.js";
|
|
3
3
|
import r from "../VIcon/VIcon.js";
|
|
4
|
-
import i from "../
|
|
5
|
-
import a from "
|
|
6
|
-
import
|
|
4
|
+
import i from "../VSpinner/VSpinner.js";
|
|
5
|
+
import { useRootAttrs as a } from "../../composables/useRootAttrs.js";
|
|
6
|
+
import o from "../VField/VField.js";
|
|
7
7
|
import { close as s } from "../VIcon/icons/close.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { computed as u, createBlock as d, createCommentVNode as f, createElementBlock as p, createElementVNode as m, createTextVNode as h, createVNode as g, defineComponent as _, guardReactiveProps as v, mergeModels as y, mergeProps as b, normalizeClass as ne, normalizeProps as x, normalizeStyle as S, openBlock as C, ref as w, renderSlot as T, toDisplayString as E, unref as D, useModel as re, vModelText as ie, withCtx as O, withDirectives as k } from "vue";
|
|
8
|
+
import { useIconClickHandlers as c } from "../../composables/useIconClickHandlers.js";
|
|
9
|
+
import { useClearable as l } from "../../composables/useClearable.js";
|
|
10
|
+
import { useTextLimit as u } from "../../composables/useTextLimit.js";
|
|
11
|
+
import { computed as d, createBlock as f, createCommentVNode as p, createElementBlock as m, createElementVNode as h, createSlots as g, createVNode as _, defineComponent as v, guardReactiveProps as y, mergeModels as b, mergeProps as x, normalizeProps as S, normalizeStyle as C, openBlock as w, ref as T, renderSlot as E, toDisplayString as D, unref as O, useModel as k, vModelText as ee, withCtx as A, withDirectives as j } from "vue";
|
|
13
12
|
//#region src/components/VTextarea/VTextarea.vue?vue&type=script&setup=true&lang.ts
|
|
14
|
-
var
|
|
13
|
+
var M = [
|
|
15
14
|
"data-size",
|
|
16
15
|
"data-compact",
|
|
17
16
|
"data-disabled",
|
|
18
|
-
"data-readonly"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"aria-invalid",
|
|
17
|
+
"data-readonly",
|
|
18
|
+
"data-auto-grow"
|
|
19
|
+
], N = ["aria-label", "disabled"], P = [
|
|
22
20
|
"rows",
|
|
23
21
|
"maxlength",
|
|
24
22
|
"disabled",
|
|
25
|
-
"readonly"
|
|
26
|
-
|
|
27
|
-
], P = ["aria-label"], F = ["aria-label", "disabled"], I = {
|
|
28
|
-
key: 1,
|
|
29
|
-
class: "v-textarea-meta v-field-meta"
|
|
30
|
-
}, L = ["id", "data-over"], R = /*@__PURE__*/ _({
|
|
23
|
+
"readonly"
|
|
24
|
+
], F = ["aria-label"], I = ["aria-label", "disabled"], L = ["id", "data-over"], R = /*@__PURE__*/ v({
|
|
31
25
|
inheritAttrs: !1,
|
|
32
26
|
__name: "VTextarea",
|
|
33
|
-
props: /*@__PURE__*/
|
|
27
|
+
props: /*@__PURE__*/ b({
|
|
34
28
|
size: { default: "md" },
|
|
35
29
|
compact: {
|
|
36
30
|
type: Boolean,
|
|
@@ -55,6 +49,16 @@ var A = [
|
|
|
55
49
|
},
|
|
56
50
|
label: { default: void 0 },
|
|
57
51
|
hint: { default: void 0 },
|
|
52
|
+
error: { default: void 0 },
|
|
53
|
+
required: {
|
|
54
|
+
type: Boolean,
|
|
55
|
+
default: !1
|
|
56
|
+
},
|
|
57
|
+
hideLabel: {
|
|
58
|
+
type: Boolean,
|
|
59
|
+
default: !1
|
|
60
|
+
},
|
|
61
|
+
labelPosition: { default: "top" },
|
|
58
62
|
iconStart: { default: void 0 },
|
|
59
63
|
iconEnd: { default: void 0 },
|
|
60
64
|
iconStartLabel: { default: void 0 },
|
|
@@ -86,118 +90,122 @@ var A = [
|
|
|
86
90
|
modelValue: { default: "" },
|
|
87
91
|
modelModifiers: {}
|
|
88
92
|
}),
|
|
89
|
-
emits: /*@__PURE__*/
|
|
93
|
+
emits: /*@__PURE__*/ b([
|
|
90
94
|
"click:icon-start",
|
|
91
95
|
"click:icon-end",
|
|
92
96
|
"clear"
|
|
93
97
|
], ["update:modelValue"]),
|
|
94
|
-
setup(
|
|
95
|
-
let z =
|
|
98
|
+
setup(v, { expose: b, emit: R }) {
|
|
99
|
+
let z = v, B = R, V = k(v, "modelValue"), H = d(() => Math.max(1, Math.round(z.rows))), { rootClass: U, rootStyle: W, forwardedAttrs: G } = a(), K = e(), q = d(() => z.clearLabel ?? K.value.common.clear), J = d(() => V.value ?? ""), { hasIconStartHandler: Y, hasIconEndHandler: X } = c({
|
|
96
100
|
name: "VTextarea",
|
|
97
101
|
iconStartLabel: z.iconStartLabel,
|
|
98
102
|
iconEndLabel: z.iconEndLabel
|
|
99
|
-
}),
|
|
103
|
+
}), Z = T(null), { showClear: Q, onClear: $ } = l({
|
|
100
104
|
clearable: () => z.clearable,
|
|
101
105
|
clearVisible: () => z.clearVisible,
|
|
102
106
|
disabled: () => z.disabled,
|
|
103
107
|
readonly: () => z.readonly,
|
|
104
|
-
text: () =>
|
|
105
|
-
controlEl:
|
|
108
|
+
text: () => J.value,
|
|
109
|
+
controlEl: Z,
|
|
106
110
|
onCleared: () => {
|
|
107
111
|
V.value = "", B("clear");
|
|
108
112
|
}
|
|
109
|
-
}), { counterText:
|
|
110
|
-
el:
|
|
111
|
-
text: () =>
|
|
113
|
+
}), { counterText: te, over: ne } = u({
|
|
114
|
+
el: Z,
|
|
115
|
+
text: () => J.value,
|
|
112
116
|
maxlength: () => z.maxlength,
|
|
113
117
|
softLimit: () => z.softLimit
|
|
114
118
|
});
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
"data-
|
|
119
|
+
function re(e) {
|
|
120
|
+
return {
|
|
121
|
+
"aria-invalid": z.invalid ? "true" : void 0,
|
|
122
|
+
...e
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return b({
|
|
126
|
+
focus: (e) => Z.value?.focus(e),
|
|
127
|
+
select: () => Z.value?.select(),
|
|
128
|
+
el: Z
|
|
129
|
+
}), (e, a) => (w(), f(o, x(O(G), {
|
|
130
|
+
class: ["v-textarea", O(U)],
|
|
131
|
+
style: O(W),
|
|
132
|
+
label: v.label,
|
|
133
|
+
hint: v.hint,
|
|
134
|
+
error: v.error,
|
|
135
|
+
required: v.required,
|
|
136
|
+
disabled: v.disabled,
|
|
137
|
+
"hide-label": v.hideLabel,
|
|
138
|
+
"label-position": v.labelPosition
|
|
139
|
+
}), g({
|
|
140
|
+
default: A(({ fieldProps: o }) => [h("div", {
|
|
141
|
+
class: "v-textarea-field v-control",
|
|
142
|
+
style: C({ "--textarea-rows": H.value }),
|
|
143
|
+
"data-size": v.size,
|
|
144
|
+
"data-compact": v.compact ? "" : void 0,
|
|
145
|
+
"data-disabled": v.disabled ? "" : void 0,
|
|
146
|
+
"data-readonly": v.readonly ? "" : void 0,
|
|
147
|
+
"data-auto-grow": v.autoGrow ? "" : void 0
|
|
141
148
|
}, [
|
|
142
|
-
|
|
149
|
+
v.iconStart && O(Y) ? (w(), m("button", {
|
|
143
150
|
key: 0,
|
|
144
151
|
type: "button",
|
|
145
152
|
class: "v-textarea-action v-field-action v-textarea-icon-start",
|
|
146
|
-
"aria-label":
|
|
147
|
-
disabled:
|
|
148
|
-
onClick:
|
|
149
|
-
}, [
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
id: D(Y),
|
|
153
|
+
"aria-label": v.iconStartLabel ?? O(t)(v.iconStart),
|
|
154
|
+
disabled: v.disabled,
|
|
155
|
+
onClick: a[0] ||= (e) => B("click:icon-start", e)
|
|
156
|
+
}, [_(r, S(y(O(n)(v.iconStart))), null, 16)], 8, N)) : v.iconStart ? (w(), f(r, x({ key: 1 }, O(n)(v.iconStart), { class: "v-textarea-icon-start" }), null, 16)) : p("", !0),
|
|
157
|
+
E(e.$slots, "start"),
|
|
158
|
+
j(h("textarea", x({
|
|
153
159
|
ref_key: "controlEl",
|
|
154
|
-
ref:
|
|
155
|
-
"onUpdate:modelValue":
|
|
156
|
-
|
|
157
|
-
}, D(K), {
|
|
160
|
+
ref: Z,
|
|
161
|
+
"onUpdate:modelValue": a[1] ||= (e) => V.value = e
|
|
162
|
+
}, re(o), {
|
|
158
163
|
class: "v-textarea-control",
|
|
159
164
|
rows: H.value,
|
|
160
|
-
maxlength:
|
|
161
|
-
disabled:
|
|
162
|
-
readonly:
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
D(le) ? (C(), p("button", {
|
|
165
|
+
maxlength: v.softLimit ? void 0 : v.maxlength,
|
|
166
|
+
disabled: v.disabled,
|
|
167
|
+
readonly: v.readonly || void 0
|
|
168
|
+
}), null, 16, P), [[ee, V.value]]),
|
|
169
|
+
E(e.$slots, "value-end"),
|
|
170
|
+
O(Q) ? (w(), m("button", {
|
|
167
171
|
key: 2,
|
|
168
172
|
type: "button",
|
|
169
173
|
class: "v-textarea-action v-field-action v-textarea-clear",
|
|
170
|
-
"aria-label":
|
|
171
|
-
onClick:
|
|
172
|
-
}, [
|
|
173
|
-
|
|
174
|
+
"aria-label": q.value,
|
|
175
|
+
onClick: a[2] ||= (...e) => O($) && O($)(...e)
|
|
176
|
+
}, [_(r, { name: O(s) }, null, 8, ["name"])], 8, F)) : p("", !0),
|
|
177
|
+
v.loading ? (w(), f(i, {
|
|
174
178
|
key: 3,
|
|
175
|
-
label:
|
|
176
|
-
}, null, 8, ["label"])) :
|
|
179
|
+
label: v.loadingText
|
|
180
|
+
}, null, 8, ["label"])) : E(e.$slots, "end", {}, () => [v.iconEnd && O(X) ? (w(), m("button", {
|
|
177
181
|
key: 0,
|
|
178
182
|
type: "button",
|
|
179
183
|
class: "v-textarea-action v-field-action v-textarea-icon-end",
|
|
180
|
-
"aria-label":
|
|
181
|
-
disabled:
|
|
182
|
-
onClick:
|
|
183
|
-
}, [
|
|
184
|
-
], 12,
|
|
185
|
-
_
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
class: "v-textarea-hint"
|
|
191
|
-
}, {
|
|
192
|
-
default: O(() => [h(E(_.hint), 1)]),
|
|
193
|
-
_: 1
|
|
194
|
-
}, 8, ["id"])) : f("", !0), _.counter ? (C(), p("span", {
|
|
195
|
-
key: 1,
|
|
196
|
-
id: D(oe),
|
|
184
|
+
"aria-label": v.iconEndLabel ?? O(t)(v.iconEnd),
|
|
185
|
+
disabled: v.disabled,
|
|
186
|
+
onClick: a[3] ||= (e) => B("click:icon-end", e)
|
|
187
|
+
}, [_(r, S(y(O(n)(v.iconEnd))), null, 16)], 8, I)) : v.iconEnd ? (w(), f(r, x({ key: 1 }, O(n)(v.iconEnd), { class: "v-textarea-icon-end" }), null, 16)) : p("", !0)], void 0, 4)
|
|
188
|
+
], 12, M)]),
|
|
189
|
+
_: 2
|
|
190
|
+
}, [v.counter ? {
|
|
191
|
+
name: "meta",
|
|
192
|
+
fn: A(({ id: e }) => [h("span", {
|
|
193
|
+
id: e,
|
|
197
194
|
class: "v-textarea-counter v-field-counter",
|
|
198
|
-
"data-over":
|
|
199
|
-
},
|
|
200
|
-
|
|
195
|
+
"data-over": O(ne) ? "" : void 0
|
|
196
|
+
}, D(O(te)), 9, L)]),
|
|
197
|
+
key: "0"
|
|
198
|
+
} : void 0]), 1040, [
|
|
199
|
+
"class",
|
|
200
|
+
"style",
|
|
201
|
+
"label",
|
|
202
|
+
"hint",
|
|
203
|
+
"error",
|
|
204
|
+
"required",
|
|
205
|
+
"disabled",
|
|
206
|
+
"hide-label",
|
|
207
|
+
"label-position"
|
|
208
|
+
]));
|
|
201
209
|
}
|
|
202
210
|
});
|
|
203
211
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VTextarea.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VTextarea/VTextarea.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * Native textarea owns editing and validity. JavaScript bridges the model, text limits and\n * clear-button focus; CSS controls optional content-based height.\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 { useClearable } from '../../composables/useClearable'\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\n/** The height of one line: 32, 40 or 48 pixels. */\nexport type TextareaSize = 'sm' | 'md' | 'lg'\n\ninterface TextareaProps {\n /** The size of the field, which sets its padding, its type scale and its icons. */\n size?: TextareaSize\n /**\n * Takes 4px off the field by tightening its padding, leaving the number of lines,\n * the type and the icons alone.\n */\n compact?: boolean\n /**\n * How many lines of text the field shows: the native `rows` attribute, which gives the field\n * its height.\n */\n rows?: number\n /**\n * Lets the field grow as the text is typed, instead of scrolling inside the height `rows`\n * gives it, which stays its starting height.\n */\n autoGrow?: boolean\n /**\n * Marks the field as invalid whatever the browser thinks: the route for a rule\n * only the server can check.\n */\n invalid?: boolean\n /** Makes the field unusable, greyed out through the colour tokens. */\n disabled?: boolean\n /**\n * Shows the text without allowing it to be changed. The field can still be focused\n * and copied from, and the clear button is hidden.\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, tied to the textarea for assistive technology so\n * that 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 a real\n * button as soon as a `@click:icon-start` listener is attached, in which case it needs\n * `iconStartLabel`.\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 design\n * system dictionary.\n */\n loadingText?: 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 from its own\n * content (a read-only field included).\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 goes into\n * error instead of silently refusing the keystrokes.\n */\n softLimit?: boolean\n /**\n * Shows how much has been typed, under the field: \"12/80\" against a limit, or just\n * \"12\" without one.\n */\n counter?: boolean\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<TextareaProps>(), {\n size: 'md',\n compact: false,\n rows: 5,\n autoGrow: false,\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 loadingText: 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, as in VInput.\n */\n start?(): unknown\n /**\n * Content at the end of the field, which replaces `iconEnd`. It is hidden while the\n * field is loading, the spinner taking that place.\n */\n end?(): unknown\n /**\n * Controls of your own inside the field, placed before the field's own: the clear cross and\n * the end icon.\n */\n 'value-end'?(): unknown\n}>()\n\n/** The text in the field, empty to begin with. */\nconst model = defineModel<string>({ default: '' })\n\n// HTML wants `rows` to be a positive integer, and it drops anything else on the floor:\n// a 0, a negative or a fractional value would leave the browser falling back to its own\n// default of two rows, which is neither what was asked for nor this component's default.\n// Rounding and flooring here is what keeps the prop's contract out of the parser's hands.\nconst resolvedRows = computed(() => Math.max(1, Math.round(props.rows)))\n\n// `class` and `style` stay on the wrapper, where a consumer expects to style the\n// field; every other attribute goes to the textarea, where it does something.\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 resolvedClearLabel = computed(() => props.clearLabel ?? m.value.common.clear)\n\nconst { fieldId, hintId, counterId, describedBy } = useFieldIds(\n attrs,\n () => !!props.hint,\n () => props.counter,\n)\n\n// Every length measurement goes through this projection: a value straight from an API or\n// a database is often `null`, and reading `.length` on it would throw at mount.\nconst modelText = computed(() => model.value ?? '')\n\nconst { hasIconStartHandler, hasIconEndHandler } = useIconClickHandlers({\n name: 'VTextarea',\n iconStartLabel: props.iconStartLabel,\n iconEndLabel: props.iconEndLabel,\n})\n\nconst controlEl = ref<HTMLTextAreaElement | null>(null)\n\nconst { showClear, onClear } = useClearable({\n clearable: () => props.clearable,\n clearVisible: () => props.clearVisible,\n disabled: () => props.disabled,\n readonly: () => props.readonly,\n text: () => modelText.value,\n controlEl,\n onCleared: () => {\n model.value = ''\n emit('clear')\n },\n})\n\nconst { counterText, over } = useTextLimit({\n el: controlEl,\n text: () => modelText.value,\n maxlength: () => props.maxlength,\n softLimit: () => props.softLimit,\n})\n\ndefineExpose({\n /** Moves the focus to the real textarea. */\n focus: (options?: FocusOptions) => controlEl.value?.focus(options),\n /** Selects everything in the field. */\n select: () => controlEl.value?.select(),\n /** The real `<textarea>`, for what neither of the two above covers. */\n el: controlEl,\n})\n</script>\n\n<template>\n <div\n class=\"v-textarea 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-textarea-label\" :for=\"fieldId\">\n {{ label }}\n </VTypography>\n\n <div\n class=\"v-textarea-field\"\n :style=\"{ '--textarea-rows': resolvedRows }\"\n :data-auto-grow=\"autoGrow ? '' : undefined\"\n >\n <!--\n The start icon is rendered before the slot, where the end icon is the slot's own\n fallback. The asymmetry is VInput's, mirrored here so the two fields answer the same\n way: what a composed field puts in that zone is OTHER content beside the icon, not\n another way of drawing it.\n -->\n <button\n v-if=\"iconStart && hasIconStartHandler\"\n type=\"button\"\n class=\"v-textarea-action v-field-action v-textarea-icon-start\"\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)\" class=\"v-textarea-icon-start\" />\n <slot name=\"start\" />\n\n <textarea\n :id=\"fieldId\"\n ref=\"controlEl\"\n v-model=\"model\"\n :aria-invalid=\"invalid || undefined\"\n v-bind=\"restAttrs\"\n class=\"v-textarea-control\"\n :rows=\"resolvedRows\"\n :maxlength=\"softLimit ? undefined : maxlength\"\n :disabled=\"disabled\"\n :readonly=\"readonly || undefined\"\n :aria-describedby=\"describedBy\"\n />\n\n <slot name=\"value-end\" />\n\n <button\n v-if=\"showClear\"\n type=\"button\"\n class=\"v-textarea-action v-field-action v-textarea-clear\"\n :aria-label=\"resolvedClearLabel\"\n @click=\"onClear\"\n >\n <VIcon :name=\"closeIcon\" />\n </button>\n\n <VSpinner v-if=\"loading\" :label=\"loadingText\" />\n <slot v-else name=\"end\">\n <button\n v-if=\"iconEnd && hasIconEndHandler\"\n type=\"button\"\n class=\"v-textarea-action v-field-action v-textarea-icon-end\"\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)\" class=\"v-textarea-icon-end\" />\n </slot>\n </div>\n\n <div v-if=\"hint || counter\" class=\"v-textarea-meta v-field-meta\">\n <VTypography v-if=\"hint\" :id=\"hintId\" variant=\"caption\" tone=\"muted\" class=\"v-textarea-hint\">\n {{ hint }}\n </VTypography>\n <span\n v-if=\"counter\"\n :id=\"counterId\"\n class=\"v-textarea-counter v-field-counter\"\n :data-over=\"over ? '' : undefined\"\n >\n {{ counterText }}\n </span>\n </div>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-textarea {\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 /*\n * The .v-textarea-label and .v-textarea-hint classes remain as hooks: a consumer overrides\n * through them, and the disabled state below reaches them that way.\n */\n\n /*\n * This is the box that carries the border, the background, the focus ring and the resize\n * handle; which is why it also hides its overflow, `resize` having no effect on a box whose\n * overflow is visible. `--field-border-color` is the single source of truth for its colour,\n * and the hover, error and disabled states do nothing but redefine it.\n */\n .v-textarea-field {\n --field-border-color: var(--vectis-color-border-strong);\n\n /*\n * Nothing here restates the size scale: the `--control-*` variables are inherited from the\n * v-control root (styles/control-size.css), the icon context included. The field carries no\n * height of its own: it is the `rows` attribute on the textarea that sets one, and the\n * field is simply as tall as the control it wraps.\n */\n\n /*\n * The leading is named once and feeds two things that have to agree by construction: the\n * field's own `line-height`, and the first line box below, against which everything sitting\n * beside the text is offset.\n */\n --textarea-leading: var(--vectis-text-body-md-leading);\n\n /*\n * It is DERIVED and must never be written as `1lh`. The buttons happened to be right only\n * because the reset gives them `font: inherit`.\n */\n --textarea-line: calc(var(--control-font-size) * var(--textarea-leading));\n\n display: flex;\n align-items: flex-start;\n gap: var(--control-gap);\n padding-inline: var(--control-padding-inline-field);\n /*\n * Derive padding from control height minus borders and one line. Read the compact-adjusted\n * height so rows=1 matches VInput and each additional row adds one line.\n */\n padding-block: calc((var(--control-height) - 2px - var(--textarea-line)) / 2);\n background: var(--vectis-color-surface);\n color: var(--vectis-color-text);\n border: 1px solid var(--field-border-color);\n /*\n * The cap is what carries the VInput identity above into the OTHER row counts, and it has\n * to stay derived from --control-height. A browser scales down any radius it cannot fit, so\n * on a one-row field a pill override is already painted as half the control height; min()\n * applies that same reduction to a field that is taller.\n */\n border-radius: min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));\n font-size: var(--control-font-size);\n /* Text running over several lines takes the body line height. The `control` type\n role, whose lines are set tight against one another, only makes sense for a\n single-line label. */\n line-height: var(--textarea-leading);\n resize: vertical;\n overflow: hidden;\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-textarea-control {\n flex: 1;\n min-width: 0;\n align-self: stretch;\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 resize: none;\n }\n\n .v-textarea-control::placeholder {\n color: var(--vectis-color-text-subtle);\n }\n\n /*\n * The margin is SYMMETRIC, the VToast rule. It looks redundant under\n * `align-items: flex-start`, where only the start side moves anything, but the end side is\n * what keeps the item's OUTER box down to one line box.\n */\n .v-textarea-field > .v-icon,\n .v-textarea-field > .v-spinner {\n margin-block: calc((var(--textarea-line) - var(--vectis-icon-size)) / 2);\n }\n\n .v-textarea-field > .v-textarea-action {\n margin-block: calc((var(--textarea-line) - var(--control-action-size)) / 2);\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-textarea-field > .v-icon {\n color: var(--vectis-color-text-muted);\n }\n\n .v-textarea-field > .v-spinner {\n font-size: var(--vectis-icon-size);\n }\n\n /*\n * This block must stay first in the sequence of states: read-only, then hover, focus, invalid\n * and disabled. The read-only, focus, invalid and disabled selectors all weigh (0,3,0),\n * `:has()` taking the specificity of what it contains, so nothing but the source order\n * arbitrates between them.\n */\n .v-textarea[data-readonly] .v-textarea-field {\n --field-border-color: var(--vectis-color-border);\n\n background: var(--vectis-color-surface-sunken);\n }\n\n .v-textarea-field:hover:not(:has(.v-textarea-control:focus)):not(\n :has(\n .v-textarea-control:disabled,\n .v-textarea-control:user-invalid,\n .v-textarea-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 /*\n * The selector watches the control's focus and not `:focus-within`, so that when one of the\n * field's own buttons takes keyboard focus, only that button's outline lights up: two\n * indicators at once would be unreadable. And it is `:focus` rather than `:focus-visible`,\n * because a text field shows its focus even when it was reached with the mouse.\n */\n .v-textarea-field:has(.v-textarea-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 /*\n * Only the colour variable is changed, which is why the border and the focus ring both turn\n * red without either being restated.\n */\n .v-textarea-field:has(.v-textarea-control:user-invalid),\n .v-textarea-field:has(.v-textarea-control[aria-invalid='true']) {\n --field-border-color: var(--vectis-color-danger);\n }\n\n /*\n * A disabled field greys out through the colour tokens, the same ones VCheckbox and VRadio\n * use, and never through opacity. It comes last in the sequence of states, which at equal\n * specificity is what makes it win over all of them, the error included: a disabled field is\n * not submitted, so it has nothing to report.\n */\n .v-textarea[data-disabled] .v-textarea-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 resize: none;\n }\n\n .v-textarea[data-disabled] .v-textarea-label,\n .v-textarea[data-disabled] .v-textarea-hint,\n .v-textarea[data-disabled] .v-textarea-counter {\n color: var(--vectis-color-text-subtle);\n }\n\n .v-textarea[data-disabled] .v-textarea-action,\n .v-textarea[data-disabled] .v-textarea-field > .v-icon {\n color: inherit;\n cursor: not-allowed;\n }\n\n .v-textarea-control:disabled {\n cursor: not-allowed;\n }\n\n /*\n * A browser without support keeps the fixed height and its scrollbar, which is the intended\n * fallback.\n */\n .v-textarea-field[data-auto-grow] {\n resize: none;\n }\n\n /*\n * It is scoped to this branch and must not be lifted onto the control at large: a floor there\n * would stop the control shrinking with the resize handle, and the field, which hides its\n * overflow, would clip it instead of scrolling.\n */\n .v-textarea-field[data-auto-grow] .v-textarea-control {\n field-sizing: content;\n min-block-size: calc(var(--textarea-rows) * var(--textarea-line));\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-textarea-field {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VTextarea.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VTextarea/VTextarea.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * Native textarea owns editing and validity. JavaScript bridges the model, text limits and\n * clear-button focus; CSS controls optional content-based height.\n */\nimport { computed, ref } from 'vue'\n\nimport VField from '../VField/VField.vue'\nimport type { FieldControlProps, FieldLabelPosition } from '../VField/VField.vue'\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'\n\nimport { useClearable } from '../../composables/useClearable'\nimport { useIconClickHandlers } from '../../composables/useIconClickHandlers'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useTextLimit } from '../../composables/useTextLimit'\nimport { useMessages } from '../../i18n/state'\n\n/** The height of one line: 32, 40 or 48 pixels. */\nexport type TextareaSize = 'sm' | 'md' | 'lg'\n\ninterface TextareaProps {\n /** The size of the field, which sets its padding, its type scale and its icons. */\n size?: TextareaSize\n /**\n * Takes 4px off the field by tightening its padding, leaving the number of lines,\n * the type and the icons alone.\n */\n compact?: boolean\n /**\n * How many lines of text the field shows: the native `rows` attribute, which gives the field\n * its height.\n */\n rows?: number\n /**\n * Lets the field grow as the text is typed, instead of scrolling inside the height `rows`\n * gives it, which stays its starting height.\n */\n autoGrow?: boolean\n /**\n * Marks the field as invalid whatever the browser thinks: the route for a rule\n * only the server can check.\n */\n invalid?: boolean\n /** Makes the field unusable, greyed out through the colour tokens. */\n disabled?: boolean\n /**\n * Shows the text without allowing it to be changed. The field can still be focused\n * and copied from, and the clear button is hidden.\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, tied to the textarea for assistive technology so\n * that it is read out along with the label.\n */\n hint?: string\n /**\n * A message saying what is wrong with the value, shown in place of the hint so that the field\n * does not grow. It marks the field invalid, is read along with it, and is announced when it\n * appears or changes.\n */\n error?: string\n /** Marks the field as required: an asterisk follows the label, and the textarea is `required`. */\n required?: boolean\n /** Hides the label visually. It still names the field for assistive technology. */\n hideLabel?: boolean\n /**\n * Where the label sits: above the field (`top`, the default), or at its start, in a column of\n * its own, moving back above when there is not room for both.\n */\n labelPosition?: FieldLabelPosition\n /**\n * An icon inside the field, at the start. It is decorative by default and becomes a real\n * button as soon as a `@click:icon-start` listener is attached, in which case it needs\n * `iconStartLabel`.\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 design\n * system dictionary.\n */\n loadingText?: 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 from its own\n * content (a read-only field included).\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 goes into\n * error instead of silently refusing the keystrokes.\n */\n softLimit?: boolean\n /**\n * Shows how much has been typed, under the field: \"12/80\" against a limit, or just\n * \"12\" without one.\n */\n counter?: boolean\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<TextareaProps>(), {\n size: 'md',\n compact: false,\n rows: 5,\n autoGrow: false,\n invalid: false,\n disabled: false,\n readonly: false,\n label: undefined,\n hint: undefined,\n error: undefined,\n required: false,\n hideLabel: false,\n labelPosition: 'top',\n iconStart: undefined,\n iconEnd: undefined,\n iconStartLabel: undefined,\n iconEndLabel: undefined,\n loading: false,\n loadingText: 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, as in VInput.\n */\n start?(): unknown\n /**\n * Content at the end of the field, which replaces `iconEnd`. It is hidden while the\n * field is loading, the spinner taking that place.\n */\n end?(): unknown\n /**\n * Controls of your own inside the field, placed before the field's own: the clear cross and\n * the end icon.\n */\n 'value-end'?(): unknown\n}>()\n\n/** The text in the field, empty to begin with. */\nconst model = defineModel<string>({ default: '' })\n\n// HTML wants `rows` to be a positive integer, and it drops anything else on the floor:\n// a 0, a negative or a fractional value would leave the browser falling back to its own\n// default of two rows, which is neither what was asked for nor this component's default.\n// Rounding and flooring here is what keeps the prop's contract out of the parser's hands.\nconst resolvedRows = computed(() => Math.max(1, Math.round(props.rows)))\n\n// `class` and `style` stay on the wrapper, where a consumer expects to style the\n// field; every other attribute goes to the textarea, where it does something.\nconst { 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 resolvedClearLabel = computed(() => props.clearLabel ?? m.value.common.clear)\n\n// Every length measurement goes through this projection: a value straight from an API or\n// a database is often `null`, and reading `.length` on it would throw at mount.\nconst modelText = computed(() => model.value ?? '')\n\nconst { hasIconStartHandler, hasIconEndHandler } = useIconClickHandlers({\n name: 'VTextarea',\n iconStartLabel: props.iconStartLabel,\n iconEndLabel: props.iconEndLabel,\n})\n\nconst controlEl = ref<HTMLTextAreaElement | null>(null)\n\nconst { showClear, onClear } = useClearable({\n clearable: () => props.clearable,\n clearVisible: () => props.clearVisible,\n disabled: () => props.disabled,\n readonly: () => props.readonly,\n text: () => modelText.value,\n controlEl,\n onCleared: () => {\n model.value = ''\n emit('clear')\n },\n})\n\nconst { counterText, over } = useTextLimit({\n el: controlEl,\n text: () => modelText.value,\n maxlength: () => props.maxlength,\n softLimit: () => props.softLimit,\n})\n\n/** The attributes of the textarea, built on VField's: the consumer's win over `invalid`. */\nfunction textareaAttrs(fieldProps: FieldControlProps): FieldControlProps {\n return { 'aria-invalid': props.invalid ? 'true' : undefined, ...fieldProps }\n}\n\ndefineExpose({\n /** Moves the focus to the real textarea. */\n focus: (options?: FocusOptions) => controlEl.value?.focus(options),\n /** Selects everything in the field. */\n select: () => controlEl.value?.select(),\n /** The real `<textarea>`, for what neither of the two above covers. */\n el: controlEl,\n})\n</script>\n\n<template>\n <VField\n v-bind=\"restAttrs\"\n class=\"v-textarea\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :label=\"label\"\n :hint=\"hint\"\n :error=\"error\"\n :required=\"required\"\n :disabled=\"disabled\"\n :hide-label=\"hideLabel\"\n :label-position=\"labelPosition\"\n >\n <template #default=\"{ fieldProps }\">\n <div\n class=\"v-textarea-field v-control\"\n :style=\"{ '--textarea-rows': resolvedRows }\"\n :data-size=\"size\"\n :data-compact=\"compact ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n :data-readonly=\"readonly ? '' : undefined\"\n :data-auto-grow=\"autoGrow ? '' : undefined\"\n >\n <!--\n The start icon is rendered before the slot, where the end icon is the slot's own\n fallback. The asymmetry is VInput's, mirrored here so the two fields answer the same\n way: what a composed field puts in that zone is OTHER content beside the icon, not\n another way of drawing it.\n -->\n <button\n v-if=\"iconStart && hasIconStartHandler\"\n type=\"button\"\n class=\"v-textarea-action v-field-action v-textarea-icon-start\"\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)\" class=\"v-textarea-icon-start\" />\n <slot name=\"start\" />\n\n <!-- The label's `for` matches the id inside fieldProps, which the rule cannot follow. -->\n <!-- eslint-disable-next-line vuejs-accessibility/form-control-has-label -->\n <textarea\n ref=\"controlEl\"\n v-model=\"model\"\n v-bind=\"textareaAttrs(fieldProps)\"\n class=\"v-textarea-control\"\n :rows=\"resolvedRows\"\n :maxlength=\"softLimit ? undefined : maxlength\"\n :disabled=\"disabled\"\n :readonly=\"readonly || undefined\"\n />\n\n <slot name=\"value-end\" />\n\n <button\n v-if=\"showClear\"\n type=\"button\"\n class=\"v-textarea-action v-field-action v-textarea-clear\"\n :aria-label=\"resolvedClearLabel\"\n @click=\"onClear\"\n >\n <VIcon :name=\"closeIcon\" />\n </button>\n\n <VSpinner v-if=\"loading\" :label=\"loadingText\" />\n <slot v-else name=\"end\">\n <button\n v-if=\"iconEnd && hasIconEndHandler\"\n type=\"button\"\n class=\"v-textarea-action v-field-action v-textarea-icon-end\"\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)\" class=\"v-textarea-icon-end\" />\n </slot>\n </div>\n </template>\n <template v-if=\"counter\" #meta=\"{ id }\">\n <span :id=\"id\" class=\"v-textarea-counter v-field-counter\" :data-over=\"over ? '' : undefined\">\n {{ counterText }}\n </span>\n </template>\n </VField>\n</template>\n\n<style>\n@layer vectis.components {\n /* The root is a VField, which lays out the label, the hint and the error. */\n .v-textarea {\n width: 100%;\n }\n\n /*\n * This is the box that carries the border, the background, the focus ring and the resize\n * handle; which is why it also hides its overflow, `resize` having no effect on a box whose\n * overflow is visible. `--field-border-color` is the single source of truth for its colour,\n * and the hover, error and disabled states do nothing but redefine it.\n */\n .v-textarea-field {\n --field-border-color: var(--vectis-color-border-strong);\n\n /*\n * Nothing here restates the size scale: the `--control-*` variables come from the v-control\n * class on this box (styles/control-size.css), the icon context included. The field carries no\n * height of its own: it is the `rows` attribute on the textarea that sets one, and the\n * field is simply as tall as the control it wraps.\n */\n\n /*\n * The leading is named once and feeds two things that have to agree by construction: the\n * field's own `line-height`, and the first line box below, against which everything sitting\n * beside the text is offset.\n */\n --textarea-leading: var(--vectis-text-body-md-leading);\n\n /*\n * Derived rather than written as `1lh`: a custom property resolves `lh` where it is used, so\n * the icons and buttons beside the text would each measure their own line height.\n */\n --textarea-line: calc(var(--control-font-size) * var(--textarea-leading));\n\n display: flex;\n align-items: flex-start;\n gap: var(--control-gap);\n padding-inline: var(--control-padding-inline-field);\n /*\n * Derive padding from control height minus borders and one line. Read the compact-adjusted\n * height so rows=1 matches VInput and each additional row adds one line.\n */\n padding-block: calc((var(--control-height) - 2px - var(--textarea-line)) / 2);\n background: var(--vectis-color-surface);\n color: var(--vectis-color-text);\n border: 1px solid var(--field-border-color);\n /*\n * The cap is what carries the VInput identity above into the OTHER row counts, and it has\n * to stay derived from --control-height. A browser scales down any radius it cannot fit, so\n * on a one-row field a pill override is already painted as half the control height; min()\n * applies that same reduction to a field that is taller.\n */\n border-radius: min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));\n font-size: var(--control-font-size);\n /* Text running over several lines takes the body line height. The `control` type\n role, whose lines are set tight against one another, only makes sense for a\n single-line label. */\n line-height: var(--textarea-leading);\n resize: vertical;\n overflow: hidden;\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-textarea-control {\n flex: 1;\n min-width: 0;\n align-self: stretch;\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 resize: none;\n }\n\n .v-textarea-control::placeholder {\n color: var(--vectis-color-text-subtle);\n }\n\n /*\n * The margin is SYMMETRIC, the VToast rule. It looks redundant under\n * `align-items: flex-start`, where only the start side moves anything, but the end side is\n * what keeps the item's OUTER box down to one line box.\n */\n .v-textarea-field > .v-icon,\n .v-textarea-field > .v-spinner {\n margin-block: calc((var(--textarea-line) - var(--vectis-icon-size)) / 2);\n }\n\n .v-textarea-field > .v-textarea-action {\n margin-block: calc((var(--textarea-line) - var(--control-action-size)) / 2);\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-textarea-field > .v-icon {\n color: var(--vectis-color-text-muted);\n }\n\n .v-textarea-field > .v-spinner {\n font-size: var(--vectis-icon-size);\n }\n\n /*\n * This block must stay first in the sequence of states: read-only, then hover, focus, invalid\n * and disabled. The read-only, focus, invalid and disabled selectors all weigh (0,3,0),\n * `:has()` taking the specificity of what it contains, so nothing but the source order\n * arbitrates between them.\n */\n .v-textarea .v-textarea-field[data-readonly] {\n --field-border-color: var(--vectis-color-border);\n\n background: var(--vectis-color-surface-sunken);\n }\n\n .v-textarea-field:hover:not(:has(.v-textarea-control:focus)):not(\n :has(\n .v-textarea-control:disabled,\n .v-textarea-control:user-invalid,\n .v-textarea-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 /*\n * The selector watches the control's focus and not `:focus-within`, so that when one of the\n * field's own buttons takes keyboard focus, only that button's outline lights up: two\n * indicators at once would be unreadable. And it is `:focus` rather than `:focus-visible`,\n * because a text field shows its focus even when it was reached with the mouse.\n */\n .v-textarea-field:has(.v-textarea-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 /*\n * Only the colour variable is changed, which is why the border and the focus ring both turn\n * red without either being restated.\n */\n .v-textarea-field:has(.v-textarea-control:user-invalid),\n .v-textarea-field:has(.v-textarea-control[aria-invalid='true']) {\n --field-border-color: var(--vectis-color-danger);\n }\n\n /*\n * A disabled field greys out through the colour tokens, the same ones VCheckbox and VRadio\n * use, and never through opacity. It comes last in the sequence of states, which at equal\n * specificity is what makes it win over all of them, the error included: a disabled field is\n * not submitted, so it has nothing to report.\n */\n .v-textarea .v-textarea-field[data-disabled] {\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 resize: none;\n }\n\n .v-textarea[data-disabled] .v-textarea-counter {\n color: var(--vectis-color-text-subtle);\n }\n\n .v-textarea-field[data-disabled] .v-textarea-action,\n .v-textarea-field[data-disabled] > .v-icon {\n color: inherit;\n cursor: not-allowed;\n }\n\n .v-textarea-control:disabled {\n cursor: not-allowed;\n }\n\n /*\n * A browser without support keeps the fixed height and its scrollbar, which is the intended\n * fallback.\n */\n .v-textarea-field[data-auto-grow] {\n resize: none;\n }\n\n /*\n * It is scoped to this branch and must not be lifted onto the control at large: a floor there\n * would stop the control shrinking with the resize handle, and the field, which hides its\n * overflow, would clip it instead of scrolling.\n */\n .v-textarea-field[data-auto-grow] .v-textarea-control {\n field-sizing: content;\n min-block-size: calc(var(--textarea-rows) * var(--textarea-line));\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-textarea-field {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IconSource } from '../VIcon/types.js';
|
|
2
|
+
import { FieldLabelPosition } from '../VField/VField.js';
|
|
2
3
|
import { TimePickerFormat } from '../VTimePicker/VTimePicker.js';
|
|
3
4
|
import { TimePickerAllowed } from '../VTimePicker/limits.js';
|
|
4
5
|
/**
|
|
@@ -67,6 +68,21 @@ interface TimeInputProps {
|
|
|
67
68
|
label?: string;
|
|
68
69
|
/** A line of help under the field. */
|
|
69
70
|
hint?: string;
|
|
71
|
+
/**
|
|
72
|
+
* A message saying what is wrong with the value, shown in place of the hint so that the field
|
|
73
|
+
* does not grow. It marks the field invalid, is read along with it, and is announced when it
|
|
74
|
+
* appears or changes.
|
|
75
|
+
*/
|
|
76
|
+
error?: string;
|
|
77
|
+
/** Marks the field as required: an asterisk follows the label, and the field is `required`. */
|
|
78
|
+
required?: boolean;
|
|
79
|
+
/** Hides the label visually. It still names the field for assistive technology. */
|
|
80
|
+
hideLabel?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Where the label sits: above the field (`top`, the default), or at its start, in a column of
|
|
83
|
+
* its own, moving back above when there is not room for both.
|
|
84
|
+
*/
|
|
85
|
+
labelPosition?: FieldLabelPosition;
|
|
70
86
|
/** What the field says while empty. */
|
|
71
87
|
placeholder?: string;
|
|
72
88
|
/** The height of the field: 32, 40 or 48 pixels. */
|
|
@@ -94,7 +110,7 @@ interface TimeInputProps {
|
|
|
94
110
|
* What the clock button does, in words. It names the button `pickerIcon` renders,
|
|
95
111
|
* and falls back to the design system dictionary.
|
|
96
112
|
*/
|
|
97
|
-
|
|
113
|
+
pickerLabel?: string;
|
|
98
114
|
/**
|
|
99
115
|
* Shows a spinner at the end of the field, in place of the clock icon. It says that
|
|
100
116
|
* something is being loaded and changes nothing else: the field can still be typed
|
|
@@ -164,25 +180,29 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {
|
|
|
164
180
|
loading: boolean;
|
|
165
181
|
label: string;
|
|
166
182
|
placeholder: string;
|
|
183
|
+
format: TimePickerFormat;
|
|
184
|
+
pickerLabel: string;
|
|
185
|
+
error: string;
|
|
167
186
|
size: TimeInputSize;
|
|
168
|
-
placement: TimeInputPlacement;
|
|
169
|
-
mode: TimeInputMode;
|
|
170
187
|
compact: boolean;
|
|
171
|
-
disabled: boolean;
|
|
172
188
|
iconStart: IconSource;
|
|
189
|
+
disabled: boolean;
|
|
190
|
+
required: boolean;
|
|
191
|
+
placement: TimeInputPlacement;
|
|
192
|
+
mode: TimeInputMode;
|
|
173
193
|
invalid: boolean;
|
|
174
194
|
hint: string;
|
|
195
|
+
hideLabel: boolean;
|
|
196
|
+
labelPosition: FieldLabelPosition;
|
|
175
197
|
readonly: boolean;
|
|
176
198
|
iconStartLabel: string;
|
|
177
199
|
loadingText: string;
|
|
178
200
|
clearable: boolean;
|
|
179
201
|
clearLabel: string;
|
|
180
|
-
max: string;
|
|
181
|
-
format: TimePickerFormat;
|
|
182
202
|
min: string;
|
|
203
|
+
max: string;
|
|
183
204
|
locale: string;
|
|
184
205
|
showPicker: boolean;
|
|
185
|
-
pickerIconLabel: string;
|
|
186
206
|
pickerIcon: IconSource;
|
|
187
207
|
minuteStep: number;
|
|
188
208
|
allowedHours: TimePickerAllowed;
|