TagsDraft
View RTL<script setup lang="ts">
type TagsExampleData = {
vowels: string[]
consonant: string[]
}
const alphabet = Array.from({ length: 26 }, (_, i) =>
String.fromCharCode(65 + i),
)
const vowels: TagsExampleData['vowels'] = ['A', 'E', 'I', 'O', 'U']
const consonant: TagsExampleData['consonant'] = alphabet.filter(
(char) => !vowels.includes(char),
)
const isEditing = ref<boolean>(false)
const inlineEdit = ref<boolean>(false)
const expand = ref<boolean>(true)
const selectedTags = ref<string[]>([])
</script>
<template>
<div class="n-stack">
<div class="n-stack n-stack-horizontal">
<provet-toggle
label="Edit mode"
:checked="isEditing"
@change="isEditing = !isEditing"
/>
<provet-toggle label="Inline-edit" @change="inlineEdit = !inlineEdit" />
<provet-toggle label="Expand" checked @change="expand = !expand" />
</div>
<EditableField :is-editing>
<BaseTags
v-model:is-editing="isEditing"
v-model:selected-tags="selectedTags"
:categories="[
{ label: 'Vowels', tags: vowels },
{ label: 'Consonants', tags: consonant },
]"
/>
<template #edit>
<ComboboxMultiple
v-model="selectedTags"
label="Alphabet"
hide-label
:inline-edit
:expand
:options="
alphabet.map((letter) => ({ label: letter, value: letter }))
"
/>
</template>
</EditableField>
</div>
</template>
<script setup lang="ts">
type TagsExampleData = {
vowels: string[]
consonant: string[]
}
const alphabet = Array.from({ length: 26 }, (_, i) =>
String.fromCharCode(65 + i),
)
const fetchAlphabet = async (query: string) => {
await new Promise((resolve) =>
setTimeout(resolve, Math.floor(Math.random() * 500) + 500),
)
if (query) {
return alphabet
.filter((type) => type.toLowerCase().includes(query.toLowerCase()))
.map((letter) => ({
label: letter,
value: letter,
}))
}
return alphabet.map((letter) => ({
label: letter,
value: letter,
}))
}
const vowels: TagsExampleData['vowels'] = ['A', 'E', 'I', 'O', 'U']
const consonant: TagsExampleData['consonant'] = alphabet.filter(
(char) => !vowels.includes(char),
)
const isEditing = ref<boolean>(false)
const inlineEdit = ref<boolean>(false)
const expand = ref<boolean>(true)
const selectedTags = ref<string[]>([])
</script>
<template>
<div class="n-stack">
<div class="n-stack n-stack-horizontal">
<provet-toggle
label="Edit mode"
:checked="isEditing"
@change="isEditing = !isEditing"
/>
<provet-toggle label="Inline-edit" @change="inlineEdit = !inlineEdit" />
<provet-toggle label="Expand" checked @change="expand = !expand" />
</div>
<EditableField :is-editing>
<BaseTags
v-model:is-editing="isEditing"
v-model:selected-tags="selectedTags"
:categories="[
{ label: 'Vowels', tags: vowels },
{ label: 'Consonants', tags: consonant },
]"
/>
<template #edit>
<ComboboxMultiple
v-model="selectedTags"
async
label="Alphabet"
hide-label
:min-chars="0"
:delay="0"
:max-displayed-options="10"
resolve-on-load
resolve-on-open
infinite-scroll
:inline-edit
:expand
:options="fetchAlphabet"
/>
</template>
</EditableField>
</div>
</template>
<script setup lang="ts">
const alphabet = Array.from({ length: 26 }, (_, i) =>
String.fromCharCode(65 + i),
)
const billingTags = ['C', 'W', 'K', 'S']
const inlineEdit = ref<boolean>(false)
const fetchAlphabet = async (query: string) => {
await new Promise((resolve) =>
setTimeout(resolve, Math.floor(Math.random() * 500) + 500),
)
if (query) {
return alphabet
.filter((type) => type.toLowerCase().includes(query.toLowerCase()))
.map((letter) => ({
label: letter,
value: letter,
}))
}
return alphabet.map((letter) => ({
label: letter,
value: letter,
}))
}
</script>
<template>
<div class="n-stack">
<provet-toggle label="Inline-edit" @change="inlineEdit = !inlineEdit" />
<ClientSectionTags
:form-options="fetchAlphabet"
:billing-tags
:inline-edit
/>
</div>
</template>
<script setup lang="ts">
import { z } from 'zod'
type TagsExampleData = {
vowels: string[]
consonant: string[]
}
const alphabet = Array.from({ length: 26 }, (_, i) =>
String.fromCharCode(65 + i),
)
const fetchAlphabet = async (query: string) => {
await new Promise((resolve) =>
setTimeout(resolve, Math.floor(Math.random() * 500) + 500),
)
if (query) {
return alphabet
.filter((type) => type.toLowerCase().includes(query.toLowerCase()))
.map((letter) => ({
label: letter,
value: letter,
}))
}
return alphabet.map((letter) => ({
label: letter,
value: letter,
}))
}
const vowels: TagsExampleData['vowels'] = ['A', 'E', 'I', 'O', 'U']
const consonant: TagsExampleData['consonant'] = alphabet.filter(
(char) => !vowels.includes(char),
)
const formSchema = z.object({
letters: z.string().array().optional(),
})
const validationSchema = toTypedSchema(formSchema)
const isEditing = ref<boolean>(false)
const inlineEdit = ref<boolean>(false)
const expand = ref<boolean>(true)
const selectedTags = ref<string[]>([])
const formElement = useTemplateRef('formRef')
const { handleErrors } = useFormValidation(formElement)
const { handleSubmit } = useForm({
validationSchema,
keepValuesOnUnmount: true,
})
const onSubmit = handleSubmit(
(data) => console.log(data),
() => handleErrors(),
)
</script>
<template>
<form ref="formRef" class="n-stack" @submit="onSubmit">
<div class="n-stack n-stack-horizontal">
<provet-toggle
label="Edit mode"
:checked="isEditing"
@change="isEditing = !isEditing"
/>
<provet-toggle label="Inline-edit" @change="inlineEdit = !inlineEdit" />
<provet-toggle label="Expand" checked @change="expand = !expand" />
<provet-button size="s" variant="primary">Submit</provet-button>
</div>
<EditableField :is-editing>
<BaseTags
v-model:is-editing="isEditing"
v-model:selected-tags="selectedTags"
:categories="[
{ label: 'Vowels', tags: vowels },
{ label: 'Consonants', tags: consonant },
]"
/>
<template #edit>
<FormComboboxMultiple
v-model="selectedTags"
async
name="letters"
label="Alphabet"
hide-label
:min-chars="0"
:delay="0"
:max-displayed-options="10"
resolve-on-load
resolve-on-open
infinite-scroll
:inline-edit
:expand
:options="fetchAlphabet"
/>
</template>
</EditableField>
</form>
</template>
<script setup lang="ts">
import { z } from 'zod'
type TagsExampleData = {
vowels: string[]
consonant: string[]
}
const alphabet = Array.from({ length: 26 }, (_, i) =>
String.fromCharCode(65 + i),
)
const vowels: TagsExampleData['vowels'] = ['A', 'E', 'I', 'O', 'U']
const consonant: TagsExampleData['consonant'] = alphabet.filter(
(char) => !vowels.includes(char),
)
const formSchema = z.object({
letters: z.string().array().min(1, 'You need some letters!'),
})
const validationSchema = toTypedSchema(formSchema)
const isEditing = ref<boolean>(false)
const inlineEdit = ref<boolean>(false)
const expand = ref<boolean>(true)
const selectedTags = ref<string[]>([])
const formElement = useTemplateRef('formRef')
const { handleErrors } = useFormValidation(formElement)
const { handleSubmit } = useForm({
initialValues: { letters: [] },
validationSchema,
keepValuesOnUnmount: true,
})
const onSubmit = handleSubmit(
(data) => console.log(data),
() => handleErrors(),
)
</script>
<template>
<form ref="formRef" class="n-stack" @submit="onSubmit">
<div class="n-stack n-stack-horizontal">
<provet-toggle
label="Edit mode"
:checked="isEditing"
@change="isEditing = !isEditing"
/>
<provet-toggle label="Inline-edit" @change="inlineEdit = !inlineEdit" />
<provet-toggle label="Expand" checked @change="expand = !expand" />
<provet-button size="s" variant="primary">Submit</provet-button>
</div>
<EditableField :is-editing>
<BaseTags
v-model:is-editing="isEditing"
v-model:selected-tags="selectedTags"
:categories="[
{ label: 'Vowels', tags: vowels },
{ label: 'Consonants', tags: consonant },
]"
/>
<template #edit>
<FormComboboxMultiple
v-model="selectedTags"
name="letters"
label="Alphabet"
hide-label
:inline-edit
:expand
:options="
alphabet.map((letter) => ({ label: letter, value: letter }))
"
/>
</template>
</EditableField>
</form>
</template>
<script setup lang="ts">
type TagsExampleData = {
vowels: string[]
consonant: string[]
}
const alphabet = Array.from({ length: 26 }, (_, i) =>
String.fromCharCode(65 + i),
)
const vowels: TagsExampleData['vowels'] = ['A', 'E', 'I', 'O', 'U']
const consonant: TagsExampleData['consonant'] = alphabet.filter(
(char) => !vowels.includes(char),
)
const isEditing = ref<boolean>(true)
const inlineEdit = ref<boolean>(false)
const expand = ref<boolean>(true)
const selectedTags = ref<string[]>(['C', 'W', 'K', 'S'])
</script>
<template>
<div class="n-stack">
<div class="n-stack n-stack-horizontal">
<provet-toggle
label="Edit mode"
:checked="isEditing"
@change="isEditing = !isEditing"
/>
<provet-toggle label="Inline-edit" @change="inlineEdit = !inlineEdit" />
<provet-toggle label="Expand" checked @change="expand = !expand" />
</div>
<EditableField :is-editing>
<BaseTags
v-model:is-editing="isEditing"
v-model:selected-tags="selectedTags"
:categories="[
{ label: 'Vowels', tags: vowels },
{ label: 'Consonants', tags: consonant },
]"
/>
<template #edit>
<ComboboxMultiple
v-model="selectedTags"
label="Vowels & Consonants"
:inline-edit
:expand
:options="
alphabet.map((letter) => ({ label: letter, value: letter }))
"
/>
</template>
</EditableField>
</div>
</template>
Integration
This product pattern is currently only available to use in the New Frontend for Provet Cloud (using Vue & Nuxt).
Troubleshooting
If you experience any issues while using this pattern, please ask for support in the #vet-frontend Slack channel.