Skip to content

Commit 1289ef0

Browse files
committed
feat: allow customizing input component & props
1 parent a6e55a5 commit 1289ef0

File tree

4 files changed

+63
-10
lines changed

4 files changed

+63
-10
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<script setup lang="ts">
2+
const modelValue = defineModel<string>({ default: 'Click to clear' })
3+
</script>
4+
5+
<template>
6+
<UInput
7+
v-model="modelValue"
8+
placeholder="Type something..."
9+
:ui="{ trailing: 'pe-1' }"
10+
>
11+
<template v-if="modelValue?.length" #trailing>
12+
<UButton
13+
color="neutral"
14+
variant="link"
15+
size="sm"
16+
icon="i-lucide-circle-x"
17+
aria-label="Clear input"
18+
@click="modelValue = ''"
19+
/>
20+
</template>
21+
</UInput>
22+
</template>

playground/app/components/MyForm.vue

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import * as z from 'zod'
3+
import InputWithClear from '~/components/InputWithClear.vue'
34
45
const ENUM_MULTIPLE = [
56
'A',
@@ -13,13 +14,26 @@ const ENUM_MULTIPLE = [
1314
const schema = z.object({
1415
text: z.string()
1516
.nonempty()
16-
.meta({ title: 'Text Input', required: true }),
17+
.meta({
18+
title: 'Text Input',
19+
required: true,
20+
input: {
21+
props: {
22+
placeholder: 'Placeholder',
23+
},
24+
},
25+
}),
1726
enum: z.enum(['1', '2', '3'])
18-
.meta({ title: 'Enum Input' }),
27+
.meta({
28+
title: 'Enum Input',
29+
}),
1930
text_description: z.string()
2031
.meta({
2132
description: 'with description',
2233
hint: 'with hint',
34+
input: {
35+
component: InputWithClear,
36+
},
2337
}),
2438
custom_bool: z.boolean()
2539
.meta({ title: 'Input with custom slot' }),

src/runtime/components/AutoForm.vue

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,25 +68,25 @@ const COMPONENTS_MAP: Record<string, (key: string, zodType: any) => ComponentDef
6868
email: () => ({ component: UInput, componentProps: { type: 'email' } }),
6969
}
7070
71-
const fields = Object.entries(shape).map(([key, zodType]) => {
71+
const fields = Object.entries(shape).map(([key, zodType]: [string, any]) => {
7272
const result = mapZodTypeToComponent(key, zodType)
7373
if (!result)
7474
return null
7575
76+
const meta = typeof zodType.meta === 'function' ? zodType.meta() || {} : {}
77+
7678
return {
7779
key,
7880
formField: {
7981
name: key,
80-
...parseMeta(zodType, key),
82+
...parseMeta(meta, key),
8183
},
82-
component: result.component,
83-
props: result.componentProps ?? {},
84+
component: meta?.input?.component ?? result.component,
85+
props: defu(meta?.input?.props, result.componentProps ?? {}),
8486
}
8587
}).filter((field): field is NonNullable<typeof field> => field != null)
8688
87-
function parseMeta(zodType: any, key: string) {
88-
const meta = typeof zodType.meta === 'function' ? zodType.meta() || {} : {}
89-
89+
function parseMeta(meta: any, key: string) {
9090
return {
9191
label: meta.title ?? upperFirst(splitByCase(key).join(' ').toLowerCase()),
9292
required: meta.required,

src/runtime/types/zod.d.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Generated by Nuxt Auto Form
22

3+
import type { Component } from '@vue/runtime-core'
4+
35
declare module 'zod' {
46
/** Global configuration added by `nuxt-auto-form` Nuxt module */
57
interface GlobalMeta {
@@ -9,7 +11,22 @@ declare module 'zod' {
911
floatRight?: boolean
1012
}
1113

12-
input?: object
14+
/**
15+
* Configuration for the inner Input component.
16+
*
17+
* @remarks Added by `nuxt-auto-form`
18+
*/
19+
input?: {
20+
/**
21+
* Vue component or component name used to render the input.
22+
*/
23+
component?: string | Component
24+
/**
25+
* Props forwarded to the input component at render time.
26+
* These are merged with the module's default props - user props take precedence..
27+
*/
28+
props?: Record<string, any>
29+
}
1330

1431
/**
1532
* Field label displayed in the form's label row.

0 commit comments

Comments
 (0)