Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18040192c8 | ||
|
|
d7c4f34bab | ||
|
|
b5cf49e8ae | ||
|
|
4d87066777 | ||
|
|
5eee449df5 | ||
|
|
8a8d1ef20a | ||
|
|
3f0ded8e7f | ||
|
|
b8f60e6883 | ||
|
|
20bb9c612b | ||
|
|
69fbfb3545 | ||
|
|
2326784ba0 | ||
|
|
dc5c3fbb3c | ||
|
|
124f28240e | ||
|
|
47c4fbf815 | ||
|
|
8fec27eed4 | ||
|
|
b4e1135b15 | ||
|
|
b3e10e480f | ||
|
|
ec790cb5ba | ||
|
|
6d2515f02a | ||
|
|
d963607719 | ||
|
|
41d836335f | ||
|
|
99c685e411 | ||
|
|
360e55fd3d | ||
|
|
bb5d5b2a71 | ||
|
|
097830a15c | ||
|
|
01808de25c | ||
|
|
ec54afa796 | ||
|
|
aec80c9342 | ||
|
|
ac14ca835a | ||
|
|
5ff0b20ac2 | ||
|
|
8cd51af246 | ||
|
|
6927943477 | ||
|
|
f3f84b8e4e | ||
|
|
5c4b16c76b | ||
|
|
da5f36227f | ||
|
|
215e365d16 | ||
|
|
5ff9cda0aa | ||
|
|
19aacd90f2 | ||
|
|
f079f0161b | ||
|
|
f878cd1140 | ||
|
|
d2b3a8783c |
4
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
4
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
|
|
@ -10,8 +10,8 @@ body:
|
|||
This form is only for submitting bug reports. If you have a usage question
|
||||
or are unsure if this is really a bug, make sure to:
|
||||
|
||||
- Read the [docs](https://radix-vue.com/)
|
||||
- Ask on [Discord Chat](https://chat.radix-vue.com/)
|
||||
- Read the [docs](https://reka-ui.com/)
|
||||
- Ask on [Discord Chat](https://chat.unovue.com/)
|
||||
- Ask on [GitHub Discussions](https://github.com/shadcn-vue/shadcn-vue/discussions)
|
||||
- type: input
|
||||
id: reproduction
|
||||
|
|
|
|||
4
.github/ISSUE_TEMPLATE/config.yml
vendored
4
.github/ISSUE_TEMPLATE/config.yml
vendored
|
|
@ -1,8 +1,8 @@
|
|||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
# - name: 📚 Documentation
|
||||
# url: https://www.radix-vue.com/
|
||||
# url: https://www.reka-ui.com/
|
||||
# about: Check the documentation for usage of Radix Vue.
|
||||
- name: 🗨️ Discord
|
||||
url: https://chat.radix-vue.com/
|
||||
url: https://chat.unovue.com/
|
||||
about: Join the Radix Vue Discord server.
|
||||
|
|
|
|||
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
|
|
@ -11,7 +11,7 @@ body:
|
|||
id: feature-description
|
||||
attributes:
|
||||
label: Describe the feature
|
||||
description: A clear and concise description of what you think would be a helpful addition to radix-vue, including the possible use cases and alternatives you have considered. If you have a working prototype or module that implements it, please include a link.
|
||||
description: A clear and concise description of what you think would be a helpful addition to shadcn-vue, including the possible use cases and alternatives you have considered. If you have a working prototype or module that implements it, please include a link.
|
||||
placeholder: Feature description
|
||||
validations:
|
||||
required: true
|
||||
|
|
|
|||
6
.github/workflows/release.yaml
vendored
6
.github/workflows/release.yaml
vendored
|
|
@ -1,6 +1,6 @@
|
|||
# .github/workflows/release.yml
|
||||
|
||||
name: Release
|
||||
name: Release (next)
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
|
@ -29,11 +29,11 @@ jobs:
|
|||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
|
||||
- name: Build CLI & Publish to npm
|
||||
run: pnpm --filter shadcn-vue pub:release
|
||||
run: pnpm --filter shadcn-vue pub:next
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Build Module & Publish to npm
|
||||
run: pnpm --filter shadcn-nuxt pub:release
|
||||
run: pnpm --filter shadcn-nuxt pub:next
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
|
|
|||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -7,7 +7,7 @@ yarn-error.log*
|
|||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
.nuxt
|
||||
# .nuxt
|
||||
.env
|
||||
node_modules
|
||||
.DS_Store
|
||||
|
|
@ -34,4 +34,4 @@ test-results/
|
|||
playwright-report/
|
||||
vite.config.ts.timestamp*
|
||||
|
||||
**/.vitepress/cache/*
|
||||
**/.vitepress/cache/*
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Thanks for your interest in contributing to shadcn-vue.com. We're happy to have
|
|||
|
||||
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/).
|
||||
If you need any help, feel free to reach out to the core team on [Discord](https://chat.unovue.com/).
|
||||
|
||||
## About this repository
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ packages
|
|||
| ----------------------------| -------------------------------------------|
|
||||
| `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. |
|
||||
| `apps/www/registry` | The registry for the components. |
|
||||
| `packages/cli` | The `shadcn-vue` package. |
|
||||
|
||||
## Development
|
||||
|
|
@ -44,7 +44,7 @@ packages
|
|||
### Start by cloning the repository:
|
||||
|
||||
```
|
||||
git clone git@github.com:radix-vue/shadcn-vue.git
|
||||
git clone git@github.com:unovue/shadcn-vue.git
|
||||
```
|
||||
|
||||
### Install dependencies
|
||||
|
|
@ -83,7 +83,7 @@ Documentation is written using [md](https://vitepress.dev/guide/markdown). You c
|
|||
|
||||
## Components
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
```bash
|
||||
apps
|
||||
|
|
|
|||
2
LICENSE
2
LICENSE
|
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 radix-vue
|
||||
Copyright (c) 2023 unovue
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<p align="center">
|
||||
<img align="center" src="https://raw.githubusercontent.com/radix-vue/shadcn-vue/dev/apps/www/src/public/android-chrome-192x192.png" height="96" />
|
||||
<img align="center" src="https://raw.githubusercontent.com/unovue/shadcn-vue/dev/apps/www/src/public/android-chrome-192x192.png" height="96" />
|
||||
<h1 align="center">
|
||||
shadcn-vue
|
||||
</h1>
|
||||
|
|
@ -23,7 +23,7 @@ All credits go to these open-source works and resources
|
|||
|
||||
- [Shadcn UI](https://ui.shadcn.com) for creating this beautiful project.
|
||||
- [Shadcn Svelte](https://shadcn-svelte.com) for some inspiration for registry.
|
||||
- [Radix Vue](https://radix-vue.com) for doing all the hard work to make sure components are accessible.
|
||||
- [Radix Vue](https://reka-ui.com) for doing all the hard work to make sure components are accessible.
|
||||
- [VueUse](https://vueuse.org) for providing many useful utilities.
|
||||
|
||||
- [ahmedmayara](https://github.com/ahmedmayara/shadcn-vue) for populating many components
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export default defineConfig({
|
|||
['meta', { name: 'theme-color', media: '(prefers-color-scheme: light)', content: 'white' }],
|
||||
['meta', { name: 'theme-color', media: '(prefers-color-scheme: dark)', content: 'black' }],
|
||||
|
||||
['meta', { name: 'creator', content: 'radix-vue' }],
|
||||
['meta', { name: 'creator', content: 'reka-ui' }],
|
||||
['meta', { name: 'theme-color', content: '#41b883' }],
|
||||
['meta', { name: 'og:type', content: 'website' }],
|
||||
['meta', { name: 'og:locale', content: 'en' }],
|
||||
|
|
@ -45,7 +45,7 @@ export default defineConfig({
|
|||
provider: 'local',
|
||||
},
|
||||
editLink: {
|
||||
pattern: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/:path',
|
||||
pattern: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/:path',
|
||||
text: 'Edit this page on GitHub',
|
||||
},
|
||||
carbonAds: {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<script setup lang="ts">
|
||||
import { Separator } from '@/lib/registry/default/ui/separator'
|
||||
import ArrowRightIcon from '~icons/radix-icons/arrow-right'
|
||||
import { announcementConfig } from '../config/site'
|
||||
</script>
|
||||
|
|
@ -7,11 +6,10 @@ import { announcementConfig } from '../config/site'
|
|||
<template>
|
||||
<a
|
||||
:href="announcementConfig.link"
|
||||
class="inline-flex items-center rounded-lg bg-muted px-3 py-1 text-sm font-medium"
|
||||
class="group mb-2 inline-flex items-center px-0.5 text-sm font-medium"
|
||||
>
|
||||
{{ announcementConfig.icon }} <Separator class="mx-2 h-4" orientation="vertical" />
|
||||
<span class="sm:hidden">{{ announcementConfig.title }}</span>
|
||||
<span class="hidden sm:inline">
|
||||
<span class="sm:hidden underline-offset-4 group-hover:underline">{{ announcementConfig.title }}</span>
|
||||
<span class="hidden sm:inline underline-offset-4 group-hover:underline">
|
||||
{{ announcementConfig.title }}
|
||||
</span>
|
||||
<ArrowRightIcon class="ml-1 h-4 w-4" />
|
||||
|
|
|
|||
|
|
@ -1,31 +1,33 @@
|
|||
<script setup lang="ts">
|
||||
import type { Block } from '@/registry/schema'
|
||||
import Button from '@/registry/new-york/ui/button/Button.vue'
|
||||
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@/registry/new-york/ui/resizable'
|
||||
import { Separator } from '@/registry/new-york/ui/separator'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/registry/new-york/ui/tabs'
|
||||
import { ToggleGroup, ToggleGroupItem } from '@/registry/new-york/ui/toggle-group'
|
||||
import { useConfigStore } from '@/stores/config'
|
||||
import { CircleHelp, Info, Monitor, Smartphone, Tablet } from 'lucide-vue-next'
|
||||
import MagicString from 'magic-string'
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import { compileScript, parse, walk } from 'vue/compiler-sfc'
|
||||
import { highlight } from '../config/shiki'
|
||||
import BlockCopyButton from './BlockCopyButton.vue'
|
||||
import StyleSwitcher from './StyleSwitcher.vue'
|
||||
|
||||
// import { V0Button } from '@/components/v0-button'
|
||||
import { Badge } from '@/lib/registry/new-york/ui/badge'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/lib/registry/new-york/ui/popover'
|
||||
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@/lib/registry/new-york/ui/resizable'
|
||||
import { Separator } from '@/lib/registry/new-york/ui/separator'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/lib/registry/new-york/ui/tabs'
|
||||
import { ToggleGroup, ToggleGroupItem } from '@/lib/registry/new-york/ui/toggle-group'
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
import { Check, Fullscreen, Monitor, Smartphone, Tablet, Terminal } from 'lucide-vue-next'
|
||||
import MagicString from 'magic-string'
|
||||
import { computed, reactive, ref, watch } from 'vue'
|
||||
import { compileScript, parse, walk } from 'vue/compiler-sfc'
|
||||
import { Index } from '../../../__registry__/block'
|
||||
import { highlight } from '../config/shiki'
|
||||
import BlockPreview from './BlockPreview.vue'
|
||||
import BlockViewerCode from './BlockViewerCode.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
name: string
|
||||
}>()
|
||||
|
||||
const { style, codeConfig } = useConfigStore()
|
||||
const { copied, copy } = useClipboard()
|
||||
|
||||
const isLoading = ref(true)
|
||||
const tabValue = ref('preview')
|
||||
const resizableRef = ref<InstanceType<typeof ResizablePanel>>()
|
||||
const componentRegistry = ref<Block>()
|
||||
|
||||
const rawString = ref('')
|
||||
const codeHtml = ref('')
|
||||
|
|
@ -35,6 +37,19 @@ const metadata = reactive({
|
|||
containerClass: null as string | null,
|
||||
})
|
||||
|
||||
const iframeURL = computed(() => {
|
||||
// @ts-expect-error env available in import.meta
|
||||
if (import.meta.env.SSR)
|
||||
return ''
|
||||
|
||||
const url = new URL(`${window.location.origin}/blocks/renderer`)
|
||||
url.searchParams.append('name', props.name)
|
||||
url.searchParams.append('styles', 'new-york')
|
||||
url.searchParams.append('containerClass', metadata.containerClass ?? '')
|
||||
|
||||
return url.href
|
||||
})
|
||||
|
||||
function removeScript(code: string) {
|
||||
const s = new MagicString(code)
|
||||
const scriptTagRegex = /<script\s+lang="ts"\s*>[\s\S]+?<\/script>/g
|
||||
|
|
@ -50,18 +65,21 @@ function removeScript(code: string) {
|
|||
|
||||
function transformImportPath(code: string) {
|
||||
const s = new MagicString(code)
|
||||
s.replaceAll(`@/lib/registry/${style.value}`, codeConfig.value.componentsPath)
|
||||
s.replaceAll(`@/registry/${style.value}`, codeConfig.value.componentsPath)
|
||||
s.replaceAll(`@/lib/utils`, codeConfig.value.utilsPath)
|
||||
return s.toString()
|
||||
}
|
||||
|
||||
watch([style, codeConfig], async () => {
|
||||
try {
|
||||
const baseRawString = await import(`../../../src/lib/registry/${style.value}/block/${props.name}.vue?raw`).then(res => res.default.trim())
|
||||
rawString.value = transformImportPath(removeScript(baseRawString))
|
||||
const styleIndex = Index[style.value]
|
||||
componentRegistry.value = styleIndex[props.name]
|
||||
if (!componentRegistry.value)
|
||||
return
|
||||
|
||||
const rawString = await componentRegistry.value.raw()
|
||||
if (!metadata.description) {
|
||||
const { descriptor } = parse(baseRawString)
|
||||
const { descriptor } = parse(rawString)
|
||||
const ast = compileScript(descriptor, { id: '' })
|
||||
walk(ast.scriptAst, {
|
||||
enter(node: any) {
|
||||
|
|
@ -78,7 +96,7 @@ watch([style, codeConfig], async () => {
|
|||
})
|
||||
}
|
||||
|
||||
codeHtml.value = highlight(rawString.value, 'vue')
|
||||
codeHtml.value = highlight(removeScript(rawString), 'vue')
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err)
|
||||
|
|
@ -90,48 +108,47 @@ watch([style, codeConfig], async () => {
|
|||
<Tabs
|
||||
:id="name"
|
||||
v-model="tabValue"
|
||||
class="relative grid w-full scroll-m-20 gap-4"
|
||||
class="group/block-view-wrapper flex min-w-0 flex-col items-stretch gap-4"
|
||||
:style=" {
|
||||
'--container-height': metadata.iframeHeight ?? '600px',
|
||||
'--height': metadata.iframeHeight ?? '600px',
|
||||
}"
|
||||
>
|
||||
<div class="flex flex-col items-center gap-4 sm:flex-row">
|
||||
<div class="flex items-center gap-2">
|
||||
<TabsList class="hidden sm:flex">
|
||||
<TabsTrigger value="preview">
|
||||
<div class="hidden items-center gap-2 sm:flex">
|
||||
<TabsList class="h-7 items-center rounded-md p-0 px-[calc(theme(spacing.1)_-_2px)] py-[theme(spacing.1)]">
|
||||
<TabsTrigger class="h-[1.45rem] rounded-sm px-2 text-xs" value="preview">
|
||||
Preview
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="code">
|
||||
<TabsTrigger class="h-[1.45rem] rounded-sm px-2 text-xs" value="code">
|
||||
Code
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
<div class="hidden items-center gap-2 sm:flex">
|
||||
<Separator
|
||||
orientation="vertical"
|
||||
class="mx-2 hidden h-4 md:flex"
|
||||
/>
|
||||
<div class="flex items-center gap-2">
|
||||
<a :href="`#${name}`">
|
||||
<Badge variant="outline">{{ name }}</Badge>
|
||||
</a>
|
||||
<Popover>
|
||||
<PopoverTrigger class="hidden text-muted-foreground hover:text-foreground sm:flex">
|
||||
<Info class="h-3.5 w-3.5" />
|
||||
<span class="sr-only">Block description</span>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
side="right"
|
||||
:side-offset="10"
|
||||
class="text-sm"
|
||||
>
|
||||
{{ metadata.description }}
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
|
||||
<Separator
|
||||
orientation="vertical"
|
||||
class="mx-2 hidden h-4 md:flex"
|
||||
/>
|
||||
<div class="text-sm font-medium underline-offset-2 hover:underline">
|
||||
<a :href="`#${name}`">{{ metadata.description }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 pr-[14px] sm:ml-auto">
|
||||
<div class="hidden h-[28px] items-center gap-1.5 rounded-md border p-[2px] shadow-sm md:flex">
|
||||
<Button
|
||||
variant="ghost"
|
||||
class="hidden h-7 w-7 rounded-md border bg-transparent shadow-none md:flex lg:w-auto"
|
||||
size="sm"
|
||||
@click="copy(`npx shadcn-vue@latest add ${name}`)"
|
||||
>
|
||||
<Check v-if="copied" />
|
||||
<Terminal v-else />
|
||||
<span class="hidden lg:inline">npx shadcn-vue add {{ name }}</span>
|
||||
</Button>
|
||||
<Separator
|
||||
orientation="vertical"
|
||||
class="mx-2 hidden h-4 md:flex"
|
||||
/>
|
||||
<div class="hidden h-7 items-center gap-1.5 rounded-md border p-[2px] shadow-none lg:flex">
|
||||
<ToggleGroup
|
||||
type="single"
|
||||
default-value="100"
|
||||
|
|
@ -157,44 +174,22 @@ watch([style, codeConfig], async () => {
|
|||
>
|
||||
<Smartphone class="h-3.5 w-3.5" />
|
||||
</ToggleGroupItem>
|
||||
<Separator orientation="vertical" class="h-4" />
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-[22px] w-[22px] rounded-sm p-0"
|
||||
as-child
|
||||
title="Open in New Tab"
|
||||
>
|
||||
<a :href="iframeURL" target="_blank">
|
||||
<span class="sr-only">Open in New Tab</span>
|
||||
<Fullscreen class="h-3.5 w-3.5" />
|
||||
</a>
|
||||
</Button>
|
||||
</ToggleGroup>
|
||||
</div>
|
||||
<Separator
|
||||
orientation="vertical"
|
||||
class="mx-2 hidden h-4 md:flex"
|
||||
/>
|
||||
<StyleSwitcher class="h-7" />
|
||||
<Popover>
|
||||
<PopoverTrigger class="hidden text-muted-foreground hover:text-foreground sm:flex">
|
||||
<CircleHelp class="h-3.5 w-3.5" />
|
||||
<span class="sr-only">Block description</span>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
side="top"
|
||||
:side-offset="20"
|
||||
class="space-y-3 rounded-[0.5rem] text-sm"
|
||||
>
|
||||
<p class="font-medium">
|
||||
What is the difference between the New York and Default style?
|
||||
</p>
|
||||
<p>
|
||||
A style comes with its own set of components, animations,
|
||||
icons and more.
|
||||
</p>
|
||||
<p>
|
||||
The <span class="font-medium">Default</span> style has
|
||||
larger inputs, uses lucide-vue-next for icons and
|
||||
tailwindcss-animate for animations.
|
||||
</p>
|
||||
<p>
|
||||
The <span class="font-medium">New York</span> style ships
|
||||
with smaller buttons and inputs. It also uses shadows on cards
|
||||
and buttons.
|
||||
</p>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<Separator orientation="vertical" class="mx-2 h-4" />
|
||||
<BlockCopyButton :code="rawString" />
|
||||
<!-- <BlockCopyButton :code="rawString" /> -->
|
||||
<!-- <V0Button
|
||||
name="{block.name}"
|
||||
description="{block.description" || "Edit in v0"}
|
||||
|
|
@ -207,7 +202,7 @@ watch([style, codeConfig], async () => {
|
|||
v-show="tabValue === 'preview'"
|
||||
force-mount
|
||||
value="preview"
|
||||
class="relative after:absolute after:inset-0 after:right-3 after:z-0 after:rounded-lg after:bg-muted h-[--container-height] px-0"
|
||||
class="relative after:absolute after:inset-0 after:right-3 after:z-0 after:rounded-lg after:bg-muted h-[--height] px-0"
|
||||
>
|
||||
<ResizablePanelGroup id="block-resizable" direction="horizontal" class="relative z-10">
|
||||
<ResizablePanel
|
||||
|
|
@ -217,17 +212,14 @@ watch([style, codeConfig], async () => {
|
|||
:min-size="30"
|
||||
:as-child="true"
|
||||
>
|
||||
<BlockPreview :name="name" styles="default" :container-class="metadata.containerClass ?? ''" container />
|
||||
<BlockPreview :url="iframeURL" container />
|
||||
</ResizablePanel>
|
||||
<ResizableHandle id="block-resizable-handle" class="relative hidden w-3 bg-transparent p-0 after:absolute after:right-0 after:top-1/2 after:h-8 after:w-[6px] after:-translate-y-1/2 after:translate-x-[-1px] after:rounded-full after:bg-border after:transition-all after:hover:h-10 sm:block" />
|
||||
<ResizablePanel id="block-resizable-panel-2" :default-size="0" :min-size="0" />
|
||||
</ResizablePanelGroup>
|
||||
</TabsContent>
|
||||
<TabsContent value="code" class="h-[--container-height]">
|
||||
<div
|
||||
class="language-vue !h-full !max-h-[none] !mt-0"
|
||||
v-html="codeHtml"
|
||||
/>
|
||||
<TabsContent value="code" class="h-[--height]">
|
||||
<BlockViewerCode v-if="componentRegistry" :item="componentRegistry" />
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from '@/lib/registry/new-york/ui/tooltip'
|
||||
import { CheckIcon, ClipboardIcon } from '@radix-icons/vue'
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
code?: string
|
||||
}>(), {
|
||||
code: '',
|
||||
})
|
||||
const { code } = toRefs(props)
|
||||
|
||||
const { copy, copied } = useClipboard({ source: code })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Tooltip :delay-duration="100">
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="outline"
|
||||
class="h-7 w-7 [&_svg]:size-3.5"
|
||||
@click="copy()"
|
||||
>
|
||||
<span class="sr-only">Copy</span>
|
||||
<CheckIcon v-if="copied" />
|
||||
<ClipboardIcon v-else />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Copy code</TooltipContent>
|
||||
</Tooltip>
|
||||
</template>
|
||||
38
apps/www/.vitepress/theme/components/BlockCopyCodeButton.vue
Normal file
38
apps/www/.vitepress/theme/components/BlockCopyCodeButton.vue
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<script setup lang="ts">
|
||||
import { Button } from '@/registry/new-york/ui/button'
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from '@/registry/new-york/ui/tooltip'
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
import { Check, Clipboard } from 'lucide-vue-next'
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
code?: string
|
||||
}>(), {
|
||||
code: '',
|
||||
})
|
||||
const { code } = toRefs(props)
|
||||
|
||||
const { copy, copied } = useClipboard({ source: code })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Tooltip :delay-duration="100">
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="outline"
|
||||
class="h-7 w-7 [&_svg]:size-3.5"
|
||||
@click="copy()"
|
||||
>
|
||||
<span class="sr-only">Copy</span>
|
||||
<Check v-if="copied" />
|
||||
<Clipboard v-else />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Copy code</TooltipContent>
|
||||
</Tooltip>
|
||||
</template>
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useUrlSearchParams } from '@vueuse/core'
|
||||
import ComponentLoader from './ComponentLoader.vue'
|
||||
|
||||
|
|
@ -6,7 +7,10 @@ const params = useUrlSearchParams('history')
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="params.name" :class="params.containerClass">
|
||||
<div
|
||||
v-if="params.name"
|
||||
:class="cn('preview flex h-screen w-full justify-center items-center', params.containerClass)"
|
||||
>
|
||||
<ComponentLoader :key="params.style?.toString()" :name="params.name?.toString()" :type-name="'block'" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,33 +1,18 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import Spinner from './Spinner.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
name: string
|
||||
styles?: string
|
||||
containerClass?: string
|
||||
container?: boolean
|
||||
url: string
|
||||
}>()
|
||||
|
||||
const isLoading = ref(true)
|
||||
|
||||
const iframeURL = computed(() => {
|
||||
// @ts-expect-error env available in import.meta
|
||||
if (import.meta.env.SSR)
|
||||
return ''
|
||||
|
||||
const url = new URL(`${window.location.origin}/blocks/renderer`)
|
||||
Object.entries(props).forEach(([key, value]) => {
|
||||
if (value)
|
||||
url.searchParams.append(key, value as string)
|
||||
})
|
||||
return url.href
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative rounded-lg border overflow-hidden bg-background" :class="[container ? '' : 'aspect-[4/2.5]']">
|
||||
<div v-if="isLoading" class="flex items-center justify-center h-full">
|
||||
<div v-if="isLoading" class="flex items-center justify-center h-full w-full z-10 relative">
|
||||
<Spinner />
|
||||
</div>
|
||||
<div
|
||||
|
|
@ -35,8 +20,8 @@ const iframeURL = computed(() => {
|
|||
>
|
||||
<iframe
|
||||
v-show="!isLoading"
|
||||
:src="iframeURL"
|
||||
class="relative z-20 w-full bg-background" :class="[container ? 'h-[--container-height]' : 'size-full']"
|
||||
:src="url"
|
||||
class="relative z-20 w-full bg-background" :class="[container ? 'h-[--height]' : 'size-full']"
|
||||
@load="isLoading = false"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
70
apps/www/.vitepress/theme/components/BlockViewerCode.vue
Normal file
70
apps/www/.vitepress/theme/components/BlockViewerCode.vue
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<script setup lang="ts">
|
||||
import type { Block } from '@/registry/schema'
|
||||
import { File } from 'lucide-vue-next'
|
||||
import { computed, onBeforeMount, ref } from 'vue'
|
||||
import { highlight } from '../config/shiki'
|
||||
import BlockCopyCodeButton from './BlockCopyCodeButton.vue'
|
||||
import BlockViewerFileTree, { type FileTree } from './BlockViewerFileTree.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
item: Block
|
||||
}>()
|
||||
|
||||
const activeFile = ref<FileTree>()
|
||||
|
||||
const cacheCodes = ref<Map<string, string>>(new Map<string, string>())
|
||||
const activeCode = computed(() => cacheCodes.value.get(activeFile.value?.path ?? ''))
|
||||
|
||||
onBeforeMount(async () => {
|
||||
for (const file of (props.item.files ?? [])) {
|
||||
const raw = await file.raw()
|
||||
const highlighted = highlight(raw, 'vue')
|
||||
cacheCodes.value.set(file.target || file.path.split(`${props.item.name}/`)[1], highlighted)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mr-[14px] flex h-[--height] overflow-hidden rounded-xl bg-zinc-950 text-white group-data-[view=preview]/block-view-wrapper:hidden">
|
||||
<div class="w-[280px]">
|
||||
<BlockViewerFileTree v-model="activeFile" :item />
|
||||
</div>
|
||||
<div class="flex min-w-0 flex-1 flex-col">
|
||||
<div class="flex h-12 flex-shrink-0 items-center gap-2 border-b border-zinc-700 bg-zinc-900 px-4 text-sm font-medium">
|
||||
<File class="size-4" />
|
||||
{{ activeFile?.path }}
|
||||
<div class="ml-auto flex items-center gap-2">
|
||||
<BlockCopyCodeButton :code="activeCode" />
|
||||
</div>
|
||||
</div>
|
||||
<div :key="activeFile?.path" data-line-codeblock class="relative flex-1 overflow-hidden after:absolute after:inset-y-0 after:left-0 after:w-10 after:bg-zinc-950 [&_.line:before]:sticky [&_.line:before]:left-2 [&_.line:before]:z-10 [&_.line:before]:translate-y-[-1px] [&_.line:before]:pr-1 [&_pre]:h-[--height] [&_pre]:overflow-auto [&_pre]:!bg-transparent [&_pre]:pb-20 [&_pre]:pt-4 [&_pre]:font-mono [&_pre]:text-sm [&_pre]:leading-relaxed" v-html="activeCode" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
[data-line-codeblock] code {
|
||||
display: grid;
|
||||
min-width: 100%;
|
||||
overflow-wrap: break-word;
|
||||
border-radius: 0;
|
||||
border-width: 0;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
counter-reset: line;
|
||||
-webkit-box-decoration-break: clone;
|
||||
box-decoration-break: clone;
|
||||
}
|
||||
|
||||
[data-line-codeblock] .line:before {
|
||||
font-size: .75rem;
|
||||
line-height: 1rem;
|
||||
color: hsla(0, 0%, 98%, .4);
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
width: 1.8rem;
|
||||
margin-right: 1.4rem;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
150
apps/www/.vitepress/theme/components/BlockViewerFileTree.vue
Normal file
150
apps/www/.vitepress/theme/components/BlockViewerFileTree.vue
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
<script lang="ts">
|
||||
export interface FileTree {
|
||||
name: string
|
||||
path?: string
|
||||
children?: FileTree[]
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Block } from '@/registry/schema'
|
||||
import Button from '@/registry/new-york/ui/button/Button.vue'
|
||||
import { ChevronRight, File, Folder } from 'lucide-vue-next'
|
||||
import { TreeItem, TreeRoot } from 'reka-ui'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
item: Block
|
||||
}>()
|
||||
|
||||
const activeFile = defineModel<FileTree>()
|
||||
|
||||
// TODO: Improve the getter logics
|
||||
const flattenFiles = computed(() => {
|
||||
const root: FileTree[] = []
|
||||
|
||||
for (const file of props.item.files ?? []) {
|
||||
const path = file.target || file.path.split(`${props.item.name}/`)[1]
|
||||
const parts = path.split('/')
|
||||
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
const part = parts[i]
|
||||
const isFile = i === parts.length - 1
|
||||
const newNode: FileTree = isFile
|
||||
? { name: part, path }
|
||||
: { name: part, children: [] }
|
||||
|
||||
root.push(newNode)
|
||||
}
|
||||
}
|
||||
return root
|
||||
})
|
||||
|
||||
const treeItem = computed(() => {
|
||||
return createFileTreeForRegistryItemFiles([...(props.item.files ?? [])])
|
||||
})
|
||||
|
||||
const expandedKeys = ref<string[]>([])
|
||||
|
||||
function createFileTreeForRegistryItemFiles(
|
||||
files: Array<{ path: string, target?: string }>,
|
||||
) {
|
||||
const root: FileTree[] = []
|
||||
|
||||
for (const file of files) {
|
||||
const path = file.target || file.path.split(`${props.item.name}/`)[1]
|
||||
const parts = path.split('/')
|
||||
let currentLevel = root
|
||||
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
const part = parts[i]
|
||||
const isFile = i === parts.length - 1
|
||||
const existingNode = currentLevel.find(node => node.name === part)
|
||||
|
||||
if (existingNode) {
|
||||
if (isFile) {
|
||||
// Update existing file node with full path
|
||||
existingNode.path = path
|
||||
}
|
||||
else {
|
||||
// Move to next level in the tree
|
||||
currentLevel = existingNode.children!
|
||||
}
|
||||
}
|
||||
else {
|
||||
const newNode: FileTree = isFile
|
||||
? { name: part, path }
|
||||
: { name: part, children: [] }
|
||||
|
||||
currentLevel.push(newNode)
|
||||
|
||||
if (!isFile) {
|
||||
currentLevel = newNode.children!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
watch(flattenFiles, (n) => {
|
||||
activeFile.value = n.filter(i => i.path)[0]
|
||||
expandedKeys.value = n.map(i => i.name)
|
||||
}, { immediate: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-full w-full has-[[data-variant=inset]]:bg-sidebar flex flex-col">
|
||||
<div class="flex h-full flex-col w-full flex-1 border-r border-zinc-700 bg-zinc-900 text-white">
|
||||
<div class="duration-200 flex shrink-0 items-center font-medium outline-none ease-linear h-12 rounded-none border-b border-zinc-700 px-4 text-sm text-white">
|
||||
Files
|
||||
</div>
|
||||
<TreeRoot
|
||||
v-slot="{ flattenItems }"
|
||||
v-model="activeFile"
|
||||
v-model:expanded="expandedKeys"
|
||||
class="list-none select-none"
|
||||
:items="treeItem"
|
||||
:get-key="(item) => item.name"
|
||||
>
|
||||
<TreeItem
|
||||
v-for="item in flattenItems"
|
||||
:key="item._id"
|
||||
v-slot="{ isSelected, isExpanded }"
|
||||
v-bind="item.bind"
|
||||
as-child
|
||||
@select="(ev) => {
|
||||
if (item.hasChildren || ev.detail.isSelected)
|
||||
ev.preventDefault()
|
||||
}"
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
:data-active="isSelected"
|
||||
class="flex w-full justify-start whitespace-nowrap rounded-none pl-[--index] hover:bg-zinc-700 hover:text-white focus-visible:bg-zinc-700 focus-visible:text-white active:bg-zinc-700 active:text-white data-[active=true]:bg-zinc-700 data-[active=true]:text-white"
|
||||
:style="{ 'padding-left': `${(item.level - 0.25) * 1.5}rem` }"
|
||||
>
|
||||
<template v-if="item.hasChildren">
|
||||
<ChevronRight
|
||||
icon="lucide:folder"
|
||||
class="h-4 w-4 transition-transform"
|
||||
:class="{ 'rotate-90': isExpanded } "
|
||||
/>
|
||||
<Folder class="h-4 w-4" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<ChevronRight
|
||||
icon="lucide:folder"
|
||||
class="invisible"
|
||||
/>
|
||||
<File class="h-4 w-4" />
|
||||
</template>
|
||||
<div>
|
||||
{{ item.value.name }}
|
||||
</div>
|
||||
</Button>
|
||||
</TreeItem>
|
||||
</TreeRoot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -1,21 +1,15 @@
|
|||
<script setup lang="ts">
|
||||
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
|
||||
import { cn } from '@/lib/utils'
|
||||
import GitHubIcon from '~icons/radix-icons/github-logo'
|
||||
import { ref } from 'vue'
|
||||
import { Button } from '@/registry/new-york/ui/button'
|
||||
import Announcement from '../components/Announcement.vue'
|
||||
import PageAction from '../components/PageAction.vue'
|
||||
|
||||
import PageHeader from '../components/PageHeader.vue'
|
||||
import PageHeaderDescription from '../components/PageHeaderDescription.vue'
|
||||
|
||||
import PageHeaderHeading from '../components/PageHeaderHeading.vue'
|
||||
import BlockContainer from './BlockContainer.vue'
|
||||
|
||||
const blocks = ref<string[]>([])
|
||||
|
||||
import('../../../__registry__/index').then((res) => {
|
||||
blocks.value = Object.values(res.Index.default).filter(i => i.type === 'components:block').map(i => i.name)
|
||||
})
|
||||
const blocks = ['Sidebar01', 'Sidebar02', 'Sidebar03', 'Sidebar04', 'Sidebar05', 'Sidebar06', 'Sidebar07', 'Sidebar08', 'Sidebar09', 'Sidebar10', 'Sidebar11', 'Sidebar12', 'Sidebar13', 'Sidebar14', 'Sidebar15', 'Login01']
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -27,27 +21,21 @@ import('../../../__registry__/index').then((res) => {
|
|||
</PageHeaderDescription>
|
||||
|
||||
<PageAction>
|
||||
<a
|
||||
href="/blocks.html#blocks"
|
||||
:class="cn(buttonVariants(), 'rounded-[6px]')"
|
||||
>
|
||||
Browse
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/radix-vue/shadcn-vue"
|
||||
target="_blank"
|
||||
:class="cn(
|
||||
buttonVariants({ variant: 'outline' }),
|
||||
'rounded-[6px]',
|
||||
)"
|
||||
>
|
||||
<GitHubIcon class="mr-2 h-4 w-4" />
|
||||
GitHub
|
||||
</a>
|
||||
<Button as-child size="sm">
|
||||
<a href="#blocks">Browse Blocks</a>
|
||||
</Button>
|
||||
<Button as-child variant="ghost" size="sm">
|
||||
<a
|
||||
href="https://github.com/shadcn-ui/ui/discussions/new?category=blocks-request"
|
||||
target="_blank"
|
||||
>
|
||||
Request a block
|
||||
</a>
|
||||
</Button>
|
||||
</PageAction>
|
||||
</PageHeader>
|
||||
|
||||
<section id="blocks" class="grid scroll-mt-24 gap-24 lg:gap-48">
|
||||
<section id="blocks" class="grid scroll-mt-24 gap-24 lg:gap-48 container py-6">
|
||||
<BlockContainer v-for="block in blocks" :key="block" :name="block" />
|
||||
</section>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import {
|
|||
Alert,
|
||||
AlertDescription,
|
||||
AlertTitle,
|
||||
} from '@/lib/registry/default/ui/alert'
|
||||
} from '@/registry/default/ui/alert'
|
||||
|
||||
interface CalloutProps {
|
||||
icon?: string
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<script lang="ts" setup>
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/lib/registry/new-york/ui/form'
|
||||
import { Input } from '@/lib/registry/new-york/ui/input'
|
||||
import { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from '@/lib/registry/new-york/ui/sheet'
|
||||
import { Button } from '@/registry/new-york/ui/button'
|
||||
import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/registry/new-york/ui/form'
|
||||
import { Input } from '@/registry/new-york/ui/input'
|
||||
import { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from '@/registry/new-york/ui/sheet'
|
||||
import { useConfigStore } from '@/stores/config'
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
import RadixIconsGear from '~icons/radix-icons/gear'
|
||||
|
|
@ -36,11 +36,11 @@ const onSubmit = handleSubmit((values) => {
|
|||
>
|
||||
<SheetTrigger as-child>
|
||||
<Button
|
||||
class="w-9 h-9"
|
||||
class="w-8 h-8"
|
||||
:variant="'ghost'"
|
||||
:size="'icon'"
|
||||
>
|
||||
<RadixIconsGear class="w-5 h-5" />
|
||||
<RadixIconsGear class="w-4 h-4" />
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { Style } from '@/lib/registry/styles'
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
import type { RegistryStyle } from '@/registry/registry-styles'
|
||||
import { Button } from '@/registry/new-york/ui/button'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { ref, toRefs, watch } from 'vue'
|
||||
import { makeCodeSandboxParams } from '../utils/codeeditor'
|
||||
|
|
@ -9,7 +9,7 @@ import Tooltip from './Tooltip.vue'
|
|||
const props = defineProps<{
|
||||
name: string
|
||||
code: string
|
||||
style: Style
|
||||
style: RegistryStyle
|
||||
}>()
|
||||
|
||||
const { code } = toRefs(props)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { useConfigStore } from '@/stores/config'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
import { Index } from '../../../__registry__'
|
||||
import Spinner from './Spinner.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
|
|
@ -9,9 +10,12 @@ const props = defineProps<{
|
|||
}>()
|
||||
const { style } = useConfigStore()
|
||||
|
||||
const styleIndex = Index[style.value]
|
||||
const componentRegistry = styleIndex[props.name]
|
||||
|
||||
const Component = defineAsyncComponent({
|
||||
loadingComponent: Spinner,
|
||||
loader: () => import(`../../../src/lib/registry/${style.value}/${props.typeName}/${props.name}.vue`),
|
||||
loader: componentRegistry.component,
|
||||
timeout: 5000,
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/lib/registry/default/ui/tabs'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/registry/default/ui/tabs'
|
||||
import { useConfigStore } from '@/stores/config'
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
import MagicString from 'magic-string'
|
||||
|
|
@ -28,14 +28,14 @@ const transformedRawString = computed(() => transformImportPath(rawString.value)
|
|||
|
||||
function transformImportPath(code: string) {
|
||||
const s = new MagicString(code)
|
||||
s.replaceAll(`@/lib/registry/${style.value}`, codeConfig.value.componentsPath)
|
||||
s.replaceAll(`@/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())
|
||||
rawString.value = await import(`../../../src/registry/${style.value}/example/${props.name}.vue?raw`).then(res => res.default.trim())
|
||||
codeHtml.value = highlight(transformedRawString.value, 'vue')
|
||||
}
|
||||
catch (err) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { themes } from '@/lib/registry'
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
import { Button } from '@/registry/new-york/ui/button'
|
||||
import { baseColors } from '@/registry/registry-base-colors'
|
||||
import { useConfigStore } from '@/stores/config'
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
import CheckIcon from '~icons/radix-icons/check'
|
||||
|
|
@ -9,7 +9,7 @@ import { computed, ref } from 'vue'
|
|||
|
||||
const { theme, config } = useConfigStore()
|
||||
|
||||
const activeTheme = computed(() => themes.find(i => i.name === theme.value))
|
||||
const activeTheme = computed(() => baseColors.find(i => i.name === theme.value))
|
||||
|
||||
const { copy, copied } = useClipboard()
|
||||
|
||||
|
|
@ -25,28 +25,28 @@ async function copyCode() {
|
|||
<code ref="codeRef" class="relative block rounded font-mono text-sm">
|
||||
<span class="line text-white">@layer base {</span>
|
||||
<span class="line text-white">:root {</span>
|
||||
<span class="line text-white"> --background: {{ activeTheme?.cssVars.light.background }};</span>
|
||||
<span class="line text-white"> --foreground: {{ activeTheme?.cssVars.light.foreground }};</span>
|
||||
<span class="line text-white"> --background: {{ activeTheme?.cssVars?.light?.background }};</span>
|
||||
<span class="line text-white"> --foreground: {{ activeTheme?.cssVars?.light?.foreground }};</span>
|
||||
<template v-for="prefix in (['card', 'popover', 'primary', 'secondary', 'muted', 'accent', 'destructive'] as const)" :key="prefix">
|
||||
<span class="line text-white">--{{ prefix }}: {{ activeTheme?.cssVars.light[prefix] }};</span>
|
||||
<span class="line text-white">--{{ prefix }}-foreground: {{ activeTheme?.cssVars.light[ `${prefix}-foreground`] }};</span>
|
||||
<span class="line text-white">--{{ prefix }}: {{ activeTheme?.cssVars?.light?.[prefix] }};</span>
|
||||
<span class="line text-white">--{{ prefix }}-foreground: {{ activeTheme?.cssVars?.light?.[ `${prefix}-foreground`] }};</span>
|
||||
</template>
|
||||
<span class="line text-white"> --border:{{ activeTheme?.cssVars.light.border }};</span>
|
||||
<span class="line text-white"> --input:{{ activeTheme?.cssVars.light.input }};</span>
|
||||
<span class="line text-white"> --ring:{{ activeTheme?.cssVars.light.ring }};</span>
|
||||
<span class="line text-white"> --border:{{ activeTheme?.cssVars?.light?.border }};</span>
|
||||
<span class="line text-white"> --input:{{ activeTheme?.cssVars?.light?.input }};</span>
|
||||
<span class="line text-white"> --ring:{{ activeTheme?.cssVars?.light?.ring }};</span>
|
||||
<span class="line text-white"> --radius: {{ config.radius }}rem;</span>
|
||||
<span class="line text-white">}</span>
|
||||
<span class="line text-white"> </span>
|
||||
<span class="line text-white">.dark {</span>
|
||||
<span class="line text-white"> --background:{{ activeTheme?.cssVars.dark.background }};</span>
|
||||
<span class="line text-white"> --foreground:{{ activeTheme?.cssVars.dark.foreground }};</span>
|
||||
<span class="line text-white"> --background:{{ activeTheme?.cssVars?.dark?.background }};</span>
|
||||
<span class="line text-white"> --foreground:{{ activeTheme?.cssVars?.dark?.foreground }};</span>
|
||||
<template v-for="prefix in (['card', 'popover', 'primary', 'secondary', 'muted', 'accent', 'destructive'] as const)" :key="prefix">
|
||||
<span class="line text-white">--{{ prefix }}:{{ activeTheme?.cssVars.dark[ prefix] }};</span>
|
||||
<span class="line text-white">--{{ prefix }}-foreground:{{ activeTheme?.cssVars.dark[ `${prefix}-foreground`] }};</span>
|
||||
<span class="line text-white">--{{ prefix }}:{{ activeTheme?.cssVars?.dark?.[ prefix] }};</span>
|
||||
<span class="line text-white">--{{ prefix }}-foreground:{{ activeTheme?.cssVars?.dark?.[ `${prefix}-foreground`] }};</span>
|
||||
</template>
|
||||
<span class="line text-white"> --border:{{ activeTheme?.cssVars.dark.border }};</span>
|
||||
<span class="line text-white"> --input:{{ activeTheme?.cssVars.dark.input }};</span>
|
||||
<span class="line text-white"> --ring:{{ activeTheme?.cssVars.dark.ring }};</span>
|
||||
<span class="line text-white"> --border:{{ activeTheme?.cssVars?.dark?.border }};</span>
|
||||
<span class="line text-white"> --input:{{ activeTheme?.cssVars?.dark?.input }};</span>
|
||||
<span class="line text-white"> --ring:{{ activeTheme?.cssVars?.dark?.ring }};</span>
|
||||
<span class="line text-white">}</span>
|
||||
<span class="line text-white">}</span>
|
||||
</code>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/registry/new-york/ui/breadcrumb'
|
||||
} from '@/registry/new-york/ui/breadcrumb'
|
||||
import { useRoute } from 'vitepress'
|
||||
import { computed } from 'vue'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { Button } from '@/lib/registry/default/ui/button'
|
||||
import { Button } from '@/registry/default/ui/button'
|
||||
import Pencil2Icon from '~icons/radix-icons/pencil-2'
|
||||
import { useData } from 'vitepress'
|
||||
import { computed } from 'vue'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { ScrollArea, ScrollBar } from '@/lib/registry/default/ui/scroll-area'
|
||||
import { cn } from '@/lib/utils'
|
||||
import ArrowRightIcon from '~icons/radix-icons/arrow-right'
|
||||
import { ScrollArea, ScrollBar } from '@/registry/default/ui/scroll-area'
|
||||
import { useRoute } from 'vitepress'
|
||||
import { computed, toRefs } from 'vue'
|
||||
|
||||
|
|
@ -11,42 +10,42 @@ const examples = [
|
|||
{
|
||||
name: 'Mail',
|
||||
href: '/examples/mail',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/mail',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/mail',
|
||||
},
|
||||
{
|
||||
name: 'Dashboard',
|
||||
href: '/examples/dashboard',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/dashboard',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/dashboard',
|
||||
},
|
||||
{
|
||||
name: 'Cards',
|
||||
href: '/examples/cards',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/cards',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/cards',
|
||||
},
|
||||
{
|
||||
name: 'Tasks',
|
||||
href: '/examples/tasks',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/tasks',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/tasks',
|
||||
},
|
||||
{
|
||||
name: 'Playground',
|
||||
href: '/examples/playground',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/playground',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/playground',
|
||||
},
|
||||
{
|
||||
name: 'Forms',
|
||||
href: '/examples/forms',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/forms',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/forms',
|
||||
},
|
||||
{
|
||||
name: 'Music',
|
||||
href: '/examples/music',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/music',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/music',
|
||||
},
|
||||
{
|
||||
name: 'Authentication',
|
||||
href: '/examples/authentication',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/authentication',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/authentication',
|
||||
},
|
||||
]
|
||||
|
||||
|
|
@ -62,10 +61,10 @@ const currentExample = computed(() => examples.find(ex => path.value.startsWith(
|
|||
:key="example.href"
|
||||
:href="example.href"
|
||||
:class="cn(
|
||||
'flex items-center px-4',
|
||||
path?.startsWith(example.href) || (path === '/' && example.name === 'Mail')
|
||||
? 'font-bold text-primary'
|
||||
: 'font-medium text-muted-foreground',
|
||||
'flex h-7 items-center justify-center rounded-full px-4 text-center text-sm transition-colors hover:text-primary',
|
||||
path?.startsWith(example.href)
|
||||
? 'bg-muted font-medium text-primary'
|
||||
: 'text-muted-foreground',
|
||||
)"
|
||||
>
|
||||
{{ example.name }}
|
||||
|
|
@ -73,14 +72,5 @@ const currentExample = computed(() => examples.find(ex => path.value.startsWith(
|
|||
</div>
|
||||
<ScrollBar orientation="horizontal" class="invisible" />
|
||||
</ScrollArea>
|
||||
|
||||
<a
|
||||
v-if="currentExample"
|
||||
:href="currentExample?.code" target="_blank" rel="nofollow"
|
||||
class="absolute right-0 top-0 hidden items-center rounded-[0.5rem] text-sm font-medium md:flex"
|
||||
>
|
||||
View code
|
||||
<ArrowRightIcon class="ml-1 h-4 w-4" />
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,21 +1,20 @@
|
|||
<script lang="ts" setup>
|
||||
import type { Color } from '../types/colors'
|
||||
import { colors } from '@/lib/registry'
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/lib/registry/new-york/ui/tooltip'
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/registry/new-york/ui/tooltip'
|
||||
import { baseColors } from '@/registry/registry-base-colors'
|
||||
import { useConfigStore } from '@/stores/config'
|
||||
import RadixIconsCheck from '~icons/radix-icons/check'
|
||||
|
||||
defineProps<{
|
||||
allColors: Color[]
|
||||
}>()
|
||||
import { Check } from 'lucide-vue-next'
|
||||
import { useData } from 'vitepress'
|
||||
|
||||
const { theme, setTheme } = useConfigStore()
|
||||
const { isDark } = useData()
|
||||
|
||||
const pickedColors = baseColors.filter((color, index) => [0, 6, 8, 9, 10].includes(index))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<TooltipProvider
|
||||
v-for="(color, index) in allColors.slice(0, 5)"
|
||||
v-for="(color, index) in pickedColors"
|
||||
:key="index"
|
||||
>
|
||||
<Tooltip>
|
||||
|
|
@ -24,18 +23,22 @@ const { theme, setTheme } = useConfigStore()
|
|||
:key="index"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-full border-2 border-border text-xs"
|
||||
:class="
|
||||
color === theme
|
||||
color.name === theme
|
||||
? 'border-primary'
|
||||
: 'border-transparent'
|
||||
"
|
||||
@click="setTheme(color)"
|
||||
:style="{
|
||||
'--theme-primary': `hsl(${
|
||||
color?.activeColor[isDark ? 'dark' : 'light']
|
||||
})`,
|
||||
}"
|
||||
@click="setTheme(color.name)"
|
||||
>
|
||||
<span
|
||||
class="flex h-6 w-6 items-center justify-center rounded-full"
|
||||
:style="{ backgroundColor: colors[color][6].rgb }"
|
||||
class="flex h-6 w-6 items-center justify-center rounded-full bg-[--theme-primary]"
|
||||
>
|
||||
<RadixIconsCheck
|
||||
v-if="color === theme"
|
||||
<Check
|
||||
v-if="color.name === theme"
|
||||
class="h-4 w-4 text-white"
|
||||
/>
|
||||
</span>
|
||||
|
|
@ -46,7 +49,7 @@ const { theme, setTheme } = useConfigStore()
|
|||
:side-offset="1"
|
||||
class="capitalize bg-zinc-900 text-zinc-50"
|
||||
>
|
||||
{{ allColors[index] }}
|
||||
{{ color.label }}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ const props = withDefaults(defineProps<KbdProps>(), {
|
|||
|
||||
const kbdClass = computed(() => {
|
||||
return cva(
|
||||
'inline-flex items-center pointer-events-none h-5 select-none items-center gap-1 rounded border border-border bg-muted font-sans font-medium',
|
||||
'inline-flex items-center pointer-events-none h-5 select-none gap-1 rounded border border-border bg-muted font-sans font-medium',
|
||||
{
|
||||
variants: {
|
||||
size: {
|
||||
|
|
|
|||
74
apps/www/.vitepress/theme/components/LandingExample.vue
Normal file
74
apps/www/.vitepress/theme/components/LandingExample.vue
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<script setup lang="ts">
|
||||
import type { DateRange } from 'reka-ui'
|
||||
import CookieSettings from '@/examples/cards/components/CookieSettings.vue'
|
||||
import CreateAccount from '@/examples/cards/components/CreateAccount.vue'
|
||||
|
||||
import PaymentMethod from '@/examples/cards/components/PaymentMethod.vue'
|
||||
|
||||
import ReportAnIssue from '@/examples/cards/components/ReportAnIssue.vue'
|
||||
import ShareDocument from '@/examples/cards/components/ShareDocument.vue'
|
||||
import TeamMembers from '@/examples/cards/components/TeamMembers.vue'
|
||||
import CardChat from '@/registry/new-york/example/CardChat.vue'
|
||||
import ActivityGoal from '@/registry/new-york/example/Cards/ActivityGoal.vue'
|
||||
import DataTable from '@/registry/new-york/example/Cards/DataTable.vue'
|
||||
|
||||
import Metric from '@/registry/new-york/example/Cards/Metric.vue'
|
||||
import CardStats from '@/registry/new-york/example/CardStats.vue'
|
||||
import { Card } from '@/registry/new-york/ui/card'
|
||||
import { RangeCalendar } from '@/registry/new-york/ui/range-calendar'
|
||||
import { getLocalTimeZone, today } from '@internationalized/date'
|
||||
|
||||
import { type Ref, ref } from 'vue'
|
||||
|
||||
const now = today(getLocalTimeZone())
|
||||
|
||||
const range = ref({
|
||||
start: now,
|
||||
end: now.add({ days: 8 }),
|
||||
}) as Ref<DateRange>
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="items-start justify-center gap-6 rounded-lg md:grids-col-2 grid md:gap-4 lg:grid-cols-10 xl:grid-cols-11 xl:gap-4"
|
||||
>
|
||||
<div class="space-y-4 lg:col-span-4 xl:col-span-6 xl:space-y-4">
|
||||
<CardStats />
|
||||
|
||||
<div class="grid gap-4 md:grid-cols-2 lg:grid-cols-1 xl:grid-cols-2">
|
||||
<div class="space-y-4">
|
||||
<TeamMembers />
|
||||
<CookieSettings />
|
||||
<PaymentMethod />
|
||||
</div>
|
||||
|
||||
<div class="space-y-4">
|
||||
<CardChat />
|
||||
<CreateAccount />
|
||||
<ReportAnIssue />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-4 lg:col-span-6 xl:col-span-5 xl:space-y-4">
|
||||
<div class="hidden gap-1 sm:grid-cols-[280px_1fr] md:grid">
|
||||
<Card class="max-w-[280px]">
|
||||
<RangeCalendar v-model="range" />
|
||||
</Card>
|
||||
|
||||
<div class="pt-3 sm:pl-2 sm:pt-0 xl:pl-3">
|
||||
<ActivityGoal />
|
||||
</div>
|
||||
<div class="pt-3 sm:col-span-2 xl:pt-3">
|
||||
<Metric />
|
||||
</div>
|
||||
<div class="pt-3 sm:col-span-2 xl:pt-3">
|
||||
<DataTable />
|
||||
</div>
|
||||
|
||||
<div class="pt-3 sm:col-span-2 xl:pt-3">
|
||||
<ShareDocument />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import MailExample from '@/examples/mail/Example.vue'
|
||||
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
|
||||
import { cn } from '@/lib/utils'
|
||||
import GitHubIcon from '~icons/radix-icons/github-logo'
|
||||
import Button from '@/registry/new-york/ui/button/Button.vue'
|
||||
import Announcement from '../components/Announcement.vue'
|
||||
import ExamplesNav from '../components/ExamplesNav.vue'
|
||||
import PageAction from '../components/PageAction.vue'
|
||||
|
|
@ -11,51 +8,52 @@ import PageHeader from '../components/PageHeader.vue'
|
|||
import PageHeaderDescription from '../components/PageHeaderDescription.vue'
|
||||
|
||||
import PageHeaderHeading from '../components/PageHeaderHeading.vue'
|
||||
import LandingExample from './LandingExample.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PageHeader class="page-header pb-8">
|
||||
<Announcement />
|
||||
<PageHeaderHeading>Build your component library.</PageHeaderHeading>
|
||||
<PageHeaderDescription>
|
||||
Beautifully designed components that you can copy and paste into your
|
||||
apps. Accessible. Customizable. Open Source.
|
||||
</PageHeaderDescription>
|
||||
<div class="relative">
|
||||
<PageHeader>
|
||||
<Announcement />
|
||||
<PageHeaderHeading>Build your component library</PageHeaderHeading>
|
||||
<PageHeaderDescription>
|
||||
Beautifully designed components that you can copy and paste into your apps. Made with Tailwind CSS. Open source.
|
||||
</PageHeaderDescription>
|
||||
|
||||
<PageAction>
|
||||
<a
|
||||
href="/docs/introduction"
|
||||
:class="cn(buttonVariants(), 'rounded-[6px]')"
|
||||
>
|
||||
Get Started
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/radix-vue/shadcn-vue"
|
||||
target="_blank"
|
||||
:class="cn(
|
||||
buttonVariants({ variant: 'outline' }),
|
||||
'rounded-[6px]',
|
||||
)"
|
||||
>
|
||||
<GitHubIcon class="mr-2 h-4 w-4" />
|
||||
GitHub
|
||||
</a>
|
||||
</PageAction>
|
||||
</PageHeader>
|
||||
<ExamplesNav />
|
||||
<section class="space-y-8 overflow-hidden rounded-lg border-2 border-primary dark:border-muted md:hidden">
|
||||
<VPImage
|
||||
alt="Mail"
|
||||
width="1280"
|
||||
height="866" class="block" :image="{
|
||||
dark: '/examples/mail-dark.png',
|
||||
light: '/examples/mail-light.png',
|
||||
}"
|
||||
/>
|
||||
</section>
|
||||
<section class="hidden md:block">
|
||||
<div class="overflow-hidden rounded-[0.5rem] border bg-background shadow">
|
||||
<MailExample />
|
||||
<PageAction>
|
||||
<Button as-child size="sm">
|
||||
<a href="/docs/introduction">
|
||||
Get Started
|
||||
</a>
|
||||
</Button>
|
||||
<Button as-child size="sm" variant="ghost">
|
||||
<a
|
||||
href="https://github.com/unovue/shadcn-vue"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
GitHub
|
||||
</a>
|
||||
</Button>
|
||||
</PageAction>
|
||||
</PageHeader>
|
||||
|
||||
<div class="container py-6">
|
||||
<ExamplesNav class="[&>a:first-child]:text-primary" />
|
||||
|
||||
<section class="space-y-8 overflow-hidden rounded-lg border-2 border-primary dark:border-muted md:hidden">
|
||||
<VPImage
|
||||
alt="Mail"
|
||||
width="1280"
|
||||
height="866" class="block" :image="{
|
||||
dark: '/examples/mail-dark.png',
|
||||
light: '/examples/mail-light.png',
|
||||
}"
|
||||
/>
|
||||
</section>
|
||||
<section class="hidden md:block">
|
||||
<LandingExample />
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -3,20 +3,10 @@
|
|||
|
||||
<template>
|
||||
<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" />
|
||||
<path d="M192 40L40 192" stroke="#41B883" stroke-width="16" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_102_1338">
|
||||
<rect width="256" height="256" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" class="h-6 w-6 text-[#41B883]"><rect width="256" height="256" fill="none" /><line x1="208" y1="128" x2="128" y2="208" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" /><line x1="192" y1="40" x2="40" y2="192" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" /></svg>
|
||||
|
||||
<span class="font-bold">
|
||||
shadcn-vue
|
||||
shadcn/vue
|
||||
</span>
|
||||
</a>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/lib/registry/default/ui/accordion'
|
||||
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/registry/default/ui/accordion'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { Button } from '@/lib/registry/default/ui/button'
|
||||
import { ScrollArea } from '@/lib/registry/default/ui/scroll-area'
|
||||
import { Sheet, SheetContent, SheetTrigger } from '@/lib/registry/default/ui/sheet'
|
||||
import { Button } from '@/registry/default/ui/button'
|
||||
import { ScrollArea } from '@/registry/default/ui/scroll-area'
|
||||
import { Sheet, SheetContent, SheetTrigger } from '@/registry/default/ui/sheet'
|
||||
import { ref } from 'vue'
|
||||
import { docsConfig } from '../config/docs'
|
||||
import Logo from './Logo.vue'
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { cn } from '@/lib/utils'
|
|||
<template>
|
||||
<section
|
||||
:class="cn(
|
||||
'flex w-full items-center justify-center space-x-4 py-4 md:pb-10',
|
||||
'flex w-full items-center justify-start gap-2 py-2',
|
||||
$attrs.class ?? '',
|
||||
)"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ import { cn } from '@/lib/utils'
|
|||
<template>
|
||||
<section
|
||||
:class="cn(
|
||||
'mx-auto flex max-w-[980px] flex-col items-center gap-2 py-8 md:py-12 md:pb-8 lg:py-24 lg:pb-20',
|
||||
'flex flex-col items-start gap-2 border-b border-border/40 py-8 dark:border-border md:py-10 lg:py-12',
|
||||
$attrs.class ?? '',
|
||||
)"
|
||||
>
|
||||
<slot />
|
||||
<div class="container">
|
||||
<slot />
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils'
|
||||
import WrapBalancer from 'vue-wrap-balancer'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<WrapBalancer :class="cn('max-w-[750px] text-center text-lg font-light text-foreground', $attrs.class ?? '')" :prefer-native="false">
|
||||
<p :class="cn('max-w-2xl text-lg font-light text-foreground', $attrs.class ?? '')">
|
||||
<slot />
|
||||
</WrapBalancer>
|
||||
</p>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { cn } from '@/lib/utils'
|
|||
<template>
|
||||
<h1
|
||||
:class="cn(
|
||||
'text-center text-3xl font-bold leading-tight tracking-tighter md:text-5xl lg:leading-[1.1]',
|
||||
'text-3xl font-bold leading-tight tracking-tighter md:text-4xl lg:leading-[1.1]',
|
||||
$attrs.class ?? '',
|
||||
)"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { Style } from '@/lib/registry/styles'
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
import type { RegistryStyle } from '@/registry/registry-styles'
|
||||
import { Button } from '@/registry/new-york/ui/button'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { ref, toRefs, watch } from 'vue'
|
||||
import { makeStackblitzParams } from '../utils/codeeditor'
|
||||
|
|
@ -9,7 +9,7 @@ import Tooltip from './Tooltip.vue'
|
|||
const props = defineProps<{
|
||||
name: string
|
||||
code: string
|
||||
style: Style
|
||||
style: RegistryStyle
|
||||
}>()
|
||||
|
||||
const { code } = toRefs(props)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div
|
||||
class="[&>h3]:step mb-12 ml-4 border-l pl-8 [counter-reset:step]"
|
||||
class="[&>h3]:step steps mb-12 ml-4 border-l pl-8 [counter-reset:step]"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
<script setup lang="ts">
|
||||
import type { SelectTriggerProps } from 'radix-vue'
|
||||
import type { SelectTriggerProps } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/lib/registry/new-york/ui/select'
|
||||
|
||||
import { styles } from '@/lib/registry/styles'
|
||||
import { cn } from '@/lib/utils'
|
||||
} from '@/registry/new-york/ui/select'
|
||||
import { styles } from '@/registry/registry-styles'
|
||||
import { useConfigStore } from '@/stores/config'
|
||||
|
||||
const props = defineProps<SelectTriggerProps & { class?: string }>()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { TabsContent } from '@/lib/registry/default/ui/tabs'
|
||||
import { TabsContent } from '@/registry/default/ui/tabs'
|
||||
|
||||
withDefaults(defineProps<{
|
||||
title?: string
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/lib/registry/default/ui/tabs'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/registry/default/ui/tabs'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
name: string
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import type { TableOfContents, TableOfContentsItem } from '../types/docs'
|
||||
import { buttonVariants } from '@/lib/registry/default/ui/button'
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/lib/registry/default/ui/collapsible'
|
||||
import { ScrollArea } from '@/lib/registry/default/ui/scroll-area'
|
||||
import { buttonVariants } from '@/registry/default/ui/button'
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/registry/default/ui/collapsible'
|
||||
import { onContentUpdated } from 'vitepress'
|
||||
import { shallowRef } from 'vue'
|
||||
import CarbonAds from '../components/CarbonAds.vue'
|
||||
|
|
@ -61,16 +60,14 @@ onContentUpdated(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="hidden xl:block">
|
||||
<ScrollArea orientation="vertical" class="h-[calc(100vh-6.5rem)] z-30 md:block overflow-y-auto" type="hover">
|
||||
<div class="space-y-2">
|
||||
<p class="font-medium">
|
||||
On This Page
|
||||
</p>
|
||||
<TableOfContentTree :tree="headers" :level="1" />
|
||||
<CarbonAds v-if="showCarbonAds" />
|
||||
</div>
|
||||
</ScrollArea>
|
||||
<div class="hidden xl:block no-scrollbar h-full overflow-auto pb-16">
|
||||
<div class="space-y-2">
|
||||
<p class="font-medium">
|
||||
On This Page
|
||||
</p>
|
||||
<TableOfContentTree :tree="headers" :level="1" />
|
||||
<CarbonAds v-if="showCarbonAds" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="block xl:hidden mb-6">
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@ watch(() => route.path, () => {
|
|||
item.url === hash
|
||||
? 'font-medium text-foreground'
|
||||
: 'text-muted-foreground')"
|
||||
>{{ item.title }} </a>
|
||||
>
|
||||
{{ item.title }}
|
||||
</a>
|
||||
|
||||
<TableOfContentTree v-if="item.items?.length" :tree="item" :level="level + 1" />
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { Tabs, TabsList, TabsTrigger } from '@/lib/registry/default/ui/tabs'
|
||||
import { Tabs, TabsList, TabsTrigger } from '@/registry/default/ui/tabs'
|
||||
import { computed, useSlots } from 'vue'
|
||||
|
||||
const slots = useSlots()
|
||||
|
|
|
|||
|
|
@ -1,105 +1,121 @@
|
|||
<script lang="ts" setup>
|
||||
import type { Color } from '../types/colors'
|
||||
import { colors } from '@/lib/registry'
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
import { Label } from '@/lib/registry/new-york/ui/label'
|
||||
import { Button } from '@/registry/new-york/ui/button'
|
||||
import { Label } from '@/registry/new-york/ui/label'
|
||||
import { baseColors } from '@/registry/registry-base-colors'
|
||||
import { RADII, useConfigStore } from '@/stores/config'
|
||||
import RadixIconsCheck from '~icons/radix-icons/check'
|
||||
import RadixIconsMoon from '~icons/radix-icons/moon'
|
||||
import RadixIconsSun from '~icons/radix-icons/sun'
|
||||
import { Check, Moon, Repeat, Sun } from 'lucide-vue-next'
|
||||
import { useData } from 'vitepress'
|
||||
|
||||
defineProps<{
|
||||
allColors: Color[]
|
||||
}>()
|
||||
|
||||
const { theme, radius, setRadius, setTheme } = useConfigStore()
|
||||
const { config, theme, radius, setRadius, setTheme } = useConfigStore()
|
||||
const { isDark } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<div class="grid space-y-1">
|
||||
<h1 class="text-md text-foreground font-semibold">
|
||||
Customize
|
||||
</h1>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
Pick a style and color for your components.
|
||||
</p>
|
||||
<div class="flex flex-col space-y-4 md:space-y-6">
|
||||
<div class="flex items-start pt-4 md:pt-0">
|
||||
<div class="space-y-1 pr-2">
|
||||
<div class="font-semibold leading-none tracking-tight">
|
||||
Theme Customizer
|
||||
</div>
|
||||
<div class="text-xs text-muted-foreground">
|
||||
Customize your components colors.
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
class="ml-auto rounded-[0.5rem]"
|
||||
@click="() => {
|
||||
config = {
|
||||
...config,
|
||||
theme: 'zinc',
|
||||
radius: 0.5,
|
||||
}
|
||||
}"
|
||||
>
|
||||
<Repeat />
|
||||
<span class="sr-only">Reset</span>
|
||||
</Button>
|
||||
</div>
|
||||
<div class="space-y-1.5 pt-6">
|
||||
<Label for="color" class="text-xs"> Color </Label>
|
||||
<div class="grid grid-cols-3 gap-2 py-1.5">
|
||||
<Button
|
||||
v-for="(color, index) in allColors"
|
||||
:key="index"
|
||||
variant="outline"
|
||||
class="h-8 justify-start px-3"
|
||||
:class="
|
||||
color === theme
|
||||
? 'border-foreground border-2'
|
||||
: ''
|
||||
"
|
||||
@click="setTheme(color)"
|
||||
>
|
||||
<span
|
||||
class="h-5 w-5 rounded-full flex items-center justify-center shrink-0"
|
||||
:style="{ backgroundColor: colors[color][7].rgb }"
|
||||
<div class="flex flex-1 flex-col space-y-4 md:space-y-6">
|
||||
<div class="space-y-1.5 ">
|
||||
<Label for="color" class="text-xs"> Color </Label>
|
||||
<div class="grid grid-cols-3 gap-2">
|
||||
<Button
|
||||
v-for="(color, index) in baseColors"
|
||||
:key="index"
|
||||
variant="outline"
|
||||
class="h-8 justify-start px-3"
|
||||
:class="
|
||||
color.name === theme
|
||||
? 'border-foreground border-2'
|
||||
: ''
|
||||
"
|
||||
:style="{
|
||||
'--theme-primary': `hsl(${
|
||||
color?.activeColor[isDark ? 'dark' : 'light']
|
||||
})`,
|
||||
}"
|
||||
@click="setTheme(color.name)"
|
||||
>
|
||||
<RadixIconsCheck
|
||||
v-if="color === theme"
|
||||
class="h-3 w-3 text-white"
|
||||
/>
|
||||
</span>
|
||||
<span class="ml-2 text-xs capitalize">
|
||||
{{ color }}
|
||||
</span>
|
||||
</Button>
|
||||
<span
|
||||
class="h-5 w-5 rounded-full flex items-center justify-center shrink-0 bg-[--theme-primary]"
|
||||
>
|
||||
<Check
|
||||
v-if="color.name === theme"
|
||||
class="h-3 w-3 text-white"
|
||||
/>
|
||||
</span>
|
||||
<span class="ml-2 text-xs capitalize">
|
||||
{{ color.name }}
|
||||
</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-1.5 pt-6">
|
||||
<Label for="radius" class="text-xs"> Radius </Label>
|
||||
<div class="grid grid-cols-5 gap-2 py-1.5">
|
||||
<Button
|
||||
v-for="(r, index) in RADII"
|
||||
:key="index"
|
||||
variant="outline"
|
||||
class="h-8 justify-center px-3"
|
||||
:class="
|
||||
r === radius
|
||||
? 'border-foreground border-2'
|
||||
: ''
|
||||
"
|
||||
@click="setRadius(r)"
|
||||
>
|
||||
<span class="text-xs">
|
||||
{{ r }}
|
||||
</span>
|
||||
</Button>
|
||||
<div class="space-y-1.5 ">
|
||||
<Label for="radius" class="text-xs"> Radius </Label>
|
||||
<div class="grid grid-cols-5 gap-2">
|
||||
<Button
|
||||
v-for="(r, index) in RADII"
|
||||
:key="index"
|
||||
variant="outline"
|
||||
class="h-8 justify-center px-3"
|
||||
:class="
|
||||
r === radius
|
||||
? 'border-foreground border-2'
|
||||
: ''
|
||||
"
|
||||
@click="setRadius(r)"
|
||||
>
|
||||
<span class="text-xs">
|
||||
{{ r }}
|
||||
</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-1.5 pt-6">
|
||||
<Label for="theme" class="text-xs"> Theme </Label>
|
||||
<div class="space-y-1.5 ">
|
||||
<Label for="theme" class="text-xs"> Theme </Label>
|
||||
|
||||
<div class="flex space-x-2 py-1.5">
|
||||
<Button
|
||||
class="h-8"
|
||||
variant="outline"
|
||||
:class="{ 'border-2 border-foreground': !isDark }"
|
||||
@click="isDark = false"
|
||||
>
|
||||
<RadixIconsSun class="w-4 h-4 mr-2" />
|
||||
<span class="text-xs">Light</span>
|
||||
</Button>
|
||||
<Button
|
||||
class="h-8"
|
||||
variant="outline"
|
||||
:class="{ 'border-2 border-foreground': isDark }"
|
||||
@click="isDark = true"
|
||||
>
|
||||
<RadixIconsMoon class="w-4 h-4 mr-2" />
|
||||
<span class="text-xs">Dark</span>
|
||||
</Button>
|
||||
<div class="flex space-x-2">
|
||||
<Button
|
||||
class="h-8"
|
||||
variant="outline"
|
||||
:class="{ 'border-2 border-foreground': !isDark }"
|
||||
@click="isDark = false"
|
||||
>
|
||||
<Sun class="w-4 h-4 mr-2" />
|
||||
<span class="text-xs">Light</span>
|
||||
</Button>
|
||||
<Button
|
||||
class="h-8"
|
||||
variant="outline"
|
||||
:class="{ 'border-2 border-foreground': isDark }"
|
||||
@click="isDark = true"
|
||||
>
|
||||
<Moon class="w-4 h-4 mr-2" />
|
||||
<span class="text-xs">Dark</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/lib/registry/new-york/ui/popover'
|
||||
import { Button } from '@/registry/new-york/ui/button'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'
|
||||
import { useConfigStore } from '@/stores/config'
|
||||
import { Paintbrush } from 'lucide-vue-next'
|
||||
import { onMounted, watch } from 'vue'
|
||||
|
|
@ -33,7 +33,7 @@ watch(radius, (radius) => {
|
|||
<Popover>
|
||||
<PopoverTrigger as-child>
|
||||
<Button
|
||||
class="w-9 h-9"
|
||||
class="w-8 h-8"
|
||||
:variant="'ghost'"
|
||||
:size="'icon'"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from '@/lib/registry/default/ui/tooltip'
|
||||
} from '@/registry/default/ui/tooltip'
|
||||
|
||||
defineProps<{
|
||||
content: string
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import type { DateRange } from 'radix-vue'
|
||||
import type { DateRange } from 'reka-ui'
|
||||
import CookieSettings from '@/examples/cards/components/CookieSettings.vue'
|
||||
import CreateAccount from '@/examples/cards/components/CreateAccount.vue'
|
||||
|
||||
|
|
@ -8,14 +8,14 @@ import PaymentMethod from '@/examples/cards/components/PaymentMethod.vue'
|
|||
import ReportAnIssue from '@/examples/cards/components/ReportAnIssue.vue'
|
||||
import ShareDocument from '@/examples/cards/components/ShareDocument.vue'
|
||||
import TeamMembers from '@/examples/cards/components/TeamMembers.vue'
|
||||
import CardChat from '@/lib/registry/new-york/example/CardChat.vue'
|
||||
import ActivityGoal from '@/lib/registry/new-york/example/Cards/ActivityGoal.vue'
|
||||
import DataTable from '@/lib/registry/new-york/example/Cards/DataTable.vue'
|
||||
import CardChat from '@/registry/new-york/example/CardChat.vue'
|
||||
import ActivityGoal from '@/registry/new-york/example/Cards/ActivityGoal.vue'
|
||||
import DataTable from '@/registry/new-york/example/Cards/DataTable.vue'
|
||||
|
||||
import Metric from '@/lib/registry/new-york/example/Cards/Metric.vue'
|
||||
import CardStats from '@/lib/registry/new-york/example/CardStats.vue'
|
||||
import { Card } from '@/lib/registry/new-york/ui/card'
|
||||
import { RangeCalendar } from '@/lib/registry/new-york/ui/range-calendar'
|
||||
import Metric from '@/registry/new-york/example/Cards/Metric.vue'
|
||||
import CardStats from '@/registry/new-york/example/CardStats.vue'
|
||||
import { Card } from '@/registry/new-york/ui/card'
|
||||
import { RangeCalendar } from '@/registry/new-york/ui/range-calendar'
|
||||
import { getLocalTimeZone, today } from '@internationalized/date'
|
||||
|
||||
import { type Ref, ref } from 'vue'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { styles } from '@/registry/registry-styles'
|
||||
import { useStorage } from '@vueuse/core'
|
||||
import { styles } from '../../../src/lib/registry/styles'
|
||||
|
||||
export const useStyle = () => useStorage('selected-style', styles[0].name)
|
||||
|
|
|
|||
|
|
@ -30,22 +30,13 @@ export const docsConfig: DocsConfig = {
|
|||
title: 'Components',
|
||||
href: '/docs/components/accordion',
|
||||
},
|
||||
{
|
||||
title: 'Themes',
|
||||
href: '/themes',
|
||||
},
|
||||
{
|
||||
title: 'Examples',
|
||||
href: '/examples/mail',
|
||||
},
|
||||
{
|
||||
title: 'Blocks',
|
||||
href: '/blocks',
|
||||
},
|
||||
{
|
||||
title: 'GitHub',
|
||||
href: 'https://github.com/radix-vue/shadcn-vue',
|
||||
external: true,
|
||||
title: 'Themes',
|
||||
href: '/themes',
|
||||
},
|
||||
],
|
||||
sidebarNav: [
|
||||
|
|
@ -377,42 +368,42 @@ export const examples: Example[] = [
|
|||
{
|
||||
name: 'Mail',
|
||||
href: '/examples/mail',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/mail',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/mail',
|
||||
},
|
||||
{
|
||||
name: 'Dashboard',
|
||||
href: '/examples/dashboard',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/dashboard',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/dashboard',
|
||||
},
|
||||
{
|
||||
name: 'Cards',
|
||||
href: '/examples/cards',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/cards',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/cards',
|
||||
},
|
||||
// {
|
||||
// name: "Tasks",
|
||||
// href: "/examples/tasks",
|
||||
// label: "New",
|
||||
// code: "https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/tasks"
|
||||
// code: "https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/tasks"
|
||||
// },
|
||||
{
|
||||
name: 'Playground',
|
||||
href: '/examples/playground',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/playground',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/playground',
|
||||
},
|
||||
{
|
||||
name: 'Music',
|
||||
href: '/examples/music',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/music',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/music',
|
||||
},
|
||||
{
|
||||
name: 'Authentication',
|
||||
href: '/examples/authentication',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/examples/authentication',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/examples/authentication',
|
||||
},
|
||||
{
|
||||
name: 'Forms',
|
||||
href: '/examples/forms',
|
||||
code: 'https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/routes/examples/forms',
|
||||
code: 'https://github.com/unovue/shadcn-vue/tree/dev/apps/www/src/routes/examples/forms',
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { ScrollArea } from '@/lib/registry/default/ui/scroll-area'
|
||||
import { cn } from '@/lib/utils'
|
||||
import RadixIconsCode from '~icons/radix-icons/code'
|
||||
import RadixIconsExternalLink from '~icons/radix-icons/external-link'
|
||||
import { useData, useRoute } from 'vitepress'
|
||||
|
|
@ -11,41 +11,33 @@ import { docsConfig } from '../config/docs'
|
|||
const $route = useRoute()
|
||||
const { frontmatter } = useData()
|
||||
|
||||
const sourceLink = 'https://github.com/radix-vue/shadcn-vue/tree/dev/'
|
||||
const sourceLink = 'https://github.com/unovue/shadcn-vue/tree/dev/'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="border-b">
|
||||
<div class="container flex-1 items-start md:grid md:grid-cols-[220px_minmax(0,1fr)] md:gap-6 lg:grid-cols-[240px_minmax(0,1fr)] lg:gap-10">
|
||||
<aside
|
||||
class="fixed top-14 z-30 -ml-2 hidden h-[calc(100vh-3.5rem)] w-full shrink-0 md:sticky md:block overflow-y-auto"
|
||||
>
|
||||
<ScrollArea orientation="vertical" class="relative overflow-hidden h-full py-6 pr-6 lg:py-8" :type="'auto'">
|
||||
<div class="w-full">
|
||||
<div v-for="docsGroup in docsConfig.sidebarNav" :key="docsGroup.title" class="pb-4">
|
||||
<h4
|
||||
class="mb-1 rounded-md px-2 py-1 text-sm font-semibold"
|
||||
>
|
||||
{{ docsGroup.title }}
|
||||
<div class="container flex-1 items-start md:grid md:grid-cols-[220px_minmax(0,1fr)] md:gap-6 lg:grid-cols-[240px_minmax(0,1fr)] lg:gap-10">
|
||||
<aside class="fixed top-14 z-30 hidden h-[calc(100vh-3.5rem)] w-full shrink-0 border-r border-border/40 dark:border-border md:sticky md:block">
|
||||
<div class="no-scrollbar h-full overflow-auto py-6 pr-6 lg:py-8">
|
||||
<div v-for="docsGroup in docsConfig.sidebarNav" :key="docsGroup.title">
|
||||
<div class="pb-4">
|
||||
<h4 class="mb-1 rounded-md px-2 py-1 text-sm font-semibold">
|
||||
{{ docsGroup.title }}
|
||||
|
||||
<span v-if="docsGroup.label" class="ml-2 font-normal rounded-md bg-[#adfa1d] px-1.5 py-0.5 text-xs leading-none text-[#000000] no-underline group-hover:no-underline">
|
||||
{{ docsGroup.label }}
|
||||
</span>
|
||||
</h4>
|
||||
<span v-if="docsGroup.label" class="ml-2 font-normal rounded-md bg-[#adfa1d] px-1.5 py-0.5 text-xs leading-none text-[#000000] no-underline group-hover:no-underline">
|
||||
{{ docsGroup.label }}
|
||||
</span>
|
||||
</h4>
|
||||
|
||||
<div
|
||||
<div class="grid grid-flow-row auto-rows-max gap-0.5 text-sm">
|
||||
<template
|
||||
v-for="doc in docsGroup.items "
|
||||
:key="doc.title"
|
||||
class="grid grid-flow-row auto-rows-max text-sm"
|
||||
>
|
||||
<a
|
||||
v-if="doc.href"
|
||||
:disabled="doc.disabled"
|
||||
:href="doc.href"
|
||||
class="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground"
|
||||
:class="{
|
||||
'!font-semibold !text-foreground': $route.path === `${doc.href}.html`,
|
||||
}"
|
||||
:class="cn('group flex w-full items-center px-2 py-1 font-normal text-foreground underline-offset-2 hover:underline', doc.disabled && 'cursor-not-allowed opacity-60', $route.path === `${doc.href}.html` && 'underline')"
|
||||
>
|
||||
{{ doc.title }}
|
||||
|
||||
|
|
@ -53,61 +45,61 @@ const sourceLink = 'https://github.com/radix-vue/shadcn-vue/tree/dev/'
|
|||
{{ doc.label }}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="relative py-6 lg:gap-10 lg:py-8 xl:grid xl:grid-cols-[1fr_300px]">
|
||||
<div class="mx-auto w-full min-w-0">
|
||||
<div class="block xl:hidden">
|
||||
<TableOfContent />
|
||||
</div>
|
||||
|
||||
<DocsBreadcrumb class="mb-4" />
|
||||
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center space-x-4">
|
||||
<h1 class="scroll-m-20 text-4xl font-bold tracking-tight">
|
||||
{{ frontmatter.title }}
|
||||
</h1>
|
||||
<span v-if="frontmatter.label" class="ml-2 rounded-md bg-[#adfa1d] px-1.5 py-0.5 text-xs leading-none text-[#000000] no-underline group-hover:no-underline">
|
||||
{{ frontmatter.label }}
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-lg text-muted-foreground">
|
||||
{{ frontmatter.description }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-2 pt-4">
|
||||
<a v-if="frontmatter.docs" :href="frontmatter.docs" target="_blank" class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 select-none border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80">
|
||||
<RadixIconsExternalLink class="mr-1" />
|
||||
Docs
|
||||
</a>
|
||||
<a v-if="frontmatter.source" :href="sourceLink + frontmatter.source" target="_blank" class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 select-none border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80">
|
||||
<RadixIconsCode class="mr-1" />
|
||||
Component Source
|
||||
</a>
|
||||
<a v-if="frontmatter.primitive" :href="frontmatter.primitive" target="_blank" class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 select-none border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80">
|
||||
Primitive API Reference
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="vp-doc">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<EditLink />
|
||||
<main class="relative py-6 lg:gap-10 lg:py-8 xl:grid xl:grid-cols-[1fr_300px]">
|
||||
<div class="mx-auto w-full min-w-0 max-w-3xl">
|
||||
<div class="block xl:hidden">
|
||||
<TableOfContent />
|
||||
</div>
|
||||
|
||||
<div class="hidden text-sm xl:block">
|
||||
<div class="sticky top-16 -mt-10 h-[calc(100vh-3.5rem)] overflow-hidden pt-6">
|
||||
<TableOfContent show-carbon-ads />
|
||||
<DocsBreadcrumb class="mb-4" />
|
||||
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center space-x-4">
|
||||
<h1 class="scroll-m-20 text-3xl font-bold tracking-tight">
|
||||
{{ frontmatter.title }}
|
||||
</h1>
|
||||
<span v-if="frontmatter.label" class="ml-2 rounded-md bg-[#adfa1d] px-1.5 py-0.5 text-xs leading-none text-[#000000] no-underline group-hover:no-underline">
|
||||
{{ frontmatter.label }}
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-base text-muted-foreground">
|
||||
{{ frontmatter.description }}
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<div v-if="frontmatter.docs || frontmatter.source || frontmatter.primitive" class="flex items-center space-x-2 pt-4">
|
||||
<a v-if="frontmatter.docs" :href="frontmatter.docs" target="_blank" class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 select-none border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80">
|
||||
<RadixIconsExternalLink class="mr-1" />
|
||||
Docs
|
||||
</a>
|
||||
<a v-if="frontmatter.source" :href="sourceLink + frontmatter.source" target="_blank" class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 select-none border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80">
|
||||
<RadixIconsCode class="mr-1" />
|
||||
Component Source
|
||||
</a>
|
||||
<a v-if="frontmatter.primitive" :href="frontmatter.primitive" target="_blank" class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 select-none border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80">
|
||||
Primitive API Reference
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="vp-doc py-8">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<EditLink />
|
||||
</div>
|
||||
|
||||
<div class="hidden text-sm xl:block">
|
||||
<div class="sticky top-20 -mt-6 h-[calc(100vh-3.5rem)] pt-4">
|
||||
<TableOfContent show-carbon-ads />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { buttonVariants } from '@/lib/registry/new-york/ui/button'
|
||||
import { cn } from '@/lib/utils'
|
||||
import Button from '@/registry/new-york/ui/button/Button.vue'
|
||||
import Announcement from '../components/Announcement.vue'
|
||||
import ExamplesNav from '../components/ExamplesNav.vue'
|
||||
import PageAction from '../components/PageAction.vue'
|
||||
|
|
@ -11,43 +10,39 @@ import PageHeaderHeading from '../components/PageHeaderHeading.vue'
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container relative">
|
||||
<PageHeader class="page-header pb-8">
|
||||
<div class="relative">
|
||||
<PageHeader>
|
||||
<Announcement />
|
||||
<PageHeaderHeading class="hidden md:block">
|
||||
Check out some examples.
|
||||
</PageHeaderHeading>
|
||||
<PageHeaderHeading class="md:hidden">
|
||||
Examples
|
||||
</PageHeaderHeading>
|
||||
<PageHeaderHeading>Build your component library</PageHeaderHeading>
|
||||
<PageHeaderDescription>
|
||||
Dashboard, cards, authentication. Some examples built using the
|
||||
components. Use this as a guide to build your own.
|
||||
Beautifully designed components that you can copy and paste into your apps. Made with Tailwind CSS. Open source.
|
||||
</PageHeaderDescription>
|
||||
|
||||
<PageAction>
|
||||
<a
|
||||
href="/docs/introduction"
|
||||
:class="cn(buttonVariants(), 'rounded-[6px]')"
|
||||
>
|
||||
Get Started
|
||||
</a>
|
||||
<a
|
||||
href="/docs/components/accordion"
|
||||
:class="cn(
|
||||
buttonVariants({ variant: 'outline' }),
|
||||
'rounded-[6px]',
|
||||
)"
|
||||
>
|
||||
Components
|
||||
</a>
|
||||
<Button as-child size="sm">
|
||||
<a href="/docs/introduction">
|
||||
Get Started
|
||||
</a>
|
||||
</Button>
|
||||
<Button as-child size="sm" variant="ghost">
|
||||
<a
|
||||
href="https://github.com/unovue/shadcn-vue"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
GitHub
|
||||
</a>
|
||||
</Button>
|
||||
</PageAction>
|
||||
</PageHeader>
|
||||
<section>
|
||||
<ExamplesNav />
|
||||
<div class="overflow-hidden rounded-[0.5rem] border bg-background shadow">
|
||||
<slot />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="container py-6">
|
||||
<section>
|
||||
<ExamplesNav class="[&>a:first-child]:text-primary" />
|
||||
<div class="overflow-hidden rounded-[0.5rem] border bg-background shadow">
|
||||
<slot />
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,27 +1,28 @@
|
|||
<script setup lang="ts">
|
||||
import { Button } from '@/lib/registry/default/ui/button'
|
||||
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from '@/lib/registry/default/ui/command'
|
||||
import { Dialog, DialogContent } from '@/lib/registry/default/ui/dialog'
|
||||
import { Toaster as DefaultToaster } from '@/lib/registry/default/ui/toast'
|
||||
import { Toaster as NewYorkSonner } from '@/lib/registry/new-york/ui/sonner'
|
||||
import { Toaster as NewYorkToaster } from '@/lib/registry/new-york/ui/toast'
|
||||
import { TooltipProvider } from '@/lib/registry/new-york/ui/tooltip'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Button } from '@/registry/default/ui/button'
|
||||
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from '@/registry/default/ui/command'
|
||||
import { Dialog, DialogContent } from '@/registry/default/ui/dialog'
|
||||
import { Toaster as DefaultToaster } from '@/registry/default/ui/toast'
|
||||
import { Toaster as NewYorkSonner } from '@/registry/new-york/ui/sonner'
|
||||
import { Toaster as NewYorkToaster } from '@/registry/new-york/ui/toast'
|
||||
|
||||
import { TooltipProvider } from '@/registry/new-york/ui/tooltip'
|
||||
import { useConfigStore } from '@/stores/config'
|
||||
import { useMagicKeys, useToggle } from '@vueuse/core'
|
||||
import Circle from '~icons/radix-icons/circle'
|
||||
|
||||
import MoonIcon from '~icons/lucide/moon'
|
||||
import SunIcon from '~icons/lucide/sun'
|
||||
import Circle from '~icons/radix-icons/circle'
|
||||
import File from '~icons/radix-icons/file'
|
||||
import RadixIconsGithubLogo from '~icons/radix-icons/github-logo'
|
||||
import RadixIconsMoon from '~icons/radix-icons/moon'
|
||||
import RadixIconsSun from '~icons/radix-icons/sun'
|
||||
import GithubLogoIcon from '~icons/radix-icons/github-logo'
|
||||
import { Content, useData, useRoute, useRouter } from 'vitepress'
|
||||
import { onMounted, ref, watch } from 'vue'
|
||||
import CodeConfigCustomizer from '../components/CodeConfigCustomizer.vue'
|
||||
import Kbd from '../components/Kbd.vue'
|
||||
import Logo from '../components/Logo.vue'
|
||||
import MobileNav from '../components/MobileNav.vue'
|
||||
|
||||
import MobileNav from '../components/MobileNav.vue'
|
||||
import ThemePopover from '../components/ThemePopover.vue'
|
||||
import { docsConfig, type NavItem } from '../config/docs'
|
||||
|
||||
|
|
@ -42,13 +43,8 @@ const links = [
|
|||
{
|
||||
name: 'GitHub',
|
||||
href: 'https://github.com/unovue/shadcn-vue',
|
||||
icon: RadixIconsGithubLogo,
|
||||
icon: GithubLogoIcon,
|
||||
},
|
||||
// {
|
||||
// name: 'X',
|
||||
// href: 'https://x.com',
|
||||
// icon: TablerBrandX,
|
||||
// },
|
||||
]
|
||||
|
||||
const isOpen = ref(false)
|
||||
|
|
@ -75,9 +71,7 @@ function handleSelectLink(item: NavItem) {
|
|||
}
|
||||
|
||||
watch(() => $route.path, (n) => {
|
||||
// @ts-expect-error View Transition API not supported by all the browser yet
|
||||
if (document.startViewTransition) {
|
||||
// @ts-expect-error View Transition API not supported by all the browser yet
|
||||
document.startViewTransition(() => {
|
||||
console.log('soft navigating to: ', n)
|
||||
})
|
||||
|
|
@ -90,27 +84,19 @@ watch(() => $route.path, (n) => {
|
|||
<div v-if="$route.data.frontmatter.layout === false">
|
||||
<Content :key="$route.path" />
|
||||
</div>
|
||||
<div v-else vaul-drawer-wrapper class="flex min-h-screen flex-col bg-background">
|
||||
<header class="sticky z-40 top-0 bg-background/80 backdrop-blur-lg border-b border-border">
|
||||
<div
|
||||
class="container flex h-14 max-w-screen-2xl items-center"
|
||||
>
|
||||
<div v-else vaul-drawer-wrapper class="mx-auto w-full border-border/40 dark:border-border min-[1800px]:max-w-[1536px] min-[1800px]:border-x">
|
||||
<header class="sticky top-0 z-50 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 dark:border-border">
|
||||
<div class="flex h-14 items-center px-4">
|
||||
<div class="mr-4 md:mr-1 hidden md:flex">
|
||||
<Logo />
|
||||
|
||||
<nav
|
||||
class="flex items-center max-lg:space-x-4 space-x-6 text-sm font-medium"
|
||||
>
|
||||
<nav class="flex items-center gap-4 text-sm xl:gap-6">
|
||||
<a
|
||||
v-for="route in docsConfig.mainNav"
|
||||
:key="route.title"
|
||||
:href="route.href"
|
||||
:target="route.external ? '_target' : undefined"
|
||||
class="transition-colors hover:text-foreground/80 text-foreground/60"
|
||||
:class="{
|
||||
'font-semibold !text-foreground': $route.path === `${route.href}.html`,
|
||||
'hidden lg:block': route?.href?.includes('github'),
|
||||
}"
|
||||
:class="cn('transition-colors hover:text-foreground/80', $route.path === `${route.href}.html` ? 'text-foreground' : 'text-foreground/80')"
|
||||
>
|
||||
{{ route.title }}
|
||||
</a>
|
||||
|
|
@ -122,18 +108,18 @@ watch(() => $route.path, (n) => {
|
|||
<div class="w-full flex-1 md:w-auto md:flex-none">
|
||||
<Button
|
||||
variant="outline"
|
||||
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"
|
||||
class="relative h-8 w-full justify-start rounded-[0.5rem] bg-muted/50 text-sm font-normal text-muted-foreground shadow-none sm:pr-12 md:w-40 lg:w-56 xl:w-64"
|
||||
@click="isOpen = true"
|
||||
>
|
||||
<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 :size="'xs'" 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">
|
||||
⌘ K
|
||||
</Kbd>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<nav class="flex items-center">
|
||||
<nav class="flex items-center gap-0.5">
|
||||
<ThemePopover />
|
||||
|
||||
<CodeConfigCustomizer />
|
||||
|
|
@ -142,28 +128,26 @@ watch(() => $route.path, (n) => {
|
|||
v-for="link in links"
|
||||
:key="link.name"
|
||||
as="a"
|
||||
class="w-9 h-9"
|
||||
class="w-8 h-8"
|
||||
:href="link.href" target="_blank"
|
||||
:variant="'ghost'"
|
||||
:size="'icon'"
|
||||
>
|
||||
<component :is="link.icon" class="w-5 h-5" />
|
||||
<component :is="link.icon" class="w-4 h-4" />
|
||||
</Button>
|
||||
|
||||
<ClientOnly>
|
||||
<Button
|
||||
class="w-9 h-9"
|
||||
aria-label="Toggle dark mode"
|
||||
:variant="'ghost'"
|
||||
:size="'icon'"
|
||||
@click="toggleDark()"
|
||||
>
|
||||
<component
|
||||
:is="isDark ? RadixIconsSun : RadixIconsMoon"
|
||||
class="w-5 h-5 text-foreground"
|
||||
/>
|
||||
</Button>
|
||||
</ClientOnly>
|
||||
<Button
|
||||
class="w-8 h-8"
|
||||
aria-label="Toggle dark mode"
|
||||
:variant="'ghost'"
|
||||
:size="'icon'"
|
||||
@click="toggleDark()"
|
||||
>
|
||||
<component
|
||||
:is="isDark ? SunIcon : MoonIcon"
|
||||
class="w-4 h-4 text-foreground"
|
||||
/>
|
||||
</Button>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -184,7 +168,7 @@ watch(() => $route.path, (n) => {
|
|||
<component :is="frontmatter.layout" v-else-if="frontmatter.layout">
|
||||
<slot />
|
||||
</component>
|
||||
<main v-else class="container">
|
||||
<main v-else class="flex-1">
|
||||
<Transition name="fade" mode="out-in">
|
||||
<Content :key="$route.path" />
|
||||
</Transition>
|
||||
|
|
@ -192,42 +176,38 @@ watch(() => $route.path, (n) => {
|
|||
</Transition>
|
||||
</div>
|
||||
|
||||
<footer class="py-6 md:px-8 md:py-0">
|
||||
<footer class="border-t border-border/40 py-6 dark:border-border md:px-8 md:py-0">
|
||||
<div class="container flex flex-col items-center justify-between gap-4 md:h-24 md:flex-row">
|
||||
<div class="text-center text-sm leading-loose text-muted-foreground md:text-left">
|
||||
<span class="inline-block">
|
||||
Built and designed by
|
||||
<p class="text-balance text-center text-sm leading-loose text-muted-foreground md:text-left">
|
||||
<span>
|
||||
Built by
|
||||
<a
|
||||
href="https://twitter.com/shadcn"
|
||||
target="_blank"
|
||||
class="underline underline-offset-4 font-bold decoration-foreground"
|
||||
class="font-medium underline underline-offset-4"
|
||||
>
|
||||
shadcn
|
||||
</a>
|
||||
shadcn</a>.
|
||||
</span>
|
||||
<span class="ml-0.5"> . </span>
|
||||
<span class="inline-block ml-2">
|
||||
<span class="inline-block ml-1">
|
||||
Ported to Vue by
|
||||
<a
|
||||
href="https://github.com/radix-vue"
|
||||
href="https://twitter.com/unovue"
|
||||
target="_blank"
|
||||
class="underline underline-offset-4 font-bold decoration-foreground"
|
||||
class="font-medium underline underline-offset-4"
|
||||
>
|
||||
Radix Vue
|
||||
unovue
|
||||
</a>
|
||||
</span>
|
||||
<span class="ml-0.5"> . </span>
|
||||
<span class="inline-block ml-2">
|
||||
</span>.
|
||||
<span class="inline-block ml-1">
|
||||
The code source is available on
|
||||
<a
|
||||
href="https://github.com/unovue/shadcn-vue"
|
||||
target="_blank"
|
||||
class="underline underline-offset-4 font-bold decoration-foreground"
|
||||
class="font-medium underline underline-offset-4"
|
||||
>
|
||||
GitHub
|
||||
</a>
|
||||
GitHub</a>.
|
||||
</span>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
|
@ -281,7 +261,7 @@ watch(() => $route.path, (n) => {
|
|||
}
|
||||
"
|
||||
>
|
||||
<RadixIconsSun class="mr-2 h-5 w-5" />
|
||||
<SunIcon class="mr-2 h-5 w-5" />
|
||||
<span>Light Theme</span>
|
||||
</CommandItem>
|
||||
<CommandItem
|
||||
|
|
@ -294,7 +274,7 @@ watch(() => $route.path, (n) => {
|
|||
}
|
||||
"
|
||||
>
|
||||
<RadixIconsMoon class="mr-2 h-5 w-5" />
|
||||
<MoonIcon class="mr-2 h-5 w-5" />
|
||||
<span>Dark Theme</span>
|
||||
</CommandItem>
|
||||
</CommandGroup>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
import type { Color } from '../types/colors'
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/lib/registry/new-york/ui/dialog'
|
||||
import { Drawer, DrawerContent, DrawerTrigger } from '@/lib/registry/new-york/ui/drawer'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/lib/registry/new-york/ui/popover'
|
||||
import { Button } from '@/registry/new-york/ui/button'
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/registry/new-york/ui/dialog'
|
||||
import { Drawer, DrawerContent, DrawerTrigger } from '@/registry/new-york/ui/drawer'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'
|
||||
import { useConfigStore } from '@/stores/config'
|
||||
import { Paintbrush } from 'lucide-vue-next'
|
||||
import { onMounted, watch } from 'vue'
|
||||
import Announcement from '../components/Announcement.vue'
|
||||
import CustomizerCode from '../components/CustomizerCode.vue'
|
||||
import InlineThemePicker from '../components/InlineThemePicker.vue'
|
||||
import PageAction from '../components/PageAction.vue'
|
||||
|
|
@ -54,8 +54,9 @@ watch(radius, (radius) => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container relative">
|
||||
<div>
|
||||
<PageHeader>
|
||||
<Announcement />
|
||||
<PageHeaderHeading class="hidden md:block">
|
||||
Add colors. Make it yours.
|
||||
</PageHeaderHeading>
|
||||
|
|
@ -67,35 +68,33 @@ watch(radius, (radius) => {
|
|||
</PageHeaderDescription>
|
||||
|
||||
<PageAction>
|
||||
<InlineThemePicker class="gap-x-1 me-4 hidden lg:flex" :all-colors="allColors" />
|
||||
<InlineThemePicker class="gap-x-1 me-4 hidden lg:flex" />
|
||||
|
||||
<Drawer>
|
||||
<DrawerTrigger as-child>
|
||||
<Button variant="outline" class="md:hidden h-9 rounded-[0.5rem]">
|
||||
<Paintbrush class="w-4 h-4 mr-2" />
|
||||
<Button size="sm" class="md:hidden">
|
||||
Customize
|
||||
</Button>
|
||||
</DrawerTrigger>
|
||||
<DrawerContent class="p-6 pt-0">
|
||||
<ThemeCustomizer :all-colors="allColors" />
|
||||
<ThemeCustomizer />
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
<Popover>
|
||||
<PopoverTrigger as-child>
|
||||
<Button variant="outline" class="hidden md:flex h-9 rounded-[0.5rem]">
|
||||
<Paintbrush class="w-4 h-4 mr-2" />
|
||||
<Button size="sm">
|
||||
Customize
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent :side-offset="8" align="end" class="w-96">
|
||||
<ThemeCustomizer :all-colors="allColors" />
|
||||
<PopoverContent :side-offset="8" :align-offset="-76" align="end" class="w-[380px] p-6">
|
||||
<ThemeCustomizer />
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
|
||||
<Dialog>
|
||||
<DialogTrigger as-child>
|
||||
<Button class="h-9 ml-2 rounded-[0.5rem]">
|
||||
<Button variant="ghost" size="sm">
|
||||
Copy code
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
|
|
@ -111,9 +110,8 @@ watch(radius, (radius) => {
|
|||
</Dialog>
|
||||
</PageAction>
|
||||
</PageHeader>
|
||||
|
||||
<section>
|
||||
<slot />
|
||||
</section>
|
||||
</div>
|
||||
<section class="container py-6">
|
||||
<slot />
|
||||
</section>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,19 @@
|
|||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@font-face {
|
||||
font-family: "Geist";
|
||||
src: url("/fonts/Geist[wght].ttf");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "GeistMono";
|
||||
src: url("/fonts/GeistMono[wght].ttf");
|
||||
}
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--font-geist-sans: "geist-sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
--font-geist-sans: "Geist";
|
||||
--font-geist-mono: "GeistMono";
|
||||
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 240 10% 3.9%;
|
||||
|
|
@ -86,15 +95,40 @@
|
|||
}
|
||||
|
||||
|
||||
* {
|
||||
@apply border-border;
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
html {
|
||||
@apply scroll-smooth;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground overscroll-none;
|
||||
/* font-feature-settings: "rlig" 1, "calt" 1; */
|
||||
font-synthesis-weight: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
@supports (font: -apple-system-body) and (-webkit-appearance: none) {
|
||||
[data-wrapper] {
|
||||
@apply min-[1800px]:border-t;
|
||||
}
|
||||
}
|
||||
|
||||
/* Custom scrollbar styling. Thanks @pranathiperii. */
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: hsl(var(--border));
|
||||
border-radius: 5px;
|
||||
}
|
||||
* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: hsl(var(--border)) transparent;
|
||||
}
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
font-variation-settings: normal;
|
||||
}
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground min-h-screen antialiased font-sans;
|
||||
/* font-feature-settings: "rlig" 1, "calt" 1; */
|
||||
|
|
@ -119,16 +153,6 @@
|
|||
}
|
||||
|
||||
|
||||
/* Firefox */
|
||||
/* https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-color#browser_compatibility */
|
||||
html {
|
||||
scrollbar-color: hsl(215.4 16.3% 46.9% / 0.3);
|
||||
}
|
||||
|
||||
html.dark {
|
||||
scrollbar-color: hsl(215.4 16.3% 56.9% / 0.3);
|
||||
}
|
||||
|
||||
html.dark .shiki,
|
||||
html.dark .shiki span {
|
||||
color: var(--shiki-dark);
|
||||
|
|
@ -147,21 +171,40 @@
|
|||
|
||||
|
||||
@layer utilities {
|
||||
.step {
|
||||
counter-increment: step;
|
||||
}
|
||||
.step {
|
||||
counter-increment: step;
|
||||
}
|
||||
|
||||
.step:before {
|
||||
@apply absolute w-9 h-9 bg-muted rounded-full font-mono font-medium text-center text-base inline-flex items-center justify-center -indent-px border-4 border-background;
|
||||
@apply -ml-[50px] -mt-1;
|
||||
content: counter(step);
|
||||
}
|
||||
.step:before {
|
||||
@apply absolute w-9 h-9 bg-muted rounded-full font-mono font-medium text-center text-base inline-flex items-center justify-center -indent-px border-4 border-background;
|
||||
@apply ml-[-50px] mt-[-4px];
|
||||
content: counter(step);
|
||||
}
|
||||
|
||||
.chunk-container {
|
||||
@apply shadow-none;
|
||||
}
|
||||
|
||||
.chunk-container::after {
|
||||
content: "";
|
||||
@apply absolute -inset-4 shadow-xl rounded-xl border;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
/* Hide scrollbar for IE, Edge and Firefox */
|
||||
.no-scrollbar {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.container {
|
||||
@apply px-4;
|
||||
}
|
||||
.container {
|
||||
@apply px-4;
|
||||
}
|
||||
}
|
||||
|
||||
div[class^="language-"] {
|
||||
|
|
@ -180,18 +223,28 @@ pre code {
|
|||
}
|
||||
|
||||
.line-numbers-wrapper {
|
||||
@apply font-mono;
|
||||
@apply !font-mono;
|
||||
}
|
||||
|
||||
pre code .line {
|
||||
@apply px-4 min-h-4 !py-0.5 w-full inline-block leading-[--vp-code-line-height];
|
||||
@apply px-4 min-h-4 w-full inline-block leading-[--vp-code-line-height];
|
||||
}
|
||||
|
||||
.line-number {
|
||||
@apply !text-[.75rem] !inline-block text-muted-foreground leading-[--vp-code-line-height];
|
||||
font-size: .75rem ;
|
||||
color: hsla(0, 0%, 98%, .4) ;
|
||||
@apply !inline-block leading-[--vp-code-line-height];
|
||||
}
|
||||
|
||||
::view-transition-old(root),
|
||||
::view-transition-new(root) {
|
||||
animation-duration: 0.3s;
|
||||
}
|
||||
|
||||
.steps:first-child > h3:first-child {
|
||||
@apply mt-0;
|
||||
}
|
||||
|
||||
.steps > h3 {
|
||||
@apply mt-8 mb-4 text-base font-semibold !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
--vp-code-bg: hsl(var(--muted));
|
||||
--vp-c-divider: hsl(var(--muted));
|
||||
--vp-code-block-color: #fff
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -22,6 +22,10 @@
|
|||
outline: none;
|
||||
}
|
||||
|
||||
.vp-doc h2:first-child {
|
||||
@apply mt-0 pt-0;
|
||||
}
|
||||
|
||||
.vp-doc h1:not(:where(.not-docs *)) {
|
||||
letter-spacing: -0.02em;
|
||||
line-height: 40px;
|
||||
|
|
@ -167,39 +171,26 @@
|
|||
* Table
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/* .vp-doc table {
|
||||
display: block;
|
||||
border-collapse: collapse;
|
||||
margin: 20px 0;
|
||||
overflow-x: auto;
|
||||
.vp-doc table:not(:where(.not-docs *)) {
|
||||
@apply relative w-full overflow-hidden border-none text-sm;
|
||||
}
|
||||
|
||||
.vp-doc tr {
|
||||
border-top: 1px solid var(--vp-c-divider);
|
||||
transition: background-color 0.5s;
|
||||
.vp-doc tr:not(:where(.not-docs *)) {
|
||||
@apply m-0 border-b;
|
||||
}
|
||||
.vp-doc tbody:not(:where(.not-docs *)) tr:last-child {
|
||||
@apply border-b-0;
|
||||
}
|
||||
|
||||
.vp-doc tr:nth-child(2n) {
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
.vp-doc th:not(:where(.not-docs *)) {
|
||||
@apply px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right;
|
||||
}
|
||||
|
||||
.vp-doc th,
|
||||
.vp-doc td {
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
padding: 8px 16px;
|
||||
.vp-doc td:not(:where(.not-docs *)) {
|
||||
@apply px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right;
|
||||
}
|
||||
|
||||
.vp-doc th {
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--vp-c-text-2);
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
}
|
||||
|
||||
.vp-doc td {
|
||||
font-size: 14px;
|
||||
} */
|
||||
|
||||
/**
|
||||
* Decorational elements
|
||||
|
|
@ -328,18 +319,15 @@
|
|||
position: relative;
|
||||
z-index: 1;
|
||||
margin: 0;
|
||||
/* padding: 20px 0; */
|
||||
background: transparent;
|
||||
overflow-x: auto;
|
||||
@apply bg-zinc-950 dark:bg-zinc-900;
|
||||
}
|
||||
|
||||
.vp-doc [class*='language-'] code {
|
||||
display: block;
|
||||
/* padding: 0 24px; */
|
||||
width: fit-content;
|
||||
min-width: 100%;
|
||||
line-height: var(--vp-code-line-height);
|
||||
/* font-size: var(--vp-code-font-size); */
|
||||
color: var(--vp-code-block-color);
|
||||
transition: color 0.5s;
|
||||
}
|
||||
|
|
@ -350,8 +338,8 @@
|
|||
padding: 0 24px; */
|
||||
width: calc(100% + 2 * 24px);
|
||||
display: inline-block;
|
||||
@apply bg-[hsl(var(--muted))] dark:bg-[hsl(var(--muted))]
|
||||
}
|
||||
@apply bg-zinc-700/50;
|
||||
}
|
||||
|
||||
.vp-doc [class*='language-'] code .highlighted.error {
|
||||
background-color: var(--vp-code-line-error-color);
|
||||
|
|
@ -421,15 +409,16 @@
|
|||
.vp-doc .line-numbers-wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 3;
|
||||
z-index: 3;
|
||||
border-right: 1px solid var(--vp-code-block-divider-color);
|
||||
padding-top: 16px;
|
||||
padding-top: 14px;
|
||||
padding-left: 20px;
|
||||
width: 32px;
|
||||
text-align: center;
|
||||
font-family: var(--vp-font-family-mono);
|
||||
line-height: var(--vp-code-line-height);
|
||||
/* line-height: var(--vp-code-line-height); */
|
||||
font-size: var(--vp-code-font-size);
|
||||
color: var(--vp-code-line-number-color);
|
||||
transition:
|
||||
|
|
@ -441,20 +430,20 @@
|
|||
/*rtl:ignore*/
|
||||
direction: ltr;
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
top: 16px;
|
||||
/*rtl:ignore*/
|
||||
right: 12px;
|
||||
right: 16px;
|
||||
z-index: 3;
|
||||
border: 1px solid var(--vp-code-copy-code-border-color);
|
||||
border-radius: 4px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background-color: var(--vp-code-copy-code-bg);
|
||||
opacity: 0;
|
||||
/* opacity: 0; */
|
||||
cursor: pointer;
|
||||
background-image: var(--vp-icon-copy);
|
||||
background-position: 50%;
|
||||
background-size: 20px;
|
||||
background-size: 16px;
|
||||
background-repeat: no-repeat;
|
||||
transition:
|
||||
border-color 0.25s,
|
||||
|
|
@ -518,14 +507,10 @@
|
|||
transition:
|
||||
color 0.4s,
|
||||
opacity 0.4s;
|
||||
|
||||
|
||||
@apply text-gray-600;
|
||||
}
|
||||
|
||||
.vp-doc [class*='language-']:hover > button.copy + span.lang,
|
||||
.vp-doc [class*='language-'] > button.copy:focus + span.lang {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component: Team
|
||||
|
|
@ -575,4 +560,4 @@
|
|||
|
||||
.line-numbers-mode pre code .line {
|
||||
padding-left: 3rem !important;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import type { Style } from '@/lib/registry/styles'
|
||||
import type { RegistryStyle } from '@/registry/registry-styles'
|
||||
import sdk from '@stackblitz/sdk'
|
||||
import { getParameters } from 'codesandbox/lib/api/define'
|
||||
// @ts-expect-error ?raw
|
||||
import cssRaw from '../../../../../packages/cli/test/fixtures/frameworks/nuxt/assets/css/tailwind.css?raw'
|
||||
import { Index as demoIndex } from '../../../../www/__registry__'
|
||||
// @ts-expect-error ?raw
|
||||
import tailwindConfigRaw from '../../../tailwind.config?raw'
|
||||
// @ts-expect-error ?raw
|
||||
import cssRaw from '../../../../../packages/cli/test/fixtures/nuxt/assets/css/tailwind.css?raw'
|
||||
|
||||
export function makeCodeSandboxParams(componentName: string, style: Style, sources: Record<string, string>) {
|
||||
export function makeCodeSandboxParams(componentName: string, style: RegistryStyle, sources: Record<string, string>) {
|
||||
let files: Record<string, any> = {}
|
||||
files = constructFiles(componentName, style, sources)
|
||||
files['.codesandbox/Dockerfile'] = {
|
||||
|
|
@ -16,12 +16,12 @@ export function makeCodeSandboxParams(componentName: string, style: Style, sourc
|
|||
return getParameters({ files, template: 'node' })
|
||||
}
|
||||
|
||||
export function makeStackblitzParams(componentName: string, style: Style, sources: Record<string, string>) {
|
||||
export function makeStackblitzParams(componentName: string, style: RegistryStyle, 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`,
|
||||
title: `${componentName} - Reka UI`,
|
||||
files,
|
||||
template: 'node',
|
||||
}, {
|
||||
|
|
@ -73,7 +73,7 @@ export default defineConfig({
|
|||
},
|
||||
}
|
||||
|
||||
function constructFiles(componentName: string, style: Style, sources: Record<string, string>) {
|
||||
function constructFiles(componentName: string, style: RegistryStyle, sources: Record<string, string>) {
|
||||
const componentsJson = {
|
||||
style,
|
||||
tailwind: {
|
||||
|
|
@ -86,19 +86,19 @@ function constructFiles(componentName: string, style: Style, sources: Record<str
|
|||
utils: '@/utils',
|
||||
components: '@/components',
|
||||
},
|
||||
iconLibrary: 'lucide',
|
||||
}
|
||||
|
||||
const iconPackage = style === 'default' ? 'lucide-vue-next' : '@radix-icons/vue'
|
||||
const dependencies = {
|
||||
'vue': 'latest',
|
||||
'radix-vue': 'latest',
|
||||
'reka-ui': 'latest',
|
||||
'@radix-ui/colors': 'latest',
|
||||
'clsx': 'latest',
|
||||
'class-variance-authority': 'latest',
|
||||
'tailwind-merge': 'latest',
|
||||
'tailwindcss-animate': 'latest',
|
||||
[iconPackage]: 'latest',
|
||||
'shadcn-vue': 'latest',
|
||||
'lucide-vue-next': 'latest',
|
||||
'shadcn-vue': 'next',
|
||||
'typescript': 'latest',
|
||||
'vaul-vue': 'latest',
|
||||
'vue-sonner': 'latest',
|
||||
|
|
@ -117,7 +117,7 @@ function constructFiles(componentName: string, style: Style, sources: Record<str
|
|||
// 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')
|
||||
parsed = parsed.replaceAll(`@/registry/${style}`, '@/components')
|
||||
parsed = parsed.replaceAll('@/lib/utils', '@/utils')
|
||||
return parsed
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ function constructFiles(componentName: string, style: Style, sources: Record<str
|
|||
})
|
||||
|
||||
// @ts-expect-error componentName might not exist in Index
|
||||
const registryDependencies = demoIndex[style][componentName as any]?.registryDependencies?.filter(i => i !== 'utils')
|
||||
const registryDependencies = demoIndex[style][componentName as any]?.registryDependencies?.filter(i => i !== 'utils') ?? []
|
||||
|
||||
const files = {
|
||||
'package.json': {
|
||||
|
|
@ -206,7 +206,7 @@ createApp(App).mount('#app')`,
|
|||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-feature-settings: "rlig" 1, "calt" 1;
|
||||
}
|
||||
}
|
||||
|
||||
#app {
|
||||
@apply w-full flex items-center justify-center px-12;
|
||||
|
|
|
|||
1
apps/www/__registry__/.autogenerated
Normal file
1
apps/www/__registry__/.autogenerated
Normal file
|
|
@ -0,0 +1 @@
|
|||
// The content of this directory is autogenerated by the registry server.
|
||||
3702
apps/www/__registry__/block.ts
Normal file
3702
apps/www/__registry__/block.ts
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "www",
|
||||
"type": "module",
|
||||
"version": "0.11.3",
|
||||
"version": "1.0.0-next.0",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
|
|
@ -17,50 +17,49 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@formkit/auto-animate": "^0.8.2",
|
||||
"@internationalized/date": "^3.5.5",
|
||||
"@internationalized/date": "^3.5.6",
|
||||
"@radix-icons/vue": "^1.0.0",
|
||||
"@stackblitz/sdk": "^1.11.0",
|
||||
"@tanstack/vue-table": "^8.20.5",
|
||||
"@unovis/ts": "^1.4.4",
|
||||
"@unovis/vue": "^1.4.4",
|
||||
"@vee-validate/zod": "^4.13.2",
|
||||
"@vueuse/core": "^11.1.0",
|
||||
"@vueuse/core": "^11.2.0",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
"codesandbox": "^2.2.3",
|
||||
"date-fns": "^4.1.0",
|
||||
"embla-carousel-autoplay": "^8.3.0",
|
||||
"embla-carousel-vue": "^8.3.0",
|
||||
"embla-carousel-autoplay": "^8.4.0",
|
||||
"embla-carousel-vue": "^8.4.0",
|
||||
"lucide-vue-next": "^0.441.0",
|
||||
"magic-string": "^0.30.11",
|
||||
"radix-vue": "catalog:",
|
||||
"magic-string": "^0.30.13",
|
||||
"reka-ui": "catalog:",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"v-calendar": "^3.1.2",
|
||||
"vaul-vue": "^0.2.0",
|
||||
"vee-validate": "4.13.2",
|
||||
"vue": "^3.5.6",
|
||||
"vue-sonner": "^1.1.5",
|
||||
"vue": "^3.5.13",
|
||||
"vue-sonner": "^1.2.5",
|
||||
"vue-wrap-balancer": "^1.2.1",
|
||||
"zod": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/traverse": "^7.25.6",
|
||||
"@iconify-json/gravity-ui": "^1.1.3",
|
||||
"@iconify-json/lucide": "^1.1.198",
|
||||
"@iconify-json/ph": "^1.1.13",
|
||||
"@iconify-json/radix-icons": "^1.1.14",
|
||||
"@iconify-json/ri": "^1.1.21",
|
||||
"@iconify-json/simple-icons": "^1.1.108",
|
||||
"@iconify-json/tabler": "^1.1.116",
|
||||
"@babel/traverse": "^7.25.9",
|
||||
"@iconify-json/gravity-ui": "^1.2.2",
|
||||
"@iconify-json/lucide": "^1.2.15",
|
||||
"@iconify-json/ph": "^1.2.1",
|
||||
"@iconify-json/radix-icons": "^1.2.1",
|
||||
"@iconify-json/ri": "^1.2.3",
|
||||
"@iconify-json/simple-icons": "^1.2.11",
|
||||
"@iconify-json/tabler": "^1.2.8",
|
||||
"@iconify/vue": "^4.1.2",
|
||||
"@oxc-parser/wasm": "catalog:",
|
||||
"@shikijs/transformers": "^1.17.7",
|
||||
"@shikijs/transformers": "^1.23.1",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^22.5.5",
|
||||
"@vitejs/plugin-vue": "^5.1.4",
|
||||
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
||||
"@vue/compiler-core": "^3.5.6",
|
||||
"@vue/compiler-dom": "^3.5.6",
|
||||
"@types/node": "^22.9.0",
|
||||
"@vitejs/plugin-vue": "^5.2.0",
|
||||
"@vitejs/plugin-vue-jsx": "^4.1.0",
|
||||
"@vue/compiler-core": "^3.5.13",
|
||||
"@vue/compiler-dom": "^3.5.13",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"fast-glob": "^3.3.2",
|
||||
|
|
@ -68,14 +67,14 @@
|
|||
"markdown-it": "^14.1.0",
|
||||
"pathe": "^1.1.2",
|
||||
"rimraf": "^6.0.1",
|
||||
"shiki": "^1.22.1",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"tailwindcss": "^3.4.12",
|
||||
"tsx": "^4.19.1",
|
||||
"shiki": "^1.23.1",
|
||||
"tailwind-merge": "^2.5.4",
|
||||
"tailwindcss": "^3.4.15",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "catalog:",
|
||||
"unplugin-icons": "^0.19.3",
|
||||
"vitepress": "^1.3.4",
|
||||
"vue-component-meta": "^2.1.6",
|
||||
"vue-tsc": "^2.1.6"
|
||||
"vitepress": "^1.5.0",
|
||||
"vue-component-meta": "^2.1.10",
|
||||
"vue-tsc": "^2.1.10"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const tsconfigChecker = createComponentMetaChecker(
|
|||
)
|
||||
|
||||
const components = fg.sync(['chart/**/*.vue', 'chart*/**/*.vue'], {
|
||||
cwd: resolve(__dirname, ROOTPATH, 'src/lib/registry/default/ui/'),
|
||||
cwd: resolve(__dirname, ROOTPATH, 'registry/default/ui/'),
|
||||
absolute: true,
|
||||
})
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
28
apps/www/scripts/fix-import.ts
Normal file
28
apps/www/scripts/fix-import.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
export function fixImport(content: string) {
|
||||
// eslint-disable-next-line regexp/no-super-linear-backtracking
|
||||
const regex = /@\/(.+?)\/((?:.*?\/)?(?:components|ui|hooks|lib))\/([\w-]+)/g
|
||||
|
||||
const replacement = (
|
||||
match: string,
|
||||
path: string,
|
||||
type: string,
|
||||
component: string,
|
||||
) => {
|
||||
if (type.endsWith('components')) {
|
||||
return `@/components/${component}`
|
||||
}
|
||||
else if (type.endsWith('ui')) {
|
||||
return `@/components/ui/${component}`
|
||||
}
|
||||
else if (type.endsWith('hooks')) {
|
||||
return `@/hooks/${component}`
|
||||
}
|
||||
else if (type.endsWith('lib')) {
|
||||
return `@/lib/${component}`
|
||||
}
|
||||
|
||||
return match
|
||||
}
|
||||
|
||||
return content.replace(regex, replacement)
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@
|
|||
<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">
|
||||
<mxCell id="PaMXV6_IjdSjTMUUNi7L-13" 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="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">
|
||||
|
|
|
|||
|
|
@ -5,16 +5,16 @@ description: Powered by amazing open source projects.
|
|||
|
||||
## About
|
||||
|
||||
[shadcn-vue](https://shadcn-vue.com) is a port of [shadcn/ui](https://ui.shadcn.com) for Vue/Nuxt. It's maintained by [radix-vue](https://github.com/radix-vue).
|
||||
[shadcn-vue](https://shadcn-vue.com) is a port of [shadcn/ui](https://ui.shadcn.com) for Vue/Nuxt. It's maintained by [unovue](https://github.com/unovue).
|
||||
|
||||
## Credits
|
||||
|
||||
- [shadcn](https://twitter.com/shadcn) - The brilliant mind behind the designs, methodology, and implementation of the original [shadcn/ui](https://ui.shadcn.com).
|
||||
- [Radix Vue](https://radix-vue.com) - The headless components that power this project.
|
||||
- [Radix Vue](https://reka-ui.com) - The headless components that power this project.
|
||||
- [Radix UI](https://radix-ui.com) - The headless components and examples that the original [shadcn/ui](https://ui.shadcn.com) was built on.
|
||||
- [Shu Ding](https://shud.in) - The typography style is adapted from his work on Nextra.
|
||||
- [Cal](https://cal.com) - Where shad copied the styles for the first component: the `Button`.
|
||||
|
||||
## License
|
||||
|
||||
MIT © [shadcn](https://shadcn.com) & [radix-vue](https://github.com/radix-vue)
|
||||
MIT © [shadcn](https://shadcn.com) & [unovue](https://github.com/unovue)
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ The following form has been created by passing a `zod` schema object to our `Aut
|
|||
|
||||
### Component Updated - Calendar
|
||||
|
||||
The [`Calendar`](/docs/components/calendar.html) component has been updated and is now built on top of the [RadixVue Calendar](https://www.radix-vue.com/components/calendar.html) component, which uses the [@internationalized/date](https://react-spectrum.adobe.com/internationalized/date/index.html) package to handle dates.
|
||||
The [`Calendar`](/docs/components/calendar.html) component has been updated and is now built on top of the [RadixVue Calendar](https://www.reka-ui.com/components/calendar.html) component, which uses the [@internationalized/date](https://react-spectrum.adobe.com/internationalized/date/index.html) package to handle dates.
|
||||
|
||||
If you're looking for a range calendar, check out the [`Range Calendar`](/docs/components/range-calendar.html) component.
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ And if you're looking for a date picker input, check out the [`Date Picker`](/do
|
|||
|
||||
### New Component - Drawer
|
||||
|
||||
[`Drawer`](/docs/components/drawer.html) - A drawer component for vue that is built on top of [Vaul Vue](https://github.com/radix-vue/vaul-vue).
|
||||
[`Drawer`](/docs/components/drawer.html) - A drawer component for vue that is built on top of [Vaul Vue](https://github.com/unovue/vaul-vue).
|
||||
|
||||
<ComponentPreview name="DrawerDemo" />
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ However, you can always pass in the desired `color` into each chart.
|
|||
## Custom tooltip
|
||||
|
||||
If you want to customize the `Tooltip` for the chart, you can pass `customTooltip` prop with a custom Vue component.
|
||||
The custom component would receive `title` and `data` props, check out [ChartTooltip.vue component](https://github.com/radix-vue/shadcn-vue/tree/dev/apps/www/src/lib/registry/default/ui/chart/ChartTooltip.vue) for example.
|
||||
The custom component would receive `title` and `data` props, check out [ChartTooltip.vue component](https://github.com/unovue/shadcn-vue/tree/dev/apps/www/registry/default/ui/chart/ChartTooltip.vue) for example.
|
||||
|
||||
The expected prop definition would be:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Area
|
||||
description: An area chart visually represents data over time, displaying trends and patterns through filled-in areas under a line graph.
|
||||
source: apps/www/src/lib/registry/default/ui/chart-area
|
||||
source: apps/www/registry/default/ui/chart-area
|
||||
label: Alpha
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Bar
|
||||
description: A line chart visually represents data using rectangular bars of varying lengths to compare quantities across different categories or groups.
|
||||
source: apps/www/src/lib/registry/default/ui/chart-bar
|
||||
source: apps/www/registry/default/ui/chart-bar
|
||||
label: Alpha
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Donut
|
||||
description: A line chart visually represents data in a circular form, similar to a pie chart but with a central void, emphasizing proportions within categories.
|
||||
source: apps/www/src/lib/registry/default/ui/chart-donut
|
||||
source: apps/www/registry/default/ui/chart-donut
|
||||
label: Alpha
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Line
|
||||
description: A line chart visually displays data points connected by straight lines, illustrating trends or relationships over a continuous axis.
|
||||
source: apps/www/src/lib/registry/default/ui/chart-line
|
||||
source: apps/www/registry/default/ui/chart-line
|
||||
label: Alpha
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ description: Use the CLI to add components to your project.
|
|||
|
||||
Use the `init` command to initialize configuration and dependencies for a new project.
|
||||
|
||||
The `init` command installs dependencies, adds the `cn`, `useEmitsAsProps` utils, configures `tailwind.config.cjs`, and creates CSS variables for the project.
|
||||
The `init` command installs dependencies, adds the `cn` util, configures `tailwind.config.js`, and CSS variables for the project.
|
||||
|
||||
```bash
|
||||
npx shadcn-vue@latest init
|
||||
|
|
@ -15,28 +15,27 @@ npx shadcn-vue@latest init
|
|||
|
||||
You will be asked a few questions to configure `components.json`:
|
||||
|
||||
```ansi:line-numbers
|
||||
Would you like to use TypeScript (recommended)? no / yes
|
||||
Which framework are you using? Vite / Nuxt / Laravel
|
||||
Which style would you like to use? › Default
|
||||
Which color would you like to use as base color? › Slate
|
||||
Where is your global CSS file? › › src/index.css
|
||||
```:line-numbers
|
||||
Which style would you like to use? › New York
|
||||
Which color would you like to use as base color? › Zinc
|
||||
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
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```ansi
|
||||
Usage: shadcn-vue init [options]
|
||||
```txt
|
||||
Usage: shadcn-vue init [options] [components...]
|
||||
|
||||
initialize your project and install dependencies
|
||||
|
||||
Arguments:
|
||||
components the components to add or a url to the component.
|
||||
|
||||
Options:
|
||||
-y, --yes skip confirmation prompt. (default: false)
|
||||
-c, --cwd <cwd> the working directory. (default: the current directory)
|
||||
-d, --defaults use default values i.e new-york, zinc and css variables. (default: false)
|
||||
-f, --force force overwrite of existing components.json. (default: false)
|
||||
-y, --yes skip confirmation prompt. (default: false)
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
|
|
@ -50,8 +49,9 @@ npx shadcn-vue@latest add [component]
|
|||
|
||||
You will be presented with a list of components to choose from:
|
||||
|
||||
```ansi
|
||||
Which components would you like to add? › Space to select. Return to submit.
|
||||
```txt
|
||||
Which components would you like to add? › Space to select. A to toggle all.
|
||||
Enter to submit.
|
||||
|
||||
◯ accordion
|
||||
◯ alert
|
||||
|
|
@ -60,45 +60,40 @@ Which components would you like to add? › Space to select. Return to submit.
|
|||
◯ avatar
|
||||
◯ badge
|
||||
◯ button
|
||||
◯ calendar
|
||||
◯ card
|
||||
◯ checkbox
|
||||
◯ collapsible
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```ansi
|
||||
```txt
|
||||
Usage: shadcn-vue add [options] [components...]
|
||||
|
||||
add components to your project
|
||||
add a component to your project
|
||||
|
||||
Arguments:
|
||||
components name of components
|
||||
components the components to add or a url to the component.
|
||||
|
||||
Options:
|
||||
--nodep disable adding & installing dependencies (advanced) (default: false)
|
||||
-y, --yes Skip confirmation prompt. (default: false)
|
||||
-y, --yes skip confirmation prompt. (default: false)
|
||||
-o, --overwrite overwrite existing files. (default: false)
|
||||
-c, --cwd <cwd> the working directory. (default: the current directory)
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
-a, --all add all available components. (default: false)
|
||||
-p, --path <path> the path to add the component to.
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
## update
|
||||
## Monorepo
|
||||
|
||||
Use the `update` command to update components in your project. This will overwrite any modifications you've made to the components, so be sure to commit your changes before running this command.
|
||||
In a monorepo, you can specify the path to your workspace with the `-c` or `--cwd` option.
|
||||
|
||||
We plan on improving this command in the future to improve the update experience.
|
||||
|
||||
```ansi
|
||||
Usage: shadcn-vue update [options] [components...]
|
||||
|
||||
update components in your project
|
||||
|
||||
Arguments:
|
||||
components name of components
|
||||
|
||||
Options:
|
||||
-c, --cwd <cwd> the working directory. (default: the current directory)
|
||||
-h, --help display help for command
|
||||
```bash
|
||||
npx shadcn-vue@latest init -c ./apps/www
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
npx shadcn-vue@latest add alert-dialog -c ./apps/www
|
||||
```
|
||||
|
|
|
|||
|
|
@ -108,6 +108,18 @@ 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.
|
||||
|
||||
### tailwind.prefix
|
||||
|
||||
The prefix to use for your Tailwind CSS utility classes. Components will be added with this prefix.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"tailwind": {
|
||||
"prefix": "tw-"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
|
@ -160,3 +172,27 @@ The CLI will use the `aliases.ui` value to determine where to place your `ui` co
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
### aliases.lib
|
||||
|
||||
Import alias for `lib` functions such as `format-date` or `generate-id`.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"lib": "@/lib"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### aliases.hooks
|
||||
|
||||
Import alias for `hooks` such as `use-media-query` or `use-toast`.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"hooks": "@/hooks"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
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
|
||||
primitive: https://www.radix-vue.com/components/accordion.html
|
||||
source: apps/www/registry/default/ui/accordion
|
||||
primitive: https://www.reka-ui.com/docs/components/accordion.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="AccordionDemo" class="sm:max-w-[70%]" />
|
||||
|
|
@ -29,10 +29,10 @@ module.exports = {
|
|||
keyframes: {
|
||||
'accordion-down': {
|
||||
from: { height: 0 },
|
||||
to: { height: 'var(--radix-accordion-content-height)' },
|
||||
to: { height: 'var(--reka-accordion-content-height)' },
|
||||
},
|
||||
'accordion-up': {
|
||||
from: { height: 'var(--radix-accordion-content-height)' },
|
||||
from: { height: 'var(--reka-accordion-content-height)' },
|
||||
to: { height: 0 },
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
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
|
||||
primitive: https://www.radix-vue.com/components/alert-dialog.html
|
||||
source: apps/www/registry/default/ui/alert-dialog
|
||||
primitive: https://www.reka-ui.com/docs/components/alert-dialog.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="AlertDialogDemo" />
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: Aspect Ratio
|
||||
description: Displays content within a desired ratio.
|
||||
source: apps/www/src/lib/registry/default/ui/aspect-ratio
|
||||
primitive: https://www.radix-vue.com/components/aspect-ratio.html
|
||||
source: apps/www/registry/default/ui/aspect-ratio
|
||||
primitive: https://www.reka-ui.com/docs/components/aspect-ratio.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="AspectRatioDemo" />
|
||||
|
|
@ -24,12 +24,12 @@ npx shadcn-vue@latest add aspect-ratio
|
|||
### Install the following dependency:
|
||||
|
||||
```bash
|
||||
npm install radix-vue
|
||||
npm install reka-ui
|
||||
```
|
||||
|
||||
### Copy and paste the following code into your project:
|
||||
|
||||
<<< @/lib/registry/default/ui/aspect-ratio/AspectRatio.vue
|
||||
<<< @/registry/default/ui/aspect-ratio/AspectRatio.vue
|
||||
|
||||
</Steps>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: Avatar
|
||||
description: An image element with a fallback for representing the user.
|
||||
source: apps/www/src/lib/registry/default/ui/avatar
|
||||
primitive: https://www.radix-vue.com/components/avatar.html
|
||||
source: apps/www/registry/default/ui/avatar
|
||||
primitive: https://www.reka-ui.com/docs/components/avatar.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="AvatarDemo" />
|
||||
|
|
@ -22,7 +22,7 @@ import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
|||
|
||||
<template>
|
||||
<Avatar>
|
||||
<AvatarImage src="https://github.com/radix-vue.png" alt="@radix-vue" />
|
||||
<AvatarImage src="https://github.com/unovue.png" alt="@unovue" />
|
||||
<AvatarFallback>CN</AvatarFallback>
|
||||
</Avatar>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,21 +1,15 @@
|
|||
---
|
||||
title: Calendar
|
||||
description: A date field component that allows users to enter and edit date.
|
||||
source: apps/www/src/lib/registry/default/ui/calendar
|
||||
primitive: https://www.radix-vue.com/components/calendar.html
|
||||
source: apps/www/registry/default/ui/calendar
|
||||
primitive: https://www.reka-ui.com/docs/components/calendar.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="CalendarDemo" />
|
||||
|
||||
<Callout class="text-base mt-12">
|
||||
|
||||
If you're looking for **previous** Calendar implementation, checkout to <span class="font-bold underline">[VCalendar](/docs/components/v-calendar)</span> component
|
||||
|
||||
</Callout>
|
||||
|
||||
## About
|
||||
|
||||
The `<Calendar />` component is built on top of the [RadixVue Calendar](https://www.radix-vue.com/components/calendar.html) component, which uses the [@internationalized/date](https://react-spectrum.adobe.com/internationalized/date/index.html) package to handle dates.
|
||||
The `<Calendar />` component is built on top of the [RadixVue Calendar](https://www.reka-ui.com/docs/components/calendar.html) component, which uses the [@internationalized/date](https://react-spectrum.adobe.com/internationalized/date/index.html) package to handle dates.
|
||||
|
||||
If you're looking for a range calendar, check out the [Range Calendar](/docs/components/range-calendar) component.
|
||||
|
||||
|
|
@ -26,7 +20,7 @@ npx shadcn-vue@latest add calendar
|
|||
```
|
||||
::: tip
|
||||
The component depends on the [@internationalized/date](https://react-spectrum.adobe.com/internationalized/date/index.html) package, which solves a lot of the problems that come with working with dates and times in JavaScript.
|
||||
Check [Dates & Times in Radix Vue](https://www.radix-vue.com/guides/dates.html) for more information and installation instructions.
|
||||
Check [Dates & Times in Radix Vue](https://www.reka-ui.com/docs/guides/dates.html) for more information and installation instructions.
|
||||
:::
|
||||
|
||||
## Datepicker
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Carousel
|
||||
description: A carousel with motion and swipe built using Embla.
|
||||
source: apps/www/src/lib/registry/default/ui/carousel
|
||||
source: apps/www/registry/default/ui/carousel
|
||||
primitive: https://www.embla-carousel.com/api
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
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
|
||||
primitive: https://www.radix-vue.com/components/checkbox.html
|
||||
source: apps/www/registry/default/ui/checkbox
|
||||
primitive: https://www.reka-ui.com/docs/components/checkbox.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="CheckboxDemo" />
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: Collapsible
|
||||
description: An interactive component which expands/collapses a panel.
|
||||
source: apps/www/src/lib/registry/default/ui/collapsible
|
||||
primitive: https://www.radix-vue.com/components/collapsible.html
|
||||
source: apps/www/registry/default/ui/collapsible
|
||||
primitive: https://www.reka-ui.com/docs/components/collapsible.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="CollapsibleDemo" />
|
||||
|
|
@ -29,10 +29,10 @@ module.exports = {
|
|||
keyframes: {
|
||||
'collapsible-down': {
|
||||
from: { height: 0 },
|
||||
to: { height: 'var(--radix-collapsible-content-height)' },
|
||||
to: { height: 'var(--reka-collapsible-content-height)' },
|
||||
},
|
||||
'collapsible-up': {
|
||||
from: { height: 'var(--radix-collapsible-content-height)' },
|
||||
from: { height: 'var(--reka-collapsible-content-height)' },
|
||||
to: { height: 0 },
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,22 +1,19 @@
|
|||
---
|
||||
title: Combobox
|
||||
description: Autocomplete input and command palette with a list of suggestions.
|
||||
source: apps/www/registry/default/ui/combobox
|
||||
primitive: https://www.reka-ui.com/docs/components/combobox.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="ComboboxDemo" />
|
||||
|
||||
<br>
|
||||
<Callout title="Note" class="bg-destructive">
|
||||
|
||||
[Radix Vue](https://github.com/radix-vue/radix-vue/releases/tag/v1.2.0) introduced a breaking change. You will need to wrap `ComboboxGroup` and `ComboboxItem` inside of `ComboboxList` now.
|
||||
|
||||
</Callout>
|
||||
|
||||
## Installation
|
||||
|
||||
The Combobox is built using a composition of the `<Popover />` and the `<Command />` components.
|
||||
|
||||
See installation instructions for the [Popover](/docs/components/popover#installation) and the [Command](/docs/components/command#installation) components.
|
||||
```bash
|
||||
npx shadcn-vue@latest add combobox
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
|
|
@ -97,11 +94,11 @@ const value = ref('')
|
|||
|
||||
## Examples
|
||||
|
||||
### Combobox
|
||||
### Combobox Trigger
|
||||
|
||||
<ComponentPreview name="ComboboxDemo" />
|
||||
<ComponentPreview name="ComboboxTrigger" />
|
||||
|
||||
### Popover
|
||||
<!-- ### Popover
|
||||
|
||||
<ComponentPreview name="ComboboxPopover" />
|
||||
|
||||
|
|
@ -113,7 +110,7 @@ const value = ref('')
|
|||
|
||||
You can create a responsive combobox by using the `<Popover />` on desktop and the `<Drawer />` components on mobile.
|
||||
|
||||
<ComponentPreview name="ComboboxResponsive" />
|
||||
<ComponentPreview name="ComboboxResponsive" /> -->
|
||||
|
||||
### Form
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: Command
|
||||
description: Fast, composable, unstyled command menu.
|
||||
source: apps/www/src/lib/registry/default/ui/command
|
||||
primitive: https://www.radix-vue.com/components/combobox.html
|
||||
source: apps/www/registry/default/ui/command
|
||||
primitive: https://www.reka-ui.com/docs/components/listbox.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="CommandDemo" />
|
||||
|
|
@ -134,6 +134,28 @@ watch(CmdJ, (v) => {
|
|||
</template>
|
||||
```
|
||||
|
||||
### Combobox
|
||||
<br></br>
|
||||
|
||||
You can use the `<Command />` component as a combobox. See the [Combobox](/docs/components/combobox) page for more information.
|
||||
<Callout>
|
||||
|
||||
You can use the `<Command />` component like a combobox.
|
||||
|
||||
</Callout>
|
||||
|
||||
### Popover
|
||||
|
||||
<ComponentPreview name="CommandPopover" />
|
||||
|
||||
### Dropdown menu
|
||||
|
||||
<ComponentPreview name="CommandDropdownMenu" />
|
||||
|
||||
### Responsive
|
||||
|
||||
You can create a responsive combobox by using the `<Popover />` on desktop and the `<Drawer />` components on mobile.
|
||||
|
||||
<ComponentPreview name="CommandResponsive" />
|
||||
|
||||
### Form
|
||||
|
||||
<ComponentPreview name="CommandForm" />
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
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
|
||||
primitive: https://www.radix-vue.com/components/context-menu.html
|
||||
source: apps/www/registry/default/ui/context-menu
|
||||
primitive: https://www.reka-ui.com/docs/components/context-menu.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="ContextMenuDemo" />
|
||||
|
|
|
|||
|
|
@ -751,7 +751,7 @@ const table = useVueTable({
|
|||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuCheckboxItem
|
||||
v-for="column in table.getAllColumns().filter((column) => column.getCanHide())" :key="column.id"
|
||||
class="capitalize" :checked="column.getIsVisible()" @update:checked="(value) => {
|
||||
class="capitalize" :modelValue="column.getIsVisible()" @update:modelValue="(value) => {
|
||||
column.toggleVisibility(!!value)
|
||||
}">
|
||||
{{ column.id }}
|
||||
|
|
@ -814,13 +814,13 @@ export const columns: ColumnDef<Payment>[] = [
|
|||
{
|
||||
id: 'select',
|
||||
header: ({ table }) => h(Checkbox, {
|
||||
'checked': table.getIsAllPageRowsSelected(),
|
||||
'onUpdate:checked': (value: boolean) => table.toggleAllPageRowsSelected(!!value),
|
||||
'modelValue': table.getIsAllPageRowsSelected(),
|
||||
'onUpdate:modelValue': (value: boolean) => table.toggleAllPageRowsSelected(!!value),
|
||||
'ariaLabel': 'Select all',
|
||||
}),
|
||||
cell: ({ row }) => h(Checkbox, {
|
||||
'checked': row.getIsSelected(),
|
||||
'onUpdate:checked': (value: boolean) => row.toggleSelected(!!value),
|
||||
'modelValue': row.getIsSelected(),
|
||||
'onUpdate:modelValue': (value: boolean) => row.toggleSelected(!!value),
|
||||
'ariaLabel': 'Select row',
|
||||
}),
|
||||
enableSorting: false,
|
||||
|
|
@ -995,7 +995,7 @@ const table = useVueTable({
|
|||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuCheckboxItem
|
||||
v-for="column in table.getAllColumns().filter((column) => column.getCanHide())" :key="column.id"
|
||||
class="capitalize" :checked="column.getIsVisible()" @update:checked="(value) => {
|
||||
class="capitalize" :modelValue="column.getIsVisible()" @update:modelValue="(value) => {
|
||||
column.toggleVisibility(!!value)
|
||||
}">
|
||||
{{ column.id }}
|
||||
|
|
@ -1369,8 +1369,8 @@ const columns = computed(() => props.table.getAllColumns()
|
|||
v-for="column in columns"
|
||||
:key="column.id"
|
||||
class="capitalize"
|
||||
:checked="column.getIsVisible()"
|
||||
@update:checked="(value) => column.toggleVisibility(!!value)"
|
||||
:modelValue="column.getIsVisible()"
|
||||
@update:modelValue="(value) => column.toggleVisibility(!!value)"
|
||||
>
|
||||
{{ column.id }}
|
||||
</DropdownMenuCheckboxItem>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,12 @@
|
|||
---
|
||||
title: Date Picker
|
||||
description: A date picker component with range and presets.
|
||||
source: apps/www/src/lib/registry/default/example/DatePickerDemo.vue
|
||||
primitive: https://www.radix-vue.com/components/calendar.html
|
||||
source: apps/www/registry/default/example/DatePickerDemo.vue
|
||||
primitive: https://www.reka-ui.com/docs/components/calendar.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="DatePickerDemo" />
|
||||
|
||||
<Callout class="text-base mt-12">
|
||||
|
||||
If you're looking for **previous** Date Picker implementation, checkout to <span class="font-bold underline">[VCalendar Datepicker](/docs/components/v-date-picker)</span> component
|
||||
|
||||
</Callout>
|
||||
|
||||
## Installation
|
||||
|
||||
The Date Picker is built using a composition of the `<Popover />` and either the `<Calendar />` or `<RangeCalendar />` components.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
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
|
||||
primitive: https://www.radix-vue.com/components/dialog.html
|
||||
source: apps/www/registry/default/ui/dialog
|
||||
primitive: https://www.reka-ui.com/docs/components/dialog.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="DialogDemo" />
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
---
|
||||
title: Drawer
|
||||
description: A drawer component for vue.
|
||||
source: apps/www/src/lib/registry/default/ui/drawer
|
||||
primitive: https://github.com/radix-vue/vaul-vue
|
||||
source: apps/www/registry/default/ui/drawer
|
||||
primitive: https://github.com/unovue/vaul-vue
|
||||
---
|
||||
|
||||
<ComponentPreview name="DrawerDemo" />
|
||||
|
||||
## About
|
||||
|
||||
Drawer is built on top of [Vaul Vue](https://github.com/radix-vue/vaul-vue).
|
||||
Drawer is built on top of [Vaul Vue](https://github.com/unovue/vaul-vue).
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: Dropdown 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/dropdown-menu
|
||||
primitive: https://www.radix-vue.com/components/dropdown-menu.html
|
||||
source: apps/www/registry/default/ui/dropdown-menu
|
||||
primitive: https://www.reka-ui.com/docs/components/dropdown-menu.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="DropdownMenuDemo" />
|
||||
|
|
|
|||
|
|
@ -108,34 +108,34 @@ npx shadcn-vue@latest add form
|
|||
### Install the following dependency:
|
||||
|
||||
```bash
|
||||
npm install radix-vue vee-validate @vee-validate/zod zod
|
||||
npm install reka-ui vee-validate @vee-validate/zod zod
|
||||
```
|
||||
|
||||
### Copy and paste the following codes into your project:
|
||||
|
||||
`index.ts`
|
||||
|
||||
<<< @/lib/registry/default/ui/form/index.ts
|
||||
<<< @/registry/default/ui/form/index.ts
|
||||
|
||||
`FormItem.vue`
|
||||
|
||||
<<< @/lib/registry/default/ui/form/FormItem.vue
|
||||
<<< @/registry/default/ui/form/FormItem.vue
|
||||
|
||||
`FormLabel.vue`
|
||||
|
||||
<<< @/lib/registry/default/ui/form/FormLabel.vue
|
||||
<<< @/registry/default/ui/form/FormLabel.vue
|
||||
|
||||
`FormControl.vue`
|
||||
|
||||
<<< @/lib/registry/default/ui/form/FormControl.vue
|
||||
<<< @/registry/default/ui/form/FormControl.vue
|
||||
|
||||
`FormMessage.vue`
|
||||
|
||||
<<< @/lib/registry/default/ui/form/FormMessage.vue
|
||||
<<< @/registry/default/ui/form/FormMessage.vue
|
||||
|
||||
`FormDescription.vue`
|
||||
|
||||
<<< @/lib/registry/default/ui/form/FormDescription.vue
|
||||
<<< @/registry/default/ui/form/FormDescription.vue
|
||||
|
||||
### Update the import paths to match your project setup.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: Hover Card
|
||||
description: For sighted users to preview content available behind a link.
|
||||
source: apps/www/src/lib/registry/default/ui/hover-card
|
||||
primitive: https://www.radix-vue.com/components/hover-card.html
|
||||
source: apps/www/registry/default/ui/hover-card
|
||||
primitive: https://www.reka-ui.com/docs/components/hover-card.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="HoverCardDemo" />
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ npx shadcn-vue@latest add input
|
|||
|
||||
### Copy and paste the following code into your project:
|
||||
|
||||
<<< @/lib/registry/default/ui/input/Input.vue
|
||||
<<< @/registry/default/ui/input/Input.vue
|
||||
|
||||
</Steps>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: Label
|
||||
description: Renders an accessible label associated with controls.
|
||||
source: apps/www/src/lib/registry/default/ui/label
|
||||
primitive: https://www.radix-vue.com/components/label.html
|
||||
source: apps/www/registry/default/ui/label
|
||||
primitive: https://www.reka-ui.com/docs/components/label.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="LabelDemo" />
|
||||
|
|
@ -24,12 +24,12 @@ npx shadcn-vue@latest add label
|
|||
### Install the following dependency:
|
||||
|
||||
```bash
|
||||
npm install radix-vue
|
||||
npm install reka-ui
|
||||
```
|
||||
|
||||
### Copy and paste the following code into your project:
|
||||
|
||||
<<< @/lib/registry/default/ui/label/Label.vue
|
||||
<<< @/registry/default/ui/label/Label.vue
|
||||
|
||||
</Steps>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
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
|
||||
primitive: https://www.radix-vue.com/components/menubar.html
|
||||
source: apps/www/registry/default/ui/menubar
|
||||
primitive: https://www.reka-ui.com/docs/components/menubar.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="MenubarDemo" />
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: Navigation Menu
|
||||
description: A collection of links for navigating websites.
|
||||
source: apps/www/src/lib/registry/default/ui/navigation-menu
|
||||
primitive: https://www.radix-vue.com/components/navigation-menu.html
|
||||
source: apps/www/registry/default/ui/navigation-menu
|
||||
primitive: https://www.reka-ui.com/docs/components/navigation-menu.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="NavigationMenuDemo" />
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
title: Number Field
|
||||
description: A number field allows a user to enter a number and increment or decrement the value using stepper buttons.
|
||||
source: apps/www/src/lib/registry/default/ui/number-field
|
||||
primitive: https://www.radix-vue.com/components/number-field.html
|
||||
source: apps/www/registry/default/ui/number-field
|
||||
primitive: https://www.reka-ui.com/docs/components/number-field.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="NumberFieldDemo" class="max-w-[180px]" />
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user