@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,17 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { tv } from 'tailwind-variants'
|
|
3
2
|
import type { DrawerRootProps, DrawerRootEmits } from 'vaul-vue'
|
|
4
|
-
import type { DialogContentProps } from '
|
|
3
|
+
import type { DialogContentProps } from 'reka-ui'
|
|
5
4
|
import type { AppConfig } from '@nuxt/schema'
|
|
6
5
|
import _appConfig from '#build/app.config'
|
|
7
6
|
import theme from '#build/ui/drawer'
|
|
8
|
-
import {
|
|
7
|
+
import { tv } from '../utils/tv'
|
|
9
8
|
|
|
10
|
-
const
|
|
9
|
+
const appConfigDrawer = _appConfig as AppConfig & { ui: { drawer: Partial<typeof theme> } }
|
|
11
10
|
|
|
12
|
-
const drawer = tv({ extend: tv(theme), ...(
|
|
11
|
+
const drawer = tv({ extend: tv(theme), ...(appConfigDrawer.ui?.drawer || {}) })
|
|
13
12
|
|
|
14
|
-
export interface DrawerProps extends Pick<DrawerRootProps, 'activeSnapPoint' | 'closeThreshold' | 'defaultOpen' | 'direction' | '
|
|
13
|
+
export interface DrawerProps extends Pick<DrawerRootProps, 'activeSnapPoint' | 'closeThreshold' | 'defaultOpen' | 'direction' | 'fadeFromIndex' | 'fixed' | 'modal' | 'nested' | 'direction' | 'open' | 'scrollLockTimeout' | 'shouldScaleBackground' | 'snapPoints'> {
|
|
15
14
|
/**
|
|
16
15
|
* The element or component this component should render as.
|
|
17
16
|
* @defaultValue 'div'
|
|
@@ -19,6 +18,11 @@ export interface DrawerProps extends Pick<DrawerRootProps, 'activeSnapPoint' | '
|
|
|
19
18
|
as?: any
|
|
20
19
|
title?: string
|
|
21
20
|
description?: string
|
|
21
|
+
/**
|
|
22
|
+
* Whether to inset the drawer from the edges.
|
|
23
|
+
* @defaultValue false
|
|
24
|
+
*/
|
|
25
|
+
inset?: boolean
|
|
22
26
|
/** The content of the drawer. */
|
|
23
27
|
content?: Omit<DialogContentProps, 'as' | 'asChild' | 'forceMount'>
|
|
24
28
|
/**
|
|
@@ -36,6 +40,11 @@ export interface DrawerProps extends Pick<DrawerRootProps, 'activeSnapPoint' | '
|
|
|
36
40
|
* @defaultValue true
|
|
37
41
|
*/
|
|
38
42
|
portal?: boolean
|
|
43
|
+
/**
|
|
44
|
+
* When `false`, the drawer will not close when clicking outside or pressing escape.
|
|
45
|
+
* @defaultValue true
|
|
46
|
+
*/
|
|
47
|
+
dismissible?: boolean
|
|
39
48
|
class?: any
|
|
40
49
|
ui?: Partial<typeof drawer.slots>
|
|
41
50
|
}
|
|
@@ -52,13 +61,11 @@ export interface DrawerSlots {
|
|
|
52
61
|
body(props?: {}): any
|
|
53
62
|
footer(props?: {}): any
|
|
54
63
|
}
|
|
55
|
-
|
|
56
|
-
extendDevtoolsMeta({ example: 'DrawerExample' })
|
|
57
64
|
</script>
|
|
58
65
|
|
|
59
66
|
<script setup lang="ts">
|
|
60
67
|
import { computed, toRef } from 'vue'
|
|
61
|
-
import { useForwardPropsEmits } from '
|
|
68
|
+
import { useForwardPropsEmits } from 'reka-ui'
|
|
62
69
|
import { DrawerRoot, DrawerTrigger, DrawerPortal, DrawerOverlay, DrawerContent, DrawerTitle, DrawerDescription } from 'vaul-vue'
|
|
63
70
|
import { reactivePick } from '@vueuse/core'
|
|
64
71
|
|
|
@@ -73,22 +80,26 @@ const slots = defineSlots<DrawerSlots>()
|
|
|
73
80
|
|
|
74
81
|
const rootProps = useForwardPropsEmits(reactivePick(props, 'activeSnapPoint', 'closeThreshold', 'defaultOpen', 'dismissible', 'fadeFromIndex', 'fixed', 'modal', 'nested', 'direction', 'open', 'scrollLockTimeout', 'shouldScaleBackground', 'snapPoints'), emits)
|
|
75
82
|
const contentProps = toRef(() => props.content)
|
|
83
|
+
const contentEvents = {
|
|
84
|
+
closeAutoFocus: (e: Event) => e.preventDefault()
|
|
85
|
+
}
|
|
76
86
|
|
|
77
87
|
const ui = computed(() => drawer({
|
|
78
|
-
direction: props.direction
|
|
88
|
+
direction: props.direction,
|
|
89
|
+
inset: props.inset
|
|
79
90
|
}))
|
|
80
91
|
</script>
|
|
81
92
|
|
|
82
93
|
<template>
|
|
83
94
|
<DrawerRoot v-bind="rootProps">
|
|
84
|
-
<DrawerTrigger v-if="!!slots.default" as-child>
|
|
95
|
+
<DrawerTrigger v-if="!!slots.default" as-child :class="props.class">
|
|
85
96
|
<slot />
|
|
86
97
|
</DrawerTrigger>
|
|
87
98
|
|
|
88
99
|
<DrawerPortal :disabled="!portal">
|
|
89
100
|
<DrawerOverlay v-if="overlay" :class="ui.overlay({ class: props.ui?.overlay })" />
|
|
90
101
|
|
|
91
|
-
<DrawerContent :class="ui.content({ class: [props.class, props.ui?.content] })" v-bind="contentProps">
|
|
102
|
+
<DrawerContent :class="ui.content({ class: [!slots.default && props.class, props.ui?.content] })" v-bind="contentProps" v-on="contentEvents">
|
|
92
103
|
<slot name="handle">
|
|
93
104
|
<div v-if="handle" :class="ui.handle({ class: props.ui?.handle })" />
|
|
94
105
|
</slot>
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import type { DropdownMenuRootProps, DropdownMenuRootEmits, DropdownMenuContentProps, DropdownMenuArrowProps } from '
|
|
2
|
+
import type { VariantProps } from 'tailwind-variants'
|
|
3
|
+
import type { DropdownMenuRootProps, DropdownMenuRootEmits, DropdownMenuContentProps, DropdownMenuArrowProps } 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/dropdown-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 appConfigDropdownMenu = _appConfig as AppConfig & { ui: { dropdownMenu: Partial<typeof theme> } }
|
|
12
12
|
|
|
13
|
-
const dropdownMenu = tv({ extend: tv(theme), ...(
|
|
13
|
+
const dropdownMenu = tv({ extend: tv(theme), ...(appConfigDropdownMenu.ui?.dropdownMenu || {}) })
|
|
14
14
|
|
|
15
15
|
type DropdownMenuVariants = VariantProps<typeof dropdownMenu>
|
|
16
16
|
|
|
@@ -50,9 +50,15 @@ export interface DropdownMenuProps<T> extends Omit<DropdownMenuRootProps, '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
|
/**
|
|
54
60
|
* The content of the menu.
|
|
55
|
-
* @defaultValue { side: 'bottom', sideOffset: 8 }
|
|
61
|
+
* @defaultValue { side: 'bottom', sideOffset: 8, collisionPadding: 8 }
|
|
56
62
|
*/
|
|
57
63
|
content?: Omit<DropdownMenuContentProps, 'as' | 'asChild' | 'forceMount'>
|
|
58
64
|
/**
|
|
@@ -86,61 +92,12 @@ export type DropdownMenuSlots<T extends { slot?: string }> = {
|
|
|
86
92
|
'item-label': SlotProps<T>
|
|
87
93
|
'item-trailing': SlotProps<T>
|
|
88
94
|
} & DynamicSlots<T, SlotProps<T>>
|
|
89
|
-
|
|
90
|
-
extendDevtoolsMeta({
|
|
91
|
-
example: 'DropdownMenuExample',
|
|
92
|
-
ignoreProps: ['items'],
|
|
93
|
-
defaultProps: {
|
|
94
|
-
items: [
|
|
95
|
-
[{
|
|
96
|
-
label: 'My account',
|
|
97
|
-
avatar: {
|
|
98
|
-
src: 'https://avatars.githubusercontent.com/u/739984?v=4'
|
|
99
|
-
},
|
|
100
|
-
type: 'label'
|
|
101
|
-
}], [{
|
|
102
|
-
label: 'Profile',
|
|
103
|
-
icon: 'i-lucide-user',
|
|
104
|
-
slot: 'custom'
|
|
105
|
-
}, {
|
|
106
|
-
label: 'Billing',
|
|
107
|
-
icon: 'i-lucide-credit-card',
|
|
108
|
-
kbds: ['meta', 'b']
|
|
109
|
-
}, {
|
|
110
|
-
label: 'Settings',
|
|
111
|
-
icon: 'i-lucide-cog',
|
|
112
|
-
kbds: ['?']
|
|
113
|
-
}], [{
|
|
114
|
-
label: 'Invite users',
|
|
115
|
-
icon: 'i-lucide-user-plus',
|
|
116
|
-
children: [[{
|
|
117
|
-
label: 'Invite by email',
|
|
118
|
-
icon: 'i-lucide-send-horizontal'
|
|
119
|
-
}, {
|
|
120
|
-
label: 'Invite by link',
|
|
121
|
-
icon: 'i-lucide-link',
|
|
122
|
-
kbds: ['meta', 'i']
|
|
123
|
-
}]]
|
|
124
|
-
}],
|
|
125
|
-
[{
|
|
126
|
-
label: 'GitHub',
|
|
127
|
-
icon: 'i-simple-icons-github',
|
|
128
|
-
to: 'https://github.com/nuxt/ui',
|
|
129
|
-
target: '_blank'
|
|
130
|
-
}, {
|
|
131
|
-
label: 'Support',
|
|
132
|
-
icon: 'i-lucide-life-buoy',
|
|
133
|
-
to: '/components/dropdown-menu'
|
|
134
|
-
}]
|
|
135
|
-
]
|
|
136
|
-
}
|
|
137
|
-
})
|
|
138
95
|
</script>
|
|
139
96
|
|
|
140
97
|
<script setup lang="ts" generic="T extends DropdownMenuItem">
|
|
141
98
|
import { computed, toRef } from 'vue'
|
|
142
99
|
import { defu } from 'defu'
|
|
143
|
-
import { DropdownMenuRoot, DropdownMenuTrigger, DropdownMenuArrow, useForwardPropsEmits } from '
|
|
100
|
+
import { DropdownMenuRoot, DropdownMenuTrigger, DropdownMenuArrow, useForwardPropsEmits } from 'reka-ui'
|
|
144
101
|
import { reactivePick } from '@vueuse/core'
|
|
145
102
|
import { omit } from '../utils'
|
|
146
103
|
import UDropdownMenuContent from './DropdownMenuContent.vue'
|
|
@@ -148,13 +105,14 @@ import UDropdownMenuContent from './DropdownMenuContent.vue'
|
|
|
148
105
|
const props = withDefaults(defineProps<DropdownMenuProps<T>>(), {
|
|
149
106
|
portal: true,
|
|
150
107
|
modal: true,
|
|
108
|
+
externalIcon: true,
|
|
151
109
|
labelKey: 'label'
|
|
152
110
|
})
|
|
153
111
|
const emits = defineEmits<DropdownMenuEmits>()
|
|
154
112
|
const slots = defineSlots<DropdownMenuSlots<T>>()
|
|
155
113
|
|
|
156
114
|
const rootProps = useForwardPropsEmits(reactivePick(props, 'defaultOpen', 'open', 'modal'), emits)
|
|
157
|
-
const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8 }) as DropdownMenuContentProps)
|
|
115
|
+
const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8, collisionPadding: 8 }) as DropdownMenuContentProps)
|
|
158
116
|
const arrowProps = toRef(() => props.arrow as DropdownMenuArrowProps)
|
|
159
117
|
const proxySlots = omit(slots, ['default']) as Record<string, DropdownMenuSlots<T>[string]>
|
|
160
118
|
|
|
@@ -165,12 +123,12 @@ const ui = computed(() => dropdownMenu({
|
|
|
165
123
|
|
|
166
124
|
<template>
|
|
167
125
|
<DropdownMenuRoot v-slot="{ open }" v-bind="rootProps">
|
|
168
|
-
<DropdownMenuTrigger v-if="!!slots.default" as-child :disabled="disabled">
|
|
126
|
+
<DropdownMenuTrigger v-if="!!slots.default" as-child :class="props.class" :disabled="disabled">
|
|
169
127
|
<slot :open="open" />
|
|
170
128
|
</DropdownMenuTrigger>
|
|
171
129
|
|
|
172
130
|
<UDropdownMenuContent
|
|
173
|
-
:class="ui.content({ class: [props.class, props.ui?.content] })"
|
|
131
|
+
:class="ui.content({ class: [!slots.default && props.class, props.ui?.content] })"
|
|
174
132
|
:ui="ui"
|
|
175
133
|
:ui-override="props.ui"
|
|
176
134
|
v-bind="contentProps"
|
|
@@ -179,6 +137,7 @@ const ui = computed(() => dropdownMenu({
|
|
|
179
137
|
:label-key="labelKey"
|
|
180
138
|
:checked-icon="checkedIcon"
|
|
181
139
|
:loading-icon="loadingIcon"
|
|
140
|
+
:external-icon="externalIcon"
|
|
182
141
|
>
|
|
183
142
|
<template v-for="(_, name) in proxySlots" #[name]="slotData: any">
|
|
184
143
|
<slot :name="name" v-bind="slotData" />
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
<!-- eslint-disable vue/block-tag-newline -->
|
|
2
2
|
<script lang="ts">
|
|
3
|
-
import {
|
|
4
|
-
import type { DropdownMenuContentProps as RadixDropdownMenuContentProps, DropdownMenuContentEmits as RadixDropdownMenuContentEmits } from 'radix-vue'
|
|
3
|
+
import type { DropdownMenuContentProps as RekaDropdownMenuContentProps, DropdownMenuContentEmits as RekaDropdownMenuContentEmits } from 'reka-ui'
|
|
5
4
|
import theme from '#build/ui/dropdown-menu'
|
|
5
|
+
import { tv } from '../utils/tv'
|
|
6
6
|
import type { KbdProps, AvatarProps, DropdownMenuItem, DropdownMenuSlots } from '../types'
|
|
7
7
|
|
|
8
8
|
const _dropdownMenu = tv(theme)()
|
|
9
9
|
|
|
10
|
-
interface DropdownMenuContentProps<T> extends Omit<
|
|
10
|
+
interface DropdownMenuContentProps<T> extends Omit<RekaDropdownMenuContentProps, 'as' | 'asChild' | 'forceMount'> {
|
|
11
11
|
items?: T[] | T[][]
|
|
12
12
|
portal?: boolean
|
|
13
13
|
sub?: boolean
|
|
14
14
|
labelKey: string
|
|
15
15
|
checkedIcon?: string
|
|
16
16
|
loadingIcon?: string
|
|
17
|
+
externalIcon?: boolean | string
|
|
17
18
|
class?: any
|
|
18
19
|
ui: typeof _dropdownMenu
|
|
19
20
|
uiOverride?: any
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
interface DropdownMenuContentEmits extends
|
|
23
|
+
interface DropdownMenuContentEmits extends RekaDropdownMenuContentEmits {}
|
|
23
24
|
|
|
24
25
|
type DropdownMenuContentSlots<T extends { slot?: string }> = Omit<DropdownMenuSlots<T>, 'default'> & {
|
|
25
26
|
default(props?: {}): any
|
|
@@ -29,8 +30,8 @@ type DropdownMenuContentSlots<T extends { slot?: string }> = Omit<DropdownMenuSl
|
|
|
29
30
|
|
|
30
31
|
<script setup lang="ts" generic="T extends DropdownMenuItem">
|
|
31
32
|
import { computed } from 'vue'
|
|
32
|
-
import { DropdownMenu } from '
|
|
33
|
-
import { useForwardPropsEmits } from '
|
|
33
|
+
import { DropdownMenu } from 'reka-ui/namespaced'
|
|
34
|
+
import { useForwardPropsEmits } from 'reka-ui'
|
|
34
35
|
import { reactiveOmit, createReusableTemplate } from '@vueuse/core'
|
|
35
36
|
import { useAppConfig } from '#imports'
|
|
36
37
|
import { omit, get } from '../utils'
|
|
@@ -40,13 +41,15 @@ import ULink from './Link.vue'
|
|
|
40
41
|
import UAvatar from './Avatar.vue'
|
|
41
42
|
import UIcon from './Icon.vue'
|
|
42
43
|
import UKbd from './Kbd.vue'
|
|
44
|
+
// eslint-disable-next-line import/no-self-import
|
|
45
|
+
import UDropdownMenuContent from './DropdownMenuContent.vue'
|
|
43
46
|
|
|
44
47
|
const props = defineProps<DropdownMenuContentProps<T>>()
|
|
45
48
|
const emits = defineEmits<DropdownMenuContentEmits>()
|
|
46
49
|
const slots = defineSlots<DropdownMenuContentSlots<T>>()
|
|
47
50
|
|
|
48
51
|
const appConfig = useAppConfig()
|
|
49
|
-
const contentProps = useForwardPropsEmits(reactiveOmit(props, 'sub', 'items', 'portal', 'class', 'ui'), emits)
|
|
52
|
+
const contentProps = useForwardPropsEmits(reactiveOmit(props, 'sub', 'items', 'portal', 'labelKey', 'checkedIcon', 'loadingIcon', 'externalIcon', 'class', 'ui', 'uiOverride'), emits)
|
|
50
53
|
const proxySlots = omit(slots, ['default']) as Record<string, DropdownMenuContentSlots<T>[string]>
|
|
51
54
|
|
|
52
55
|
const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate<{ item: DropdownMenuItem, active?: boolean, index: number }>()
|
|
@@ -68,7 +71,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
68
71
|
{{ get(item, props.labelKey as string) }}
|
|
69
72
|
</slot>
|
|
70
73
|
|
|
71
|
-
<UIcon v-if="item.target === '_blank'" :name="appConfig.ui.icons.external" :class="ui.itemLabelExternalIcon({ class: uiOverride?.itemLabelExternalIcon, color: item?.color, active })" />
|
|
74
|
+
<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 })" />
|
|
72
75
|
</span>
|
|
73
76
|
|
|
74
77
|
<span :class="ui.itemTrailing({ class: uiOverride?.itemTrailing })">
|
|
@@ -119,6 +122,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
119
122
|
:label-key="labelKey"
|
|
120
123
|
:checked-icon="checkedIcon"
|
|
121
124
|
:loading-icon="loadingIcon"
|
|
125
|
+
:external-icon="externalIcon"
|
|
122
126
|
v-bind="item.content"
|
|
123
127
|
>
|
|
124
128
|
<template v-for="(_, name) in proxySlots" #[name]="slotData: any">
|
|
@@ -128,11 +132,11 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
|
|
128
132
|
</DropdownMenu.Sub>
|
|
129
133
|
<DropdownMenu.CheckboxItem
|
|
130
134
|
v-else-if="item.type === 'checkbox'"
|
|
131
|
-
:
|
|
135
|
+
:model-value="item.checked"
|
|
132
136
|
:disabled="item.disabled"
|
|
133
137
|
:text-value="get(item, props.labelKey as string)"
|
|
134
138
|
:class="ui.item({ class: [uiOverride?.item, item.class], color: item?.color })"
|
|
135
|
-
@update:
|
|
139
|
+
@update:model-value="item.onUpdateChecked"
|
|
136
140
|
@select="item.onSelect"
|
|
137
141
|
>
|
|
138
142
|
<ReuseItemTemplate :item="item" :index="index" />
|
|
@@ -1,14 +1,14 @@
|
|
|
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/form'
|
|
6
|
-
import {
|
|
5
|
+
import { tv } from '../utils/tv'
|
|
7
6
|
import type { FormSchema, FormError, FormInputEvents, FormErrorEvent, FormSubmitEvent, FormEvent, Form, FormErrorWithId } from '../types/form'
|
|
7
|
+
import type { DeepReadonly } from 'vue'
|
|
8
8
|
|
|
9
|
-
const
|
|
9
|
+
const appConfigForm = _appConfig as AppConfig & { ui: { form: Partial<typeof theme> } }
|
|
10
10
|
|
|
11
|
-
const form = tv({ extend: tv(theme), ...(
|
|
11
|
+
const form = tv({ extend: tv(theme), ...(appConfigForm.ui?.form || {}) })
|
|
12
12
|
|
|
13
13
|
export interface FormProps<T extends object> {
|
|
14
14
|
id?: string | number
|
|
@@ -19,6 +19,7 @@ export interface FormProps<T extends object> {
|
|
|
19
19
|
disabled?: boolean
|
|
20
20
|
validateOnInputDelay?: number
|
|
21
21
|
class?: any
|
|
22
|
+
transform?: boolean
|
|
22
23
|
onSubmit?: ((event: FormSubmitEvent<T>) => void | Promise<void>) | (() => void | Promise<void>)
|
|
23
24
|
}
|
|
24
25
|
|
|
@@ -30,29 +31,29 @@ export interface FormEmits<T extends object> {
|
|
|
30
31
|
export interface FormSlots {
|
|
31
32
|
default(props?: {}): any
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
-
extendDevtoolsMeta({ example: 'FormExample' })
|
|
35
34
|
</script>
|
|
36
35
|
|
|
37
36
|
<script lang="ts" setup generic="T extends object">
|
|
38
37
|
import { provide, inject, nextTick, ref, onUnmounted, onMounted, computed, useId, readonly } from 'vue'
|
|
39
38
|
import { useEventBus } from '@vueuse/core'
|
|
40
39
|
import { formOptionsInjectionKey, formInputsInjectionKey, formBusInjectionKey, formLoadingInjectionKey } from '../composables/useFormField'
|
|
41
|
-
import {
|
|
40
|
+
import { validateSchema } from '../utils/form'
|
|
42
41
|
import { FormValidationException } from '../types/form'
|
|
43
42
|
|
|
44
43
|
const props = withDefaults(defineProps<FormProps<T>>(), {
|
|
45
44
|
validateOn() {
|
|
46
45
|
return ['input', 'blur', 'change'] as FormInputEvents[]
|
|
47
46
|
},
|
|
48
|
-
validateOnInputDelay: 300
|
|
47
|
+
validateOnInputDelay: 300,
|
|
48
|
+
transform: true
|
|
49
49
|
})
|
|
50
|
+
|
|
50
51
|
const emits = defineEmits<FormEmits<T>>()
|
|
51
52
|
defineSlots<FormSlots>()
|
|
52
53
|
|
|
53
54
|
const formId = props.id ?? useId() as string
|
|
54
55
|
|
|
55
|
-
const bus = useEventBus<FormEvent
|
|
56
|
+
const bus = useEventBus<FormEvent<T>>(`form-${formId}`)
|
|
56
57
|
const parentBus = inject(
|
|
57
58
|
formBusInjectionKey,
|
|
58
59
|
undefined
|
|
@@ -60,7 +61,7 @@ const parentBus = inject(
|
|
|
60
61
|
|
|
61
62
|
provide(formBusInjectionKey, bus)
|
|
62
63
|
|
|
63
|
-
const nestedForms = ref<Map<string | number, { validate:
|
|
64
|
+
const nestedForms = ref<Map<string | number, { validate: typeof _validate }>>(new Map())
|
|
64
65
|
|
|
65
66
|
onMounted(async () => {
|
|
66
67
|
bus.on(async (event) => {
|
|
@@ -68,8 +69,24 @@ onMounted(async () => {
|
|
|
68
69
|
nestedForms.value.set(event.formId, { validate: event.validate })
|
|
69
70
|
} else if (event.type === 'detach') {
|
|
70
71
|
nestedForms.value.delete(event.formId)
|
|
71
|
-
} else if (props.validateOn?.includes(event.type
|
|
72
|
-
|
|
72
|
+
} else if (props.validateOn?.includes(event.type)) {
|
|
73
|
+
if (event.type !== 'input') {
|
|
74
|
+
await _validate({ name: event.name, silent: true, nested: false })
|
|
75
|
+
} else if (event.eager || blurredFields.has(event.name)) {
|
|
76
|
+
await _validate({ name: event.name, silent: true, nested: false })
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (event.type === 'blur') {
|
|
81
|
+
blurredFields.add(event.name)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (event.type === 'change' || event.type === 'input' || event.type === 'blur' || event.type === 'focus') {
|
|
85
|
+
touchedFields.add(event.name)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (event.type === 'change' || event.type === 'input') {
|
|
89
|
+
dirtyFields.add(event.name)
|
|
73
90
|
}
|
|
74
91
|
})
|
|
75
92
|
})
|
|
@@ -94,70 +111,78 @@ onUnmounted(() => {
|
|
|
94
111
|
const errors = ref<FormErrorWithId[]>([])
|
|
95
112
|
provide('form-errors', errors)
|
|
96
113
|
|
|
97
|
-
const inputs = ref<
|
|
98
|
-
provide(formInputsInjectionKey, inputs)
|
|
114
|
+
const inputs = ref<{ [P in keyof T]?: { id?: string, pattern?: RegExp } }>({})
|
|
115
|
+
provide(formInputsInjectionKey, inputs as any)
|
|
116
|
+
|
|
117
|
+
const dirtyFields = new Set<keyof T>()
|
|
118
|
+
const touchedFields = new Set<keyof T>()
|
|
119
|
+
const blurredFields = new Set<keyof T>()
|
|
99
120
|
|
|
100
121
|
function resolveErrorIds(errs: FormError[]): FormErrorWithId[] {
|
|
101
122
|
return errs.map(err => ({
|
|
102
123
|
...err,
|
|
103
|
-
id: inputs.value[err.name]
|
|
124
|
+
id: inputs.value[err.name]?.id
|
|
104
125
|
}))
|
|
105
126
|
}
|
|
106
127
|
|
|
128
|
+
const transformedState = ref<T | null>(null)
|
|
129
|
+
|
|
107
130
|
async function getErrors(): Promise<FormErrorWithId[]> {
|
|
108
131
|
let errs = props.validate ? (await props.validate(props.state)) ?? [] : []
|
|
109
132
|
|
|
110
133
|
if (props.schema) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
errs = errs.concat(await getYupErrors(props.state, props.schema))
|
|
115
|
-
} else if (isJoiSchema(props.schema)) {
|
|
116
|
-
errs = errs.concat(await getJoiErrors(props.state, props.schema))
|
|
117
|
-
} else if (isValibotSchema(props.schema)) {
|
|
118
|
-
errs = errs.concat(await getValibotErrors(props.state, props.schema))
|
|
119
|
-
} else if (isSuperStructSchema(props.schema)) {
|
|
120
|
-
errs = errs.concat(await getSuperStructErrors(props.state, props.schema))
|
|
121
|
-
} else if (isStandardSchema(props.schema)) {
|
|
122
|
-
errs = errs.concat(await getStandardErrors(props.state, props.schema))
|
|
134
|
+
const { errors, result } = await validateSchema(props.state, props.schema as FormSchema<typeof props.state>)
|
|
135
|
+
if (errors) {
|
|
136
|
+
errs = errs.concat(errors)
|
|
123
137
|
} else {
|
|
124
|
-
|
|
138
|
+
transformedState.value = result
|
|
125
139
|
}
|
|
126
140
|
}
|
|
127
141
|
|
|
128
142
|
return resolveErrorIds(errs)
|
|
129
143
|
}
|
|
130
144
|
|
|
131
|
-
async function _validate(opts: { name?:
|
|
132
|
-
const names = opts.name && !Array.isArray(opts.name) ? [opts.name] : opts.name
|
|
145
|
+
async function _validate(opts: { name?: keyof T | (keyof T)[], silent?: boolean, nested?: boolean, transform?: boolean } = { silent: false, nested: true, transform: false }): Promise<T | false> {
|
|
146
|
+
const names = opts.name && !Array.isArray(opts.name) ? [opts.name] : opts.name as (keyof T)[]
|
|
133
147
|
|
|
134
148
|
const nestedValidatePromises = !names && opts.nested
|
|
135
149
|
? Array.from(nestedForms.value.values()).map(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
150
|
+
({ validate }) => validate(opts).then(() => undefined).catch((error: Error) => {
|
|
151
|
+
if (!(error instanceof FormValidationException)) {
|
|
152
|
+
throw error
|
|
153
|
+
}
|
|
154
|
+
return error
|
|
155
|
+
})
|
|
156
|
+
)
|
|
143
157
|
: []
|
|
144
158
|
|
|
145
159
|
if (names) {
|
|
146
|
-
const otherErrors = errors.value.filter(error => !names
|
|
147
|
-
|
|
148
|
-
|
|
160
|
+
const otherErrors = errors.value.filter(error => !names.some((name) => {
|
|
161
|
+
const pattern = inputs.value?.[name]?.pattern
|
|
162
|
+
return name === error.name || (pattern && error.name.match(pattern))
|
|
163
|
+
}))
|
|
164
|
+
|
|
165
|
+
const pathErrors = (await getErrors()).filter(error => names.some((name) => {
|
|
166
|
+
const pattern = inputs.value?.[name]?.pattern
|
|
167
|
+
return name === error.name || (pattern && error.name.match(pattern))
|
|
168
|
+
}))
|
|
169
|
+
|
|
149
170
|
errors.value = otherErrors.concat(pathErrors)
|
|
150
171
|
} else {
|
|
151
172
|
errors.value = await getErrors()
|
|
152
173
|
}
|
|
153
174
|
|
|
154
|
-
const childErrors = (await Promise.all(nestedValidatePromises)).filter(val => val)
|
|
175
|
+
const childErrors = (await Promise.all(nestedValidatePromises)).filter(val => val !== undefined)
|
|
155
176
|
|
|
156
177
|
if (errors.value.length + childErrors.length > 0) {
|
|
157
178
|
if (opts.silent) return false
|
|
158
179
|
throw new FormValidationException(formId, errors.value, childErrors)
|
|
159
180
|
}
|
|
160
181
|
|
|
182
|
+
if (opts.transform) {
|
|
183
|
+
Object.assign(props.state, transformedState.value)
|
|
184
|
+
}
|
|
185
|
+
|
|
161
186
|
return props.state as T
|
|
162
187
|
}
|
|
163
188
|
|
|
@@ -170,8 +195,7 @@ async function onSubmitWrapper(payload: Event) {
|
|
|
170
195
|
const event = payload as FormSubmitEvent<any>
|
|
171
196
|
|
|
172
197
|
try {
|
|
173
|
-
await _validate({ nested: true })
|
|
174
|
-
event.data = props.state
|
|
198
|
+
event.data = await _validate({ nested: true, transform: props.transform })
|
|
175
199
|
await props.onSubmit?.(event)
|
|
176
200
|
} catch (error) {
|
|
177
201
|
if (!(error instanceof FormValidationException)) {
|
|
@@ -181,12 +205,12 @@ async function onSubmitWrapper(payload: Event) {
|
|
|
181
205
|
const errorEvent: FormErrorEvent = {
|
|
182
206
|
...event,
|
|
183
207
|
errors: error.errors,
|
|
184
|
-
|
|
208
|
+
children: error.children
|
|
185
209
|
}
|
|
186
210
|
emits('error', errorEvent)
|
|
211
|
+
} finally {
|
|
212
|
+
loading.value = false
|
|
187
213
|
}
|
|
188
|
-
|
|
189
|
-
loading.value = false
|
|
190
214
|
}
|
|
191
215
|
|
|
192
216
|
const disabled = computed(() => props.disabled || loading.value)
|
|
@@ -200,7 +224,7 @@ defineExpose<Form<T>>({
|
|
|
200
224
|
validate: _validate,
|
|
201
225
|
errors,
|
|
202
226
|
|
|
203
|
-
setErrors(errs: FormError[], name?:
|
|
227
|
+
setErrors(errs: FormError[], name?: keyof T) {
|
|
204
228
|
if (name) {
|
|
205
229
|
errors.value = errors.value
|
|
206
230
|
.filter(error => error.name !== name)
|
|
@@ -214,7 +238,7 @@ defineExpose<Form<T>>({
|
|
|
214
238
|
await onSubmitWrapper(new Event('submit'))
|
|
215
239
|
},
|
|
216
240
|
|
|
217
|
-
getErrors(name?:
|
|
241
|
+
getErrors(name?: keyof T) {
|
|
218
242
|
if (name) {
|
|
219
243
|
return errors.value.filter(err => err.name === name)
|
|
220
244
|
}
|
|
@@ -229,7 +253,12 @@ defineExpose<Form<T>>({
|
|
|
229
253
|
}
|
|
230
254
|
},
|
|
231
255
|
|
|
232
|
-
disabled
|
|
256
|
+
disabled,
|
|
257
|
+
dirty: computed(() => !!dirtyFields.size),
|
|
258
|
+
|
|
259
|
+
dirtyFields: readonly(dirtyFields) as DeepReadonly<Set<keyof T>>,
|
|
260
|
+
blurredFields: readonly(blurredFields) as DeepReadonly<Set<keyof T>>,
|
|
261
|
+
touchedFields: readonly(touchedFields) as DeepReadonly<Set<keyof T>>
|
|
233
262
|
})
|
|
234
263
|
</script>
|
|
235
264
|
|