Skip to content

Commit 3af5e1f

Browse files
committed
docs: add TagsInput docs
build registry
1 parent e1ceaea commit 3af5e1f

File tree

9 files changed

+184
-6
lines changed

9 files changed

+184
-6
lines changed

apps/v4/components/CodeBlockCommand.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const tabs = computed(() => {
3434
}
3535
else if (props.code.includes('npx')) {
3636
data.npm = props.code
37-
data.yarn = props.code.replaceAll('npx', 'yarn')
37+
data.yarn = props.code.replaceAll('npx', 'yarn dlx')
3838
data.pnpm = props.code.replaceAll('npx', 'pnpm dlx')
3939
data.bun = props.code.replaceAll('npx', 'bunx --bun')
4040
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script setup lang="ts">
2+
import { ref } from 'vue'
3+
import { TagsInput, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText } from '@/registry/new-york-v4/ui/tags-input'
4+
5+
const modelValue = ref(['Apple', 'Banana'])
6+
</script>
7+
8+
<template>
9+
<TagsInput v-model="modelValue" class="w-[300px]">
10+
<TagsInputItem v-for="item in modelValue" :key="item" :value="item">
11+
<TagsInputItemText />
12+
<TagsInputItemDelete />
13+
</TagsInputItem>
14+
15+
<TagsInputInput placeholder="Fruits..." />
16+
</TagsInput>
17+
</template>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<script setup lang="ts">
2+
import { CheckIcon, ChevronDown } from 'lucide-vue-next'
3+
import { ListboxContent, ListboxFilter, ListboxItem, ListboxItemIndicator, ListboxRoot, useFilter } from 'reka-ui'
4+
import { ref } from 'vue'
5+
import { Button } from '@/registry/new-york-v4/ui/button'
6+
import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from '@/registry/new-york-v4/ui/popover'
7+
import { TagsInput, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText } from '@/registry/new-york-v4/ui/tags-input'
8+
9+
const frameworks = [
10+
{ value: 'next.js', label: 'Next.js' },
11+
{ value: 'sveltekit', label: 'SvelteKit' },
12+
{ value: 'nuxt', label: 'Nuxt' },
13+
{ value: 'remix', label: 'Remix' },
14+
{ value: 'astro', label: 'Astro' },
15+
]
16+
17+
const searchTerm = ref('')
18+
const frameworksRef = ref(['Nuxt', 'Remix'])
19+
const open = ref(false)
20+
21+
const { contains } = useFilter({ sensitivity: 'base' })
22+
23+
const filteredFrameworks = computed(() =>
24+
searchTerm.value === ''
25+
? frameworks
26+
: frameworks.filter(option => contains(option.label, searchTerm.value)),
27+
)
28+
29+
watch(searchTerm, (f) => {
30+
if (f) {
31+
open.value = true
32+
}
33+
})
34+
</script>
35+
36+
<template>
37+
<Popover v-model:open="open">
38+
<ListboxRoot
39+
v-model="frameworksRef"
40+
highlight-on-hover
41+
multiple
42+
>
43+
<PopoverAnchor class="inline-flex w-[300px]">
44+
<TagsInput v-slot="{ modelValue: tags }" v-model="frameworksRef" class="w-full">
45+
<TagsInputItem v-for="item in tags" :key="item.toString()" :value="item.toString()">
46+
<TagsInputItemText />
47+
<TagsInputItemDelete />
48+
</TagsInputItem>
49+
50+
<ListboxFilter v-model="searchTerm" as-child>
51+
<TagsInputInput placeholder="Frameworks..." @keydown.enter.prevent @keydown.down="open = true" />
52+
</ListboxFilter>
53+
54+
<PopoverTrigger as-child>
55+
<Button size="icon-sm" variant="ghost" class="order-last self-start ml-auto">
56+
<ChevronDown class="size-3.5" />
57+
</Button>
58+
</PopoverTrigger>
59+
</TagsInput>
60+
</PopoverAnchor>
61+
62+
<PopoverContent
63+
class="p-1"
64+
@open-auto-focus.prevent
65+
>
66+
<ListboxContent class="max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto empty:after:content-['No_options'] empty:p-1 empty:after:block" tabindex="0">
67+
<!-- <CommandEmpty>No results found.</CommandEmpty> -->
68+
<ListboxItem
69+
v-for="item in filteredFrameworks" :key="item.value" class="data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground [&_svg:not([class*=\'text-\'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4" :value="item.label" @select="() => {
70+
searchTerm = ''
71+
}"
72+
>
73+
<span>{{ item.label }}</span>
74+
75+
<ListboxItemIndicator
76+
class="ml-auto inline-flex items-center justify-center"
77+
>
78+
<CheckIcon />
79+
</ListboxItemIndicator>
80+
</ListboxItem>
81+
</ListboxContent>
82+
</PopoverContent>
83+
</ListboxRoot>
84+
</Popover>
85+
</template>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
title: Tags Input
3+
description: Tag inputs render tags inside an input, followed by an actual text input.
4+
component: true
5+
links:
6+
doc: https://reka-ui.com/docs/components/tags-input
7+
api: https://reka-ui.com/docs/components/tags-input#api-reference
8+
---
9+
10+
::component-preview
11+
---
12+
name: TagsInputDemo
13+
---
14+
::
15+
16+
## Installation
17+
18+
::code-tabs
19+
20+
::tabs-list
21+
22+
::tabs-trigger{value="cli"}
23+
CLI
24+
::
25+
26+
::tabs-trigger{value="manual"}
27+
Manual
28+
::
29+
30+
::
31+
32+
::tabs-content{value="cli"}
33+
34+
```bash
35+
npx shadcn-vue@latest add tags-input
36+
```
37+
38+
::
39+
40+
::tabs-content{value="manual"}
41+
::steps
42+
::step
43+
Install the following dependencies:
44+
::
45+
46+
```bash
47+
npm install reka-ui
48+
```
49+
50+
::step
51+
Copy and paste the [GitHub source code](https://github.com/unovue/shadcn-vue/tree/dev/apps/v4/registry/new-york-v4/ui/tags-input) into your project.
52+
::
53+
54+
::step
55+
Update the import paths to match your project setup.
56+
::
57+
::
58+
::
59+
60+
::
61+
62+
## Examples
63+
64+
### Tags with Listbox
65+
66+
::component-preview
67+
---
68+
name: TagsInputWithListbox
69+
---
70+
::

apps/v4/public/r/index.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,7 @@
933933
"reka-ui",
934934
"vee-validate",
935935
"@vee-validate/zod",
936-
"zod"
936+
"zod@3.25.76"
937937
],
938938
"registryDependencies": [
939939
"label"

apps/v4/public/r/styles/new-york-v4/form.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"reka-ui",
77
"vee-validate",
88
"@vee-validate/zod",
9-
"zod"
9+
"zod@3.25.76"
1010
],
1111
"registryDependencies": [
1212
"label"

apps/v4/public/r/styles/new-york-v4/registry.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,7 @@
968968
"reka-ui",
969969
"vee-validate",
970970
"@vee-validate/zod",
971-
"zod"
971+
"zod@3.25.76"
972972
],
973973
"registryDependencies": [
974974
"label"

apps/v4/public/r/styles/new-york-v4/tags-input.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"files": [
1010
{
1111
"path": "registry/new-york-v4/ui/tags-input/TagsInput.vue",
12-
"content": "<script setup lang=\"ts\">\nimport type { TagsInputRootEmits, TagsInputRootProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { reactiveOmit } from \"@vueuse/core\"\nimport { TagsInputRoot, useForwardPropsEmits } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<TagsInputRootProps & { class?: HTMLAttributes[\"class\"] }>()\nconst emits = defineEmits<TagsInputRootEmits>()\n\nconst delegatedProps = reactiveOmit(props, \"class\")\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <TagsInputRoot v-slot=\"slotProps\" 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)\">\n <slot v-bind=\"slotProps\" />\n </TagsInputRoot>\n</template>\n",
12+
"content": "<script setup lang=\"ts\">\nimport type { TagsInputRootEmits, TagsInputRootProps } from \"reka-ui\"\nimport type { HTMLAttributes } from \"vue\"\nimport { reactiveOmit } from \"@vueuse/core\"\nimport { TagsInputRoot, useForwardPropsEmits } from \"reka-ui\"\nimport { cn } from \"@/lib/utils\"\n\nconst props = defineProps<TagsInputRootProps & { class?: HTMLAttributes[\"class\"] }>()\nconst emits = defineEmits<TagsInputRootEmits>()\n\nconst delegatedProps = reactiveOmit(props, \"class\")\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <TagsInputRoot\n v-slot=\"slotProps\" v-bind=\"forwarded\" :class=\"cn(\n 'flex flex-wrap gap-2 items-center rounded-md border border-input bg-background px-2 py-1 text-sm shadow-xs transition-[color,box-shadow] outline-none',\n 'focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[3px]',\n 'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',\n props.class)\"\n >\n <slot v-bind=\"slotProps\" />\n </TagsInputRoot>\n</template>\n",
1313
"type": "registry:ui"
1414
},
1515
{

apps/v4/registry/new-york-v4/ui/tags-input/TagsInput.vue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
1414
</script>
1515

1616
<template>
17-
<TagsInputRoot v-slot="slotProps" 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)">
17+
<TagsInputRoot
18+
v-slot="slotProps" v-bind="forwarded" :class="cn(
19+
'flex flex-wrap gap-2 items-center rounded-md border border-input bg-background px-2 py-1 text-sm shadow-xs transition-[color,box-shadow] outline-none',
20+
'focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[3px]',
21+
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
22+
props.class)"
23+
>
1824
<slot v-bind="slotProps" />
1925
</TagsInputRoot>
2026
</template>

0 commit comments

Comments
 (0)