diff --git a/docs/app/components/content/examples/input-tags/InputTagsFormFieldExample.vue b/docs/app/components/content/examples/input-tags/InputTagsFormFieldExample.vue new file mode 100644 index 0000000000..22bbba17a0 --- /dev/null +++ b/docs/app/components/content/examples/input-tags/InputTagsFormFieldExample.vue @@ -0,0 +1,9 @@ + + + diff --git a/docs/content/3.components/input-menu.md b/docs/content/3.components/input-menu.md index d416fdfba6..564b9f6960 100644 --- a/docs/content/3.components/input-menu.md +++ b/docs/content/3.components/input-menu.md @@ -135,7 +135,7 @@ props: ### Multiple -Use the `multiple` prop to allow multiple selections, the selected items will be displayed as badges. +Use the `multiple` prop to allow multiple selections, the selected items will be displayed as tags. ::component-code --- @@ -166,7 +166,7 @@ Ensure to pass an array to the `default-value` prop or the `v-model` directive. ### Delete Icon -With `multiple`, use the `delete-icon` prop to customize the delete [Icon](/components/icon) in the badges. Defaults to `i-lucide-x`. +With `multiple`, use the `delete-icon` prop to customize the delete [Icon](/components/icon) in the tags. Defaults to `i-lucide-x`. ::component-code --- diff --git a/docs/content/3.components/input-tags.md b/docs/content/3.components/input-tags.md new file mode 100644 index 0000000000..cada7c1fd6 --- /dev/null +++ b/docs/content/3.components/input-tags.md @@ -0,0 +1,284 @@ +--- +title: InputTags +description: An input element that displays interactive tags. +links: + - label: InputTags + icon: i-custom-reka-ui + to: https://reka-ui.com/docs/components/tags-input + - label: GitHub + icon: i-simple-icons-github + to: https://github.com/nuxt/ui/tree/v3/src/runtime/components/InputTags.vue +navigation.badge: Soon +--- + +## Usage + +Use the `v-model` directive to control the value of the InputTags. + +::component-code +--- +prettier: true +ignore: + - modelValue +external: + - modelValue +props: + modelValue: ['Vue'] +--- +:: + +Use the `default-value` prop to set the initial value when you do not need to control its state. + +::component-code +--- +prettier: true +ignore: + - defaultValue +props: + defaultValue: ['Vue'] +--- +:: + +### Placeholder + +Use the `placeholder` prop to set a placeholder text. + +::component-code +--- +props: + placeholder: 'Enter tags...' +--- +:: + +### Color + +Use the `color` prop to change the ring color when the InputTags is focused. + +::component-code +--- +prettier: true +ignore: + - modelValue +external: + - modelValue +props: + modelValue: ['Vue'] + color: neutral + highlight: true +--- +:: + +::note +The `highlight` prop is used here to show the focus state. It's used internally when a validation error occurs. +:: + +### Variants + +Use the `variant` prop to change the appearance of the InputTags. + +::component-code +--- +prettier: true +ignore: + - modelValue +external: + - modelValue +props: + modelValue: ['Vue'] + variant: subtle + color: neutral + highlight: false +--- +:: + +### Sizes + +Use the `size` prop to adjust the size of the InputTags. + +::component-code +--- +prettier: true +ignore: + - modelValue +external: + - modelValue +props: + modelValue: ['Vue'] + size: xl +--- +:: + +### Icon + +Use the `icon` prop to show an [Icon](/components/icon) inside the InputTags. + +::component-code +--- +prettier: true +ignore: + - modelValue +external: + - modelValue +props: + modelValue: ['Vue'] + icon: 'i-lucide-search' + size: md + variant: outline +--- +:: + +::note +Use the `leading` and `trailing` props to set the icon position or the `leading-icon` and `trailing-icon` props to set a different icon for each position. +:: + +### Avatar + +Use the `avatar` prop to show an [Avatar](/components/avatar) inside the InputTags. + +::component-code +--- +prettier: true +ignore: + - modelValue +external: + - modelValue +props: + modelValue: ['Vue'] + avatar: + src: 'https://github.com/vuejs.png' + size: md + variant: outline +--- +:: + +### Delete Icon + +Use the `delete-icon` prop to customize the delete [Icon](/components/icon) in the tags. Defaults to `i-lucide-x`. + +::component-code +--- +prettier: true +ignore: + - modelValue +external: + - modelValue +props: + modelValue: ['Vue'] + deleteIcon: 'i-lucide-trash' +--- +:: + +::framework-only +#nuxt +:::tip{to="/getting-started/icons/nuxt#theme"} +You can customize this icon globally in your `app.config.ts` under `ui.icons.close` key. +::: + +#vue +:::tip{to="/getting-started/icons/vue#theme"} +You can customize this icon globally in your `vite.config.ts` under `ui.icons.close` key. +::: +:: + +### Loading + +Use the `loading` prop to show a loading icon on the InputTags. + +::component-code +--- +prettier: true +ignore: + - modelValue +external: + - modelValue +props: + modelValue: ['Vue'] + loading: true + trailing: false +--- +:: + +### Loading Icon + +Use the `loading-icon` prop to customize the loading icon. Defaults to `i-lucide-loader-circle`. + +::component-code +--- +prettier: true +ignore: + - modelValue +external: + - modelValue +props: + modelValue: ['Vue'] + loading: true + loadingIcon: 'i-lucide-loader' +--- +:: + +::framework-only +#nuxt +:::tip{to="/getting-started/icons/nuxt#theme"} +You can customize this icon globally in your `app.config.ts` under `ui.icons.loading` key. +::: + +#vue +:::tip{to="/getting-started/icons/vue#theme"} +You can customize this icon globally in your `vite.config.ts` under `ui.icons.loading` key. +::: +:: + +### Disabled + +Use the `disabled` prop to disable the InputTags. + +::component-code +--- +prettier: true +ignore: + - modelValue +external: + - modelValue +props: + modelValue: ['Vue'] + disabled: true +--- +:: + +## Examples + +### Within a FormField + +You can use the InputTags within a [FormField](/components/form-field) component to display a label, help text, required indicator, etc. + +::component-example +--- +name: 'input-tags-form-field-example' +--- +:: + +## API + +### Props + +:component-props + +### Slots + +:component-slots + +### Emits + +:component-emits + +### Expose + +When accessing the component via a template ref, you can use the following: + +| Name | Type | +|----------------------------|-------------------------------------------------| +| `inputRef`{lang="ts-type"} | `Ref`{lang="ts-type"} | + +## Theme + +:component-theme diff --git a/playground-vue/src/app.vue b/playground-vue/src/app.vue index 62f0573b83..cc2e69d572 100644 --- a/playground-vue/src/app.vue +++ b/playground-vue/src/app.vue @@ -40,6 +40,7 @@ const components = [ 'input', 'input-menu', 'input-number', + 'input-tags', 'kbd', 'link', 'modal', diff --git a/playground/app/app.vue b/playground/app/app.vue index d547b989ed..7348fbd70f 100644 --- a/playground/app/app.vue +++ b/playground/app/app.vue @@ -40,6 +40,7 @@ const components = [ 'input', 'input-menu', 'input-number', + 'input-tags', 'kbd', 'link', 'modal', diff --git a/playground/app/pages/components/input-menu.vue b/playground/app/pages/components/input-menu.vue index 20363ae490..f946be1ede 100644 --- a/playground/app/pages/components/input-menu.vue +++ b/playground/app/pages/components/input-menu.vue @@ -145,5 +145,18 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode class="w-48" /> +
+ +
diff --git a/playground/app/pages/components/input-tags.vue b/playground/app/pages/components/input-tags.vue new file mode 100644 index 0000000000..342742a7fd --- /dev/null +++ b/playground/app/pages/components/input-tags.vue @@ -0,0 +1,87 @@ + + + diff --git a/src/runtime/components/InputTags.vue b/src/runtime/components/InputTags.vue new file mode 100644 index 0000000000..87d4970a9a --- /dev/null +++ b/src/runtime/components/InputTags.vue @@ -0,0 +1,203 @@ + + + + + + diff --git a/src/runtime/types/index.ts b/src/runtime/types/index.ts index f2a9d6841e..f413b71caa 100644 --- a/src/runtime/types/index.ts +++ b/src/runtime/types/index.ts @@ -26,6 +26,7 @@ export * from '../components/Icon.vue' export * from '../components/Input.vue' export * from '../components/InputMenu.vue' export * from '../components/InputNumber.vue' +export * from '../components/InputTags.vue' export * from '../components/Kbd.vue' export * from '../components/Link.vue' export * from '../components/Modal.vue' diff --git a/src/theme/index.ts b/src/theme/index.ts index c52531309d..e03aecd3b5 100644 --- a/src/theme/index.ts +++ b/src/theme/index.ts @@ -24,6 +24,7 @@ export { default as formField } from './form-field' export { default as input } from './input' export { default as inputMenu } from './input-menu' export { default as inputNumber } from './input-number' +export { default as inputTags } from './input-tags' export { default as kbd } from './kbd' export { default as link } from './link' export { default as modal } from './modal' diff --git a/src/theme/input-menu.ts b/src/theme/input-menu.ts index 700218f494..4e3d11022e 100644 --- a/src/theme/input-menu.ts +++ b/src/theme/input-menu.ts @@ -26,14 +26,13 @@ export default (options: Required) => { tagsItem: 'px-1.5 py-0.5 rounded-sm font-medium inline-flex items-center gap-0.5 ring ring-inset ring-accented bg-elevated text-default data-disabled:cursor-not-allowed data-disabled:opacity-75', tagsItemText: 'truncate', tagsItemDelete: ['inline-flex items-center rounded-xs text-dimmed hover:text-default hover:bg-accented/75 disabled:pointer-events-none', options.theme.transitions && 'transition-colors'], - tagsItemDeleteIcon: '', - tagsInput: '' + tagsItemDeleteIcon: 'shrink-0', + tagsInput: 'flex-1 border-0 bg-transparent placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75' }, variants: { multiple: { true: { - root: 'flex-wrap', - tagsInput: 'border-0 bg-transparent placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75' + root: 'flex-wrap' }, false: { base: 'w-full border-0 placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75' @@ -97,7 +96,15 @@ export default (options: Required) => { } } }, - compoundVariants: [...(options.theme.colors || []).map((color: string) => ({ + compoundVariants: [{ + variant: 'soft', + multiple: true, + class: 'has-focus:bg-elevated' + }, { + variant: 'ghost', + multiple: true, + class: 'has-focus:bg-elevated' + }, ...(options.theme.colors || []).map((color: string) => ({ color, multiple: true, variant: ['outline', 'subtle'], diff --git a/src/theme/input-tags.ts b/src/theme/input-tags.ts new file mode 100644 index 0000000000..c26d5235e6 --- /dev/null +++ b/src/theme/input-tags.ts @@ -0,0 +1,54 @@ +import { defuFn } from 'defu' +import type { ModuleOptions } from '../module' +import input from './input' + +export default (options: Required) => { + return defuFn({ + slots: { + root: (prev: string) => [prev, 'flex-wrap'], + base: () => ['rounded-md', options.theme.transitions && 'transition-colors'], + item: 'px-1.5 py-0.5 rounded-sm font-medium inline-flex items-center gap-0.5 ring ring-inset ring-accented bg-elevated text-default data-disabled:cursor-not-allowed data-disabled:opacity-75 wrap-anywhere data-[state="active"]:bg-accented', + itemText: '', + itemDelete: ['inline-flex items-center rounded-xs text-dimmed hover:text-default hover:bg-accented/75 disabled:pointer-events-none', options.theme.transitions && 'transition-colors'], + itemDeleteIcon: 'shrink-0', + input: 'flex-1 border-0 bg-transparent placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75' + }, + variants: { + size: { + xs: { + item: 'text-[10px]/3', + itemDeleteIcon: 'size-3' + }, + sm: { + item: 'text-[10px]/3', + itemDeleteIcon: 'size-3' + }, + md: { + item: 'text-xs', + itemDeleteIcon: 'size-3.5' + }, + lg: { + item: 'text-xs', + itemDeleteIcon: 'size-3.5' + }, + xl: { + item: 'text-sm', + itemDeleteIcon: 'size-4' + } + }, + variant: (prev: Record) => Object.fromEntries( + Object.entries(prev).map(([key, value]) => [key, replaceFocus(value)]) + ) + }, + compoundVariants: (prev: Record[]) => prev.map(item => ({ + ...item, + class: typeof item.class === 'string' ? replaceFocus(item.class) : item.class + })) + }, input(options)) +} + +function replaceFocus(str: string): string { + return str + .replace(/focus:/g, 'has-focus:') + .replace(/focus-visible:/g, 'has-focus-visible:') +} diff --git a/test/components/InputMenu.spec.ts b/test/components/InputMenu.spec.ts index f64bef17b4..dd2f1d5c7c 100644 --- a/test/components/InputMenu.spec.ts +++ b/test/components/InputMenu.spec.ts @@ -42,6 +42,8 @@ describe('InputMenu', () => { ['with defaultValue', { props: { ...props, defaultValue: items[0] } }], ['with valueKey', { props: { ...props, valueKey: 'value' } }], ['with labelKey', { props: { ...props, labelKey: 'value' } }], + ['with multiple', { props: { ...props, multiple: true } }], + ['with multiple and modelValue', { props: { ...props, multiple: true, modelValue: [items[0], items[1]] } }], ['with id', { props: { ...props, id: 'id' } }], ['with name', { props: { ...props, name: 'name' } }], ['with placeholder', { props: { ...props, placeholder: 'Search...' } }], diff --git a/test/components/InputTags.spec.ts b/test/components/InputTags.spec.ts new file mode 100644 index 0000000000..54bc658b29 --- /dev/null +++ b/test/components/InputTags.spec.ts @@ -0,0 +1,42 @@ +import { describe, it, expect } from 'vitest' +import theme from '#build/ui/input' +import InputTags, { type InputTagsProps, type InputTagsSlots } from '../../src/runtime/components/InputTags.vue' +import ComponentRender from '../component-render' + +describe('InputTags', () => { + const sizes = Object.keys(theme.variants.size) as any + const variants = Object.keys(theme.variants.variant) as any + + it.each([ + // Props + ['with modelValue', { props: { modelValue: ['test'] } }], + ['with defaultValue', { props: { defaultValue: ['test'] } }], + ['with id', { props: { id: 'id' } }], + ['with name', { props: { name: 'name' } }], + ['with placeholder', { props: { placeholder: 'Search...' } }], + ['with disabled', { props: { disabled: true } }], + ['with required', { props: { required: true } }], + ['with icon', { props: { icon: 'i-lucide-search' } }], + ['with trailing and icon', { props: { trailing: true, icon: 'i-lucide-arrow-right' } }], + ['with trailingIcon', { props: { trailingIcon: 'i-lucide-arrow-right' } }], + ['with loading', { props: { loading: true } }], + ['with loading trailing', { props: { loading: true, trailing: true } }], + ['with loadingIcon', { props: { loading: true, loadingIcon: 'i-lucide-loader' } }], + ['with ariaLabel', { attrs: { 'aria-label': 'Aria label' } }], + ['with as', { props: { as: 'section' } }], + ['with class', { props: { class: '' } }], + ['with ui', { props: { ui: {} } }], + ...sizes.map((size: string) => [`with size ${size}`, { props: { size } }]), + ...variants.map((variant: string) => [`with primary variant ${variant}`, { props: { variant } }]), + ...variants.map((variant: string) => [`with neutral variant ${variant}`, { props: { variant, color: 'neutral' } }]), + // Slots + ['with leading slot', { slots: { leading: () => 'Leading slot' } }], + ['with default slot', { slots: { default: () => 'Default slot' } }], + ['with trailing slot', { slots: { trailing: () => 'Trailing slot' } }], + ['with item-text slot', { slots: { ['item-text']: () => 'Item Text slot' } }], + ['with item-delete slot', { slots: { ['item-delete']: () => 'Item Delete slot' } }] + ])('renders %s correctly', async (nameOrHtml: string, options: { props?: InputTagsProps, slots?: Partial, attrs?: Record }) => { + const html = await ComponentRender(nameOrHtml, options, InputTags) + expect(html).toMatchSnapshot() + }) +}) diff --git a/test/components/__snapshots__/InputMenu-vue.spec.ts.snap b/test/components/__snapshots__/InputMenu-vue.spec.ts.snap index 7e6164c503..11231c3850 100644 --- a/test/components/__snapshots__/InputMenu-vue.spec.ts.snap +++ b/test/components/__snapshots__/InputMenu-vue.spec.ts.snap @@ -482,6 +482,70 @@ exports[`InputMenu > renders with modelValue correctly 1`] = ` " `; +exports[`InputMenu > renders with multiple and modelValue correctly 1`] = ` +"
+
Backlog
+
Todo
+ + +
+ + + +
+
+ + + +
+
+ + + +" +`; + +exports[`InputMenu > renders with multiple correctly 1`] = ` +"
+ + +
+ + + +
+
+ + + +
+
+ + + +" +`; + exports[`InputMenu > renders with name correctly 1`] = ` "
diff --git a/test/components/__snapshots__/InputMenu.spec.ts.snap b/test/components/__snapshots__/InputMenu.spec.ts.snap index 0460329602..bcbc88f640 100644 --- a/test/components/__snapshots__/InputMenu.spec.ts.snap +++ b/test/components/__snapshots__/InputMenu.spec.ts.snap @@ -482,6 +482,70 @@ exports[`InputMenu > renders with modelValue correctly 1`] = `
" `; +exports[`InputMenu > renders with multiple and modelValue correctly 1`] = ` +"
+
Backlog
+
Todo
+ + +
+ + + +
+
+ + + +
+
+ + + +" +`; + +exports[`InputMenu > renders with multiple correctly 1`] = ` +"
+ + +
+ + + +
+
+ + + +
+
+ + + +" +`; + exports[`InputMenu > renders with name correctly 1`] = ` "
diff --git a/test/components/__snapshots__/InputTags-vue.spec.ts.snap b/test/components/__snapshots__/InputTags-vue.spec.ts.snap new file mode 100644 index 0000000000..789a6b7b6a --- /dev/null +++ b/test/components/__snapshots__/InputTags-vue.spec.ts.snap @@ -0,0 +1,291 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`InputTags > renders with ariaLabel correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with as correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with class correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with default slot correctly 1`] = ` +"
Default slot + + + +
" +`; + +exports[`InputTags > renders with defaultValue correctly 1`] = ` +"
+
test
+ + + +
" +`; + +exports[`InputTags > renders with disabled correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with icon correctly 1`] = ` +"
+ + +
" +`; + +exports[`InputTags > renders with id correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with item-delete slot correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with item-text slot correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with leading slot correctly 1`] = ` +"
Leading slot + + +
" +`; + +exports[`InputTags > renders with loading correctly 1`] = ` +"
+ + +
" +`; + +exports[`InputTags > renders with loading trailing correctly 1`] = ` +"
+ + +
" +`; + +exports[`InputTags > renders with loadingIcon correctly 1`] = ` +"
+ + +
" +`; + +exports[`InputTags > renders with modelValue correctly 1`] = ` +"
+
test
+ + + +
" +`; + +exports[`InputTags > renders with name correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with neutral variant ghost correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with neutral variant none correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with neutral variant outline correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with neutral variant soft correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with neutral variant subtle correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with placeholder correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with primary variant ghost correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with primary variant none correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with primary variant outline correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with primary variant soft correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with primary variant subtle correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with required correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with size lg correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with size md correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with size sm correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with size xl correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with size xs correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with trailing and icon correctly 1`] = ` +"
+ + +
" +`; + +exports[`InputTags > renders with trailing slot correctly 1`] = ` +"
+ Trailing slot + +
" +`; + +exports[`InputTags > renders with trailingIcon correctly 1`] = ` +"
+ + +
" +`; + +exports[`InputTags > renders with ui correctly 1`] = ` +"
+ + + +
" +`; diff --git a/test/components/__snapshots__/InputTags.spec.ts.snap b/test/components/__snapshots__/InputTags.spec.ts.snap new file mode 100644 index 0000000000..7f6c24bbf5 --- /dev/null +++ b/test/components/__snapshots__/InputTags.spec.ts.snap @@ -0,0 +1,291 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`InputTags > renders with ariaLabel correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with as correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with class correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with default slot correctly 1`] = ` +"
Default slot + + + +
" +`; + +exports[`InputTags > renders with defaultValue correctly 1`] = ` +"
+
test
+ + + +
" +`; + +exports[`InputTags > renders with disabled correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with icon correctly 1`] = ` +"
+ + +
" +`; + +exports[`InputTags > renders with id correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with item-delete slot correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with item-text slot correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with leading slot correctly 1`] = ` +"
Leading slot + + +
" +`; + +exports[`InputTags > renders with loading correctly 1`] = ` +"
+ + +
" +`; + +exports[`InputTags > renders with loading trailing correctly 1`] = ` +"
+ + +
" +`; + +exports[`InputTags > renders with loadingIcon correctly 1`] = ` +"
+ + +
" +`; + +exports[`InputTags > renders with modelValue correctly 1`] = ` +"
+
test
+ + + +
" +`; + +exports[`InputTags > renders with name correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with neutral variant ghost correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with neutral variant none correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with neutral variant outline correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with neutral variant soft correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with neutral variant subtle correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with placeholder correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with primary variant ghost correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with primary variant none correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with primary variant outline correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with primary variant soft correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with primary variant subtle correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with required correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with size lg correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with size md correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with size sm correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with size xl correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with size xs correctly 1`] = ` +"
+ + + +
" +`; + +exports[`InputTags > renders with trailing and icon correctly 1`] = ` +"
+ + +
" +`; + +exports[`InputTags > renders with trailing slot correctly 1`] = ` +"
+ Trailing slot + +
" +`; + +exports[`InputTags > renders with trailingIcon correctly 1`] = ` +"
+ + +
" +`; + +exports[`InputTags > renders with ui correctly 1`] = ` +"
+ + + +
" +`;