@falcondev-oss/nuxt-layers-base 0.34.0 → 0.35.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/.playground/app/components/FormCard.tsx +81 -92
- package/.playground/app/components/Select.tsx +4 -3
- package/app/components/layout/LayoutSidebar.vue +3 -2
- package/app/components/u/UField.vue +3 -2
- package/app/utils/define-setup-component.ts +3 -2
- package/app/utils/ui.ts +13 -0
- package/package.json +30 -27
|
@@ -1,100 +1,89 @@
|
|
|
1
|
-
import type { VNode } from 'vue'
|
|
2
|
-
import { UCard, UDropdownMenu, UField, UForm, UInput } from '#components'
|
|
3
|
-
import {
|
|
4
|
-
import { z } from 'zod'
|
|
5
|
-
|
|
6
|
-
// https://github.com/vuejs/language-tools/blob/master/packages/component-type-helpers/index.ts
|
|
7
|
-
type ComponentSlots<T> = T extends new (...args: any) => { $slots: infer S }
|
|
8
|
-
? NonNullable<S>
|
|
9
|
-
: T extends (props: any, ctx: { slots: infer S; attrs: any; emit: any }, ...args: any) => any
|
|
10
|
-
? NonNullable<S>
|
|
11
|
-
: {}
|
|
12
|
-
|
|
13
|
-
type ComponentProps<T> = T extends new (...args: any) => { $props: infer P }
|
|
14
|
-
? NonNullable<P>
|
|
15
|
-
: T extends (props: infer P, ...args: any) => any
|
|
16
|
-
? P
|
|
17
|
-
: {}
|
|
1
|
+
// import type { VNode } from 'vue'
|
|
2
|
+
// import { UCard, UDropdownMenu, UField, UForm, UInput } from '#components'
|
|
3
|
+
// import { z } from 'zod'
|
|
18
4
|
|
|
19
5
|
/* eslint-disable ts/no-empty-object-type */
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
6
|
+
// @ts-expect-error FIXME: empty emits causes type error
|
|
7
|
+
export default defineSetupComponent((_: { props: { name: string }; emits: {}; slots: {} }) => ({
|
|
8
|
+
props: props(_, ['name']),
|
|
9
|
+
emits: emits(_, []),
|
|
10
|
+
setup: (props) => {
|
|
11
|
+
console.log(props)
|
|
12
|
+
// const form = useForm({
|
|
13
|
+
// schema: z.object({
|
|
14
|
+
// duration: z.number().meta({ title: 'Duration' }),
|
|
15
|
+
// dateIso: z.string().meta({ title: 'Datum' }),
|
|
16
|
+
// text: z
|
|
17
|
+
// .string()
|
|
18
|
+
// .length(8)
|
|
19
|
+
// // .max(8)
|
|
20
|
+
// .meta({
|
|
21
|
+
// title: 'Text',
|
|
22
|
+
// description: 'Beschreibung',
|
|
23
|
+
// default: 'Default Wert',
|
|
24
|
+
// examples: ['Hier könnte ein Beispieltext stehen', '123'],
|
|
25
|
+
// }),
|
|
26
|
+
// }),
|
|
27
|
+
// sourceValues: () => ({
|
|
28
|
+
// dateIso: null,
|
|
29
|
+
// duration: null,
|
|
30
|
+
// text: '',
|
|
31
|
+
// }),
|
|
32
|
+
// async submit({ values }) {
|
|
33
|
+
// await new Promise((resolve) => setTimeout(resolve, 2000))
|
|
34
|
+
// console.log(values)
|
|
35
|
+
// },
|
|
36
|
+
// })
|
|
49
37
|
|
|
50
38
|
return () => (
|
|
51
|
-
<UCard
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
>
|
|
57
|
-
|
|
58
|
-
|
|
39
|
+
// <UCard
|
|
40
|
+
// class="max-w-sm"
|
|
41
|
+
// ui={{
|
|
42
|
+
// body: 'flex flex-col gap-4 items-start ',
|
|
43
|
+
// }}
|
|
44
|
+
// >
|
|
45
|
+
// <UForm form={form} successToast={{ title: 'Success' }} class="flex flex-col gap-4">
|
|
46
|
+
// {form.data}
|
|
59
47
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
</UCard>
|
|
48
|
+
// {/* <UField
|
|
49
|
+
// field={form.fields.text.$use()}
|
|
50
|
+
// error-inline
|
|
51
|
+
// vSlots={vSlots(UField, {
|
|
52
|
+
// default({ bind }) {
|
|
53
|
+
// return <UInput class="w-full" {...bind} />
|
|
54
|
+
// },
|
|
55
|
+
// })}
|
|
56
|
+
// ></UField> */}
|
|
57
|
+
// </UForm>
|
|
58
|
+
// {/* <UForm
|
|
59
|
+
// :form
|
|
60
|
+
// :success-toast="{
|
|
61
|
+
// title: 'test',
|
|
62
|
+
// description: 'wow',
|
|
63
|
+
// }"
|
|
64
|
+
// class="flex flex-col gap-4"
|
|
65
|
+
// >
|
|
66
|
+
// {{ form.data }}
|
|
67
|
+
// <UField v-slot="{ bind, field }" :field="form.fields.text.$use()" error-inline>
|
|
68
|
+
// {{ field.schema }}
|
|
69
|
+
// <UInput class="w-full" v-bind="bind" />
|
|
70
|
+
// </UField>
|
|
71
|
+
// <UField
|
|
72
|
+
// v-slot="{ bind }"
|
|
73
|
+
// :field="
|
|
74
|
+
// form.fields.dateIso.$use({
|
|
75
|
+
// translate: dateValueIsoTranslator(),
|
|
76
|
+
// })
|
|
77
|
+
// "
|
|
78
|
+
// >
|
|
79
|
+
// <UInputDatePicker class="w-full" v-bind="bind" />
|
|
80
|
+
// </UField>
|
|
81
|
+
// <UField v-slot="{ bind }" :field="form.fields.duration.$use()">
|
|
82
|
+
// <UInputDurationMinutes class="w-full" v-bind="bind" />
|
|
83
|
+
// </UField>
|
|
84
|
+
// </UForm> */}
|
|
85
|
+
// </UCard>
|
|
86
|
+
<></>
|
|
98
87
|
)
|
|
99
88
|
},
|
|
100
89
|
}))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { UButton, UCard } from '#components'
|
|
2
|
+
import { setup } from '../../../app/utils/define-setup-component'
|
|
2
3
|
|
|
3
4
|
export type ListItems = { label: string; value: string }[]
|
|
4
5
|
|
|
@@ -18,14 +19,14 @@ export default defineSetupComponent(
|
|
|
18
19
|
// props: ['items'],
|
|
19
20
|
emits: emits(_, ['choose']),
|
|
20
21
|
// emits: ['choose'],
|
|
21
|
-
setup:
|
|
22
|
+
setup: setup(_, (props, { emit, slots }) => {
|
|
22
23
|
const selected = ref<T[number]>()
|
|
23
24
|
|
|
24
25
|
return () => (
|
|
25
26
|
<UCard
|
|
26
27
|
class="w-fit"
|
|
27
28
|
vSlots={vSlots(UCard, {
|
|
28
|
-
header: () => <h1>Select an item</h1
|
|
29
|
+
header: () => [<h1>Select an item</h1>],
|
|
29
30
|
})}
|
|
30
31
|
>
|
|
31
32
|
<div class="flex flex-col gap-2">
|
|
@@ -39,7 +40,7 @@ export default defineSetupComponent(
|
|
|
39
40
|
emit('choose', item)
|
|
40
41
|
}}
|
|
41
42
|
vSlots={vSlots(UButton, {
|
|
42
|
-
leading: () => `[${selected.value?.value === item.value ? 'x' : ' '}]
|
|
43
|
+
leading: () => [<>{`[${selected.value?.value === item.value ? 'x' : ' '}] `}</>],
|
|
43
44
|
})}
|
|
44
45
|
>
|
|
45
46
|
{item.label}
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
NavigationMenuItem,
|
|
8
8
|
NavigationMenuProps,
|
|
9
9
|
} from '@nuxt/ui'
|
|
10
|
+
import { mergeSlotClass } from '../../utils/ui'
|
|
10
11
|
|
|
11
12
|
defineProps<{
|
|
12
13
|
sidebar?: DashboardSidebarProps
|
|
@@ -43,8 +44,8 @@ const config = useRuntimeConfig()
|
|
|
43
44
|
collapsible
|
|
44
45
|
:ui="{
|
|
45
46
|
...sidebar?.ui,
|
|
46
|
-
header:
|
|
47
|
-
footer:
|
|
47
|
+
header: mergeSlotClass(sidebar?.ui?.header, 'border-b border-default'),
|
|
48
|
+
footer: mergeSlotClass(sidebar?.ui?.footer, 'border-t border-default'),
|
|
48
49
|
}"
|
|
49
50
|
>
|
|
50
51
|
<template
|
|
@@ -4,6 +4,7 @@ import type { FormFieldProps, FormFieldSlots } from '@nuxt/ui'
|
|
|
4
4
|
import { createReusableTemplate } from '@vueuse/core'
|
|
5
5
|
import { useForwardProps } from 'reka-ui'
|
|
6
6
|
import * as R from 'remeda'
|
|
7
|
+
import { mergeSlotClass } from '../../utils/ui'
|
|
7
8
|
|
|
8
9
|
type InputProps<T> = {
|
|
9
10
|
'modelValue': T
|
|
@@ -99,8 +100,8 @@ const [DefineErrorTemplate, ErrorTemplate] = createReusableTemplate({
|
|
|
99
100
|
v-bind="formFieldProps"
|
|
100
101
|
:ui="{
|
|
101
102
|
...formFieldProps.ui,
|
|
102
|
-
hint:
|
|
103
|
-
error:
|
|
103
|
+
hint: mergeSlotClass(formFieldProps.ui?.hint, isOverMaxLength ? 'text-error' : ''),
|
|
104
|
+
error: mergeSlotClass(formFieldProps.ui?.error, 'mt-1!'),
|
|
104
105
|
}"
|
|
105
106
|
:error="!!field.errors"
|
|
106
107
|
:class="props.class"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable ts/no-empty-object-type */
|
|
2
|
-
import type { AllUnionFields,
|
|
2
|
+
import type { AllUnionFields, UnionToTuple } from 'type-fest'
|
|
3
3
|
import type {
|
|
4
4
|
ComponentOptionsMixin,
|
|
5
5
|
CreateComponentPublicInstanceWithMixins,
|
|
@@ -84,7 +84,7 @@ export function emits<
|
|
|
84
84
|
return emits
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
export function
|
|
87
|
+
export function setup<
|
|
88
88
|
const Opts extends {
|
|
89
89
|
props: Record<string, any>
|
|
90
90
|
emits: ObjectEmitsOptions
|
|
@@ -96,6 +96,7 @@ export function generic<
|
|
|
96
96
|
props: Props,
|
|
97
97
|
ctx: SetupContext<Opts['emits'], Slots>,
|
|
98
98
|
) => RenderFunction | Promise<RenderFunction>,
|
|
99
|
+
// eslint-disable-next-line no-shadow
|
|
99
100
|
>(_opts: Opts, setup: Setup): NoInfer<Setup> {
|
|
100
101
|
return setup
|
|
101
102
|
}
|
package/app/utils/ui.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SlotClass, SlotClassReplacer } from '@nuxt/ui'
|
|
2
|
+
import type { ClassValue } from 'tailwind-variants'
|
|
3
|
+
import { cnMerge } from 'tailwind-variants'
|
|
4
|
+
|
|
5
|
+
export function mergeSlotClass(ui: SlotClass, extend: ClassValue): SlotClassReplacer {
|
|
6
|
+
return (defaults) => {
|
|
7
|
+
const withBase = cnMerge(defaults, extend)() ?? ''
|
|
8
|
+
if (typeof ui === 'function') {
|
|
9
|
+
return ui(withBase)
|
|
10
|
+
}
|
|
11
|
+
return cnMerge(withBase, ui)() ?? ''
|
|
12
|
+
}
|
|
13
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@falcondev-oss/nuxt-layers-base",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.35.2",
|
|
5
5
|
"description": "Nuxt layer with lots of useful helpers and @nuxt/ui components",
|
|
6
6
|
"license": "MIT",
|
|
7
|
-
"repository":
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "github:falcondev-oss/nuxt-layers"
|
|
10
|
+
},
|
|
8
11
|
"bugs": {
|
|
9
12
|
"url": "https://github.com/falcondev-oss/nuxt-layers/issues"
|
|
10
13
|
},
|
|
@@ -14,46 +17,46 @@
|
|
|
14
17
|
"pnpm": "11"
|
|
15
18
|
},
|
|
16
19
|
"peerDependencies": {
|
|
17
|
-
"@falcondev-oss/form-core": ">=0.
|
|
18
|
-
"@falcondev-oss/form-vue": ">=0.
|
|
19
|
-
"@internationalized/date": ">=3.12.
|
|
20
|
-
"@nuxt/ui": ">=4.
|
|
20
|
+
"@falcondev-oss/form-core": ">=0.23.5",
|
|
21
|
+
"@falcondev-oss/form-vue": ">=0.23.5",
|
|
22
|
+
"@internationalized/date": ">=3.12.1",
|
|
23
|
+
"@nuxt/ui": ">=4.9.0",
|
|
24
|
+
"tailwind-variants": ">=3.2.2"
|
|
21
25
|
},
|
|
22
26
|
"dependencies": {
|
|
23
27
|
"@falcondev-oss/trpc-typed-form-data": "^0.4.3",
|
|
24
28
|
"@falcondev-oss/trpc-vue-query": "^0.5.4",
|
|
25
|
-
"@iconify-json/lucide": "^1.2.
|
|
26
|
-
"@nuxt/icon": "^2.2.
|
|
27
|
-
"@nuxtjs/color-mode": "^4.0.
|
|
28
|
-
"@tanstack/vue-query": "^5.
|
|
29
|
-
"@trpc/client": "^11.
|
|
30
|
-
"@trpc/server": "^11.
|
|
31
|
-
"@vue/devtools-api": "^8.1.
|
|
32
|
-
"@vueuse/core": "^14.
|
|
33
|
-
"@vueuse/nuxt": "^14.
|
|
34
|
-
"@vueuse/router": "^14.
|
|
29
|
+
"@iconify-json/lucide": "^1.2.114",
|
|
30
|
+
"@nuxt/icon": "^2.2.3",
|
|
31
|
+
"@nuxtjs/color-mode": "^4.0.1",
|
|
32
|
+
"@tanstack/vue-query": "^5.101.0",
|
|
33
|
+
"@trpc/client": "^11.18.0",
|
|
34
|
+
"@trpc/server": "^11.18.0",
|
|
35
|
+
"@vue/devtools-api": "^8.1.3",
|
|
36
|
+
"@vueuse/core": "^14.3.0",
|
|
37
|
+
"@vueuse/nuxt": "^14.3.0",
|
|
38
|
+
"@vueuse/router": "^14.3.0",
|
|
35
39
|
"arkregex": "^0.0.5",
|
|
36
40
|
"consola": "^3.4.2",
|
|
37
41
|
"defu": "^6.1.7",
|
|
38
42
|
"maska": "^3.2.0",
|
|
39
|
-
"reka-ui": "
|
|
40
|
-
"remeda": "^2.
|
|
43
|
+
"reka-ui": "~2.9.10",
|
|
44
|
+
"remeda": "^2.39.0",
|
|
41
45
|
"superjson": "^2.2.6",
|
|
42
|
-
"tailwindcss": "^4.
|
|
43
|
-
"trpc-nuxt": "^2.
|
|
44
|
-
"type-fest": "^5.
|
|
45
|
-
"vue": "^3.5.
|
|
46
|
-
"vue-router": "^5.0
|
|
46
|
+
"tailwindcss": "^4.3.1",
|
|
47
|
+
"trpc-nuxt": "^2.1.1",
|
|
48
|
+
"type-fest": "^5.7.0",
|
|
49
|
+
"vue": "^3.5.38",
|
|
50
|
+
"vue-router": "^5.1.0"
|
|
47
51
|
},
|
|
48
52
|
"devDependencies": {
|
|
49
|
-
"nuxt": "^4.4.
|
|
53
|
+
"nuxt": "^4.4.8",
|
|
50
54
|
"typescript": "^5.9.3",
|
|
51
|
-
"vue-tsc": "^3.
|
|
52
|
-
"zod": "^4.3
|
|
55
|
+
"vue-tsc": "^3.3.5",
|
|
56
|
+
"zod": "^4.4.3"
|
|
53
57
|
},
|
|
54
58
|
"scripts": {
|
|
55
59
|
"dev": "nuxi dev .playground",
|
|
56
|
-
"dev:prepare": "nuxt prepare .playground",
|
|
57
60
|
"type-check": "vue-tsc --build",
|
|
58
61
|
"lint": "pnpm -w eslint:cmd \"$PWD\" && pnpm -w prettier:cmd \"$PWD\" --check",
|
|
59
62
|
"lint:fix": "pnpm -w eslint:cmd \"$PWD\" --fix && pnpm -w prettier:cmd \"$PWD\" --write"
|