@nuxt/ui 3.0.0-alpha.6 → 3.0.0-alpha.8
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 +20 -0
- package/.nuxt/ui/alert.ts +242 -0
- package/.nuxt/ui/avatar-group.ts +40 -0
- package/.nuxt/ui/avatar.ts +42 -0
- package/.nuxt/ui/badge.ts +194 -0
- package/.nuxt/ui/breadcrumb.ts +45 -0
- package/.nuxt/ui/button-group.ts +16 -0
- package/.nuxt/ui/button.ts +344 -0
- package/.nuxt/ui/card.ts +8 -0
- package/.nuxt/ui/carousel.ts +41 -0
- package/.nuxt/ui/checkbox.ts +105 -0
- package/.nuxt/ui/chip.ts +67 -0
- package/.nuxt/ui/collapsible.ts +6 -0
- package/.nuxt/ui/command-palette.ts +40 -0
- package/.nuxt/ui/container.ts +3 -0
- package/.nuxt/ui/context-menu.ts +198 -0
- package/.nuxt/ui/drawer.ts +55 -0
- package/.nuxt/ui/dropdown-menu.ts +199 -0
- package/.nuxt/ui/form-field.ts +40 -0
- package/.nuxt/ui/form.ts +3 -0
- package/.nuxt/ui/index.ts +43 -0
- package/.nuxt/ui/input-menu.ts +411 -0
- package/.nuxt/ui/input.ts +263 -0
- package/.nuxt/ui/kbd.ts +19 -0
- package/.nuxt/ui/link.ts +15 -0
- package/.nuxt/ui/modal.ts +28 -0
- package/.nuxt/ui/navigation-menu.ts +390 -0
- package/.nuxt/ui/pagination.ts +8 -0
- package/.nuxt/ui/popover.ts +6 -0
- package/.nuxt/ui/progress.ts +258 -0
- package/.nuxt/ui/radio-group.ts +112 -0
- package/.nuxt/ui/select-menu.ts +321 -0
- package/.nuxt/ui/select.ts +314 -0
- package/.nuxt/ui/separator.ts +143 -0
- package/.nuxt/ui/skeleton.ts +3 -0
- package/.nuxt/ui/slideover.ts +63 -0
- package/.nuxt/ui/slider.ts +148 -0
- package/.nuxt/ui/switch.ts +113 -0
- package/.nuxt/ui/table.ts +128 -0
- package/.nuxt/ui/tabs.ts +227 -0
- package/.nuxt/ui/textarea.ts +263 -0
- package/.nuxt/ui/toast.ts +66 -0
- package/.nuxt/ui/toaster.ts +75 -0
- package/.nuxt/ui/tooltip.ts +9 -0
- package/cli/templates.mjs +1 -1
- package/dist/chunks/component-meta.cjs +73264 -0
- package/dist/chunks/component-meta.mjs +73262 -0
- package/dist/client/devtools/200.html +1 -0
- package/dist/client/devtools/404.html +1 -0
- 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/Bj9hdafK.js +1 -0
- package/dist/client/devtools/_nuxt/DM3_wAgz.js +62 -0
- package/dist/client/devtools/_nuxt/builds/latest.json +1 -0
- package/dist/client/devtools/_nuxt/builds/meta/e6b425f7-b919-4014-915b-0ea07c316790.json +1 -0
- package/dist/client/devtools/_nuxt/entry.DaJP-ZMB.css +24 -0
- package/dist/client/devtools/_nuxt/error-404.B0Nmv3fV.css +1 -0
- package/dist/client/devtools/_nuxt/error-500.C8fgTxVz.css +1 -0
- package/dist/client/devtools/_nuxt/hKiujHsR.js +1 -0
- package/dist/client/devtools/favicon.svg +1 -0
- package/dist/client/devtools/index.html +1 -0
- package/dist/devtools/runtime/DevtoolsRenderer.vue +53 -0
- package/dist/devtools/runtime/examples/AvatarGroupExample.vue +7 -0
- package/dist/devtools/runtime/examples/ButtonGroupExample.vue +8 -0
- package/dist/devtools/runtime/examples/CardExample.vue +13 -0
- package/dist/devtools/runtime/examples/CarouselExample.vue +13 -0
- package/dist/devtools/runtime/examples/ChipExample.vue +5 -0
- package/dist/devtools/runtime/examples/CollapsibleExample.vue +8 -0
- package/dist/devtools/runtime/examples/CommandPaletteExample.vue +29 -0
- package/dist/devtools/runtime/examples/ContainerExample.vue +5 -0
- package/dist/devtools/runtime/examples/ContextMenuExample.vue +5 -0
- package/dist/devtools/runtime/examples/DrawerExample.vue +8 -0
- package/dist/devtools/runtime/examples/DropdownMenuExample.vue +5 -0
- package/dist/devtools/runtime/examples/FormExample.vue +30 -0
- package/dist/devtools/runtime/examples/FormFieldExample.vue +5 -0
- package/dist/devtools/runtime/examples/LinkExample.vue +5 -0
- package/dist/devtools/runtime/examples/ModalExample.vue +8 -0
- package/dist/devtools/runtime/examples/PopoverExample.vue +8 -0
- package/dist/devtools/runtime/examples/SkeletonExample.vue +3 -0
- package/dist/devtools/runtime/examples/SlideoverExample.vue +8 -0
- package/dist/devtools/runtime/examples/ToasterExample.vue +11 -0
- package/dist/devtools/runtime/examples/TooltipExample.vue +5 -0
- package/dist/module.cjs +222 -4
- package/dist/module.d.cts +54 -0
- package/dist/module.d.mts +16 -6
- package/dist/module.d.ts +16 -6
- package/dist/module.json +1 -1
- package/dist/module.mjs +157 -2629
- package/dist/runtime/components/Accordion.vue +45 -6
- package/dist/runtime/components/Alert.vue +4 -0
- package/dist/runtime/components/App.vue +8 -0
- package/dist/runtime/components/Avatar.vue +23 -5
- package/dist/runtime/components/AvatarGroup.vue +3 -0
- package/dist/runtime/components/Badge.vue +33 -3
- package/dist/runtime/components/Breadcrumb.vue +39 -7
- package/dist/runtime/components/Button.vue +10 -3
- package/dist/runtime/components/ButtonGroup.vue +4 -1
- package/dist/runtime/components/Card.vue +3 -0
- package/dist/runtime/components/Carousel.vue +13 -8
- package/dist/runtime/components/Checkbox.vue +7 -6
- package/dist/runtime/components/Chip.vue +9 -2
- package/dist/runtime/components/Collapsible.vue +3 -0
- package/dist/runtime/components/CommandPalette.vue +28 -17
- package/dist/runtime/components/Container.vue +3 -0
- package/dist/runtime/components/ContextMenu.vue +95 -10
- package/dist/runtime/components/ContextMenuContent.vue +41 -13
- package/dist/runtime/components/Drawer.vue +3 -0
- package/dist/runtime/components/DropdownMenu.vue +83 -10
- package/dist/runtime/components/DropdownMenuContent.vue +43 -13
- package/dist/runtime/components/Form.vue +6 -1
- package/dist/runtime/components/FormField.vue +3 -0
- package/dist/runtime/components/Input.vue +7 -4
- package/dist/runtime/components/InputMenu.vue +61 -34
- package/dist/runtime/components/Kbd.vue +2 -0
- package/dist/runtime/components/Link.vue +50 -1
- package/dist/runtime/components/LinkBase.vue +4 -2
- package/dist/runtime/components/Modal.vue +3 -0
- package/dist/runtime/components/NavigationMenu.vue +159 -75
- package/dist/runtime/components/Pagination.vue +5 -1
- package/dist/runtime/components/Popover.vue +3 -0
- package/dist/runtime/components/Progress.vue +1 -1
- package/dist/runtime/components/RadioGroup.vue +26 -4
- package/dist/runtime/components/Select.vue +44 -21
- package/dist/runtime/components/SelectMenu.vue +67 -43
- package/dist/runtime/components/Separator.vue +1 -1
- package/dist/runtime/components/Skeleton.vue +3 -0
- package/dist/runtime/components/Slideover.vue +3 -0
- package/dist/runtime/components/Slider.vue +1 -1
- package/dist/runtime/components/Switch.vue +5 -1
- package/dist/runtime/components/Table.vue +241 -0
- package/dist/runtime/components/Tabs.vue +35 -8
- package/dist/runtime/components/Toast.vue +4 -0
- package/dist/runtime/components/Toaster.vue +8 -1
- package/dist/runtime/components/Tooltip.vue +3 -0
- package/dist/runtime/composables/defineShortcuts.js +1 -7
- package/dist/runtime/composables/extendDevtoolsMeta.d.ts +7 -0
- package/dist/runtime/composables/extendDevtoolsMeta.js +2 -0
- package/dist/runtime/composables/useComponentIcons.d.ts +3 -0
- package/dist/runtime/composables/useKbd.d.ts +10 -3
- package/dist/runtime/composables/useKbd.js +14 -8
- package/dist/runtime/composables/useModal.d.ts +1 -1
- package/dist/runtime/composables/useSlideover.d.ts +1 -1
- package/dist/runtime/index.css +1 -1
- package/dist/runtime/keyframes.css +1 -0
- package/dist/runtime/types/form.d.ts +2 -1
- package/dist/runtime/types/index.d.ts +1 -0
- package/dist/runtime/types/index.js +1 -0
- package/dist/runtime/types/utils.d.ts +7 -0
- package/dist/runtime/utils/form.d.ts +3 -0
- package/dist/runtime/utils/form.js +14 -0
- package/dist/runtime/utils/index.d.ts +1 -0
- package/dist/runtime/utils/index.js +3 -0
- package/dist/runtime/utils/link.d.ts +1 -1
- package/dist/runtime/vue/components/Icon.vue +15 -0
- package/dist/runtime/vue/components/Link.vue +195 -0
- package/dist/runtime/vue/plugins/color-mode.d.ts +4 -0
- package/dist/runtime/vue/plugins/color-mode.js +6 -0
- package/dist/runtime/vue/plugins/head.d.ts +4 -0
- package/dist/runtime/vue/plugins/head.js +6 -0
- package/dist/runtime/vue/stubs.d.ts +15 -0
- package/dist/runtime/vue/stubs.js +27 -0
- package/dist/shared/ui.BU7wzH0D.cjs +2872 -0
- package/dist/shared/ui.BufKhDiD.mjs +2865 -0
- package/dist/unplugin.cjs +192 -0
- package/dist/unplugin.d.cts +47 -0
- package/dist/unplugin.d.mts +47 -0
- package/dist/unplugin.d.ts +47 -0
- package/dist/unplugin.mjs +181 -0
- package/dist/vite.cjs +22 -0
- package/dist/vite.d.cts +13 -0
- package/dist/vite.d.mts +13 -0
- package/dist/vite.d.ts +13 -0
- package/dist/vite.mjs +20 -0
- package/package.json +73 -32
- package/vue-plugin.d.ts +5 -0
- package/cli/node_modules/.ignored/citty/LICENSE +0 -36
- package/cli/node_modules/.ignored/citty/README.md +0 -134
- package/cli/node_modules/.ignored/citty/dist/index.cjs +0 -475
- package/cli/node_modules/.ignored/citty/dist/index.d.cts +0 -80
- package/cli/node_modules/.ignored/citty/dist/index.d.mts +0 -80
- package/cli/node_modules/.ignored/citty/dist/index.d.ts +0 -80
- package/cli/node_modules/.ignored/citty/dist/index.mjs +0 -463
- package/cli/node_modules/.ignored/citty/package.json +0 -49
- package/cli/node_modules/.ignored/consola/LICENSE +0 -47
- package/cli/node_modules/.ignored/consola/README.md +0 -318
- package/cli/node_modules/.ignored/consola/core.d.ts +0 -1
- package/cli/node_modules/.ignored/consola/dist/basic.cjs +0 -32
- package/cli/node_modules/.ignored/consola/dist/basic.d.ts +0 -9
- package/cli/node_modules/.ignored/consola/dist/basic.mjs +0 -24
- package/cli/node_modules/.ignored/consola/dist/browser.cjs +0 -80
- package/cli/node_modules/.ignored/consola/dist/browser.d.ts +0 -7
- package/cli/node_modules/.ignored/consola/dist/browser.mjs +0 -72
- package/cli/node_modules/.ignored/consola/dist/chunks/prompt.cjs +0 -436
- package/cli/node_modules/.ignored/consola/dist/chunks/prompt.mjs +0 -429
- package/cli/node_modules/.ignored/consola/dist/core.cjs +0 -415
- package/cli/node_modules/.ignored/consola/dist/core.d.ts +0 -124
- package/cli/node_modules/.ignored/consola/dist/core.mjs +0 -410
- package/cli/node_modules/.ignored/consola/dist/index.cjs +0 -21
- package/cli/node_modules/.ignored/consola/dist/index.d.ts +0 -9
- package/cli/node_modules/.ignored/consola/dist/index.mjs +0 -8
- package/cli/node_modules/.ignored/consola/dist/shared/consola.06ad8a64.mjs +0 -62
- package/cli/node_modules/.ignored/consola/dist/shared/consola.36c0034f.mjs +0 -636
- package/cli/node_modules/.ignored/consola/dist/shared/consola.4bbae468.cjs +0 -645
- package/cli/node_modules/.ignored/consola/dist/shared/consola.deac7d5a.cjs +0 -65
- package/cli/node_modules/.ignored/consola/dist/utils.cjs +0 -308
- package/cli/node_modules/.ignored/consola/dist/utils.d.ts +0 -169
- package/cli/node_modules/.ignored/consola/dist/utils.mjs +0 -284
- package/cli/node_modules/.ignored/consola/lib/index.cjs +0 -9
- package/cli/node_modules/.ignored/consola/package.json +0 -101
- package/cli/node_modules/.ignored/consola/utils.d.ts +0 -1
- package/cli/node_modules/.ignored/pathe/LICENSE +0 -44
- package/cli/node_modules/.ignored/pathe/README.md +0 -69
- package/cli/node_modules/.ignored/pathe/dist/index.cjs +0 -23
- package/cli/node_modules/.ignored/pathe/dist/index.d.cts +0 -36
- package/cli/node_modules/.ignored/pathe/dist/index.d.mts +0 -36
- package/cli/node_modules/.ignored/pathe/dist/index.d.ts +0 -36
- package/cli/node_modules/.ignored/pathe/dist/index.mjs +0 -1
- package/cli/node_modules/.ignored/pathe/dist/shared/pathe.1f0a373c.cjs +0 -238
- package/cli/node_modules/.ignored/pathe/dist/shared/pathe.ff20891b.mjs +0 -221
- package/cli/node_modules/.ignored/pathe/dist/utils.cjs +0 -58
- package/cli/node_modules/.ignored/pathe/dist/utils.d.cts +0 -5
- package/cli/node_modules/.ignored/pathe/dist/utils.d.mts +0 -5
- package/cli/node_modules/.ignored/pathe/dist/utils.d.ts +0 -5
- package/cli/node_modules/.ignored/pathe/dist/utils.mjs +0 -54
- package/cli/node_modules/.ignored/pathe/package.json +0 -48
- package/cli/node_modules/.ignored/pathe/utils.d.ts +0 -1
- package/cli/node_modules/.ignored/scule/LICENSE +0 -21
- package/cli/node_modules/.ignored/scule/README.md +0 -149
- package/cli/node_modules/.ignored/scule/dist/index.cjs +0 -92
- package/cli/node_modules/.ignored/scule/dist/index.d.cts +0 -57
- package/cli/node_modules/.ignored/scule/dist/index.d.mts +0 -57
- package/cli/node_modules/.ignored/scule/dist/index.d.ts +0 -57
- package/cli/node_modules/.ignored/scule/dist/index.mjs +0 -80
- package/cli/node_modules/.ignored/scule/package.json +0 -43
- package/cli/node_modules/.package-lock.json +0 -33
- package/dist/runtime/types/component.d.ts +0 -17
- package/dist/runtime/types/component.js +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<!-- eslint-disable vue/block-tag-newline -->
|
|
1
2
|
<script lang="ts">
|
|
2
3
|
import { tv } from 'tailwind-variants'
|
|
3
4
|
import type { DropdownMenuContentProps as RadixDropdownMenuContentProps, DropdownMenuContentEmits as RadixDropdownMenuContentEmits } from 'radix-vue'
|
|
@@ -10,6 +11,9 @@ interface DropdownMenuContentProps<T> extends Omit<RadixDropdownMenuContentProps
|
|
|
10
11
|
items?: T[] | T[][]
|
|
11
12
|
portal?: boolean
|
|
12
13
|
sub?: boolean
|
|
14
|
+
labelKey: string
|
|
15
|
+
checkedIcon?: string
|
|
16
|
+
loadingIcon?: string
|
|
13
17
|
class?: any
|
|
14
18
|
ui: typeof _dropdownMenu
|
|
15
19
|
uiOverride?: any
|
|
@@ -20,6 +24,7 @@ interface DropdownMenuContentEmits extends RadixDropdownMenuContentEmits {}
|
|
|
20
24
|
type DropdownMenuContentSlots<T extends { slot?: string }> = Omit<DropdownMenuSlots<T>, 'default'> & {
|
|
21
25
|
default(props?: {}): any
|
|
22
26
|
}
|
|
27
|
+
|
|
23
28
|
</script>
|
|
24
29
|
|
|
25
30
|
<script setup lang="ts" generic="T extends DropdownMenuItem">
|
|
@@ -28,13 +33,13 @@ import { DropdownMenu } from 'radix-vue/namespaced'
|
|
|
28
33
|
import { useForwardPropsEmits } from 'radix-vue'
|
|
29
34
|
import { reactiveOmit, createReusableTemplate } from '@vueuse/core'
|
|
30
35
|
import { useAppConfig } from '#imports'
|
|
36
|
+
import { omit, get } from '../utils'
|
|
37
|
+
import { pickLinkProps } from '../utils/link'
|
|
31
38
|
import ULinkBase from './LinkBase.vue'
|
|
32
39
|
import ULink from './Link.vue'
|
|
33
40
|
import UAvatar from './Avatar.vue'
|
|
34
41
|
import UIcon from './Icon.vue'
|
|
35
42
|
import UKbd from './Kbd.vue'
|
|
36
|
-
import { omit } from '../utils'
|
|
37
|
-
import { pickLinkProps } from '../utils/link'
|
|
38
43
|
|
|
39
44
|
const props = defineProps<DropdownMenuContentProps<T>>()
|
|
40
45
|
const emits = defineEmits<DropdownMenuContentEmits>()
|
|
@@ -53,25 +58,30 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
53
58
|
<DefineItemTemplate v-slot="{ item, active, index }">
|
|
54
59
|
<slot :name="item.slot || 'item'" :item="(item as T)" :index="index">
|
|
55
60
|
<slot :name="item.slot ? `${item.slot}-leading`: 'item-leading'" :item="(item as T)" :active="active" :index="index">
|
|
56
|
-
<
|
|
57
|
-
<UIcon v-else-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: uiOverride?.itemLeadingIcon, active })" />
|
|
61
|
+
<UIcon v-if="item.loading" :name="loadingIcon || appConfig.ui.icons.loading" :class="ui.itemLeadingIcon({ class: uiOverride?.itemLeadingIcon, color: item?.color, loading: true })" />
|
|
62
|
+
<UIcon v-else-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: uiOverride?.itemLeadingIcon, color: item?.color, active })" />
|
|
63
|
+
<UAvatar v-else-if="item.avatar" :size="((props.uiOverride?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: uiOverride?.itemLeadingAvatar, active })" />
|
|
58
64
|
</slot>
|
|
59
65
|
|
|
60
|
-
<span v-if="item.
|
|
66
|
+
<span v-if="get(item, props.labelKey as string) || !!slots[item.slot ? `${item.slot}-label`: 'item-label']" :class="ui.itemLabel({ class: uiOverride?.itemLabel, active })">
|
|
61
67
|
<slot :name="item.slot ? `${item.slot}-label`: 'item-label'" :item="(item as T)" :active="active" :index="index">
|
|
62
|
-
{{ item.
|
|
68
|
+
{{ get(item, props.labelKey as string) }}
|
|
63
69
|
</slot>
|
|
64
70
|
|
|
65
|
-
<UIcon v-if="item.target === '_blank'" :name="appConfig.ui.icons.external" :class="ui.itemLabelExternalIcon({ class: uiOverride?.itemLabelExternalIcon, active })" />
|
|
71
|
+
<UIcon v-if="item.target === '_blank'" :name="appConfig.ui.icons.external" :class="ui.itemLabelExternalIcon({ class: uiOverride?.itemLabelExternalIcon, color: item?.color, active })" />
|
|
66
72
|
</span>
|
|
67
73
|
|
|
68
|
-
<span
|
|
74
|
+
<span :class="ui.itemTrailing({ class: uiOverride?.itemTrailing })">
|
|
69
75
|
<slot :name="item.slot ? `${item.slot}-trailing`: 'item-trailing'" :item="(item as T)" :active="active" :index="index">
|
|
70
|
-
<UIcon v-if="item.children?.length" :name="appConfig.ui.icons.chevronRight" :class="ui.itemTrailingIcon({ class: uiOverride?.itemTrailingIcon, active })" />
|
|
76
|
+
<UIcon v-if="item.children?.length" :name="appConfig.ui.icons.chevronRight" :class="ui.itemTrailingIcon({ class: uiOverride?.itemTrailingIcon, color: item?.color, active })" />
|
|
71
77
|
<span v-else-if="item.kbds?.length" :class="ui.itemTrailingKbds({ class: uiOverride?.itemTrailingKbds })">
|
|
72
78
|
<UKbd v-for="(kbd, kbdIndex) in item.kbds" :key="kbdIndex" :size="((props.uiOverride?.itemTrailingKbdsSize || ui.itemTrailingKbdsSize()) as KbdProps['size'])" v-bind="typeof kbd === 'string' ? { value: kbd } : kbd" />
|
|
73
79
|
</span>
|
|
74
80
|
</slot>
|
|
81
|
+
|
|
82
|
+
<DropdownMenu.ItemIndicator as-child>
|
|
83
|
+
<UIcon :name="checkedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: uiOverride?.itemTrailingIcon, color: item?.color })" />
|
|
84
|
+
</DropdownMenu.ItemIndicator>
|
|
75
85
|
</span>
|
|
76
86
|
</slot>
|
|
77
87
|
</DefineItemTemplate>
|
|
@@ -89,8 +99,8 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
89
99
|
as="button"
|
|
90
100
|
type="button"
|
|
91
101
|
:disabled="item.disabled"
|
|
92
|
-
:text-value="item.
|
|
93
|
-
:class="ui.item({ class: uiOverride?.item })"
|
|
102
|
+
:text-value="get(item, props.labelKey as string)"
|
|
103
|
+
:class="ui.item({ class: uiOverride?.item, color: item?.color })"
|
|
94
104
|
>
|
|
95
105
|
<ReuseItemTemplate :item="item" :index="index" />
|
|
96
106
|
</DropdownMenu.SubTrigger>
|
|
@@ -106,6 +116,9 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
106
116
|
align="start"
|
|
107
117
|
:align-offset="-4"
|
|
108
118
|
:side-offset="3"
|
|
119
|
+
:label-key="labelKey"
|
|
120
|
+
:checked-icon="checkedIcon"
|
|
121
|
+
:loading-icon="loadingIcon"
|
|
109
122
|
v-bind="item.content"
|
|
110
123
|
>
|
|
111
124
|
<template v-for="(_, name) in proxySlots" #[name]="slotData: any">
|
|
@@ -113,9 +126,26 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
113
126
|
</template>
|
|
114
127
|
</UDropdownMenuContent>
|
|
115
128
|
</DropdownMenu.Sub>
|
|
116
|
-
<DropdownMenu.
|
|
129
|
+
<DropdownMenu.CheckboxItem
|
|
130
|
+
v-else-if="item.type === 'checkbox'"
|
|
131
|
+
:checked="item.checked"
|
|
132
|
+
:disabled="item.disabled"
|
|
133
|
+
:text-value="get(item, props.labelKey as string)"
|
|
134
|
+
:class="ui.item({ class: [uiOverride?.item, item.class], color: item?.color })"
|
|
135
|
+
@update:checked="item.onUpdateChecked"
|
|
136
|
+
@select="item.onSelect"
|
|
137
|
+
>
|
|
138
|
+
<ReuseItemTemplate :item="item" :index="index" />
|
|
139
|
+
</DropdownMenu.CheckboxItem>
|
|
140
|
+
<DropdownMenu.Item
|
|
141
|
+
v-else
|
|
142
|
+
as-child
|
|
143
|
+
:disabled="item.disabled"
|
|
144
|
+
:text-value="get(item, props.labelKey as string)"
|
|
145
|
+
@select="item.onSelect"
|
|
146
|
+
>
|
|
117
147
|
<ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item as Omit<DropdownMenuItem, 'type'>)" custom>
|
|
118
|
-
<ULinkBase v-bind="slotProps" :class="ui.item({ class: [uiOverride?.item, item.class], active })">
|
|
148
|
+
<ULinkBase v-bind="slotProps" :class="ui.item({ class: [uiOverride?.item, item.class], color: item?.color, active })">
|
|
119
149
|
<ReuseItemTemplate :item="item" :active="active" :index="index" />
|
|
120
150
|
</ULinkBase>
|
|
121
151
|
</ULink>
|
|
@@ -3,6 +3,7 @@ import { tv } from 'tailwind-variants'
|
|
|
3
3
|
import type { AppConfig } from '@nuxt/schema'
|
|
4
4
|
import _appConfig from '#build/app.config'
|
|
5
5
|
import theme from '#build/ui/form'
|
|
6
|
+
import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
|
|
6
7
|
import type { FormSchema, FormError, FormInputEvents, FormErrorEvent, FormSubmitEvent, FormEvent, Form, FormErrorWithId } from '../types/form'
|
|
7
8
|
|
|
8
9
|
const appConfig = _appConfig as AppConfig & { ui: { form: Partial<typeof theme> } }
|
|
@@ -29,13 +30,15 @@ export interface FormEmits<T extends object> {
|
|
|
29
30
|
export interface FormSlots {
|
|
30
31
|
default(props?: {}): any
|
|
31
32
|
}
|
|
33
|
+
|
|
34
|
+
extendDevtoolsMeta({ example: 'FormExample' })
|
|
32
35
|
</script>
|
|
33
36
|
|
|
34
37
|
<script lang="ts" setup generic="T extends object">
|
|
35
38
|
import { provide, inject, nextTick, ref, onUnmounted, onMounted, computed, useId, readonly } from 'vue'
|
|
36
39
|
import { useEventBus } from '@vueuse/core'
|
|
37
40
|
import { formOptionsInjectionKey, formInputsInjectionKey, formBusInjectionKey, formLoadingInjectionKey } from '../composables/useFormField'
|
|
38
|
-
import { getYupErrors, isYupSchema, getValibotErrors, isValibotSchema, getZodErrors, isZodSchema, getJoiErrors, isJoiSchema, getStandardErrors, isStandardSchema } from '../utils/form'
|
|
41
|
+
import { getYupErrors, isYupSchema, getValibotErrors, isValibotSchema, getZodErrors, isZodSchema, getJoiErrors, isJoiSchema, getStandardErrors, isStandardSchema, getSuperStructErrors, isSuperStructSchema } from '../utils/form'
|
|
39
42
|
import { FormValidationException } from '../types/form'
|
|
40
43
|
|
|
41
44
|
const props = withDefaults(defineProps<FormProps<T>>(), {
|
|
@@ -113,6 +116,8 @@ async function getErrors(): Promise<FormErrorWithId[]> {
|
|
|
113
116
|
errs = errs.concat(await getJoiErrors(props.state, props.schema))
|
|
114
117
|
} else if (isValibotSchema(props.schema)) {
|
|
115
118
|
errs = errs.concat(await getValibotErrors(props.state, props.schema))
|
|
119
|
+
} else if (isSuperStructSchema(props.schema)) {
|
|
120
|
+
errs = errs.concat(await getSuperStructErrors(props.state, props.schema))
|
|
116
121
|
} else if (isStandardSchema(props.schema)) {
|
|
117
122
|
errs = errs.concat(await getStandardErrors(props.state, props.schema))
|
|
118
123
|
} else {
|
|
@@ -3,6 +3,7 @@ import { tv, type VariantProps } from 'tailwind-variants'
|
|
|
3
3
|
import type { AppConfig } from '@nuxt/schema'
|
|
4
4
|
import _appConfig from '#build/app.config'
|
|
5
5
|
import theme from '#build/ui/form-field'
|
|
6
|
+
import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
|
|
6
7
|
|
|
7
8
|
const appConfig = _appConfig as AppConfig & { ui: { formField: Partial<typeof theme> } }
|
|
8
9
|
|
|
@@ -33,6 +34,8 @@ export interface FormFieldSlots {
|
|
|
33
34
|
error(props: { error?: string | boolean }): any
|
|
34
35
|
default(props: { error?: string | boolean }): any
|
|
35
36
|
}
|
|
37
|
+
|
|
38
|
+
extendDevtoolsMeta({ example: 'FormFieldExample', defaultProps: { label: 'Label' } })
|
|
36
39
|
</script>
|
|
37
40
|
|
|
38
41
|
<script setup lang="ts">
|
|
@@ -5,6 +5,7 @@ import type { AppConfig } from '@nuxt/schema'
|
|
|
5
5
|
import _appConfig from '#build/app.config'
|
|
6
6
|
import theme from '#build/ui/input'
|
|
7
7
|
import type { UseComponentIconsProps } from '../composables/useComponentIcons'
|
|
8
|
+
import type { AvatarProps } from '../types'
|
|
8
9
|
import type { PartialString } from '../types/utils'
|
|
9
10
|
|
|
10
11
|
const appConfig = _appConfig as AppConfig & { ui: { input: Partial<typeof theme> } }
|
|
@@ -51,8 +52,9 @@ import { ref, computed, onMounted } from 'vue'
|
|
|
51
52
|
import { useButtonGroup } from '../composables/useButtonGroup'
|
|
52
53
|
import { useComponentIcons } from '../composables/useComponentIcons'
|
|
53
54
|
import { useFormField } from '../composables/useFormField'
|
|
54
|
-
import UIcon from './Icon.vue'
|
|
55
55
|
import { looseToNumber } from '../utils'
|
|
56
|
+
import UIcon from './Icon.vue'
|
|
57
|
+
import UAvatar from './Avatar.vue'
|
|
56
58
|
|
|
57
59
|
defineOptions({ inheritAttrs: false })
|
|
58
60
|
|
|
@@ -79,7 +81,7 @@ const ui = computed(() => input({
|
|
|
79
81
|
size: inputSize?.value,
|
|
80
82
|
loading: props.loading,
|
|
81
83
|
highlight: highlight.value,
|
|
82
|
-
leading: isLeading.value || !!slots.leading,
|
|
84
|
+
leading: isLeading.value || !!props.avatar || !!slots.leading,
|
|
83
85
|
trailing: isTrailing.value || !!slots.trailing,
|
|
84
86
|
buttonGroup: orientation.value
|
|
85
87
|
}))
|
|
@@ -165,9 +167,10 @@ onMounted(() => {
|
|
|
165
167
|
|
|
166
168
|
<slot />
|
|
167
169
|
|
|
168
|
-
<span v-if="isLeading || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })">
|
|
170
|
+
<span v-if="isLeading || !!avatar || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })">
|
|
169
171
|
<slot name="leading">
|
|
170
|
-
<UIcon v-if="leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
|
|
172
|
+
<UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
|
|
173
|
+
<UAvatar v-else-if="!!avatar" :size="((props.ui?.leadingAvatarSize || ui.leadingAvatarSize()) as AvatarProps['size'])" v-bind="avatar" :class="ui.leadingAvatar({ class: props.ui?.leadingAvatar })" />
|
|
171
174
|
</slot>
|
|
172
175
|
</span>
|
|
173
176
|
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { InputHTMLAttributes } from 'vue'
|
|
3
3
|
import { tv, type VariantProps } from 'tailwind-variants'
|
|
4
|
-
import type { ComboboxRootProps, ComboboxRootEmits, ComboboxContentProps,
|
|
4
|
+
import type { ComboboxRootProps, ComboboxRootEmits, ComboboxContentProps, ComboboxArrowProps } from 'radix-vue'
|
|
5
5
|
import type { AppConfig } from '@nuxt/schema'
|
|
6
6
|
import _appConfig from '#build/app.config'
|
|
7
7
|
import theme from '#build/ui/input-menu'
|
|
8
8
|
import type { UseComponentIconsProps } from '../composables/useComponentIcons'
|
|
9
|
+
import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
|
|
9
10
|
import type { AvatarProps, ChipProps, InputProps } from '../types'
|
|
10
|
-
import type { AcceptableValue, ArrayOrWrapped, PartialString } from '../types/utils'
|
|
11
|
+
import type { AcceptableValue, ArrayOrWrapped, PartialString, MaybeArrayOfArray, MaybeArrayOfArrayItem, SelectModelValue, SelectModelValueEmits, SelectItemKey } from '../types/utils'
|
|
11
12
|
|
|
12
13
|
const appConfig = _appConfig as AppConfig & { ui: { inputMenu: Partial<typeof theme> } }
|
|
13
14
|
|
|
14
15
|
const inputMenu = tv({ extend: tv(theme), ...(appConfig.ui?.inputMenu || {}) })
|
|
15
16
|
|
|
16
|
-
export interface InputMenuItem
|
|
17
|
+
export interface InputMenuItem {
|
|
17
18
|
label?: string
|
|
18
19
|
icon?: string
|
|
19
20
|
avatar?: AvatarProps
|
|
@@ -23,12 +24,13 @@ export interface InputMenuItem extends Pick<ComboboxItemProps, 'disabled'> {
|
|
|
23
24
|
* @defaultValue 'item'
|
|
24
25
|
*/
|
|
25
26
|
type?: 'label' | 'separator' | 'item'
|
|
26
|
-
|
|
27
|
+
disabled?: boolean
|
|
28
|
+
onSelect?(e?: Event): void
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
type InputMenuVariants = VariantProps<typeof inputMenu>
|
|
30
32
|
|
|
31
|
-
export interface InputMenuProps<T> extends Pick<ComboboxRootProps<T>, '
|
|
33
|
+
export interface InputMenuProps<T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<InputMenuItem | AcceptableValue> = MaybeArrayOfArray<InputMenuItem | AcceptableValue>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false> extends Pick<ComboboxRootProps<T>, 'defaultValue' | 'selectedValue' | 'open' | 'defaultOpen' | 'searchTerm' | 'disabled' | 'name' | 'resetSearchTermOnBlur'>, UseComponentIconsProps {
|
|
32
34
|
/**
|
|
33
35
|
* The element or component this component should render as.
|
|
34
36
|
* @defaultValue 'div'
|
|
@@ -85,19 +87,28 @@ export interface InputMenuProps<T> extends Pick<ComboboxRootProps<T>, 'modelValu
|
|
|
85
87
|
* When `items` is an array of objects, select the field to use as the value instead of the object itself.
|
|
86
88
|
* @defaultValue undefined
|
|
87
89
|
*/
|
|
88
|
-
valueKey?:
|
|
89
|
-
|
|
90
|
+
valueKey?: V
|
|
91
|
+
/**
|
|
92
|
+
* When `items` is an array of objects, select the field to use as the label.
|
|
93
|
+
* @defaultValue 'label'
|
|
94
|
+
*/
|
|
95
|
+
labelKey?: keyof T
|
|
96
|
+
items?: I
|
|
90
97
|
/** Highlight the ring color like a focus state. */
|
|
91
98
|
highlight?: boolean
|
|
92
99
|
class?: any
|
|
93
100
|
ui?: PartialString<typeof inputMenu.slots>
|
|
101
|
+
/** The controlled value of the Combobox. Can be binded-with with `v-model`. */
|
|
102
|
+
modelValue?: SelectModelValue<T, V, M>
|
|
103
|
+
/** Whether multiple options can be selected or not. */
|
|
104
|
+
multiple?: M
|
|
94
105
|
}
|
|
95
106
|
|
|
96
|
-
export type InputMenuEmits<T> = ComboboxRootEmits<T> & {
|
|
107
|
+
export type InputMenuEmits<T, V, M extends boolean> = Omit<ComboboxRootEmits<T>, 'update:modelValue'> & {
|
|
97
108
|
change: [payload: Event]
|
|
98
109
|
blur: [payload: FocusEvent]
|
|
99
110
|
focus: [payload: FocusEvent]
|
|
100
|
-
}
|
|
111
|
+
} & SelectModelValueEmits<T, V, M>
|
|
101
112
|
|
|
102
113
|
type SlotProps<T> = (props: { item: T, index: number }) => any
|
|
103
114
|
|
|
@@ -112,31 +123,35 @@ export interface InputMenuSlots<T> {
|
|
|
112
123
|
'tags-item-text': SlotProps<T>
|
|
113
124
|
'tags-item-delete': SlotProps<T>
|
|
114
125
|
}
|
|
126
|
+
|
|
127
|
+
extendDevtoolsMeta({ defaultProps: { items: ['Option 1', 'Option 2', 'Option 3'] } })
|
|
115
128
|
</script>
|
|
116
129
|
|
|
117
|
-
<script setup lang="ts" generic="T extends InputMenuItem | AcceptableValue">
|
|
130
|
+
<script setup lang="ts" generic="T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<InputMenuItem | AcceptableValue> = MaybeArrayOfArray<InputMenuItem | AcceptableValue>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false">
|
|
118
131
|
import { computed, ref, toRef, onMounted } from 'vue'
|
|
119
|
-
import { ComboboxRoot, ComboboxAnchor, ComboboxInput, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxViewport, ComboboxEmpty, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxItem, ComboboxItemIndicator, TagsInputRoot, TagsInputItem, TagsInputItemText, TagsInputItemDelete, TagsInputInput, useForwardPropsEmits } from 'radix-vue'
|
|
132
|
+
import { ComboboxRoot, ComboboxArrow, ComboboxAnchor, ComboboxInput, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxViewport, ComboboxEmpty, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxItem, ComboboxItemIndicator, TagsInputRoot, TagsInputItem, TagsInputItemText, TagsInputItemDelete, TagsInputInput, useForwardPropsEmits } from 'radix-vue'
|
|
120
133
|
import { defu } from 'defu'
|
|
134
|
+
import * as isEqual from 'fast-deep-equal'
|
|
121
135
|
import { reactivePick } from '@vueuse/core'
|
|
122
136
|
import { useAppConfig } from '#imports'
|
|
123
137
|
import { useButtonGroup } from '../composables/useButtonGroup'
|
|
124
138
|
import { useComponentIcons } from '../composables/useComponentIcons'
|
|
125
139
|
import { useFormField } from '../composables/useFormField'
|
|
140
|
+
import { get, escapeRegExp } from '../utils'
|
|
126
141
|
import UIcon from './Icon.vue'
|
|
127
142
|
import UAvatar from './Avatar.vue'
|
|
128
143
|
import UChip from './Chip.vue'
|
|
129
|
-
import { get } from '../utils'
|
|
130
144
|
|
|
131
145
|
defineOptions({ inheritAttrs: false })
|
|
132
146
|
|
|
133
|
-
const props = withDefaults(defineProps<InputMenuProps<T>>(), {
|
|
147
|
+
const props = withDefaults(defineProps<InputMenuProps<T, I, V, M>>(), {
|
|
134
148
|
type: 'text',
|
|
135
149
|
autofocusDelay: 0,
|
|
136
150
|
portal: true,
|
|
137
|
-
filter: () => ['label']
|
|
151
|
+
filter: () => ['label'],
|
|
152
|
+
labelKey: 'label' as keyof T
|
|
138
153
|
})
|
|
139
|
-
const emits = defineEmits<InputMenuEmits<T>>()
|
|
154
|
+
const emits = defineEmits<InputMenuEmits<T, V, M>>()
|
|
140
155
|
const slots = defineSlots<InputMenuSlots<T>>()
|
|
141
156
|
|
|
142
157
|
const searchTerm = defineModel<string>('searchTerm', { default: '' })
|
|
@@ -144,6 +159,8 @@ const searchTerm = defineModel<string>('searchTerm', { default: '' })
|
|
|
144
159
|
const appConfig = useAppConfig()
|
|
145
160
|
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'selectedValue', 'open', 'defaultOpen', 'multiple', 'resetSearchTermOnBlur'), emits)
|
|
146
161
|
const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8, position: 'popper' }) as ComboboxContentProps)
|
|
162
|
+
const arrowProps = toRef(() => props.arrow as ComboboxArrowProps)
|
|
163
|
+
|
|
147
164
|
const { emitFormBlur, emitFormChange, emitFormInput, size: formGroupSize, color, id, name, highlight, disabled } = useFormField<InputProps>(props)
|
|
148
165
|
const { orientation, size: buttonGroupSize } = useButtonGroup<InputProps>(props)
|
|
149
166
|
const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(toRef(() => defu(props, { trailingIcon: appConfig.ui.icons.chevronDown })))
|
|
@@ -156,18 +173,16 @@ const ui = computed(() => inputMenu({
|
|
|
156
173
|
size: inputSize?.value,
|
|
157
174
|
loading: props.loading,
|
|
158
175
|
highlight: highlight.value,
|
|
159
|
-
leading: isLeading.value || !!slots.leading,
|
|
176
|
+
leading: isLeading.value || !!props.avatar || !!slots.leading,
|
|
160
177
|
trailing: isTrailing.value || !!slots.trailing,
|
|
161
178
|
multiple: props.multiple,
|
|
162
179
|
buttonGroup: orientation.value
|
|
163
180
|
}))
|
|
164
181
|
|
|
165
|
-
function displayValue(
|
|
166
|
-
|
|
167
|
-
return val.label
|
|
168
|
-
}
|
|
182
|
+
function displayValue(value: AcceptableValue): string {
|
|
183
|
+
const item = items.value.find(item => props.valueKey ? isEqual.default(get(item as Record<string, any>, props.valueKey as string), value) : isEqual.default(item, value))
|
|
169
184
|
|
|
170
|
-
return
|
|
185
|
+
return item && (typeof item === 'object' ? get(item, props.labelKey as string) : item)
|
|
171
186
|
}
|
|
172
187
|
|
|
173
188
|
function filterFunction(items: ArrayOrWrapped<AcceptableValue>, searchTerm: string): ArrayOrWrapped<AcceptableValue> {
|
|
@@ -175,22 +190,25 @@ function filterFunction(items: ArrayOrWrapped<AcceptableValue>, searchTerm: stri
|
|
|
175
190
|
return items
|
|
176
191
|
}
|
|
177
192
|
|
|
178
|
-
const fields = Array.isArray(props.filter) ? props.filter : [
|
|
193
|
+
const fields = Array.isArray(props.filter) ? props.filter : [props.labelKey]
|
|
194
|
+
const escapedSearchTerm = escapeRegExp(searchTerm)
|
|
179
195
|
|
|
180
196
|
return items.filter((item) => {
|
|
181
197
|
if (typeof item !== 'object') {
|
|
182
|
-
return String(item).search(new RegExp(
|
|
198
|
+
return String(item).search(new RegExp(escapedSearchTerm, 'i')) !== -1
|
|
183
199
|
}
|
|
184
200
|
|
|
185
201
|
return fields.some((field) => {
|
|
186
|
-
const child = get(item, field)
|
|
202
|
+
const child = get(item, field as string)
|
|
187
203
|
|
|
188
|
-
return child !== null && child !== undefined && String(child).search(new RegExp(
|
|
204
|
+
return child !== null && child !== undefined && String(child).search(new RegExp(escapedSearchTerm, 'i')) !== -1
|
|
189
205
|
})
|
|
190
206
|
}) as ArrayOrWrapped<T>
|
|
191
207
|
}
|
|
192
208
|
|
|
193
209
|
const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0]) ? props.items : [props.items]) as InputMenuItem[][] : [])
|
|
210
|
+
// eslint-disable-next-line vue/no-dupe-keys
|
|
211
|
+
const items = computed(() => groups.value.flatMap(group => group) as T[])
|
|
194
212
|
|
|
195
213
|
const inputRef = ref<InstanceType<typeof ComboboxInput> | null>(null)
|
|
196
214
|
|
|
@@ -219,6 +237,10 @@ function onBlur(event: FocusEvent) {
|
|
|
219
237
|
emitFormBlur()
|
|
220
238
|
}
|
|
221
239
|
|
|
240
|
+
function onFocus(event: FocusEvent) {
|
|
241
|
+
emits('focus', event)
|
|
242
|
+
}
|
|
243
|
+
|
|
222
244
|
function onUpdateOpen(value: boolean) {
|
|
223
245
|
if (!value) {
|
|
224
246
|
const event = new FocusEvent('blur')
|
|
@@ -260,11 +282,12 @@ defineExpose({
|
|
|
260
282
|
delimiter=""
|
|
261
283
|
as-child
|
|
262
284
|
@blur="onBlur"
|
|
285
|
+
@focus="onFocus"
|
|
263
286
|
>
|
|
264
287
|
<TagsInputItem v-for="(item, index) in tags" :key="index" :value="(item as string)" :class="ui.tagsItem({ class: props.ui?.tagsItem })">
|
|
265
288
|
<TagsInputItemText :class="ui.tagsItemText({ class: props.ui?.tagsItemText })">
|
|
266
289
|
<slot name="tags-item-text" :item="(item as T)" :index="index">
|
|
267
|
-
{{
|
|
290
|
+
{{ displayValue(item as T) }}
|
|
268
291
|
</slot>
|
|
269
292
|
</TagsInputItemText>
|
|
270
293
|
|
|
@@ -296,11 +319,13 @@ defineExpose({
|
|
|
296
319
|
:required="required"
|
|
297
320
|
:class="ui.base({ class: props.ui?.base })"
|
|
298
321
|
@blur="onBlur"
|
|
322
|
+
@focus="onFocus"
|
|
299
323
|
/>
|
|
300
324
|
|
|
301
|
-
<span v-if="isLeading || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })">
|
|
325
|
+
<span v-if="isLeading || !!avatar || !!slots.leading" :class="ui.leading({ class: props.ui?.leading })">
|
|
302
326
|
<slot name="leading" :model-value="(modelValue as T)" :open="open" :ui="ui">
|
|
303
|
-
<UIcon v-if="leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
|
|
327
|
+
<UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
|
|
328
|
+
<UAvatar v-else-if="!!avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
|
304
329
|
</slot>
|
|
305
330
|
</span>
|
|
306
331
|
|
|
@@ -323,7 +348,7 @@ defineExpose({
|
|
|
323
348
|
<ComboboxGroup v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
|
|
324
349
|
<template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
|
|
325
350
|
<ComboboxLabel v-if="item?.type === 'label'" :class="ui.label({ class: props.ui?.label })">
|
|
326
|
-
{{ item.
|
|
351
|
+
{{ get(item, props.labelKey as string) }}
|
|
327
352
|
</ComboboxLabel>
|
|
328
353
|
|
|
329
354
|
<ComboboxSeparator v-else-if="item?.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
|
|
@@ -332,13 +357,13 @@ defineExpose({
|
|
|
332
357
|
v-else
|
|
333
358
|
:class="ui.item({ class: props.ui?.item })"
|
|
334
359
|
:disabled="item.disabled"
|
|
335
|
-
:value="valueKey && typeof item === 'object' ? (item
|
|
336
|
-
@select="item.
|
|
360
|
+
:value="valueKey && typeof item === 'object' ? get(item, props.valueKey as string) : item"
|
|
361
|
+
@select="item.onSelect"
|
|
337
362
|
>
|
|
338
363
|
<slot name="item" :item="(item as T)" :index="index">
|
|
339
364
|
<slot name="item-leading" :item="(item as T)" :index="index">
|
|
340
|
-
<
|
|
341
|
-
<
|
|
365
|
+
<UIcon v-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
|
|
366
|
+
<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 })" />
|
|
342
367
|
<UChip
|
|
343
368
|
v-else-if="item.chip"
|
|
344
369
|
:size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
|
|
@@ -351,7 +376,7 @@ defineExpose({
|
|
|
351
376
|
|
|
352
377
|
<span :class="ui.itemLabel({ class: props.ui?.itemLabel })">
|
|
353
378
|
<slot name="item-label" :item="(item as T)" :index="index">
|
|
354
|
-
{{
|
|
379
|
+
{{ typeof item === 'object' ? get(item, props.labelKey as string) : item }}
|
|
355
380
|
</slot>
|
|
356
381
|
</span>
|
|
357
382
|
|
|
@@ -367,6 +392,8 @@ defineExpose({
|
|
|
367
392
|
</template>
|
|
368
393
|
</ComboboxGroup>
|
|
369
394
|
</ComboboxViewport>
|
|
395
|
+
|
|
396
|
+
<ComboboxArrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
|
|
370
397
|
</ComboboxContent>
|
|
371
398
|
</ComboboxPortal>
|
|
372
399
|
</ComboboxRoot>
|
|
@@ -4,6 +4,7 @@ import type { AppConfig } from '@nuxt/schema'
|
|
|
4
4
|
import _appConfig from '#build/app.config'
|
|
5
5
|
import theme from '#build/ui/kbd'
|
|
6
6
|
import type { KbdKey } from '../composables/useKbd'
|
|
7
|
+
import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
|
|
7
8
|
|
|
8
9
|
const appConfig = _appConfig as AppConfig & { ui: { kbd: Partial<typeof theme> } }
|
|
9
10
|
|
|
@@ -26,6 +27,7 @@ export interface KbdProps {
|
|
|
26
27
|
export interface KbdSlots {
|
|
27
28
|
default(props?: {}): any
|
|
28
29
|
}
|
|
30
|
+
extendDevtoolsMeta({ defaultProps: { value: 'K' } })
|
|
29
31
|
</script>
|
|
30
32
|
|
|
31
33
|
<script setup lang="ts">
|
|
@@ -3,8 +3,55 @@ import type { ButtonHTMLAttributes } from 'vue'
|
|
|
3
3
|
import { tv } from 'tailwind-variants'
|
|
4
4
|
import type { AppConfig } from '@nuxt/schema'
|
|
5
5
|
import _appConfig from '#build/app.config'
|
|
6
|
+
import type { RouterLinkProps, RouteLocationRaw } from 'vue-router'
|
|
6
7
|
import theme from '#build/ui/link'
|
|
7
|
-
import
|
|
8
|
+
import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
|
|
9
|
+
|
|
10
|
+
interface NuxtLinkProps extends Omit<RouterLinkProps, 'to'> {
|
|
11
|
+
/**
|
|
12
|
+
* Route Location the link should navigate to when clicked on.
|
|
13
|
+
*/
|
|
14
|
+
to?: RouteLocationRaw // need to manually type to avoid breaking typedPages
|
|
15
|
+
/**
|
|
16
|
+
* An alias for `to`. If used with `to`, `href` will be ignored
|
|
17
|
+
*/
|
|
18
|
+
href?: NuxtLinkProps['to']
|
|
19
|
+
/**
|
|
20
|
+
* Forces the link to be considered as external (true) or internal (false). This is helpful to handle edge-cases
|
|
21
|
+
*/
|
|
22
|
+
external?: boolean
|
|
23
|
+
/**
|
|
24
|
+
* Where to display the linked URL, as the name for a browsing context.
|
|
25
|
+
*/
|
|
26
|
+
target?: '_blank' | '_parent' | '_self' | '_top' | (string & {}) | null
|
|
27
|
+
/**
|
|
28
|
+
* A rel attribute value to apply on the link. Defaults to "noopener noreferrer" for external links.
|
|
29
|
+
*/
|
|
30
|
+
rel?: 'noopener' | 'noreferrer' | 'nofollow' | 'sponsored' | 'ugc' | (string & {}) | null
|
|
31
|
+
/**
|
|
32
|
+
* If set to true, no rel attribute will be added to the link
|
|
33
|
+
*/
|
|
34
|
+
noRel?: boolean
|
|
35
|
+
/**
|
|
36
|
+
* A class to apply to links that have been prefetched.
|
|
37
|
+
*/
|
|
38
|
+
prefetchedClass?: string
|
|
39
|
+
/**
|
|
40
|
+
* When enabled will prefetch middleware, layouts and payloads of links in the viewport.
|
|
41
|
+
*/
|
|
42
|
+
prefetch?: boolean
|
|
43
|
+
/**
|
|
44
|
+
* Allows controlling when to prefetch links. By default, prefetch is triggered only on visibility.
|
|
45
|
+
*/
|
|
46
|
+
prefetchOn?: 'visibility' | 'interaction' | Partial<{
|
|
47
|
+
visibility: boolean
|
|
48
|
+
interaction: boolean
|
|
49
|
+
}>
|
|
50
|
+
/**
|
|
51
|
+
* Escape hatch to disable `prefetch` attribute.
|
|
52
|
+
*/
|
|
53
|
+
noPrefetch?: boolean
|
|
54
|
+
}
|
|
8
55
|
|
|
9
56
|
const appConfig = _appConfig as AppConfig & { ui: { link: Partial<typeof theme> } }
|
|
10
57
|
|
|
@@ -41,6 +88,8 @@ export interface LinkProps extends NuxtLinkProps {
|
|
|
41
88
|
export interface LinkSlots {
|
|
42
89
|
default(props: { active: boolean }): any
|
|
43
90
|
}
|
|
91
|
+
|
|
92
|
+
extendDevtoolsMeta({ example: 'LinkExample' })
|
|
44
93
|
</script>
|
|
45
94
|
|
|
46
95
|
<script setup lang="ts">
|
|
@@ -3,7 +3,7 @@ export interface LinkBaseProps {
|
|
|
3
3
|
as?: string
|
|
4
4
|
type?: string
|
|
5
5
|
disabled?: boolean
|
|
6
|
-
onClick?: (e: MouseEvent) => void | Promise<void>
|
|
6
|
+
onClick?: ((e: MouseEvent) => void | Promise<void>) | Array<((e: MouseEvent) => void | Promise<void>)>
|
|
7
7
|
href?: string
|
|
8
8
|
navigate?: (e: MouseEvent) => void
|
|
9
9
|
rel?: string
|
|
@@ -28,7 +28,9 @@ function onClickWrapper(e: MouseEvent) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
if (props.onClick) {
|
|
31
|
-
props.onClick
|
|
31
|
+
for (const onClick of Array.isArray(props.onClick) ? props.onClick : [props.onClick]) {
|
|
32
|
+
onClick(e)
|
|
33
|
+
}
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
if (props.href && props.navigate && !props.isExternal) {
|
|
@@ -4,6 +4,7 @@ import type { DialogRootProps, DialogRootEmits, DialogContentProps } from 'radix
|
|
|
4
4
|
import type { AppConfig } from '@nuxt/schema'
|
|
5
5
|
import _appConfig from '#build/app.config'
|
|
6
6
|
import theme from '#build/ui/modal'
|
|
7
|
+
import { extendDevtoolsMeta } from '../composables/extendDevtoolsMeta'
|
|
7
8
|
import type { ButtonProps } from '../types'
|
|
8
9
|
|
|
9
10
|
const appConfig = _appConfig as AppConfig & { ui: { modal: Partial<typeof theme> } }
|
|
@@ -67,6 +68,8 @@ export interface ModalSlots {
|
|
|
67
68
|
body(props?: {}): any
|
|
68
69
|
footer(props?: {}): any
|
|
69
70
|
}
|
|
71
|
+
|
|
72
|
+
extendDevtoolsMeta({ example: 'ModalExample' })
|
|
70
73
|
</script>
|
|
71
74
|
|
|
72
75
|
<script setup lang="ts">
|