feat(FormGroup): add slots (#714)

Co-authored-by: Romain Hamel <rom.hml@gmail.com>
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
Co-authored-by: saveliy <savelii.moshkota@ext.jumingo.com>
This commit is contained in:
Levy
2023-09-28 19:30:41 +03:00
committed by GitHub
parent ff9d51863e
commit 2fc938575d
3 changed files with 152 additions and 9 deletions

View File

@@ -0,0 +1,16 @@
<template>
<UFormGroup label="Email" :error="!email && 'You must enter an email'" help="This is a nice email!">
<template #default="{ error }">
<UInput v-model="email" type="email" placeholder="Enter email" :trailing-icon="error ? 'i-heroicons-exclamation-triangle-20-solid' : undefined" />
</template>
<template #error="{ error }">
<UAlert v-if="error" icon="i-heroicons-exclamation-triangle-20-solid" :title="error" color="red" />
<UAlert v-else icon="i-heroicons-check-circle-20-solid" title="Your email is valid" color="green" />
</template>
</UFormGroup>
</template>
<script setup lang="ts">
const email = ref('')
</script>

View File

@@ -190,6 +190,115 @@ code: >-
This will only work with form elements that support the `size` prop.
::
## Slots
### `label`
Use the `#label` slot to set the custom content for label.
::component-card
---
slots:
label: <UAvatar src="https://avatars.githubusercontent.com/u/739984?v=4" size="3xs" />
default: <UInput model-value="benjamincanac" placeholder="you@example.com" />
---
#label
:u-avatar{src="https://avatars.githubusercontent.com/u/739984?v=4" size="3xs" class="mr-2 inline-flex"}
#default
:u-input{model-value="benjamincanac" placeholder="you@example.com"}
::
### `description`
Use the `#description` slot to set the custom content for description.
::component-card
---
slots:
description: Write only valid email address <UIcon name="i-heroicons-arrow-right-20-solid" />
default: <UInput model-value="benjamincanac" placeholder="you@example.com" />
props:
label: 'Email'
---
#description
Write only valid email address :u-icon{name="i-heroicons-information-circle" class="align-middle"}
#default
:u-input{model-value="benjamincanac" placeholder="you@example.com"}
::
### `hint`
Use the `#hint` slot to set the custom content for hint.
::component-card
---
slots:
hint: <UIcon name="i-heroicons-arrow-right-20-solid" />
default: <UInput model-value="benjamincanac" placeholder="you@example.com" />
props:
label: 'Step 1'
---
#hint
:u-icon{name="i-heroicons-arrow-right-20-solid"}
#default
:u-input{model-value="benjamincanac" placeholder="you@example.com"}
::
### `help`
Use the `#help` slot to set the custom content for help.
::component-card
---
slots:
help: Here are some examples <UIcon name="i-heroicons-arrow-right-20-solid" />
default: <UInput model-value="benjamincanac" placeholder="you@example.com" />
props:
label: 'Email'
---
#help
Here are some examples :u-icon{name="i-heroicons-information-circle" class="align-middle"}
#default
:u-input{model-value="benjamincanac" placeholder="you@example.com"}
::
### `error`
Use the `#error` slot to set the custom content for error.
::component-example
#default
:form-group-error-slot-example{class="w-60"}
#code
```vue
<template>
<UFormGroup label="Email" :error="!email && 'You must enter an email'" help="This is a nice email!">
<template #default="{ error }">
<UInput v-model="email" type="email" placeholder="Enter email" :trailing-icon="error ? 'i-heroicons-exclamation-triangle-20-solid' : undefined" />
</template>
<template #error="{ error }">
<UAlert v-if="error" icon="i-heroicons-exclamation-triangle-20-solid" :title="error" color="red" />
<UAlert v-else icon="i-heroicons-check-circle-20-solid" title="Your email is valid" color="green" />
</template>
</UFormGroup>
</template>
<script setup lang="ts">
const email = ref('')
</script>
```
::
## Props
:component-props

View File

@@ -1,19 +1,37 @@
<template>
<div :class="ui.wrapper" v-bind="attrs">
<div v-if="label" :class="[ui.label.wrapper, size]">
<label :for="inputId" :class="[ui.label.base, required ? ui.label.required : '']">{{ label }}</label>
<span v-if="hint" :class="[ui.hint]">{{ hint }}</span>
<div v-if="label || $slots.label" :class="[ui.label.wrapper, size]">
<label :for="inputId" :class="[ui.label.base, required ? ui.label.required : '']">
<slot v-if="$slots.label" name="label" v-bind="{ error, label, name, hint, description, help }" />
<template v-else>{{ label }}</template>
</label>
<span v-if="hint || $slots.hint" :class="[ui.hint]">
<slot v-if="$slots.hint" name="hint" v-bind="{ error, label, name, hint, description, help }" />
<template v-else>{{ hint }}</template>
</span>
</div>
<p v-if="description" :class="[ui.description, size]">
{{ description }}
<p v-if="description || $slots.description" :class="[ui.description, size]">
<slot v-if="$slots.description" name="description" v-bind="{ error, label, name, hint, description, help }" />
<template v-else>
{{ description }}
</template>
</p>
<div :class="[label ? ui.container : '']">
<slot v-bind="{ error }" />
<p v-if="typeof error === 'string' && error" :class="[ui.error, size]">
{{ error }}
<p v-if="(typeof error === 'string' && error) || $slots.error" :class="[ui.error, size]">
<slot v-if="$slots.error" name="error" v-bind="{ error, label, name, hint, description, help }" />
<template v-else>
{{ error }}
</template>
</p>
<p v-else-if="help" :class="[ui.help, size]">
{{ help }}
<p v-else-if="help || $slots.help" :class="[ui.help, size]">
<slot v-if="$slots.help" name="help" v-bind="{ error, label, name, hint, description, help }" />
<template v-else>
{{ help }}
</template>
</p>
</div>
</div>