feat(Form): new component (#4)

Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
Romain Hamel
2024-03-19 16:09:12 +01:00
committed by GitHub
parent 1cec712fb8
commit de62676647
35 changed files with 2735 additions and 69 deletions

View File

@@ -1,19 +1,48 @@
<script setup lang="ts">
import { splitByCase, upperFirst } from 'scule'
useHead({
bodyAttrs: {
class: 'antialiased font-sans text-gray-900 dark:text-white bg-white dark:bg-gray-900'
}
})
const components = ['avatar', 'badge', 'button', 'card', 'chip', 'collapsible', 'kbd', 'modal', 'popover', 'skeleton', 'slideover', 'tabs', 'tooltip']
const components = [
'avatar',
'badge',
'button',
'card',
'chip',
'collapsible',
'form',
'form-field',
'input',
'kbd',
'modal',
'popover',
'skeleton',
'slideover',
'tabs',
'tooltip'
]
function upperName (name: string) {
return splitByCase(name).map(p => upperFirst(p)).join('')
}
</script>
<template>
<UProvider>
<UContainer class="min-h-screen flex flex-col gap-4 items-center justify-center overflow-y-auto">
<div class="flex gap-1.5 py-4 overflow-x-auto w-full">
<ULink v-for="component in components" :key="component" :to="`/${component}`" active-class="text-primary-500 dark:text-primary-400 font-medium" class="capitalize text-sm">
{{ component }}
<div class="flex gap-1.5 py-4">
<ULink
v-for="component in components"
:key="component"
:to="`/${component}`"
active-class="text-primary-500 dark:text-primary-400 font-medium"
class="capitalize text-sm"
>
{{ upperName(component) }}
</ULink>
</div>

View File

@@ -2,6 +2,6 @@
export default defineNuxtConfig({
modules: ['../src/module'],
ui: {
colors: ['primary']
colors: ['primary', 'red']
}
})

View File

@@ -1,3 +1,20 @@
<script setup lang="ts">
import chip from '#build/ui/chip'
const sizes = Object.keys(chip.variants.size)
const positions = Object.keys(chip.variants.position)
const items = [{
name: 'messages',
icon: 'i-heroicons-chat-bubble-oval-left',
count: 3
}, {
name: 'notifications',
icon: 'i-heroicons-bell',
count: 0
}]
</script>
<template>
<div class="flex flex-col gap-4">
<div class="flex items-center gap-2">
@@ -19,20 +36,3 @@
</div>
</div>
</template>
<script setup lang="ts">
import chip from '#build/ui/chip'
const sizes = Object.keys(chip.variants.size)
const positions = Object.keys(chip.variants.position)
const items = [{
name: 'messages',
icon: 'i-heroicons-chat-bubble-oval-left',
count: 3
}, {
name: 'notifications',
icon: 'i-heroicons-bell',
count: 0
}]
</script>

View File

@@ -0,0 +1,35 @@
<script setup lang="ts">
import formField from '#build/ui/formField'
const feedbacks = [
{ description: 'This is a description' },
{ error: 'This is an error' },
{ hint: 'This is a hint' },
{ help: 'Help! I need somebody!' },
{ required: true }
]
</script>
<template>
<div class="flex flex-col items-center gap-4">
<div class="flex flex-col gap-4 -ml-[258px]">
<div v-for="(feedback, count) in feedbacks" :key="count" class="flex items-center">
<UFormField v-bind="feedback" label="Email" name="email">
<UInput placeholder="john@lennon.com" />
</UFormField>
</div>
</div>
<div class="flex items-center gap-4">
<UFormField
v-for="size in Object.keys(formField.variants.size)"
:key="size"
:size="(size as any)"
label="Email"
name="email"
>
<UInput placeholder="john@lennon.com" />
</UFormField>
</div>
</div>
</template>

104
playground/pages/form.vue Normal file
View File

@@ -0,0 +1,104 @@
<script setup lang="ts">
import { z } from 'zod'
import type { Form, FormSubmitEvent } from '#ui/types/form'
type User = {
email: string
password: string
}
const state = ref<User>({ email: '', password: '' })
const state2 = ref<User>({ email: '', password: '' })
const state3 = ref<User>({ email: '', password: '' })
const schema = z.object({
email: z.string().email(),
password: z.string().min(8)
})
const disabledForm = ref<Form<User>>()
function onSubmit (event: FormSubmitEvent<User>) {
console.log(event.data)
}
</script>
<template>
<div class="flex gap-4">
<UForm
:state="state"
:schema="schema"
class="gap-4 flex flex-col w-60"
@submit="(event) => onSubmit(event)"
>
<UFormField label="Email" name="email">
<UInput v-model="state.email" placeholder="john@lennon.com" />
</UFormField>
<UFormField label="Password" name="password">
<UInput v-model="state.password" type="password" />
</UFormField>
<div>
<UButton color="gray" type="submit">
Submit
</UButton>
</div>
</UForm>
<UForm
:state="state2"
:schema="schema"
class="gap-4 flex flex-col w-60"
:validate-on-input-delay="2000"
@submit="(event) => onSubmit(event)"
>
<UFormField label="Email" name="email">
<UInput v-model="state2.email" placeholder="john@lennon.com" />
</UFormField>
<UFormField
label="Password"
name="password"
:validate-on-input-delay="50"
eager-validation
>
<UInput v-model="state2.password" type="password" />
</UFormField>
<div>
<UButton color="gray" type="submit">
Submit
</UButton>
</div>
</UForm>
<UForm
ref="disabledForm"
:state="state3"
:schema="schema"
class="gap-4 flex flex-col w-60"
disabled
@submit="(event) => onSubmit(event)"
>
<UFormField label="Email" name="email">
<UInput v-model="state2.email" placeholder="john@lennon.com" />
</UFormField>
<UFormField
label="Password"
name="password"
:validate-on-input-delay="50"
eager-validation
>
<UInput v-model="state2.password" type="password" />
</UFormField>
<div>
<UButton color="gray" type="submit" :disabled="disabledForm?.disabled">
Submit
</UButton>
</div>
</UForm>
</div>
</template>

View File

@@ -0,0 +1,19 @@
<script setup lang="ts">
import input from '#build/ui/input'
</script>
<template>
<div class="flex flex-col items-center gap-4">
<div class="flex flex-col gap-4 -ml-[258px]">
<UInput placeholder="Write something..." autofocus />
<UInput placeholder="Write something..." />
<UInput placeholder="Write something..." color="gray" />
<UInput placeholder="Write something..." color="primary" />
<UInput placeholder="Write something..." color="red" />
<UInput placeholder="Write something..." disabled />
</div>
<div class="flex items-center gap-4">
<UInput v-for="size in Object.keys(input.variants.size)" :key="size" placeholder="Write something..." :size="(size as any)" />
</div>
</div>
</template>

View File

@@ -1,3 +1,7 @@
<script setup lang="ts">
const open = ref(false)
</script>
<template>
<div class="flex flex-col gap-2">
<UModal title="First modal">
@@ -47,7 +51,3 @@
</UModal>
</div>
</template>
<script setup lang="ts">
const open = ref(false)
</script>

View File

@@ -1,3 +1,17 @@
<script setup lang="ts">
const open = ref(false)
const loading = ref(false)
function send () {
loading.value = true
setTimeout(() => {
loading.value = false
open.value = false
}, 1000)
}
</script>
<template>
<div class="text-center">
<UPopover v-model:open="open" arrow>
@@ -48,17 +62,3 @@
</div>
</div>
</template>
<script setup lang="ts">
const open = ref(false)
const loading = ref(false)
function send () {
loading.value = true
setTimeout(() => {
loading.value = false
open.value = false
}, 1000)
}
</script>

View File

@@ -1,3 +1,7 @@
<script setup lang="ts">
const open = ref(false)
</script>
<template>
<div class="flex flex-col gap-2">
<USlideover title="First slideover">
@@ -103,7 +107,3 @@
</USlideover>
</div>
</template>
<script setup lang="ts">
const open = ref(false)
</script>

View File

@@ -1,11 +1,3 @@
<template>
<UTabs :items="items" class="w-96">
<template #tab1="{ item }">
{{ item.label }}
</template>
</UTabs>
</template>
<script setup lang="ts">
const items = [{
label: 'Tab1',
@@ -19,3 +11,11 @@ const items = [{
content: 'Finally, this is the content for Tab3'
}]
</script>
<template>
<UTabs :items="items" class="w-96">
<template #tab1="{ item }">
{{ item.label }}
</template>
</UTabs>
</template>