Merge remote-tracking branch 'origin/dev' into charting

This commit is contained in:
zernonia 2024-03-21 10:50:00 +08:00
commit 26e3ea917c
272 changed files with 4845 additions and 1490 deletions

View File

@ -1,4 +1,5 @@
{
"vue.server.hybridMode": true,
"eslint.experimental.useFlatConfig": true,
"prettier.enable": false,
"editor.formatOnSave": false,

View File

@ -19,7 +19,7 @@ This repository is structured as follows:
```
apps
└── www
├── src
├── src
│ └── content
└── registry
├── default
@ -32,12 +32,12 @@ packages
└── cli
```
| Path | Description |
| --------------------- | ---------------------------------------- |
| `apps/www/app` | The Next.js application for the website. |
| `apps/www/content` | The content for the website. |
| `apps/www/registry` | The registry for the components. |
| `packages/cli` | The `shadcn-vue` package. |
| Path | Description |
| ----------------------------| -------------------------------------------|
| `apps/www/.vitepress` | The Vitepress application for the website. |
| `apps/www/src/content` | The content for the website. |
| `apps/www/src/lib/registry` | The registry for the components. |
| `packages/cli` | The `shadcn-vue` package. |
## Development
@ -79,22 +79,24 @@ The documentation for this project is located in the `www` workspace. You can ru
pnpm dev
```
Documentation is written using [md](https://vitepress.dev/guide/markdown). You can find the documentation files in the `apps/www/content/docs` directory.
Documentation is written using [md](https://vitepress.dev/guide/markdown). You can find the documentation files in the `apps/www/src/content` directory.
## Components
We use a registry system for developing components. You can find the source code for the components under `apps/www/registry`. The components are organized by styles.
We use a registry system for developing components. You can find the source code for the components under `apps/www/src/lib/registry`. The components are organized by styles.
```bash
apps
└── www
└── registry
├── default
│ ├── example
│ └── ui
└── new-york
├── example
└── ui
└── src
└── lib
└── registry
├── default
│ ├── example
│ └── ui
└── new-york
├── example
└── ui
```
When adding or modifying components, please ensure that:
@ -130,13 +132,10 @@ the following categories:
e.g. `feat(components): add new prop to the avatar component`
If you are interested in the detailed specification you can visit
https://www.conventionalcommits.org/ or check out the
[Angular Commit Message Guidelines](https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#-commit-message-guidelines).
## Requests for new components
If you have a request for a new component, please open a discussion on GitHub. We'll be happy to help you out.
@ -155,4 +154,4 @@ Tests are written using [Vitest](https://vitest.dev). You can run all the tests
pnpm test
```
Please ensure that the tests are passing when submitting a pull request. If you're adding new features, please include tests.
Please ensure that the tests are passing when submitting a pull request. If you're adding new features, please include tests.

View File

@ -3,16 +3,12 @@ import { defineConfig } from 'vitepress'
import Icons from 'unplugin-icons/vite'
import tailwind from 'tailwindcss'
import autoprefixer from 'autoprefixer'
import { createCssVariablesTheme } from 'shiki'
import { cssVariables } from './theme/config/shiki'
// import { transformerMetaWordHighlight, transformerNotationWordHighlight } from '@shikijs/transformers'
import { siteConfig } from './theme/config/site'
import ComponentPreviewPlugin from './theme/plugins/previewer'
const cssVariables = createCssVariablesTheme({
variablePrefix: '--shiki-',
variableDefaults: {},
})
import CodeWrapperPlugin from './theme/plugins/codewrapper'
// https://vitepress.dev/reference/site-config
export default defineConfig({
@ -65,6 +61,7 @@ export default defineConfig({
],
config(md) {
md.use(ComponentPreviewPlugin)
md.use(CodeWrapperPlugin)
},
},
rewrites: {

View File

@ -0,0 +1,98 @@
<script lang="ts" setup>
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
import { useConfigStore } from '@/stores/config'
import { Button } from '@/lib/registry/new-york/ui/button'
import { Input } from '@/lib/registry/new-york/ui/input'
import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/lib/registry/new-york/ui/form'
import { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from '@/lib/registry/new-york/ui/sheet'
import RadixIconsGear from '~icons/radix-icons/gear'
const { codeConfig, setCodeConfig } = useConfigStore()
const formSchema = toTypedSchema(z.object({
prefix: z.string().default(''),
componentsPath: z.string().default('@/components'),
utilsPath: z.string().default('@/utils'),
}))
const { handleSubmit, setValues } = useForm({
validationSchema: formSchema,
initialValues: codeConfig.value,
})
const onSubmit = handleSubmit((values) => {
setCodeConfig(values)
setValues(values)
})
</script>
<template>
<Sheet
@update:open="(open) => {
if (open) setValues(codeConfig)
}"
>
<SheetTrigger as-child>
<Button
class="w-9 h-9"
:variant="'ghost'"
:size="'icon'"
>
<RadixIconsGear class="w-5 h-5" />
</Button>
</SheetTrigger>
<SheetContent>
<form @submit="onSubmit">
<SheetHeader>
<SheetTitle>Edit code config</SheetTitle>
<SheetDescription>
Configure how the CodeBlock should render on the site.
</SheetDescription>
</SheetHeader>
<div class="my-4">
<!-- <FormField v-slot="{ componentField }" name="prefix">
<FormItem>
<FormLabel>Prefix</FormLabel>
<FormControl>
<Input placeholder="" v-bind="componentField" />
</FormControl>
<FormDescription />
<FormMessage />
</FormItem>
</FormField> -->
<FormField v-slot="{ componentField }" name="componentsPath">
<FormItem>
<FormLabel>Components Path</FormLabel>
<FormControl>
<Input placeholder="@/components" v-bind="componentField" />
</FormControl>
<FormDescription />
<FormMessage />
</FormItem>
</FormField>
<FormField v-slot="{ componentField }" name="utilsPath">
<FormItem>
<FormLabel>Utils Path</FormLabel>
<FormControl>
<Input placeholder="@/utils" v-bind="componentField" />
</FormControl>
<FormDescription />
<FormMessage />
</FormItem>
</FormField>
</div>
<SheetFooter>
<SheetClose as-child>
<Button type="submit">
Save changes
</Button>
</SheetClose>
</SheetFooter>
</form>
</SheetContent>
</Sheet>
</template>

View File

@ -1,10 +1,10 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { ref, toRefs, watch } from 'vue'
import { Icon } from '@iconify/vue'
import { makeCodeSandboxParams } from '../utils/codeeditor'
import Tooltip from './Tooltip.vue'
import { Button } from '@/lib/registry/new-york/ui/button'
import { type Style } from '@/lib/registry/styles'
import type { Style } from '@/lib/registry/styles'
const props = defineProps<{
name: string
@ -12,11 +12,12 @@ const props = defineProps<{
style: Style
}>()
const { code } = toRefs(props)
const sources = ref<Record<string, string>>({})
onMounted(() => {
sources.value['App.vue'] = props.code
})
watch(code, () => {
sources.value['App.vue'] = code.value
}, { immediate: true })
</script>
<template>

View File

@ -0,0 +1,46 @@
import { type VNode, type VNodeArrayChildren, cloneVNode, defineComponent } from 'vue'
import { useConfigStore } from '@/stores/config'
function crawlSpan(children: VNodeArrayChildren, cb: (vnode: VNode) => void) {
children.forEach((childNode) => {
if (!Array.isArray(childNode) && typeof childNode === 'object') {
if (typeof childNode?.children === 'string')
cb(childNode)
else
crawlSpan(childNode?.children as VNodeArrayChildren ?? [], cb)
}
})
}
export default defineComponent(
(props, { slots }) => {
const { codeConfig } = useConfigStore()
return () => {
const clonedVNode = slots.default?.()?.[0]
? cloneVNode(slots.default?.()?.[0], {
key: JSON.stringify(codeConfig.value),
})
: undefined
// @ts-expect-error cloneVNode
const preVNode = [...clonedVNode?.children].find((node: VNode) => node.type === 'pre') as VNode
// @ts-expect-error cloneVNode
const codeVNode = preVNode.children?.at(0) as VNode
if (codeVNode) {
crawlSpan(codeVNode.children as VNodeArrayChildren, (vnode) => {
if (typeof vnode.children === 'string') {
vnode.children = vnode.children.replaceAll('@/components', codeConfig.value.componentsPath)
vnode.children = vnode.children.replaceAll('@/libs', codeConfig.value.utilsPath)
}
})
return clonedVNode
}
else {
return slots.default?.()
}
}
},
)

View File

@ -1,4 +1,8 @@
<script setup lang="ts">
import { ref, watch } from 'vue'
import { codeToHtml } from 'shiki'
import MagicString from 'magic-string'
import { cssVariables } from '../config/shiki'
import StyleSwitcher from './StyleSwitcher.vue'
import ComponentLoader from './ComponentLoader.vue'
import Stackblitz from './Stackblitz.vue'
@ -11,14 +15,35 @@ defineOptions({
inheritAttrs: false,
})
withDefaults(defineProps<{
const props = withDefaults(defineProps<{
name: string
align?: 'center' | 'start' | 'end'
sfcTsCode?: string
sfcTsHtml?: string
}>(), { align: 'center' })
const { style } = useConfigStore()
const { style, codeConfig } = useConfigStore()
const rawString = ref('')
const codeHtml = ref('')
function transformImportPath(code: string) {
const s = new MagicString(code)
s.replaceAll(`@/lib/registry/${style.value}`, codeConfig.value.componentsPath)
s.replaceAll(`@/lib/utils`, codeConfig.value.utilsPath)
return s.toString()
}
watch([style, codeConfig], async () => {
try {
rawString.value = await import(`../../../src/lib/registry/${style.value}/example/${props.name}.vue?raw`).then(res => res.default.trim())
codeHtml.value = await codeToHtml(transformImportPath(rawString.value), {
lang: 'vue',
theme: cssVariables,
})
}
catch (err) {
console.error(err)
}
}, { immediate: true, deep: true })
</script>
<template>
@ -47,8 +72,8 @@ const { style } = useConfigStore()
<StyleSwitcher />
<div class="flex items-center gap-x-1">
<Stackblitz :key="style" :style="style" :name="name" :code="decodeURIComponent(sfcTsCode ?? '')" />
<CodeSandbox :key="style" :style="style" :name="name" :code="decodeURIComponent(sfcTsCode ?? '')" />
<Stackblitz :key="style" :style="style" :name="name" :code="rawString" />
<CodeSandbox :key="style" :style="style" :name="name" :code="rawString" />
</div>
</div>
<div
@ -62,7 +87,7 @@ const { style } = useConfigStore()
</div>
</TabsContent>
<TabsContent value="code">
<div v-if="sfcTsHtml" class="language-vue" style="flex: 1;" v-html="decodeURIComponent(sfcTsHtml)" />
<div v-if="codeHtml" class="language-vue" style="flex: 1;" v-html="codeHtml" />
<slot v-else />
</TabsContent>
</Tabs>

View File

@ -2,7 +2,7 @@
</script>
<template>
<a href="/" class="mr-4 md:mr-2 xl:mr-6 flex items-center lg:space-x1 xl:space-x-2">
<a href="/" class="mr-4 md:mr-2 lg:mr-6 flex items-center lg:space-x1 xl:space-x-2">
<svg class="h-6 w-6" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_102_1338)">
<path d="M208 128L128 208" stroke="#41B883" stroke-width="16" stroke-linecap="round" stroke-linejoin="round" />

View File

@ -1,10 +1,10 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { ref, toRefs, watch } from 'vue'
import { Icon } from '@iconify/vue'
import { makeStackblitzParams } from '../utils/codeeditor'
import Tooltip from './Tooltip.vue'
import { Button } from '@/lib/registry/new-york/ui/button'
import { type Style } from '@/lib/registry/styles'
import type { Style } from '@/lib/registry/styles'
const props = defineProps<{
name: string
@ -12,11 +12,12 @@ const props = defineProps<{
style: Style
}>()
const { code } = toRefs(props)
const sources = ref<Record<string, string>>({})
onMounted(() => {
sources.value['App.vue'] = props.code
})
watch(code, () => {
sources.value['App.vue'] = code.value
}, { immediate: true })
function handleClick() {
makeStackblitzParams(props.name, props.style, sources.value)

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { type SelectTriggerProps } from 'radix-vue'
import type { SelectTriggerProps } from 'radix-vue'
import { useConfigStore } from '@/stores/config'
import { cn } from '@/lib/utils'

View File

@ -1,6 +1,5 @@
<script setup lang="ts">
import { useSlots } from 'vue'
import { TabsContent, TabsTrigger } from '@/lib/registry/default/ui/tabs'
import { TabsContent } from '@/lib/registry/default/ui/tabs'
withDefaults(defineProps<{
title?: string

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed, useSlots } from 'vue'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/lib/registry/default/ui/tabs'
import { Tabs, TabsList, TabsTrigger } from '@/lib/registry/default/ui/tabs'
const slots = useSlots()

View File

@ -1,3 +1,4 @@
export { default as CodeWrapper } from './CodeWrapper'
export { default as ComponentPreview } from './ComponentPreview.vue'
export { default as TabPreview } from './TabPreview.vue'
export { default as TabMarkdown } from './TabMarkdown.vue'

View File

@ -89,6 +89,12 @@ export const docsConfig: DocsConfig = {
title: 'About',
href: '/docs/about',
},
{
title: 'Contribution',
href: '/docs/contribution',
items: [],
label: 'New',
},
],
},
{
@ -161,6 +167,12 @@ export const docsConfig: DocsConfig = {
title: 'Badge',
href: '/docs/components/badge',
},
{
title: 'Breadcrumb',
href: '/docs/components/breadcrumb',
items: [],
label: 'New',
},
{
title: 'Button',
href: '/docs/components/button',

View File

@ -0,0 +1,6 @@
import { createCssVariablesTheme } from 'shiki'
export const cssVariables = createCssVariablesTheme({
variablePrefix: '--shiki-',
variableDefaults: {},
})

View File

@ -4,7 +4,6 @@ import { docsConfig } from '../config/docs'
import TableOfContentVue from '../components/TableOfContent.vue'
import EditLink from '../components/EditLink.vue'
import { ScrollArea } from '@/lib/registry/default/ui/scroll-area'
import { Badge } from '@/lib/registry/default/ui/badge'
import RadixIconsCode from '~icons/radix-icons/code'
import RadixIconsExternalLink from '~icons/radix-icons/external-link'
import ChevronRightIcon from '~icons/lucide/chevron-right'

View File

@ -2,10 +2,10 @@
import { useMagicKeys, useToggle } from '@vueuse/core'
import { onMounted, ref, watch } from 'vue'
import { Content, useData, useRoute, useRouter } from 'vitepress'
import { SearchIcon } from 'lucide-vue-next'
import { type NavItem, docsConfig } from '../config/docs'
import Logo from '../components/Logo.vue'
import MobileNav from '../components/MobileNav.vue'
import CodeConfigCustomizer from '../components/CodeConfigCustomizer.vue'
import Kbd from '../components/Kbd.vue'
import ThemePopover from '../components/ThemePopover.vue'
@ -94,7 +94,7 @@ watch(() => $route.path, (n) => {
<Logo />
<nav
class="flex items-center space-x-6 text-sm font-medium"
class="flex items-center max-lg:space-x-4 space-x-6 text-sm font-medium"
>
<a
v-for="route in docsConfig.mainNav"
@ -120,38 +120,42 @@ watch(() => $route.path, (n) => {
class="relative h-8 w-full justify-start rounded-[0.5rem] bg-background text-sm font-normal text-muted-foreground shadow-none sm:pr-12 md:w-40 lg:w-64"
@click="isOpen = true"
>
<span className="hidden lg:inline-flex">Search documentation...</span>
<span className="inline-flex lg:hidden">Search...</span>
<kbd className="pointer-events-none absolute right-[0.3rem] top-[0.3rem] hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex">
<span className="text-xs"></span>K
</kbd>
<span class="hidden lg:inline-flex">Search documentation...</span>
<span class="inline-flex lg:hidden">Search...</span>
<Kbd class="pointer-events-none absolute right-[0.3rem] top-[0.3rem] hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex">
<span class="text-xs"></span>K
</Kbd>
</Button>
</div>
<nav class="flex items-center gap-x-1">
<nav class="flex items-center">
<ThemePopover />
<CodeConfigCustomizer />
<Button
v-for="link in links"
:key="link.name"
as="a"
class="w-9 h-9"
:href="link.href" target="_blank"
:variant="'ghost'"
:size="'sm'"
:size="'icon'"
>
<component :is="link.icon" class="w-[20px] h-5" />
<component :is="link.icon" class="w-5 h-5" />
</Button>
<ClientOnly>
<Button
class="flex items-center justify-center"
class="w-9 h-9"
aria-label="Toggle dark mode"
:variant="'ghost'"
:size="'icon'" @click="toggleDark()"
:size="'icon'"
@click="toggleDark()"
>
<component
:is="isDark ? RadixIconsSun : RadixIconsMoon"
class="w-[20px] h-5 text-foreground"
class="w-5 h-5 text-foreground"
/>
</Button>
</ClientOnly>
@ -297,4 +301,4 @@ watch(() => $route.path, (n) => {
<NewYorkSonner :theme="'system'" />
<NewYorkToaster />
</div>
</template>
</template>../components/CodeConfigCustomizer.vue

View File

@ -0,0 +1,20 @@
import type { MarkdownRenderer } from 'vitepress'
export default function (md: MarkdownRenderer) {
const defaultFenceRenderer = md.renderer.rules.fence
if (!defaultFenceRenderer)
return
md.renderer.rules.fence = function (tokens, idx, options, env, self) {
// Check if this is a code block
const token = tokens[idx]
const isAllowedExtension = (token.info.includes('vue') || token.info.includes('astro') || token.info.includes('ts'))
if (token && token.tag === 'code' && isAllowedExtension) {
// Wrap the code block in CodeWrapper
return `<CodeWrapper>${defaultFenceRenderer(tokens, idx, options, env, self)}</CodeWrapper>`
}
// If not a code block, return the default rendering
return defaultFenceRenderer(tokens, idx, options, env, self)
}
}

View File

@ -1,7 +1,5 @@
import { dirname, resolve } from 'node:path'
import fs from 'node:fs'
import type { MarkdownEnv, MarkdownRenderer } from 'vitepress'
import { generateDemoComponent, parseProps } from './utils'
import type { MarkdownRenderer } from 'vitepress'
import { parseProps } from './utils'
export default function (md: MarkdownRenderer) {
function addRenderRule(type: string) {
@ -12,31 +10,9 @@ export default function (md: MarkdownRenderer) {
if (!content.match(/^<ComponentPreview\s/) || !content.endsWith('/>'))
return defaultRender!(tokens, idx, options, env, self)
const { path } = env as MarkdownEnv
const props = parseProps(content)
const { name, attrs } = props
const pluginPath = dirname(__dirname)
const srcPath = resolve(pluginPath, '../../src/lib/registry/default/example/', `${name}.vue`).replace(/\\/g, '/')
if (!fs.existsSync(srcPath)) {
console.error(`rendering ${path}: ${srcPath} does not exist`)
return defaultRender!(tokens, idx, options, env, self)
}
let code = fs.readFileSync(srcPath, 'utf-8')
code = code.replaceAll(
'@/lib/registry/default/',
'@/components/',
)
const demoScripts = generateDemoComponent(md, env, {
attrs,
props,
code,
path: srcPath,
})
const { attrs } = props
const demoScripts = `<ComponentPreview ${attrs ?? ''} v-bind='${JSON.stringify(props)}'></ComponentPreview>`.trim()
return demoScripts
}
}

View File

@ -1,6 +1,5 @@
// Credit to @hairyf https://github.com/hairyf/markdown-it-vitepress-demo
import type { MarkdownEnv, MarkdownRenderer } from 'vitepress'
import { baseParse } from '@vue/compiler-core'
import type { AttributeNode, ElementNode } from '@vue/compiler-core'
@ -11,36 +10,6 @@ export interface GenerateOptions {
code: string
}
export function parse(
md: MarkdownRenderer,
env: MarkdownEnv,
{ code, attrs: _attrs, props }: GenerateOptions,
) {
const highlightedHtml = md.options.highlight!(code, 'vue', _attrs || '')
const sfcTsHtml = highlightedHtml
const attrs
= `sfcTsCode="${encodeURIComponent(code)}"\n`
+ `sfcTsHtml="${encodeURIComponent(sfcTsHtml)}"\n`
+ `v-bind='${JSON.stringify(props)}'\n`
return {
attrs,
highlightedHtml,
sfcTsCode: code,
sfcTsHtml,
}
}
export function generateDemoComponent(
md: MarkdownRenderer,
env: MarkdownEnv,
options: GenerateOptions,
) {
const { attrs } = parse(md, env, options)
return `<ComponentPreview \n${attrs}></ComponentPreview>`.trim()
}
export function isUndefined(v: any): v is undefined {
return v === undefined || v === null
}

View File

@ -18,6 +18,7 @@ export function makeCodeSandboxParams(componentName: string, style: Style, sourc
export function makeStackblitzParams(componentName: string, style: Style, sources: Record<string, string>) {
const files: Record<string, string> = {}
Object.entries(constructFiles(componentName, style, sources)).forEach(([k, v]) => (files[`${k}`] = typeof v.content === 'object' ? JSON.stringify(v.content, null, 2) : v.content))
return sdk.openProject({
title: `${componentName} - Radix Vue`,
files,
@ -91,6 +92,7 @@ function constructFiles(componentName: string, style: Style, sources: Record<str
'shadcn-vue': 'latest',
'typescript': 'latest',
'vaul-vue': 'latest',
'vue-sonner': 'latest',
'@unovis/vue': 'latest',
'@unovis/ts': 'latest',
}
@ -104,6 +106,7 @@ function constructFiles(componentName: string, style: Style, sources: Record<str
'autoprefixer': 'latest',
}
// We have static replace here as this is only showing for code reproduction, doesn't need dynamic codeConfig
const transformImportPath = (code: string) => {
let parsed = code
parsed = parsed.replaceAll(`@/lib/registry/${style}`, '@/components')

View File

@ -1 +1 @@
> Files inside this directory is autogenerated by `./scripts/build-registry.ts`. **Do not edit them manually.**
> Files inside this directory is autogenerated by `./scripts/build-registry.ts`. **Do not edit them manually.**

View File

@ -80,12 +80,47 @@ export const Index = {
component: () => import("../src/lib/registry/default/example/BadgeSecondaryDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/BadgeSecondaryDemo.vue"],
},
"BarChartDemo": {
name: "BarChartDemo",
"BreadcrumbDemo": {
name: "BreadcrumbDemo",
type: "components:example",
registryDependencies: ["chart-bar"],
component: () => import("../src/lib/registry/default/example/BarChartDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/BarChartDemo.vue"],
registryDependencies: ["breadcrumb","dropdown-menu"],
component: () => import("../src/lib/registry/default/example/BreadcrumbDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/BreadcrumbDemo.vue"],
},
"BreadcrumbDropdown": {
name: "BreadcrumbDropdown",
type: "components:example",
registryDependencies: ["breadcrumb","dropdown-menu"],
component: () => import("../src/lib/registry/default/example/BreadcrumbDropdown.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/BreadcrumbDropdown.vue"],
},
"BreadcrumbEllipsisDemo": {
name: "BreadcrumbEllipsisDemo",
type: "components:example",
registryDependencies: ["breadcrumb"],
component: () => import("../src/lib/registry/default/example/BreadcrumbEllipsisDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/BreadcrumbEllipsisDemo.vue"],
},
"BreadcrumbLinkDemo": {
name: "BreadcrumbLinkDemo",
type: "components:example",
registryDependencies: ["breadcrumb"],
component: () => import("../src/lib/registry/default/example/BreadcrumbLinkDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/BreadcrumbLinkDemo.vue"],
},
"BreadcrumbResponsive": {
name: "BreadcrumbResponsive",
type: "components:example",
registryDependencies: ["breadcrumb","button","drawer","dropdown-menu"],
component: () => import("../src/lib/registry/default/example/BreadcrumbResponsive.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/BreadcrumbResponsive.vue"],
},
"BreadcrumbSeparatorDemo": {
name: "BreadcrumbSeparatorDemo",
type: "components:example",
registryDependencies: ["breadcrumb"],
component: () => import("../src/lib/registry/default/example/BreadcrumbSeparatorDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/BreadcrumbSeparatorDemo.vue"],
},
"ButtonAsChildDemo": {
name: "ButtonAsChildDemo",
@ -1159,12 +1194,47 @@ export const Index = {
component: () => import("../src/lib/registry/new-york/example/BadgeSecondaryDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/BadgeSecondaryDemo.vue"],
},
"BarChartDemo": {
name: "BarChartDemo",
"BreadcrumbDemo": {
name: "BreadcrumbDemo",
type: "components:example",
registryDependencies: ["chart-bar"],
component: () => import("../src/lib/registry/new-york/example/BarChartDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/BarChartDemo.vue"],
registryDependencies: ["breadcrumb","dropdown-menu"],
component: () => import("../src/lib/registry/new-york/example/BreadcrumbDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/BreadcrumbDemo.vue"],
},
"BreadcrumbDropdown": {
name: "BreadcrumbDropdown",
type: "components:example",
registryDependencies: ["breadcrumb","dropdown-menu"],
component: () => import("../src/lib/registry/new-york/example/BreadcrumbDropdown.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/BreadcrumbDropdown.vue"],
},
"BreadcrumbEllipsisDemo": {
name: "BreadcrumbEllipsisDemo",
type: "components:example",
registryDependencies: ["breadcrumb"],
component: () => import("../src/lib/registry/new-york/example/BreadcrumbEllipsisDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/BreadcrumbEllipsisDemo.vue"],
},
"BreadcrumbLinkDemo": {
name: "BreadcrumbLinkDemo",
type: "components:example",
registryDependencies: ["breadcrumb"],
component: () => import("../src/lib/registry/new-york/example/BreadcrumbLinkDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/BreadcrumbLinkDemo.vue"],
},
"BreadcrumbResponsive": {
name: "BreadcrumbResponsive",
type: "components:example",
registryDependencies: ["breadcrumb","button","drawer","dropdown-menu"],
component: () => import("../src/lib/registry/new-york/example/BreadcrumbResponsive.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/BreadcrumbResponsive.vue"],
},
"BreadcrumbSeparatorDemo": {
name: "BreadcrumbSeparatorDemo",
type: "components:example",
registryDependencies: ["breadcrumb"],
component: () => import("../src/lib/registry/new-york/example/BreadcrumbSeparatorDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/new-york/example/BreadcrumbSeparatorDemo.vue"],
},
"ButtonAsChildDemo": {
name: "ButtonAsChildDemo",

View File

@ -1,7 +1,7 @@
{
"name": "www",
"type": "module",
"version": "0.10.1",
"version": "0.10.2",
"files": [
"dist"
],
@ -18,20 +18,21 @@
"@formkit/auto-animate": "^0.8.1",
"@radix-icons/vue": "^1.0.0",
"@stackblitz/sdk": "^1.9.0",
"@tanstack/vue-table": "^8.13.2",
"@tanstack/vue-table": "^8.14.0",
"@unovis/ts": "^1.3.5",
"@unovis/vue": "^1.3.5",
"@vee-validate/zod": "^4.12.5",
"@vee-validate/zod": "^4.12.6",
"@vueuse/core": "^10.9.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"codesandbox": "^2.2.3",
"date-fns": "^3.3.1",
"date-fns": "^3.6.0",
"embla-carousel": "^8.0.0",
"embla-carousel-autoplay": "^8.0.0",
"embla-carousel-vue": "^8.0.0",
"lucide-vue-next": "^0.350.0",
"radix-vue": "^1.5.0",
"lucide-vue-next": "^0.359.0",
"magic-string": "^0.30.8",
"radix-vue": "^1.5.3",
"tailwindcss-animate": "^1.0.7",
"v-calendar": "^3.1.2",
"vaul-vue": "^0.1.0",
@ -47,9 +48,9 @@
"@iconify-json/tabler": "^1.1.106",
"@iconify/json": "^2.2.189",
"@iconify/vue": "^4.1.1",
"@shikijs/transformers": "^1.1.7",
"@shikijs/transformers": "^1.2.0",
"@types/lodash.template": "^4.5.3",
"@types/node": "^20.11.25",
"@types/node": "^20.11.30",
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@vue/compiler-core": "^3.4.21",
@ -60,14 +61,14 @@
"oxc-parser": "^0.8.0",
"pathe": "^1.1.2",
"rimraf": "^5.0.5",
"shiki": "^1.1.7",
"tailwind-merge": "^2.2.1",
"shiki": "^1.2.0",
"tailwind-merge": "^2.2.2",
"tailwindcss": "^3.4.1",
"tsx": "^4.7.1",
"typescript": "^5.4.2",
"unplugin-icons": "^0.18.5",
"vite": "^5.1.5",
"vite": "^5.2.2",
"vitepress": "^1.0.0-rc.45",
"vue-tsc": "^2.0.6"
"vue-tsc": "^2.0.7"
}
}

View File

@ -0,0 +1,176 @@
<mxfile host="app.diagrams.net" modified="2024-03-15T08:14:00.888Z" agent="Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0" etag="eUNOuIh_rCPXdI6LG0BE" version="24.0.6" type="device">
<diagram name="Page-1" id="10a91c8b-09ff-31b1-d368-03940ed4cc9e">
<mxGraphModel dx="1636" dy="971" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" background="none" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="PaMXV6_IjdSjTMUUNi7L-41" value="" style="rounded=0;whiteSpace=wrap;html=1;fontColor=none;noLabel=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="30" y="70" width="1010" height="680" as="geometry" />
</mxCell>
<mxCell id="62893188c0fa7362-1" value="Shadcn/Vue" style="whiteSpace=wrap;html=1;rounded=1;shadow=0;labelBackgroundColor=none;strokeWidth=1;fontFamily=Garamond;fontSize=17;align=center;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="380" y="130" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="62893188c0fa7362-2" value="Packages" style="whiteSpace=wrap;html=1;rounded=1;shadow=0;labelBackgroundColor=none;strokeWidth=1;fontFamily=Garamond;fontSize=17;align=center;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="160" y="250" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="62893188c0fa7362-3" value="Apps/www" style="whiteSpace=wrap;html=1;rounded=1;shadow=0;labelBackgroundColor=none;strokeWidth=1;fontFamily=Garamond;fontSize=17;align=center;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="630" y="250" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="62893188c0fa7362-4" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;sketch=1;curveFitting=1;jiggle=2;shadow=0;" parent="1" source="PaMXV6_IjdSjTMUUNi7L-27" target="62893188c0fa7362-3" edge="1">
<mxGeometry x="-0.3002" y="13" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="62893188c0fa7362-5" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;sketch=1;curveFitting=1;jiggle=2;shadow=0;" parent="1" source="62893188c0fa7362-1" target="62893188c0fa7362-2" edge="1">
<mxGeometry x="-0.359" y="-11" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="62893188c0fa7362-8" value="Module" style="whiteSpace=wrap;html=1;rounded=1;shadow=0;labelBackgroundColor=none;strokeWidth=1;fontFamily=Garamond;fontSize=17;align=center;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="80" y="360" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="62893188c0fa7362-9" value="CLI" style="whiteSpace=wrap;html=1;rounded=1;shadow=0;labelBackgroundColor=none;strokeWidth=1;fontFamily=Garamond;fontSize=17;align=center;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="220" y="360" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="62893188c0fa7362-14" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;sketch=1;curveFitting=1;jiggle=2;shadow=0;" parent="1" source="62893188c0fa7362-2" target="62893188c0fa7362-8" edge="1">
<mxGeometry x="-0.2" y="-14" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="62893188c0fa7362-15" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;sketch=1;curveFitting=1;jiggle=2;shadow=0;" parent="1" source="62893188c0fa7362-2" target="62893188c0fa7362-9" edge="1">
<mxGeometry x="-0.2" y="14" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="62893188c0fa7362-16" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;entryX=0.75;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;shadow=0;" parent="1" source="62893188c0fa7362-3" target="PaMXV6_IjdSjTMUUNi7L-2" edge="1">
<mxGeometry x="-0.2614" y="-13" relative="1" as="geometry">
<mxPoint as="offset" />
<mxPoint x="644.5454545454545" y="360" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="62893188c0fa7362-17" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;entryX=0.25;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;shadow=0;" parent="1" source="62893188c0fa7362-3" target="PaMXV6_IjdSjTMUUNi7L-1" edge="1">
<mxGeometry x="-0.1294" y="17" relative="1" as="geometry">
<mxPoint as="offset" />
<mxPoint x="782.7272727272725" y="360" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-1" value="Registry" style="whiteSpace=wrap;html=1;rounded=1;shadow=0;labelBackgroundColor=none;strokeWidth=1;fontFamily=Garamond;fontSize=17;align=center;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="720" y="370" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-2" value=".vitepress" style="whiteSpace=wrap;html=1;rounded=1;shadow=0;labelBackgroundColor=none;strokeWidth=1;fontFamily=Garamond;fontSize=17;align=center;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="420" y="370" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-3" value="Scripts" style="whiteSpace=wrap;html=1;rounded=1;shadow=0;labelBackgroundColor=none;strokeWidth=1;fontFamily=Garamond;fontSize=17;align=center;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="870" y="370" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-4" value="Src" style="whiteSpace=wrap;html=1;rounded=1;shadow=0;labelBackgroundColor=none;strokeWidth=1;fontFamily=Garamond;fontSize=17;align=center;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="570" y="370" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-7" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;entryX=0.333;entryY=0.017;entryDx=0;entryDy=0;exitX=1;exitY=1;exitDx=0;exitDy=0;entryPerimeter=0;sketch=1;curveFitting=1;jiggle=2;shadow=0;" edge="1" parent="1" source="62893188c0fa7362-3" target="PaMXV6_IjdSjTMUUNi7L-3">
<mxGeometry x="-0.1294" y="17" relative="1" as="geometry">
<mxPoint as="offset" />
<mxPoint x="841" y="270" as="sourcePoint" />
<mxPoint x="910" y="320" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-9" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.358;exitY=1.017;exitDx=0;exitDy=0;exitPerimeter=0;sketch=1;curveFitting=1;jiggle=2;shadow=0;" edge="1" parent="1" source="62893188c0fa7362-3" target="PaMXV6_IjdSjTMUUNi7L-4">
<mxGeometry x="-0.2614" y="-13" relative="1" as="geometry">
<mxPoint as="offset" />
<mxPoint x="720" y="540" as="sourcePoint" />
<mxPoint x="613" y="600" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-11" value="Content" style="whiteSpace=wrap;html=1;rounded=1;shadow=0;labelBackgroundColor=none;strokeWidth=1;fontFamily=Garamond;fontSize=17;align=center;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="420" y="500" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-12" value="Examples" style="whiteSpace=wrap;html=1;rounded=1;shadow=0;labelBackgroundColor=none;strokeWidth=1;fontFamily=Garamond;fontSize=17;align=center;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="570" y="500" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-13" value="Lib/Registry" style="whiteSpace=wrap;html=1;rounded=1;shadow=0;labelBackgroundColor=none;strokeWidth=1;fontFamily=Garamond;fontSize=17;align=center;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="720" y="500" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-14" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.308;exitY=1.033;exitDx=0;exitDy=0;exitPerimeter=0;sketch=1;curveFitting=1;jiggle=2;shadow=0;" edge="1" parent="1" source="PaMXV6_IjdSjTMUUNi7L-4" target="PaMXV6_IjdSjTMUUNi7L-11">
<mxGeometry x="-0.2614" y="-13" relative="1" as="geometry">
<mxPoint as="offset" />
<mxPoint x="560" y="470" as="sourcePoint" />
<mxPoint x="507" y="529" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-15" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;sketch=1;curveFitting=1;jiggle=2;shadow=0;" edge="1" parent="1" source="PaMXV6_IjdSjTMUUNi7L-4" target="PaMXV6_IjdSjTMUUNi7L-12">
<mxGeometry x="-0.2614" y="-13" relative="1" as="geometry">
<mxPoint as="offset" />
<mxPoint x="657" y="442" as="sourcePoint" />
<mxPoint x="540" y="560" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-16" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.75;exitY=1;exitDx=0;exitDy=0;sketch=1;curveFitting=1;jiggle=2;shadow=0;" edge="1" parent="1" source="PaMXV6_IjdSjTMUUNi7L-4" target="PaMXV6_IjdSjTMUUNi7L-13">
<mxGeometry x="-0.2614" y="-13" relative="1" as="geometry">
<mxPoint as="offset" />
<mxPoint x="660" y="435" as="sourcePoint" />
<mxPoint x="660" y="555" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-20" value="Default" style="rounded=1;whiteSpace=wrap;html=1;fontFamily=Garamond;fontSize=17;sketch=1;curveFitting=1;jiggle=2;shadow=0;" vertex="1" parent="1">
<mxGeometry x="650" y="630" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-21" value="New York" style="rounded=1;whiteSpace=wrap;html=1;fontFamily=Garamond;fontSize=17;sketch=1;curveFitting=1;jiggle=2;shadow=0;" vertex="1" parent="1">
<mxGeometry x="800" y="630" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-22" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;sketch=1;curveFitting=1;jiggle=2;shadow=0;" edge="1" parent="1" source="PaMXV6_IjdSjTMUUNi7L-13" target="PaMXV6_IjdSjTMUUNi7L-20">
<mxGeometry x="-0.2614" y="-13" relative="1" as="geometry">
<mxPoint as="offset" />
<mxPoint x="730" y="670" as="sourcePoint" />
<mxPoint x="530" y="818" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-23" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;sketch=1;curveFitting=1;jiggle=2;shadow=0;" edge="1" parent="1" source="PaMXV6_IjdSjTMUUNi7L-13" target="PaMXV6_IjdSjTMUUNi7L-21">
<mxGeometry x="-0.2614" y="-13" relative="1" as="geometry">
<mxPoint as="offset" />
<mxPoint x="790" y="670" as="sourcePoint" />
<mxPoint x="750" y="820" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-26" value="1" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;sketch=1;curveFitting=1;jiggle=2;fontFamily=Garamond;fontSize=21;" vertex="1" parent="1">
<mxGeometry x="140" y="230" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-28" value="3" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;sketch=1;curveFitting=1;jiggle=2;fontFamily=Garamond;fontSize=21;" vertex="1" parent="1">
<mxGeometry x="400" y="350" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-29" value="4" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;sketch=1;curveFitting=1;jiggle=2;fontFamily=Garamond;fontSize=21;" vertex="1" parent="1">
<mxGeometry x="550" y="350" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-30" value="5" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;sketch=1;curveFitting=1;jiggle=2;fontFamily=Garamond;fontSize=21;" vertex="1" parent="1">
<mxGeometry x="700" y="350" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-31" value="6" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;sketch=1;curveFitting=1;jiggle=2;fontFamily=Garamond;fontSize=21;" vertex="1" parent="1">
<mxGeometry x="850" y="350" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-32" value="7" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;sketch=1;curveFitting=1;jiggle=2;fontFamily=Garamond;fontSize=21;" vertex="1" parent="1">
<mxGeometry x="400" y="480" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-33" value="8" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;sketch=1;curveFitting=1;jiggle=2;fontFamily=Garamond;fontSize=21;" vertex="1" parent="1">
<mxGeometry x="550" y="480" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-34" value="9" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;sketch=1;curveFitting=1;jiggle=2;fontFamily=Garamond;fontSize=21;" vertex="1" parent="1">
<mxGeometry x="700" y="480" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-36" value="10" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;sketch=1;curveFitting=1;jiggle=2;fontFamily=Garamond;fontSize=21;" vertex="1" parent="1">
<mxGeometry x="630" y="610" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-38" value="11" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;sketch=1;curveFitting=1;jiggle=2;fontFamily=Garamond;fontSize=21;" vertex="1" parent="1">
<mxGeometry x="780" y="610" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-39" value="" style="rounded=0;html=1;labelBackgroundColor=none;startArrow=none;startFill=0;startSize=5;endArrow=none;endFill=0;endSize=5;jettySize=auto;orthogonalLoop=1;strokeWidth=1;fontFamily=Garamond;fontSize=17;sketch=1;curveFitting=1;jiggle=2;shadow=0;" edge="1" parent="1" source="62893188c0fa7362-1" target="PaMXV6_IjdSjTMUUNi7L-27">
<mxGeometry x="-0.3002" y="13" relative="1" as="geometry">
<mxPoint as="offset" />
<mxPoint x="500" y="189" as="sourcePoint" />
<mxPoint x="630" y="251" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="PaMXV6_IjdSjTMUUNi7L-27" value="2" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;sketch=1;curveFitting=1;jiggle=2;fontFamily=Garamond;fontSize=21;" vertex="1" parent="1">
<mxGeometry x="610" y="230" width="40" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@ -24,7 +24,7 @@ Where is your global CSS file? src/index.css
Do you want to use CSS variables for colors? no / yes
Where is your tailwind.config.js located? tailwind.config.js
Configure the import alias for components: @/components
Configure the import alias for utils: @/lib/utils
Configure the import alias for utils: @/lib/utils
```
### Options
@ -101,4 +101,4 @@ Arguments:
Options:
-c, --cwd <cwd> the working directory. (default: the current directory)
-h, --help display help for command
```
```

View File

@ -89,7 +89,6 @@ This is used to generate the default color palette for your components. **This c
}
```
### tailwind.cssVariables
You can choose between using CSS variables or Tailwind CSS utility classes for theming.
@ -109,7 +108,6 @@ For more information, see the [theming docs](/docs/theming).
**This cannot be changed after initialization.** To switch between CSS variables and utility classes, you'll have to delete and re-install your components.
## aliases
The CLI uses these values and the `paths` config from your `tsconfig.json` or `jsconfig.json` file to place generated components in the correct location.
@ -117,7 +115,6 @@ The CLI uses these values and the `paths` config from your `tsconfig.json` or `j
Path aliases have to be set up in your `tsconfig.json` or `jsconfig.json` file.
> A fallback to `tsconfig.app.json` if no `paths` were found in `tsconfig.json`
<Callout class="mt-6">
@ -126,7 +123,6 @@ Path aliases have to be set up in your `tsconfig.json` or `jsconfig.json` file.
</Callout>
### aliases.utils
Import alias for your utility functions.

View File

@ -1,15 +1,13 @@
---
title: Accordion
description: A vertically stacked set of interactive headings that each reveal a section of content.
source: apps/www/src/lib/registry/default/ui/accordion
description: A vertically stacked set of interactive headings that each reveal a section of content.
source: apps/www/src/lib/registry/default/ui/accordion
primitive: https://www.radix-vue.com/components/accordion.html
---
<ComponentPreview name="AccordionDemo" class="sm:max-w-[70%]" />
## Installation
<Steps>
@ -46,9 +44,8 @@ module.exports = {
},
}
```
</Steps>
## Usage
@ -68,4 +65,3 @@ import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/
</Accordion>
</template>
```

View File

@ -1,21 +1,18 @@
---
title: Alert Dialog
description: A modal dialog that interrupts the user with important content and expects a response.
source: apps/www/src/lib/registry/default/ui/alert-dialog
source: apps/www/src/lib/registry/default/ui/alert-dialog
primitive: https://www.radix-vue.com/components/alert-dialog.html
---
<ComponentPreview name="AlertDialogDemo" />
## Installation
<ComponentPreview name="AlertDialogDemo" />
## Installation
```bash
npx shadcn-vue@latest add alert-dialog
```
## Usage
```vue
@ -51,4 +48,4 @@ import {
</AlertDialogContent>
</AlertDialog>
</template>
```
```

View File

@ -3,16 +3,14 @@ title: Alert
description: Displays a callout for user attention.
---
<ComponentPreview name="AlertDemo" />
<ComponentPreview name="AlertDemo" />
## Installation
```bash
npx shadcn-vue@latest add alert
```
## Usage
```vue
@ -34,11 +32,8 @@ import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
### Default
<ComponentPreview name="AlertDemo" />
<ComponentPreview name="AlertDemo" />
### Destructive
<ComponentPreview name="AlertDestructiveDemo" />
<ComponentPreview name="AlertDestructiveDemo" />

View File

@ -1,11 +1,10 @@
---
title: Aspect Ratio
description: Displays content within a desired ratio.
source: apps/www/src/lib/registry/default/ui/aspect-ratio
source: apps/www/src/lib/registry/default/ui/aspect-ratio
primitive: https://www.radix-vue.com/components/aspect-ratio.html
---
<ComponentPreview name="AspectRatioDemo" />
## Installation
@ -51,4 +50,4 @@ import { AspectRatio } from '@/components/ui/aspect-ratio'
</AspectRatio>
</div>
</template>
```
```

View File

@ -1,20 +1,17 @@
---
title: Avatar
description: An image element with a fallback for representing the user.
source: apps/www/src/lib/registry/default/ui/avatar
source: apps/www/src/lib/registry/default/ui/avatar
primitive: https://www.radix-vue.com/components/avatar.html
---
<ComponentPreview name="AvatarDemo" />
<ComponentPreview name="AvatarDemo" />
## Installation
```bash
npx shadcn-vue@latest add avatar
```
```
## Usage
@ -29,4 +26,4 @@ import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
<AvatarFallback>CN</AvatarFallback>
</Avatar>
</template>
```
```

View File

@ -3,8 +3,7 @@ title: Badge
description: Displays a badge or a component that looks like a badge.
---
<ComponentPreview name="BadgeDemo" />
<ComponentPreview name="BadgeDemo" />
## Installation
@ -80,13 +79,11 @@ import { Badge } from '@/components/ui/badge'
</template>
```
## Examples
### Default
<ComponentPreview name="BadgeDemo" />
<ComponentPreview name="BadgeDemo" />
### Secondary
@ -98,4 +95,4 @@ import { Badge } from '@/components/ui/badge'
### Destructive
<ComponentPreview name="BadgeDestructiveDemo" />
<ComponentPreview name="BadgeDestructiveDemo" />

View File

@ -0,0 +1,205 @@
---
title: Breadcrumb
description: Displays the path to the current resource using a hierarchy of links.
---
<ComponentPreview name="BreadcrumbDemo" class="[&_.preview]:p-2" />
## Installation
```bash
npx shadcn-vue@latest add breadcrumb
```
## Usage
```vue
<script setup lang="ts">
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/lib/components/ui/breadcrumb'
</script>
<template>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">
Home
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="/components">
Components
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</template>
```
## Examples
### Custom separator
Use a custom component as `slot` for `<BreadcrumbSeparator />` to create a custom separator.
<ComponentPreview name="BreadcrumbSeparatorDemo" />
```vue showLineNumbers {2,20-22}
<script setup lang="ts">
import { Slash } from 'lucide-react'
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbSeparator,
} from '@/lib/components/ui/breadcrumb'
</script>
<template>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">
Home
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator>
<Slash />
</BreadcrumbSeparator>
<BreadcrumbItem>
<BreadcrumbLink href="/components">
Components
</BreadcrumbLink>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</template>
```
---
### Dropdown
You can compose `<BreadcrumbItem />` with a `<DropdownMenu />` to create a dropdown in the breadcrumb.
<ComponentPreview name="BreadcrumbDropdown" class="[&_.preview]:p-2" />
```vue showLineNumbers {2-7,16-26}
<script setup lang="ts">
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/lib/components/ui/dropdown-menu'
import { BreadcrumbItem } from '@/lib/components/ui/breadcrumb'
import ChevronDownIcon from '~icons/radix-icons/chevron-down'
</script>
<template>
<BreadcrumbItem>
<DropdownMenu>
<DropdownMenuTrigger class="flex items-center gap-1">
Components
<ChevronDownIcon />
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuItem>Documentation</DropdownMenuItem>
<DropdownMenuItem>Themes</DropdownMenuItem>
<DropdownMenuItem>GitHub</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</BreadcrumbItem>
</template>
```
---
### Collapsed
We provide a `<BreadcrumbEllipsis />` component to show a collapsed state when the breadcrumb is too long.
<ComponentPreview name="BreadcrumbEllipsisDemo" class="[&_.preview]:p-2" />
```vue showLineNumbers {3,15}
<script setup lang="ts">
import {
Breadcrumb,
BreadcrumbEllipsis,
BreadcrumbItem,
BreadcrumbList,
} from '@/lib/components/ui/breadcrumb'
</script>
<template>
<Breadcrumb>
<BreadcrumbList>
<!-- ... -->
<BreadcrumbItem>
<BreadcrumbEllipsis />
</BreadcrumbItem>
<!-- ... -->
</BreadcrumbList>
</Breadcrumb>
</template>
```
---
### Link component
To use a custom link component from your routing library, you can use the `asChild` prop on `<BreadcrumbLink />`.
<ComponentPreview name="BreadcrumbLinkDemo" />
```vue showLineNumbers {15-19}
<script setup lang="ts">
import { RouterLink } from 'vue-router'
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
} from '@/lib/components/ui/breadcrumb'
</script>
<template>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink as-child>
<RouterLink to="/">
Home
</RouterLink>
</BreadcrumbLink>
</BreadcrumbItem>
<!-- -->
</BreadcrumbList>
</Breadcrumb>
</template>
```
---
### Responsive
Here's an example of a responsive breadcrumb that composes `<BreadcrumbItem />` with `<BreadcrumbEllipsis />`, `<DropdownMenu />`, and `<Drawer />`.
It displays a dropdown on desktop and a drawer on mobile.
<ComponentPreview name="BreadcrumbResponsive" class="[&_.preview]:p-2" />

View File

@ -3,8 +3,7 @@ title: Button
description: Displays a button or a component that looks like a button.
---
<ComponentPreview name="ButtonDemo" />
<ComponentPreview name="ButtonDemo" />
## Installation
@ -94,24 +93,20 @@ import { Button } from '@/components/ui/button'
</template>
```
## Examples
### Primary
<ComponentPreview name="ButtonDemo" />
<ComponentPreview name="ButtonDemo" />
### Secondary
<ComponentPreview name="ButtonSecondaryDemo" />
### Destructive
<ComponentPreview name="ButtonDestructiveDemo" />
### Outline
<ComponentPreview name="ButtonOutlineDemo" />
@ -138,4 +133,4 @@ import { Button } from '@/components/ui/button'
### As Child
<ComponentPreview name="ButtonAsChildDemo" />
<ComponentPreview name="ButtonAsChildDemo" />

View File

@ -1,12 +1,11 @@
---
title: Calendar
description: A date field component that allows users to enter and edit date.
source: apps/www/src/lib/registry/default/ui/calendar
source: apps/www/src/lib/registry/default/ui/calendar
primitive: https://vcalendar.io/
---
<ComponentPreview name="CalendarDemo" />
<ComponentPreview name="CalendarDemo" />
## About
@ -34,13 +33,10 @@ npm install v-calendar
### Copy and paste the following code into your project
<<< @/lib/registry/default/ui/calendar/Calendar.vue
</Steps>
</template>
</TabPreview>
@ -92,4 +88,4 @@ import { Calendar } from '@/components/ui/calendar'
</template>
</Calendar>
</template>
```
```

View File

@ -3,16 +3,13 @@ title: Card
description: Displays a card with header, content, and footer.
---
<ComponentPreview name="CardFormDemo" />
<ComponentPreview name="CardFormDemo" />
## Installation
```bash
npx shadcn-vue@latest add card
```
```
## Usage
@ -46,4 +43,4 @@ import {
## Examples
<ComponentPreview name="CardDemo" />
<ComponentPreview name="CardDemo" />

View File

@ -1,20 +1,17 @@
---
title: Checkbox
description: A control that allows the user to toggle between checked and not checked.
source: apps/www/src/lib/registry/default/ui/checkbox
source: apps/www/src/lib/registry/default/ui/checkbox
primitive: https://www.radix-vue.com/components/checkbox.html
---
<ComponentPreview name="CheckboxDemo" />
<ComponentPreview name="CheckboxDemo" />
## Installation
```bash
npx shadcn-vue@latest add checkbox
```
```
## Usage

View File

@ -1,23 +1,21 @@
---
---
title: Collapsible
description: An interactive component which expands/collapses a panel.
source: apps/www/src/lib/registry/default/ui/collapsible
source: apps/www/src/lib/registry/default/ui/collapsible
primitive: https://www.radix-vue.com/components/collapsible.html
---
<ComponentPreview name="CollapsibleDemo" />
<ComponentPreview name="CollapsibleDemo" />
## Installation
<Steps>
### Run the following command
```bash
npx shadcn-vue@latest add collapsible
```
```
### Update `tailwind.config.js`
@ -46,9 +44,8 @@ module.exports = {
},
}
```
</Steps>
</Steps>
## Usage
@ -73,4 +70,4 @@ const isOpen = ref(false)
</CollapsibleContent>
</Collapsible>
</template>
```
```

View File

@ -1,21 +1,17 @@
---
title: Command
description: Fast, composable, unstyled command menu.
source: apps/www/src/lib/registry/default/ui/command
source: apps/www/src/lib/registry/default/ui/command
primitive: https://www.radix-vue.com/components/combobox.html
---
<ComponentPreview name="CommandDemo" />
<ComponentPreview name="CommandDemo" />
## Installation
```bash
npx shadcn-vue@latest add command
```
```
## Usage
```vue
@ -66,9 +62,9 @@ import {
</template>
```
## Examples
## Examples
### Dialog
### Dialog
<ComponentPreview name="CommandDialogDemo" />

View File

@ -1,18 +1,17 @@
---
---
title: Context Menu
description: Displays a menu to the user — such as a set of actions or functions — triggered by a button.
source: apps/www/src/lib/registry/default/ui/context-menu
source: apps/www/src/lib/registry/default/ui/context-menu
primitive: https://www.radix-vue.com/components/context-menu.html
---
<ComponentPreview name="ContextMenuDemo" />
<ComponentPreview name="ContextMenuDemo" />
## Installation
```bash
npx shadcn-vue@latest add context-menu
```
```
## Usage
@ -46,4 +45,4 @@ import {
</ContextMenuContent>
</ContextMenu>
</template>
```
```

View File

@ -3,8 +3,7 @@ title: Date Picker
description: A date picker component with range and presets.
---
<ComponentPreview name="DatePickerDemo" />
<ComponentPreview name="DatePickerDemo" />
## Installation
@ -53,7 +52,6 @@ const date = ref<Date>()
</template>
```
## Examples
### Date Picker

View File

@ -1,13 +1,12 @@
---
title: Dialog
description: A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
source: apps/www/src/lib/registry/default/ui/dialog
source: apps/www/src/lib/registry/default/ui/dialog
primitive: https://www.radix-vue.com/components/dialog.html
---
<ComponentPreview name="DialogDemo" />
<ComponentPreview name="DialogDemo" />
## Installation
```bash
npx shadcn-vue@latest add dialog
@ -49,11 +48,11 @@ import {
</template>
```
## Examples
## Examples
### Custom close button
<ComponentPreview name="DialogCustomCloseButton" />
<ComponentPreview name="DialogCustomCloseButton" />
### Scroll body
@ -67,7 +66,6 @@ import {
To activate the `Dialog` component from within a `Context Menu` or `Dropdown Menu`, you must encase the `Context Menu` or `Dropdown Menu` component in the `Dialog` component. For more information, refer to the linked issue [here](https://github.com/radix-ui/primitives/issues/1836).
```js:line-numbers showLineNumber{14-25}
<Dialog>
<ContextMenu>

View File

@ -1,18 +1,17 @@
---
title: Hover Card
description: For sighted users to preview content available behind a link.
source: apps/www/src/lib/registry/default/ui/hover-card
source: apps/www/src/lib/registry/default/ui/hover-card
primitive: https://www.radix-vue.com/components/hover-card.html
---
<ComponentPreview name="HoverCardDemo" />
<ComponentPreview name="HoverCardDemo" />
## Installation
```bash
npx shadcn-vue@latest add hover-card
```
```
## Usage
```vue
@ -32,4 +31,4 @@ import {
</HoverCardContent>
</HoverCard>
</template>
```
```

View File

@ -1,12 +1,11 @@
---
title: Label
description: Renders an accessible label associated with controls.
source: apps/www/src/lib/registry/default/ui/label
source: apps/www/src/lib/registry/default/ui/label
primitive: https://www.radix-vue.com/components/label.html
---
<ComponentPreview name="LabelDemo" />
<ComponentPreview name="LabelDemo" />
## Installation
@ -47,4 +46,4 @@ import { Label } from '@/components/ui/label'
<template>
<Label for="email">Your email address</Label>
</template>
```
```

View File

@ -1,14 +1,13 @@
---
title: Menubar
description: A visually persistent menu common in desktop applications that provides quick access to a consistent set of commands.
source: apps/www/src/lib/registry/default/ui/menubar
source: apps/www/src/lib/registry/default/ui/menubar
primitive: https://www.radix-vue.com/components/menubar.html
---
<ComponentPreview name="MenubarDemo" />
<ComponentPreview name="MenubarDemo" />
## Installation
```bash
npx shadcn-vue@latest add menubar
@ -46,4 +45,4 @@ import {
</MenubarMenu>
</Menubar>
</template>
```
```

View File

@ -1,13 +1,13 @@
---
title: Navigation Menu
description: A collection of links for navigating websites.
source: apps/www/src/lib/registry/default/ui/navigation-menu
source: apps/www/src/lib/registry/default/ui/navigation-menu
primitive: https://www.radix-vue.com/components/navigation-menu.html
---
<ComponentPreview name="NavigationMenuDemo" />
<ComponentPreview name="NavigationMenuDemo" />
## Installation
## Installation
```bash
npx shadcn-vue@latest add navigation-menu
@ -43,7 +43,7 @@ import {
</template>
```
## Examples
## Examples
### Link Component
@ -64,4 +64,3 @@ import { navigationMenuTriggerStyle } from '@/components/ui/navigation-menu'
</NavigationMenuItem>
</template>
```

View File

@ -5,15 +5,14 @@ source: apps/www/src/lib/registry/default/ui/pagination
primitive: https://www.radix-vue.com/components/pagination.html
---
<ComponentPreview name="PaginationDemo" />
<ComponentPreview name="PaginationDemo" />
## Installation
```bash
npx shadcn-vue@latest add pagination
```
## Usage
```vue

View File

@ -1,16 +1,14 @@
---
title: Popover
description: Displays rich content in a portal, triggered by a button.
source: apps/www/src/lib/registry/default/ui/popover
source: apps/www/src/lib/registry/default/ui/popover
primitive: https://www.radix-vue.com/components/popover.html
---
<ComponentPreview name="PopoverDemo" />
<ComponentPreview name="PopoverDemo" />
## Installation
```bash
npx shadcn-vue@latest add popover
```
@ -34,4 +32,4 @@ import {
<PopoverContent />
</Popover>
</template>
```
```

View File

@ -1,13 +1,11 @@
---
title: Progress
description: Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.
source: apps/www/src/lib/registry/default/ui/progress
source: apps/www/src/lib/registry/default/ui/progress
primitive: https://www.radix-vue.com/components/progress.html
---
<ComponentPreview name="ProgressDemo" />
<ComponentPreview name="ProgressDemo" />
## Installation
@ -48,4 +46,4 @@ import { Progress } from '@/components/ui/progress'
<template>
<Progress :model-value="33" />
</template>
```
```

View File

@ -1,15 +1,14 @@
---
title: Radio Group
description: A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time.
source: apps/www/src/lib/registry/default/ui/radio-group
source: apps/www/src/lib/registry/default/ui/radio-group
primitive: https://www.radix-vue.com/components/radio-group.html
---
<ComponentPreview name="RadioGroupDemo" />
<ComponentPreview name="RadioGroupDemo" />
## Installation
```bash
npx shadcn-vue@latest add radio-group
```

View File

@ -84,7 +84,7 @@ import {
</script>
<template>
<ResizablePanelGroup direction="horizontal">
<ResizablePanelGroup direction="vertical">
<ResizablePanel>One</ResizablePanel>
<ResizableHandle />
<ResizablePanel>Two</ResizablePanel>

View File

@ -1,15 +1,14 @@
---
title: Scroll-area
description: Augments native scroll functionality for custom, cross-browser styling.
source: apps/www/src/lib/registry/default/ui/scroll-area
source: apps/www/src/lib/registry/default/ui/scroll-area
primitive: https://www.radix-vue.com/components/scroll-area.html
---
<ComponentPreview name="ScrollAreaDemo" />
<ComponentPreview name="ScrollAreaDemo" />
## Installation
```bash
npx shadcn-vue@latest add scroll-area
```
@ -37,4 +36,3 @@ import { ScrollArea } from '@/components/ui/scroll-area'
### Horizontal Scrolling
<ComponentPreview name="ScrollAreaHorizontalDemo" />

View File

@ -1,12 +1,11 @@
---
title: Separator
description: Visually or semantically separates content.
source: apps/www/src/lib/registry/default/ui/separator
source: apps/www/src/lib/registry/default/ui/separator
primitive: https://www.radix-vue.com/components/separator.html
---
<ComponentPreview name="SeparatorDemo" />
<ComponentPreview name="SeparatorDemo" />
## Installation
@ -32,7 +31,6 @@ npm install radix-vue
<<< @/lib/registry/default/ui/separator/Separator.vue
</Steps>
</template>
@ -48,4 +46,4 @@ import { Separator } from '@/components/ui/separator'
<template>
<Separator />
</template>
```
```

View File

@ -1,15 +1,14 @@
---
title: Sheet
description: Extends the Dialog component to display content that complements the main content of the screen.
source: apps/www/src/lib/registry/default/ui/sheet
source: apps/www/src/lib/registry/default/ui/sheet
primitive: https://www.radix-vue.com/components/dialog.html
---
<ComponentPreview name="SheetDemo" />
<ComponentPreview name="SheetDemo" />
## Installation
```bash
npx shadcn-vue@latest add sheet
```
@ -50,8 +49,7 @@ import {
Use the `side` property to `<SheetContent />` to indicate the edge of the screen where the component will appear. The values can be `top`, `right`, `bottom` or `left`.
<ComponentPreview name="SheetSideDemo" />
<ComponentPreview name="SheetSideDemo" />
### Size

View File

@ -2,7 +2,7 @@
title: Sonner
description: An opinionated toast component for Vue.
docs: https://vue-sonner.vercel.app
source: apps/www/src/lib/registry/default/ui/sonner
source: apps/www/src/lib/registry/default/ui/sonner
---
<ComponentPreview name="SonnerDemo" />
@ -34,7 +34,7 @@ import { Toaster } from '@/components/ui/sonner'
<Toaster />
</template>
```
</Steps>
## Usage

View File

@ -1,12 +1,11 @@
---
title: Switch
description: A control that allows the user to toggle between checked and not checked.
source: apps/www/src/lib/registry/default/ui/switch
source: apps/www/src/lib/registry/default/ui/switch
primitive: https://www.radix-vue.com/components/switch.html
---
<ComponentPreview name="SwitchDemo" />
<ComponentPreview name="SwitchDemo" />
## Installation
@ -29,7 +28,7 @@ npm install radix-vue
```
### Copy and paste the following code into your project
<<< @/lib/registry/default/ui/switch/Switch.vue
</Steps>

View File

@ -3,8 +3,7 @@ title: Table
description: A responsive table component.
---
<ComponentPreview name="TableDemo" />
<ComponentPreview name="TableDemo" />
## Installation
@ -64,4 +63,4 @@ You can use the `<Table />` component to build more complex data tables. Combine
See the [Data Table](/docs/components/data-table) documentation for more information.
You can also see an example of a data table in the [Tasks](/examples/tasks) demo.
You can also see an example of a data table in the [Tasks](/examples/tasks) demo.

View File

@ -1,17 +1,14 @@
---
title: Tabs
description: A set of layered sections of content—known as tab panels—that are displayed one at a time.
source: apps/www/src/lib/registry/default/ui/tabs
source: apps/www/src/lib/registry/default/ui/tabs
primitive: https://www.radix-vue.com/components/tabs.html
---
<ComponentPreview name="TabsDemo" />
<ComponentPreview name="TabsDemo" />
## Installation
```bash
npx shadcn-vue@latest add tabs
```
@ -41,4 +38,4 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
</TabsContent>
</Tabs>
</template>
```
```

View File

@ -5,7 +5,7 @@ source: apps/www/src/lib/registry/default/ui/tags-input
primitive: https://www.radix-vue.com/components/tags-input.html
---
<ComponentPreview name="TagsInputDemo" />
<ComponentPreview name="TagsInputDemo" />
## Installation
@ -13,9 +13,8 @@ primitive: https://www.radix-vue.com/components/tags-input.html
npx shadcn-vue@latest add tags-input
```
## Usage
### Tags with Combobox
<ComponentPreview name="TagsInputComboboxDemo" />
<ComponentPreview name="TagsInputComboboxDemo" />

View File

@ -3,8 +3,7 @@ title: Textarea
description: Displays a form textarea or a component that looks like a textarea.
---
<ComponentPreview name="TextareaDemo" />
<ComponentPreview name="TextareaDemo" />
## Installation

View File

@ -1,15 +1,13 @@
---
title: Toast
description: A succinct message that is displayed temporarily.
source: apps/www/src/lib/registry/default/ui/toast
source: apps/www/src/lib/registry/default/ui/toast
primitive: https://www.radix-vue.com/components/toast.html
---
<ComponentPreview name="ToastDemo" />
## Installation
<Steps>
@ -32,9 +30,8 @@ import Toaster from '@/components/ui/toast/Toaster.vue'
<Toaster />
</template>
```
</Steps>
## Usage

View File

@ -5,7 +5,7 @@ source: apps/www/src/lib/registry/default/ui/toggle-group
primitive: https://www.radix-vue.com/components/toggle-group.html
---
<ComponentPreview name="ToggleGroupDemo" />
<ComponentPreview name="ToggleGroupDemo" />
## Installation
@ -60,34 +60,26 @@ import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'
## Examples
### Default
<ComponentPreview name="ToggleGroupDemo" />
### Default
<ComponentPreview name="ToggleGroupDemo" />
### Outline
<ComponentPreview name="ToggleGroupOutlineDemo" />
<ComponentPreview name="ToggleGroupOutlineDemo" />
### Single
<ComponentPreview name="ToggleGroupSingleDemo" />
### Small
<ComponentPreview name="ToggleGroupSmallDemo" />
### Large
<ComponentPreview name="ToggleGroupLargeDemo" />
### Disabled
<ComponentPreview name="ToggleGroupDisabledDemo" />

View File

@ -1,13 +1,11 @@
---
title: Toggle
description: A two-state button that can be either on or off.
source: apps/www/src/lib/registry/default/ui/toggle
source: apps/www/src/lib/registry/default/ui/toggle
primitive: https://www.radix-vue.com/components/toggle.html
---
<ComponentPreview name="ToggleDemo" />
<ComponentPreview name="ToggleDemo" />
## Installation
@ -52,34 +50,26 @@ import { Toggle } from '@/components/ui/toggle'
## Examples
### Default
<ComponentPreview name="ToggleDemo" />
### Default
<ComponentPreview name="ToggleDemo" />
### Outline
<ComponentPreview name="ToggleItalicDemo" />
<ComponentPreview name="ToggleItalicDemo" />
### With Text
<ComponentPreview name="ToggleItalicWithTextDemo" />
### Small
<ComponentPreview name="ToggleSmallDemo" />
### Large
<ComponentPreview name="ToggleLargeDemo" />
### Disabled
<ComponentPreview name="ToggleDisabledDemo" />

View File

@ -1,12 +1,11 @@
---
title: Tooltip
description: A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.
source: apps/www/src/lib/registry/default/ui/tooltip
source: apps/www/src/lib/registry/default/ui/tooltip
primitive: https://www.radix-vue.com/components/tooltip.html
---
<ComponentPreview name="TooltipDemo" />
<ComponentPreview name="TooltipDemo" />
## Installation
@ -36,4 +35,4 @@ import {
</Tooltip>
</TooltipProvider>
</template>
```
```

View File

@ -0,0 +1,341 @@
---
title: Contribution
description: Learn on how to contribute to shadcn/vue.
---
## Introduction
Thanks for your interest in contributing to shadcn-vue.com. We're happy to have you here.
Please take a moment to review this document before submitting your first pull request. We also strongly recommend that you check for open issues and pull requests to see if someone else is working on something similar.
If you need any help, feel free to reach out to the core team on [Discord](https://chat.radix-vue.com/).
This guide provides detailed information to help new contributors.
## About this repository
This repository is a monorepo.
- We use [pnpm](https://pnpm.io) and [`workspaces`](https://pnpm.io/workspaces) for development.
## Project Structure
The GitHub repository consists of the several folders. here's a quick view.
<VPImage
alt="folder-structure"
class="block" :image="{
dark: '/diagrams/structure-dark.svg',
light: '/diagrams/structure-light.svg',
}"
/>
1. **packages** -
Contains source code for supporting `nuxt` as a module and the `cli` to add new components.
2. **apps/www** -
The main folder that holds the source code for the website and every `shadcn/vue` component. This folder contains important sub-folders and is a subproject with its own `package.json`.
3. **.vitepress** -
Contains the configuration and source code for `vitepress` and the `shadcn/vue` website.
4. **src** -
Hosts the main source code for every `shadcn/vue` component or demo and their documentation on the website.
5. **\_\_registry\_\_** -
Holds the registry file generated by `scripts/build-registry.ts` to serve components for the `cli`. This folder's content is auto-generated and should not be edited manually.
6. **scripts** -
Contains various helper scripts, such as `build-registry.ts`, which automatically generates the `__registry__` folder.
7. **content** -
This folder holds all the documentation for the `/docs` route. Each component has one `.md` file documenting the installation and usage of the component.
8. **examples** -
Holds all examples not part of `/docs`, like the [main page](/).
9. **lib/registry** -
The main folder hosts the source code for different styles of every component. This is likely the main folder you'll be changing.
We support two different styles for every component in `shadcn/vue`:
1. Default
2. New York
Every component added to the repository must support both versions, including the main source code and associated demos.
When adding or modifying components, please ensure that:
1. You make the changes for every style.
2. You update the documentation.
3. You run `pnpm build:registry` to update the registry.
## Development
Start by cloning the repository:
```bash
git clone git@github.com:radix-vue/shadcn-vue.git
```
### Install dependencies
```bash
pnpm install
```
### Run a workspace
You can use the `pnpm --filter=[WORKSPACE]` command to start the development process for a workspace or some of the shortcut command that we have setup.
#### Examples
1. To run the `shadcn-vue.com` website:
```
pnpm dev
```
2. To run the `shadcn-vue` cli package:
```
pnpm dev:cli
```
## Documentation
The documentation for this project is located in the `www` workspace. You can run the documentation locally by running the following command:
```bash
pnpm dev
```
Documentation is written using [md](https://vitepress.dev/guide/markdown). You can find the documentation files in the `apps/www/src/content` directory.
## CLI
The `shadcn-vue` package is a CLI for adding components to your project. You can find the documentation for the CLI [here](https://shadcn-vue.com/docs/cli).
Any changes to the CLI should be made in the `packages/cli` directory. If you can, it would be great if you could add tests for your changes.
## Testing
Tests are written using [Vitest](https://vitest.dev). You can run all the tests from the root of the repository.
```bash
pnpm test
```
Please ensure that the tests are passing when submitting a pull request. If you're adding new features, please include tests.
## Commit Convention
Before you create a Pull Request, please check whether your commits comply with
the commit conventions used in this repository.
When you create a commit we kindly ask you to follow the convention
`category(scope or module): message` in your commit message while using one of
the following categories:
- `feat / feature`: all changes that introduce completely new code or new
features
- `fix`: changes that fix a bug (ideally you will additionally reference an
issue if present)
- `refactor`: any code related change that is not a fix nor a feature
- `docs`: changing existing or creating new documentation (i.e. README, docs for
usage of a lib or cli usage)
- `build`: all changes regarding the build of the software, changes to
dependencies or the addition of new dependencies
- `test`: all changes regarding tests (adding new tests or changing existing
ones)
- `ci`: all changes regarding the configuration of continuous integration (i.e.
github actions, ci system)
- `chore`: all changes to the repository that do not fit into any of the above
categories
e.g. `feat(components): add new prop to the avatar component`
If you are interested in the detailed specification you can visit [Conventional Commits](https://www.conventionalcommits.org/).
## SFC - Single File Components
Multiple components are integrated into one file in `shadcn/ui` - the React version of `shadcn` - while Vue only supports one component per file, hence the name Single File Component (SFC). In such cases, you need to create separate files for each component part and then export them all in an `index.ts` file.
See the [`Accordion`](https://github.com/radix-vue/shadcn-vue/tree/v0.10.2/apps/www/src/lib/registry/default/ui/accordion) source code as an example.
## Wrapping Radix-Vue Components
[Radix-Vue](https://www.radix-vue.com) hosts many low-level UI components that are used to build reusable components.
There are many cases that you need to wrap `Radix-Vue` components.
### Props & Events
All of the `Radix-Vue` compoennts expose their prop and emit types. We need to forward any props/events that are coming from outside to the `Radix-Vue` component.
To do so, we have a helper function named [`useForwardPropsEmits`](https://www.radix-vue.com/utilities/use-forward-props-emits.html) that combines props and events that must be binded to the child radix component.
To be more clear, the function `useForwardPropsEmits` takes in props and an optional emit function, and returns a
computed object that combines the parsed props and emits as props.
Here's an example from `Accordian` root component.
```vue
<script setup lang="ts">
import {
AccordionRoot,
type AccordionRootEmits,
type AccordionRootProps,
useForwardPropsEmits,
} from 'radix-vue'
const props = defineProps<AccordionRootProps>()
const emits = defineEmits<AccordionRootEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script>
<template>
<AccordionRoot v-bind="forwarded">
<slot />
</AccordionRoot>
</template>
```
As you can see, `AccordionRootEmits` and `AccordionRootProps` types are imported from radix, combined with `useForwardPropsEmits` and then are binded using `v-bind` syntaxt.
### CSS Classes
There are cases when we want to accept `class` as a prop in our `shadcn/vue` component and then combine it with a default tailwind class on our `radix-vue` component via `cn` utility function.
In these cases, we can not use `v-bind`, because this would lead in [double class binding](https://github.com/radix-vue/shadcn-vue/pull/241).
Take a look at `DrawerDescription.vue`.
```vue
<script lang="ts" setup>
import type { DrawerDescriptionProps } from 'vaul-vue'
import { DrawerDescription } from 'vaul-vue'
import { type HtmlHTMLAttributes, computed } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<DrawerDescriptionProps & { class?: HtmlHTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script>
<template>
<DrawerDescription v-bind="delegatedProps" :class="cn('text-sm text-muted-foreground', props.class)">
<slot />
</DrawerDescription>
</template>
```
As you can see, we have created a computed property named `delegatedProps` to remove `class` from props, and only then bind
the returned value to our radix component (`DrawerDescription` in this case).
As for our class, we first declared it as type of `HtmlHTMLAttributes['class']` and used `cn` to merge tailwind classes from `class` prop and our own classes.
This pattern only needs to be applied when the `cn` utility is required. For instances where there are no default Tailwind classes that need to be merged with user-provided classes, this pattern is not necessary. A good example of this is the `SelectValue.vue` component.
```vue
<script setup lang="ts">
import { SelectValue, type SelectValueProps } from 'radix-vue'
const props = defineProps<SelectValueProps>()
</script>
<template>
<SelectValue v-bind="props">
<slot />
</SelectValue>
</template>
```
### Boolean Props
When you are building a wrapper for a component, in some cases you want to ignore Vue [Props Boolean Casting](https://vuejs.org/guide/components/props.html#boolean-casting).
You can either set default value as undefined for all the boolean field, or you can use [`useForwardProps`](https://www.radix-vue.com/utilities/use-forward-props.html) composable.
Take a look at `AccordionItem.vue`
```vue
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { AccordionItem, type AccordionItemProps, useForwardProps } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<AccordionItemProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps)
</script>
<template>
<AccordionItem
v-bind="forwardedProps"
:class="cn('border-b', props.class)"
>
<slot />
</AccordionItem>
</template>
```
Since `AccordionItemProps` type has atleast one boolean property, we need to use `useForwardProps` on the entire props object.
Note that `useForwardPropsEmits` use `useForwardProps` under the hood.
### Component as Root
Whenever your root component is a `Component` Primitive from vue, it's easier to use [`Primitive`](https://www.radix-vue.com/utilities/primitive.html) instead.
Let's take a look at `Button.vue`
```vue
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { Primitive, type PrimitiveProps } from 'radix-vue'
import { type ButtonVariants, buttonVariants } from '.'
import { cn } from '@/lib/utils'
interface Props extends PrimitiveProps {
variant?: ButtonVariants['variant']
size?: ButtonVariants['size']
class?: HTMLAttributes['class']
}
const props = withDefaults(defineProps<Props>(), {
as: 'button',
})
</script>
<template>
<Primitive
:as="as"
:as-child="asChild"
:class="cn(buttonVariants({ variant, size }), props.class)"
>
<slot />
</Primitive>
</template>
```
You'll need to extend `PrimitiveProps` in your props to support `Primitive` component. In most cases you would also need a default value for [`as`](https://www.radix-vue.com/utilities/primitive.html#changing-as-value) property.
## Debugging
Here are some tools and techniques that can help you debug more effectively while contributing to `shadcn/vue` or developing your own projects.
### Install Vue Dev Tools
To easily inspect component props, attributes, events, and more, you can leverage the [`Vue DevTools`](https://devtools.vuejs.org/) extension for browsers. This extension provides a user-friendly interface for debugging Vue components and can improve your development experience.
### Enable Custom Formmaters
Vue wraps values stored in a `ref` in a way that, when logged, results in a nested object and requires manual inspection to access the value stored in the ref.
You can enable Custom Formatters in your browser to automate this process.
- [Firefox](https://firefox-source-docs.mozilla.org/devtools-user/custom_formatters/index.html)
- Chrome, Edge, Brave and other Chromium based [browsers](https://www.google.com/search?q=how+to+enable+custom++formatter+chrome)

View File

@ -2,7 +2,7 @@
title: Installation
description: How to install dependencies and structure your app.
---
## Frameworks
<div class="grid gap-4 mt-8 sm:grid-cols-2 sm:gap-6 not-docs">
@ -18,7 +18,7 @@ description: How to install dependencies and structure your app.
<path d="m8.286 10.578.512-8.657a.306.306 0 0 1 .247-.282L17.377.006a.306.306 0 0 1 .353.385l-1.558 5.403a.306.306 0 0 0 .352.385l2.388-.46a.306.306 0 0 1 .332.438l-6.79 13.55-.123.19a.294.294 0 0 1-.252.14c-.177 0-.35-.152-.305-.369l1.095-5.301a.306.306 0 0 0-.388-.355l-1.433.435a.306.306 0 0 1-.389-.354l.69-3.375a.306.306 0 0 0-.37-.36l-2.32.536a.306.306 0 0 1-.374-.316zm14.976-7.926L17.284 3.74l-.544 1.887 2.077-.4a.8.8 0 0 1 .84.369.8.8 0 0 1 .034.783L12.9 19.93l-.013.025-.015.023-.122.19a.801.801 0 0 1-.672.37.826.826 0 0 1-.634-.302.8.8 0 0 1-.16-.67l1.029-4.981-1.12.34a.81.81 0 0 1-.86-.262.802.802 0 0 1-.165-.67l.63-3.08-2.027.468a.808.808 0 0 1-.768-.233.81.81 0 0 1-.217-.6l.389-6.57-7.44-1.33a.612.612 0 0 0-.64.906L11.58 23.691a.612.612 0 0 0 1.066-.004l11.26-20.135a.612.612 0 0 0-.644-.9z" />
</svg>
<p class="mt-2 font-medium">Vite</p>
</LinkedCard>
</LinkedCard>
<LinkedCard href="/docs/installation/nuxt">
<svg xmlns="http://www.w3.org/2000/svg" class="w-12 h-12" viewBox="0 0 900 900" fill="none">
<title>Nuxt</title>
@ -53,11 +53,9 @@ description: How to install dependencies and structure your app.
<path d="M61.8548 14.6253C61.8778 14.7102 61.8895 14.7978 61.8897 14.8858V28.5615C61.8898 28.737 61.8434 28.9095 61.7554 29.0614C61.6675 29.2132 61.5409 29.3392 61.3887 29.4265L49.9104 36.0351V49.1337C49.9104 49.4902 49.7209 49.8192 49.4118 49.9987L25.4519 63.7916C25.3971 63.8227 25.3372 63.8427 25.2774 63.8639C25.255 63.8714 25.2338 63.8851 25.2101 63.8913C25.0426 63.9354 24.8666 63.9354 24.6991 63.8913C24.6716 63.8838 24.6467 63.8689 24.6205 63.8589C24.5657 63.8389 24.5084 63.8215 24.456 63.7916L0.501061 49.9987C0.348882 49.9113 0.222437 49.7853 0.134469 49.6334C0.0465019 49.4816 0.000120578 49.3092 0 49.1337L0 8.10652C0 8.01678 0.0124642 7.92953 0.0348998 7.84477C0.0423783 7.8161 0.0598282 7.78993 0.0697995 7.76126C0.0884958 7.70891 0.105946 7.65531 0.133367 7.6067C0.152063 7.5743 0.179485 7.54812 0.20192 7.51821C0.230588 7.47832 0.256763 7.43719 0.290416 7.40229C0.319084 7.37362 0.356476 7.35243 0.388883 7.32751C0.425029 7.29759 0.457436 7.26518 0.498568 7.2415L12.4779 0.345059C12.6296 0.257786 12.8015 0.211853 12.9765 0.211853C13.1515 0.211853 13.3234 0.257786 13.475 0.345059L25.4531 7.2415H25.4556C25.4955 7.26643 25.5292 7.29759 25.5653 7.32626C25.5977 7.35119 25.6339 7.37362 25.6625 7.40104C25.6974 7.43719 25.7224 7.47832 25.7523 7.51821C25.7735 7.54812 25.8021 7.5743 25.8196 7.6067C25.8483 7.65656 25.8645 7.70891 25.8844 7.76126C25.8944 7.78993 25.9118 7.8161 25.9193 7.84602C25.9423 7.93096 25.954 8.01853 25.9542 8.10652V33.7317L35.9355 27.9844V14.8846C35.9355 14.7973 35.948 14.7088 35.9704 14.6253C35.9792 14.5954 35.9954 14.5692 36.0053 14.5405C36.0253 14.4882 36.0427 14.4346 36.0702 14.386C36.0888 14.3536 36.1163 14.3274 36.1375 14.2975C36.1674 14.2576 36.1923 14.2165 36.2272 14.1816C36.2559 14.1529 36.292 14.1317 36.3244 14.1068C36.3618 14.0769 36.3942 14.0445 36.4341 14.0208L48.4147 7.12434C48.5663 7.03694 48.7383 6.99094 48.9133 6.99094C49.0883 6.99094 49.2602 7.03694 49.4118 7.12434L61.3899 14.0208C61.4323 14.0457 61.4647 14.0769 61.5021 14.1055C61.5333 14.1305 61.5694 14.1529 61.5981 14.1803C61.633 14.2165 61.6579 14.2576 61.6878 14.2975C61.7103 14.3274 61.7377 14.3536 61.7551 14.386C61.7838 14.4346 61.8 14.4882 61.8199 14.5405C61.8312 14.5692 61.8474 14.5954 61.8548 14.6253ZM59.893 27.9844V16.6121L55.7013 19.0252L49.9104 22.3593V33.7317L59.8942 27.9844H59.893ZM47.9149 48.5566V37.1768L42.2187 40.4299L25.953 49.7133V61.2003L47.9149 48.5566ZM1.99677 9.83281V48.5566L23.9562 61.199V49.7145L12.4841 43.2219L12.4804 43.2194L12.4754 43.2169C12.4368 43.1945 12.4044 43.1621 12.3682 43.1347C12.3371 43.1097 12.3009 43.0898 12.2735 43.0624L12.271 43.0586C12.2386 43.0275 12.2162 42.9888 12.1887 42.9539C12.1638 42.9203 12.1339 42.8916 12.114 42.8567L12.1127 42.853C12.0903 42.8156 12.0766 42.7707 12.0604 42.7283C12.0442 42.6909 12.023 42.656 12.013 42.6161C12.0005 42.5688 11.998 42.5177 11.9931 42.4691C11.9881 42.4317 11.9781 42.3943 11.9781 42.3569V15.5801L6.18848 12.2446L1.99677 9.83281ZM12.9777 2.36177L2.99764 8.10652L12.9752 13.8513L22.9541 8.10527L12.9752 2.36177H12.9777ZM18.1678 38.2138L23.9574 34.8809V9.83281L19.7657 12.2459L13.9749 15.5801V40.6281L18.1678 38.2138ZM48.9133 9.14105L38.9344 14.8858L48.9133 20.6305L58.8909 14.8846L48.9133 9.14105ZM47.9149 22.3593L42.124 19.0252L37.9323 16.6121V27.9844L43.7219 31.3174L47.9149 33.7317V22.3593ZM24.9533 47.987L39.59 39.631L46.9065 35.4555L36.9352 29.7145L25.4544 36.3242L14.9907 42.3482L24.9533 47.987Z" />
</svg>
<p class="mt-2 font-medium">Laravel</p>
</LinkedCard>
</LinkedCard>
</div>
## TypeScript
This project and the components are written in TypeScript. We recommend using TypeScript for your project as well.
@ -97,11 +95,11 @@ To configure import aliases, you can use the following `jsconfig.json`:
## VSCode extension
Install the [shadcn-vue](https://marketplace.visualstudio.com/items?itemName=Selemondev.shadcn-vue) extension by [@selemondev](https://github.com/selemondev) in Visual Studio Code to easily add Shadcn Vue components to your project.
Install the [shadcn-vue](https://marketplace.visualstudio.com/items?itemName=Selemondev.shadcn-vue) extension by [@selemondev](https://github.com/selemondev) in Visual Studio Code to easily add Shadcn Vue components to your project.
This extension offers a range of features:
- Ability to initialize the Shadcn Vue CLI
- Install components
- Open documentation
- Navigate to a specific component's documentation page directly from your IDE.
- Navigate to a specific component's documentation page directly from your IDE.
- Handy snippets for quick and straightforward component imports and markup.

View File

@ -126,7 +126,7 @@ import '@/styles/globals.css'
To prevent serving the Tailwind base styles twice, we need to tell Astro not to apply the base styles, since we already include them in our own `globals.css` file. To do this, set the `applyBaseStyles` config option for the tailwind plugin in `astro.config.mjs` to `false`.
```ts:line-numbers {3-5}
```ts:line-numbers {3-5}
export default defineConfig({
integrations: [
tailwind({
@ -161,4 +161,4 @@ import { Button } from "@/components/ui/button"
</html>
```
</Steps>
</Steps>

View File

@ -34,7 +34,7 @@ Where is your global CSS file? resources/css/app.css
Do you want to use CSS variables for colors? no / yes
Where is your tailwind.config.js located? tailwind.config.js
Configure the import alias for components: @/Components
Configure the import alias for utils: @/lib/utils
Configure the import alias for utils: @/lib/utils
```
### Update tailwind.config.js
@ -150,4 +150,4 @@ import { Button } from '@/Components/ui/button'
</template>
```
</Steps>
</Steps>

View File

@ -41,7 +41,6 @@ npm install -D @nuxtjs/tailwindcss
</TabMarkdown>
<TabMarkdown title="manual">
Add the following code to `modules/shadcn.ts`.
@ -148,7 +147,6 @@ declare module '@nuxt/schema' {
</TabMarkdown>
</TabsMarkdown>
### Configure `nuxt.config.ts`
```ts
@ -189,7 +187,7 @@ Where is your global CSS file? src/index.css
Do you want to use CSS variables for colors? no / yes
Where is your tailwind.config.js located? tailwind.config.js
Configure the import alias for components: @/components
Configure the import alias for utils: @/lib/utils
Configure the import alias for utils: @/lib/utils
```
### App structure
@ -197,7 +195,7 @@ Configure the import alias for utils: @/lib/utils
Here's the default structure of Nuxt app. You can use this as a reference:
```txt {6-16,20-21}
.
.
├── pages
│ ├── index.vue
│ └── dashboard.vue

View File

@ -21,7 +21,6 @@ _Use this as a reference to build your own component libraries._
## FAQ
<Accordion type="multiple">
<AccordionItem value="faq-1">
@ -58,4 +57,4 @@ Yes. Free to use for personal and commercial projects. No attribution required.
But let us know if you do use it. We'd love to see what you build with it.
</AccordionContent>
</AccordionItem>
</Accordion>
</Accordion>

View File

@ -3,7 +3,6 @@ title: Theming
description: Use CSS Variables to customize the look and feel of your application.
---
You can choose between using CSS variables or Tailwind CSS utility classes for theming.
## Utility classes
@ -37,7 +36,6 @@ To use utility classes for theming set `tailwind.cssVariables` to `false` in you
```
To use CSS variables for theming set `tailwind.cssVariables` to `true` in your `components.json` file.
```json {7} title="components.json"
{
@ -96,64 +94,64 @@ Here's the list of variables available for customization:
--foreground: 222.2 47.4% 11.2%;
```
```css
```css
/* Muted backgrounds such as <TabsList />, <Skeleton /> and <Switch /> */
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
```
```css
```css
/* Background color for <Card /> */
--card: 0 0% 100%;
--card-foreground: 222.2 47.4% 11.2%;
```
```css
```css
/* Background color for popovers such as <DropdownMenu />, <HoverCard />, <Popover /> */
--popover: 0 0% 100%;
--popover-foreground: 222.2 47.4% 11.2%;
```
```css
```css
/* Default border color */
--border: 214.3 31.8% 91.4%;
```
```css
```css
/* Border color for inputs such as <Input />, <Select />, <Textarea /> */
--input: 214.3 31.8% 91.4%;
```
```css
```css
/* Primary colors for <Button /> */
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
```
```css
```css
/* Secondary colors for <Button /> */
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
```
```css
```css
/* Used for accents such as hover effects on <DropdownMenuItem>, <SelectItem>...etc */
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
```
```css
```css
/* Used for destructive actions such as <Button variant="destructive"> */
--destructive: 0 100% 50%;
--destructive-foreground: 210 40% 98%;
```
```css
```css
/* Used for focus ring */
--ring: 215 20.2% 65.1%;
```
```css
```css
/* Border radius for card, input and buttons */
--radius: 0.5rem;
```
@ -201,9 +199,6 @@ I recommend using [HSL colors](https://www.smashingmagazine.com/2021/07/hsl-colo
See the [Tailwind CSS documentation](https://tailwindcss.com/docs/customizing-colors#using-css-variables) for more information on using `rgb`, `rgba` or `hsl` colors.
## Hex -> Color Channel
You can use this tool to convert your HEX color to HSL without the color space function. Simply add your color in hex format, copy one of the generated values, then add them to the CSS variable.

View File

@ -56,4 +56,4 @@ component: true
## Muted
<ComponentPreview name="TypographyMuted" />
<ComponentPreview name="TypographyMuted" />

View File

@ -2,4 +2,4 @@
import AuthenticationExample from "@/examples/authentication/Example.vue"
</script>
<AuthenticationExample />
<AuthenticationExample />

View File

@ -2,4 +2,4 @@
import CardsExample from "@/examples/cards/Example.vue"
</script>
<CardsExample />
<CardsExample />

View File

@ -2,4 +2,4 @@
import DashboardExample from "@/examples/dashboard/Example.vue"
</script>
<DashboardExample />
<DashboardExample />

View File

@ -2,4 +2,4 @@
import AccountExample from "@/examples/forms/Account.vue"
</script>
<AccountExample />
<AccountExample />

View File

@ -2,4 +2,4 @@
import AppearanceExample from "@/examples/forms/Appearance.vue"
</script>
<AppearanceExample />
<AppearanceExample />

View File

@ -2,4 +2,4 @@
import DisplayExample from "@/examples/forms/Display.vue"
</script>
<DisplayExample />
<DisplayExample />

View File

@ -2,4 +2,4 @@
import FormsExample from "@/examples/forms/Example.vue"
</script>
<FormsExample />
<FormsExample />

View File

@ -2,4 +2,4 @@
import NotificationsExample from "@/examples/forms/Notifications.vue"
</script>
<NotificationsExample />
<NotificationsExample />

View File

@ -2,4 +2,4 @@
import MusicExample from "@/examples/music/Example.vue"
</script>
<MusicExample />
<MusicExample />

View File

@ -2,4 +2,4 @@
import PlaygroundExample from "@/examples/playground/Example.vue"
</script>
<PlaygroundExample />
<PlaygroundExample />

View File

@ -2,4 +2,4 @@
import TasksExample from "@/examples/tasks/Example.vue"
</script>
<TasksExample />
<TasksExample />

View File

@ -7,4 +7,4 @@ title: Shadcn for Vue
import LandingPage from "../../.vitepress/theme/components/LandingPage.vue"
</script>
<LandingPage />
<LandingPage />

View File

@ -6,4 +6,4 @@ title: Theming - shadcn-vue
import Theming from "../../.vitepress/theme/components/theming/Theming.vue"
</script>
<Theming />
<Theming />

View File

@ -46,8 +46,8 @@ const debouncedSearch = refDebounced(searchValue, 250)
const filteredMailList = computed(() => {
let output: Mail[] = []
const serachValue = debouncedSearch.value?.trim()
if (!serachValue) {
const searchValue = debouncedSearch.value?.trim()
if (!searchValue) {
output = props.mails
}

View File

@ -91,7 +91,7 @@ const table = useVueTable({
<TableRow v-else>
<TableCell
col-span="{columns.length}"
:colspan="columns.length"
class="h-24 text-center"
>
No results.

View File

@ -0,0 +1,53 @@
<script lang="ts" setup>
import {
Breadcrumb,
BreadcrumbEllipsis,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/lib/registry/default/ui/breadcrumb'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/lib/registry/default/ui/dropdown-menu'
</script>
<template>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">
Home
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<DropdownMenu>
<DropdownMenuTrigger class="flex items-center gap-1">
<BreadcrumbEllipsis class="h-4 w-4" />
<span class="sr-only">Toggle menu</span>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuItem>Documentation</DropdownMenuItem>
<DropdownMenuItem>Themes</DropdownMenuItem>
<DropdownMenuItem>GitHub</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="/docs/components/accordion.html">
Components
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</template>

View File

@ -0,0 +1,51 @@
<script lang="ts" setup>
import { ChevronDown, Slash } from 'lucide-vue-next'
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/lib/registry/default/ui/breadcrumb'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/lib/registry/default/ui/dropdown-menu'
</script>
<template>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">
Home
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator>
<Slash />
</BreadcrumbSeparator>
<BreadcrumbItem>
<DropdownMenu>
<DropdownMenuTrigger class="flex items-center gap-1">
Components
<ChevronDown class="h-4 w-4" />
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuItem>Documentation</DropdownMenuItem>
<DropdownMenuItem>Themes</DropdownMenuItem>
<DropdownMenuItem>GitHub</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</BreadcrumbItem>
<BreadcrumbSeparator>
<Slash />
</BreadcrumbSeparator>
<BreadcrumbItem>
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</template>

View File

@ -0,0 +1,41 @@
<script lang="ts" setup>
import {
Breadcrumb,
BreadcrumbEllipsis,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/lib/registry/default/ui/breadcrumb'
</script>
<template>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink as-child>
<a href="/">
Home
</a>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbEllipsis />
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink as-child>
<a href="/docs/components/accordion.html">
Components
</a>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</template>

View File

@ -0,0 +1,36 @@
<script lang="ts" setup>
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/lib/registry/default/ui/breadcrumb'
</script>
<template>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink>
<a href="/">
Home
</a>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink>
<a href="/docs/components/accordion.html">
Components
</a>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</template>

View File

@ -0,0 +1,125 @@
<script lang="ts" setup>
import { useMediaQuery } from '@vueuse/core'
import { computed, ref } from 'vue'
import {
Breadcrumb,
BreadcrumbEllipsis,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/lib/registry/default/ui/breadcrumb'
import { Button } from '@/lib/registry/default/ui/button'
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from '@/lib/registry/default/ui/drawer'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/lib/registry/default/ui/dropdown-menu'
const isDesktop = useMediaQuery('(min-width: 768px)')
const isOpen = ref(false)
const items = ref([
{ href: '#', label: 'Home' },
{ href: '#', label: 'Documentation' },
{ href: '#', label: 'Building Your Application' },
{ href: '#', label: 'Data Fetching' },
{ label: 'Caching and Revalidating' },
])
const itemsToDisplay = 3
const firstLabel = computed(() => items.value[0]?.label)
const allButLastTwoItems = computed(() => items.value.slice(1, -2))
const remainingItems = computed(() => items.value.slice(-itemsToDisplay + 1))
</script>
<template>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="{items[0].href}">
{{ firstLabel }}
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<template v-if="items.length > itemsToDisplay">
<BreadcrumbItem>
<DropdownMenu v-if="isDesktop" v-model:open="isOpen">
<DropdownMenuTrigger
class="flex items-center gap-1"
aria-label="Toggle menu"
>
<BreadcrumbEllipsis class="h-4 w-4" />
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuItem v-for="item of allButLastTwoItems" :key="item.label">
<a :href="item.href || '#'">
{{ item.label }}
</a>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<Drawer v-else v-model:open="isOpen">
<DrawerTrigger aria-label="Toggle Menu">
<BreadcrumbEllipsis class="h-4 w-4" />
</DrawerTrigger>
<DrawerContent>
<DrawerHeader class="text-left">
<DrawerTitle>Navigate to</DrawerTitle>
<DrawerDescription>
Select a page to navigate to.
</DrawerDescription>
</DrawerHeader>
<div class="grid gap-1 px-4">
<a
v-for="item of allButLastTwoItems"
:key="item.label"
:href="item.href"
class="py-1 text-sm"
>
{{ item.label }}
</a>
</div>
<DrawerFooter class="pt-4">
<DrawerClose as-child>
<Button variant="outline">
Close
</Button>
</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>
</BreadcrumbItem>
<BreadcrumbSeparator />
</template>
<BreadcrumbItem v-for=" item of remainingItems" :key="item.label">
<template v-if="item.href">
<BreadcrumbLink
as-child
class="max-w-20 truncate md:max-w-none"
>
<a :href="item.href">
{{ item.label }}
</a>
</BreadcrumbLink>
<BreadcrumbSeparator />
</template>
<BreadcrumbPage v-else class="max-w-20 truncate md:max-w-none">
{{ item.label }}
</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</template>

View File

@ -0,0 +1,37 @@
<script lang="ts" setup>
import { Slash } from 'lucide-vue-next'
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/lib/registry/default/ui/breadcrumb'
</script>
<template>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">
Home
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator>
<Slash />
</BreadcrumbSeparator>
<BreadcrumbItem>
<BreadcrumbLink href="/docs/components/accordion.html">
Components
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator>
<Slash />
</BreadcrumbSeparator>
<BreadcrumbItem>
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</template>

View File

@ -221,7 +221,7 @@ const table = useVueTable({
<TableRow v-else>
<TableCell
:col-span="columns.length"
:colspan="columns.length"
class="h-24 text-center"
>
No results.

View File

@ -1,6 +1,5 @@
<script setup lang="ts">
import type {
ColumnDef,
ColumnFiltersState,
SortingState,
VisibilityState,
@ -233,7 +232,7 @@ const table = useVueTable({
<TableRow v-else>
<TableCell
col-span="{columns.length}"
:colspan="columns.length"
class="h-24 text-center"
>
No results.

View File

@ -214,7 +214,7 @@ const table = useVueTable({
<TableRow v-else>
<TableCell
col-span="{columns.length}"
:colspan="columns.length"
class="h-24 text-center"
>
No results.

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { MagnifyingGlassIcon } from '@radix-icons/vue'
import { Search } from 'lucide-vue-next'
import { Input } from '@/lib/registry/default/ui/input'
</script>
@ -7,7 +7,7 @@ import { Input } from '@/lib/registry/default/ui/input'
<div class="relative w-full max-w-sm items-center">
<Input id="search" type="text" placeholder="Search..." class="pl-10" />
<span class="absolute start-0 inset-y-0 flex items-center justify-center px-2">
<MagnifyingGlassIcon class="size-6 text-muted-foreground" />
<Search class="size-6 text-muted-foreground" />
</span>
</div>
</template>

View File

@ -10,7 +10,7 @@ import {
navigationMenuTriggerStyle,
} from '@/lib/registry/default/ui/navigation-menu'
const components: { title: string; href: string; description: string }[] = [
const components: { title: string, href: string, description: string }[] = [
{
title: 'Alert Dialog',
href: '/docs/primitives/alert-dialog',

View File

@ -4,7 +4,7 @@ import {
NavigationMenuLink,
} from '@/lib/registry/default/ui/navigation-menu'
defineProps<{ title?: string; href?: string }>()
defineProps<{ title?: string, href?: string }>()
</script>
<template>

Some files were not shown because too many files have changed in this diff Show More