@livestorm/ui-vue 2.0.5 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -6
- package/components-vite.js +2 -2
- package/dist/UiButton-uyW8EHRJ.mjs +602 -0
- package/dist/UiTimelineItem-EiOEi1yF.mjs +7293 -0
- package/dist/UiTooltip-DZcPD6_N.mjs +158 -0
- package/dist/a11y-CaZxRWzo.mjs +6 -0
- package/dist/breakpoints.mjs +4 -9
- package/dist/bus.mjs +5 -5
- package/dist/components.mjs +236 -222
- package/dist/i18n-B8QOMuFD.mjs +46 -0
- package/dist/index.mjs +4 -87
- package/dist/integrations.mjs +3 -14
- package/dist/layouts.mjs +228 -236
- package/dist/responsive.mjs +31 -36
- package/dist/slot.mjs +11 -17
- package/dist/toastDSV2-D3xDZPe5.mjs +105 -0
- package/dist/types/index.d.ts +23 -1
- package/dist/types/src/components/Toast/ToastMessage.vue.d.ts +17 -7
- package/dist/types/src/components/Toast/toastDSV2.d.ts +89 -64
- package/dist/types/src/components/UiActionBar/UiActionBar.vue.d.ts +3 -1
- package/dist/types/src/components/UiActionBar/UiActionBarItem.vue.d.ts +18 -3
- package/dist/types/src/components/UiActionBar/types.d.ts +5 -1
- package/dist/types/src/components/UiAvatar/UiAvatar.vue.d.ts +4 -2
- package/dist/types/src/components/UiAvatarList/UiAvatarList.vue.d.ts +3 -2
- package/dist/types/src/components/UiBanner/UiBanner.vue.d.ts +13 -1
- package/dist/types/src/components/UiButton/UiButton.vue.d.ts +102 -38
- package/dist/types/src/components/UiButtonGroup/UiButtonGroup.vue.d.ts +8 -2
- package/dist/types/src/components/UiButtonGroup/UiButtonGroupItem.vue.d.ts +3 -0
- package/dist/types/src/components/UiButtonGroup/types.d.ts +5 -1
- package/dist/types/src/components/UiChoice/UiChoice.vue.d.ts +71 -0
- package/dist/types/src/components/UiChoice/index.d.ts +2 -0
- package/dist/types/src/components/UiChoice/types.d.ts +7 -0
- package/dist/types/src/components/UiColorField/UiColorField.vue.d.ts +1 -1
- package/dist/types/src/components/UiColorPicker/UiColorPicker.vue.d.ts +2 -2
- package/dist/types/src/components/UiCombobox/UiCombobox.types.d.ts +47 -0
- package/dist/types/src/components/UiCombobox/UiCombobox.vue.d.ts +40 -0
- package/dist/types/src/components/UiCombobox/index.d.ts +2 -0
- package/dist/types/src/components/UiDataTable/UiDataTable.types.d.ts +46 -0
- package/dist/types/src/components/UiDataTable/UiDataTable.vue.d.ts +136 -0
- package/dist/types/src/components/UiDataTable/index.d.ts +5 -0
- package/dist/types/src/components/UiDrawer/UiDrawer.vue.d.ts +28 -0
- package/dist/types/src/components/UiDrawer/UiDrawerContent.vue.d.ts +18 -0
- package/dist/types/src/components/UiDrawer/UiDrawerTrigger.vue.d.ts +14 -0
- package/dist/types/src/components/UiDropdown/DropdownItemCheckbox.vue.d.ts +3 -0
- package/dist/types/src/components/UiDropdown/UiDropdownContent.vue.d.ts +10 -0
- package/dist/types/src/components/UiDropdown/UiDropdownGroup.vue.d.ts +17 -0
- package/dist/types/src/components/UiDropdown/UiDropdownItem.vue.d.ts +9 -4
- package/dist/types/src/components/UiDropdown/UiDropdownTrigger.vue.d.ts +21 -5
- package/dist/types/src/components/UiDropdown/index.d.ts +1 -0
- package/dist/types/src/components/UiEmojiPickerList/UiEmojiPickerList.vue.d.ts +22 -0
- package/dist/types/src/components/UiEmptyState/UiEmptyState.vue.d.ts +8 -3
- package/dist/types/src/components/UiFieldWrapper/UiFieldWrapper.vue.d.ts +2 -2
- package/dist/types/src/components/UiInputCheckbox/CheckboxGlyph.vue.d.ts +17 -0
- package/dist/types/src/components/UiInputCheckbox/UiInputCheckbox.vue.d.ts +35 -4
- package/dist/types/src/components/UiInputEmoji/UiInputEmoji.vue.d.ts +45 -0
- package/dist/types/src/components/UiInputRadio/RadioGlyph.vue.d.ts +19 -0
- package/dist/types/src/components/UiInputRadio/UiInputRadio.vue.d.ts +80 -0
- package/dist/types/src/components/UiInputRadio/UiInputRadioGroup.vue.d.ts +86 -0
- package/dist/types/src/components/UiInputRadio/types.d.ts +19 -0
- package/dist/types/src/components/UiInputSelect/UiInputSelect.vue.d.ts +5 -5
- package/dist/types/src/components/UiInputTextarea/UiInputTextarea.vue.d.ts +5 -5
- package/dist/types/src/components/UiListItem/UiListItem.vue.d.ts +18 -4
- package/dist/types/src/components/UiLoader/UiLoader.vue.d.ts +6 -5
- package/dist/types/src/components/UiLoader/UiSpinnerIcon.vue.d.ts +3 -0
- package/dist/types/src/components/UiLogo/UiLogo.vue.d.ts +9 -3
- package/dist/types/src/components/UiMenu/UiMenuContent.vue.d.ts +15 -2
- package/dist/types/src/components/UiMenu/UiMenuItem.vue.d.ts +9 -3
- package/dist/types/src/components/UiNestedOptions/UiNestedOptions.vue.d.ts +13 -0
- package/dist/types/src/components/UiPage/UiPage.vue.d.ts +106 -8
- package/dist/types/src/components/UiPagination/UiPagination.vue.d.ts +36 -0
- package/dist/types/src/components/UiPagination/index.d.ts +2 -0
- package/dist/types/src/components/UiPagination/types.d.ts +4 -0
- package/dist/types/src/components/UiPane/UiPane.vue.d.ts +22 -0
- package/dist/types/src/components/UiPane/UiPaneContent.vue.d.ts +75 -0
- package/dist/types/src/components/UiPane/UiPaneTrigger.vue.d.ts +14 -0
- package/dist/types/src/components/UiPane/index.d.ts +5 -0
- package/dist/types/src/components/UiProgress/UiProgress.vue.d.ts +1 -1
- package/dist/types/src/components/UiRating/UiRating.vue.d.ts +62 -0
- package/dist/types/src/components/UiRating/types.d.ts +1 -0
- package/dist/types/src/components/UiRoomButton/UiRoomButton.vue.d.ts +5 -3
- package/dist/types/src/components/UiRoomCountdown/UiRoomCountdown.vue.d.ts +32 -0
- package/dist/types/src/components/UiShell/UiShell.vue.d.ts +3 -0
- package/dist/types/src/components/UiSideMenu/UiSideMenu.vue.d.ts +22 -1
- package/dist/types/src/components/UiSideMenu/UiSideMenuItemContent.vue.d.ts +2 -2
- package/dist/types/src/components/UiSwitch/UiSwitch.vue.d.ts +114 -0
- package/dist/types/src/components/UiSwitch/types.d.ts +3 -0
- package/dist/types/src/components/UiTable/UiTable.vue.d.ts +13 -4
- package/dist/types/src/components/UiTable/UiTableActionsCell.vue.d.ts +49 -0
- package/dist/types/src/components/UiTable/UiTableActionsHeaderCell.vue.d.ts +3 -0
- package/dist/types/src/components/UiTable/UiTableBody.vue.d.ts +11 -1
- package/dist/types/src/components/UiTable/UiTableCell.vue.d.ts +16 -1
- package/dist/types/src/components/UiTable/UiTableHeaderCell.vue.d.ts +31 -2
- package/dist/types/src/components/UiTable/UiTableRow.vue.d.ts +32 -2
- package/dist/types/src/components/UiTable/context.d.ts +3 -0
- package/dist/types/src/components/UiTable/index.d.ts +4 -0
- package/dist/types/src/components/UiTabs/UiTabs.vue.d.ts +8 -2
- package/dist/types/src/components/UiTag/UiTag.types.d.ts +25 -0
- package/dist/types/src/components/UiTag/UiTag.vue.d.ts +5 -26
- package/dist/types/src/components/UiTag/index.d.ts +2 -1
- package/dist/types/src/components/UiTextField/UiTextField.vue.d.ts +10 -5
- package/dist/types/src/components/UiTooltip/UiTooltipProvider.vue.d.ts +1 -0
- package/dist/types/src/components/UiTooltip/UiTooltipTrigger.vue.d.ts +2 -2
- package/dist/types/src/composables/storedThemingApplies.d.ts +17 -0
- package/dist/types/src/composables/useButtonStyles.d.ts +1 -0
- package/dist/types/src/composables/useChoiceboxSurface.d.ts +11 -0
- package/dist/types/src/composables/useContentMode.d.ts +23 -0
- package/dist/types/src/composables/useControlModes.d.ts +7 -0
- package/dist/types/src/composables/useControlShape.d.ts +24 -0
- package/dist/types/src/composables/useFieldFocusEvents.d.ts +12 -0
- package/dist/types/src/composables/useIconSize.d.ts +13 -0
- package/dist/types/src/composables/usePullGesture.d.ts +42 -0
- package/dist/types/src/composables/useThemeAndModes.d.ts +4 -0
- package/dist/types/src/constants/sizes.d.ts +1 -1
- package/dist/types/src/theming/colorScale.d.ts +165 -0
- package/dist/types/src/theming/legacyColorScale.d.ts +27 -0
- package/dist/types/src/theming/presetColors.d.ts +11 -0
- package/dist/types/src/theming/primitiveTokens.d.ts +2 -0
- package/dist/types/src/utils/effectiveOpacity.d.ts +2 -0
- package/dist/types/src/utils/numbers.d.ts +1 -2
- package/dist/types/src/utils/tokenColor.d.ts +2 -0
- package/dist/ui-vue.css +2 -1
- package/dist/utils.mjs +165 -194
- package/index.d.ts +22 -0
- package/index.js +44 -0
- package/package.json +28 -20
- package/src/components/Toast/LayoutToasts.vue +19 -11
- package/src/components/Toast/ToastMessage.vue +130 -73
- package/src/components/Toast/toastDSV2.ts +238 -67
- package/src/components/UiActionBar/UiActionBar.vue +15 -5
- package/src/components/UiActionBar/UiActionBarItem.vue +65 -38
- package/src/components/UiActionBar/types.ts +16 -1
- package/src/components/UiAvatar/UiAvatar.vue +9 -3
- package/src/components/UiAvatarList/UiAvatarList.vue +51 -20
- package/src/components/UiBadge/UiBadge.vue +1 -1
- package/src/components/UiBanner/UiBanner.vue +77 -27
- package/src/components/UiBreadcrumb/UiBreadcrumb.vue +1 -1
- package/src/components/UiButton/UiButton.vue +96 -29
- package/src/components/UiButtonGroup/UiButtonGroup.vue +22 -16
- package/src/components/UiButtonGroup/UiButtonGroupItem.vue +44 -14
- package/src/components/UiButtonGroup/types.ts +20 -1
- package/src/components/UiCard/UiCard.vue +20 -23
- package/src/components/UiCarousel/UiCarousel.vue +2 -2
- package/src/components/UiChoice/UiChoice.vue +187 -0
- package/src/components/UiChoice/index.ts +2 -0
- package/src/components/UiChoice/types.ts +11 -0
- package/src/components/UiColorField/UiColorField.vue +2 -2
- package/src/components/UiColorPicker/UiColorPicker.vue +16 -13
- package/src/components/UiCombobox/UiCombobox.types.ts +52 -0
- package/src/components/UiCombobox/UiCombobox.vue +296 -0
- package/src/components/UiCombobox/index.ts +2 -0
- package/src/components/UiDataTable/UiDataTable.types.ts +47 -0
- package/src/components/UiDataTable/UiDataTable.vue +422 -0
- package/src/components/UiDataTable/index.ts +12 -0
- package/src/components/UiDialog/UiDialogClose.vue +1 -1
- package/src/components/UiDialog/UiDialogContent.vue +22 -7
- package/src/components/UiDrawer/UiDrawer.vue +16 -0
- package/src/components/UiDrawer/UiDrawerContent.vue +42 -0
- package/src/components/UiDrawer/UiDrawerTrigger.vue +17 -0
- package/src/components/UiDropdown/DropdownItemCheckbox.vue +10 -0
- package/src/components/UiDropdown/UiDropdownContent.vue +32 -21
- package/src/components/UiDropdown/UiDropdownGroup.vue +23 -0
- package/src/components/UiDropdown/UiDropdownItem.vue +45 -18
- package/src/components/UiDropdown/UiDropdownSeparator.vue +1 -1
- package/src/components/UiDropdown/UiDropdownTrigger.vue +139 -45
- package/src/components/UiDropdown/index.ts +1 -0
- package/src/components/UiEmojiPickerList/UiEmojiPickerList.vue +122 -0
- package/src/components/UiEmptyState/UiEmptyState.vue +16 -4
- package/src/components/UiFieldWrapper/UiFieldWrapper.vue +10 -4
- package/src/components/UiHorizontalSeparator/UiHorizontalSeparator.vue +2 -2
- package/src/components/UiInputCheckbox/CheckboxGlyph.vue +78 -0
- package/src/components/UiInputCheckbox/UiInputCheckbox.vue +213 -177
- package/src/components/UiInputEmoji/UiInputEmoji.vue +96 -0
- package/src/components/UiInputRadio/RadioGlyph.vue +45 -0
- package/src/components/UiInputRadio/UiInputRadio.vue +382 -0
- package/src/components/UiInputRadio/UiInputRadioGroup.vue +166 -0
- package/src/components/UiInputRadio/types.ts +24 -0
- package/src/components/UiInputSelect/UiInputSelect.vue +9 -7
- package/src/components/UiInputTextarea/UiInputTextarea.vue +20 -35
- package/src/components/UiLabel/UiLabel.vue +1 -1
- package/src/components/UiListItem/UiListItem.vue +55 -9
- package/src/components/UiLoader/UiLoader.vue +11 -29
- package/src/components/UiLoader/UiSpinnerIcon.vue +21 -0
- package/src/components/UiLogo/UiLogo.vue +41 -7
- package/src/components/UiMenu/UiMenuContent.vue +24 -3
- package/src/components/UiMenu/UiMenuGroup.vue +1 -1
- package/src/components/UiMenu/UiMenuItem.vue +14 -3
- package/src/components/UiMenu/UiMenuSubContent.vue +1 -1
- package/src/components/UiMenu/UiMenuSubTrigger.vue +2 -2
- package/src/components/UiNestedOptions/UiNestedOptions.vue +6 -0
- package/src/components/UiPage/UiPage.vue +273 -47
- package/src/components/UiPageHeader/UiPageHeader.vue +29 -9
- package/src/components/UiPagination/UiPagination.vue +99 -0
- package/src/components/UiPagination/index.ts +2 -0
- package/src/components/UiPagination/types.ts +28 -0
- package/src/components/UiPane/UiPane.vue +20 -0
- package/src/components/UiPane/UiPaneContent.vue +232 -0
- package/src/components/UiPane/UiPaneTrigger.vue +14 -0
- package/src/components/UiPane/index.ts +12 -0
- package/src/components/UiPopover/UiPopoverContent.vue +21 -1
- package/src/components/UiProgress/UiProgress.vue +2 -2
- package/src/components/UiRating/UiRating.vue +258 -0
- package/src/components/UiRating/types.ts +1 -0
- package/src/components/UiRoomButton/UiRoomButton.vue +14 -45
- package/src/components/UiRoomCountdown/UiRoomCountdown.vue +376 -0
- package/src/components/UiShell/UiShell.vue +10 -4
- package/src/components/UiSideMenu/UiSideMenu.vue +158 -18
- package/src/components/UiSideMenu/UiSideMenuItemContent.vue +22 -18
- package/src/components/UiStepper/UiStepper.vue +3 -16
- package/src/components/UiStepper/UiStepperDescription.vue +1 -13
- package/src/components/UiStepper/UiStepperIndicator.vue +17 -57
- package/src/components/UiStepper/UiStepperItem.vue +1 -8
- package/src/components/UiStepper/UiStepperSeparator.vue +5 -16
- package/src/components/UiStepper/UiStepperTitle.vue +1 -10
- package/src/components/UiSwitch/UiSwitch.vue +375 -0
- package/src/components/UiSwitch/types.ts +5 -0
- package/src/components/UiTable/UiTable.vue +98 -8
- package/src/components/UiTable/UiTableActionsCell.vue +135 -0
- package/src/components/UiTable/UiTableActionsHeaderCell.vue +19 -0
- package/src/components/UiTable/UiTableBody.vue +16 -1
- package/src/components/UiTable/UiTableCell.vue +33 -16
- package/src/components/UiTable/UiTableHeader.vue +6 -5
- package/src/components/UiTable/UiTableHeaderCell.vue +61 -9
- package/src/components/UiTable/UiTableRow.vue +46 -10
- package/src/components/UiTable/context.ts +5 -0
- package/src/components/UiTable/index.ts +4 -0
- package/src/components/UiTabs/UiTabs.vue +61 -63
- package/src/components/UiTag/UiTag.types.ts +28 -0
- package/src/components/UiTag/UiTag.vue +24 -42
- package/src/components/UiTag/index.ts +2 -0
- package/src/components/UiTextField/UiTextField.vue +27 -47
- package/src/components/UiTimeline/README.md +6 -6
- package/src/components/UiTimeline/UiTimelineItem.vue +3 -3
- package/src/components/UiTooltip/UiTooltipContent.vue +1 -1
- package/src/components/UiTooltip/UiTooltipProvider.vue +3 -0
- package/src/components/UiTooltip/UiTooltipTrigger.vue +16 -1
- package/src/composables/storedThemingApplies.ts +19 -0
- package/src/composables/useButtonStyles.ts +9 -13
- package/src/composables/useChoiceboxSurface.ts +36 -0
- package/src/composables/useContentMode.ts +66 -0
- package/src/composables/useControlModes.ts +11 -0
- package/src/composables/useControlShape.ts +34 -0
- package/src/composables/useFieldFocusEvents.ts +30 -0
- package/src/composables/useIconSize.ts +43 -0
- package/src/composables/usePullGesture.ts +142 -0
- package/src/composables/useThemeAndModes.ts +28 -1
- package/src/constants/sizes.ts +1 -1
- package/src/css/body.css +16 -1
- package/src/css/fonts.css +39 -5
- package/src/global.d.ts +44 -0
- package/src/theming/colorScale.ts +173 -0
- package/src/theming/legacyColorScale.ts +58 -0
- package/src/theming/presetColors.ts +33 -0
- package/src/theming/primitiveTokens.ts +71 -0
- package/src/utils/effectiveOpacity.ts +8 -0
- package/src/utils/i18n.ts +6 -0
- package/src/utils/numbers.ts +1 -1
- package/src/utils/responsive.d.ts +14 -0
- package/src/utils/tokenColor.ts +9 -0
- package/dist/UiTimelineItem.vue_vue_type_style_index_0_lang-DJFdCn2R.mjs +0 -5456
- package/dist/a11y-BhF_nl7L.mjs +0 -159
- package/dist/i18n-Cktw9hIu.mjs +0 -49
- package/dist/toastDSV2-wMh-UMzW.mjs +0 -74
- package/dist/types/src/components/UiAvatar/index.d.ts +0 -1
- package/dist/types/src/components/UiAvatarList/index.d.ts +0 -1
- package/dist/types/src/components/UiBadge/index.d.ts +0 -1
- package/dist/types/src/components/UiBanner/index.d.ts +0 -2
- package/dist/types/src/components/UiButtonGroup/index.d.ts +0 -3
- package/dist/types/src/components/UiCarousel/index.d.ts +0 -2
- package/dist/types/src/components/UiColorField/index.d.ts +0 -2
- package/dist/types/src/components/UiDialog/MarketplaceHeaderExample.vue.d.ts +0 -28
- package/dist/types/src/components/UiDialog/index.d.ts +0 -7
- package/dist/types/src/components/UiFieldWrapper/index.d.ts +0 -1
- package/dist/types/src/components/UiInputCheckbox/index.d.ts +0 -2
- package/dist/types/src/components/UiInputSelect/index.d.ts +0 -2
- package/dist/types/src/components/UiInputTextarea/index.d.ts +0 -2
- package/dist/types/src/components/UiMenu/index.d.ts +0 -10
- package/dist/types/src/components/UiProgress/index.d.ts +0 -2
- package/dist/types/src/components/UiTabs/index.d.ts +0 -2
- package/dist/types/src/components/UiTimeline/index.d.ts +0 -2
- package/dist/types/src/components/UiTooltip/index.d.ts +0 -4
- package/dist/types/src/mixins/DynamicAction.d.ts +0 -30
- package/dist/useThemeAndModes-BzYwSOEv.mjs +0 -108
- package/src/components/UiAvatar/index.js +0 -1
- package/src/components/UiAvatarList/index.js +0 -1
- package/src/components/UiBadge/index.ts +0 -2
- package/src/components/UiBanner/index.ts +0 -2
- package/src/components/UiButtonGroup/index.ts +0 -3
- package/src/components/UiCarousel/index.ts +0 -2
- package/src/components/UiColorField/index.ts +0 -2
- package/src/components/UiDialog/MarketplaceHeaderExample.vue +0 -217
- package/src/components/UiDialog/index.ts +0 -18
- package/src/components/UiFieldWrapper/index.ts +0 -1
- package/src/components/UiInputCheckbox/index.ts +0 -2
- package/src/components/UiInputSelect/index.ts +0 -2
- package/src/components/UiInputTextarea/index.ts +0 -2
- package/src/components/UiMenu/index.ts +0 -10
- package/src/components/UiProgress/index.ts +0 -2
- package/src/components/UiTabs/index.ts +0 -5
- package/src/components/UiTag/index.js +0 -1
- package/src/components/UiTimeline/index.ts +0 -2
- package/src/components/UiTooltip/index.js +0 -4
- package/src/mixins/DynamicAction.js +0 -61
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
import type { Color } from 'reka-ui'
|
|
27
27
|
import { UiDropdown, UiDropdownTrigger, UiDropdownContent, UiDropdownItem } from '../UiDropdown'
|
|
28
28
|
import type { ColorFormat, UiColorPickerPreset, UiColorPickerProps, UiColorPickerSwatchSize } from './types'
|
|
29
|
+
import { useControlShape } from '../../composables/useControlShape'
|
|
29
30
|
|
|
30
31
|
const props = withDefaults(defineProps<UiColorPickerProps>(), {
|
|
31
32
|
modelValue: undefined,
|
|
@@ -54,8 +55,8 @@ const presetsLabel = computed<string | null>(() => {
|
|
|
54
55
|
// Preset selector swatch sizes; the selection check icon scales to half the swatch.
|
|
55
56
|
// maxPerRow is how many swatches (at that size + gap) fit the panel's content width.
|
|
56
57
|
const SWATCH_SIZE_CLASSES: Record<UiColorPickerSwatchSize, { swatch: string; swatchPickerList: string; indicatorWrapper: string; indicator: string; maxPerRow: number }> = {
|
|
57
|
-
sm: { swatch: 'size-6', swatchPickerList: 'gap-2', indicatorWrapper: 'ring-2', indicator: '
|
|
58
|
-
lg: { swatch: 'size-12', swatchPickerList: 'gap-4', indicatorWrapper: 'ring-4', indicator: '
|
|
58
|
+
sm: { swatch: 'size-6', swatchPickerList: 'gap-2', indicatorWrapper: 'ring-2', indicator: 'size-3', maxPerRow: 8 },
|
|
59
|
+
lg: { swatch: 'size-12', swatchPickerList: 'gap-4', indicatorWrapper: 'ring-4', indicator: 'size-5', maxPerRow: 4 },
|
|
59
60
|
}
|
|
60
61
|
const swatchSizeClasses = computed(() => SWATCH_SIZE_CLASSES[props.presetConfig?.swatchSize ?? 'lg'])
|
|
61
62
|
|
|
@@ -124,10 +125,12 @@ const MODE_CHANNELS: Record<Exclude<ColorFormat, 'hex'>, ChannelDef[]> = {
|
|
|
124
125
|
],
|
|
125
126
|
}
|
|
126
127
|
|
|
128
|
+
const fieldShape = useControlShape('field', 'md')
|
|
129
|
+
|
|
127
130
|
// Shared styling for each bordered value box (the hex field and each channel field).
|
|
128
131
|
// The mode switcher is a separate bordered box (the dropdown trigger draws its own).
|
|
129
132
|
const FIELD_BOX_CLASS =
|
|
130
|
-
'flex h-full items-center
|
|
133
|
+
'flex h-full items-center border border-solid border-control-field-border bg-control-field-bg transition-all focus-within:bg-control-field-bg-focus has-[input:focus-visible]:focus-ring'
|
|
131
134
|
|
|
132
135
|
// Detect a value's mode. reka represents hex as space 'rgb', so hex must be
|
|
133
136
|
// matched on the '#' prefix; rgb/hsl/hsb (and hsv→hsb) come from normalizeColor.
|
|
@@ -268,14 +271,14 @@ watch(
|
|
|
268
271
|
color-space="hsb"
|
|
269
272
|
x-channel="saturation"
|
|
270
273
|
y-channel="brightness"
|
|
271
|
-
class="relative h-[189px] w-full rounded-
|
|
274
|
+
class="relative h-[189px] w-full rounded-row"
|
|
272
275
|
:class="{ 'cursor-not-allowed': disabled }"
|
|
273
276
|
@update:color="onColorUpdate"
|
|
274
277
|
@change-end="onCommit"
|
|
275
278
|
>
|
|
276
279
|
<ColorAreaArea
|
|
277
280
|
:style="style"
|
|
278
|
-
class="absolute inset-0 rounded-
|
|
281
|
+
class="absolute inset-0 rounded-row"
|
|
279
282
|
>
|
|
280
283
|
<ColorAreaThumb class="group size-6 rounded-full border-4 border-actions-neutral-invert-idle transition-shadow hover:cursor-pointer hover:shadow-md">
|
|
281
284
|
<span class="pointer-events-none absolute -inset-1 rounded-full bg-actions-primary-hover-overlay opacity-0 transition-opacity group-hover:opacity-100" />
|
|
@@ -322,13 +325,13 @@ watch(
|
|
|
322
325
|
<div
|
|
323
326
|
v-if="showCustomControls"
|
|
324
327
|
data-testid="ui-color-picker-field"
|
|
325
|
-
class="flex
|
|
326
|
-
:class="{ 'cursor-not-allowed opacity-50': disabled }"
|
|
328
|
+
class="flex w-full items-center gap-2"
|
|
329
|
+
:class="[fieldShape.height, { 'cursor-not-allowed opacity-50': disabled }]"
|
|
327
330
|
>
|
|
328
331
|
<!-- Mode switcher — its own bordered box; hidden when only one mode is available -->
|
|
329
332
|
<div
|
|
330
333
|
v-if="showSwitcher"
|
|
331
|
-
class="h-full w-
|
|
334
|
+
class="h-full w-21 shrink-0"
|
|
332
335
|
>
|
|
333
336
|
<UiDropdown
|
|
334
337
|
v-model="colorMode"
|
|
@@ -357,12 +360,12 @@ watch(
|
|
|
357
360
|
:model-value="internalColor"
|
|
358
361
|
:disabled="disabled"
|
|
359
362
|
color-space="hsb"
|
|
360
|
-
:class="[FIELD_BOX_CLASS, 'min-w-0 flex-1 gap-1.5 px-3']"
|
|
363
|
+
:class="[FIELD_BOX_CLASS, fieldShape.radius, 'min-w-0 flex-1 gap-1.5 px-3']"
|
|
361
364
|
@update:color="onColorUpdate"
|
|
362
365
|
>
|
|
363
366
|
<ColorSwatch
|
|
364
367
|
:color="internalColor"
|
|
365
|
-
class="size-4 shrink-0 rounded-
|
|
368
|
+
class="size-4 shrink-0 rounded-check border border-borders-neutral-light bg-(--reka-color-swatch-color)"
|
|
366
369
|
/>
|
|
367
370
|
<Label
|
|
368
371
|
:for="fieldId"
|
|
@@ -386,7 +389,7 @@ watch(
|
|
|
386
389
|
:disabled="disabled"
|
|
387
390
|
:color-space="colorMode"
|
|
388
391
|
:channel="ch.channel"
|
|
389
|
-
:class="[FIELD_BOX_CLASS, 'min-w-0 flex-1 justify-center px-2']"
|
|
392
|
+
:class="[FIELD_BOX_CLASS, fieldShape.radius, 'min-w-0 flex-1 justify-center px-2']"
|
|
390
393
|
@update:color="onColorUpdate"
|
|
391
394
|
>
|
|
392
395
|
<ColorFieldInput
|
|
@@ -456,7 +459,7 @@ watch(
|
|
|
456
459
|
class="absolute inset-0 flex items-center justify-center rounded-full bg-actions-neutral-hover-overlay opacity-0 transition-opacity group-hover:opacity-100 group-focus-visible:opacity-100"
|
|
457
460
|
>
|
|
458
461
|
<div
|
|
459
|
-
class="i-
|
|
462
|
+
class="i-ph-check-circle-fill text-text-neutral-invert-tertiary"
|
|
460
463
|
:class="swatchSizeClasses.indicator"
|
|
461
464
|
/>
|
|
462
465
|
</span>
|
|
@@ -472,7 +475,7 @@ watch(
|
|
|
472
475
|
:class="swatchSizeClasses.indicatorWrapper"
|
|
473
476
|
>
|
|
474
477
|
<div
|
|
475
|
-
class="i-
|
|
478
|
+
class="i-ph-check-circle-fill text-text-neutral-invert-base"
|
|
476
479
|
:class="swatchSizeClasses.indicator"
|
|
477
480
|
/>
|
|
478
481
|
</span>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { FieldSize } from '../../composables/useControlShape'
|
|
2
|
+
|
|
3
|
+
export type UiComboboxSize = FieldSize
|
|
4
|
+
|
|
5
|
+
export interface UiComboboxOption {
|
|
6
|
+
value: string
|
|
7
|
+
label: string
|
|
8
|
+
description?: string
|
|
9
|
+
disabled?: boolean
|
|
10
|
+
/** Shown instead of the description, typically why the option is disabled. */
|
|
11
|
+
hint?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface UiComboboxGroup<T extends UiComboboxOption = UiComboboxOption> {
|
|
15
|
+
label: string
|
|
16
|
+
options: T[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** A selectable row after the options, picked like an option but emitted as `action`. `icon` is a complete icon class such as `i-ph-user-plus`. */
|
|
20
|
+
export interface UiComboboxAction {
|
|
21
|
+
id: string
|
|
22
|
+
label: string
|
|
23
|
+
icon?: string
|
|
24
|
+
disabled?: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface UiComboboxProps<T extends UiComboboxOption = UiComboboxOption> {
|
|
28
|
+
modelValue?: string
|
|
29
|
+
items?: UiComboboxGroup<T>[]
|
|
30
|
+
/** Selectable rows after the options. */
|
|
31
|
+
actions?: UiComboboxAction[]
|
|
32
|
+
loading?: boolean
|
|
33
|
+
size?: UiComboboxSize
|
|
34
|
+
placeholder?: string
|
|
35
|
+
disabled?: boolean
|
|
36
|
+
label?: string
|
|
37
|
+
ariaLabel?: string
|
|
38
|
+
/** Translated result count, announced through a polite live region while the list is open. */
|
|
39
|
+
resultsLabel?: string
|
|
40
|
+
id?: string
|
|
41
|
+
/** Rows shown before the list scrolls, with a peek of the next one. All rows show when unset. */
|
|
42
|
+
maxVisibleOptions?: number
|
|
43
|
+
/** Options show a checkbox and the list stays open after a pick, so several can be picked in a row. */
|
|
44
|
+
multiple?: boolean
|
|
45
|
+
/** Values of the options shown checked when `multiple` is set. Picking one of them emits `deselect`. */
|
|
46
|
+
selected?: string[]
|
|
47
|
+
/**
|
|
48
|
+
* 'trigger' matches the list to the field. 'compact' caps it at 480px, so on a wide field part of the
|
|
49
|
+
* page behind stays visible, such as a list that updates while picking.
|
|
50
|
+
*/
|
|
51
|
+
width?: 'trigger' | 'compact'
|
|
52
|
+
}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
<script setup lang="ts" generic="T extends UiComboboxOption">
|
|
2
|
+
import {
|
|
3
|
+
ComboboxAnchor,
|
|
4
|
+
ComboboxContent,
|
|
5
|
+
ComboboxGroup,
|
|
6
|
+
ComboboxInput,
|
|
7
|
+
ComboboxItem,
|
|
8
|
+
ComboboxLabel,
|
|
9
|
+
ComboboxPortal,
|
|
10
|
+
ComboboxRoot,
|
|
11
|
+
ComboboxViewport,
|
|
12
|
+
} from 'reka-ui'
|
|
13
|
+
import { computed, nextTick, ref, watch } from 'vue'
|
|
14
|
+
import CheckboxGlyph from '../UiInputCheckbox/CheckboxGlyph.vue'
|
|
15
|
+
import UiFieldWrapper from '../UiFieldWrapper/UiFieldWrapper.vue'
|
|
16
|
+
import { useControlShape } from '../../composables/useControlShape'
|
|
17
|
+
import type { UiComboboxAction, UiComboboxOption, UiComboboxProps, UiComboboxSize } from './UiCombobox.types'
|
|
18
|
+
|
|
19
|
+
const props = withDefaults(defineProps<UiComboboxProps<T>>(), {
|
|
20
|
+
modelValue: '',
|
|
21
|
+
items: () => [],
|
|
22
|
+
actions: () => [],
|
|
23
|
+
loading: false,
|
|
24
|
+
size: 'md',
|
|
25
|
+
placeholder: undefined,
|
|
26
|
+
disabled: false,
|
|
27
|
+
label: undefined,
|
|
28
|
+
ariaLabel: undefined,
|
|
29
|
+
resultsLabel: undefined,
|
|
30
|
+
id: undefined,
|
|
31
|
+
maxVisibleOptions: undefined,
|
|
32
|
+
multiple: false,
|
|
33
|
+
selected: () => [],
|
|
34
|
+
width: 'trigger',
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const emit = defineEmits<{
|
|
38
|
+
'update:modelValue': [value: string]
|
|
39
|
+
'update:open': [open: boolean]
|
|
40
|
+
'select': [option: T]
|
|
41
|
+
'deselect': [option: T]
|
|
42
|
+
'action': [id: string]
|
|
43
|
+
}>()
|
|
44
|
+
|
|
45
|
+
const slots = defineSlots<{
|
|
46
|
+
item?: (props: { option: T }) => unknown
|
|
47
|
+
empty?: () => unknown
|
|
48
|
+
action?: (props: { action: UiComboboxAction }) => unknown
|
|
49
|
+
/** Pinned under the options, outside their scroll: `close` closes the list. Hidden from assistive tech, so keep anything focusable out of the Tab order (`tabindex="-1"`) and redundant with Escape. */
|
|
50
|
+
footer?: (props: { close: () => void }) => unknown
|
|
51
|
+
}>()
|
|
52
|
+
|
|
53
|
+
const FIELD_PADDING: Record<UiComboboxSize, string> = {
|
|
54
|
+
sm: 'px-2 gap-1',
|
|
55
|
+
md: 'px-3 gap-1.5',
|
|
56
|
+
lg: 'px-4 gap-2',
|
|
57
|
+
xl: 'px-4 gap-2',
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const ITEM_CLASSES = 'focus-indicator-none group/option flex items-center gap-2 min-h-10 px-3 py-1.5 rounded-row cursor-pointer outline-hidden transition-colors duration-150 text-content-text-md-regular text-text-neutral-base data-highlighted:bg-actions-neutral-hover-overlay data-[state=checked]:bg-actions-primary-active-overlay data-disabled:opacity-50 data-disabled:cursor-not-allowed'
|
|
61
|
+
|
|
62
|
+
const shape = useControlShape('field', () => props.size)
|
|
63
|
+
const open = ref(false)
|
|
64
|
+
|
|
65
|
+
const fieldClasses = computed(() => [
|
|
66
|
+
'relative flex items-center w-full border transition-all duration-150',
|
|
67
|
+
'bg-control-field-bg border-control-field-border',
|
|
68
|
+
'focus-within:bg-control-field-bg-focus has-[input:focus-visible]:focus-ring',
|
|
69
|
+
"before:content-[''] before:absolute before:-inset-px before:rounded-[inherit] before:pointer-events-none before:opacity-0 before:transition-opacity before:bg-actions-neutral-hover-overlay [&>*]:relative",
|
|
70
|
+
props.disabled ? 'opacity-50 cursor-not-allowed' : 'hover:not-focus-within:before:opacity-100',
|
|
71
|
+
shape.value.height,
|
|
72
|
+
shape.value.radius,
|
|
73
|
+
FIELD_PADDING[props.size],
|
|
74
|
+
])
|
|
75
|
+
|
|
76
|
+
const WIDTH_CLASSES = {
|
|
77
|
+
trigger: 'w-(--reka-combobox-trigger-width)',
|
|
78
|
+
compact: 'w-[min(var(--reka-combobox-trigger-width),30rem)]',
|
|
79
|
+
} as const
|
|
80
|
+
|
|
81
|
+
const options = computed(() => props.items.flatMap(group => group.options))
|
|
82
|
+
const hasContent = computed(() => options.value.length > 0 || props.actions.length > 0 || (!!slots.empty && !props.loading))
|
|
83
|
+
|
|
84
|
+
const viewport = ref<{ $el: HTMLElement } | null>(null)
|
|
85
|
+
const viewportMaxHeight = ref<string>()
|
|
86
|
+
|
|
87
|
+
async function fitVisibleOptions () {
|
|
88
|
+
viewportMaxHeight.value = undefined
|
|
89
|
+
if (!open.value || !props.maxVisibleOptions) return
|
|
90
|
+
await nextTick()
|
|
91
|
+
const element = viewport.value?.$el
|
|
92
|
+
const peeked = element?.querySelectorAll('[role=option]')[props.maxVisibleOptions]
|
|
93
|
+
if (!element || !peeked) return
|
|
94
|
+
const row = peeked.getBoundingClientRect()
|
|
95
|
+
viewportMaxHeight.value = `${row.top + row.height / 2 - element.getBoundingClientRect().top + element.scrollTop}px`
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
watch([open, () => props.items, () => props.actions, () => props.maxVisibleOptions], fitVisibleOptions, { flush: 'post' })
|
|
99
|
+
|
|
100
|
+
function onOpenChange (value: boolean) {
|
|
101
|
+
if (open.value === value) return
|
|
102
|
+
open.value = value
|
|
103
|
+
emit('update:open', value)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
defineExpose({
|
|
107
|
+
/** Closes the list, for a pick that leads somewhere else, such as a dialog. */
|
|
108
|
+
close: () => onOpenChange(false),
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
// Reka hands back the whole checked list; the one value that differs from `selected` is the pick.
|
|
112
|
+
function onMultipleValueChange (values: unknown[]) {
|
|
113
|
+
const action = props.actions.find(candidate => values.includes(candidate))
|
|
114
|
+
if (action) {
|
|
115
|
+
emit('action', action.id)
|
|
116
|
+
emit('update:modelValue', '')
|
|
117
|
+
onOpenChange(false)
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
const added = values.find(value => !props.selected.includes(value as string))
|
|
121
|
+
const removed = props.selected.find(value => !values.includes(value))
|
|
122
|
+
const picked = options.value.find(option => option.value === (added ?? removed))
|
|
123
|
+
if (!picked) return
|
|
124
|
+
if (added === undefined) emit('deselect', picked)
|
|
125
|
+
else emit('select', picked)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function onValueChange (value: unknown) {
|
|
129
|
+
if (props.multiple) {
|
|
130
|
+
onMultipleValueChange(Array.isArray(value) ? value : [])
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
if (props.actions.includes(value as UiComboboxAction)) {
|
|
134
|
+
emit('action', (value as UiComboboxAction).id)
|
|
135
|
+
} else {
|
|
136
|
+
const picked = options.value.find(option => option.value === value)
|
|
137
|
+
if (picked) emit('select', picked)
|
|
138
|
+
}
|
|
139
|
+
emit('update:modelValue', '')
|
|
140
|
+
}
|
|
141
|
+
</script>
|
|
142
|
+
|
|
143
|
+
<template>
|
|
144
|
+
<UiFieldWrapper
|
|
145
|
+
:id="id"
|
|
146
|
+
:label="label"
|
|
147
|
+
>
|
|
148
|
+
<template #default="{ fieldId }">
|
|
149
|
+
<ComboboxRoot
|
|
150
|
+
:model-value="multiple ? selected : null"
|
|
151
|
+
:open="open"
|
|
152
|
+
:multiple="multiple"
|
|
153
|
+
:disabled="disabled"
|
|
154
|
+
ignore-filter
|
|
155
|
+
open-on-click
|
|
156
|
+
:reset-search-term-on-blur="false"
|
|
157
|
+
:reset-search-term-on-select="false"
|
|
158
|
+
@update:model-value="onValueChange"
|
|
159
|
+
@update:open="onOpenChange"
|
|
160
|
+
>
|
|
161
|
+
<ComboboxAnchor :class="fieldClasses">
|
|
162
|
+
<ComboboxInput
|
|
163
|
+
:id="fieldId"
|
|
164
|
+
:model-value="modelValue"
|
|
165
|
+
:placeholder="placeholder"
|
|
166
|
+
:aria-label="ariaLabel"
|
|
167
|
+
:aria-expanded="open && hasContent"
|
|
168
|
+
class="flex-1 min-w-0 bg-transparent outline-none text-content-text-md-regular text-text-neutral-base placeholder:text-control-placeholder disabled:cursor-not-allowed"
|
|
169
|
+
data-testid="ui-combobox-input"
|
|
170
|
+
@update:model-value="emit('update:modelValue', $event)"
|
|
171
|
+
/>
|
|
172
|
+
<span
|
|
173
|
+
v-if="loading"
|
|
174
|
+
class="size-4 shrink-0 rounded-full border-2 border-current border-t-transparent animate-spin text-text-neutral-tertiary"
|
|
175
|
+
data-testid="ui-combobox-loader"
|
|
176
|
+
/>
|
|
177
|
+
</ComboboxAnchor>
|
|
178
|
+
|
|
179
|
+
<ComboboxPortal>
|
|
180
|
+
<ComboboxContent
|
|
181
|
+
position="popper"
|
|
182
|
+
align="start"
|
|
183
|
+
:side-offset="8"
|
|
184
|
+
data-colors-semantic="light"
|
|
185
|
+
:aria-busy="loading || undefined"
|
|
186
|
+
:hide-when-empty="!hasContent"
|
|
187
|
+
:class="WIDTH_CLASSES[width]"
|
|
188
|
+
class="focus-indicator-none z-overlay flex flex-col p-1 rounded-container border border-container-border bg-surface-neutral-bg-main shadow-shadows-drop-shadow-lg max-w-(--reka-combobox-content-available-width) max-h-(--reka-combobox-content-available-height)"
|
|
189
|
+
>
|
|
190
|
+
<ComboboxViewport
|
|
191
|
+
ref="viewport"
|
|
192
|
+
class="flex flex-col gap-1 min-h-0 max-h-[300px] rounded-row"
|
|
193
|
+
:style="{ maxHeight: viewportMaxHeight }"
|
|
194
|
+
>
|
|
195
|
+
<div
|
|
196
|
+
v-if="slots.empty && options.length === 0 && !loading"
|
|
197
|
+
class="px-3 py-2 text-content-text-md-regular text-text-neutral-secondary"
|
|
198
|
+
data-testid="ui-combobox-empty"
|
|
199
|
+
>
|
|
200
|
+
<slot name="empty" />
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
<ComboboxGroup
|
|
204
|
+
v-for="(group, index) in items"
|
|
205
|
+
:key="`${index}-${group.label}`"
|
|
206
|
+
class="flex flex-col gap-1"
|
|
207
|
+
>
|
|
208
|
+
<ComboboxLabel class="px-3 pt-2 pb-1 text-content-legends-bold-md text-text-neutral-tertiary">
|
|
209
|
+
{{ group.label }}
|
|
210
|
+
</ComboboxLabel>
|
|
211
|
+
<ComboboxItem
|
|
212
|
+
v-for="option in group.options"
|
|
213
|
+
:key="option.value"
|
|
214
|
+
:value="option.value"
|
|
215
|
+
:disabled="option.disabled"
|
|
216
|
+
:text-value="option.label"
|
|
217
|
+
:class="ITEM_CLASSES"
|
|
218
|
+
data-testid="ui-combobox-option"
|
|
219
|
+
>
|
|
220
|
+
<CheckboxGlyph
|
|
221
|
+
v-if="multiple"
|
|
222
|
+
:checked="selected.includes(option.value)"
|
|
223
|
+
:disabled="option.disabled"
|
|
224
|
+
/>
|
|
225
|
+
<slot
|
|
226
|
+
name="item"
|
|
227
|
+
:option="option"
|
|
228
|
+
>
|
|
229
|
+
<span class="flex flex-col min-w-0 py-1">
|
|
230
|
+
<span class="truncate text-content-text-md-medium">{{ option.label }}</span>
|
|
231
|
+
<span
|
|
232
|
+
v-if="option.hint || option.description"
|
|
233
|
+
class="truncate text-content-legends-medium-md text-text-neutral-secondary"
|
|
234
|
+
>
|
|
235
|
+
{{ option.hint ?? option.description }}
|
|
236
|
+
</span>
|
|
237
|
+
</span>
|
|
238
|
+
</slot>
|
|
239
|
+
</ComboboxItem>
|
|
240
|
+
</ComboboxGroup>
|
|
241
|
+
|
|
242
|
+
<ComboboxItem
|
|
243
|
+
v-for="action in actions"
|
|
244
|
+
:key="action.id"
|
|
245
|
+
:value="action"
|
|
246
|
+
:disabled="action.disabled"
|
|
247
|
+
:text-value="action.label"
|
|
248
|
+
:class="ITEM_CLASSES"
|
|
249
|
+
data-testid="ui-combobox-action"
|
|
250
|
+
>
|
|
251
|
+
<slot
|
|
252
|
+
name="action"
|
|
253
|
+
:action="action"
|
|
254
|
+
>
|
|
255
|
+
<span
|
|
256
|
+
v-if="action.icon"
|
|
257
|
+
class="size-4 shrink-0"
|
|
258
|
+
:class="action.icon"
|
|
259
|
+
aria-hidden="true"
|
|
260
|
+
/>
|
|
261
|
+
<span class="truncate">{{ action.label }}</span>
|
|
262
|
+
</slot>
|
|
263
|
+
</ComboboxItem>
|
|
264
|
+
</ComboboxViewport>
|
|
265
|
+
|
|
266
|
+
<!--
|
|
267
|
+
The whole card is the listbox, which may only hold options: the footer is a pointer shortcut,
|
|
268
|
+
hidden from assistive tech, and Escape stays the keyboard way out. pointerdown is prevented so a
|
|
269
|
+
click here keeps the focus in the field.
|
|
270
|
+
-->
|
|
271
|
+
<div
|
|
272
|
+
v-if="slots.footer"
|
|
273
|
+
class="flex items-center gap-2 shrink-0 -mx-1 -mb-1 mt-1 pl-4 pr-2 py-2 border-t border-container-border"
|
|
274
|
+
aria-hidden="true"
|
|
275
|
+
data-testid="ui-combobox-footer"
|
|
276
|
+
@pointerdown.prevent
|
|
277
|
+
>
|
|
278
|
+
<slot
|
|
279
|
+
name="footer"
|
|
280
|
+
:close="() => onOpenChange(false)"
|
|
281
|
+
/>
|
|
282
|
+
</div>
|
|
283
|
+
</ComboboxContent>
|
|
284
|
+
</ComboboxPortal>
|
|
285
|
+
</ComboboxRoot>
|
|
286
|
+
|
|
287
|
+
<div
|
|
288
|
+
class="sr-only"
|
|
289
|
+
aria-live="polite"
|
|
290
|
+
data-testid="ui-combobox-live"
|
|
291
|
+
>
|
|
292
|
+
{{ open && resultsLabel ? resultsLabel : '' }}
|
|
293
|
+
</div>
|
|
294
|
+
</template>
|
|
295
|
+
</UiFieldWrapper>
|
|
296
|
+
</template>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export interface UiDataTableColumn<TData> {
|
|
2
|
+
/**
|
|
3
|
+
* Unique column id. Also names the per-column slots:
|
|
4
|
+
* `#cell-<id>` and `#header-<id>`.
|
|
5
|
+
*/
|
|
6
|
+
id: string
|
|
7
|
+
/** Header label. An empty string renders an empty header cell. */
|
|
8
|
+
header: string
|
|
9
|
+
/**
|
|
10
|
+
* Row property rendered by default. Omit for columns rendered
|
|
11
|
+
* entirely through their `#cell-<id>` slot.
|
|
12
|
+
*/
|
|
13
|
+
accessorKey?: keyof TData & string
|
|
14
|
+
/**
|
|
15
|
+
* Shows the sort affordance on the header. Sorting logic stays in the
|
|
16
|
+
* consumer: bind `v-model:sorting` and sort/refetch the data yourself.
|
|
17
|
+
* @default false
|
|
18
|
+
*/
|
|
19
|
+
sortable?: boolean
|
|
20
|
+
/**
|
|
21
|
+
* Content alignment. Textual data stays left-aligned; reserve `right`
|
|
22
|
+
* for numeric data.
|
|
23
|
+
* @default 'left'
|
|
24
|
+
*/
|
|
25
|
+
align?: 'left' | 'right'
|
|
26
|
+
/** Fixed column width as a CSS value (e.g. '160px', '20%'). */
|
|
27
|
+
width?: string
|
|
28
|
+
/**
|
|
29
|
+
* Minimum column width as a CSS length (e.g. '160px'). The column never
|
|
30
|
+
* shrinks below it: when the columns do not fit, the table grows wider
|
|
31
|
+
* than its region, which scrolls horizontally.
|
|
32
|
+
*/
|
|
33
|
+
minWidth?: string
|
|
34
|
+
/**
|
|
35
|
+
* Keeps the header and the values of the column on one line: the column
|
|
36
|
+
* grows to fit them instead of wrapping, and the table grows wider than
|
|
37
|
+
* its region when needed, as with `minWidth`.
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
nowrap?: boolean
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface UiDataTableSort {
|
|
44
|
+
/** Column id being sorted. */
|
|
45
|
+
id: string
|
|
46
|
+
direction: 'asc' | 'desc'
|
|
47
|
+
}
|