Skip to content

Commit 7bd0b52

Browse files
committed
feat: add AInput components (#6)
Closes #6
1 parent 88384a2 commit 7bd0b52

File tree

8 files changed

+104
-8
lines changed

8 files changed

+104
-8
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<script setup lang="ts">
2+
import { AInputPasswordToggle, AInputWithClear }
3+
from '#components'
4+
import * as z from 'zod'
5+
6+
const schema = z.object({
7+
with_clear: z.string()
8+
.default('Press to clear!')
9+
.meta({
10+
input: {
11+
component: AInputWithClear,
12+
},
13+
}),
14+
password: z.string().meta({
15+
input: {
16+
component: AInputPasswordToggle,
17+
},
18+
}),
19+
})
20+
</script>
21+
22+
<template>
23+
<AutoForm :schema="schema" />
24+
</template>

docs/content/2.customization/4.submit_button.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@ export default defineAppConfig({
2121

2222
## Custom component
2323

24-
If it is not sufficient and you want to create completly custom component for submit button you can do that as well.
24+
If it is not sufficient, and you want to create completely custom component for submit button you can do that as well.
2525

2626
::caution
2727
If you use string to define the component it **must** be [globally registered](https://nuxt.com/docs/4.x/guide/directory-structure/app/components#dynamic-components) to work.
2828
To do this, name your component with the `.global.vue` suffix, or place it in `components/global/` directory.
2929
::
3030

31+
::tip
32+
To learn more about importing and registering components, visit the [components](/customization/config#components) sections of config docs.
33+
::
34+
3135
```ts [app.config.ts]{3-5}
3236
export default defineAppConfig({
3337
autoForm: {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
title: <AInput */>
3+
description: UInput components with custom features
4+
---
5+
6+
Nuxt Auto Form aims to make form creation as effortless as possible.
7+
To achieve this, we provide a set of reusable input components that come with enhanced functionality out of the box.
8+
9+
::tip
10+
To read more about customizing `UInput` field visit the [Input customization](/customization/fields#input-customization) docs.
11+
::
12+
13+
## Components
14+
15+
| Prop | Source | Notes |
16+
|----------------------------|------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
17+
| `<AInputPasswordToggle />` | [PasswordToggle.vue](https://github.com/Norbiros/nuxt-auto-form/blob/master/src/runtime/components/input/PasswordToggle.vue) | Adds a toggle to show/hide passwords. Based on Nuxt UI's [example](https://ui.nuxt.com/components/input#with-password-toggle) code |
18+
| `<AInputWithClear />` | [WithClear.vue](https://github.com/Norbiros/nuxt-auto-form/blob/master/src/runtime/components/input/PasswordToggle.vue) | Adds a clear button to easily reset input values. Based on Nuxt UI's [example](https://ui.nuxt.com/components/input#with-clear-button) code |
19+
20+
## Example
21+
22+
::component-preview{name="AInput"}

playground/app/components/MyForm.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
2+
import { AInputPasswordToggle } from '#components'
23
import * as z from 'zod'
3-
import InputWithClear from '~/components/InputWithClear.vue'
44
55
const ENUM_MULTIPLE = [
66
'A',
@@ -34,7 +34,7 @@ const schema = z.object({
3434
description: 'with description',
3535
hint: 'with hint',
3636
input: {
37-
component: InputWithClear,
37+
component: AInputPasswordToggle,
3838
},
3939
}),
4040
custom_bool: z.boolean()
@@ -48,6 +48,7 @@ const schema = z.object({
4848
multiple_input: z
4949
.array(z.enum(ENUM_MULTIPLE))
5050
.meta({ title: 'Multiple Enum Input' }),
51+
password: z.string().nonempty().meta({ input: { component: APasswordToggle } }),
5152
})
5253
5354
function onSubmit(data: Record<string, any>) {

src/module.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { addComponent, addTypeTemplate, createResolver, defineNuxtModule } from '@nuxt/kit'
1+
import { addComponent, addComponentsDir, addTypeTemplate, createResolver, defineNuxtModule } from '@nuxt/kit'
22
import { ensureDependencies } from './utils/packages'
33

44
// Module options TypeScript interface definition
@@ -29,8 +29,13 @@ export default defineNuxtModule<ModuleOptions>({
2929
})
3030

3131
addComponent({
32-
name: 'AutoForm', // name of the component to be used in vue templates
32+
name: 'AutoForm',
3333
filePath: resolver.resolve('runtime/components/AutoForm.vue'),
3434
})
35+
addComponentsDir({
36+
path: resolver.resolve('runtime/components/input/'),
37+
prefix: 'AInput',
38+
pathPrefix: false,
39+
})
3540
},
3641
})

src/runtime/components/AutoForm.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ const submitButtonProps = computed(() => {
123123
:is="field.component"
124124
v-bind="field.props"
125125
v-model="(state as Record<string, any>)[field.key]"
126-
/>
126+
>
127+
<slot :name="`${field.key}-content`" />
128+
</component>
127129
</slot>
128130
</UFormField>
129131

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<script setup lang="ts">
2+
import UButton from '@nuxt/ui/components/Button.vue'
3+
import UInput from '@nuxt/ui/components/Input.vue'
4+
import { ref } from 'vue'
5+
6+
const show = ref(false)
7+
const input = defineModel<string>({ default: '' })
8+
</script>
9+
10+
<template>
11+
<UInput
12+
v-model="input"
13+
:type="show ? 'text' : 'password'"
14+
:ui="{ trailing: 'pe-1' }"
15+
>
16+
<template #trailing>
17+
<UButton
18+
color="neutral"
19+
variant="link"
20+
size="sm"
21+
:icon="show ? 'i-lucide-eye-off' : 'i-lucide-eye'"
22+
:aria-label="show ? 'Hide password' : 'Show password'"
23+
:aria-pressed="show"
24+
aria-controls="password"
25+
@click="show = !show"
26+
/>
27+
</template>
28+
</UInput>
29+
</template>
30+
31+
<style>
32+
/* Hide the password reveal button in Edge */
33+
::-ms-reveal {
34+
display: none;
35+
}
36+
</style>

playground/app/components/InputWithClear.vue renamed to src/runtime/components/input/WithClear.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<script setup lang="ts">
2-
const modelValue = defineModel<string>({ default: 'Click to clear' })
2+
import UButton from '@nuxt/ui/components/Button.vue'
3+
import UInput from '@nuxt/ui/components/Input.vue'
4+
5+
const modelValue = defineModel<string>({ default: '' })
36
</script>
47

58
<template>
69
<UInput
710
v-model="modelValue"
8-
placeholder="Type something..."
911
:ui="{ trailing: 'pe-1' }"
1012
>
1113
<template v-if="modelValue?.length" #trailing>

0 commit comments

Comments
 (0)