@falcondev-oss/nuxt-layers-base 0.22.0 → 0.23.0
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/pages/index.vue +153 -154
- package/.playground/app.vue +0 -10
- package/.playground/nuxt.config.ts +10 -0
- package/app/components/u/UField.vue +9 -13
- package/package.json +8 -8
|
@@ -9,7 +9,7 @@ const form = useForm({
|
|
|
9
9
|
schema: z.object({
|
|
10
10
|
duration: z.number().meta({ title: 'Duration' }),
|
|
11
11
|
dateIso: z.string().meta({ title: 'Datum' }),
|
|
12
|
-
text: z.string().max(10).meta({ title: 'Text' })
|
|
12
|
+
text: z.string().max(10).meta({ title: 'Text' }),
|
|
13
13
|
}),
|
|
14
14
|
sourceValues: () => ({
|
|
15
15
|
dateIso: null,
|
|
@@ -69,86 +69,85 @@ const columns = useTableColumns<typeof data>(
|
|
|
69
69
|
</script>
|
|
70
70
|
|
|
71
71
|
<template>
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
],
|
|
136
|
-
},
|
|
137
|
-
],
|
|
138
|
-
userMenu: {
|
|
139
|
-
name: 'Benjamin Canac',
|
|
140
|
-
avatarSrc: 'https://github.com/benjamincanac.png',
|
|
72
|
+
<LayoutSidebar
|
|
73
|
+
:items="[
|
|
74
|
+
{
|
|
75
|
+
label: 'Home',
|
|
76
|
+
icon: 'i-lucide-house',
|
|
77
|
+
active: true,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
label: 'Inbox',
|
|
81
|
+
icon: 'i-lucide-inbox',
|
|
82
|
+
badge: '4',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
label: 'Contacts',
|
|
86
|
+
icon: 'i-lucide-users',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
label: 'Settings',
|
|
90
|
+
icon: 'i-lucide-settings',
|
|
91
|
+
defaultOpen: true,
|
|
92
|
+
children: [
|
|
93
|
+
{
|
|
94
|
+
label: 'General',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
label: 'Members',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
label: 'Notifications',
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
]"
|
|
105
|
+
:bottom-items="[
|
|
106
|
+
{
|
|
107
|
+
label: 'Home',
|
|
108
|
+
icon: 'i-lucide-house',
|
|
109
|
+
active: true,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
label: 'Inbox',
|
|
113
|
+
icon: 'i-lucide-inbox',
|
|
114
|
+
badge: '4',
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
label: 'Contacts',
|
|
118
|
+
icon: 'i-lucide-users',
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
label: 'Settings',
|
|
122
|
+
icon: 'i-lucide-settings',
|
|
123
|
+
defaultOpen: true,
|
|
124
|
+
children: [
|
|
125
|
+
{
|
|
126
|
+
label: 'General',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
label: 'Members',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
label: 'Notifications',
|
|
133
|
+
},
|
|
134
|
+
],
|
|
141
135
|
},
|
|
136
|
+
]"
|
|
137
|
+
:user-menu="{
|
|
138
|
+
name: 'Benjamin Canac',
|
|
139
|
+
avatarSrc: 'https://github.com/benjamincanac.png',
|
|
142
140
|
}"
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
>
|
|
142
|
+
<LayoutNavbar
|
|
143
|
+
:navbar="{
|
|
145
144
|
title: 'Dashboard',
|
|
146
145
|
ui: {
|
|
147
146
|
root: 'relative',
|
|
148
147
|
title: 'flex-1 absolute inset-0 w-full',
|
|
149
148
|
},
|
|
150
|
-
}
|
|
151
|
-
toolbar
|
|
149
|
+
}"
|
|
150
|
+
:toolbar="{
|
|
152
151
|
items: [
|
|
153
152
|
{
|
|
154
153
|
label: 'General',
|
|
@@ -179,90 +178,90 @@ const columns = useTableColumns<typeof data>(
|
|
|
179
178
|
icon: 'i-lucide-bell',
|
|
180
179
|
},
|
|
181
180
|
],
|
|
182
|
-
},
|
|
183
|
-
}"
|
|
184
|
-
>
|
|
185
|
-
<template #navbar-title>
|
|
186
|
-
<div class="w-full text-center">title</div>
|
|
187
|
-
</template>
|
|
188
|
-
|
|
189
|
-
<UTableCard>
|
|
190
|
-
<UTable :data :columns @select="() => {}" />
|
|
191
|
-
</UTableCard>
|
|
192
|
-
<UCard
|
|
193
|
-
:ui="{
|
|
194
|
-
body: 'flex flex-col gap-4 items-start',
|
|
195
|
-
}"
|
|
196
|
-
>
|
|
197
|
-
<UButton
|
|
198
|
-
label="Confirm"
|
|
199
|
-
variant="subtle"
|
|
200
|
-
@click="
|
|
201
|
-
() => {
|
|
202
|
-
confirm.confirmDestructive({
|
|
203
|
-
title: 'Are you sure?',
|
|
204
|
-
description: 'This action cannot be undone.',
|
|
205
|
-
submitLabel: 'Yes, delete it',
|
|
206
|
-
})
|
|
207
|
-
}
|
|
208
|
-
"
|
|
209
|
-
/>
|
|
210
|
-
<UButton
|
|
211
|
-
label="Actions"
|
|
212
|
-
variant="subtle"
|
|
213
|
-
@click="
|
|
214
|
-
() => {
|
|
215
|
-
overlay.create(LazyOverlayModalActions, {
|
|
216
|
-
defaultOpen: true,
|
|
217
|
-
props: {
|
|
218
|
-
title: 'Actions',
|
|
219
|
-
description: 'Choose an action to perform',
|
|
220
|
-
actions: [
|
|
221
|
-
{
|
|
222
|
-
label: 'Action 1',
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
label: 'Action 2',
|
|
226
|
-
},
|
|
227
|
-
],
|
|
228
|
-
},
|
|
229
|
-
})
|
|
230
|
-
}
|
|
231
|
-
"
|
|
232
|
-
/>
|
|
233
|
-
</UCard>
|
|
234
|
-
<UCard
|
|
235
|
-
class="max-w-sm"
|
|
236
|
-
:ui="{
|
|
237
|
-
body: 'flex flex-col gap-4 items-start ',
|
|
238
181
|
}"
|
|
239
182
|
>
|
|
240
|
-
<
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
183
|
+
<template #navbar-title>
|
|
184
|
+
<div class="w-full text-center">title</div>
|
|
185
|
+
</template>
|
|
186
|
+
|
|
187
|
+
<UTableCard>
|
|
188
|
+
<UTable :data :columns @select="() => {}" />
|
|
189
|
+
</UTableCard>
|
|
190
|
+
<UCard
|
|
191
|
+
:ui="{
|
|
192
|
+
body: 'flex flex-col gap-4 items-start',
|
|
245
193
|
}"
|
|
246
|
-
class="flex flex-col gap-4"
|
|
247
194
|
>
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
195
|
+
<UButton
|
|
196
|
+
label="Confirm"
|
|
197
|
+
variant="subtle"
|
|
198
|
+
@click="
|
|
199
|
+
() => {
|
|
200
|
+
confirm.confirmDestructive({
|
|
201
|
+
title: 'Are you sure?',
|
|
202
|
+
description: 'This action cannot be undone.',
|
|
203
|
+
submitLabel: 'Yes, delete it',
|
|
204
|
+
})
|
|
205
|
+
}
|
|
258
206
|
"
|
|
207
|
+
/>
|
|
208
|
+
<UButton
|
|
209
|
+
label="Actions"
|
|
210
|
+
variant="subtle"
|
|
211
|
+
@click="
|
|
212
|
+
() => {
|
|
213
|
+
overlay.create(LazyOverlayModalActions, {
|
|
214
|
+
defaultOpen: true,
|
|
215
|
+
props: {
|
|
216
|
+
title: 'Actions',
|
|
217
|
+
description: 'Choose an action to perform',
|
|
218
|
+
actions: [
|
|
219
|
+
{
|
|
220
|
+
label: 'Action 1',
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
label: 'Action 2',
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
},
|
|
227
|
+
})
|
|
228
|
+
}
|
|
229
|
+
"
|
|
230
|
+
/>
|
|
231
|
+
</UCard>
|
|
232
|
+
<UCard
|
|
233
|
+
class="max-w-sm"
|
|
234
|
+
:ui="{
|
|
235
|
+
body: 'flex flex-col gap-4 items-start ',
|
|
236
|
+
}"
|
|
237
|
+
>
|
|
238
|
+
<UForm
|
|
239
|
+
:form
|
|
240
|
+
:success-toast="{
|
|
241
|
+
title: 'test',
|
|
242
|
+
description: 'wow',
|
|
243
|
+
}"
|
|
244
|
+
class="flex flex-col gap-4"
|
|
259
245
|
>
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
246
|
+
{{ form.data }}
|
|
247
|
+
<UField v-slot="{ props }" :field="form.fields.text.$use()">
|
|
248
|
+
<UInput class="w-full" v-bind="props" />
|
|
249
|
+
</UField>
|
|
250
|
+
<UField
|
|
251
|
+
v-slot="{ props }"
|
|
252
|
+
:field="
|
|
253
|
+
form.fields.dateIso.$use({
|
|
254
|
+
translate: dateValueIsoTranslator(),
|
|
255
|
+
})
|
|
256
|
+
"
|
|
257
|
+
>
|
|
258
|
+
<UInputDatePicker class="w-full" v-bind="props" />
|
|
259
|
+
</UField>
|
|
260
|
+
<UField v-slot="{ props }" :field="form.fields.duration.$use()">
|
|
261
|
+
<UInputDurationMinutes class="w-full" v-bind="props" />
|
|
262
|
+
</UField>
|
|
263
|
+
</UForm>
|
|
264
|
+
</UCard>
|
|
265
|
+
</LayoutNavbar>
|
|
266
|
+
</LayoutSidebar>
|
|
268
267
|
</template>
|
package/.playground/app.vue
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { de } from '@nuxt/ui/locale'
|
|
3
3
|
import { Settings } from 'luxon'
|
|
4
|
-
import { authRedirect } from './middleware/auth.global'
|
|
5
|
-
import { channel } from './utils/channel'
|
|
6
4
|
|
|
7
5
|
Settings.throwOnInvalid = true
|
|
8
6
|
Settings.defaultLocale = 'de'
|
|
9
|
-
|
|
10
|
-
// redirect when auth status changes through broadcast channel
|
|
11
|
-
const route = useRoute()
|
|
12
|
-
useEventListener<MessageEvent>(channel, 'message', (event) => {
|
|
13
|
-
if (event.data.type === 'auth') {
|
|
14
|
-
authRedirect(route)
|
|
15
|
-
}
|
|
16
|
-
})
|
|
17
7
|
</script>
|
|
18
8
|
|
|
19
9
|
<template>
|
|
@@ -6,5 +6,15 @@ export default defineNuxtConfig({
|
|
|
6
6
|
projectId: 'my-project',
|
|
7
7
|
},
|
|
8
8
|
},
|
|
9
|
+
typescript: {
|
|
10
|
+
tsConfig: {
|
|
11
|
+
vueCompilerOptions: {
|
|
12
|
+
strictTemplates: true,
|
|
13
|
+
strictVModel: false,
|
|
14
|
+
htmlAttributes: ['aria-*'],
|
|
15
|
+
dataAttributes: ['data-*'],
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
9
19
|
css: ['~/assets/test.css'],
|
|
10
20
|
})
|
|
@@ -1,31 +1,27 @@
|
|
|
1
|
-
<script setup lang="ts" generic="T">
|
|
1
|
+
<script setup lang="ts" generic="T, const Nullable extends boolean = false">
|
|
2
2
|
import type { FormField } from '@falcondev-oss/form-core'
|
|
3
3
|
import type { FormFieldProps, FormFieldSlots } from '@nuxt/ui'
|
|
4
|
-
import type { ModelModifiers } from '@nuxt/ui/runtime/types/input.js'
|
|
5
4
|
import { useForwardProps } from 'reka-ui'
|
|
6
5
|
import * as R from 'remeda'
|
|
7
6
|
|
|
8
|
-
type
|
|
7
|
+
type InputSlotProps<T, Nullable extends boolean> = {
|
|
9
8
|
'modelValue': T
|
|
10
9
|
'onUpdate:modelValue': (value: T) => void
|
|
11
10
|
'onBlur': () => void
|
|
12
11
|
'disabled': boolean
|
|
13
12
|
'loading': boolean
|
|
14
|
-
'modelModifiers'
|
|
13
|
+
'modelModifiers': true extends Nullable ? { nullable: true } : never
|
|
15
14
|
'placeholder'?: string
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
const props = defineProps<
|
|
19
18
|
FormFieldProps & {
|
|
20
19
|
field: FormField<T>
|
|
21
|
-
}
|
|
20
|
+
} & { nullable?: Nullable }
|
|
22
21
|
>()
|
|
23
22
|
const slots = defineSlots<
|
|
24
23
|
{
|
|
25
|
-
default: (slot: {
|
|
26
|
-
props: Omit<FieldSlotProps<T>, 'modelModifiers'>
|
|
27
|
-
field: FormField<T>
|
|
28
|
-
}) => any
|
|
24
|
+
default: (slot: { props: InputSlotProps<T, Nullable>; field: FormField<T> }) => any
|
|
29
25
|
} & Omit<FormFieldSlots, 'default'>
|
|
30
26
|
>()
|
|
31
27
|
|
|
@@ -67,11 +63,11 @@ const inputProps = computed(() => {
|
|
|
67
63
|
'onBlur': () => field.handleBlur(),
|
|
68
64
|
'disabled': field.disabled,
|
|
69
65
|
'loading': field.isPending,
|
|
70
|
-
'modelModifiers':
|
|
71
|
-
nullable: true
|
|
72
|
-
|
|
66
|
+
'modelModifiers': (props.nullable === true
|
|
67
|
+
? { nullable: true }
|
|
68
|
+
: undefined) as true extends Nullable ? { nullable: true } : never,
|
|
73
69
|
placeholder,
|
|
74
|
-
} satisfies
|
|
70
|
+
} satisfies InputSlotProps<T, Nullable>
|
|
75
71
|
})
|
|
76
72
|
</script>
|
|
77
73
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@falcondev-oss/nuxt-layers-base",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.23.0",
|
|
5
5
|
"description": "Nuxt layer with lots of useful helpers and @nuxt/ui components",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": "github:falcondev-oss/nuxt-layers",
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
"pnpm": "10"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@falcondev-oss/form-core": "^0.21.
|
|
18
|
-
"@falcondev-oss/form-vue": "^0.21.
|
|
17
|
+
"@falcondev-oss/form-core": "^0.21.1",
|
|
18
|
+
"@falcondev-oss/form-vue": "^0.21.1",
|
|
19
19
|
"@falcondev-oss/trpc-typed-form-data": "^0.4.1",
|
|
20
20
|
"@falcondev-oss/trpc-vue-query": "^0.5.2",
|
|
21
|
-
"@iconify-json/lucide": "^1.2.
|
|
21
|
+
"@iconify-json/lucide": "^1.2.94",
|
|
22
22
|
"@internationalized/date": "^3.11.0",
|
|
23
23
|
"@nuxt/icon": "^2.2.1",
|
|
24
24
|
"@nuxt/ui": "4.4.0",
|
|
@@ -34,19 +34,19 @@
|
|
|
34
34
|
"consola": "^3.4.2",
|
|
35
35
|
"defu": "^6.1.4",
|
|
36
36
|
"maska": "^3.2.0",
|
|
37
|
-
"reka-ui": "^2.8.
|
|
37
|
+
"reka-ui": "^2.8.2",
|
|
38
38
|
"remeda": "^2.33.6",
|
|
39
39
|
"superjson": "^2.2.6",
|
|
40
|
-
"tailwindcss": "^4.1
|
|
40
|
+
"tailwindcss": "^4.2.1",
|
|
41
41
|
"trpc-nuxt": "^2.0.1",
|
|
42
42
|
"type-fest": "^5.4.4",
|
|
43
|
-
"vue": "^3.5.
|
|
43
|
+
"vue": "^3.5.29",
|
|
44
44
|
"vue-router": "^4.6.4"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"nuxt": "^4.3.1",
|
|
48
48
|
"typescript": "^5.9.3",
|
|
49
|
-
"vue-tsc": "^3.2.
|
|
49
|
+
"vue-tsc": "^3.2.5",
|
|
50
50
|
"zod": "^4.3.6"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|