@nuxt/ui 3.0.0-alpha.9 → 3.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nuxt/ui/accordion.ts +2 -2
- package/.nuxt/ui/alert.ts +122 -95
- package/.nuxt/ui/avatar-group.ts +14 -2
- package/.nuxt/ui/avatar.ts +16 -4
- package/.nuxt/ui/badge.ts +139 -93
- package/.nuxt/ui/breadcrumb.ts +5 -5
- package/.nuxt/ui/button-group.ts +13 -0
- package/.nuxt/ui/button.ts +167 -136
- package/.nuxt/ui/calendar.ts +103 -0
- package/.nuxt/ui/card.ts +27 -1
- package/.nuxt/ui/carousel.ts +7 -5
- package/.nuxt/ui/checkbox.ts +45 -27
- package/.nuxt/ui/chip.ts +44 -15
- package/.nuxt/ui/color-picker.ts +47 -0
- package/.nuxt/ui/command-palette.ts +28 -18
- package/.nuxt/ui/container.ts +1 -1
- package/.nuxt/ui/context-menu.ts +64 -46
- package/.nuxt/ui/drawer.ts +83 -15
- package/.nuxt/ui/dropdown-menu.ts +65 -47
- package/.nuxt/ui/form-field.ts +15 -7
- package/.nuxt/ui/index.ts +5 -1
- package/.nuxt/ui/input-menu.ts +150 -116
- package/.nuxt/ui/input-number.ts +102 -71
- package/.nuxt/ui/input.ts +111 -76
- package/.nuxt/ui/kbd.ts +18 -6
- package/.nuxt/ui/link.ts +3 -3
- package/.nuxt/ui/modal.ts +8 -7
- package/.nuxt/ui/navigation-menu.ts +244 -131
- package/.nuxt/ui/pin-input.ts +77 -51
- package/.nuxt/ui/popover.ts +2 -2
- package/.nuxt/ui/progress.ts +111 -72
- package/.nuxt/ui/radio-group.ts +45 -22
- package/.nuxt/ui/select-menu.ts +122 -86
- package/.nuxt/ui/select.ts +120 -84
- package/.nuxt/ui/separator.ts +60 -31
- package/.nuxt/ui/skeleton.ts +1 -1
- package/.nuxt/ui/slideover.ts +17 -9
- package/.nuxt/ui/slider.ts +61 -38
- package/.nuxt/ui/stepper.ts +202 -0
- package/.nuxt/ui/switch.ts +40 -22
- package/.nuxt/ui/table.ts +48 -31
- package/.nuxt/ui/tabs.ts +100 -72
- package/.nuxt/ui/textarea.ts +111 -76
- package/.nuxt/ui/toast.ts +53 -33
- package/.nuxt/ui/toaster.ts +31 -15
- package/.nuxt/ui/tooltip.ts +2 -2
- package/.nuxt/ui/tree.ts +154 -0
- package/.nuxt/ui.css +92 -0
- package/README.md +19 -8
- package/cli/commands/make/component.mjs +12 -0
- package/cli/package.json +2 -2
- package/cli/templates.mjs +27 -22
- package/dist/module.cjs +9 -171
- package/dist/module.d.cts +5 -15
- package/dist/module.d.mts +5 -15
- package/dist/module.d.ts +5 -15
- package/dist/module.json +2 -2
- package/dist/module.mjs +12 -168
- package/dist/runtime/components/Accordion.vue +8 -39
- package/dist/runtime/components/Alert.vue +22 -21
- package/dist/runtime/components/App.vue +9 -15
- package/dist/runtime/components/Avatar.vue +33 -21
- package/dist/runtime/components/AvatarGroup.vue +5 -7
- package/dist/runtime/components/Badge.vue +10 -8
- package/dist/runtime/components/Breadcrumb.vue +5 -31
- package/dist/runtime/components/Button.vue +5 -8
- package/dist/runtime/components/ButtonGroup.vue +5 -7
- package/dist/runtime/components/Calendar.vue +194 -0
- package/dist/runtime/components/Card.vue +10 -9
- package/dist/runtime/components/Carousel.vue +15 -10
- package/dist/runtime/components/Checkbox.vue +32 -38
- package/dist/runtime/components/Chip.vue +6 -8
- package/dist/runtime/components/Collapsible.vue +10 -11
- package/dist/runtime/components/ColorPicker.vue +297 -0
- package/dist/runtime/components/CommandPalette.vue +111 -97
- package/dist/runtime/components/Container.vue +4 -7
- package/dist/runtime/components/ContextMenu.vue +16 -69
- package/dist/runtime/components/ContextMenuContent.vue +12 -10
- package/dist/runtime/components/Drawer.vue +23 -12
- package/dist/runtime/components/DropdownMenu.vue +18 -59
- package/dist/runtime/components/DropdownMenuContent.vue +12 -10
- package/dist/runtime/components/Form.vue +65 -34
- package/dist/runtime/components/FormField.vue +22 -13
- package/dist/runtime/components/Icon.vue +1 -1
- package/dist/runtime/components/Input.vue +15 -7
- package/dist/runtime/components/InputMenu.vue +95 -104
- package/dist/runtime/components/InputNumber.vue +14 -9
- package/dist/runtime/components/Kbd.vue +5 -6
- package/dist/runtime/components/Link.vue +5 -8
- package/dist/runtime/components/LinkBase.vue +1 -1
- package/dist/runtime/components/Modal.vue +51 -38
- package/dist/runtime/components/NavigationMenu.vue +129 -114
- package/dist/runtime/components/OverlayProvider.vue +29 -0
- package/dist/runtime/components/Pagination.vue +6 -9
- package/dist/runtime/components/PinInput.vue +10 -11
- package/dist/runtime/components/Popover.vue +16 -18
- package/dist/runtime/components/Progress.vue +28 -12
- package/dist/runtime/components/RadioGroup.vue +9 -12
- package/dist/runtime/components/Select.vue +60 -34
- package/dist/runtime/components/SelectMenu.vue +160 -165
- package/dist/runtime/components/Separator.vue +6 -5
- package/dist/runtime/components/Skeleton.vue +4 -7
- package/dist/runtime/components/Slideover.vue +51 -37
- package/dist/runtime/components/Slider.vue +8 -7
- package/dist/runtime/components/Stepper.vue +170 -0
- package/dist/runtime/components/Switch.vue +19 -23
- package/dist/runtime/components/Table.vue +146 -31
- package/dist/runtime/components/Tabs.vue +12 -31
- package/dist/runtime/components/Textarea.vue +17 -8
- package/dist/runtime/components/Toast.vue +36 -25
- package/dist/runtime/components/Toaster.vue +10 -11
- package/dist/runtime/components/Tooltip.vue +9 -12
- package/dist/runtime/components/Tree.vue +196 -0
- package/dist/runtime/composables/defineShortcuts.d.ts +1 -1
- package/dist/runtime/composables/defineShortcuts.js +2 -2
- package/dist/runtime/composables/useFormField.d.ts +7 -3
- package/dist/runtime/composables/useFormField.js +18 -8
- package/dist/runtime/composables/useLocale.js +1 -1
- package/dist/runtime/composables/useOverlay.d.ts +30 -0
- package/dist/runtime/composables/useOverlay.js +71 -0
- package/dist/runtime/composables/useToast.d.ts +4 -3
- package/dist/runtime/composables/useToast.js +20 -6
- package/dist/runtime/index.css +1 -1
- package/dist/runtime/keyframes.css +1 -1
- package/dist/runtime/locale/ar.js +9 -1
- package/dist/runtime/locale/az.js +54 -0
- package/dist/runtime/locale/bn.js +54 -0
- package/dist/runtime/locale/cs.js +9 -1
- package/dist/runtime/locale/da.d.ts +2 -0
- package/dist/runtime/locale/da.js +54 -0
- package/dist/runtime/locale/de.js +11 -3
- package/dist/runtime/locale/el.d.ts +2 -0
- package/dist/runtime/locale/el.js +54 -0
- package/dist/runtime/locale/en.js +9 -1
- package/dist/runtime/locale/es.js +9 -1
- package/dist/runtime/locale/et.d.ts +2 -0
- package/dist/runtime/locale/et.js +54 -0
- package/dist/runtime/locale/fa_ir.js +9 -1
- package/dist/runtime/locale/fi.d.ts +2 -0
- package/dist/runtime/locale/fi.js +54 -0
- package/dist/runtime/locale/fr.js +9 -1
- package/dist/runtime/locale/he.d.ts +2 -0
- package/dist/runtime/locale/he.js +53 -0
- package/dist/runtime/locale/hi.d.ts +2 -0
- package/dist/runtime/locale/hi.js +54 -0
- package/dist/runtime/locale/hu.d.ts +2 -0
- package/dist/runtime/locale/hu.js +54 -0
- package/dist/runtime/locale/id.d.ts +2 -0
- package/dist/runtime/locale/id.js +54 -0
- package/dist/runtime/locale/index.d.ts +25 -3
- package/dist/runtime/locale/index.js +25 -3
- package/dist/runtime/locale/it.js +9 -1
- package/dist/runtime/locale/ja.d.ts +2 -0
- package/dist/runtime/locale/ja.js +54 -0
- package/dist/runtime/locale/km.d.ts +2 -0
- package/dist/runtime/locale/km.js +54 -0
- package/dist/runtime/locale/ko.d.ts +2 -0
- package/dist/runtime/locale/ko.js +54 -0
- package/dist/runtime/locale/nb_no.d.ts +2 -0
- package/dist/runtime/locale/nb_no.js +54 -0
- package/dist/runtime/locale/nl.d.ts +2 -0
- package/dist/runtime/locale/nl.js +54 -0
- package/dist/runtime/locale/pl.js +9 -1
- package/dist/runtime/locale/pt.d.ts +2 -0
- package/dist/runtime/locale/pt.js +54 -0
- package/dist/runtime/locale/pt_br.d.ts +2 -0
- package/dist/runtime/locale/pt_br.js +54 -0
- package/dist/runtime/locale/ru.js +9 -1
- package/dist/runtime/locale/sk.d.ts +2 -0
- package/dist/runtime/locale/sk.js +54 -0
- package/dist/runtime/locale/sv.d.ts +2 -0
- package/dist/runtime/locale/sv.js +54 -0
- package/dist/runtime/locale/th.d.ts +2 -0
- package/dist/runtime/locale/th.js +54 -0
- package/dist/runtime/locale/tr.d.ts +2 -0
- package/dist/runtime/locale/tr.js +54 -0
- package/dist/runtime/locale/uk.d.ts +2 -0
- package/dist/runtime/locale/uk.js +54 -0
- package/dist/runtime/locale/vi.d.ts +2 -0
- package/dist/runtime/locale/vi.js +54 -0
- package/dist/runtime/locale/zh_cn.d.ts +2 -0
- package/dist/runtime/locale/{zh_hans.js → zh_cn.js} +10 -2
- package/dist/runtime/locale/zh_tw.d.ts +2 -0
- package/dist/runtime/locale/{zh_hant.js → zh_tw.js} +16 -8
- package/dist/runtime/plugins/colors.js +8 -5
- package/dist/runtime/types/form.d.ts +24 -15
- package/dist/runtime/types/form.js +2 -2
- package/dist/runtime/types/index.d.ts +5 -0
- package/dist/runtime/types/index.js +5 -0
- package/dist/runtime/types/locale.d.ts +8 -0
- package/dist/runtime/types/utils.d.ts +7 -3
- package/dist/runtime/utils/form.d.ts +4 -4
- package/dist/runtime/utils/form.js +6 -8
- package/dist/runtime/utils/index.d.ts +1 -1
- package/dist/runtime/utils/index.js +15 -2
- package/dist/runtime/utils/tv.d.ts +1 -0
- package/dist/runtime/utils/tv.js +4 -0
- package/dist/runtime/vue/components/Icon.vue +2 -2
- package/dist/runtime/vue/components/Link.vue +87 -23
- package/dist/runtime/vue/composables/useAppConfig.d.ts +1 -0
- package/dist/runtime/vue/composables/useAppConfig.js +2 -0
- package/dist/runtime/vue/plugins/head.d.ts +1 -1
- package/dist/runtime/vue/plugins/head.js +3 -3
- package/dist/runtime/vue/stubs.d.ts +19 -0
- package/dist/runtime/vue/stubs.js +37 -0
- package/dist/shared/{ui.d52SSCwA.mjs → ui.DSPu6Y8j.mjs} +905 -401
- package/dist/shared/{ui.BPnAe4QS.cjs → ui.DfK2RX6G.cjs} +908 -401
- package/dist/unplugin.cjs +62 -26
- package/dist/unplugin.d.cts +13 -1
- package/dist/unplugin.d.mts +13 -1
- package/dist/unplugin.d.ts +13 -1
- package/dist/unplugin.mjs +61 -25
- package/dist/vite.cjs +3 -2
- package/dist/vite.d.cts +2 -0
- package/dist/vite.d.mts +2 -0
- package/dist/vite.d.ts +2 -0
- package/dist/vite.mjs +3 -2
- package/package.json +103 -67
- package/dist/chunks/component-meta.cjs +0 -77249
- package/dist/chunks/component-meta.mjs +0 -77247
- package/dist/client/devtools/200.html +0 -1
- package/dist/client/devtools/404.html +0 -1
- package/dist/client/devtools/_fonts/rP2Wp2ywxg089UriCZaSExd86J3t9jz86MvyyKK58UfivUw4aw-SK92LTmKP0.woff2 +0 -0
- package/dist/client/devtools/_fonts/rP2Wp2ywxg089UriCZaSExd86J3t9jz86MvyyKy58UfivUw-9uYm8d48E4.woff2 +0 -0
- package/dist/client/devtools/_fonts/rP2Yp2ywxg089UriI5-g4vlH9VoD8Cmcqbu0-K6z9mXg-VNw7NHvqnp.woff2 +0 -0
- package/dist/client/devtools/_fonts/rP2Yp2ywxg089UriI5-g4vlH9VoD8Cmcqbu6-K6z9mXgjU0-EkYdMs3MAX.woff2 +0 -0
- package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-7DW3w-R7n06NbhGy.woff +0 -0
- package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-JDG3w-leGNfkTmsj.woff +0 -0
- package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat-JDW3w-ciElMF03ku.woff +0 -0
- package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8JCm3w-sB722Uoa0f.woff +0 -0
- package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8JDW3w-PBDI1JDjwV.woff +0 -0
- package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat8gCm3w-0q1hqVn09O.woff +0 -0
- package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat9XCm3w-ByvzuLy2fa.woff +0 -0
- package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat9uCm3w-5TKCIs6EEw.woff +0 -0
- package/dist/client/devtools/_fonts/rP2rp2ywxg089UriCZaSExd86J3t9jz86Mvy4qCRAL19DksVat_XDW3w-r2swRDGfn2.woff +0 -0
- package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAC5thTQ-ldB60l5U8r.woff +0 -0
- package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAIpthTQ-wbFKGFDrgo.woff +0 -0
- package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAIpxhTQ-LLUBv5jskj.woff +0 -0
- package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwARZthTQ-F71RdTRbNg.woff +0 -0
- package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwA_JxhTQ-6nh65gZkc0.woff +0 -0
- package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAfJthTQ-aMoWEJLmTt.woff +0 -0
- package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAkJxhTQ-WMBvmLOgKm.woff +0 -0
- package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAop1hTQ-utGC2hnWq2.woff +0 -0
- package/dist/client/devtools/_fonts/rP2tp2ywxg089UriI5-g4vlH9VoD8CmcqZG40F9JadbnoEwAopxhTQ-YpyTieVa5B.woff +0 -0
- package/dist/client/devtools/_nuxt/BDC8ywlR.js +0 -1
- package/dist/client/devtools/_nuxt/BT004Uxp.js +0 -53
- package/dist/client/devtools/_nuxt/C1H2Soz3.js +0 -1
- package/dist/client/devtools/_nuxt/builds/latest.json +0 -1
- package/dist/client/devtools/_nuxt/builds/meta/f98c13ea-d751-4b37-8ce3-94e99708745f.json +0 -1
- package/dist/client/devtools/_nuxt/entry.Bx6WJjrx.css +0 -1
- package/dist/client/devtools/_nuxt/error-404.Cq4qshcf.css +0 -1
- package/dist/client/devtools/_nuxt/error-500.ax1aM34m.css +0 -1
- package/dist/client/devtools/favicon.svg +0 -1
- package/dist/client/devtools/index.html +0 -1
- package/dist/devtools/runtime/DevtoolsRenderer.vue +0 -53
- package/dist/devtools/runtime/examples/AvatarGroupExample.vue +0 -7
- package/dist/devtools/runtime/examples/ButtonGroupExample.vue +0 -8
- package/dist/devtools/runtime/examples/CardExample.vue +0 -13
- package/dist/devtools/runtime/examples/CarouselExample.vue +0 -13
- package/dist/devtools/runtime/examples/ChipExample.vue +0 -5
- package/dist/devtools/runtime/examples/CollapsibleExample.vue +0 -8
- package/dist/devtools/runtime/examples/CommandPaletteExample.vue +0 -29
- package/dist/devtools/runtime/examples/ContainerExample.vue +0 -5
- package/dist/devtools/runtime/examples/ContextMenuExample.vue +0 -5
- package/dist/devtools/runtime/examples/DrawerExample.vue +0 -8
- package/dist/devtools/runtime/examples/DropdownMenuExample.vue +0 -5
- package/dist/devtools/runtime/examples/FormExample.vue +0 -30
- package/dist/devtools/runtime/examples/FormFieldExample.vue +0 -5
- package/dist/devtools/runtime/examples/LinkExample.vue +0 -5
- package/dist/devtools/runtime/examples/ModalExample.vue +0 -8
- package/dist/devtools/runtime/examples/PopoverExample.vue +0 -8
- package/dist/devtools/runtime/examples/SkeletonExample.vue +0 -3
- package/dist/devtools/runtime/examples/SlideoverExample.vue +0 -8
- package/dist/devtools/runtime/examples/ToasterExample.vue +0 -11
- package/dist/devtools/runtime/examples/TooltipExample.vue +0 -5
- package/dist/runtime/components/ModalProvider.vue +0 -12
- package/dist/runtime/components/SlideoverProvider.vue +0 -12
- package/dist/runtime/composables/extendDevtoolsMeta.d.ts +0 -7
- package/dist/runtime/composables/extendDevtoolsMeta.js +0 -2
- package/dist/runtime/composables/useModal.d.ts +0 -17
- package/dist/runtime/composables/useModal.js +0 -46
- package/dist/runtime/composables/useSlideover.d.ts +0 -17
- package/dist/runtime/composables/useSlideover.js +0 -46
- package/dist/runtime/plugins/modal.d.ts +0 -2
- package/dist/runtime/plugins/modal.js +0 -10
- package/dist/runtime/plugins/slideover.d.ts +0 -2
- package/dist/runtime/plugins/slideover.js +0 -10
- /package/dist/runtime/locale/{zh_hans.d.ts → az.d.ts} +0 -0
- /package/dist/runtime/locale/{zh_hant.d.ts → bn.d.ts} +0 -0
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import type { ComboboxRootProps, ComboboxRootEmits, ComboboxContentProps, ComboboxArrowProps } from '
|
|
2
|
+
import type { VariantProps } from 'tailwind-variants'
|
|
3
|
+
import type { ComboboxRootProps, ComboboxRootEmits, ComboboxContentProps, ComboboxArrowProps, AcceptableValue } from 'reka-ui'
|
|
4
4
|
import type { AppConfig } from '@nuxt/schema'
|
|
5
5
|
import _appConfig from '#build/app.config'
|
|
6
6
|
import theme from '#build/ui/select-menu'
|
|
7
7
|
import type { UseComponentIconsProps } from '../composables/useComponentIcons'
|
|
8
|
-
import {
|
|
8
|
+
import { tv } from '../utils/tv'
|
|
9
9
|
import type { AvatarProps, ChipProps, InputProps } from '../types'
|
|
10
|
-
import type {
|
|
10
|
+
import type { PartialString, MaybeArrayOfArray, MaybeArrayOfArrayItem, SelectModelValue, SelectModelValueEmits, SelectItemKey } from '../types/utils'
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const appConfigSelectMenu = _appConfig as AppConfig & { ui: { selectMenu: Partial<typeof theme> } }
|
|
13
13
|
|
|
14
|
-
const selectMenu = tv({ extend: tv(theme), ...(
|
|
14
|
+
const selectMenu = tv({ extend: tv(theme), ...(appConfigSelectMenu.ui?.selectMenu || {}) })
|
|
15
15
|
|
|
16
16
|
export interface SelectMenuItem {
|
|
17
17
|
label?: string
|
|
@@ -29,7 +29,7 @@ export interface SelectMenuItem {
|
|
|
29
29
|
|
|
30
30
|
type SelectMenuVariants = VariantProps<typeof selectMenu>
|
|
31
31
|
|
|
32
|
-
export interface SelectMenuProps<T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<SelectMenuItem | AcceptableValue> = MaybeArrayOfArray<SelectMenuItem | AcceptableValue>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false> extends Pick<ComboboxRootProps<T>, '
|
|
32
|
+
export interface SelectMenuProps<T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<SelectMenuItem | AcceptableValue | boolean> = MaybeArrayOfArray<SelectMenuItem | AcceptableValue | boolean>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false> extends Pick<ComboboxRootProps<T>, 'open' | 'defaultOpen' | 'disabled' | 'name' | 'resetSearchTermOnBlur' | 'highlightOnHover'>, UseComponentIconsProps {
|
|
33
33
|
id?: string
|
|
34
34
|
/** The placeholder text when the select is empty. */
|
|
35
35
|
placeholder?: string
|
|
@@ -56,7 +56,7 @@ export interface SelectMenuProps<T extends MaybeArrayOfArrayItem<I>, I extends M
|
|
|
56
56
|
selectedIcon?: string
|
|
57
57
|
/**
|
|
58
58
|
* The content of the menu.
|
|
59
|
-
* @defaultValue { side: 'bottom', sideOffset: 8, position: 'popper' }
|
|
59
|
+
* @defaultValue { side: 'bottom', sideOffset: 8, collisionPadding: 8, position: 'popper' }
|
|
60
60
|
*/
|
|
61
61
|
content?: Omit<ComboboxContentProps, 'as' | 'asChild' | 'forceMount'>
|
|
62
62
|
/**
|
|
@@ -69,13 +69,6 @@ export interface SelectMenuProps<T extends MaybeArrayOfArrayItem<I>, I extends M
|
|
|
69
69
|
* @defaultValue true
|
|
70
70
|
*/
|
|
71
71
|
portal?: boolean
|
|
72
|
-
/**
|
|
73
|
-
* Whether to filter items or not, can be an array of fields to filter. Defaults to `[labelKey]`.
|
|
74
|
-
* When `false`, items will not be filtered which is useful for custom filtering (useAsyncData, useFetch, etc.).
|
|
75
|
-
* `['label']`{lang="ts-type"}
|
|
76
|
-
* @defaultValue true
|
|
77
|
-
*/
|
|
78
|
-
filter?: boolean | string[]
|
|
79
72
|
/**
|
|
80
73
|
* When `items` is an array of objects, select the field to use as the value instead of the object itself.
|
|
81
74
|
* @defaultValue undefined
|
|
@@ -87,94 +80,101 @@ export interface SelectMenuProps<T extends MaybeArrayOfArrayItem<I>, I extends M
|
|
|
87
80
|
*/
|
|
88
81
|
labelKey?: V
|
|
89
82
|
items?: I
|
|
83
|
+
/** The value of the SelectMenu when initially rendered. Use when you do not need to control the state of the SelectMenu. */
|
|
84
|
+
defaultValue?: SelectModelValue<T, V, M>
|
|
85
|
+
/** The controlled value of the SelectMenu. Can be binded-with with `v-model`. */
|
|
86
|
+
modelValue?: SelectModelValue<T, V, M>
|
|
87
|
+
/** Whether multiple options can be selected or not. */
|
|
88
|
+
multiple?: M & boolean
|
|
90
89
|
/** Highlight the ring color like a focus state. */
|
|
91
90
|
highlight?: boolean
|
|
92
91
|
/**
|
|
93
92
|
* Determines if custom user input that does not exist in options can be added.
|
|
94
93
|
* @defaultValue false
|
|
95
94
|
*/
|
|
96
|
-
createItem?: boolean | 'always' | {
|
|
95
|
+
createItem?: boolean | 'always' | { position?: 'top' | 'bottom', when?: 'empty' | 'always' }
|
|
96
|
+
/**
|
|
97
|
+
* Fields to filter items by.
|
|
98
|
+
* @defaultValue [labelKey]
|
|
99
|
+
*/
|
|
100
|
+
filterFields?: string[]
|
|
101
|
+
/**
|
|
102
|
+
* When `true`, disable the default filters, useful for custom filtering (useAsyncData, useFetch, etc.).
|
|
103
|
+
* @defaultValue false
|
|
104
|
+
*/
|
|
105
|
+
ignoreFilter?: boolean
|
|
97
106
|
class?: any
|
|
98
107
|
ui?: PartialString<typeof selectMenu.slots>
|
|
99
|
-
/** The controlled value of the Combobox. Can be binded-with with `v-model`. */
|
|
100
|
-
modelValue?: SelectModelValue<T, V, M>
|
|
101
|
-
/** Whether multiple options can be selected or not. */
|
|
102
|
-
multiple?: M
|
|
103
108
|
}
|
|
104
109
|
|
|
105
110
|
export type SelectMenuEmits<T, V, M extends boolean> = Omit<ComboboxRootEmits<T>, 'update:modelValue'> & {
|
|
106
111
|
change: [payload: Event]
|
|
107
112
|
blur: [payload: FocusEvent]
|
|
108
113
|
focus: [payload: FocusEvent]
|
|
109
|
-
create: [
|
|
114
|
+
create: [item: string]
|
|
110
115
|
} & SelectModelValueEmits<T, V, M>
|
|
111
116
|
|
|
112
117
|
type SlotProps<T> = (props: { item: T, index: number }) => any
|
|
113
118
|
|
|
114
|
-
export interface SelectMenuSlots<T> {
|
|
115
|
-
'leading'(props: { modelValue: T, open: boolean, ui: any }): any
|
|
116
|
-
'default'(props: { modelValue: T, open: boolean }): any
|
|
117
|
-
'trailing'(props: { modelValue: T, open: boolean, ui: any }): any
|
|
119
|
+
export interface SelectMenuSlots<T, M extends boolean> {
|
|
120
|
+
'leading'(props: { modelValue?: M extends true ? T[] : T, open: boolean, ui: any }): any
|
|
121
|
+
'default'(props: { modelValue?: M extends true ? T[] : T, open: boolean }): any
|
|
122
|
+
'trailing'(props: { modelValue?: M extends true ? T[] : T, open: boolean, ui: any }): any
|
|
118
123
|
'empty'(props: { searchTerm?: string }): any
|
|
119
124
|
'item': SlotProps<T>
|
|
120
125
|
'item-leading': SlotProps<T>
|
|
121
126
|
'item-label': SlotProps<T>
|
|
122
127
|
'item-trailing': SlotProps<T>
|
|
123
|
-
'create-item-label'(props: { item:
|
|
128
|
+
'create-item-label'(props: { item: string }): any
|
|
124
129
|
}
|
|
125
|
-
|
|
126
|
-
extendDevtoolsMeta({ defaultProps: { items: ['Option 1', 'Option 2', 'Option 3'] } })
|
|
127
130
|
</script>
|
|
128
131
|
|
|
129
|
-
<script setup lang="ts" generic="T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<SelectMenuItem | AcceptableValue> = MaybeArrayOfArray<SelectMenuItem | AcceptableValue>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false">
|
|
132
|
+
<script setup lang="ts" generic="T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<SelectMenuItem | AcceptableValue | boolean> = MaybeArrayOfArray<SelectMenuItem | AcceptableValue | boolean>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false">
|
|
130
133
|
import { computed, toRef, toRaw } from 'vue'
|
|
131
|
-
import { ComboboxRoot, ComboboxArrow, ComboboxAnchor, ComboboxInput, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxViewport, ComboboxEmpty, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxItem, ComboboxItemIndicator, useForwardPropsEmits } from '
|
|
134
|
+
import { ComboboxRoot, ComboboxArrow, ComboboxAnchor, ComboboxInput, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxViewport, ComboboxEmpty, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxItem, ComboboxItemIndicator, FocusScope, useForwardPropsEmits, useFilter } from 'reka-ui'
|
|
132
135
|
import { defu } from 'defu'
|
|
133
|
-
import { isEqual } from 'ohash'
|
|
134
136
|
import { reactivePick, createReusableTemplate } from '@vueuse/core'
|
|
135
137
|
import { useAppConfig } from '#imports'
|
|
136
138
|
import { useButtonGroup } from '../composables/useButtonGroup'
|
|
137
139
|
import { useComponentIcons } from '../composables/useComponentIcons'
|
|
138
140
|
import { useFormField } from '../composables/useFormField'
|
|
139
141
|
import { useLocale } from '../composables/useLocale'
|
|
140
|
-
import { get,
|
|
142
|
+
import { get, compare } from '../utils'
|
|
141
143
|
import UIcon from './Icon.vue'
|
|
142
144
|
import UAvatar from './Avatar.vue'
|
|
143
145
|
import UChip from './Chip.vue'
|
|
144
146
|
import UInput from './Input.vue'
|
|
145
147
|
|
|
148
|
+
defineOptions({ inheritAttrs: false })
|
|
149
|
+
|
|
146
150
|
const props = withDefaults(defineProps<SelectMenuProps<T, I, V, M>>(), {
|
|
147
|
-
search: true,
|
|
148
151
|
portal: true,
|
|
149
|
-
autofocusDelay: 0,
|
|
150
152
|
searchInput: true,
|
|
151
|
-
|
|
152
|
-
|
|
153
|
+
labelKey: 'label' as never,
|
|
154
|
+
resetSearchTermOnBlur: true
|
|
153
155
|
})
|
|
154
|
-
|
|
155
156
|
const emits = defineEmits<SelectMenuEmits<T, V, M>>()
|
|
156
|
-
const slots = defineSlots<SelectMenuSlots<T>>()
|
|
157
|
+
const slots = defineSlots<SelectMenuSlots<T, M>>()
|
|
157
158
|
|
|
158
159
|
const searchTerm = defineModel<string>('searchTerm', { default: '' })
|
|
159
160
|
|
|
161
|
+
const { t } = useLocale()
|
|
160
162
|
const appConfig = useAppConfig()
|
|
163
|
+
const { contains } = useFilter({ sensitivity: 'base' })
|
|
161
164
|
|
|
162
|
-
const
|
|
163
|
-
const
|
|
164
|
-
const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8, position: 'popper' }) as ComboboxContentProps)
|
|
165
|
+
const rootProps = useForwardPropsEmits(reactivePick(props, 'modelValue', 'defaultValue', 'open', 'defaultOpen', 'multiple', 'resetSearchTermOnBlur', 'highlightOnHover'), emits)
|
|
166
|
+
const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8, collisionPadding: 8, position: 'popper' }) as ComboboxContentProps)
|
|
165
167
|
const arrowProps = toRef(() => props.arrow as ComboboxArrowProps)
|
|
166
|
-
const searchInputProps = toRef(() => defu(props.searchInput, { placeholder: '
|
|
167
|
-
// This is a hack due to generic boolean casting (see https://github.com/nuxt/ui/issues/2541)
|
|
168
|
-
const multiple = toRef(() => typeof props.multiple === 'string' ? true : props.multiple)
|
|
169
|
-
|
|
170
|
-
const [DefineCreateItemTemplate, ReuseCreateItemTemplate] = createReusableTemplate()
|
|
168
|
+
const searchInputProps = toRef(() => defu(props.searchInput, { placeholder: t('selectMenu.search'), variant: 'none' }) as InputProps)
|
|
171
169
|
|
|
172
|
-
const { emitFormBlur, emitFormInput, emitFormChange, size: formGroupSize, color, id, name, highlight, disabled } = useFormField<InputProps>(props)
|
|
170
|
+
const { emitFormBlur, emitFormFocus, emitFormInput, emitFormChange, size: formGroupSize, color, id, name, highlight, disabled, ariaAttrs } = useFormField<InputProps>(props)
|
|
173
171
|
const { orientation, size: buttonGroupSize } = useButtonGroup<InputProps>(props)
|
|
174
172
|
const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(toRef(() => defu(props, { trailingIcon: appConfig.ui.icons.chevronDown })))
|
|
175
173
|
|
|
176
174
|
const selectSize = computed(() => buttonGroupSize.value || formGroupSize.value)
|
|
177
175
|
|
|
176
|
+
const [DefineCreateItemTemplate, ReuseCreateItemTemplate] = createReusableTemplate()
|
|
177
|
+
|
|
178
178
|
const ui = computed(() => selectMenu({
|
|
179
179
|
color: color.value,
|
|
180
180
|
variant: props.variant,
|
|
@@ -187,7 +187,7 @@ const ui = computed(() => selectMenu({
|
|
|
187
187
|
}))
|
|
188
188
|
|
|
189
189
|
function displayValue(value: T | T[]): string {
|
|
190
|
-
if (multiple
|
|
190
|
+
if (props.multiple && Array.isArray(value)) {
|
|
191
191
|
return value.map(v => displayValue(v)).filter(Boolean).join(', ')
|
|
192
192
|
}
|
|
193
193
|
|
|
@@ -195,69 +195,49 @@ function displayValue(value: T | T[]): string {
|
|
|
195
195
|
return value && (typeof value === 'object' ? get(value, props.labelKey as string) : value)
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
const item = items.value.find(item =>
|
|
199
|
-
|
|
198
|
+
const item = items.value.find(item => compare(typeof item === 'object' ? get(item as Record<string, any>, props.valueKey as string) : item, value))
|
|
200
199
|
return item && (typeof item === 'object' ? get(item, props.labelKey as string) : item)
|
|
201
200
|
}
|
|
202
201
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
)
|
|
208
|
-
if (props.
|
|
209
|
-
return
|
|
202
|
+
const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0]) ? props.items : [props.items]) as SelectMenuItem[][] : [])
|
|
203
|
+
// eslint-disable-next-line vue/no-dupe-keys
|
|
204
|
+
const items = computed(() => groups.value.flatMap(group => group) as T[])
|
|
205
|
+
|
|
206
|
+
const filteredGroups = computed(() => {
|
|
207
|
+
if (props.ignoreFilter || !searchTerm.value) {
|
|
208
|
+
return groups.value
|
|
210
209
|
}
|
|
211
210
|
|
|
212
|
-
const fields = Array.isArray(props.
|
|
213
|
-
const escapedSearchTerm = escapeRegExp(filterSearchTerm)
|
|
211
|
+
const fields = Array.isArray(props.filterFields) ? props.filterFields : [props.labelKey] as string[]
|
|
214
212
|
|
|
215
|
-
return
|
|
213
|
+
return groups.value.map(items => items.filter((item) => {
|
|
216
214
|
if (typeof item !== 'object') {
|
|
217
|
-
return
|
|
215
|
+
return contains(item, searchTerm.value)
|
|
218
216
|
}
|
|
219
217
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
return child !== null && child !== undefined && comparator(child, escapedSearchTerm)
|
|
224
|
-
})
|
|
225
|
-
}) as ArrayOrWrapped<T>
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0]) ? props.items : [props.items]) as SelectMenuItem[][] : [])
|
|
229
|
-
// eslint-disable-next-line vue/no-dupe-keys
|
|
230
|
-
const items = computed(() => groups.value.flatMap(group => group) as T[])
|
|
231
|
-
|
|
232
|
-
const creatable = computed(() => {
|
|
233
|
-
if (!props.createItem) {
|
|
234
|
-
return false
|
|
235
|
-
}
|
|
218
|
+
if (item.type && ['label', 'separator'].includes(item.type)) {
|
|
219
|
+
return true
|
|
220
|
+
}
|
|
236
221
|
|
|
237
|
-
|
|
222
|
+
return fields.some(field => contains(get(item, field), searchTerm.value))
|
|
223
|
+
})).filter(group => group.filter(item => !item.type || !['label', 'separator'].includes(item.type)).length > 0)
|
|
224
|
+
})
|
|
225
|
+
const filteredItems = computed(() => filteredGroups.value.flatMap(group => group) as T[])
|
|
238
226
|
|
|
239
|
-
|
|
227
|
+
const createItem = computed(() => {
|
|
228
|
+
if (!props.createItem || !searchTerm.value) {
|
|
240
229
|
return false
|
|
241
230
|
}
|
|
242
231
|
|
|
243
|
-
const
|
|
244
|
-
const newItem = searchTerm.value && {
|
|
245
|
-
item: props.valueKey ? { [props.valueKey]: searchTerm.value, [props.labelKey ?? 'label']: searchTerm.value } : searchTerm.value,
|
|
246
|
-
position: ((typeof props.createItem === 'object' && props.createItem.placement) || 'bottom') as 'top' | 'bottom'
|
|
247
|
-
}
|
|
232
|
+
const newItem = props.valueKey ? { [props.valueKey]: searchTerm.value } as T : searchTerm.value
|
|
248
233
|
|
|
249
234
|
if ((typeof props.createItem === 'object' && props.createItem.when === 'always') || props.createItem === 'always') {
|
|
250
|
-
return
|
|
235
|
+
return !filteredItems.value.find(item => compare(item, newItem, props.valueKey))
|
|
251
236
|
}
|
|
252
237
|
|
|
253
|
-
return filteredItems.length
|
|
238
|
+
return !filteredItems.value.length
|
|
254
239
|
})
|
|
255
|
-
|
|
256
|
-
const rootItems = computed(() => [
|
|
257
|
-
...(creatable.value && creatable.value.position === 'top' ? [creatable.value.item] : []),
|
|
258
|
-
...filterFunction(),
|
|
259
|
-
...(creatable.value && creatable.value.position === 'bottom' ? [creatable.value.item] : [])
|
|
260
|
-
] as ArrayOrWrapped<T>)
|
|
240
|
+
const createItemPosition = computed(() => typeof props.createItem === 'object' ? props.createItem.position : 'bottom')
|
|
261
241
|
|
|
262
242
|
function onUpdate(value: any) {
|
|
263
243
|
if (toRaw(props.modelValue) === value) {
|
|
@@ -271,28 +251,44 @@ function onUpdate(value: any) {
|
|
|
271
251
|
}
|
|
272
252
|
|
|
273
253
|
function onUpdateOpen(value: boolean) {
|
|
254
|
+
let timeoutId
|
|
255
|
+
|
|
274
256
|
if (!value) {
|
|
275
257
|
const event = new FocusEvent('blur')
|
|
258
|
+
|
|
276
259
|
emits('blur', event)
|
|
277
260
|
emitFormBlur()
|
|
261
|
+
|
|
262
|
+
// Since we use `displayValue` prop inside ComboboxInput we should reset searchTerm manually
|
|
263
|
+
// https://reka-ui.com/docs/components/combobox#api-reference
|
|
264
|
+
if (props.resetSearchTermOnBlur) {
|
|
265
|
+
const STATE_ANIMATION_DELAY_MS = 100
|
|
266
|
+
|
|
267
|
+
timeoutId = setTimeout(() => {
|
|
268
|
+
searchTerm.value = ''
|
|
269
|
+
}, STATE_ANIMATION_DELAY_MS)
|
|
270
|
+
}
|
|
278
271
|
} else {
|
|
279
272
|
const event = new FocusEvent('focus')
|
|
280
273
|
emits('focus', event)
|
|
274
|
+
emitFormFocus()
|
|
275
|
+
clearTimeout(timeoutId)
|
|
281
276
|
}
|
|
282
277
|
}
|
|
283
278
|
</script>
|
|
284
279
|
|
|
280
|
+
<!-- eslint-disable vue/no-template-shadow -->
|
|
285
281
|
<template>
|
|
286
282
|
<DefineCreateItemTemplate>
|
|
287
|
-
<ComboboxGroup
|
|
283
|
+
<ComboboxGroup :class="ui.group({ class: props.ui?.group })">
|
|
288
284
|
<ComboboxItem
|
|
289
285
|
:class="ui.item({ class: props.ui?.item })"
|
|
290
|
-
:value="
|
|
291
|
-
@select="
|
|
286
|
+
:value="searchTerm"
|
|
287
|
+
@select.prevent="emits('create', searchTerm)"
|
|
292
288
|
>
|
|
293
289
|
<span :class="ui.itemLabel({ class: props.ui?.itemLabel })">
|
|
294
|
-
<slot name="create-item-label" :item="
|
|
295
|
-
{{ t('selectMenu.create', { label:
|
|
290
|
+
<slot name="create-item-label" :item="searchTerm">
|
|
291
|
+
{{ t('selectMenu.create', { label: searchTerm }) }}
|
|
296
292
|
</slot>
|
|
297
293
|
</span>
|
|
298
294
|
</ComboboxItem>
|
|
@@ -302,28 +298,25 @@ function onUpdateOpen(value: boolean) {
|
|
|
302
298
|
<ComboboxRoot
|
|
303
299
|
:id="id"
|
|
304
300
|
v-slot="{ modelValue, open }"
|
|
305
|
-
v-bind="rootProps"
|
|
306
|
-
|
|
301
|
+
v-bind="{ ...rootProps, ...$attrs, ...ariaAttrs }"
|
|
302
|
+
ignore-filter
|
|
307
303
|
as-child
|
|
308
304
|
:name="name"
|
|
309
305
|
:disabled="disabled"
|
|
310
|
-
:multiple="multiple"
|
|
311
|
-
:display-value="() => searchTerm"
|
|
312
|
-
:filter-function="() => rootItems"
|
|
313
306
|
@update:model-value="onUpdate"
|
|
314
307
|
@update:open="onUpdateOpen"
|
|
315
308
|
>
|
|
316
309
|
<ComboboxAnchor as-child>
|
|
317
310
|
<ComboboxTrigger :class="ui.base({ class: [props.class, props.ui?.base] })" tabindex="0">
|
|
318
311
|
<span v-if="isLeading || !!avatar || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })">
|
|
319
|
-
<slot name="leading" :model-value="(modelValue as T)" :open="open" :ui="ui">
|
|
312
|
+
<slot name="leading" :model-value="(modelValue as M extends true ? T[] : T)" :open="open" :ui="ui">
|
|
320
313
|
<UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
|
|
321
314
|
<UAvatar v-else-if="!!avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
|
322
315
|
</slot>
|
|
323
316
|
</span>
|
|
324
317
|
|
|
325
|
-
<slot :model-value="(modelValue as T)" :open="open">
|
|
326
|
-
<template v-for="displayedModelValue in [displayValue(modelValue)]" :key="displayedModelValue">
|
|
318
|
+
<slot :model-value="(modelValue as M extends true ? T[] : T)" :open="open">
|
|
319
|
+
<template v-for="displayedModelValue in [displayValue(modelValue as M extends true ? T[] : T)]" :key="displayedModelValue">
|
|
327
320
|
<span v-if="displayedModelValue" :class="ui.value({ class: props.ui?.value })">
|
|
328
321
|
{{ displayedModelValue }}
|
|
329
322
|
</span>
|
|
@@ -334,7 +327,7 @@ function onUpdateOpen(value: boolean) {
|
|
|
334
327
|
</slot>
|
|
335
328
|
|
|
336
329
|
<span v-if="isTrailing || !!slots.trailing" :class="ui.trailing({ class: props.ui?.trailing })">
|
|
337
|
-
<slot name="trailing" :model-value="(modelValue as T)" :open="open" :ui="ui">
|
|
330
|
+
<slot name="trailing" :model-value="(modelValue as M extends true ? T[] : T)" :open="open" :ui="ui">
|
|
338
331
|
<UIcon v-if="trailingIconName" :name="trailingIconName" :class="ui.trailingIcon({ class: props.ui?.trailingIcon })" />
|
|
339
332
|
</slot>
|
|
340
333
|
</span>
|
|
@@ -343,68 +336,70 @@ function onUpdateOpen(value: boolean) {
|
|
|
343
336
|
|
|
344
337
|
<ComboboxPortal :disabled="!portal">
|
|
345
338
|
<ComboboxContent :class="ui.content({ class: props.ui?.content })" v-bind="contentProps">
|
|
346
|
-
<
|
|
347
|
-
<
|
|
348
|
-
|
|
339
|
+
<FocusScope trapped :class="ui.focusScope({ class: props.ui?.focusScope })">
|
|
340
|
+
<ComboboxInput v-if="!!searchInput" v-model="searchTerm" :display-value="() => searchTerm" as-child>
|
|
341
|
+
<UInput autofocus autocomplete="off" v-bind="searchInputProps" :class="ui.input({ class: props.ui?.input })" />
|
|
342
|
+
</ComboboxInput>
|
|
343
|
+
|
|
344
|
+
<ComboboxEmpty :class="ui.empty({ class: props.ui?.empty })">
|
|
345
|
+
<slot name="empty" :search-term="searchTerm">
|
|
346
|
+
{{ searchTerm ? t('selectMenu.noMatch', { searchTerm }) : t('selectMenu.noData') }}
|
|
347
|
+
</slot>
|
|
348
|
+
</ComboboxEmpty>
|
|
349
|
+
|
|
350
|
+
<ComboboxViewport :class="ui.viewport({ class: props.ui?.viewport })">
|
|
351
|
+
<ReuseCreateItemTemplate v-if="createItem && createItemPosition === 'top'" />
|
|
352
|
+
|
|
353
|
+
<ComboboxGroup v-for="(group, groupIndex) in filteredGroups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
|
|
354
|
+
<template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
|
|
355
|
+
<ComboboxLabel v-if="item?.type === 'label'" :class="ui.label({ class: props.ui?.label })">
|
|
356
|
+
{{ get(item, props.labelKey as string) }}
|
|
357
|
+
</ComboboxLabel>
|
|
358
|
+
|
|
359
|
+
<ComboboxSeparator v-else-if="item?.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
|
|
360
|
+
|
|
361
|
+
<ComboboxItem
|
|
362
|
+
v-else
|
|
363
|
+
:class="ui.item({ class: props.ui?.item })"
|
|
364
|
+
:disabled="item.disabled"
|
|
365
|
+
:value="valueKey && typeof item === 'object' ? get(item, props.valueKey as string) : item"
|
|
366
|
+
@select="item.onSelect"
|
|
367
|
+
>
|
|
368
|
+
<slot name="item" :item="(item as T)" :index="index">
|
|
369
|
+
<slot name="item-leading" :item="(item as T)" :index="index">
|
|
370
|
+
<UIcon v-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
|
|
371
|
+
<UAvatar v-else-if="item.avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
|
372
|
+
<UChip
|
|
373
|
+
v-else-if="item.chip"
|
|
374
|
+
:size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
|
|
375
|
+
inset
|
|
376
|
+
standalone
|
|
377
|
+
v-bind="item.chip"
|
|
378
|
+
:class="ui.itemLeadingChip({ class: props.ui?.itemLeadingChip })"
|
|
379
|
+
/>
|
|
380
|
+
</slot>
|
|
349
381
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
</ComboboxLabel>
|
|
364
|
-
|
|
365
|
-
<ComboboxSeparator v-else-if="item?.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
|
|
366
|
-
|
|
367
|
-
<ComboboxItem
|
|
368
|
-
v-else
|
|
369
|
-
:class="ui.item({ class: props.ui?.item })"
|
|
370
|
-
:disabled="item.disabled"
|
|
371
|
-
:value="valueKey && typeof item === 'object' ? get(item, props.valueKey as string) : item"
|
|
372
|
-
@select="item.onSelect"
|
|
373
|
-
>
|
|
374
|
-
<slot name="item" :item="(item as T)" :index="index">
|
|
375
|
-
<slot name="item-leading" :item="(item as T)" :index="index">
|
|
376
|
-
<UIcon v-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
|
|
377
|
-
<UAvatar v-else-if="item.avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
|
378
|
-
<UChip
|
|
379
|
-
v-else-if="item.chip"
|
|
380
|
-
:size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
|
|
381
|
-
inset
|
|
382
|
-
standalone
|
|
383
|
-
v-bind="item.chip"
|
|
384
|
-
:class="ui.itemLeadingChip({ class: props.ui?.itemLeadingChip })"
|
|
385
|
-
/>
|
|
382
|
+
<span :class="ui.itemLabel({ class: props.ui?.itemLabel })">
|
|
383
|
+
<slot name="item-label" :item="(item as T)" :index="index">
|
|
384
|
+
{{ typeof item === 'object' ? get(item, props.labelKey as string) : item }}
|
|
385
|
+
</slot>
|
|
386
|
+
</span>
|
|
387
|
+
|
|
388
|
+
<span :class="ui.itemTrailing({ class: props.ui?.itemTrailing })">
|
|
389
|
+
<slot name="item-trailing" :item="(item as T)" :index="index" />
|
|
390
|
+
|
|
391
|
+
<ComboboxItemIndicator as-child>
|
|
392
|
+
<UIcon :name="selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: props.ui?.itemTrailingIcon })" />
|
|
393
|
+
</ComboboxItemIndicator>
|
|
394
|
+
</span>
|
|
386
395
|
</slot>
|
|
396
|
+
</ComboboxItem>
|
|
397
|
+
</template>
|
|
398
|
+
</ComboboxGroup>
|
|
387
399
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
</slot>
|
|
392
|
-
</span>
|
|
393
|
-
|
|
394
|
-
<span :class="ui.itemTrailing({ class: props.ui?.itemTrailing })">
|
|
395
|
-
<slot name="item-trailing" :item="(item as T)" :index="index" />
|
|
396
|
-
|
|
397
|
-
<ComboboxItemIndicator as-child>
|
|
398
|
-
<UIcon :name="selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: props.ui?.itemTrailingIcon })" />
|
|
399
|
-
</ComboboxItemIndicator>
|
|
400
|
-
</span>
|
|
401
|
-
</slot>
|
|
402
|
-
</ComboboxItem>
|
|
403
|
-
</template>
|
|
404
|
-
</ComboboxGroup>
|
|
405
|
-
|
|
406
|
-
<ReuseCreateItemTemplate v-if="creatable && creatable.position === 'bottom'" />
|
|
407
|
-
</ComboboxViewport>
|
|
400
|
+
<ReuseCreateItemTemplate v-if="createItem && createItemPosition === 'bottom'" />
|
|
401
|
+
</ComboboxViewport>
|
|
402
|
+
</FocusScope>
|
|
408
403
|
|
|
409
404
|
<ComboboxArrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
|
|
410
405
|
</ComboboxContent>
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import type { SeparatorProps as _SeparatorProps } from '
|
|
2
|
+
import type { VariantProps } from 'tailwind-variants'
|
|
3
|
+
import type { SeparatorProps as _SeparatorProps } from 'reka-ui'
|
|
4
4
|
import type { AppConfig } from '@nuxt/schema'
|
|
5
5
|
import _appConfig from '#build/app.config'
|
|
6
6
|
import theme from '#build/ui/separator'
|
|
7
|
+
import { tv } from '../utils/tv'
|
|
7
8
|
import type { AvatarProps } from '../types'
|
|
8
9
|
|
|
9
|
-
const
|
|
10
|
+
const appConfigSeparator = _appConfig as AppConfig & { ui: { separator: Partial<typeof theme> } }
|
|
10
11
|
|
|
11
|
-
const separator = tv({ extend: tv(theme), ...(
|
|
12
|
+
const separator = tv({ extend: tv(theme), ...(appConfigSeparator.ui?.separator || {}) })
|
|
12
13
|
|
|
13
14
|
type SeparatorVariants = VariantProps<typeof separator>
|
|
14
15
|
|
|
@@ -43,7 +44,7 @@ export interface SeparatorSlots {
|
|
|
43
44
|
|
|
44
45
|
<script setup lang="ts">
|
|
45
46
|
import { computed } from 'vue'
|
|
46
|
-
import { Separator, useForwardProps } from '
|
|
47
|
+
import { Separator, useForwardProps } from 'reka-ui'
|
|
47
48
|
import { reactivePick } from '@vueuse/core'
|
|
48
49
|
import UIcon from './Icon.vue'
|
|
49
50
|
import UAvatar from './Avatar.vue'
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { tv } from 'tailwind-variants'
|
|
3
2
|
import type { AppConfig } from '@nuxt/schema'
|
|
4
3
|
import _appConfig from '#build/app.config'
|
|
5
4
|
import theme from '#build/ui/skeleton'
|
|
6
|
-
import {
|
|
5
|
+
import { tv } from '../utils/tv'
|
|
7
6
|
|
|
8
|
-
const
|
|
7
|
+
const appConfigSkeleton = _appConfig as AppConfig & { ui: { skeleton: Partial<typeof theme> } }
|
|
9
8
|
|
|
10
|
-
const skeleton = tv({ extend: tv(theme), ...(
|
|
9
|
+
const skeleton = tv({ extend: tv(theme), ...(appConfigSkeleton.ui?.skeleton || {}) })
|
|
11
10
|
|
|
12
11
|
export interface SkeletonProps {
|
|
13
12
|
/**
|
|
@@ -17,12 +16,10 @@ export interface SkeletonProps {
|
|
|
17
16
|
as?: any
|
|
18
17
|
class?: any
|
|
19
18
|
}
|
|
20
|
-
|
|
21
|
-
extendDevtoolsMeta({ example: 'SkeletonExample' })
|
|
22
19
|
</script>
|
|
23
20
|
|
|
24
21
|
<script setup lang="ts">
|
|
25
|
-
import { Primitive } from '
|
|
22
|
+
import { Primitive } from 'reka-ui'
|
|
26
23
|
|
|
27
24
|
const props = defineProps<SkeletonProps>()
|
|
28
25
|
</script>
|