-
Notifications
You must be signed in to change notification settings - Fork 296
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: tags input * chore: add `tags-input` to sidebar links * chore: update * chore: add combobox demo * chore: improve tag highlight * chore: update * chore: rename title * chore: add static width to `TagsInputCombo` example --------- Co-authored-by: zernonia <zernonia@gmail.com>
- Loading branch information
1 parent
60fbe49
commit 43f9f56
Showing
23 changed files
with
527 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
--- | ||
title: Tags Input | ||
description: Tag inputs render tags inside an input, followed by an actual text input. | ||
source: apps/www/src/lib/registry/default/ui/tags-input | ||
primitive: https://www.radix-vue.com/components/tags-input.html | ||
--- | ||
|
||
<ComponentPreview name="TagsInputDemo" /> | ||
|
||
## Installation | ||
|
||
```bash | ||
npx shadcn-vue@latest add tags-input | ||
``` | ||
|
||
|
||
## Usage | ||
|
||
### Tags with Combobox | ||
|
||
<ComponentPreview name="TagsInputComboboxDemo" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
apps/www/src/lib/registry/default/example/TagsInputComboboxDemo.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<script setup lang="ts"> | ||
import { computed, ref } from 'vue' | ||
import { ComboboxAnchor, ComboboxInput, ComboboxPortal, ComboboxRoot } from 'radix-vue' | ||
import { CommandEmpty, CommandGroup, CommandItem, CommandList } from '@/lib/registry/default/ui/command' | ||
import { TagsInput, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText } from '@/lib/registry/default/ui/tags-input' | ||
const frameworks = [ | ||
{ value: 'next.js', label: 'Next.js' }, | ||
{ value: 'sveltekit', label: 'SvelteKit' }, | ||
{ value: 'nuxt.js', label: 'Nuxt.js' }, | ||
{ value: 'remix', label: 'Remix' }, | ||
{ value: 'astro', label: 'Astro' }, | ||
] | ||
const modelValue = ref<string[]>([]) | ||
const open = ref(false) | ||
const searchTerm = ref('') | ||
const filteredFrameworks = computed(() => frameworks.filter(i => !modelValue.value.includes(i.label))) | ||
</script> | ||
|
||
<template> | ||
<TagsInput class="px-0 gap-0 w-80" :model-value="modelValue"> | ||
<div class="flex gap-2 flex-wrap items-center px-3"> | ||
<TagsInputItem v-for="item in modelValue" :key="item" :value="item"> | ||
<TagsInputItemText /> | ||
<TagsInputItemDelete /> | ||
</TagsInputItem> | ||
</div> | ||
|
||
<ComboboxRoot v-model="modelValue" v-model:open="open" v-model:searchTerm="searchTerm" class="w-full"> | ||
<ComboboxAnchor as-child> | ||
<ComboboxInput placeholder="Framework..." as-child> | ||
<TagsInputInput class="w-full px-3" :class="modelValue.length > 0 ? 'mt-2' : ''" @keydown.enter.prevent /> | ||
</ComboboxInput> | ||
</ComboboxAnchor> | ||
|
||
<ComboboxPortal> | ||
<CommandList | ||
position="popper" | ||
class="w-[--radix-popper-anchor-width] rounded-md mt-2 border bg-popover text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2" | ||
> | ||
<CommandEmpty /> | ||
<CommandGroup> | ||
<CommandItem | ||
v-for="framework in filteredFrameworks" :key="framework.value" :value="framework.label" | ||
@select.prevent="(ev) => { | ||
if (typeof ev.detail.value === 'string') { | ||
searchTerm = '' | ||
modelValue.push(ev.detail.value) | ||
} | ||
if (filteredFrameworks.length === 0) { | ||
open = false | ||
} | ||
}" | ||
> | ||
{{ framework.label }} | ||
</CommandItem> | ||
</CommandGroup> | ||
</CommandList> | ||
</ComboboxPortal> | ||
</ComboboxRoot> | ||
</TagsInput> | ||
</template> |
17 changes: 17 additions & 0 deletions
17
apps/www/src/lib/registry/default/example/TagsInputDemo.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<script setup lang="ts"> | ||
import { ref } from 'vue' | ||
import { TagsInput, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText } from '@/lib/registry/default/ui/tags-input' | ||
const modelValue = ref(['Apple', 'Banana']) | ||
</script> | ||
|
||
<template> | ||
<TagsInput v-model="modelValue"> | ||
<TagsInputItem v-for="item in modelValue" :key="item" :value="item"> | ||
<TagsInputItemText /> | ||
<TagsInputItemDelete /> | ||
</TagsInputItem> | ||
|
||
<TagsInputInput placeholder="Fruits..." /> | ||
</TagsInput> | ||
</template> |
22 changes: 22 additions & 0 deletions
22
apps/www/src/lib/registry/default/ui/tags-input/TagsInput.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<script setup lang="ts"> | ||
import { type HTMLAttributes, computed } from 'vue' | ||
import { TagsInputRoot, type TagsInputRootEmits, type TagsInputRootProps, useForwardPropsEmits } from 'radix-vue' | ||
import { cn } from '@/lib/utils' | ||
const props = defineProps<TagsInputRootProps & { class?: HTMLAttributes['class'] }>() | ||
const emits = defineEmits<TagsInputRootEmits>() | ||
const delegatedProps = computed(() => { | ||
const { class: _, ...delegated } = props | ||
return delegated | ||
}) | ||
const forwarded = useForwardPropsEmits(delegatedProps, emits) | ||
</script> | ||
|
||
<template> | ||
<TagsInputRoot v-bind="forwarded" :class="cn('flex flex-wrap gap-2 items-center rounded-md border border-input bg-background px-3 py-2 text-sm', props.class)"> | ||
<slot /> | ||
</TagsInputRoot> | ||
</template> |
19 changes: 19 additions & 0 deletions
19
apps/www/src/lib/registry/default/ui/tags-input/TagsInputInput.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<script setup lang="ts"> | ||
import { type HTMLAttributes, computed } from 'vue' | ||
import { TagsInputInput, type TagsInputInputProps, useForwardProps } from 'radix-vue' | ||
import { cn } from '@/lib/utils' | ||
const props = defineProps<TagsInputInputProps & { class?: HTMLAttributes['class'] }>() | ||
const delegatedProps = computed(() => { | ||
const { class: _, ...delegated } = props | ||
return delegated | ||
}) | ||
const forwardedProps = useForwardProps(delegatedProps) | ||
</script> | ||
|
||
<template> | ||
<TagsInputInput v-bind="forwardedProps" :class="cn('text-sm min-h-6 focus:outline-none flex-1 bg-transparent px-1', props.class)" /> | ||
</template> |
22 changes: 22 additions & 0 deletions
22
apps/www/src/lib/registry/default/ui/tags-input/TagsInputItem.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<script setup lang="ts"> | ||
import { type HTMLAttributes, computed } from 'vue' | ||
import { TagsInputItem, type TagsInputItemProps, useForwardProps } from 'radix-vue' | ||
import { cn } from '@/lib/utils' | ||
const props = defineProps<TagsInputItemProps & { class?: HTMLAttributes['class'] }>() | ||
const delegatedProps = computed(() => { | ||
const { class: _, ...delegated } = props | ||
return delegated | ||
}) | ||
const forwardedProps = useForwardProps(delegatedProps) | ||
</script> | ||
|
||
<template> | ||
<TagsInputItem v-bind="forwardedProps" :class="cn('flex h-6 items-center rounded bg-secondary data-[state=active]:ring-ring data-[state=active]:ring-2 data-[state=active]:ring-offset-2 ring-offset-background', props.class)"> | ||
<slot /> | ||
</TagsInputItem> | ||
</template> |
24 changes: 24 additions & 0 deletions
24
apps/www/src/lib/registry/default/ui/tags-input/TagsInputItemDelete.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<script setup lang="ts"> | ||
import { type HTMLAttributes, computed } from 'vue' | ||
import { TagsInputItemDelete, type TagsInputItemDeleteProps, useForwardProps } from 'radix-vue' | ||
import { X } from 'lucide-vue-next' | ||
import { cn } from '@/lib/utils' | ||
const props = defineProps<TagsInputItemDeleteProps & { class?: HTMLAttributes['class'] }>() | ||
const delegatedProps = computed(() => { | ||
const { class: _, ...delegated } = props | ||
return delegated | ||
}) | ||
const forwardedProps = useForwardProps(delegatedProps) | ||
</script> | ||
|
||
<template> | ||
<TagsInputItemDelete v-bind="forwardedProps" :class="cn('flex rounded bg-transparent mr-1', props.class)"> | ||
<slot> | ||
<X class="w-4 h-4" /> | ||
</slot> | ||
</TagsInputItemDelete> | ||
</template> |
19 changes: 19 additions & 0 deletions
19
apps/www/src/lib/registry/default/ui/tags-input/TagsInputItemText.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<script setup lang="ts"> | ||
import { type HTMLAttributes, computed } from 'vue' | ||
import { TagsInputItemText, type TagsInputItemTextProps, useForwardProps } from 'radix-vue' | ||
import { cn } from '@/lib/utils' | ||
const props = defineProps<TagsInputItemTextProps & { class?: HTMLAttributes['class'] }>() | ||
const delegatedProps = computed(() => { | ||
const { class: _, ...delegated } = props | ||
return delegated | ||
}) | ||
const forwardedProps = useForwardProps(delegatedProps) | ||
</script> | ||
|
||
<template> | ||
<TagsInputItemText v-bind="forwardedProps" :class="cn('py-1 px-2 text-sm rounded bg-transparent', props.class)" /> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export { default as TagsInput } from './TagsInput.vue' | ||
export { default as TagsInputInput } from './TagsInputInput.vue' | ||
export { default as TagsInputItem } from './TagsInputItem.vue' | ||
export { default as TagsInputItemDelete } from './TagsInputItemDelete.vue' | ||
export { default as TagsInputItemText } from './TagsInputItemText.vue' |
65 changes: 65 additions & 0 deletions
65
apps/www/src/lib/registry/new-york/example/TagsInputComboboxDemo.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<script setup lang="ts"> | ||
import { computed, ref } from 'vue' | ||
import { ComboboxAnchor, ComboboxInput, ComboboxPortal, ComboboxRoot } from 'radix-vue' | ||
import { CommandEmpty, CommandGroup, CommandItem, CommandList } from '@/lib/registry/new-york/ui/command' | ||
import { TagsInput, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText } from '@/lib/registry/new-york/ui/tags-input' | ||
const frameworks = [ | ||
{ value: 'next.js', label: 'Next.js' }, | ||
{ value: 'sveltekit', label: 'SvelteKit' }, | ||
{ value: 'nuxt.js', label: 'Nuxt.js' }, | ||
{ value: 'remix', label: 'Remix' }, | ||
{ value: 'astro', label: 'Astro' }, | ||
] | ||
const modelValue = ref<string[]>([]) | ||
const open = ref(false) | ||
const searchTerm = ref('') | ||
const filteredFrameworks = computed(() => frameworks.filter(i => !modelValue.value.includes(i.label))) | ||
</script> | ||
|
||
<template> | ||
<TagsInput class="px-0 gap-0 w-80" :model-value="modelValue"> | ||
<div class="flex gap-2 flex-wrap items-center px-3"> | ||
<TagsInputItem v-for="item in modelValue" :key="item" :value="item"> | ||
<TagsInputItemText /> | ||
<TagsInputItemDelete /> | ||
</TagsInputItem> | ||
</div> | ||
|
||
<ComboboxRoot v-model="modelValue" v-model:open="open" v-model:searchTerm="searchTerm" class="w-full"> | ||
<ComboboxAnchor as-child> | ||
<ComboboxInput placeholder="Framework..." as-child> | ||
<TagsInputInput class="w-full px-3" :class="modelValue.length > 0 ? 'mt-2' : ''" @keydown.enter.prevent /> | ||
</ComboboxInput> | ||
</ComboboxAnchor> | ||
|
||
<ComboboxPortal> | ||
<CommandList | ||
position="popper" | ||
class="w-[--radix-popper-anchor-width] rounded-md mt-2 border bg-popover text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2" | ||
> | ||
<CommandEmpty /> | ||
<CommandGroup> | ||
<CommandItem | ||
v-for="framework in filteredFrameworks" :key="framework.value" :value="framework.label" | ||
@select.prevent="(ev) => { | ||
if (typeof ev.detail.value === 'string') { | ||
searchTerm = '' | ||
modelValue.push(ev.detail.value) | ||
} | ||
if (filteredFrameworks.length === 0) { | ||
open = false | ||
} | ||
}" | ||
> | ||
{{ framework.label }} | ||
</CommandItem> | ||
</CommandGroup> | ||
</CommandList> | ||
</ComboboxPortal> | ||
</ComboboxRoot> | ||
</TagsInput> | ||
</template> |
17 changes: 17 additions & 0 deletions
17
apps/www/src/lib/registry/new-york/example/TagsInputDemo.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<script setup lang="ts"> | ||
import { ref } from 'vue' | ||
import { TagsInput, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText } from '@/lib/registry/new-york/ui/tags-input' | ||
const modelValue = ref(['Apple', 'Banana']) | ||
</script> | ||
|
||
<template> | ||
<TagsInput v-model="modelValue"> | ||
<TagsInputItem v-for="item in modelValue" :key="item" :value="item"> | ||
<TagsInputItemText /> | ||
<TagsInputItemDelete /> | ||
</TagsInputItem> | ||
|
||
<TagsInputInput placeholder="Fruits..." /> | ||
</TagsInput> | ||
</template> |
22 changes: 22 additions & 0 deletions
22
apps/www/src/lib/registry/new-york/ui/tags-input/TagsInput.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<script setup lang="ts"> | ||
import { type HTMLAttributes, computed } from 'vue' | ||
import { TagsInputRoot, type TagsInputRootEmits, type TagsInputRootProps, useForwardPropsEmits } from 'radix-vue' | ||
import { cn } from '@/lib/utils' | ||
const props = defineProps<TagsInputRootProps & { class?: HTMLAttributes['class'] }>() | ||
const emits = defineEmits<TagsInputRootEmits>() | ||
const delegatedProps = computed(() => { | ||
const { class: _, ...delegated } = props | ||
return delegated | ||
}) | ||
const forwarded = useForwardPropsEmits(delegatedProps, emits) | ||
</script> | ||
|
||
<template> | ||
<TagsInputRoot v-bind="forwarded" :class="cn('flex flex-wrap gap-2 items-center rounded-md border border-input bg-background px-3 py-1.5 text-sm', props.class)"> | ||
<slot /> | ||
</TagsInputRoot> | ||
</template> |
Oops, something went wrong.