@nuxt/ui 3.0.0-alpha.8 → 3.0.0-beta.1
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 +9 -7
- 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 +7 -1
- package/.nuxt/ui/input-menu.ts +150 -116
- package/.nuxt/ui/input-number.ts +235 -0
- 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 +171 -0
- 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 +127 -96
- 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 +49 -31
- package/.nuxt/ui/tabs.ts +101 -73
- 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 +69 -18
- package/cli/commands/{init.mjs → make/component.mjs} +16 -4
- package/cli/commands/make/index.mjs +14 -0
- package/cli/commands/make/locale.mjs +64 -0
- package/cli/index.mjs +2 -2
- package/cli/package.json +2 -2
- package/cli/templates.mjs +62 -12
- package/cli/utils.mjs +14 -0
- package/dist/module.cjs +9 -170
- 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 -167
- package/dist/runtime/components/Accordion.vue +8 -39
- package/dist/runtime/components/Alert.vue +25 -21
- package/dist/runtime/components/App.vue +15 -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 +13 -34
- 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 +26 -17
- 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 +114 -98
- package/dist/runtime/components/Container.vue +4 -7
- package/dist/runtime/components/ContextMenu.vue +16 -69
- package/dist/runtime/components/ContextMenuContent.vue +14 -10
- package/dist/runtime/components/Drawer.vue +23 -12
- package/dist/runtime/components/DropdownMenu.vue +18 -59
- package/dist/runtime/components/DropdownMenuContent.vue +14 -10
- package/dist/runtime/components/Form.vue +78 -49
- package/dist/runtime/components/FormField.vue +28 -15
- package/dist/runtime/components/Icon.vue +1 -1
- package/dist/runtime/components/Input.vue +15 -7
- package/dist/runtime/components/InputMenu.vue +133 -66
- package/dist/runtime/components/InputNumber.vue +197 -0
- package/dist/runtime/components/Kbd.vue +5 -6
- package/dist/runtime/components/Link.vue +24 -13
- package/dist/runtime/components/LinkBase.vue +1 -1
- package/dist/runtime/components/Modal.vue +56 -34
- package/dist/runtime/components/NavigationMenu.vue +129 -112
- package/dist/runtime/components/OverlayProvider.vue +28 -0
- package/dist/runtime/components/Pagination.vue +18 -14
- package/dist/runtime/components/PinInput.vue +95 -0
- package/dist/runtime/components/Popover.vue +28 -14
- package/dist/runtime/components/Progress.vue +28 -12
- package/dist/runtime/components/RadioGroup.vue +9 -12
- package/dist/runtime/components/Select.vue +61 -35
- package/dist/runtime/components/SelectMenu.vue +201 -130
- package/dist/runtime/components/Separator.vue +6 -5
- package/dist/runtime/components/Skeleton.vue +4 -7
- package/dist/runtime/components/Slideover.vue +56 -33
- 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 +157 -32
- package/dist/runtime/components/Tabs.vue +12 -31
- package/dist/runtime/components/Textarea.vue +18 -9
- package/dist/runtime/components/Toast.vue +39 -25
- package/dist/runtime/components/Toaster.vue +31 -24
- package/dist/runtime/components/Tooltip.vue +9 -12
- package/dist/runtime/components/Tree.vue +196 -0
- package/dist/runtime/composables/defineLocale.d.ts +9 -0
- package/dist/runtime/composables/defineLocale.js +4 -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 +11 -4
- package/dist/runtime/composables/useFormField.js +19 -9
- package/dist/runtime/composables/useLocale.d.ts +4 -0
- package/dist/runtime/composables/useLocale.js +10 -0
- package/dist/runtime/composables/useOverlay.d.ts +30 -0
- package/dist/runtime/composables/useOverlay.js +70 -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.d.ts +2 -0
- package/dist/runtime/locale/ar.js +55 -0
- package/dist/runtime/locale/az.d.ts +2 -0
- package/dist/runtime/locale/az.js +54 -0
- package/dist/runtime/locale/bn.d.ts +2 -0
- package/dist/runtime/locale/bn.js +54 -0
- package/dist/runtime/locale/cs.d.ts +2 -0
- package/dist/runtime/locale/cs.js +54 -0
- package/dist/runtime/locale/da.d.ts +2 -0
- package/dist/runtime/locale/da.js +54 -0
- package/dist/runtime/locale/de.d.ts +2 -0
- package/dist/runtime/locale/de.js +54 -0
- package/dist/runtime/locale/el.d.ts +2 -0
- package/dist/runtime/locale/el.js +54 -0
- package/dist/runtime/locale/en.d.ts +2 -0
- package/dist/runtime/locale/en.js +54 -0
- package/dist/runtime/locale/es.d.ts +2 -0
- package/dist/runtime/locale/es.js +54 -0
- package/dist/runtime/locale/et.d.ts +2 -0
- package/dist/runtime/locale/et.js +54 -0
- package/dist/runtime/locale/fa_ir.d.ts +2 -0
- package/dist/runtime/locale/fa_ir.js +55 -0
- package/dist/runtime/locale/fi.d.ts +2 -0
- package/dist/runtime/locale/fi.js +54 -0
- package/dist/runtime/locale/fr.d.ts +2 -0
- package/dist/runtime/locale/fr.js +54 -0
- 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 +34 -0
- package/dist/runtime/locale/index.js +34 -0
- package/dist/runtime/locale/it.d.ts +2 -0
- package/dist/runtime/locale/it.js +54 -0
- 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.d.ts +2 -0
- package/dist/runtime/locale/pl.js +54 -0
- 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.d.ts +2 -0
- package/dist/runtime/locale/ru.js +54 -0
- 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_cn.js +54 -0
- package/dist/runtime/locale/zh_tw.d.ts +2 -0
- package/dist/runtime/locale/zh_tw.js +54 -0
- package/dist/runtime/plugins/colors.js +8 -5
- package/dist/runtime/types/form.d.ts +29 -15
- package/dist/runtime/types/form.js +2 -2
- package/dist/runtime/types/index.d.ts +8 -0
- package/dist/runtime/types/index.js +8 -0
- package/dist/runtime/types/locale.d.ts +56 -0
- package/dist/runtime/types/locale.js +0 -0
- package/dist/runtime/types/utils.d.ts +7 -3
- package/dist/runtime/utils/form.d.ts +5 -9
- package/dist/runtime/utils/form.js +113 -50
- package/dist/runtime/utils/index.d.ts +1 -1
- package/dist/runtime/utils/index.js +15 -2
- package/dist/runtime/utils/link.d.ts +1 -1
- package/dist/runtime/utils/locale.d.ts +15 -0
- package/dist/runtime/utils/locale.js +25 -0
- 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.BufKhDiD.mjs → ui.DSPu6Y8j.mjs} +1071 -409
- package/dist/shared/{ui.BU7wzH0D.cjs → ui.DfK2RX6G.cjs} +1074 -409
- package/dist/unplugin.cjs +62 -26
- package/dist/unplugin.d.cts +17 -3
- package/dist/unplugin.d.mts +17 -3
- package/dist/unplugin.d.ts +17 -3
- 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 +110 -67
- package/dist/chunks/component-meta.cjs +0 -73264
- package/dist/chunks/component-meta.mjs +0 -73262
- 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/Bj9hdafK.js +0 -1
- package/dist/client/devtools/_nuxt/DM3_wAgz.js +0 -62
- package/dist/client/devtools/_nuxt/builds/latest.json +0 -1
- package/dist/client/devtools/_nuxt/builds/meta/e6b425f7-b919-4014-915b-0ea07c316790.json +0 -1
- package/dist/client/devtools/_nuxt/entry.DaJP-ZMB.css +0 -24
- package/dist/client/devtools/_nuxt/error-404.B0Nmv3fV.css +0 -1
- package/dist/client/devtools/_nuxt/error-500.C8fgTxVz.css +0 -1
- package/dist/client/devtools/_nuxt/hKiujHsR.js +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
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import type { ComboboxRootProps, ComboboxRootEmits } from 'radix-vue'
|
|
2
|
+
import type { ListboxRootProps, ListboxRootEmits } from 'reka-ui'
|
|
4
3
|
import type { FuseResult } from 'fuse.js'
|
|
5
4
|
import type { AppConfig } from '@nuxt/schema'
|
|
6
5
|
import type { UseFuseOptions } from '@vueuse/integrations/useFuse'
|
|
7
6
|
import _appConfig from '#build/app.config'
|
|
8
7
|
import theme from '#build/ui/command-palette'
|
|
9
8
|
import type { UseComponentIconsProps } from '../composables/useComponentIcons'
|
|
10
|
-
import {
|
|
11
|
-
import type { AvatarProps, ButtonProps, ChipProps, KbdProps, InputProps } from '../types'
|
|
9
|
+
import { tv } from '../utils/tv'
|
|
10
|
+
import type { AvatarProps, ButtonProps, ChipProps, KbdProps, InputProps, LinkProps } from '../types'
|
|
12
11
|
import type { DynamicSlots, PartialString } from '../types/utils'
|
|
13
12
|
|
|
14
|
-
const
|
|
13
|
+
const appConfigCommandPalette = _appConfig as AppConfig & { ui: { commandPalette: Partial<typeof theme> } }
|
|
15
14
|
|
|
16
|
-
const commandPalette = tv({ extend: tv(theme), ...(
|
|
15
|
+
const commandPalette = tv({ extend: tv(theme), ...(appConfigCommandPalette.ui?.commandPalette || {}) })
|
|
17
16
|
|
|
18
|
-
export interface CommandPaletteItem {
|
|
17
|
+
export interface CommandPaletteItem extends Omit<LinkProps, 'type' | 'raw' | 'custom'> {
|
|
19
18
|
prefix?: string
|
|
20
19
|
label?: string
|
|
21
20
|
suffix?: string
|
|
@@ -23,6 +22,7 @@ export interface CommandPaletteItem {
|
|
|
23
22
|
avatar?: AvatarProps
|
|
24
23
|
chip?: ChipProps
|
|
25
24
|
kbds?: KbdProps['value'][] | KbdProps[]
|
|
25
|
+
active?: boolean
|
|
26
26
|
loading?: boolean
|
|
27
27
|
disabled?: boolean
|
|
28
28
|
slot?: string
|
|
@@ -35,18 +35,18 @@ export interface CommandPaletteGroup<T> {
|
|
|
35
35
|
slot?: string
|
|
36
36
|
items?: T[]
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
* When `
|
|
40
|
-
* @defaultValue
|
|
38
|
+
* Whether to filter group items with [useFuse](https://vueuse.org/integrations/useFuse).
|
|
39
|
+
* When `true`, items will not be filtered which is useful for custom filtering (useAsyncData, useFetch, etc.).
|
|
40
|
+
* @defaultValue false
|
|
41
41
|
*/
|
|
42
|
-
|
|
42
|
+
ignoreFilter?: boolean
|
|
43
43
|
/** Filter group items after the search happened. */
|
|
44
44
|
postFilter?: (searchTerm: string, items: T[]) => T[]
|
|
45
45
|
/** The icon displayed when an item is highlighted. */
|
|
46
46
|
highlightedIcon?: string
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export interface CommandPaletteProps<G, T> extends Pick<
|
|
49
|
+
export interface CommandPaletteProps<G, T> extends Pick<ListboxRootProps, 'multiple' | 'disabled' | 'modelValue' | 'defaultValue' | 'highlightOnHover'>, Pick<UseComponentIconsProps, 'loading' | 'loadingIcon'> {
|
|
50
50
|
/**
|
|
51
51
|
* The element or component this component should render as.
|
|
52
52
|
* @defaultValue 'div'
|
|
@@ -67,12 +67,18 @@ export interface CommandPaletteProps<G, T> extends Pick<ComboboxRootProps, 'mult
|
|
|
67
67
|
* @defaultValue 'Type a command or search...'
|
|
68
68
|
*/
|
|
69
69
|
placeholder?: InputProps['placeholder']
|
|
70
|
+
/**
|
|
71
|
+
* Automatically focus the input when component is mounted.
|
|
72
|
+
* @defaultValue true
|
|
73
|
+
*/
|
|
74
|
+
autofocus?: boolean
|
|
70
75
|
/**
|
|
71
76
|
* Display a close button in the input (useful when inside a Modal for example).
|
|
72
77
|
* `{ size: 'md', color: 'neutral', variant: 'ghost' }`{lang="ts-type"}
|
|
78
|
+
* @emits 'update:open'
|
|
73
79
|
* @defaultValue false
|
|
74
80
|
*/
|
|
75
|
-
close?:
|
|
81
|
+
close?: boolean | Partial<ButtonProps>
|
|
76
82
|
/**
|
|
77
83
|
* The icon displayed in the close button.
|
|
78
84
|
* @defaultValue appConfig.ui.icons.close
|
|
@@ -101,7 +107,9 @@ export interface CommandPaletteProps<G, T> extends Pick<ComboboxRootProps, 'mult
|
|
|
101
107
|
ui?: PartialString<typeof commandPalette.slots>
|
|
102
108
|
}
|
|
103
109
|
|
|
104
|
-
export type CommandPaletteEmits<T> =
|
|
110
|
+
export type CommandPaletteEmits<T> = ListboxRootEmits<T> & {
|
|
111
|
+
'update:open': [value: boolean]
|
|
112
|
+
}
|
|
105
113
|
|
|
106
114
|
type SlotProps<T> = (props: { item: T, index: number }) => any
|
|
107
115
|
|
|
@@ -113,39 +121,43 @@ export type CommandPaletteSlots<G extends { slot?: string }, T extends { slot?:
|
|
|
113
121
|
'item-label': SlotProps<T>
|
|
114
122
|
'item-trailing': SlotProps<T>
|
|
115
123
|
} & DynamicSlots<G, SlotProps<T>> & DynamicSlots<T, SlotProps<T>>
|
|
116
|
-
|
|
117
|
-
extendDevtoolsMeta({ example: 'CommandPaletteExample', ignoreProps: ['groups'] })
|
|
118
124
|
</script>
|
|
119
125
|
|
|
120
126
|
<script setup lang="ts" generic="G extends CommandPaletteGroup<T>, T extends CommandPaletteItem">
|
|
121
127
|
import { computed } from 'vue'
|
|
122
|
-
import {
|
|
128
|
+
import { ListboxRoot, ListboxFilter, ListboxContent, ListboxGroup, ListboxGroupLabel, ListboxItem, ListboxItemIndicator, useForwardProps, useForwardPropsEmits } from 'reka-ui'
|
|
123
129
|
import { defu } from 'defu'
|
|
124
130
|
import { reactivePick } from '@vueuse/core'
|
|
125
131
|
import { useFuse } from '@vueuse/integrations/useFuse'
|
|
126
132
|
import { useAppConfig } from '#imports'
|
|
133
|
+
import { useLocale } from '../composables/useLocale'
|
|
127
134
|
import { omit, get } from '../utils'
|
|
128
135
|
import { highlight } from '../utils/fuse'
|
|
136
|
+
import { pickLinkProps } from '../utils/link'
|
|
129
137
|
import UIcon from './Icon.vue'
|
|
130
138
|
import UAvatar from './Avatar.vue'
|
|
131
139
|
import UButton from './Button.vue'
|
|
132
140
|
import UChip from './Chip.vue'
|
|
133
|
-
import
|
|
141
|
+
import ULinkBase from './LinkBase.vue'
|
|
142
|
+
import ULink from './Link.vue'
|
|
134
143
|
import UInput from './Input.vue'
|
|
144
|
+
import UKbd from './Kbd.vue'
|
|
135
145
|
|
|
136
146
|
const props = withDefaults(defineProps<CommandPaletteProps<G, T>>(), {
|
|
137
147
|
modelValue: '',
|
|
138
|
-
|
|
139
|
-
|
|
148
|
+
labelKey: 'label',
|
|
149
|
+
autofocus: true
|
|
140
150
|
})
|
|
141
151
|
const emits = defineEmits<CommandPaletteEmits<T>>()
|
|
142
152
|
const slots = defineSlots<CommandPaletteSlots<G, T>>()
|
|
143
153
|
|
|
144
154
|
const searchTerm = defineModel<string>('searchTerm', { default: '' })
|
|
145
155
|
|
|
156
|
+
const { t } = useLocale()
|
|
146
157
|
const appConfig = useAppConfig()
|
|
147
|
-
|
|
148
|
-
const
|
|
158
|
+
|
|
159
|
+
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'disabled', 'multiple', 'modelValue', 'defaultValue', 'highlightOnHover'), emits)
|
|
160
|
+
const inputProps = useForwardProps(reactivePick(props, 'loading', 'loadingIcon'))
|
|
149
161
|
|
|
150
162
|
// eslint-disable-next-line vue/no-dupe-keys
|
|
151
163
|
const ui = commandPalette()
|
|
@@ -166,7 +178,7 @@ const items = computed(() => props.groups?.filter((group) => {
|
|
|
166
178
|
return false
|
|
167
179
|
}
|
|
168
180
|
|
|
169
|
-
if (group.
|
|
181
|
+
if (group.ignoreFilter) {
|
|
170
182
|
return false
|
|
171
183
|
}
|
|
172
184
|
|
|
@@ -214,24 +226,26 @@ const groups = computed(() => {
|
|
|
214
226
|
return getGroupWithItems(group, items)
|
|
215
227
|
}).filter(group => !!group)
|
|
216
228
|
|
|
217
|
-
const nonFuseGroups = props.groups
|
|
218
|
-
|
|
219
|
-
|
|
229
|
+
const nonFuseGroups = props.groups
|
|
230
|
+
?.map((group, index) => ({ ...group, index }))
|
|
231
|
+
?.filter(group => group.ignoreFilter && group.items?.length)
|
|
232
|
+
?.map(group => ({ ...getGroupWithItems(group, group.items || []), index: group.index })) || []
|
|
220
233
|
|
|
221
|
-
return
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
]
|
|
234
|
+
return nonFuseGroups.reduce((acc, group) => {
|
|
235
|
+
acc.splice(group.index, 0, group)
|
|
236
|
+
return acc
|
|
237
|
+
}, [...fuseGroups])
|
|
225
238
|
})
|
|
226
239
|
</script>
|
|
227
240
|
|
|
228
241
|
<!-- eslint-disable vue/no-v-html -->
|
|
229
242
|
<template>
|
|
230
|
-
<
|
|
231
|
-
<
|
|
243
|
+
<ListboxRoot v-bind="rootProps" :class="ui.root({ class: [props.class, props.ui?.root] })">
|
|
244
|
+
<ListboxFilter v-model="searchTerm" as-child>
|
|
232
245
|
<UInput
|
|
246
|
+
:placeholder="placeholder || t('commandPalette.placeholder')"
|
|
233
247
|
variant="none"
|
|
234
|
-
autofocus
|
|
248
|
+
:autofocus="autofocus"
|
|
235
249
|
size="lg"
|
|
236
250
|
v-bind="inputProps"
|
|
237
251
|
:icon="icon || appConfig.ui.icons.search"
|
|
@@ -245,80 +259,82 @@ const groups = computed(() => {
|
|
|
245
259
|
size="md"
|
|
246
260
|
color="neutral"
|
|
247
261
|
variant="ghost"
|
|
248
|
-
aria-label="
|
|
249
|
-
v-bind="typeof close === 'object' ? close :
|
|
262
|
+
:aria-label="t('commandPalette.close')"
|
|
263
|
+
v-bind="(typeof close === 'object' ? close as Partial<ButtonProps> : {})"
|
|
250
264
|
:class="ui.close({ class: props.ui?.close })"
|
|
251
265
|
@click="emits('update:open', false)"
|
|
252
266
|
/>
|
|
253
267
|
</slot>
|
|
254
268
|
</template>
|
|
255
269
|
</UInput>
|
|
256
|
-
</
|
|
270
|
+
</ListboxFilter>
|
|
271
|
+
|
|
272
|
+
<ListboxContent :class="ui.content({ class: props.ui?.content })">
|
|
273
|
+
<div v-if="groups?.length" :class="ui.viewport({ class: props.ui?.viewport })">
|
|
274
|
+
<ListboxGroup v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
|
|
275
|
+
<ListboxGroupLabel v-if="get(group, props.labelKey as string)" :class="ui.label({ class: props.ui?.label })">
|
|
276
|
+
{{ get(group, props.labelKey as string) }}
|
|
277
|
+
</ListboxGroupLabel>
|
|
278
|
+
|
|
279
|
+
<ListboxItem
|
|
280
|
+
v-for="(item, index) in group.items"
|
|
281
|
+
:key="`group-${groupIndex}-${index}`"
|
|
282
|
+
:value="omit(item, ['matches' as any, 'group' as any, 'onSelect', 'labelHtml', 'suffixHtml'])"
|
|
283
|
+
:disabled="item.disabled"
|
|
284
|
+
as-child
|
|
285
|
+
@select="item.onSelect"
|
|
286
|
+
>
|
|
287
|
+
<ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
|
|
288
|
+
<ULinkBase v-bind="slotProps" :class="ui.item({ class: props.ui?.item, active: active || item.active })">
|
|
289
|
+
<slot :name="item.slot || group.slot || 'item'" :item="item" :index="index">
|
|
290
|
+
<slot :name="item.slot ? `${item.slot}-leading` : group.slot ? `${group.slot}-leading` : `item-leading`" :item="item" :index="index">
|
|
291
|
+
<UIcon v-if="item.loading" :name="loadingIcon || appConfig.ui.icons.loading" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon, loading: true })" />
|
|
292
|
+
<UIcon v-else-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon, active: active || item.active })" />
|
|
293
|
+
<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, active: active || item.active })" />
|
|
294
|
+
<UChip
|
|
295
|
+
v-else-if="item.chip"
|
|
296
|
+
:size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
|
|
297
|
+
inset
|
|
298
|
+
standalone
|
|
299
|
+
v-bind="item.chip"
|
|
300
|
+
:class="ui.itemLeadingChip({ class: props.ui?.itemLeadingChip, active: active || item.active })"
|
|
301
|
+
/>
|
|
302
|
+
</slot>
|
|
257
303
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
<slot name="empty" :search-term="searchTerm">
|
|
262
|
-
{{ searchTerm ? `No results for ${searchTerm}` : 'No results' }}
|
|
263
|
-
</slot>
|
|
264
|
-
</ComboboxEmpty>
|
|
265
|
-
|
|
266
|
-
<ComboboxViewport :class="ui.viewport({ class: props.ui?.viewport })">
|
|
267
|
-
<ComboboxGroup v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
|
|
268
|
-
<ComboboxLabel v-if="get(group, props.labelKey as string)" :class="ui.label({ class: props.ui?.label })">
|
|
269
|
-
{{ get(group, props.labelKey as string) }}
|
|
270
|
-
</ComboboxLabel>
|
|
271
|
-
|
|
272
|
-
<ComboboxItem
|
|
273
|
-
v-for="(item, index) in group.items"
|
|
274
|
-
:key="`group-${groupIndex}-${index}`"
|
|
275
|
-
:value="omit(item, ['matches' as any, 'group' as any, 'onSelect', 'labelHtml', 'suffixHtml'])"
|
|
276
|
-
:disabled="item.disabled"
|
|
277
|
-
:class="ui.item({ class: props.ui?.item })"
|
|
278
|
-
@select="item.onSelect"
|
|
279
|
-
>
|
|
280
|
-
<slot :name="item.slot || group.slot || 'item'" :item="item" :index="index">
|
|
281
|
-
<slot :name="item.slot ? `${item.slot}-leading` : group.slot ? `${group.slot}-leading` : `item-leading`" :item="item" :index="index">
|
|
282
|
-
<UIcon v-if="item.loading" :name="loadingIcon || appConfig.ui.icons.loading" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon, loading: true })" />
|
|
283
|
-
<UIcon v-else-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
|
|
284
|
-
<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 })" />
|
|
285
|
-
<UChip
|
|
286
|
-
v-else-if="item.chip"
|
|
287
|
-
:size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
|
|
288
|
-
inset
|
|
289
|
-
standalone
|
|
290
|
-
v-bind="item.chip"
|
|
291
|
-
:class="ui.itemLeadingChip({ class: props.ui?.itemLeadingChip })"
|
|
292
|
-
/>
|
|
293
|
-
</slot>
|
|
304
|
+
<span v-if="item.labelHtml || get(item, props.labelKey as string) || !!slots[item.slot ? `${item.slot}-label` : group.slot ? `${group.slot}-label` : `item-label`]" :class="ui.itemLabel({ class: props.ui?.itemLabel, active: active || item.active })">
|
|
305
|
+
<slot :name="item.slot ? `${item.slot}-label` : group.slot ? `${group.slot}-label` : `item-label`" :item="item" :index="index">
|
|
306
|
+
<span v-if="item.prefix" :class="ui.itemLabelPrefix({ class: props.ui?.itemLabelPrefix })">{{ item.prefix }}</span>
|
|
294
307
|
|
|
295
|
-
|
|
296
|
-
<slot :name="item.slot ? `${item.slot}-label` : group.slot ? `${group.slot}-label` : `item-label`" :item="item" :index="index">
|
|
297
|
-
<span v-if="item.prefix" :class="ui.itemLabelPrefix({ class: props.ui?.itemLabelPrefix })">{{ item.prefix }}</span>
|
|
308
|
+
<span :class="ui.itemLabelBase({ class: props.ui?.itemLabelBase, active: active || item.active })" v-html="item.labelHtml || get(item, props.labelKey as string)" />
|
|
298
309
|
|
|
299
|
-
|
|
310
|
+
<span :class="ui.itemLabelSuffix({ class: props.ui?.itemLabelSuffix, active: active || item.active })" v-html="item.suffixHtml || item.suffix" />
|
|
311
|
+
</slot>
|
|
312
|
+
</span>
|
|
300
313
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
<UKbd v-for="(kbd, kbdIndex) in item.kbds" :key="kbdIndex" :size="((props.ui?.itemTrailingKbdsSize || ui.itemTrailingKbdsSize()) as KbdProps['size'])" v-bind="typeof kbd === 'string' ? { value: kbd } : kbd" />
|
|
309
|
-
</span>
|
|
310
|
-
<UIcon v-else-if="group.highlightedIcon" :name="group.highlightedIcon" :class="ui.itemTrailingHighlightedIcon({ class: props.ui?.itemTrailingHighlightedIcon })" />
|
|
311
|
-
</slot>
|
|
314
|
+
<span :class="ui.itemTrailing({ class: props.ui?.itemTrailing })">
|
|
315
|
+
<slot :name="item.slot ? `${item.slot}-trailing` : group.slot ? `${group.slot}-trailing` : `item-trailing`" :item="item" :index="index">
|
|
316
|
+
<span v-if="item.kbds?.length" :class="ui.itemTrailingKbds({ class: props.ui?.itemTrailingKbds })">
|
|
317
|
+
<UKbd v-for="(kbd, kbdIndex) in item.kbds" :key="kbdIndex" :size="((props.ui?.itemTrailingKbdsSize || ui.itemTrailingKbdsSize()) as KbdProps['size'])" v-bind="typeof kbd === 'string' ? { value: kbd } : kbd" />
|
|
318
|
+
</span>
|
|
319
|
+
<UIcon v-else-if="group.highlightedIcon" :name="group.highlightedIcon" :class="ui.itemTrailingHighlightedIcon({ class: props.ui?.itemTrailingHighlightedIcon })" />
|
|
320
|
+
</slot>
|
|
312
321
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
322
|
+
<ListboxItemIndicator as-child>
|
|
323
|
+
<UIcon :name="selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: props.ui?.itemTrailingIcon })" />
|
|
324
|
+
</ListboxItemIndicator>
|
|
325
|
+
</span>
|
|
326
|
+
</slot>
|
|
327
|
+
</ULinkBase>
|
|
328
|
+
</ULink>
|
|
329
|
+
</ListboxItem>
|
|
330
|
+
</ListboxGroup>
|
|
331
|
+
</div>
|
|
332
|
+
|
|
333
|
+
<div v-else :class="ui.empty({ class: props.ui?.empty })">
|
|
334
|
+
<slot name="empty" :search-term="searchTerm">
|
|
335
|
+
{{ searchTerm ? t('commandPalette.noMatch', { searchTerm }) : t('commandPalette.noData') }}
|
|
336
|
+
</slot>
|
|
337
|
+
</div>
|
|
338
|
+
</ListboxContent>
|
|
339
|
+
</ListboxRoot>
|
|
324
340
|
</template>
|
|
@@ -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/container'
|
|
6
|
-
import {
|
|
5
|
+
import { tv } from '../utils/tv'
|
|
7
6
|
|
|
8
|
-
const
|
|
7
|
+
const appConfigContainer = _appConfig as AppConfig & { ui: { container: Partial<typeof theme> } }
|
|
9
8
|
|
|
10
|
-
const container = tv({ extend: tv(theme), ...(
|
|
9
|
+
const container = tv({ extend: tv(theme), ...(appConfigContainer.ui?.container || {}) })
|
|
11
10
|
|
|
12
11
|
export interface ContainerProps {
|
|
13
12
|
/**
|
|
@@ -21,12 +20,10 @@ export interface ContainerProps {
|
|
|
21
20
|
export interface ContainerSlots {
|
|
22
21
|
default(props?: {}): any
|
|
23
22
|
}
|
|
24
|
-
|
|
25
|
-
extendDevtoolsMeta({ example: 'ContainerExample' })
|
|
26
23
|
</script>
|
|
27
24
|
|
|
28
25
|
<script setup lang="ts">
|
|
29
|
-
import { Primitive } from '
|
|
26
|
+
import { Primitive } from 'reka-ui'
|
|
30
27
|
|
|
31
28
|
const props = defineProps<ContainerProps>()
|
|
32
29
|
defineSlots<ContainerSlots>()
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import type { ContextMenuRootProps, ContextMenuRootEmits, ContextMenuContentProps } from '
|
|
2
|
+
import type { VariantProps } from 'tailwind-variants'
|
|
3
|
+
import type { ContextMenuRootProps, ContextMenuRootEmits, ContextMenuContentProps } 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/context-menu'
|
|
7
|
-
import {
|
|
7
|
+
import { tv } from '../utils/tv'
|
|
8
8
|
import type { AvatarProps, KbdProps, LinkProps } from '../types'
|
|
9
9
|
import type { DynamicSlots, PartialString } from '../types/utils'
|
|
10
10
|
|
|
11
|
-
const
|
|
11
|
+
const appConfigContextMenu = _appConfig as AppConfig & { ui: { contextMenu: Partial<typeof theme> } }
|
|
12
12
|
|
|
13
|
-
const contextMenu = tv({ extend: tv(theme), ...(
|
|
13
|
+
const contextMenu = tv({ extend: tv(theme), ...(appConfigContextMenu.ui?.contextMenu || {}) })
|
|
14
14
|
|
|
15
15
|
type ContextMenuVariants = VariantProps<typeof contextMenu>
|
|
16
16
|
|
|
@@ -50,6 +50,12 @@ export interface ContextMenuProps<T> extends Omit<ContextMenuRootProps, 'dir'> {
|
|
|
50
50
|
* @defaultValue appConfig.ui.icons.loading
|
|
51
51
|
*/
|
|
52
52
|
loadingIcon?: string
|
|
53
|
+
/**
|
|
54
|
+
* The icon displayed when the item is an external link.
|
|
55
|
+
* Set to `false` to hide the external icon.
|
|
56
|
+
* @defaultValue appConfig.ui.icons.external
|
|
57
|
+
*/
|
|
58
|
+
externalIcon?: boolean | string
|
|
53
59
|
/** The content of the menu. */
|
|
54
60
|
content?: Omit<ContextMenuContentProps, 'as' | 'asChild' | 'forceMount'>
|
|
55
61
|
/**
|
|
@@ -78,72 +84,11 @@ export type ContextMenuSlots<T extends { slot?: string }> = {
|
|
|
78
84
|
'item-label': SlotProps<T>
|
|
79
85
|
'item-trailing': SlotProps<T>
|
|
80
86
|
} & DynamicSlots<T, SlotProps<T>>
|
|
81
|
-
|
|
82
|
-
extendDevtoolsMeta({
|
|
83
|
-
example: 'ContextMenuExample',
|
|
84
|
-
ignoreProps: ['items'],
|
|
85
|
-
defaultProps: {
|
|
86
|
-
items: [
|
|
87
|
-
[{
|
|
88
|
-
label: 'My account',
|
|
89
|
-
avatar: {
|
|
90
|
-
src: 'https://avatars.githubusercontent.com/u/739984?v=4'
|
|
91
|
-
}
|
|
92
|
-
}],
|
|
93
|
-
[{
|
|
94
|
-
label: 'Appearance',
|
|
95
|
-
children: [{
|
|
96
|
-
label: 'System',
|
|
97
|
-
icon: 'i-lucide-monitor'
|
|
98
|
-
}, {
|
|
99
|
-
label: 'Light',
|
|
100
|
-
icon: 'i-lucide-sun'
|
|
101
|
-
}, {
|
|
102
|
-
label: 'Dark',
|
|
103
|
-
icon: 'i-lucide-moon'
|
|
104
|
-
}]
|
|
105
|
-
}],
|
|
106
|
-
[{
|
|
107
|
-
label: 'Show Sidebar',
|
|
108
|
-
kbds: ['meta', 'S']
|
|
109
|
-
}, {
|
|
110
|
-
label: 'Show Toolbar',
|
|
111
|
-
kbds: ['shift', 'meta', 'D']
|
|
112
|
-
}, {
|
|
113
|
-
label: 'Collapse Pinned Tabs',
|
|
114
|
-
disabled: true
|
|
115
|
-
}], [{
|
|
116
|
-
label: 'Refresh the Page'
|
|
117
|
-
}, {
|
|
118
|
-
label: 'Clear Cookies and Refresh'
|
|
119
|
-
}, {
|
|
120
|
-
label: 'Clear Cache and Refresh'
|
|
121
|
-
}, {
|
|
122
|
-
type: 'separator'
|
|
123
|
-
}, {
|
|
124
|
-
label: 'Developer',
|
|
125
|
-
children: [[{
|
|
126
|
-
label: 'View Source',
|
|
127
|
-
kbds: ['option', 'meta', 'U']
|
|
128
|
-
}, {
|
|
129
|
-
label: 'Developer Tools',
|
|
130
|
-
kbds: ['option', 'meta', 'I']
|
|
131
|
-
}], [{
|
|
132
|
-
label: 'Inspect Elements',
|
|
133
|
-
kbds: ['option', 'meta', 'C']
|
|
134
|
-
}], [{
|
|
135
|
-
label: 'JavaScript Console',
|
|
136
|
-
kbds: ['option', 'meta', 'J']
|
|
137
|
-
}]]
|
|
138
|
-
}]
|
|
139
|
-
]
|
|
140
|
-
}
|
|
141
|
-
})
|
|
142
87
|
</script>
|
|
143
88
|
|
|
144
89
|
<script setup lang="ts" generic="T extends ContextMenuItem">
|
|
145
90
|
import { computed, toRef } from 'vue'
|
|
146
|
-
import { ContextMenuRoot, ContextMenuTrigger, useForwardPropsEmits } from '
|
|
91
|
+
import { ContextMenuRoot, ContextMenuTrigger, useForwardPropsEmits } from 'reka-ui'
|
|
147
92
|
import { reactivePick } from '@vueuse/core'
|
|
148
93
|
import { omit } from '../utils'
|
|
149
94
|
import UContextMenuContent from './ContextMenuContent.vue'
|
|
@@ -151,6 +96,7 @@ import UContextMenuContent from './ContextMenuContent.vue'
|
|
|
151
96
|
const props = withDefaults(defineProps<ContextMenuProps<T>>(), {
|
|
152
97
|
portal: true,
|
|
153
98
|
modal: true,
|
|
99
|
+
externalIcon: true,
|
|
154
100
|
labelKey: 'label'
|
|
155
101
|
})
|
|
156
102
|
const emits = defineEmits<ContextMenuEmits>()
|
|
@@ -167,12 +113,12 @@ const ui = computed(() => contextMenu({
|
|
|
167
113
|
|
|
168
114
|
<template>
|
|
169
115
|
<ContextMenuRoot v-bind="rootProps">
|
|
170
|
-
<ContextMenuTrigger v-if="!!slots.default" as-child :disabled="disabled">
|
|
116
|
+
<ContextMenuTrigger v-if="!!slots.default" as-child :disabled="disabled" :class="props.class">
|
|
171
117
|
<slot />
|
|
172
118
|
</ContextMenuTrigger>
|
|
173
119
|
|
|
174
120
|
<UContextMenuContent
|
|
175
|
-
:class="ui.content({ class: [props.class, props.ui?.content] })"
|
|
121
|
+
:class="ui.content({ class: [!slots.default && props.class, props.ui?.content] })"
|
|
176
122
|
:ui="ui"
|
|
177
123
|
:ui-override="props.ui"
|
|
178
124
|
v-bind="contentProps"
|
|
@@ -181,6 +127,7 @@ const ui = computed(() => contextMenu({
|
|
|
181
127
|
:label-key="labelKey"
|
|
182
128
|
:checked-icon="checkedIcon"
|
|
183
129
|
:loading-icon="loadingIcon"
|
|
130
|
+
:external-icon="externalIcon"
|
|
184
131
|
>
|
|
185
132
|
<template v-for="(_, name) in proxySlots" #[name]="slotData: any">
|
|
186
133
|
<slot :name="name" v-bind="slotData" />
|
|
@@ -1,30 +1,31 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import type { ContextMenuContentProps as RadixContextMenuContentProps, ContextMenuContentEmits as RadixContextMenuContentEmits } from 'radix-vue'
|
|
2
|
+
import type { ContextMenuContentProps as RekaContextMenuContentProps, ContextMenuContentEmits as RekaContextMenuContentEmits } from 'reka-ui'
|
|
4
3
|
import theme from '#build/ui/context-menu'
|
|
4
|
+
import { tv } from '../utils/tv'
|
|
5
5
|
import type { KbdProps, AvatarProps, ContextMenuItem, ContextMenuSlots } from '../types'
|
|
6
6
|
|
|
7
7
|
const _contextMenu = tv(theme)()
|
|
8
8
|
|
|
9
|
-
interface ContextMenuContentProps<T> extends Omit<
|
|
9
|
+
interface ContextMenuContentProps<T> extends Omit<RekaContextMenuContentProps, 'as' | 'asChild' | 'forceMount'> {
|
|
10
10
|
items?: T[] | T[][]
|
|
11
11
|
portal?: boolean
|
|
12
12
|
sub?: boolean
|
|
13
13
|
labelKey: string
|
|
14
14
|
checkedIcon?: string
|
|
15
15
|
loadingIcon?: string
|
|
16
|
+
externalIcon?: boolean | string
|
|
16
17
|
class?: any
|
|
17
18
|
ui: typeof _contextMenu
|
|
18
19
|
uiOverride?: any
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
interface ContextMenuContentEmits extends
|
|
22
|
+
interface ContextMenuContentEmits extends RekaContextMenuContentEmits {}
|
|
22
23
|
</script>
|
|
23
24
|
|
|
24
25
|
<script setup lang="ts" generic="T extends ContextMenuItem">
|
|
25
26
|
import { computed } from 'vue'
|
|
26
|
-
import { ContextMenu } from '
|
|
27
|
-
import { useForwardPropsEmits } from '
|
|
27
|
+
import { ContextMenu } from 'reka-ui/namespaced'
|
|
28
|
+
import { useForwardPropsEmits } from 'reka-ui'
|
|
28
29
|
import { reactiveOmit, createReusableTemplate } from '@vueuse/core'
|
|
29
30
|
import { useAppConfig } from '#imports'
|
|
30
31
|
import { omit, get } from '../utils'
|
|
@@ -34,13 +35,15 @@ import ULink from './Link.vue'
|
|
|
34
35
|
import UAvatar from './Avatar.vue'
|
|
35
36
|
import UIcon from './Icon.vue'
|
|
36
37
|
import UKbd from './Kbd.vue'
|
|
38
|
+
// eslint-disable-next-line import/no-self-import
|
|
39
|
+
import UContextMenuContent from './ContextMenuContent.vue'
|
|
37
40
|
|
|
38
41
|
const props = defineProps<ContextMenuContentProps<T>>()
|
|
39
42
|
const emits = defineEmits<ContextMenuContentEmits>()
|
|
40
43
|
const slots = defineSlots<ContextMenuSlots<T>>()
|
|
41
44
|
|
|
42
45
|
const appConfig = useAppConfig()
|
|
43
|
-
const contentProps = useForwardPropsEmits(reactiveOmit(props, 'sub', 'items', 'portal', 'class', 'ui'), emits)
|
|
46
|
+
const contentProps = useForwardPropsEmits(reactiveOmit(props, 'sub', 'items', 'portal', 'labelKey', 'checkedIcon', 'loadingIcon', 'externalIcon', 'class', 'ui', 'uiOverride'), emits)
|
|
44
47
|
const proxySlots = omit(slots, ['default']) as Record<string, ContextMenuSlots<T>[string]>
|
|
45
48
|
|
|
46
49
|
const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate<{ item: ContextMenuItem, active?: boolean, index: number }>()
|
|
@@ -62,7 +65,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
62
65
|
{{ get(item, props.labelKey as string) }}
|
|
63
66
|
</slot>
|
|
64
67
|
|
|
65
|
-
<UIcon v-if="item.target === '_blank'" :name="appConfig.ui.icons.external" :class="ui.itemLabelExternalIcon({ class: uiOverride?.itemLabelExternalIcon, color: item?.color, active })" />
|
|
68
|
+
<UIcon v-if="item.target === '_blank' && externalIcon !== false" :name="typeof externalIcon === 'string' ? externalIcon : appConfig.ui.icons.external" :class="ui.itemLabelExternalIcon({ class: uiOverride?.itemLabelExternalIcon, color: item?.color, active })" />
|
|
66
69
|
</span>
|
|
67
70
|
|
|
68
71
|
<span :class="ui.itemTrailing({ class: uiOverride?.itemTrailing })">
|
|
@@ -110,6 +113,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
110
113
|
:label-key="labelKey"
|
|
111
114
|
:checked-icon="checkedIcon"
|
|
112
115
|
:loading-icon="loadingIcon"
|
|
116
|
+
:external-icon="externalIcon"
|
|
113
117
|
v-bind="item.content"
|
|
114
118
|
>
|
|
115
119
|
<template v-for="(_, name) in proxySlots" #[name]="slotData: any">
|
|
@@ -119,11 +123,11 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
119
123
|
</ContextMenu.Sub>
|
|
120
124
|
<ContextMenu.CheckboxItem
|
|
121
125
|
v-else-if="item.type === 'checkbox'"
|
|
122
|
-
:
|
|
126
|
+
:model-value="item.checked"
|
|
123
127
|
:disabled="item.disabled"
|
|
124
128
|
:text-value="get(item, props.labelKey as string)"
|
|
125
129
|
:class="ui.item({ class: [uiOverride?.item, item.class], color: item?.color })"
|
|
126
|
-
@update:
|
|
130
|
+
@update:model-value="item.onUpdateChecked"
|
|
127
131
|
@select="item.onSelect"
|
|
128
132
|
>
|
|
129
133
|
<ReuseItemTemplate :item="item" :index="index" />
|