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