feat: add auto registry, rename folder

This commit is contained in:
zernonia 2023-09-06 09:55:07 +08:00
parent 36716468d9
commit 8e762393d1
58 changed files with 7828 additions and 953 deletions

View File

@ -0,0 +1,385 @@
// This file is autogenerated by scripts/build-registry.ts
// Do not edit this file directly.
export const Index = {
"default": {
"AccordionDemo": {
name: "AccordionDemo",
type: "components:example",
registryDependencies: ["accordion"],
component: () => import("../src/lib/registry/default/example/AccordionDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/AccordionDemo.vue"],
},
"AlertDemo": {
name: "AlertDemo",
type: "components:example",
registryDependencies: ["alert"],
component: () => import("../src/lib/registry/default/example/AlertDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/AlertDemo.vue"],
},
"AlertDialogDemo": {
name: "AlertDialogDemo",
type: "components:example",
registryDependencies: ["alert-dialog","button"],
component: () => import("../src/lib/registry/default/example/AlertDialogDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/AlertDialogDemo.vue"],
},
"AspectRatioDemo": {
name: "AspectRatioDemo",
type: "components:example",
registryDependencies: ["aspect-ratio"],
component: () => import("../src/lib/registry/default/example/AspectRatioDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/AspectRatioDemo.vue"],
},
"AvatarDemo": {
name: "AvatarDemo",
type: "components:example",
registryDependencies: ["avatar"],
component: () => import("../src/lib/registry/default/example/AvatarDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/AvatarDemo.vue"],
},
"BadgeDemo": {
name: "BadgeDemo",
type: "components:example",
registryDependencies: ["badge"],
component: () => import("../src/lib/registry/default/example/BadgeDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/BadgeDemo.vue"],
},
"ButtonDemo": {
name: "ButtonDemo",
type: "components:example",
registryDependencies: ["button"],
component: () => import("../src/lib/registry/default/example/ButtonDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/ButtonDemo.vue"],
},
"CalendarDemo": {
name: "CalendarDemo",
type: "components:example",
registryDependencies: ["calendar"],
component: () => import("../src/lib/registry/default/example/CalendarDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/CalendarDemo.vue"],
},
"CardDemo": {
name: "CardDemo",
type: "components:example",
registryDependencies: ["button","card","switch","utils"],
component: () => import("../src/lib/registry/default/example/CardDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/CardDemo.vue"],
},
"CardWithForm": {
name: "CardWithForm",
type: "components:example",
registryDependencies: ["button","card","input","label","select"],
component: () => import("../src/lib/registry/default/example/CardWithForm.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/CardWithForm.vue"],
},
"CheckboxDemo": {
name: "CheckboxDemo",
type: "components:example",
registryDependencies: ["checkbox"],
component: () => import("../src/lib/registry/default/example/CheckboxDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/CheckboxDemo.vue"],
},
"CollapsibleDemo": {
name: "CollapsibleDemo",
type: "components:example",
registryDependencies: ["button","collapsible"],
component: () => import("../src/lib/registry/default/example/CollapsibleDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/CollapsibleDemo.vue"],
},
"ContextMenuDemo": {
name: "ContextMenuDemo",
type: "components:example",
registryDependencies: ["context-menu"],
component: () => import("../src/lib/registry/default/example/ContextMenuDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/ContextMenuDemo.vue"],
},
"DataTableDemo": {
name: "DataTableDemo",
type: "components:example",
registryDependencies: ["button","checkbox","dropdown-menu","input","table","utils"],
component: () => import("../src/lib/registry/default/example/DataTableDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/DataTableDemo.vue"],
},
"DataTableDemoColumn": {
name: "DataTableDemoColumn",
type: "components:example",
registryDependencies: ["dropdown-menu","button"],
component: () => import("../src/lib/registry/default/example/DataTableDemoColumn.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/DataTableDemoColumn.vue"],
},
"DatePickerDemo": {
name: "DatePickerDemo",
type: "components:example",
registryDependencies: ["utils","button","calendar","popover"],
component: () => import("../src/lib/registry/default/example/DatePickerDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/DatePickerDemo.vue"],
},
"DatePickerWithRange": {
name: "DatePickerWithRange",
type: "components:example",
registryDependencies: ["utils","button","calendar","popover"],
component: () => import("../src/lib/registry/default/example/DatePickerWithRange.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/DatePickerWithRange.vue"],
},
"DialogDemo": {
name: "DialogDemo",
type: "components:example",
registryDependencies: ["button","dialog","input","label"],
component: () => import("../src/lib/registry/default/example/DialogDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/DialogDemo.vue"],
},
"DropdownMenuDemo": {
name: "DropdownMenuDemo",
type: "components:example",
registryDependencies: ["button","dropdown-menu"],
component: () => import("../src/lib/registry/default/example/DropdownMenuDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/DropdownMenuDemo.vue"],
},
"HoverCardDemo": {
name: "HoverCardDemo",
type: "components:example",
registryDependencies: ["avatar","button","hover-card"],
component: () => import("../src/lib/registry/default/example/HoverCardDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/HoverCardDemo.vue"],
},
"InputDemo": {
name: "InputDemo",
type: "components:example",
registryDependencies: ["input"],
component: () => import("../src/lib/registry/default/example/InputDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/InputDemo.vue"],
},
"LabelDemo": {
name: "LabelDemo",
type: "components:example",
registryDependencies: ["checkbox","label"],
component: () => import("../src/lib/registry/default/example/LabelDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/LabelDemo.vue"],
},
"MenubarDemo": {
name: "MenubarDemo",
type: "components:example",
registryDependencies: ["menubar"],
component: () => import("../src/lib/registry/default/example/MenubarDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/MenubarDemo.vue"],
},
"NavigationMenuDemo": {
name: "NavigationMenuDemo",
type: "components:example",
registryDependencies: ["navigation-menu"],
component: () => import("../src/lib/registry/default/example/NavigationMenuDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/NavigationMenuDemo.vue"],
},
"NavigationMenuDemoItem": {
name: "NavigationMenuDemoItem",
type: "components:example",
registryDependencies: ["utils","navigation-menu"],
component: () => import("../src/lib/registry/default/example/NavigationMenuDemoItem.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/NavigationMenuDemoItem.vue"],
},
"PopoverDemo": {
name: "PopoverDemo",
type: "components:example",
registryDependencies: ["popover","button","label","input"],
component: () => import("../src/lib/registry/default/example/PopoverDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/PopoverDemo.vue"],
},
"ProgressDemo": {
name: "ProgressDemo",
type: "components:example",
registryDependencies: ["progress"],
component: () => import("../src/lib/registry/default/example/ProgressDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/ProgressDemo.vue"],
},
"RadioGroupDemo": {
name: "RadioGroupDemo",
type: "components:example",
registryDependencies: ["label","radio-group"],
component: () => import("../src/lib/registry/default/example/RadioGroupDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/RadioGroupDemo.vue"],
},
"ScrollAreaDemo": {
name: "ScrollAreaDemo",
type: "components:example",
registryDependencies: ["scroll-area","separator"],
component: () => import("../src/lib/registry/default/example/ScrollAreaDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/ScrollAreaDemo.vue"],
},
"SelectDemo": {
name: "SelectDemo",
type: "components:example",
registryDependencies: ["select"],
component: () => import("../src/lib/registry/default/example/SelectDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/SelectDemo.vue"],
},
"SeparatorDemo": {
name: "SeparatorDemo",
type: "components:example",
registryDependencies: ["separator"],
component: () => import("../src/lib/registry/default/example/SeparatorDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/SeparatorDemo.vue"],
},
"SheetDemo": {
name: "SheetDemo",
type: "components:example",
registryDependencies: ["button","input","label","sheet"],
component: () => import("../src/lib/registry/default/example/SheetDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/SheetDemo.vue"],
},
"SkeletonDemo": {
name: "SkeletonDemo",
type: "components:example",
registryDependencies: ["skeleton"],
component: () => import("../src/lib/registry/default/example/SkeletonDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/SkeletonDemo.vue"],
},
"SliderDemo": {
name: "SliderDemo",
type: "components:example",
registryDependencies: ["utils","slider"],
component: () => import("../src/lib/registry/default/example/SliderDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/SliderDemo.vue"],
},
"SwitchDemo": {
name: "SwitchDemo",
type: "components:example",
registryDependencies: ["label","switch"],
component: () => import("../src/lib/registry/default/example/SwitchDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/SwitchDemo.vue"],
},
"TableDemo": {
name: "TableDemo",
type: "components:example",
registryDependencies: ["table"],
component: () => import("../src/lib/registry/default/example/TableDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TableDemo.vue"],
},
"TabsDemo": {
name: "TabsDemo",
type: "components:example",
registryDependencies: ["button","card","input","label","tabs"],
component: () => import("../src/lib/registry/default/example/TabsDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TabsDemo.vue"],
},
"TextareaDemo": {
name: "TextareaDemo",
type: "components:example",
registryDependencies: ["textarea"],
component: () => import("../src/lib/registry/default/example/TextareaDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TextareaDemo.vue"],
},
"ToggleDemo": {
name: "ToggleDemo",
type: "components:example",
registryDependencies: ["toggle"],
component: () => import("../src/lib/registry/default/example/ToggleDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/ToggleDemo.vue"],
},
"TooltipDemo": {
name: "TooltipDemo",
type: "components:example",
registryDependencies: ["button","tooltip"],
component: () => import("../src/lib/registry/default/example/TooltipDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TooltipDemo.vue"],
},
"TypographyBlockquote": {
name: "TypographyBlockquote",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographyBlockquote.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographyBlockquote.vue"],
},
"TypographyDemo": {
name: "TypographyDemo",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographyDemo.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographyDemo.vue"],
},
"TypographyH1": {
name: "TypographyH1",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographyH1.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographyH1.vue"],
},
"TypographyH2": {
name: "TypographyH2",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographyH2.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographyH2.vue"],
},
"TypographyH3": {
name: "TypographyH3",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographyH3.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographyH3.vue"],
},
"TypographyH4": {
name: "TypographyH4",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographyH4.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographyH4.vue"],
},
"TypographyInlineCode": {
name: "TypographyInlineCode",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographyInlineCode.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographyInlineCode.vue"],
},
"TypographyLarge": {
name: "TypographyLarge",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographyLarge.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographyLarge.vue"],
},
"TypographyLead": {
name: "TypographyLead",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographyLead.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographyLead.vue"],
},
"TypographyList": {
name: "TypographyList",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographyList.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographyList.vue"],
},
"TypographyMuted": {
name: "TypographyMuted",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographyMuted.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographyMuted.vue"],
},
"TypographyP": {
name: "TypographyP",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographyP.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographyP.vue"],
},
"TypographySmall": {
name: "TypographySmall",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographySmall.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographySmall.vue"],
},
"TypographyTable": {
name: "TypographyTable",
type: "components:example",
registryDependencies: [],
component: () => import("../src/lib/registry/default/example/TypographyTable.vue").then((m) => m.default),
files: ["../src/lib/registry/default/example/TypographyTable.vue"],
},
},
}

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
"dev": "vitepress dev", "dev": "vitepress dev",
"build": "vitepress build", "build": "vitepress build",
"preview": "vitepress preview", "preview": "vitepress preview",
"build:registry": "ts-node --esm --project ./tsconfig.json ./scripts/build-registry.ts" "build:registry": "ts-node --esm --project ./tsconfig.scripts.json ./scripts/build-registry.ts"
}, },
"dependencies": { "dependencies": {
"@morev/vue-transitions": "^2.3.6", "@morev/vue-transitions": "^2.3.6",
@ -37,6 +37,7 @@
"@types/node": "^20.5.7", "@types/node": "^20.5.7",
"@vitejs/plugin-vue": "^4.1.0", "@vitejs/plugin-vue": "^4.1.0",
"@vue/compiler-core": "^3.3.4", "@vue/compiler-core": "^3.3.4",
"@vue/compiler-dom": "^3.3.4",
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.14",
"lodash.template": "^4.5.0", "lodash.template": "^4.5.0",
"postcss": "^8.4.24", "postcss": "^8.4.24",
@ -44,6 +45,7 @@
"rimraf": "^5.0.1", "rimraf": "^5.0.1",
"tailwind-merge": "^1.14.0", "tailwind-merge": "^1.14.0",
"tailwindcss": "^3.3.3", "tailwindcss": "^3.3.3",
"ts-node": "^10.9.1",
"typescript": "^5.0.2", "typescript": "^5.0.2",
"unplugin-icons": "^0.16.6", "unplugin-icons": "^0.16.6",
"vite": "^4.3.9", "vite": "^4.3.9",

View File

@ -4,13 +4,14 @@ import template from 'lodash.template'
import { rimraf } from 'rimraf' import { rimraf } from 'rimraf'
import { colorMapping, colors } from '../src/lib/registry/colors' import { colorMapping, colors } from '../src/lib/registry/colors'
import { registry } from '../src/lib/registry/registry'
import { registrySchema } from '../src/lib/registry/schema' import { registrySchema } from '../src/lib/registry/schema'
import { styles } from '../src/lib/registry/styles' import { styles } from '../src/lib/registry/styles'
import { themes } from '../src/lib/registry/themes' import { themes } from '../src/lib/registry/themes'
import { buildRegistry } from '../src/lib/registry/registry'
const REGISTRY_PATH = path.join(process.cwd(), 'src/public/registry') const REGISTRY_PATH = path.join(process.cwd(), 'static/registry')
const registry = await buildRegistry()
const result = registrySchema.safeParse(registry) const result = registrySchema.safeParse(registry)
if (!result.success) { if (!result.success) {
@ -19,14 +20,12 @@ if (!result.success) {
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Build __registry__/index.tsx. // Build __registry__/index.js.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
let index = `// @ts-nocheck let index = `
// This file is autogenerated by scripts/build-registry.ts // This file is autogenerated by scripts/build-registry.ts
// Do not edit this file directly. // Do not edit this file directly.
import * as React from "react" export const Index = {
export const Index: Record<string, any> = {
` `
for (const style of styles) { for (const style of styles) {
@ -34,12 +33,11 @@ for (const style of styles) {
// Build style index. // Build style index.
for (const item of result.data) { for (const item of result.data) {
// if (item.type === "components:ui") { if (item.type === 'components:ui')
// continue continue
// }
const resolveFiles = item.files.map( const resolveFiles = item.files.map(
file => `registry/${style.name}/${file}`, file => `../src/lib/registry/${style.name}/${file}`,
) )
const type = item.type.split(':')[1] const type = item.type.split(':')[1]
@ -48,9 +46,9 @@ for (const style of styles) {
name: "${item.name}", name: "${item.name}",
type: "${item.type}", type: "${item.type}",
registryDependencies: ${JSON.stringify(item.registryDependencies)}, registryDependencies: ${JSON.stringify(item.registryDependencies)},
component: React.lazy(() => import("@/registry/${style.name}/${type}/${ component: () => import("../src/lib/registry/${style.name}/${type}/${
item.name item.name
}")), }.vue").then((m) => m.default),
files: [${resolveFiles.map(file => `"${file}"`)}], files: [${resolveFiles.map(file => `"${file}"`)}],
},` },`
} }
@ -64,8 +62,8 @@ index += `
` `
// Write style index. // Write style index.
rimraf.sync(path.join(process.cwd(), '__registry__/index.tsx')) rimraf.sync(path.join(process.cwd(), '__registry__/index.js'))
fs.writeFileSync(path.join(process.cwd(), '__registry__/index.tsx'), index) fs.writeFileSync(path.join(process.cwd(), '__registry__/index.js'), index)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Build registry/styles/[style]/[name].json. // Build registry/styles/[style]/[name].json.
@ -83,7 +81,7 @@ for (const style of styles) {
const files = item.files?.map((file) => { const files = item.files?.map((file) => {
const content = fs.readFileSync( const content = fs.readFileSync(
path.join(process.cwd(), 'registry', style.name, file), path.join(process.cwd(), 'src/lib/registry', style.name, file),
'utf8', 'utf8',
) )
@ -116,10 +114,15 @@ fs.writeFileSync(
'utf8', 'utf8',
) )
const REGISTRY_IGNORE = ['super-form']
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Build registry/index.json. // Build registry/index.json.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
const names = result.data.filter(item => item.type === 'components:ui') const names = result.data.filter(
item =>
item.type === 'components:ui' && !REGISTRY_IGNORE.includes(item.name),
)
const registryJson = JSON.stringify(names, null, 2) const registryJson = JSON.stringify(names, null, 2)
rimraf.sync(path.join(REGISTRY_PATH, 'index.json')) rimraf.sync(path.join(REGISTRY_PATH, 'index.json'))
fs.writeFileSync(path.join(REGISTRY_PATH, 'index.json'), registryJson, 'utf8') fs.writeFileSync(path.join(REGISTRY_PATH, 'index.json'), registryJson, 'utf8')
@ -142,7 +145,10 @@ for (const [color, value] of Object.entries(colors)) {
if (Array.isArray(value)) { if (Array.isArray(value)) {
colorsData[color] = value.map(item => ({ colorsData[color] = value.map(item => ({
...item, ...item,
rgbChannel: item.rgb.replace(/^rgb\((\d+),(\d+),(\d+)\)$/, '$1 $2 $3'), rgbChannel: item.rgb.replace(
/^rgb\((\d+),(\d+),(\d+)\)$/,
'$1 $2 $3',
),
hslChannel: item.hsl.replace( hslChannel: item.hsl.replace(
/^hsl\(([\d.]+),([\d.]+%),([\d.]+%)\)$/, /^hsl\(([\d.]+),([\d.]+%),([\d.]+%)\)$/,
'$1 $2 $3', '$1 $2 $3',
@ -154,7 +160,10 @@ for (const [color, value] of Object.entries(colors)) {
if (typeof value === 'object') { if (typeof value === 'object') {
colorsData[color] = { colorsData[color] = {
...value, ...value,
rgbChannel: value.rgb.replace(/^rgb\((\d+),(\d+),(\d+)\)$/, '$1 $2 $3'), rgbChannel: value.rgb.replace(
/^rgb\((\d+),(\d+),(\d+)\)$/,
'$1 $2 $3',
),
hslChannel: value.hsl.replace( hslChannel: value.hsl.replace(
/^hsl\(([\d.]+),([\d.]+%),([\d.]+%)\)$/, /^hsl\(([\d.]+),([\d.]+%),([\d.]+%)\)$/,
'$1 $2 $3', '$1 $2 $3',
@ -187,29 +196,30 @@ export const BASE_STYLES_WITH_VARIABLES = `@tailwind base;
--background: <%- colors.light["background"] %>; --background: <%- colors.light["background"] %>;
--foreground: <%- colors.light["foreground"] %>; --foreground: <%- colors.light["foreground"] %>;
--card: <%- colors.light["card"] %>; --muted: <%- colors.light["muted"] %>;
--card-foreground: <%- colors.light["card-foreground"] %>; --muted-foreground: <%- colors.light["muted-foreground"] %>;
--popover: <%- colors.light["popover"] %>; --popover: <%- colors.light["popover"] %>;
--popover-foreground: <%- colors.light["popover-foreground"] %>; --popover-foreground: <%- colors.light["popover-foreground"] %>;
--card: <%- colors.light["card"] %>;
--card-foreground: <%- colors.light["card-foreground"] %>;
--border: <%- colors.light["border"] %>;
--input: <%- colors.light["input"] %>;
--primary: <%- colors.light["primary"] %>; --primary: <%- colors.light["primary"] %>;
--primary-foreground: <%- colors.light["primary-foreground"] %>; --primary-foreground: <%- colors.light["primary-foreground"] %>;
--secondary: <%- colors.light["secondary"] %>; --secondary: <%- colors.light["secondary"] %>;
--secondary-foreground: <%- colors.light["secondary-foreground"] %>; --secondary-foreground: <%- colors.light["secondary-foreground"] %>;
--muted: <%- colors.light["muted"] %>;
--muted-foreground: <%- colors.light["muted-foreground"] %>;
--accent: <%- colors.light["accent"] %>; --accent: <%- colors.light["accent"] %>;
--accent-foreground: <%- colors.light["accent-foreground"] %>; --accent-foreground: <%- colors.light["accent-foreground"] %>;
--destructive: <%- colors.light["destructive"] %>; --destructive: <%- colors.light["destructive"] %>;
--destructive-foreground: <%- colors.light["destructive-foreground"] %>; --destructive-foreground: <%- colors.light["destructive-foreground"] %>;
--border: <%- colors.light["border"] %>;
--input: <%- colors.light["input"] %>;
--ring: <%- colors.light["ring"] %>; --ring: <%- colors.light["ring"] %>;
--radius: 0.5rem; --radius: 0.5rem;
@ -219,29 +229,30 @@ export const BASE_STYLES_WITH_VARIABLES = `@tailwind base;
--background: <%- colors.dark["background"] %>; --background: <%- colors.dark["background"] %>;
--foreground: <%- colors.dark["foreground"] %>; --foreground: <%- colors.dark["foreground"] %>;
--card: <%- colors.dark["card"] %>; --muted: <%- colors.dark["muted"] %>;
--card-foreground: <%- colors.dark["card-foreground"] %>; --muted-foreground: <%- colors.dark["muted-foreground"] %>;
--popover: <%- colors.dark["popover"] %>; --popover: <%- colors.dark["popover"] %>;
--popover-foreground: <%- colors.dark["popover-foreground"] %>; --popover-foreground: <%- colors.dark["popover-foreground"] %>;
--card: <%- colors.dark["card"] %>;
--card-foreground: <%- colors.dark["card-foreground"] %>;
--border: <%- colors.dark["border"] %>;
--input: <%- colors.dark["input"] %>;
--primary: <%- colors.dark["primary"] %>; --primary: <%- colors.dark["primary"] %>;
--primary-foreground: <%- colors.dark["primary-foreground"] %>; --primary-foreground: <%- colors.dark["primary-foreground"] %>;
--secondary: <%- colors.dark["secondary"] %>; --secondary: <%- colors.dark["secondary"] %>;
--secondary-foreground: <%- colors.dark["secondary-foreground"] %>; --secondary-foreground: <%- colors.dark["secondary-foreground"] %>;
--muted: <%- colors.dark["muted"] %>;
--muted-foreground: <%- colors.dark["muted-foreground"] %>;
--accent: <%- colors.dark["accent"] %>; --accent: <%- colors.dark["accent"] %>;
--accent-foreground: <%- colors.dark["accent-foreground"] %>; --accent-foreground: <%- colors.dark["accent-foreground"] %>;
--destructive: <%- colors.dark["destructive"] %>; --destructive: <%- colors.dark["destructive"] %>;
--destructive-foreground: <%- colors.dark["destructive-foreground"] %>; --destructive-foreground: <%- colors.dark["destructive-foreground"] %>;
--border: <%- colors.dark["border"] %>;
--input: <%- colors.dark["input"] %>;
--ring: <%- colors.dark["ring"] %>; --ring: <%- colors.dark["ring"] %>;
} }
} }
@ -255,7 +266,7 @@ export const BASE_STYLES_WITH_VARIABLES = `@tailwind base;
} }
}` }`
for (const baseColor of ['slate', 'gray', 'zinc', 'neutral', 'stone']) { for (const baseColor of ['slate', 'gray', 'zinc', 'neutral', 'stone', 'lime']) {
const base: Record<string, any> = { const base: Record<string, any> = {
inlineColors: {}, inlineColors: {},
cssVars: {}, cssVars: {},
@ -265,14 +276,17 @@ for (const baseColor of ['slate', 'gray', 'zinc', 'neutral', 'stone']) {
base.cssVars[mode] = {} base.cssVars[mode] = {}
for (const [key, value] of Object.entries(values)) { for (const [key, value] of Object.entries(values)) {
if (typeof value === 'string') { if (typeof value === 'string') {
const resolvedColor = value.replace(/{{base}}-/g, `${baseColor}-`) const resolvedColor = value.replace(
/{{base}}-/g,
`${baseColor}-`,
)
base.inlineColors[mode][key] = resolvedColor base.inlineColors[mode][key] = resolvedColor
const [resolvedBase, scale] = resolvedColor.split('-') const [resolvedBase, scale] = resolvedColor.split('-')
const color = scale const color = scale
? colorsData[resolvedBase].find( ? colorsData[resolvedBase].find(
item => item.scale === Number.parseInt(scale), (item: any) => item.scale === Number.parseInt(scale),
) )
: colorsData[resolvedBase] : colorsData[resolvedBase]
if (color) if (color)
base.cssVars[mode][key] = color.hslChannel base.cssVars[mode][key] = color.hslChannel
@ -327,7 +341,7 @@ export const THEME_STYLES_WITH_VARIABLES = `
--ring: <%- colors.light["ring"] %>; --ring: <%- colors.light["ring"] %>;
--radius: <%- colors.light["radius"] %>; --radius: 0.5rem;
} }
.dark .theme-<%- theme %> { .dark .theme-<%- theme %> {
@ -377,47 +391,4 @@ fs.writeFileSync(
'utf8', 'utf8',
) )
// ----------------------------------------------------------------------------
// Build registry/themes/[theme].json
// ----------------------------------------------------------------------------
rimraf.sync(path.join(REGISTRY_PATH, 'themes'))
for (const baseColor of ['slate', 'gray', 'zinc', 'neutral', 'stone']) {
const payload = {
name: baseColor,
label: baseColor.charAt(0).toUpperCase() + baseColor.slice(1),
cssVars: {},
}
for (const [mode, values] of Object.entries(colorMapping)) {
payload.cssVars[mode] = {}
for (const [key, value] of Object.entries(values)) {
if (typeof value === 'string') {
const resolvedColor = value.replace(/{{base}}-/g, `${baseColor}-`)
payload.cssVars[mode][key] = resolvedColor
const [resolvedBase, scale] = resolvedColor.split('-')
const color = scale
? colorsData[resolvedBase].find(
item => item.scale === Number.parseInt(scale),
)
: colorsData[resolvedBase]
if (color)
payload.cssVars[mode][key] = color.hslChannel
}
}
}
const targetPath = path.join(REGISTRY_PATH, 'themes')
// Create directory if it doesn't exist.
if (!fs.existsSync(targetPath))
fs.mkdirSync(targetPath, { recursive: true })
fs.writeFileSync(
path.join(targetPath, `${payload.name}.json`),
JSON.stringify(payload, null, 2),
'utf8',
)
}
console.log('✅ Done!') console.log('✅ Done!')

View File

@ -0,0 +1,4 @@
export * from './colors'
export * from './themes'
export * from './schema'
export * from './styles'

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,10 @@ export const styles = [
name: 'default', name: 'default',
label: 'Default', label: 'Default',
}, },
{ // {
name: 'new-york', // name: 'new-york',
label: 'New York', // label: 'New York',
}, // },
] as const ] as const
export type Style = (typeof styles)[number] export type Style = (typeof styles)[number]

View File

@ -0,0 +1,92 @@
{
"inlineColors": {
"light": {
"background": "white",
"foreground": "gray-950",
"card": "white",
"card-foreground": "gray-950",
"popover": "white",
"popover-foreground": "gray-950",
"primary": "gray-900",
"primary-foreground": "gray-50",
"secondary": "gray-100",
"secondary-foreground": "gray-900",
"muted": "gray-100",
"muted-foreground": "gray-500",
"accent": "gray-100",
"accent-foreground": "gray-900",
"destructive": "red-500",
"destructive-foreground": "gray-50",
"border": "gray-200",
"input": "gray-200",
"ring": "gray-950"
},
"dark": {
"background": "gray-950",
"foreground": "gray-50",
"card": "gray-950",
"card-foreground": "gray-50",
"popover": "gray-950",
"popover-foreground": "gray-50",
"primary": "gray-50",
"primary-foreground": "gray-900",
"secondary": "gray-800",
"secondary-foreground": "gray-50",
"muted": "gray-800",
"muted-foreground": "gray-400",
"accent": "gray-800",
"accent-foreground": "gray-50",
"destructive": "red-900",
"destructive-foreground": "gray-50",
"border": "gray-800",
"input": "gray-800",
"ring": "gray-300"
}
},
"cssVars": {
"light": {
"background": "0 0% 100%",
"foreground": "224 71.4% 4.1%",
"card": "0 0% 100%",
"card-foreground": "224 71.4% 4.1%",
"popover": "0 0% 100%",
"popover-foreground": "224 71.4% 4.1%",
"primary": "220.9 39.3% 11%",
"primary-foreground": "210 20% 98%",
"secondary": "220 14.3% 95.9%",
"secondary-foreground": "220.9 39.3% 11%",
"muted": "220 14.3% 95.9%",
"muted-foreground": "220 8.9% 46.1%",
"accent": "220 14.3% 95.9%",
"accent-foreground": "220.9 39.3% 11%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "210 20% 98%",
"border": "220 13% 91%",
"input": "220 13% 91%",
"ring": "224 71.4% 4.1%"
},
"dark": {
"background": "224 71.4% 4.1%",
"foreground": "210 20% 98%",
"card": "224 71.4% 4.1%",
"card-foreground": "210 20% 98%",
"popover": "224 71.4% 4.1%",
"popover-foreground": "210 20% 98%",
"primary": "210 20% 98%",
"primary-foreground": "220.9 39.3% 11%",
"secondary": "215 27.9% 16.9%",
"secondary-foreground": "210 20% 98%",
"muted": "215 27.9% 16.9%",
"muted-foreground": "217.9 10.6% 64.9%",
"accent": "215 27.9% 16.9%",
"accent-foreground": "210 20% 98%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "210 20% 98%",
"border": "215 27.9% 16.9%",
"input": "215 27.9% 16.9%",
"ring": "216 12.2% 83.9%"
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 224 71.4% 4.1%;\n \n --muted: 220 14.3% 95.9%;\n --muted-foreground: 220 8.9% 46.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 224 71.4% 4.1%;\n \n --card: 0 0% 100%;\n --card-foreground: 224 71.4% 4.1%;\n \n --border: 220 13% 91%;\n --input: 220 13% 91%;\n \n --primary: 220.9 39.3% 11%;\n --primary-foreground: 210 20% 98%;\n \n --secondary: 220 14.3% 95.9%;\n --secondary-foreground: 220.9 39.3% 11%;\n \n --accent: 220 14.3% 95.9%;\n --accent-foreground: 220.9 39.3% 11%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 20% 98%;\n \n --ring: 224 71.4% 4.1%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 224 71.4% 4.1%;\n --foreground: 210 20% 98%;\n \n --muted: 215 27.9% 16.9%;\n --muted-foreground: 217.9 10.6% 64.9%;\n \n --popover: 224 71.4% 4.1%;\n --popover-foreground: 210 20% 98%;\n \n --card: 224 71.4% 4.1%;\n --card-foreground: 210 20% 98%;\n \n --border: 215 27.9% 16.9%;\n --input: 215 27.9% 16.9%;\n \n --primary: 210 20% 98%;\n --primary-foreground: 220.9 39.3% 11%;\n \n --secondary: 215 27.9% 16.9%;\n --secondary-foreground: 210 20% 98%;\n \n --accent: 215 27.9% 16.9%;\n --accent-foreground: 210 20% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 20% 98%;\n \n --ring: 216 12.2% 83.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
{
"inlineColors": {
"light": {
"background": "white",
"foreground": "lime-950",
"card": "white",
"card-foreground": "lime-950",
"popover": "white",
"popover-foreground": "lime-950",
"primary": "lime-900",
"primary-foreground": "lime-50",
"secondary": "lime-100",
"secondary-foreground": "lime-900",
"muted": "lime-100",
"muted-foreground": "lime-500",
"accent": "lime-100",
"accent-foreground": "lime-900",
"destructive": "red-500",
"destructive-foreground": "lime-50",
"border": "lime-200",
"input": "lime-200",
"ring": "lime-950"
},
"dark": {
"background": "lime-950",
"foreground": "lime-50",
"card": "lime-950",
"card-foreground": "lime-50",
"popover": "lime-950",
"popover-foreground": "lime-50",
"primary": "lime-50",
"primary-foreground": "lime-900",
"secondary": "lime-800",
"secondary-foreground": "lime-50",
"muted": "lime-800",
"muted-foreground": "lime-400",
"accent": "lime-800",
"accent-foreground": "lime-50",
"destructive": "red-900",
"destructive-foreground": "lime-50",
"border": "lime-800",
"input": "lime-800",
"ring": "lime-300"
}
},
"cssVars": {
"light": {
"background": "0 0% 100%",
"foreground": "89.3 80.4% 10%",
"card": "0 0% 100%",
"card-foreground": "89.3 80.4% 10%",
"popover": "0 0% 100%",
"popover-foreground": "89.3 80.4% 10%",
"primary": "87.6 61.2% 20.2%",
"primary-foreground": "78.3 92% 95.1%",
"secondary": "79.6 89.1% 89.2%",
"secondary-foreground": "87.6 61.2% 20.2%",
"muted": "79.6 89.1% 89.2%",
"muted-foreground": "83.7 80.5% 44.3%",
"accent": "79.6 89.1% 89.2%",
"accent-foreground": "87.6 61.2% 20.2%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "78.3 92% 95.1%",
"border": "80.9 88.5% 79.6%",
"input": "80.9 88.5% 79.6%",
"ring": "89.3 80.4% 10%"
},
"dark": {
"background": "89.3 80.4% 10%",
"foreground": "78.3 92% 95.1%",
"card": "89.3 80.4% 10%",
"card-foreground": "78.3 92% 95.1%",
"popover": "89.3 80.4% 10%",
"popover-foreground": "78.3 92% 95.1%",
"primary": "78.3 92% 95.1%",
"primary-foreground": "87.6 61.2% 20.2%",
"secondary": "86.3 69% 22.7%",
"secondary-foreground": "78.3 92% 95.1%",
"muted": "86.3 69% 22.7%",
"muted-foreground": "82.7 78% 55.5%",
"accent": "86.3 69% 22.7%",
"accent-foreground": "78.3 92% 95.1%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "78.3 92% 95.1%",
"border": "86.3 69% 22.7%",
"input": "86.3 69% 22.7%",
"ring": "82 84.5% 67.1%"
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 89.3 80.4% 10%;\n \n --muted: 79.6 89.1% 89.2%;\n --muted-foreground: 83.7 80.5% 44.3%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 89.3 80.4% 10%;\n \n --card: 0 0% 100%;\n --card-foreground: 89.3 80.4% 10%;\n \n --border: 80.9 88.5% 79.6%;\n --input: 80.9 88.5% 79.6%;\n \n --primary: 87.6 61.2% 20.2%;\n --primary-foreground: 78.3 92% 95.1%;\n \n --secondary: 79.6 89.1% 89.2%;\n --secondary-foreground: 87.6 61.2% 20.2%;\n \n --accent: 79.6 89.1% 89.2%;\n --accent-foreground: 87.6 61.2% 20.2%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 78.3 92% 95.1%;\n \n --ring: 89.3 80.4% 10%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 89.3 80.4% 10%;\n --foreground: 78.3 92% 95.1%;\n \n --muted: 86.3 69% 22.7%;\n --muted-foreground: 82.7 78% 55.5%;\n \n --popover: 89.3 80.4% 10%;\n --popover-foreground: 78.3 92% 95.1%;\n \n --card: 89.3 80.4% 10%;\n --card-foreground: 78.3 92% 95.1%;\n \n --border: 86.3 69% 22.7%;\n --input: 86.3 69% 22.7%;\n \n --primary: 78.3 92% 95.1%;\n --primary-foreground: 87.6 61.2% 20.2%;\n \n --secondary: 86.3 69% 22.7%;\n --secondary-foreground: 78.3 92% 95.1%;\n \n --accent: 86.3 69% 22.7%;\n --accent-foreground: 78.3 92% 95.1%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 78.3 92% 95.1%;\n \n --ring: 82 84.5% 67.1%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@ -0,0 +1,92 @@
{
"inlineColors": {
"light": {
"background": "white",
"foreground": "neutral-950",
"card": "white",
"card-foreground": "neutral-950",
"popover": "white",
"popover-foreground": "neutral-950",
"primary": "neutral-900",
"primary-foreground": "neutral-50",
"secondary": "neutral-100",
"secondary-foreground": "neutral-900",
"muted": "neutral-100",
"muted-foreground": "neutral-500",
"accent": "neutral-100",
"accent-foreground": "neutral-900",
"destructive": "red-500",
"destructive-foreground": "neutral-50",
"border": "neutral-200",
"input": "neutral-200",
"ring": "neutral-950"
},
"dark": {
"background": "neutral-950",
"foreground": "neutral-50",
"card": "neutral-950",
"card-foreground": "neutral-50",
"popover": "neutral-950",
"popover-foreground": "neutral-50",
"primary": "neutral-50",
"primary-foreground": "neutral-900",
"secondary": "neutral-800",
"secondary-foreground": "neutral-50",
"muted": "neutral-800",
"muted-foreground": "neutral-400",
"accent": "neutral-800",
"accent-foreground": "neutral-50",
"destructive": "red-900",
"destructive-foreground": "neutral-50",
"border": "neutral-800",
"input": "neutral-800",
"ring": "neutral-300"
}
},
"cssVars": {
"light": {
"background": "0 0% 100%",
"foreground": "0 0% 3.9%",
"card": "0 0% 100%",
"card-foreground": "0 0% 3.9%",
"popover": "0 0% 100%",
"popover-foreground": "0 0% 3.9%",
"primary": "0 0% 9%",
"primary-foreground": "0 0% 98%",
"secondary": "0 0% 96.1%",
"secondary-foreground": "0 0% 9%",
"muted": "0 0% 96.1%",
"muted-foreground": "0 0% 45.1%",
"accent": "0 0% 96.1%",
"accent-foreground": "0 0% 9%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "0 0% 98%",
"border": "0 0% 89.8%",
"input": "0 0% 89.8%",
"ring": "0 0% 3.9%"
},
"dark": {
"background": "0 0% 3.9%",
"foreground": "0 0% 98%",
"card": "0 0% 3.9%",
"card-foreground": "0 0% 98%",
"popover": "0 0% 3.9%",
"popover-foreground": "0 0% 98%",
"primary": "0 0% 98%",
"primary-foreground": "0 0% 9%",
"secondary": "0 0% 14.9%",
"secondary-foreground": "0 0% 98%",
"muted": "0 0% 14.9%",
"muted-foreground": "0 0% 63.9%",
"accent": "0 0% 14.9%",
"accent-foreground": "0 0% 98%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "0 0% 98%",
"border": "0 0% 14.9%",
"input": "0 0% 14.9%",
"ring": "0 0% 83.1%"
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 0 0% 3.9%;\n \n --muted: 0 0% 96.1%;\n --muted-foreground: 0 0% 45.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 0 0% 3.9%;\n \n --card: 0 0% 100%;\n --card-foreground: 0 0% 3.9%;\n \n --border: 0 0% 89.8%;\n --input: 0 0% 89.8%;\n \n --primary: 0 0% 9%;\n --primary-foreground: 0 0% 98%;\n \n --secondary: 0 0% 96.1%;\n --secondary-foreground: 0 0% 9%;\n \n --accent: 0 0% 96.1%;\n --accent-foreground: 0 0% 9%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n \n --ring: 0 0% 3.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 0 0% 3.9%;\n --foreground: 0 0% 98%;\n \n --muted: 0 0% 14.9%;\n --muted-foreground: 0 0% 63.9%;\n \n --popover: 0 0% 3.9%;\n --popover-foreground: 0 0% 98%;\n \n --card: 0 0% 3.9%;\n --card-foreground: 0 0% 98%;\n \n --border: 0 0% 14.9%;\n --input: 0 0% 14.9%;\n \n --primary: 0 0% 98%;\n --primary-foreground: 0 0% 9%;\n \n --secondary: 0 0% 14.9%;\n --secondary-foreground: 0 0% 98%;\n \n --accent: 0 0% 14.9%;\n --accent-foreground: 0 0% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 0% 98%;\n \n --ring: 0 0% 83.1%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@ -0,0 +1,92 @@
{
"inlineColors": {
"light": {
"background": "white",
"foreground": "slate-950",
"card": "white",
"card-foreground": "slate-950",
"popover": "white",
"popover-foreground": "slate-950",
"primary": "slate-900",
"primary-foreground": "slate-50",
"secondary": "slate-100",
"secondary-foreground": "slate-900",
"muted": "slate-100",
"muted-foreground": "slate-500",
"accent": "slate-100",
"accent-foreground": "slate-900",
"destructive": "red-500",
"destructive-foreground": "slate-50",
"border": "slate-200",
"input": "slate-200",
"ring": "slate-950"
},
"dark": {
"background": "slate-950",
"foreground": "slate-50",
"card": "slate-950",
"card-foreground": "slate-50",
"popover": "slate-950",
"popover-foreground": "slate-50",
"primary": "slate-50",
"primary-foreground": "slate-900",
"secondary": "slate-800",
"secondary-foreground": "slate-50",
"muted": "slate-800",
"muted-foreground": "slate-400",
"accent": "slate-800",
"accent-foreground": "slate-50",
"destructive": "red-900",
"destructive-foreground": "slate-50",
"border": "slate-800",
"input": "slate-800",
"ring": "slate-300"
}
},
"cssVars": {
"light": {
"background": "0 0% 100%",
"foreground": "222.2 84% 4.9%",
"card": "0 0% 100%",
"card-foreground": "222.2 84% 4.9%",
"popover": "0 0% 100%",
"popover-foreground": "222.2 84% 4.9%",
"primary": "222.2 47.4% 11.2%",
"primary-foreground": "210 40% 98%",
"secondary": "210 40% 96.1%",
"secondary-foreground": "222.2 47.4% 11.2%",
"muted": "210 40% 96.1%",
"muted-foreground": "215.4 16.3% 46.9%",
"accent": "210 40% 96.1%",
"accent-foreground": "222.2 47.4% 11.2%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "210 40% 98%",
"border": "214.3 31.8% 91.4%",
"input": "214.3 31.8% 91.4%",
"ring": "222.2 84% 4.9%"
},
"dark": {
"background": "222.2 84% 4.9%",
"foreground": "210 40% 98%",
"card": "222.2 84% 4.9%",
"card-foreground": "210 40% 98%",
"popover": "222.2 84% 4.9%",
"popover-foreground": "210 40% 98%",
"primary": "210 40% 98%",
"primary-foreground": "222.2 47.4% 11.2%",
"secondary": "217.2 32.6% 17.5%",
"secondary-foreground": "210 40% 98%",
"muted": "217.2 32.6% 17.5%",
"muted-foreground": "215 20.2% 65.1%",
"accent": "217.2 32.6% 17.5%",
"accent-foreground": "210 40% 98%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "210 40% 98%",
"border": "217.2 32.6% 17.5%",
"input": "217.2 32.6% 17.5%",
"ring": "212.7 26.8% 83.9%"
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n \n --muted: 210 40% 96.1%;\n --muted-foreground: 215.4 16.3% 46.9%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n \n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n \n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n \n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n \n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n \n --accent: 210 40% 96.1%;\n --accent-foreground: 222.2 47.4% 11.2%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n \n --ring: 222.2 84% 4.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 222.2 84% 4.9%;\n --foreground: 210 40% 98%;\n \n --muted: 217.2 32.6% 17.5%;\n --muted-foreground: 215 20.2% 65.1%;\n \n --popover: 222.2 84% 4.9%;\n --popover-foreground: 210 40% 98%;\n \n --card: 222.2 84% 4.9%;\n --card-foreground: 210 40% 98%;\n \n --border: 217.2 32.6% 17.5%;\n --input: 217.2 32.6% 17.5%;\n \n --primary: 210 40% 98%;\n --primary-foreground: 222.2 47.4% 11.2%;\n \n --secondary: 217.2 32.6% 17.5%;\n --secondary-foreground: 210 40% 98%;\n \n --accent: 217.2 32.6% 17.5%;\n --accent-foreground: 210 40% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 40% 98%;\n \n --ring: 212.7 26.8% 83.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@ -0,0 +1,92 @@
{
"inlineColors": {
"light": {
"background": "white",
"foreground": "stone-950",
"card": "white",
"card-foreground": "stone-950",
"popover": "white",
"popover-foreground": "stone-950",
"primary": "stone-900",
"primary-foreground": "stone-50",
"secondary": "stone-100",
"secondary-foreground": "stone-900",
"muted": "stone-100",
"muted-foreground": "stone-500",
"accent": "stone-100",
"accent-foreground": "stone-900",
"destructive": "red-500",
"destructive-foreground": "stone-50",
"border": "stone-200",
"input": "stone-200",
"ring": "stone-950"
},
"dark": {
"background": "stone-950",
"foreground": "stone-50",
"card": "stone-950",
"card-foreground": "stone-50",
"popover": "stone-950",
"popover-foreground": "stone-50",
"primary": "stone-50",
"primary-foreground": "stone-900",
"secondary": "stone-800",
"secondary-foreground": "stone-50",
"muted": "stone-800",
"muted-foreground": "stone-400",
"accent": "stone-800",
"accent-foreground": "stone-50",
"destructive": "red-900",
"destructive-foreground": "stone-50",
"border": "stone-800",
"input": "stone-800",
"ring": "stone-300"
}
},
"cssVars": {
"light": {
"background": "0 0% 100%",
"foreground": "20 14.3% 4.1%",
"card": "0 0% 100%",
"card-foreground": "20 14.3% 4.1%",
"popover": "0 0% 100%",
"popover-foreground": "20 14.3% 4.1%",
"primary": "24 9.8% 10%",
"primary-foreground": "60 9.1% 97.8%",
"secondary": "60 4.8% 95.9%",
"secondary-foreground": "24 9.8% 10%",
"muted": "60 4.8% 95.9%",
"muted-foreground": "25 5.3% 44.7%",
"accent": "60 4.8% 95.9%",
"accent-foreground": "24 9.8% 10%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "60 9.1% 97.8%",
"border": "20 5.9% 90%",
"input": "20 5.9% 90%",
"ring": "20 14.3% 4.1%"
},
"dark": {
"background": "20 14.3% 4.1%",
"foreground": "60 9.1% 97.8%",
"card": "20 14.3% 4.1%",
"card-foreground": "60 9.1% 97.8%",
"popover": "20 14.3% 4.1%",
"popover-foreground": "60 9.1% 97.8%",
"primary": "60 9.1% 97.8%",
"primary-foreground": "24 9.8% 10%",
"secondary": "12 6.5% 15.1%",
"secondary-foreground": "60 9.1% 97.8%",
"muted": "12 6.5% 15.1%",
"muted-foreground": "24 5.4% 63.9%",
"accent": "12 6.5% 15.1%",
"accent-foreground": "60 9.1% 97.8%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "60 9.1% 97.8%",
"border": "12 6.5% 15.1%",
"input": "12 6.5% 15.1%",
"ring": "24 5.7% 82.9%"
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 20 14.3% 4.1%;\n \n --muted: 60 4.8% 95.9%;\n --muted-foreground: 25 5.3% 44.7%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 20 14.3% 4.1%;\n \n --card: 0 0% 100%;\n --card-foreground: 20 14.3% 4.1%;\n \n --border: 20 5.9% 90%;\n --input: 20 5.9% 90%;\n \n --primary: 24 9.8% 10%;\n --primary-foreground: 60 9.1% 97.8%;\n \n --secondary: 60 4.8% 95.9%;\n --secondary-foreground: 24 9.8% 10%;\n \n --accent: 60 4.8% 95.9%;\n --accent-foreground: 24 9.8% 10%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 60 9.1% 97.8%;\n \n --ring: 20 14.3% 4.1%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 20 14.3% 4.1%;\n --foreground: 60 9.1% 97.8%;\n \n --muted: 12 6.5% 15.1%;\n --muted-foreground: 24 5.4% 63.9%;\n \n --popover: 20 14.3% 4.1%;\n --popover-foreground: 60 9.1% 97.8%;\n \n --card: 20 14.3% 4.1%;\n --card-foreground: 60 9.1% 97.8%;\n \n --border: 12 6.5% 15.1%;\n --input: 12 6.5% 15.1%;\n \n --primary: 60 9.1% 97.8%;\n --primary-foreground: 24 9.8% 10%;\n \n --secondary: 12 6.5% 15.1%;\n --secondary-foreground: 60 9.1% 97.8%;\n \n --accent: 12 6.5% 15.1%;\n --accent-foreground: 60 9.1% 97.8%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 60 9.1% 97.8%;\n \n --ring: 24 5.7% 82.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@ -0,0 +1,92 @@
{
"inlineColors": {
"light": {
"background": "white",
"foreground": "zinc-950",
"card": "white",
"card-foreground": "zinc-950",
"popover": "white",
"popover-foreground": "zinc-950",
"primary": "zinc-900",
"primary-foreground": "zinc-50",
"secondary": "zinc-100",
"secondary-foreground": "zinc-900",
"muted": "zinc-100",
"muted-foreground": "zinc-500",
"accent": "zinc-100",
"accent-foreground": "zinc-900",
"destructive": "red-500",
"destructive-foreground": "zinc-50",
"border": "zinc-200",
"input": "zinc-200",
"ring": "zinc-950"
},
"dark": {
"background": "zinc-950",
"foreground": "zinc-50",
"card": "zinc-950",
"card-foreground": "zinc-50",
"popover": "zinc-950",
"popover-foreground": "zinc-50",
"primary": "zinc-50",
"primary-foreground": "zinc-900",
"secondary": "zinc-800",
"secondary-foreground": "zinc-50",
"muted": "zinc-800",
"muted-foreground": "zinc-400",
"accent": "zinc-800",
"accent-foreground": "zinc-50",
"destructive": "red-900",
"destructive-foreground": "zinc-50",
"border": "zinc-800",
"input": "zinc-800",
"ring": "zinc-300"
}
},
"cssVars": {
"light": {
"background": "0 0% 100%",
"foreground": "240 10% 3.9%",
"card": "0 0% 100%",
"card-foreground": "240 10% 3.9%",
"popover": "0 0% 100%",
"popover-foreground": "240 10% 3.9%",
"primary": "240 5.9% 10%",
"primary-foreground": "0 0% 98%",
"secondary": "240 4.8% 95.9%",
"secondary-foreground": "240 5.9% 10%",
"muted": "240 4.8% 95.9%",
"muted-foreground": "240 3.8% 46.1%",
"accent": "240 4.8% 95.9%",
"accent-foreground": "240 5.9% 10%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "0 0% 98%",
"border": "240 5.9% 90%",
"input": "240 5.9% 90%",
"ring": "240 10% 3.9%"
},
"dark": {
"background": "240 10% 3.9%",
"foreground": "0 0% 98%",
"card": "240 10% 3.9%",
"card-foreground": "0 0% 98%",
"popover": "240 10% 3.9%",
"popover-foreground": "0 0% 98%",
"primary": "0 0% 98%",
"primary-foreground": "240 5.9% 10%",
"secondary": "240 3.7% 15.9%",
"secondary-foreground": "0 0% 98%",
"muted": "240 3.7% 15.9%",
"muted-foreground": "240 5% 64.9%",
"accent": "240 3.7% 15.9%",
"accent-foreground": "0 0% 98%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "0 0% 98%",
"border": "240 3.7% 15.9%",
"input": "240 3.7% 15.9%",
"ring": "240 4.9% 83.9%"
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 240 10% 3.9%;\n \n --muted: 240 4.8% 95.9%;\n --muted-foreground: 240 3.8% 46.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 240 10% 3.9%;\n \n --card: 0 0% 100%;\n --card-foreground: 240 10% 3.9%;\n \n --border: 240 5.9% 90%;\n --input: 240 5.9% 90%;\n \n --primary: 240 5.9% 10%;\n --primary-foreground: 0 0% 98%;\n \n --secondary: 240 4.8% 95.9%;\n --secondary-foreground: 240 5.9% 10%;\n \n --accent: 240 4.8% 95.9%;\n --accent-foreground: 240 5.9% 10%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n \n --ring: 240 10% 3.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 240 10% 3.9%;\n --foreground: 0 0% 98%;\n \n --muted: 240 3.7% 15.9%;\n --muted-foreground: 240 5% 64.9%;\n \n --popover: 240 10% 3.9%;\n --popover-foreground: 0 0% 98%;\n \n --card: 240 10% 3.9%;\n --card-foreground: 0 0% 98%;\n \n --border: 240 3.7% 15.9%;\n --input: 240 3.7% 15.9%;\n \n --primary: 0 0% 98%;\n --primary-foreground: 240 5.9% 10%;\n \n --secondary: 240 3.7% 15.9%;\n --secondary-foreground: 0 0% 98%;\n \n --accent: 240 3.7% 15.9%;\n --accent-foreground: 0 0% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 0% 98%;\n \n --ring: 240 4.9% 83.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@ -0,0 +1,611 @@
[
{
"name": "accordion",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/accordion/Accordion.vue",
"ui/accordion/AccordionContent.vue",
"ui/accordion/AccordionItem.vue",
"ui/accordion/AccordionTrigger.vue",
"ui/accordion/index.ts"
],
"type": "components:ui"
},
{
"name": "alert",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
"ui/alert/Alert.vue",
"ui/alert/AlertDescription.vue",
"ui/alert/AlertTitle.vue",
"ui/alert/index.ts"
],
"type": "components:ui"
},
{
"name": "alert-dialog",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils",
"button"
],
"files": [
"ui/alert-dialog/AlertDialog.vue",
"ui/alert-dialog/AlertDialogAction.vue",
"ui/alert-dialog/AlertDialogCancel.vue",
"ui/alert-dialog/AlertDialogContent.vue",
"ui/alert-dialog/AlertDialogDescription.vue",
"ui/alert-dialog/AlertDialogFooter.vue",
"ui/alert-dialog/AlertDialogHeader.vue",
"ui/alert-dialog/AlertDialogTitle.vue",
"ui/alert-dialog/AlertDialogTrigger.vue",
"ui/alert-dialog/index.ts"
],
"type": "components:ui"
},
{
"name": "aspect-ratio",
"dependencies": [
"radix-vue"
],
"registryDependencies": [],
"files": [
"ui/aspect-ratio/AspectRatio.vue",
"ui/aspect-ratio/index.ts"
],
"type": "components:ui"
},
{
"name": "avatar",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/avatar/Avatar.vue",
"ui/avatar/AvatarFallback.vue",
"ui/avatar/AvatarImage.vue",
"ui/avatar/index.ts"
],
"type": "components:ui"
},
{
"name": "badge",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
"ui/badge/Badge.vue",
"ui/badge/index.ts"
],
"type": "components:ui"
},
{
"name": "breadcrumb",
"dependencies": [],
"registryDependencies": [],
"files": [
"ui/breadcrumb/BreadCrumb.vue",
"ui/breadcrumb/BreadCrumbItem.vue",
"ui/breadcrumb/index.ts"
],
"type": "components:ui"
},
{
"name": "button",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
"ui/button/Button.vue",
"ui/button/index.ts"
],
"type": "components:ui"
},
{
"name": "calendar",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
"ui/calendar/Calendar.vue",
"ui/calendar/index.ts"
],
"type": "components:ui"
},
{
"name": "card",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
"ui/card/Card.vue",
"ui/card/CardContent.vue",
"ui/card/CardDescription.vue",
"ui/card/CardFooter.vue",
"ui/card/CardHeader.vue",
"ui/card/CardTitle.vue",
"ui/card/index.ts"
],
"type": "components:ui"
},
{
"name": "checkbox",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/checkbox/Checkbox.vue",
"ui/checkbox/index.ts"
],
"type": "components:ui"
},
{
"name": "collapsible",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/collapsible/Collapsible.vue",
"ui/collapsible/CollapsibleContent.vue",
"ui/collapsible/CollapsibleTrigger.vue",
"ui/collapsible/index.ts"
],
"type": "components:ui"
},
{
"name": "context-menu",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/context-menu/ContextMenu.vue",
"ui/context-menu/ContextMenuCheckboxItem.vue",
"ui/context-menu/ContextMenuContent.vue",
"ui/context-menu/ContextMenuGroup.vue",
"ui/context-menu/ContextMenuItem.vue",
"ui/context-menu/ContextMenuLabel.vue",
"ui/context-menu/ContextMenuPortal.vue",
"ui/context-menu/ContextMenuRadioGroup.vue",
"ui/context-menu/ContextMenuRadioItem.vue",
"ui/context-menu/ContextMenuSeparator.vue",
"ui/context-menu/ContextMenuShortcut.vue",
"ui/context-menu/ContextMenuSub.vue",
"ui/context-menu/ContextMenuSubContent.vue",
"ui/context-menu/ContextMenuSubTrigger.vue",
"ui/context-menu/ContextMenuTrigger.vue",
"ui/context-menu/index.ts"
],
"type": "components:ui"
},
{
"name": "data-table",
"dependencies": [],
"registryDependencies": [],
"files": [
"ui/data-table/DataTable.vue",
"ui/data-table/index.ts"
],
"type": "components:ui"
},
{
"name": "date-picker",
"dependencies": [],
"registryDependencies": [],
"files": [
"ui/date-picker/DatePicker.vue",
"ui/date-picker/index.ts"
],
"type": "components:ui"
},
{
"name": "dialog",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/dialog/Dialog.vue",
"ui/dialog/DialogContent.vue",
"ui/dialog/DialogDescription.vue",
"ui/dialog/DialogFooter.vue",
"ui/dialog/DialogHeader.vue",
"ui/dialog/DialogTitle.vue",
"ui/dialog/DialogTrigger.vue",
"ui/dialog/index.ts"
],
"type": "components:ui"
},
{
"name": "dropdown-menu",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/dropdown-menu/DropdownMenu.vue",
"ui/dropdown-menu/DropdownMenuCheckboxItem.vue",
"ui/dropdown-menu/DropdownMenuContent.vue",
"ui/dropdown-menu/DropdownMenuGroup.vue",
"ui/dropdown-menu/DropdownMenuItem.vue",
"ui/dropdown-menu/DropdownMenuLabel.vue",
"ui/dropdown-menu/DropdownMenuRadioGroup.vue",
"ui/dropdown-menu/DropdownMenuRadioItem.vue",
"ui/dropdown-menu/DropdownMenuSeparator.vue",
"ui/dropdown-menu/DropdownMenuShortcut.vue",
"ui/dropdown-menu/DropdownMenuSub.vue",
"ui/dropdown-menu/DropdownMenuSubContent.vue",
"ui/dropdown-menu/DropdownMenuSubTrigger.vue",
"ui/dropdown-menu/DropdownMenuTrigger.vue",
"ui/dropdown-menu/index.ts"
],
"type": "components:ui"
},
{
"name": "hover-card",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/hover-card/HoverCard.vue",
"ui/hover-card/HoverCardContent.vue",
"ui/hover-card/HoverCardTrigger.vue",
"ui/hover-card/index.ts"
],
"type": "components:ui"
},
{
"name": "input",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
"ui/input/Input.vue",
"ui/input/index.ts"
],
"type": "components:ui"
},
{
"name": "kbd",
"dependencies": [],
"registryDependencies": [],
"files": [
"ui/kbd/Kbd.vue",
"ui/kbd/index.ts"
],
"type": "components:ui"
},
{
"name": "label",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/label/Label.vue",
"ui/label/index.ts"
],
"type": "components:ui"
},
{
"name": "menubar",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/menubar/Menubar.vue",
"ui/menubar/MenubarCheckboxItem.vue",
"ui/menubar/MenubarContent.vue",
"ui/menubar/MenubarGroup.vue",
"ui/menubar/MenubarItem.vue",
"ui/menubar/MenubarLabel.vue",
"ui/menubar/MenubarMenu.vue",
"ui/menubar/MenubarRadioGroup.vue",
"ui/menubar/MenubarRadioItem.vue",
"ui/menubar/MenubarSeparator.vue",
"ui/menubar/MenubarShortcut.vue",
"ui/menubar/MenubarSub.vue",
"ui/menubar/MenubarSubContent.vue",
"ui/menubar/MenubarSubTrigger.vue",
"ui/menubar/MenubarTrigger.vue",
"ui/menubar/index.ts"
],
"type": "components:ui"
},
{
"name": "navigation-menu",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/navigation-menu/NavigationMenu.vue",
"ui/navigation-menu/NavigationMenuContent.vue",
"ui/navigation-menu/NavigationMenuIndicator.vue",
"ui/navigation-menu/NavigationMenuItem.vue",
"ui/navigation-menu/NavigationMenuLink.vue",
"ui/navigation-menu/NavigationMenuList.vue",
"ui/navigation-menu/NavigationMenuTrigger.vue",
"ui/navigation-menu/NavigationMenuViewport.vue",
"ui/navigation-menu/index.ts"
],
"type": "components:ui"
},
{
"name": "popover",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/popover/Popover.vue",
"ui/popover/PopoverContent.vue",
"ui/popover/PopoverTrigger.vue",
"ui/popover/index.ts"
],
"type": "components:ui"
},
{
"name": "progress",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/progress/Progress.vue",
"ui/progress/index.ts"
],
"type": "components:ui"
},
{
"name": "radio-group",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/radio-group/RadioGroup.vue",
"ui/radio-group/RadioGroupItem.vue",
"ui/radio-group/index.ts"
],
"type": "components:ui"
},
{
"name": "scroll-area",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/scroll-area/ScrollArea.vue",
"ui/scroll-area/ScrollBar.vue",
"ui/scroll-area/index.ts"
],
"type": "components:ui"
},
{
"name": "select",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/select/Select.vue",
"ui/select/SelectContent.vue",
"ui/select/SelectGroup.vue",
"ui/select/SelectItem.vue",
"ui/select/SelectItemText.vue",
"ui/select/SelectLabel.vue",
"ui/select/SelectSeparator.vue",
"ui/select/SelectTrigger.vue",
"ui/select/SelectValue.vue",
"ui/select/index.ts"
],
"type": "components:ui"
},
{
"name": "separator",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/separator/Separator.vue",
"ui/separator/index.ts"
],
"type": "components:ui"
},
{
"name": "sheet",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/sheet/Sheet.vue",
"ui/sheet/SheetClose.vue",
"ui/sheet/SheetContent.vue",
"ui/sheet/SheetDescription.vue",
"ui/sheet/SheetFooter.vue",
"ui/sheet/SheetHeader.vue",
"ui/sheet/SheetTitle.vue",
"ui/sheet/SheetTrigger.vue",
"ui/sheet/index.ts"
],
"type": "components:ui"
},
{
"name": "skeleton",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
"ui/skeleton/Skeleton.vue",
"ui/skeleton/index.ts"
],
"type": "components:ui"
},
{
"name": "slider",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/slider/Slider.vue",
"ui/slider/index.ts"
],
"type": "components:ui"
},
{
"name": "switch",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/switch/Switch.vue",
"ui/switch/index.ts"
],
"type": "components:ui"
},
{
"name": "table",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
"ui/table/Table.vue",
"ui/table/TableBody.vue",
"ui/table/TableCaption.vue",
"ui/table/TableCell.vue",
"ui/table/TableEmpty.vue",
"ui/table/TableFooter.vue",
"ui/table/TableHead.vue",
"ui/table/TableHeader.vue",
"ui/table/TableRow.vue",
"ui/table/index.ts"
],
"type": "components:ui"
},
{
"name": "tabs",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/tabs/Tabs.vue",
"ui/tabs/TabsContent.vue",
"ui/tabs/TabsList.vue",
"ui/tabs/TabsTrigger.vue",
"ui/tabs/index.ts"
],
"type": "components:ui"
},
{
"name": "textarea",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
"ui/textarea/Textarea.vue",
"ui/textarea/index.ts"
],
"type": "components:ui"
},
{
"name": "toggle",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/toggle/Toggle.vue",
"ui/toggle/index.ts"
],
"type": "components:ui"
},
{
"name": "tooltip",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
"ui/tooltip/Tooltip.vue",
"ui/tooltip/TooltipContent.vue",
"ui/tooltip/TooltipProvider.vue",
"ui/tooltip/TooltipTrigger.vue",
"ui/tooltip/index.ts"
],
"type": "components:ui"
}
]

View File

@ -0,0 +1,32 @@
{
"name": "accordion",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Accordion.vue",
"content": "<script setup lang=\"ts\">\nimport {\n AccordionRoot,\n type AccordionRootEmits,\n type AccordionRootProps,\n} from 'radix-vue'\nimport { useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<AccordionRootProps>()\nconst emits = defineEmits<AccordionRootEmits>()\n</script>\n\n<template>\n <AccordionRoot v-bind=\"{ ...props, ...useEmitAsProps(emits) }\" class=\"accordion\">\n <slot />\n </AccordionRoot>\n</template>\n"
},
{
"name": "AccordionContent.vue",
"content": "<script setup lang=\"ts\">\nimport { AccordionContent, type AccordionContentProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<AccordionContentProps & { class?: string }>()\n</script>\n\n<template>\n <AccordionContent\n v-bind=\"props\"\n :class=\"\n cn(\n 'overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down',\n props.class,\n )\n \"\n >\n <div class=\"pb-4 pt-0\">\n <slot />\n </div>\n </AccordionContent>\n</template>\n"
},
{
"name": "AccordionItem.vue",
"content": "<script setup lang=\"ts\">\nimport { AccordionItem, type AccordionItemProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<AccordionItemProps & { class?: string }>()\n</script>\n\n<template>\n <AccordionItem\n v-bind=\"props\"\n :class=\"cn('border-b', props.class ?? '')\"\n >\n <slot />\n </AccordionItem>\n</template>\n"
},
{
"name": "AccordionTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport {\n AccordionHeader,\n AccordionTrigger,\n type AccordionTriggerProps,\n} from 'radix-vue'\nimport { ChevronDown } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<AccordionTriggerProps & { class?: string }>()\n</script>\n\n<template>\n <AccordionHeader class=\"flex\" as=\"div\">\n <AccordionTrigger\n v-bind=\"props\"\n :class=\"\n cn(\n 'flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',\n props.class,\n )\n \"\n >\n <slot />\n <ChevronDown\n class=\"h-4 w-4 shrink-0 transition-transform duration-200\"\n />\n </AccordionTrigger>\n </AccordionHeader>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Accordion } from './Accordion.vue'\nexport { default as AccordionContent } from './AccordionContent.vue'\nexport { default as AccordionItem } from './AccordionItem.vue'\nexport { default as AccordionTrigger } from './AccordionTrigger.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,53 @@
{
"name": "alert-dialog",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils",
"button"
],
"files": [
{
"name": "AlertDialog.vue",
"content": "<script setup lang=\"ts\">\nimport { type AlertDialogEmits, type AlertDialogProps, AlertDialogRoot } from 'radix-vue'\nimport { useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<AlertDialogProps>()\n\nconst emits = defineEmits<AlertDialogEmits>()\n\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <AlertDialogRoot v-bind=\"{ ...props, ...emitsAsProps }\">\n <slot />\n </AlertDialogRoot>\n</template>\n"
},
{
"name": "AlertDialogAction.vue",
"content": "<script setup lang=\"ts\">\nimport { AlertDialogAction, type AlertDialogActionProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/lib/registry/default/ui/button'\n\nconst props = defineProps<AlertDialogActionProps>()\n</script>\n\n<template>\n <AlertDialogAction v-bind=\"props\" :class=\"cn(buttonVariants(), $attrs.class ?? '')\">\n <slot />\n </AlertDialogAction>\n</template>\n"
},
{
"name": "AlertDialogCancel.vue",
"content": "<script setup lang=\"ts\">\nimport { AlertDialogCancel, type AlertDialogCancelProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/lib/registry/default/ui/button'\n\nconst props = defineProps<AlertDialogCancelProps>()\n</script>\n\n<template>\n <AlertDialogCancel v-bind=\"props\" :class=\"cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', $attrs.class ?? '')\">\n <slot />\n </AlertDialogCancel>\n</template>\n"
},
{
"name": "AlertDialogContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n AlertDialogContent,\n type AlertDialogContentEmits,\n type AlertDialogContentProps,\n AlertDialogOverlay,\n AlertDialogPortal,\n} from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<AlertDialogContentProps & { class?: string }>()\n\nconst emits = defineEmits<AlertDialogContentEmits>()\n\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <AlertDialogPortal>\n <AlertDialogOverlay\n class=\"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n />\n <AlertDialogContent\n v-bind=\"{ ...props, ...emitsAsProps }\"\n :class=\"\n cn(\n 'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full',\n props.class,\n )\n \"\n >\n <slot />\n </AlertDialogContent>\n </AlertDialogPortal>\n</template>\n"
},
{
"name": "AlertDialogDescription.vue",
"content": "<script setup lang=\"ts\">\nimport {\n AlertDialogDescription,\n type AlertDialogDescriptionProps,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<AlertDialogDescriptionProps & { class?: string }>()\n</script>\n\n<template>\n <AlertDialogDescription\n :class=\"cn('text-muted-foreground text-sm', props.class)\"\n :as-child=\"props.asChild\"\n >\n <slot />\n </AlertDialogDescription>\n</template>\n"
},
{
"name": "AlertDialogFooter.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps({\n class: {\n type: String,\n default: '',\n },\n})\n</script>\n\n<template>\n <div\n :class=\"\n cn(\n 'flex flex-col space-y-2 sm:space-y-0 mt-3.5 sm:flex-row sm:justify-end sm:space-x-2',\n props.class,\n )\n \"\n >\n <slot />\n </div>\n</template>\n"
},
{
"name": "AlertDialogHeader.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps({\n class: {\n type: String,\n default: '',\n },\n})\n</script>\n\n<template>\n <div\n :class=\"cn('flex flex-col space-y-2 text-center sm:text-left', props.class)\"\n >\n <slot />\n </div>\n</template>\n"
},
{
"name": "AlertDialogTitle.vue",
"content": "<script setup lang=\"ts\">\nimport { AlertDialogTitle, type AlertDialogTitleProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<AlertDialogTitleProps & { class?: string }>()\n</script>\n\n<template>\n <AlertDialogTitle\n :as-child=\"props.asChild\"\n :class=\"cn('text-lg text-foreground font-semibold', props.class)\"\n >\n <slot />\n </AlertDialogTitle>\n</template>\n"
},
{
"name": "AlertDialogTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { AlertDialogTrigger, type AlertDialogTriggerProps } from 'radix-vue'\n\nconst props = defineProps<AlertDialogTriggerProps>()\n</script>\n\n<template>\n <AlertDialogTrigger v-bind=\"props\">\n <slot />\n </AlertDialogTrigger>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as AlertDialog } from './AlertDialog.vue'\nexport { default as AlertDialogTrigger } from './AlertDialogTrigger.vue'\nexport { default as AlertDialogContent } from './AlertDialogContent.vue'\nexport { default as AlertDialogHeader } from './AlertDialogHeader.vue'\nexport { default as AlertDialogTitle } from './AlertDialogTitle.vue'\nexport { default as AlertDialogDescription } from './AlertDialogDescription.vue'\nexport { default as AlertDialogFooter } from './AlertDialogFooter.vue'\nexport { default as AlertDialogAction } from './AlertDialogAction.vue'\nexport { default as AlertDialogCancel } from './AlertDialogCancel.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,26 @@
{
"name": "alert",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Alert.vue",
"content": "<script setup lang=\"ts\">\nimport { alertVariants } from '.'\nimport { cn } from '@/lib/utils'\n\ninterface Props {\n variant?: NonNullable<Parameters<typeof alertVariants>[0]>['variant']\n class?: string\n}\n\nconst props = defineProps<Props>()\n</script>\n\n<template>\n <div :class=\"cn(alertVariants({ variant }), props.class ?? '')\">\n <slot />\n </div>\n</template>\n"
},
{
"name": "AlertDescription.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps({\n class: String,\n})\n</script>\n\n<template>\n <div :class=\"cn('text-sm [&_p]:leading-relaxed', props.class)\">\n <slot />\n </div>\n</template>\n"
},
{
"name": "AlertTitle.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n</script>\n\n<template>\n <h5 :class=\"cn('mb-1 font-medium leading-none tracking-tight', $attrs.class ?? '')\">\n <slot />\n </h5>\n</template>\n"
},
{
"name": "index.ts",
"content": "import { cva } from 'class-variance-authority'\n\nexport { default as Alert } from './Alert.vue'\nexport { default as AlertTitle } from './AlertTitle.vue'\nexport { default as AlertDescription } from './AlertDescription.vue'\n\nexport const alertVariants = cva(\n 'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground',\n {\n variants: {\n variant: {\n default: 'bg-background text-foreground',\n destructive:\n 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n)\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,18 @@
{
"name": "aspect-ratio",
"dependencies": [
"radix-vue"
],
"registryDependencies": [],
"files": [
{
"name": "AspectRatio.vue",
"content": "<script setup lang=\"ts\">\nimport { AspectRatio, type AspectRatioProps } from 'radix-vue'\n\nconst props = defineProps<AspectRatioProps>()\n</script>\n\n<template>\n <AspectRatio v-bind=\"props\">\n <slot />\n </AspectRatio>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as AspectRatio } from './AspectRatio.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,28 @@
{
"name": "avatar",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Avatar.vue",
"content": "<script setup lang=\"ts\">\nimport { AvatarRoot } from 'radix-vue'\nimport { avatarVariant } from '.'\nimport { cn } from '@/lib/utils'\n\ninterface Props {\n size?: NonNullable<Parameters<typeof avatarVariant>[0]>['size']\n shape?: NonNullable<Parameters<typeof avatarVariant>[0]>['shape']\n class?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: 'sm',\n shape: 'circle',\n})\n</script>\n\n<template>\n <AvatarRoot :class=\"cn(avatarVariant({ size, shape }), props.class)\">\n <slot />\n </AvatarRoot>\n</template>\n"
},
{
"name": "AvatarFallback.vue",
"content": "<script setup lang=\"ts\">\nimport { AvatarFallback, type AvatarFallbackProps } from 'radix-vue'\n\nconst props = defineProps<AvatarFallbackProps>()\n</script>\n\n<template>\n <AvatarFallback v-bind=\"props\">\n <slot />\n </AvatarFallback>\n</template>\n"
},
{
"name": "AvatarImage.vue",
"content": "<script setup lang=\"ts\">\nimport { AvatarImage, type AvatarImageProps } from 'radix-vue'\n\nconst props = defineProps<AvatarImageProps>()\n</script>\n\n<template>\n <AvatarImage v-bind=\"props\" class=\"h-full w-full object-cover\" />\n</template>\n"
},
{
"name": "index.ts",
"content": "import { cva } from 'class-variance-authority'\n\nexport { default as Avatar } from './Avatar.vue'\nexport { default as AvatarImage } from './AvatarImage.vue'\nexport { default as AvatarFallback } from './AvatarFallback.vue'\n\nexport const avatarVariant = cva(\n 'inline-flex items-center justify-center font-normal text-foregorund select-none shrink-0 bg-secondary overflow-hidden',\n {\n variants: {\n size: {\n sm: 'h-10 w-10 text-xs',\n base: 'h-16 w-16 text-2xl',\n lg: 'h-32 w-32 text-5xl',\n },\n shape: {\n circle: 'rounded-full',\n square: 'rounded-md',\n },\n },\n },\n)\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,18 @@
{
"name": "badge",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Badge.vue",
"content": "<script setup lang=\"ts\">\nimport type { VariantProps } from 'class-variance-authority'\nimport { badgeVariants } from '.'\nimport { cn } from '@/lib/utils'\n\ninterface BadgeVariantProps extends VariantProps<typeof badgeVariants> {}\n\ninterface Props {\n variant?: BadgeVariantProps['variant']\n}\ndefineProps<Props>()\n</script>\n\n<template>\n <div :class=\"cn(badgeVariants({ variant }), $attrs.class ?? '')\">\n <slot />\n </div>\n</template>\n"
},
{
"name": "index.ts",
"content": "import { cva } from 'class-variance-authority'\n\nexport { default as Badge } from './Badge.vue'\n\nexport const badgeVariants = cva(\n 'inline-flex items-center rounded-full 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',\n {\n variants: {\n variant: {\n default:\n 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',\n secondary:\n 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',\n destructive:\n 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80',\n outline: 'text-foreground',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n)\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,20 @@
{
"name": "breadcrumb",
"dependencies": [],
"registryDependencies": [],
"files": [
{
"name": "BreadCrumb.vue",
"content": "<template>\n <ol class=\"flex items-center whitespace-nowrap min-w-0\">\n <slot />\n </ol>\n</template>\n"
},
{
"name": "BreadCrumbItem.vue",
"content": "<script setup lang=\"ts\">\nimport { ChevronRight } from 'lucide-vue-next'\n\ninterface BreadCrumbItemProps {\n path?: string\n lastItem?: boolean\n as?: string | object\n}\n\nconst props = withDefaults(defineProps<BreadCrumbItemProps>(), {\n as: 'span',\n})\n</script>\n\n<template>\n <li class=\"text-sm text-muted\">\n <component\n :is=\"props.as\"\n :to=\"props.path\"\n class=\"flex items-center\"\n :class=\"{\n '!font-semibold !text-foreground': $route.path === props.path,\n }\"\n >\n <slot />\n <ChevronRight\n v-if=\"!props.lastItem\"\n class=\"flex-shrink-0 h-3 w-3 text-muted mx-2\"\n />\n </component>\n </li>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as BreadCrumb } from './BreadCrumb.vue'\nexport { default as BreadCrumbItem } from './BreadCrumbItem.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,18 @@
{
"name": "button",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Button.vue",
"content": "<script setup lang=\"ts\">\nimport { buttonVariants } from '.'\nimport { cn } from '@/lib/utils'\n\ninterface Props {\n variant?: NonNullable<Parameters<typeof buttonVariants>[0]>['variant']\n size?: NonNullable<Parameters<typeof buttonVariants>[0]>['size']\n as?: string\n}\n\nwithDefaults(defineProps<Props>(), {\n as: 'button',\n})\n</script>\n\n<template>\n <component\n :is=\"as\"\n :class=\"cn(buttonVariants({ variant, size }), $attrs.class ?? '')\"\n >\n <slot />\n </component>\n</template>\n"
},
{
"name": "index.ts",
"content": "import { cva } from 'class-variance-authority'\n\nexport { default as Button } from './Button.vue'\n\nexport const buttonVariants = cva(\n 'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n outline:\n 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-10 px-4 py-2',\n sm: 'h-9 rounded-md px-3',\n lg: 'h-11 rounded-md px-8',\n icon: 'h-10 w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,18 @@
{
"name": "calendar",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Calendar.vue",
"content": "<script setup lang=\"ts\">\nimport { useVModel } from '@vueuse/core'\nimport type { Calendar } from 'v-calendar'\nimport { DatePicker } from 'v-calendar'\nimport { ChevronLeft, ChevronRight } from 'lucide-vue-next'\nimport { computed, nextTick, onMounted, ref } from 'vue'\nimport { buttonVariants } from '../button'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(defineProps< {\n modelValue?: string | number | Date | Partial<{\n start: Date\n end: Date\n }>\n modelModifiers?: object\n columns?: number\n type?: 'single' | 'range'\n}>(), {\n type: 'single',\n columns: 1,\n})\nconst emits = defineEmits<{\n (e: 'update:modelValue', payload: typeof props.modelValue): void\n}>()\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n passive: true,\n})\n\nconst datePicker = ref<InstanceType<typeof DatePicker>>()\n// @ts-expect-error in this current version of v-calendar has the calendaRef instance, which is required to handle arrow nav.\nconst calendarRef = computed<InstanceType<typeof Calendar>>(() => datePicker.value.calendarRef)\n\nfunction handleNav(direction: 'prev' | 'next') {\n if (!calendarRef.value)\n return\n\n if (direction === 'prev')\n calendarRef.value.movePrev()\n else calendarRef.value.moveNext()\n}\n\nonMounted(async () => {\n await nextTick()\n await nextTick()\n if (modelValue.value instanceof Date && calendarRef.value)\n calendarRef.value.focusDate(modelValue.value)\n})\n</script>\n\n<template>\n <div class=\"relative\">\n <div class=\"absolute top-3 flex justify-between w-full px-4\">\n <button :class=\"cn(buttonVariants({ variant: 'outline' }), 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100')\" @click=\"handleNav('prev')\">\n <ChevronLeft class=\"w-4 h-4\" />\n </button>\n <button :class=\"cn(buttonVariants({ variant: 'outline' }), 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100')\" @click=\"handleNav('next')\">\n <ChevronRight class=\"w-4 h-4\" />\n </button>\n </div>\n\n <DatePicker ref=\"datePicker\" v-model=\"modelValue\" :model-modifiers=\"modelModifiers\" class=\"calendar\" trim-weeks :transition=\"'none'\" :columns=\"columns\" />\n </div>\n</template>\n\n<style lang=\"postcss\">\n.calendar {\n @apply p-3 text-center;\n}\n.calendar .vc-pane-layout {\n @apply grid gap-4;\n}\n.calendar .vc-title {\n @apply text-sm font-medium pointer-events-none;\n}\n.calendar .vc-pane-header-wrapper {\n @apply hidden;\n}\n.calendar .vc-weeks {\n @apply mt-4;\n}\n.calendar .vc-weekdays {\n @apply flex;\n}\n.calendar .vc-weekday {\n @apply text-muted-foreground rounded-md w-9 font-normal text-[0.8rem];\n}\n.calendar .vc-weeks {\n @apply w-full space-y-2 flex flex-col [&>_div]:grid [&>_div]:grid-cols-7;\n}\n.calendar .vc-day:has(.vc-highlights) {\n @apply bg-accent first:rounded-l-md last:rounded-r-md overflow-hidden;\n}\n.calendar .vc-day-content {\n @apply text-center text-sm p-0 relative focus-within:relative focus-within:z-20 inline-flex items-center justify-center ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 hover:bg-accent hover:text-accent-foreground h-9 w-9 font-normal aria-selected:opacity-100 select-none;\n}\n.calendar .vc-day-content:not(.vc-highlight-content-light) {\n @apply rounded-md;\n}\n.calendar .is-not-in-month:not(:has(.vc-highlight-content-solid)):not(:has(.vc-highlight-content-light)):not(:has(.vc-highlight-content-outline)),\n.calendar .vc-disabled {\n @apply text-muted-foreground opacity-50;\n}\n.calendar .vc-highlight-content-solid, .calendar .vc-highlight-content-outline {\n @apply bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground;\n}\n.calendar .vc-highlight-content-light {\n @apply bg-accent text-accent-foreground;\n}\n</style>\n"
},
{
"name": "index.ts",
"content": "export { default as Calendar } from './Calendar.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,38 @@
{
"name": "card",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Card.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps({\n class: {\n type: String,\n default: '',\n },\n})\n</script>\n\n<template>\n <div\n :class=\"\n cn(\n 'rounded-lg border bg-card text-card-foreground shadow-sm',\n props.class,\n )\n \"\n >\n <slot />\n </div>\n</template>\n"
},
{
"name": "CardContent.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps({\n class: {\n type: String,\n default: '',\n },\n})\n</script>\n\n<template>\n <div :class=\"cn('p-6 pt-0', props.class)\">\n <slot />\n </div>\n</template>\n"
},
{
"name": "CardDescription.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps({\n class: {\n type: String,\n default: '',\n },\n})\n</script>\n\n<template>\n <p :class=\"cn('text-sm text-muted-foreground', props.class)\">\n <slot />\n </p>\n</template>\n"
},
{
"name": "CardFooter.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps({\n class: {\n type: String,\n default: '',\n },\n})\n</script>\n\n<template>\n <div :class=\"cn('p-6 pt-0', props.class)\">\n <slot />\n </div>\n</template>\n"
},
{
"name": "CardHeader.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps({\n class: {\n type: String,\n default: '',\n },\n})\n</script>\n\n<template>\n <div :class=\"cn('flex flex-col space-y-1.5 p-6', props.class)\">\n <slot />\n </div>\n</template>\n"
},
{
"name": "CardTitle.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps({\n class: {\n type: String,\n default: '',\n },\n})\n</script>\n\n<template>\n <h3\n :class=\"\n cn('text-2xl font-semibold leading-none tracking-tighter', props.class)\n \"\n >\n <slot />\n </h3>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Card } from './Card.vue'\nexport { default as CardHeader } from './CardHeader.vue'\nexport { default as CardTitle } from './CardTitle.vue'\nexport { default as CardDescription } from './CardDescription.vue'\nexport { default as CardContent } from './CardContent.vue'\nexport { default as CardFooter } from './CardFooter.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,20 @@
{
"name": "checkbox",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Checkbox.vue",
"content": "<script setup lang=\"ts\">\nimport type { CheckboxRootEmits, CheckboxRootProps } from 'radix-vue'\nimport { CheckboxIndicator, CheckboxRoot } from 'radix-vue'\nimport { Check } from 'lucide-vue-next'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<CheckboxRootProps>()\nconst emits = defineEmits<CheckboxRootEmits>()\n\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <CheckboxRoot\n v-bind=\"{ ...props, ...emitsAsProps }\"\n :class=\"\n cn('peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',\n $attrs.class ?? '')\"\n >\n <CheckboxIndicator class=\"flex items-center justify-center text-current\">\n <Check class=\"h-4 w-4\" />\n </CheckboxIndicator>\n </CheckboxRoot>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Checkbox } from './Checkbox.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,28 @@
{
"name": "collapsible",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Collapsible.vue",
"content": "<script setup lang=\"ts\">\nimport { CollapsibleRoot } from 'radix-vue'\nimport type { CollapsibleRootEmits, CollapsibleRootProps } from 'radix-vue'\nimport { useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<CollapsibleRootProps>()\nconst emits = defineEmits<CollapsibleRootEmits>()\n</script>\n\n<template>\n <CollapsibleRoot v-slot=\"{ open }\" v-bind=\"{ ...props, ...useEmitAsProps(emits) }\">\n <slot :open=\"open\" />\n </CollapsibleRoot>\n</template>\n"
},
{
"name": "CollapsibleContent.vue",
"content": "<script setup lang=\"ts\">\nimport { CollapsibleContent, type CollapsibleContentProps } from 'radix-vue'\n\nconst props = defineProps<CollapsibleContentProps>()\n</script>\n\n<template>\n <CollapsibleContent v-bind=\"props\">\n <slot />\n </CollapsibleContent>\n</template>\n"
},
{
"name": "CollapsibleTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { CollapsibleTrigger, type CollapsibleTriggerProps } from 'radix-vue'\n\nconst props = defineProps<CollapsibleTriggerProps>()\n</script>\n\n<template>\n <CollapsibleTrigger v-bind=\"props\">\n <slot />\n </CollapsibleTrigger>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Collapsible } from './Collapsible.vue'\nexport { default as CollapsibleTrigger } from './CollapsibleTrigger.vue'\nexport { default as CollapsibleContent } from './CollapsibleContent.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,76 @@
{
"name": "context-menu",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "ContextMenu.vue",
"content": "<script setup lang=\"ts\">\nimport { ContextMenuRoot } from 'radix-vue'\nimport type { ContextMenuRootEmits, ContextMenuRootProps } from 'radix-vue'\nimport { useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<ContextMenuRootProps>()\nconst emits = defineEmits<ContextMenuRootEmits>()\n</script>\n\n<template>\n <ContextMenuRoot v-bind=\"{ ...props, ...useEmitAsProps(emits) }\">\n <slot />\n </ContextMenuRoot>\n</template>\n"
},
{
"name": "ContextMenuCheckboxItem.vue",
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenuCheckboxItem,\n type ContextMenuCheckboxItemEmits,\n type ContextMenuCheckboxItemProps,\n ContextMenuItemIndicator,\n} from 'radix-vue'\nimport { Check } from 'lucide-vue-next'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<ContextMenuCheckboxItemProps & { class?: string }>()\nconst emits = defineEmits<ContextMenuCheckboxItemEmits>()\n</script>\n\n<template>\n <ContextMenuCheckboxItem\n v-bind=\"{ ...props, ...useEmitAsProps(emits) }\"\n :class=\"[\n cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n ),\n ]\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <ContextMenuItemIndicator\n class=\"absolute left-1.5 inline-flex w-4 h-4 items-center justify-center\"\n >\n <Check class=\"h-4 h-w\" />\n </ContextMenuItemIndicator>\n </span>\n <slot />\n </ContextMenuCheckboxItem>\n</template>\n"
},
{
"name": "ContextMenuContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenuContent,\n type ContextMenuContentEmits,\n type ContextMenuContentProps,\n ContextMenuPortal,\n} from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<ContextMenuContentProps & { class?: string }>()\nconst emits = defineEmits<ContextMenuContentEmits>()\n</script>\n\n<template>\n <ContextMenuPortal>\n <ContextMenuContent\n :align-offset=\"props.alignOffset\"\n :class=\"[\n cn(\n 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n ),\n ]\"\n v-bind=\"{ ...props, ...useEmitAsProps(emits) }\"\n >\n <slot />\n </ContextMenuContent>\n </ContextMenuPortal>\n</template>\n"
},
{
"name": "ContextMenuGroup.vue",
"content": "<script setup lang=\"ts\">\nimport { ContextMenuGroup, type ContextMenuGroupProps } from 'radix-vue'\n\nconst props = defineProps<ContextMenuGroupProps>()\n</script>\n\n<template>\n <ContextMenuGroup v-bind=\"props\">\n <slot />\n </ContextMenuGroup>\n</template>\n"
},
{
"name": "ContextMenuItem.vue",
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenuItem,\n type ContextMenuItemEmits,\n type ContextMenuItemProps,\n} from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<ContextMenuItemProps & { class?: string; inset?: boolean }>()\nconst emits = defineEmits<ContextMenuItemEmits>()\n</script>\n\n<template>\n <ContextMenuItem\n v-bind=\"{ ...props, ...useEmitAsProps(emits) }\"\n :class=\"[\n cn(\n 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && 'pl-8',\n props.class,\n ),\n ]\"\n >\n <slot />\n </ContextMenuItem>\n</template>\n"
},
{
"name": "ContextMenuLabel.vue",
"content": "<script setup lang=\"ts\">\nimport { ContextMenuLabel, type ContextMenuLabelProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<ContextMenuLabelProps & { class?: string; inset?: boolean }>()\n</script>\n\n<template>\n <ContextMenuLabel\n v-bind=\"props\"\n :class=\"\n cn('px-2 py-1.5 text-sm font-semibold text-foreground',\n inset && 'pl-8', props.class ?? '',\n )\"\n >\n <slot />\n </ContextMenuLabel>\n</template>\n"
},
{
"name": "ContextMenuPortal.vue",
"content": "<script setup lang=\"ts\">\nimport { ContextMenuPortal, type ContextMenuPortalProps } from 'radix-vue'\n\nconst props = defineProps<ContextMenuPortalProps>()\n</script>\n\n<template>\n <ContextMenuPortal v-bind=\"props\">\n <slot />\n </ContextMenuPortal>\n</template>\n"
},
{
"name": "ContextMenuRadioGroup.vue",
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenuRadioGroup,\n type ContextMenuRadioGroupEmits,\n type ContextMenuRadioGroupProps,\n} from 'radix-vue'\n\nconst props = defineProps<ContextMenuRadioGroupProps>()\n\nconst emits = defineEmits<ContextMenuRadioGroupEmits>()\n</script>\n\n<template>\n <ContextMenuRadioGroup\n v-bind=\"props\"\n @update:model-value=\"emits('update:modelValue', $event)\"\n >\n <slot />\n </ContextMenuRadioGroup>\n</template>\n"
},
{
"name": "ContextMenuRadioItem.vue",
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenuItemIndicator,\n ContextMenuRadioItem,\n type ContextMenuRadioItemEmits,\n type ContextMenuRadioItemProps,\n} from 'radix-vue'\nimport { Circle } from 'lucide-vue-next'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<ContextMenuRadioItemProps & { class?: string }>()\nconst emits = defineEmits<ContextMenuRadioItemEmits>()\n</script>\n\n<template>\n <ContextMenuRadioItem\n v-bind=\"{ ...props, ...useEmitAsProps(emits) }\"\n :class=\"[\n cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n ),\n ]\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <ContextMenuItemIndicator>\n <Circle class=\"h-2 w-2 fill-current\" />\n </ContextMenuItemIndicator>\n </span>\n <slot />\n </ContextMenuRadioItem>\n</template>\n"
},
{
"name": "ContextMenuSeparator.vue",
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenuSeparator,\n type ContextMenuSeparatorProps,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<ContextMenuSeparatorProps>()\n</script>\n\n<template>\n <ContextMenuSeparator v-bind=\"props\" :class=\"cn('-mx-1 my-1 h-px bg-border', $attrs.class ?? '')\" />\n</template>\n"
},
{
"name": "ContextMenuShortcut.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n</script>\n\n<template>\n <span :class=\"cn('ml-auto text-xs tracking-widest text-muted-foreground', $attrs.class ?? '')\">\n <slot />\n </span>\n</template>\n"
},
{
"name": "ContextMenuSub.vue",
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenuSub,\n type ContextMenuSubEmits,\n type ContextMenuSubProps,\n} from 'radix-vue'\n\nconst props = defineProps<ContextMenuSubProps>()\n\nconst emits = defineEmits<ContextMenuSubEmits>()\n</script>\n\n<template>\n <ContextMenuSub v-bind=\"props\" @update:open=\"emits('update:open', $event)\">\n <slot />\n </ContextMenuSub>\n</template>\n"
},
{
"name": "ContextMenuSubContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenuSubContent,\n type DropdownMenuSubContentEmits,\n type DropdownMenuSubContentProps,\n} from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<DropdownMenuSubContentProps & { class?: string }>()\nconst emits = defineEmits<DropdownMenuSubContentEmits>()\n</script>\n\n<template>\n <ContextMenuSubContent\n v-bind=\"{ ...props, ...useEmitAsProps(emits) }\"\n :class=\"\n cn(\n 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </ContextMenuSubContent>\n</template>\n"
},
{
"name": "ContextMenuSubTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenuSubTrigger,\n type ContextMenuSubTriggerProps,\n} from 'radix-vue'\nimport { ChevronRight } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<ContextMenuSubTriggerProps & { class?: string; inset?: boolean }>()\n</script>\n\n<template>\n <ContextMenuSubTrigger\n v-bind=\"props\"\n :class=\"[\n cn(\n 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',\n inset && 'pl-8',\n props.class,\n ),\n ]\"\n >\n <slot />\n <ChevronRight class=\"ml-auto h-4 w-4\" />\n </ContextMenuSubTrigger>\n</template>\n"
},
{
"name": "ContextMenuTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { ContextMenuTrigger, type ContextMenuTriggerProps } from 'radix-vue'\n\nconst props = defineProps<ContextMenuTriggerProps>()\n</script>\n\n<template>\n <ContextMenuTrigger v-bind=\"props\">\n <slot />\n </ContextMenuTrigger>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as ContextMenu } from './ContextMenu.vue'\nexport { default as ContextMenuTrigger } from './ContextMenuTrigger.vue'\nexport { default as ContextMenuContent } from './ContextMenuContent.vue'\nexport { default as ContextMenuGroup } from './ContextMenuGroup.vue'\nexport { default as ContextMenuRadioGroup } from './ContextMenuRadioGroup.vue'\nexport { default as ContextMenuItem } from './ContextMenuItem.vue'\nexport { default as ContextMenuCheckboxItem } from './ContextMenuCheckboxItem.vue'\nexport { default as ContextMenuRadioItem } from './ContextMenuRadioItem.vue'\nexport { default as ContextMenuShortcut } from './ContextMenuShortcut.vue'\nexport { default as ContextMenuSeparator } from './ContextMenuSeparator.vue'\nexport { default as ContextMenuLabel } from './ContextMenuLabel.vue'\nexport { default as ContextMenuSub } from './ContextMenuSub.vue'\nexport { default as ContextMenuSubTrigger } from './ContextMenuSubTrigger.vue'\nexport { default as ContextMenuSubContent } from './ContextMenuSubContent.vue'\n"
}
],
"type": "components:ui"
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,16 @@
{
"name": "date-picker",
"dependencies": [],
"registryDependencies": [],
"files": [
{
"name": "DatePicker.vue",
"content": "<script setup lang=\"ts\">\nimport { useDark } from '@vueuse/core'\nimport { DatePicker } from 'v-calendar'\nimport 'v-calendar/style.css'\n\nconst isDark = useDark()\n</script>\n\n<template>\n <DatePicker :is-dark=\"isDark\" borderless trim-weeks expanded />\n</template>\n\n<style>\n:root {\n --vc-font-family: \"Inter\", sans-serif;\n --vc-rounded-full: var(--radius);\n --vc-font-bold: 500;\n --vc-font-semibold: 600;\n --vc-text-lg: 14px;\n}\n\n.vc-light,\n.vc-dark {\n --vc-bg: var(--background);\n --vc-border: var(--border);\n --vc-focus-ring: 0 0 0 3px rgba(0, 0, 0, 0.2);\n --vc-weekday-color: var(--muted);\n --vc-popover-content-color: var(--muted);\n --vc-popover-content-bg: var(--background);\n --vc-popover-content-border: var(--border);\n\n &.vc-attr,\n & .vc-attr {\n --vc-content-color: var(--primary);\n --vc-highlight-outline-bg: var(--primary);\n --vc-highlight-outline-border: var(--primary);\n --vc-highlight-outline-content-color: var(--primary-foreground);\n --vc-highlight-light-bg: var(\n --vc-accent-200\n ); /* Highlighted color between two dates */\n --vc-highlight-light-content-color: var(--secondary-foreground);\n --vc-highlight-solid-bg: var(--primary);\n --vc-highlight-solid-content-color: var(--primary-foreground);\n --vc-dot-bg: var(--primary);\n --vc-bar-bg: var(--primary);\n }\n}\n\n.vc-blue {\n --vc-accent-200: var(--secondary);\n --vc-accent-400: var(--primary);\n --vc-accent-500: var(--primary);\n --vc-accent-600: var(--primary);\n}\n\n.dark {\n .vc-blue {\n --vc-accent-200: var(--secondary);\n --vc-accent-400: var(--primary);\n --vc-accent-500: var(--secondary);\n }\n}\n</style>\n"
},
{
"name": "index.ts",
"content": "export { default as DatePicker } from './DatePicker.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,44 @@
{
"name": "dialog",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Dialog.vue",
"content": "<script setup lang=\"ts\">\nimport { DialogRoot } from 'radix-vue'\n</script>\n\n<template>\n <DialogRoot>\n <slot />\n </DialogRoot>\n</template>\n"
},
{
"name": "DialogContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n} from 'radix-vue'\nimport { X } from 'lucide-vue-next'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<DialogContentProps & { class?: string }>()\nconst emits = defineEmits<DialogContentEmits>()\n\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay\n class=\"fixed inset-0 z-50 bg-white/80 dark:bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n />\n <DialogContent\n :class=\"\n cn(\n 'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full',\n props.class,\n )\n \"\n v-bind=\"{ ...props, ...emitsAsProps }\"\n >\n <slot />\n\n <DialogClose\n class=\"absolute top-4 right-4 p-0.5 transition-colors rounded-md hover:bg-secondary\"\n >\n <X class=\"w-4 h-4\" />\n <span className=\"sr-only\">Close</span>\n </DialogClose>\n </DialogContent>\n </DialogPortal>\n</template>\n"
},
{
"name": "DialogDescription.vue",
"content": "<script setup lang=\"ts\">\nimport { DialogDescription, type DialogDescriptionProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DialogDescriptionProps & { class?: string }>()\n</script>\n\n<template>\n <DialogDescription\n v-bind=\"props\"\n :class=\"cn('text-muted-foreground text-sm', props.class)\"\n >\n <slot />\n </DialogDescription>\n</template>\n"
},
{
"name": "DialogFooter.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\ninterface DialogFooterProps {\n class?: string\n}\n\nconst props = defineProps<DialogFooterProps>()\n</script>\n\n<template>\n <div\n :class=\"\n cn(\n 'flex flex-col space-y-2 sm:space-y-0 mt-1.5 sm:flex-row sm:justify-end sm:space-x-2',\n props.class,\n )\n \"\n >\n <slot />\n </div>\n</template>\n"
},
{
"name": "DialogHeader.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\ninterface DialogHeaderProps {\n class?: string\n}\n\nconst props = defineProps<DialogHeaderProps>()\n</script>\n\n<template>\n <div\n :class=\"cn('flex flex-col space-y-2 text-center sm:text-left', props.class)\"\n >\n <slot />\n </div>\n</template>\n"
},
{
"name": "DialogTitle.vue",
"content": "<script setup lang=\"ts\">\nimport { DialogTitle, type DialogTitleProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DialogTitleProps & { class?: string }>()\n</script>\n\n<template>\n <DialogTitle\n v-bind=\"props\"\n :class=\"\n cn(\n 'text-lg text-foreground font-semibold leading-none tracking-tight',\n props.class,\n )\n \"\n >\n <slot />\n </DialogTitle>\n</template>\n"
},
{
"name": "DialogTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { DialogTrigger, type DialogTriggerProps } from 'radix-vue'\n\nconst props = defineProps<DialogTriggerProps>()\n</script>\n\n<template>\n <DialogTrigger v-bind=\"props\">\n <slot />\n </DialogTrigger>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Dialog } from './Dialog.vue'\nexport { default as DialogTrigger } from './DialogTrigger.vue'\nexport { default as DialogHeader } from './DialogHeader.vue'\nexport { default as DialogTitle } from './DialogTitle.vue'\nexport { default as DialogDescription } from './DialogDescription.vue'\nexport { default as DialogContent } from './DialogContent.vue'\nexport { default as DialogFooter } from './DialogFooter.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,72 @@
{
"name": "dropdown-menu",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "DropdownMenu.vue",
"content": "<script setup lang=\"ts\">\nimport { DropdownMenuRoot, type DropdownMenuRootEmits, type DropdownMenuRootProps } from 'radix-vue'\nimport { useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<DropdownMenuRootProps>()\nconst emits = defineEmits<DropdownMenuRootEmits>()\n</script>\n\n<template>\n <DropdownMenuRoot v-bind=\"{ ...props, ...useEmitAsProps(emits) }\">\n <slot />\n </DropdownMenuRoot>\n</template>\n"
},
{
"name": "DropdownMenuCheckboxItem.vue",
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenuCheckboxItem,\n type DropdownMenuCheckboxItemEmits,\n type DropdownMenuCheckboxItemProps,\n DropdownMenuItemIndicator,\n} from 'radix-vue'\nimport { Check } from 'lucide-vue-next'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<DropdownMenuCheckboxItemProps & { class?: string }>()\nconst emits = defineEmits<DropdownMenuCheckboxItemEmits>()\n</script>\n\n<template>\n <DropdownMenuCheckboxItem\n v-bind=\"{ ...props, ...useEmitAsProps(emits) }\"\n :class=\" cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuItemIndicator>\n <Check class=\"w-4 h-4\" />\n </DropdownMenuItemIndicator>\n </span>\n <slot />\n </DropdownMenuCheckboxItem>\n</template>\n"
},
{
"name": "DropdownMenuContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenuContent,\n type DropdownMenuContentProps,\n DropdownMenuPortal,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(\n defineProps<DropdownMenuContentProps & { class?: string }>(),\n {\n sideOffset: 4,\n },\n)\n</script>\n\n<template>\n <DropdownMenuPortal>\n <DropdownMenuContent\n :loop=\"props.loop\"\n :as-child=\"props.asChild\"\n :side-offset=\"props.sideOffset\"\n :side=\"props.side\"\n :align=\"props.align\"\n :align-offset=\"props.alignOffset\"\n :class=\"[\n cn(\n 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n ),\n ]\"\n >\n <slot />\n </DropdownMenuContent>\n </DropdownMenuPortal>\n</template>\n"
},
{
"name": "DropdownMenuGroup.vue",
"content": "<script setup lang=\"ts\">\nimport { DropdownMenuGroup, type DropdownMenuGroupProps } from 'radix-vue'\n\nconst props = defineProps<DropdownMenuGroupProps>()\n</script>\n\n<template>\n <DropdownMenuGroup v-bind=\"props\">\n <slot />\n </DropdownMenuGroup>\n</template>\n"
},
{
"name": "DropdownMenuItem.vue",
"content": "<script setup lang=\"ts\">\nimport { DropdownMenuItem, type DropdownMenuItemProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DropdownMenuItemProps & { inset?: boolean; class?: string }>()\n</script>\n\n<template>\n <DropdownMenuItem\n v-bind=\"props\"\n :class=\"[\n cn(\n 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && 'pl-8',\n props.class,\n ),\n ]\"\n >\n <slot />\n </DropdownMenuItem>\n</template>\n"
},
{
"name": "DropdownMenuLabel.vue",
"content": "<script setup lang=\"ts\">\nimport { DropdownMenuLabel, type DropdownMenuLabelProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DropdownMenuLabelProps & {\n inset?: boolean\n class?: string\n}>()\n</script>\n\n<template>\n <DropdownMenuLabel\n v-bind=\"props\"\n :class=\"\n cn('px-2 py-1.5 text-sm font-semibold',\n inset && 'pl-8', props.class)\"\n >\n <slot />\n </DropdownMenuLabel>\n</template>\n"
},
{
"name": "DropdownMenuRadioGroup.vue",
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenuRadioGroup,\n type DropdownMenuRadioGroupEmits,\n type DropdownMenuRadioGroupProps,\n} from 'radix-vue'\n\nconst props = defineProps<DropdownMenuRadioGroupProps>()\n\nconst emits = defineEmits<DropdownMenuRadioGroupEmits>()\n</script>\n\n<template>\n <DropdownMenuRadioGroup\n v-bind=\"props\"\n @update:model-value=\"emits('update:modelValue', $event)\"\n >\n <slot />\n </DropdownMenuRadioGroup>\n</template>\n"
},
{
"name": "DropdownMenuRadioItem.vue",
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenuItemIndicator,\n DropdownMenuRadioItem,\n type DropdownMenuRadioItemEmits,\n type DropdownMenuRadioItemProps,\n} from 'radix-vue'\nimport { Circle } from 'lucide-vue-next'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<DropdownMenuRadioItemProps & { class?: string }>()\n\nconst emits = defineEmits<DropdownMenuRadioItemEmits>()\n</script>\n\n<template>\n <DropdownMenuRadioItem\n v-bind=\"{ ...props, ...useEmitAsProps(emits) }\"\n :class=\"cn(\n 'flex relative items-center rounded-md transition-colors data-[disabled]:opacity-50 data-[disabled]:pointer-events-none data-[highlighted]:bg-outline-hover pl-7 py-1.5 text-sm outline-none select-none cursor-default',\n props.class,\n )\"\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n\n <DropdownMenuItemIndicator>\n <Circle class=\"h-2 w-2 fill-current\" />\n </DropdownMenuItemIndicator>\n </span>\n <slot />\n </DropdownMenuRadioItem>\n</template>\n"
},
{
"name": "DropdownMenuSeparator.vue",
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenuSeparator,\n type DropdownMenuSeparatorProps,\n} from 'radix-vue'\n\nconst props = defineProps<DropdownMenuSeparatorProps>()\n</script>\n\n<template>\n <DropdownMenuSeparator v-bind=\"props\" class=\"-mx-1 my-1 h-px bg-muted\" />\n</template>\n"
},
{
"name": "DropdownMenuShortcut.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n</script>\n\n<template>\n <span :class=\"cn('ml-auto text-xs tracking-widest opacity-60', $attrs.class ?? '')\">\n <slot />\n </span>\n</template>\n"
},
{
"name": "DropdownMenuSub.vue",
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenuSub,\n type DropdownMenuSubEmits,\n type DropdownMenuSubProps,\n} from 'radix-vue'\n\nconst props = defineProps<DropdownMenuSubProps>()\n\nconst emits = defineEmits<DropdownMenuSubEmits>()\n</script>\n\n<template>\n <DropdownMenuSub v-bind=\"props\" @update:open=\"emits('update:open', $event)\">\n <slot />\n </DropdownMenuSub>\n</template>\n"
},
{
"name": "DropdownMenuSubContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenuSubContent,\n type DropdownMenuSubContentEmits,\n type DropdownMenuSubContentProps,\n} from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<DropdownMenuSubContentProps>()\nconst emits = defineEmits<DropdownMenuSubContentEmits>()\n</script>\n\n<template>\n <DropdownMenuSubContent\n v-bind=\"{ ...props, ...useEmitAsProps(emits) }\"\n :class=\"cn('z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', $attrs.class ?? '')\"\n >\n <slot />\n </DropdownMenuSubContent>\n</template>\n"
},
{
"name": "DropdownMenuSubTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenuSubTrigger,\n type DropdownMenuSubTriggerProps,\n} from 'radix-vue'\nimport { ChevronRight } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DropdownMenuSubTriggerProps & { class?: string }>()\n</script>\n\n<template>\n <DropdownMenuSubTrigger\n v-bind=\"props\"\n :class=\"[\n cn(\n 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent',\n props.class,\n ),\n ]\"\n >\n <slot />\n <ChevronRight class=\"ml-auto h-4 w-4\" />\n </DropdownMenuSubTrigger>\n</template>\n"
},
{
"name": "DropdownMenuTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { DropdownMenuTrigger, type DropdownMenuTriggerProps } from 'radix-vue'\n\nconst props = defineProps<DropdownMenuTriggerProps>()\n</script>\n\n<template>\n <DropdownMenuTrigger class=\"outline-none\" v-bind=\"props\">\n <slot />\n </DropdownMenuTrigger>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { DropdownMenuPortal } from 'radix-vue'\n\nexport { default as DropdownMenu } from './DropdownMenu.vue'\nexport { default as DropdownMenuTrigger } from './DropdownMenuTrigger.vue'\nexport { default as DropdownMenuContent } from './DropdownMenuContent.vue'\nexport { default as DropdownMenuGroup } from './DropdownMenuGroup.vue'\nexport { default as DropdownMenuRadioGroup } from './DropdownMenuRadioGroup.vue'\nexport { default as DropdownMenuItem } from './DropdownMenuItem.vue'\nexport { default as DropdownMenuCheckboxItem } from './DropdownMenuCheckboxItem.vue'\nexport { default as DropdownMenuRadioItem } from './DropdownMenuRadioItem.vue'\nexport { default as DropdownMenuShortcut } from './DropdownMenuShortcut.vue'\nexport { default as DropdownMenuSeparator } from './DropdownMenuSeparator.vue'\nexport { default as DropdownMenuLabel } from './DropdownMenuLabel.vue'\nexport { default as DropdownMenuSub } from './DropdownMenuSub.vue'\nexport { default as DropdownMenuSubTrigger } from './DropdownMenuSubTrigger.vue'\nexport { default as DropdownMenuSubContent } from './DropdownMenuSubContent.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,28 @@
{
"name": "hover-card",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "HoverCard.vue",
"content": "<script setup lang=\"ts\">\nimport { HoverCardRoot, type HoverCardRootProps } from 'radix-vue'\n\nconst props = defineProps<HoverCardRootProps>()\n</script>\n\n<template>\n <HoverCardRoot v-bind=\"props\">\n <slot />\n </HoverCardRoot>\n</template>\n"
},
{
"name": "HoverCardContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n HoverCardContent,\n type HoverCardContentProps,\n HoverCardPortal,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(\n defineProps<HoverCardContentProps & { class?: string }>(),\n {\n sideOffset: 4,\n },\n)\n</script>\n\n<template>\n <HoverCardPortal>\n <HoverCardContent\n v-bind=\"props\"\n :class=\"\n cn(\n 'z-50 w-64 rounded-md bg-background border border-border p-4 text-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </HoverCardContent>\n </HoverCardPortal>\n</template>\n"
},
{
"name": "HoverCardTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { HoverCardTrigger, type HoverCardTriggerProps } from 'radix-vue'\n\nconst props = defineProps<HoverCardTriggerProps>()\n</script>\n\n<template>\n <HoverCardTrigger v-bind=\"props\">\n <slot />\n </HoverCardTrigger>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as HoverCard } from './HoverCard.vue'\nexport { default as HoverCardTrigger } from './HoverCardTrigger.vue'\nexport { default as HoverCardContent } from './HoverCardContent.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,18 @@
{
"name": "input",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Input.vue",
"content": "<script setup lang=\"ts\">\nimport { useVModel } from '@vueuse/core'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n defaultValue?: string | number\n modelValue?: string | number\n}>()\n\nconst emits = defineEmits<{\n (e: 'update:modelValue', payload: string | number): void\n}>()\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n passive: true,\n defaultValue: props.defaultValue,\n})\n</script>\n\n<template>\n <input v-model=\"modelValue\" type=\"text\" :class=\"cn(cn('flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', $attrs.class ?? ''))\">\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Input } from './Input.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,16 @@
{
"name": "kbd",
"dependencies": [],
"registryDependencies": [],
"files": [
{
"name": "Kbd.vue",
"content": "<script setup lang=\"ts\">\nimport { cva } from 'class-variance-authority'\nimport { computed } from 'vue'\n\ninterface KbdProps {\n as?: string\n size?: 'xs' | 'sm' | 'md'\n}\n\nconst props = withDefaults(defineProps<KbdProps>(), {\n as: 'kbd',\n size: 'sm',\n})\n\nconst kbdClass = computed(() => {\n return cva(\n 'inline-flex items-center font-sans justify-center text-foreground rounded font-semibold bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700',\n {\n variants: {\n size: {\n xs: 'min-h-[16px] text-[10px] h-4 px-1',\n sm: 'min-h-[20px] text-[11px] h-5 px-1',\n md: 'min-h-[24px] text-[12px] h-6 px-1.5',\n },\n },\n },\n )({\n size: props.size,\n })\n})\n</script>\n\n<template>\n <component :is=\"props.as\" :class=\"kbdClass\">\n <slot />\n </component>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Kbd } from './Kbd.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,20 @@
{
"name": "label",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Label.vue",
"content": "<script setup lang=\"ts\">\nimport { Label, type LabelProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<LabelProps & { class?: string }>()\n</script>\n\n<template>\n <Label\n v-bind=\"props\"\n :class=\"\n cn(\n 'block text-sm tracking-tight font-medium text-foreground text-left',\n props.class,\n )\n \"\n >\n <slot />\n </Label>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Label } from './Label.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,76 @@
{
"name": "menubar",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Menubar.vue",
"content": "<script setup lang=\"ts\">\nimport {\n MenubarRoot,\n type MenubarRootEmits,\n type MenubarRootProps,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<MenubarRootProps & { class?: string }>()\n\nconst emits = defineEmits<MenubarRootEmits>()\n</script>\n\n<template>\n <MenubarRoot\n v-bind=\"props\"\n :class=\"\n cn(\n 'flex h-10 items-center space-x-1 rounded-md border border-border p-1',\n props.class,\n )\n \"\n @update:model-value=\"emits('update:modelValue', $event)\"\n >\n <slot />\n </MenubarRoot>\n</template>\n"
},
{
"name": "MenubarCheckboxItem.vue",
"content": "<script setup lang=\"ts\">\nimport {\n MenubarCheckboxItem,\n type MenubarCheckboxItemEmits,\n type MenubarCheckboxItemProps,\n MenubarItemIndicator,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\nimport RadixIconsCheck from '~icons/radix-icons/check'\n\nconst props = defineProps<MenubarCheckboxItemProps & { class?: string }>()\n\nconst emit = defineEmits<MenubarCheckboxItemEmits>()\n</script>\n\n<template>\n <MenubarCheckboxItem\n v-bind=\"props\"\n :class=\"[\n cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n ),\n ]\"\n @update:checked=\"emit('update:checked', $event)\"\n @select=\"emit('select', $event)\"\n >\n <MenubarItemIndicator\n class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\"\n >\n <RadixIconsCheck class=\"w-4 h-4\" />\n </MenubarItemIndicator>\n <slot />\n </MenubarCheckboxItem>\n</template>\n"
},
{
"name": "MenubarContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n MenubarContent,\n type MenubarContentProps,\n MenubarPortal,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(\n defineProps<MenubarContentProps & { class?: string }>(),\n {\n align: 'start',\n alignOffset: -4,\n sideOffset: 8,\n },\n)\n</script>\n\n<template>\n <MenubarPortal>\n <MenubarContent\n :loop=\"props.loop\"\n :as-child=\"props.asChild\"\n :side-offset=\"props.sideOffset\"\n :side=\"props.side\"\n :align=\"props.align\"\n :align-offset=\"props.alignOffset\"\n :class=\"\n cn(\n 'z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </MenubarContent>\n </MenubarPortal>\n</template>\n"
},
{
"name": "MenubarGroup.vue",
"content": "<script setup lang=\"ts\">\nimport { MenubarGroup, type MenubarGroupProps } from 'radix-vue'\n\nconst props = defineProps<MenubarGroupProps>()\n</script>\n\n<template>\n <MenubarGroup v-bind=\"props\">\n <slot />\n </MenubarGroup>\n</template>\n"
},
{
"name": "MenubarItem.vue",
"content": "<script setup lang=\"ts\">\nimport {\n MenubarItem,\n type MenubarItemEmits,\n type MenubarItemProps,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<MenubarItemProps & { inset?: boolean; class?: string }>()\n\nconst emits = defineEmits<MenubarItemEmits>()\n</script>\n\n<template>\n <MenubarItem\n v-bind=\"props\"\n :class=\"[\n cn(\n 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && 'pl-8',\n props.class,\n ),\n ]\"\n @select=\"emits('select', $event)\"\n >\n <slot />\n </MenubarItem>\n</template>\n"
},
{
"name": "MenubarLabel.vue",
"content": "<script setup lang=\"ts\">\nimport { MenubarLabel, type MenubarLabelProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<MenubarLabelProps & { inset?: boolean; class?: string }>()\n</script>\n\n<template>\n <MenubarLabel :class=\"cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', props.class)\">\n <slot />\n </MenubarLabel>\n</template>\n"
},
{
"name": "MenubarMenu.vue",
"content": "<script setup lang=\"ts\">\nimport { MenubarMenu, type MenubarMenuProps } from 'radix-vue'\n\nconst props = defineProps<MenubarMenuProps>()\n</script>\n\n<template>\n <MenubarMenu v-bind=\"props\">\n <slot />\n </MenubarMenu>\n</template>\n"
},
{
"name": "MenubarRadioGroup.vue",
"content": "<script setup lang=\"ts\">\nimport {\n MenubarRadioGroup,\n type MenubarRadioGroupEmits,\n type MenubarRadioGroupProps,\n} from 'radix-vue'\n\nconst props = defineProps<MenubarRadioGroupProps>()\n\nconst emits = defineEmits<MenubarRadioGroupEmits>()\n</script>\n\n<template>\n <MenubarRadioGroup\n v-bind=\"props\"\n @update:model-value=\"emits('update:modelValue', $event)\"\n >\n <slot />\n </MenubarRadioGroup>\n</template>\n"
},
{
"name": "MenubarRadioItem.vue",
"content": "<script setup lang=\"ts\">\nimport {\n MenubarItemIndicator,\n MenubarRadioItem,\n type MenubarRadioItemEmits,\n type MenubarRadioItemProps,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\nimport RiCheckboxBlankCircleFill from '~icons/ri/checkbox-blank-circle-fill'\n\nconst props = defineProps<MenubarRadioItemProps & { class?: string }>()\n\nconst emits = defineEmits<MenubarRadioItemEmits>()\n</script>\n\n<template>\n <MenubarRadioItem\n v-bind=\"props\"\n :class=\"[\n cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n ),\n ]\"\n @select=\"emits('select', $event)\"\n >\n <MenubarItemIndicator\n class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\"\n >\n <RiCheckboxBlankCircleFill class=\"h-2 w-2 fill-curren\" />\n </MenubarItemIndicator>\n\n <slot />\n </MenubarRadioItem>\n</template>\n"
},
{
"name": "MenubarSeparator.vue",
"content": "<script setup lang=\"ts\">\nimport { MenubarSeparator, type MenubarSeparatorProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<MenubarSeparatorProps>()\n</script>\n\n<template>\n <MenubarSeparator :class=\" cn('-mx-1 my-1 h-px bg-secondary', $attrs.class ?? '')\" v-bind=\"props\" />\n</template>\n"
},
{
"name": "MenubarShortcut.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n</script>\n\n<template>\n <span :class=\"cn('text-xxs ml-auto tracking-widest opacity-50', $attrs.class ?? '')\">\n <slot />\n </span>\n</template>\n"
},
{
"name": "MenubarSub.vue",
"content": "<script setup lang=\"ts\">\nimport {\n MenubarSub,\n type MenubarSubEmits,\n} from 'radix-vue'\n\ninterface MenubarSubRootProps {\n defaultOpen?: boolean\n open?: boolean\n}\n\nconst props = defineProps<MenubarSubRootProps>()\n\nconst emits = defineEmits<MenubarSubEmits>()\n</script>\n\n<template>\n <MenubarSub v-bind=\"props\" @update:open=\"emits('update:open', $event)\">\n <slot />\n </MenubarSub>\n</template>\n"
},
{
"name": "MenubarSubContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n MenubarPortal,\n MenubarSubContent,\n type MenubarSubContentEmits,\n type MenubarSubContentProps,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(\n defineProps<MenubarSubContentProps & { class?: string }>(),\n {\n sideOffset: 2,\n alignOffset: 0,\n },\n)\n\nconst emits = defineEmits<MenubarSubContentEmits>()\n</script>\n\n<template>\n <MenubarPortal>\n <MenubarSubContent\n :loop=\"props.loop\"\n :as-child=\"props.asChild\"\n :side-offset=\"props.sideOffset\"\n :side=\"props.side\"\n :align=\"props.align\"\n :align-offset=\"props.alignOffset\"\n :class=\"\n cn(\n 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </MenubarSubContent>\n </MenubarPortal>\n</template>\n"
},
{
"name": "MenubarSubTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { MenubarSubTrigger, type MenubarSubTriggerProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<MenubarSubTriggerProps & { inset?: boolean; class?: string }>()\n</script>\n\n<template>\n <MenubarSubTrigger\n v-bind=\"props\"\n :class=\"[\n cn(\n 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',\n inset && 'pl-8',\n props.class,\n ),\n ]\"\n >\n <slot />\n </MenubarSubTrigger>\n</template>\n"
},
{
"name": "MenubarTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { MenubarTrigger, type MenubarTriggerProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<MenubarTriggerProps & { class?: string }>()\n</script>\n\n<template>\n <MenubarTrigger\n v-bind=\"props\"\n :class=\"\n cn(\n 'flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',\n props.class,\n )\n \"\n >\n <slot />\n </MenubarTrigger>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Menubar } from './Menubar.vue'\nexport { default as MenubarItem } from './MenubarItem.vue'\nexport { default as MenubarContent } from './MenubarContent.vue'\nexport { default as MenubarGroup } from './MenubarGroup.vue'\nexport { default as MenubarMenu } from './MenubarMenu.vue'\nexport { default as MenubarRadioGroup } from './MenubarRadioGroup.vue'\nexport { default as MenubarRadioItem } from './MenubarRadioItem.vue'\nexport { default as MenubarCheckboxItem } from './MenubarCheckboxItem.vue'\nexport { default as MenubarSeparator } from './MenubarSeparator.vue'\nexport { default as MenubarSub } from './MenubarSub.vue'\nexport { default as MenubarSubContent } from './MenubarSubContent.vue'\nexport { default as MenubarSubTrigger } from './MenubarSubTrigger.vue'\nexport { default as MenubarTrigger } from './MenubarTrigger.vue'\nexport { default as MenubarShortcut } from './MenubarShortcut.vue'\nexport { default as MenubarLabel } from './MenubarLabel.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,48 @@
{
"name": "navigation-menu",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "NavigationMenu.vue",
"content": "<script setup lang=\"ts\">\nimport {\n NavigationMenuRoot,\n type NavigationMenuRootEmits,\n type NavigationMenuRootProps,\n} from 'radix-vue'\nimport NavigationMenuViewport from './NavigationMenuViewport.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<NavigationMenuRootProps & { class?: string }>()\n\nconst emits = defineEmits<NavigationMenuRootEmits>()\n</script>\n\n<template>\n <NavigationMenuRoot\n v-bind=\"props\"\n :class=\"cn('relative z-10 flex max-w-max flex-1 items-center justify-center', props.class)\"\n @update:model-value=\"emits('update:modelValue', $event)\"\n >\n <slot />\n <NavigationMenuViewport />\n </NavigationMenuRoot>\n</template>\n"
},
{
"name": "NavigationMenuContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n NavigationMenuContent,\n type NavigationMenuContentEmits,\n type NavigationMenuContentProps,\n} from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<NavigationMenuContentProps & { class?: string }>()\n\nconst emits = defineEmits<NavigationMenuContentEmits>()\n</script>\n\n<template>\n <NavigationMenuContent\n v-bind=\"{ ...props, ...useEmitAsProps(emits) }\"\n :class=\"\n cn(\n 'left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto ',\n props.class,\n )\n \"\n >\n <slot />\n </NavigationMenuContent>\n</template>\n"
},
{
"name": "NavigationMenuIndicator.vue",
"content": "<script setup lang=\"ts\">\nimport { NavigationMenuIndicator, type NavigationMenuIndicatorProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<NavigationMenuIndicatorProps>()\n</script>\n\n<template>\n <NavigationMenuIndicator\n v-bind=\"props\"\n :class=\"cn('top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in', $attrs.class ?? '')\"\n >\n <div class=\"relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md\" />\n </NavigationMenuIndicator>\n</template>\n"
},
{
"name": "NavigationMenuItem.vue",
"content": "<script setup lang=\"ts\">\nimport { NavigationMenuItem, type NavigationMenuItemProps } from 'radix-vue'\n\nconst props = defineProps<NavigationMenuItemProps>()\n</script>\n\n<template>\n <NavigationMenuItem v-bind=\"props\">\n <slot />\n </NavigationMenuItem>\n</template>\n"
},
{
"name": "NavigationMenuLink.vue",
"content": "<script setup lang=\"ts\">\nimport {\n NavigationMenuLink,\n type NavigationMenuLinkEmits,\n type NavigationMenuLinkProps,\n} from 'radix-vue'\nimport { useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<NavigationMenuLinkProps>()\nconst emits = defineEmits<NavigationMenuLinkEmits>()\n</script>\n\n<template>\n <NavigationMenuLink v-bind=\"{ ...props, ...useEmitAsProps(emits) }\">\n <slot />\n </NavigationMenuLink>\n</template>\n"
},
{
"name": "NavigationMenuList.vue",
"content": "<script setup lang=\"ts\">\nimport { NavigationMenuList, type NavigationMenuListProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<NavigationMenuListProps & { class?: string }>()\n</script>\n\n<template>\n <NavigationMenuList\n v-bind=\"props\"\n :class=\"\n cn(\n 'group flex flex-1 list-none items-center justify-center space-x-1',\n props.class,\n )\n \"\n >\n <slot />\n </NavigationMenuList>\n</template>\n"
},
{
"name": "NavigationMenuTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport {\n NavigationMenuTrigger,\n type NavigationMenuTriggerProps,\n} from 'radix-vue'\nimport { ChevronDown } from 'lucide-vue-next'\nimport { navigationMenuTriggerStyle } from '.'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<NavigationMenuTriggerProps & { class?: string }>()\n</script>\n\n<template>\n <NavigationMenuTrigger\n :class=\"cn(navigationMenuTriggerStyle(), 'group', props.class)\"\n v-bind=\"props\"\n >\n <slot />\n <ChevronDown\n class=\"relative top-[1px] ml-1 h-3 w-3 transition duration-200 group-data-[state=open]:rotate-180\"\n aria-hidden=\"true\"\n />\n </NavigationMenuTrigger>\n</template>\n"
},
{
"name": "NavigationMenuViewport.vue",
"content": "<script setup lang=\"ts\">\nimport {\n NavigationMenuViewport,\n type NavigationMenuViewportProps,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<NavigationMenuViewportProps>()\n</script>\n\n<template>\n <div class=\"absolute left-0 top-full flex justify-center\">\n <NavigationMenuViewport\n v-bind=\"props\"\n :class=\"\n cn(\n 'origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]',\n $attrs.class ?? '',\n )\n \"\n />\n </div>\n</template>\n"
},
{
"name": "index.ts",
"content": "import { cva } from 'class-variance-authority'\n\nexport { default as NavigationMenu } from './NavigationMenu.vue'\nexport { default as NavigationMenuList } from './NavigationMenuList.vue'\nexport { default as NavigationMenuItem } from './NavigationMenuItem.vue'\nexport { default as NavigationMenuTrigger } from './NavigationMenuTrigger.vue'\nexport { default as NavigationMenuContent } from './NavigationMenuContent.vue'\nexport { default as NavigationMenuLink } from './NavigationMenuLink.vue'\n\nexport const navigationMenuTriggerStyle = cva(\n 'group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50',\n)\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,28 @@
{
"name": "popover",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Popover.vue",
"content": "<script setup lang=\"ts\">\nimport { PopoverRoot, type PopoverRootProps } from 'radix-vue'\n\nconst props = defineProps<PopoverRootProps>()\n</script>\n\n<template>\n <PopoverRoot v-bind=\"props\">\n <slot />\n </PopoverRoot>\n</template>\n"
},
{
"name": "PopoverContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n PopoverContent,\n type PopoverContentEmits,\n type PopoverContentProps,\n PopoverPortal,\n} from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = withDefaults(\n defineProps<PopoverContentProps & { class?: string }>(),\n {\n sideOffset: 4,\n },\n)\nconst emits = defineEmits<PopoverContentEmits>()\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <PopoverPortal>\n <PopoverContent\n v-bind=\"{ ...props, ...emitsAsProps, $attrs }\"\n :class=\"\n cn(\n 'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </PopoverContent>\n </PopoverPortal>\n</template>\n"
},
{
"name": "PopoverTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { PopoverTrigger, type PopoverTriggerProps } from 'radix-vue'\n\nconst props = defineProps<PopoverTriggerProps>()\n</script>\n\n<template>\n <PopoverTrigger v-bind=\"props\">\n <slot />\n </PopoverTrigger>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Popover } from './Popover.vue'\nexport { default as PopoverTrigger } from './PopoverTrigger.vue'\nexport { default as PopoverContent } from './PopoverContent.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,20 @@
{
"name": "progress",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Progress.vue",
"content": "<script setup lang=\"ts\">\nimport {\n ProgressIndicator,\n ProgressRoot,\n type ProgressRootProps,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(\n defineProps<ProgressRootProps & { class?: string }>(),\n {\n class: '',\n modelValue: 0,\n },\n)\n</script>\n\n<template>\n <ProgressRoot\n :class=\"\n cn(\n 'relative h-4 w-full overflow-hidden rounded-full bg-secondary',\n props.class,\n )\n \"\n v-bind=\"props\"\n >\n <ProgressIndicator\n :class=\"\n cn(\n 'h-full w-full flex-1 duration-300 bg-foreground transition-all',\n props.class,\n )\n \"\n :style=\"`transform: translateX(-${100 - (props.modelValue ?? 0)}%);`\"\n />\n </ProgressRoot>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Progress } from './Progress.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,24 @@
{
"name": "radio-group",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "RadioGroup.vue",
"content": "<script setup lang=\"ts\">\nimport { RadioGroupRoot, type RadioGroupRootProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<RadioGroupRootProps & { class?: string }>()\n</script>\n\n<template>\n <RadioGroupRoot :class=\"cn('grid gap-2', props.class)\">\n <slot />\n </RadioGroupRoot>\n</template>\n"
},
{
"name": "RadioGroupItem.vue",
"content": "<script setup lang=\"ts\">\nimport {\n RadioGroupIndicator,\n RadioGroupItem,\n type RadioGroupItemProps,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\nimport RiCheckboxBlankCircleFill from '~icons/ri/checkbox-blank-circle-fill'\n\nconst props = defineProps<RadioGroupItemProps & { class?: string }>()\n</script>\n\n<template>\n <RadioGroupItem\n v-bind=\"props\"\n :class=\"\n cn(\n 'aspect-square h-4 w-4 rounded-full cursor-pointer flex justify-center items-center border border-primary disabled:cursor-not-allowed disabled:opacity-50',\n props.class,\n )\n \"\n >\n <RadioGroupIndicator\n :class=\"cn('flex items-center justify-center', props.class)\"\n >\n <RiCheckboxBlankCircleFill class=\"w-2.5 h-2.5 text-foreground\" />\n </RadioGroupIndicator>\n </RadioGroupItem>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as RadioGroup } from './RadioGroup.vue'\nexport { default as RadioGroupItem } from './RadioGroupItem.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,24 @@
{
"name": "scroll-area",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "ScrollArea.vue",
"content": "<script setup lang=\"ts\">\nimport {\n ScrollAreaCorner,\n ScrollAreaRoot,\n type ScrollAreaRootProps,\n ScrollAreaViewport,\n} from 'radix-vue'\nimport ScrollBar from './ScrollBar.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(\n defineProps<\n ScrollAreaRootProps & { class?: string }\n >(),\n {\n class: '',\n orientation: 'vertical',\n },\n)\n</script>\n\n<template>\n <ScrollAreaRoot :type=\"type\" :class=\"cn('relative overflow-hidden', props.class)\">\n <ScrollAreaViewport class=\"h-full w-full rounded-[inherit]\">\n <slot />\n </ScrollAreaViewport>\n <ScrollBar />\n <ScrollAreaCorner />\n </ScrollAreaRoot>\n</template>\n"
},
{
"name": "ScrollBar.vue",
"content": "<script setup lang=\"ts\">\nimport { ScrollAreaScrollbar, type ScrollAreaScrollbarProps, ScrollAreaThumb } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(defineProps<ScrollAreaScrollbarProps>(), {\n orientation: 'vertical',\n})\n</script>\n\n<template>\n <ScrollAreaScrollbar\n v-bind=\"props\"\n :class=\"\n cn('flex touch-none select-none transition-colors',\n orientation === 'vertical'\n && 'h-full w-2.5 border-l border-l-transparent p-[1px]',\n orientation === 'horizontal'\n && 'h-2.5 border-t border-t-transparent p-[1px]',\n $attrs.class ?? '')\"\n >\n <ScrollAreaThumb class=\"relative flex-1 rounded-full bg-border\" />\n </ScrollAreaScrollbar>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as ScrollArea } from './ScrollArea.vue'\nexport { default as ScrollBar } from './ScrollBar.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,52 @@
{
"name": "select",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Select.vue",
"content": "<script setup lang=\"ts\">\nimport type { SelectRootEmits, SelectRootProps } from 'radix-vue'\nimport { SelectRoot } from 'radix-vue'\nimport { useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<SelectRootProps>()\nconst emits = defineEmits<SelectRootEmits>()\n</script>\n\n<template>\n <SelectRoot v-bind=\"{ ...props, ...useEmitAsProps(emits) }\">\n <slot />\n </SelectRoot>\n</template>\n"
},
{
"name": "SelectContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n SelectContent,\n type SelectContentEmits,\n type SelectContentProps,\n SelectPortal,\n SelectViewport,\n} from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = withDefaults(\n defineProps<SelectContentProps & { class?: string }>(), {\n position: 'popper',\n sideOffset: 4,\n },\n)\nconst emits = defineEmits<SelectContentEmits>()\nconst emitsAsProps = useEmitAsProps(emits)\n</script>\n\n<template>\n <SelectPortal>\n <SelectContent\n v-bind=\"{ ...props, ...emitsAsProps, ...$attrs }\"\n :class=\"\n cn(\n 'relative z-50 min-w-[10rem] overflow-hidden rounded-md bg-background border border-border text-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n position === 'popper'\n && 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',\n props.class,\n )\n \"\n >\n <SelectViewport\n :class=\"\n cn('p-1',\n position === 'popper'\n && 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]')\"\n >\n <slot />\n </SelectViewport>\n </SelectContent>\n </SelectPortal>\n</template>\n"
},
{
"name": "SelectGroup.vue",
"content": "<script setup lang=\"ts\">\nimport { SelectGroup, type SelectGroupProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SelectGroupProps & { class?: string }>()\n</script>\n\n<template>\n <SelectGroup :class=\"cn('p-1 w-full', props.class)\" v-bind=\"props\">\n <slot />\n </SelectGroup>\n</template>\n"
},
{
"name": "SelectItem.vue",
"content": "<script setup lang=\"ts\">\nimport {\n SelectItem,\n SelectItemIndicator,\n type SelectItemProps,\n SelectItemText,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\nimport RadixIconsCheck from '~icons/radix-icons/check'\n\nconst props = defineProps<SelectItemProps & { class?: string }>()\n</script>\n\n<template>\n <SelectItem\n v-bind=\"props\"\n :class=\"\n cn(\n 'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\n \"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectItemIndicator>\n <RadixIconsCheck class=\"h-4 w-4\" />\n </SelectItemIndicator>\n </span>\n\n <SelectItemText>\n <slot />\n </SelectItemText>\n </SelectItem>\n</template>\n"
},
{
"name": "SelectItemText.vue",
"content": "<script setup lang=\"ts\">\nimport { SelectItemText, type SelectItemTextProps } from 'radix-vue'\n\nconst props = defineProps<SelectItemTextProps>()\n</script>\n\n<template>\n <SelectItemText v-bind=\"props\">\n <slot />\n </SelectItemText>\n</template>\n"
},
{
"name": "SelectLabel.vue",
"content": "<script setup lang=\"ts\">\nimport { SelectLabel, type SelectLabelProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SelectLabelProps & { class?: string }>()\n</script>\n\n<template>\n <SelectLabel :class=\"cn('py-1.5 pl-8 pr-2 text-sm font-semibold', props.class)\">\n <slot />\n </SelectLabel>\n</template>\n"
},
{
"name": "SelectSeparator.vue",
"content": "<script setup lang=\"ts\">\nimport { SelectSeparator, type SelectSeparatorProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SelectSeparatorProps & { class?: string }>()\n</script>\n\n<template>\n <SelectSeparator :class=\"cn('-mx-1 my-1 h-px bg-muted', props.class)\" />\n</template>\n"
},
{
"name": "SelectTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { SelectIcon, SelectTrigger, type SelectTriggerProps } from 'radix-vue'\nimport { ChevronDown } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(\n defineProps<SelectTriggerProps & { class?: string; invalid?: boolean }>(),\n {\n class: '',\n invalid: false,\n },\n)\n</script>\n\n<template>\n <SelectTrigger\n v-bind=\"props\"\n :class=\"[\n cn(\n 'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n props.class,\n ),\n props.invalid\n ? '!ring-destructive ring-2 placeholder:!text-destructive'\n : '',\n ]\"\n >\n <slot />\n <SelectIcon as-child>\n <ChevronDown class=\"w-4 h-4 opacity-50\" />\n </SelectIcon>\n </SelectTrigger>\n</template>\n"
},
{
"name": "SelectValue.vue",
"content": "<script setup lang=\"ts\">\nimport { SelectValue, type SelectValueProps } from 'radix-vue'\n\nconst props = defineProps<SelectValueProps>()\n</script>\n\n<template>\n <SelectValue v-bind=\"props\">\n <slot />\n </SelectValue>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Select } from './Select.vue'\nexport { default as SelectValue } from './SelectValue.vue'\nexport { default as SelectTrigger } from './SelectTrigger.vue'\nexport { default as SelectContent } from './SelectContent.vue'\nexport { default as SelectGroup } from './SelectGroup.vue'\nexport { default as SelectItem } from './SelectItem.vue'\nexport { default as SelectItemText } from './SelectItemText.vue'\nexport { default as SelectLabel } from './SelectLabel.vue'\nexport { default as SelectSeparator } from './SelectSeparator.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,20 @@
{
"name": "separator",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Separator.vue",
"content": "<script setup lang=\"ts\">\nimport { Separator, type SeparatorProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SeparatorProps & { class?: string }>()\n</script>\n\n<template>\n <Separator\n :class=\"[\n cn('shrink-0 bg-secondary', props.class),\n props.orientation === 'vertical' ? 'w-px h-full' : 'h-px w-full',\n ]\"\n />\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Separator } from './Separator.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,48 @@
{
"name": "sheet",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Sheet.vue",
"content": "<script setup lang=\"ts\">\nimport { DialogRoot } from 'radix-vue'\n</script>\n\n<template>\n <DialogRoot>\n <slot />\n </DialogRoot>\n</template>\n"
},
{
"name": "SheetClose.vue",
"content": "<script setup lang=\"ts\">\nimport { DialogClose, type DialogCloseProps } from 'radix-vue'\n\nconst props = defineProps<DialogCloseProps>()\n</script>\n\n<template>\n <DialogClose v-bind=\"props\">\n <slot />\n </DialogClose>\n</template>\n"
},
{
"name": "SheetContent.vue",
"content": "<script setup lang=\"ts\">\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n} from 'radix-vue'\nimport { X } from 'lucide-vue-next'\nimport { cva } from 'class-variance-authority'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\ninterface SheetContentProps extends DialogContentProps {\n side?: 'left' | 'right' | 'top' | 'bottom'\n class?: string\n}\n\nconst props = defineProps<SheetContentProps>()\n\nconst emits = defineEmits<DialogContentEmits>()\n\nconst emitsAsProps = useEmitAsProps(emits)\n\nconst sheetVariants = cva(\n 'fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500',\n {\n variants: {\n side: {\n top: 'inset-x-0 top-0 border-b border-border data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',\n bottom:\n 'inset-x-0 bottom-0 border-t border-border data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',\n left: 'inset-y-0 left-0 h-full w-3/4 border-r border-border data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm',\n right:\n 'inset-y-0 right-0 h-full w-3/4 border-l border-border data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm',\n },\n },\n defaultVariants: {\n side: 'right',\n },\n },\n)\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay\n class=\"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n />\n <DialogContent\n :class=\"cn(sheetVariants({ side: props.side }), props.class)\"\n v-bind=\"{ ...props, ...emitsAsProps }\"\n >\n <slot />\n\n <DialogClose\n class=\"absolute top-4 right-4 p-0.5 transition-colors rounded-md hover:bg-secondary\"\n >\n <X class=\"w-4 h-4 text-muted-foreground\" />\n </DialogClose>\n </DialogContent>\n </DialogPortal>\n</template>\n"
},
{
"name": "SheetDescription.vue",
"content": "<script setup lang=\"ts\">\nimport { DialogDescription, type DialogDescriptionProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DialogDescriptionProps & { class?: string }>()\n</script>\n\n<template>\n <DialogDescription\n :class=\"cn('text-sm text-muted-foreground', props.class)\"\n v-bind=\"props\"\n >\n <slot />\n </DialogDescription>\n</template>\n"
},
{
"name": "SheetFooter.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: string }>()\n</script>\n\n<template>\n <div\n :class=\"\n cn(\n 'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',\n props.class,\n )\n \"\n >\n <slot />\n </div>\n</template>\n"
},
{
"name": "SheetHeader.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: string }>()\n</script>\n\n<template>\n <div\n :class=\"\n cn('flex flex-col space-y-2 text-center sm:text-left', props.class)\n \"\n >\n <slot />\n </div>\n</template>\n"
},
{
"name": "SheetTitle.vue",
"content": "<script setup lang=\"ts\">\nimport { DialogTitle, type DialogTitleProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<DialogTitleProps & { class?: string }>()\n</script>\n\n<template>\n <DialogTitle\n :class=\"cn('text-lg font-semibold text-foreground', props.class)\"\n v-bind=\"props\"\n >\n <slot />\n </DialogTitle>\n</template>\n"
},
{
"name": "SheetTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { DialogTrigger, type DialogTriggerProps } from 'radix-vue'\n\nconst props = defineProps<DialogTriggerProps>()\n</script>\n\n<template>\n <DialogTrigger v-bind=\"props\">\n <slot />\n </DialogTrigger>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Sheet } from './Sheet.vue'\nexport { default as SheetTrigger } from './SheetTrigger.vue'\nexport { default as SheetClose } from './SheetClose.vue'\nexport { default as SheetContent } from './SheetContent.vue'\nexport { default as SheetHeader } from './SheetHeader.vue'\nexport { default as SheetTitle } from './SheetTitle.vue'\nexport { default as SheetDescription } from './SheetDescription.vue'\nexport { default as SheetFooter } from './SheetFooter.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,18 @@
{
"name": "skeleton",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Skeleton.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\ninterface SkeletonProps {\n class?: string\n}\n\nconst props = defineProps<SkeletonProps>()\n</script>\n\n<template>\n <div :class=\"cn('animate-pulse rounded-md bg-secondary', props.class)\" />\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Skeleton } from './Skeleton.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,20 @@
{
"name": "slider",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Slider.vue",
"content": "<script setup lang=\"ts\">\nimport type { SliderRootEmits, SliderRootProps } from 'radix-vue'\nimport { SliderRange, SliderRoot, SliderThumb, SliderTrack } from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<SliderRootProps>()\nconst emits = defineEmits<SliderRootEmits>()\n</script>\n\n<template>\n <SliderRoot\n :class=\"cn(\n 'relative flex w-full touch-none select-none items-center',\n $attrs.class ?? '',\n )\"\n v-bind=\"{ ...props, ...useEmitAsProps(emits) }\"\n >\n <SliderTrack class=\"relative h-2 w-full grow overflow-hidden rounded-full bg-secondary\">\n <SliderRange class=\"absolute h-full bg-primary\" />\n </SliderTrack>\n <SliderThumb class=\"block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\" />\n </SliderRoot>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Slider } from './Slider.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,20 @@
{
"name": "switch",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Switch.vue",
"content": "<script setup lang=\"ts\">\nimport {\n SwitchRoot,\n type SwitchRootEmits,\n type SwitchRootProps,\n SwitchThumb,\n} from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SwitchRootProps & { class?: string }>()\n\nconst emits = defineEmits<SwitchRootEmits>()\n</script>\n\n<template>\n <SwitchRoot\n v-bind=\"props\"\n :class=\"\n cn(\n 'peer inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',\n props.class,\n )\n \"\n @update:checked=\"emits('update:checked', $event)\"\n >\n <SwitchThumb\n :class=\"\n cn(\n 'pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0',\n )\n \"\n />\n </SwitchRoot>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Switch } from './Switch.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,50 @@
{
"name": "table",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Table.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: string }>()\n</script>\n\n<template>\n <div class=\"w-full overflow-auto\">\n <table :class=\"cn('w-full caption-bottom text-sm', props.class)\">\n <slot />\n </table>\n </div>\n</template>\n"
},
{
"name": "TableBody.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: string }>()\n</script>\n\n<template>\n <tbody :class=\"cn('[&_tr:last-child]:border-0', props.class)\">\n <slot />\n </tbody>\n</template>\n"
},
{
"name": "TableCaption.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: string }>()\n</script>\n\n<template>\n <caption :class=\"cn('mt-4 text-sm text-muted-foreground', props.class)\">\n <slot />\n </caption>\n</template>\n"
},
{
"name": "TableCell.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: string }>()\n</script>\n\n<template>\n <td\n :class=\"\n cn(\n 'p-4 align-middle [&:has([role=checkbox])]:pr-0',\n props.class,\n )\n \"\n >\n <slot />\n </td>\n</template>\n"
},
{
"name": "TableEmpty.vue",
"content": "<script setup lang=\"ts\">\nimport TableRow from './TableRow.vue'\nimport TableCell from './TableCell.vue'\nimport { cn } from '@/lib/utils'\n\ninterface Props {\n class?: string\n colspan?: number\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n class: '',\n colspan: 1,\n})\n</script>\n\n<template>\n <TableRow>\n <TableCell\n :class=\"\n cn(\n 'p-4 whitespace-nowrap align-middle text-sm text-foreground',\n props.class,\n )\n \"\n :colspan=\"props.colspan\"\n >\n <div class=\"flex items-center justify-center py-10\">\n <slot />\n </div>\n </TableCell>\n </TableRow>\n</template>\n"
},
{
"name": "TableFooter.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: string }>()\n</script>\n\n<template>\n <tfoot :class=\"cn('bg-primary font-medium text-primary-foreground', props.class)\">\n <slot />\n </tfoot>\n</template>\n"
},
{
"name": "TableHead.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: string }>()\n</script>\n\n<template>\n <th :class=\"cn('h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0', props.class)\">\n <slot />\n </th>\n</template>\n"
},
{
"name": "TableHeader.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: string }>()\n</script>\n\n<template>\n <thead :class=\"cn('[&_tr]:border-b', props.class)\">\n <slot />\n </thead>\n</template>\n"
},
{
"name": "TableRow.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: string }>()\n</script>\n\n<template>\n <tr :class=\"cn('border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted', props.class)\">\n <slot />\n </tr>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Table } from './Table.vue'\nexport { default as TableBody } from './TableBody.vue'\nexport { default as TableCell } from './TableCell.vue'\nexport { default as TableHead } from './TableHead.vue'\nexport { default as TableHeader } from './TableHeader.vue'\nexport { default as TableRow } from './TableRow.vue'\nexport { default as TableCaption } from './TableCaption.vue'\nexport { default as TableEmpty } from './TableEmpty.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,32 @@
{
"name": "tabs",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Tabs.vue",
"content": "<script setup lang=\"ts\">\nimport { TabsRoot, type TabsRootProps } from 'radix-vue'\n\nconst props = defineProps<TabsRootProps>()\n</script>\n\n<template>\n <TabsRoot v-bind=\"props\">\n <slot />\n </TabsRoot>\n</template>\n"
},
{
"name": "TabsContent.vue",
"content": "<script setup lang=\"ts\">\nimport { TabsContent, type TabsContentProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<TabsContentProps & { class?: string }>()\n</script>\n\n<template>\n <TabsContent\n :class=\"cn('mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2', props.class)\"\n v-bind=\"props\"\n >\n <slot />\n </TabsContent>\n</template>\n"
},
{
"name": "TabsList.vue",
"content": "<script setup lang=\"ts\">\nimport { TabsList, type TabsListProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<TabsListProps & { class?: string }>()\n</script>\n\n<template>\n <TabsList\n v-bind=\"props\"\n :class=\"\n cn(\n 'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',\n props.class,\n )\n \"\n >\n <slot />\n </TabsList>\n</template>\n"
},
{
"name": "TabsTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { TabsTrigger, type TabsTriggerProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<TabsTriggerProps & { class?: string }>()\n</script>\n\n<template>\n <TabsTrigger\n v-bind=\"props\"\n :class=\"\n cn(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm',\n props.class,\n )\n \"\n >\n <slot />\n </TabsTrigger>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Tabs } from './Tabs.vue'\nexport { default as TabsTrigger } from './TabsTrigger.vue'\nexport { default as TabsList } from './TabsList.vue'\nexport { default as TabsContent } from './TabsContent.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,18 @@
{
"name": "textarea",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Textarea.vue",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n</script>\n\n<template>\n <textarea :class=\"cn('flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', $attrs.class ?? '')\" />\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Textarea } from './Textarea.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,20 @@
{
"name": "toggle",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Toggle.vue",
"content": "<script setup lang=\"ts\">\nimport type { ToggleEmits, ToggleProps } from 'radix-vue'\nimport { Toggle } from 'radix-vue'\nimport type { VariantProps } from 'class-variance-authority'\nimport { computed } from 'vue'\nimport { toggleVariants } from '.'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\ninterface ToggleVariantProps extends VariantProps<typeof toggleVariants> {}\n\ninterface Props extends ToggleProps {\n variant?: ToggleVariantProps['variant']\n size?: ToggleVariantProps['size']\n}\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'default',\n size: 'default',\n})\nconst emits = defineEmits<ToggleEmits>()\n\nconst toggleProps = computed(() => {\n // eslint-disable-next-line unused-imports/no-unused-vars\n const { variant, size, ...otherProps } = props\n return otherProps\n})\n</script>\n\n<template>\n <Toggle\n v-bind=\"{ ...toggleProps, ...useEmitAsProps(emits) }\"\n :class=\"cn(toggleVariants({ variant, size, class: $attrs.class ?? '' }))\"\n >\n <slot />\n </Toggle>\n</template>\n"
},
{
"name": "index.ts",
"content": "import { cva } from 'class-variance-authority'\n\nexport { default as Toggle } from './Toggle.vue'\n\nexport const toggleVariants = cva(\n 'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground',\n {\n variants: {\n variant: {\n default: 'bg-transparent',\n outline:\n 'border border-input bg-transparent hover:bg-accent hover:text-accent-foreground',\n },\n size: {\n default: 'h-10 px-3',\n sm: 'h-9 px-2.5',\n lg: 'h-11 px-5',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,32 @@
{
"name": "tooltip",
"dependencies": [
"radix-vue"
],
"registryDependencies": [
"utils"
],
"files": [
{
"name": "Tooltip.vue",
"content": "<script setup lang=\"ts\">\nimport { TooltipRoot, type TooltipRootEmits, type TooltipRootProps } from 'radix-vue'\nimport { useEmitAsProps } from '@/lib/utils'\n\nconst props = defineProps<TooltipRootProps>()\nconst emits = defineEmits<TooltipRootEmits>()\n</script>\n\n<template>\n <TooltipRoot v-bind=\"{ ...props, ...useEmitAsProps(emits) }\">\n <slot />\n </TooltipRoot>\n</template>\n"
},
{
"name": "TooltipContent.vue",
"content": "<script setup lang=\"ts\">\nimport { TooltipContent, type TooltipContentEmits, type TooltipContentProps } from 'radix-vue'\nimport { cn, useEmitAsProps } from '@/lib/utils'\n\nconst props = withDefaults(defineProps<TooltipContentProps>(), {\n sideOffset: 4,\n})\nconst emits = defineEmits<TooltipContentEmits>()\n</script>\n\n<template>\n <TooltipContent v-bind=\"{ ...props, ...useEmitAsProps(emits) }\" :class=\"cn('z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', $attrs.class ?? '')\">\n <slot />\n </TooltipContent>\n</template>\n"
},
{
"name": "TooltipProvider.vue",
"content": "<script setup lang=\"ts\">\nimport { TooltipProvider, type TooltipProviderProps } from 'radix-vue'\n\nconst props = defineProps<TooltipProviderProps>()\n</script>\n\n<template>\n <TooltipProvider v-bind=\"props\">\n <slot />\n </TooltipProvider>\n</template>\n"
},
{
"name": "TooltipTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport { TooltipTrigger, type TooltipTriggerProps } from 'radix-vue'\n\nconst props = defineProps<TooltipTriggerProps>()\n</script>\n\n<template>\n <TooltipTrigger v-bind=\"props\">\n <slot />\n </TooltipTrigger>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Tooltip } from './Tooltip.vue'\nexport { default as TooltipContent } from './TooltipContent.vue'\nexport { default as TooltipTrigger } from './TooltipTrigger.vue'\nexport { default as TooltipProvider } from './TooltipProvider.vue'\n"
}
],
"type": "components:ui"
}

View File

@ -0,0 +1,6 @@
[
{
"name": "default",
"label": "Default"
}
]

View File

@ -0,0 +1,768 @@
.theme-zinc {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--ring: 240 5.9% 10%;
--radius: 0.5rem;
}
.dark .theme-zinc {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;
--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;
--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--ring: 240 4.9% 83.9%;
}
.theme-slate {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--ring: 222.2 84% 4.9%;
--radius: 0.5rem;
}
.dark .theme-slate {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--ring: 212.7 26.8% 83.9;
}
.theme-stone {
--background: 0 0% 100%;
--foreground: 20 14.3% 4.1%;
--muted: 60 4.8% 95.9%;
--muted-foreground: 25 5.3% 44.7%;
--popover: 0 0% 100%;
--popover-foreground: 20 14.3% 4.1%;
--card: 0 0% 100%;
--card-foreground: 20 14.3% 4.1%;
--border: 20 5.9% 90%;
--input: 20 5.9% 90%;
--primary: 24 9.8% 10%;
--primary-foreground: 60 9.1% 97.8%;
--secondary: 60 4.8% 95.9%;
--secondary-foreground: 24 9.8% 10%;
--accent: 60 4.8% 95.9%;
--accent-foreground: 24 9.8% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 60 9.1% 97.8%;
--ring: 20 14.3% 4.1%;
--radius: 0.5rem;
}
.dark .theme-stone {
--background: 20 14.3% 4.1%;
--foreground: 60 9.1% 97.8%;
--muted: 12 6.5% 15.1%;
--muted-foreground: 24 5.4% 63.9%;
--popover: 20 14.3% 4.1%;
--popover-foreground: 60 9.1% 97.8%;
--card: 20 14.3% 4.1%;
--card-foreground: 60 9.1% 97.8%;
--border: 12 6.5% 15.1%;
--input: 12 6.5% 15.1%;
--primary: 60 9.1% 97.8%;
--primary-foreground: 24 9.8% 10%;
--secondary: 12 6.5% 15.1%;
--secondary-foreground: 60 9.1% 97.8%;
--accent: 12 6.5% 15.1%;
--accent-foreground: 60 9.1% 97.8%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 60 9.1% 97.8%;
--ring: 24 5.7% 82.9%;
}
.theme-gray {
--background: 0 0% 100%;
--foreground: 224 71.4% 4.1%;
--muted: 220 14.3% 95.9%;
--muted-foreground: 220 8.9% 46.1%;
--popover: 0 0% 100%;
--popover-foreground: 224 71.4% 4.1%;
--card: 0 0% 100%;
--card-foreground: 224 71.4% 4.1%;
--border: 220 13% 91%;
--input: 220 13% 91%;
--primary: 220.9 39.3% 11%;
--primary-foreground: 210 20% 98%;
--secondary: 220 14.3% 95.9%;
--secondary-foreground: 220.9 39.3% 11%;
--accent: 220 14.3% 95.9%;
--accent-foreground: 220.9 39.3% 11%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 20% 98%;
--ring: 224 71.4% 4.1%;
--radius: 0.5rem;
}
.dark .theme-gray {
--background: 224 71.4% 4.1%;
--foreground: 210 20% 98%;
--muted: 215 27.9% 16.9%;
--muted-foreground: 217.9 10.6% 64.9%;
--popover: 224 71.4% 4.1%;
--popover-foreground: 210 20% 98%;
--card: 224 71.4% 4.1%;
--card-foreground: 210 20% 98%;
--border: 215 27.9% 16.9%;
--input: 215 27.9% 16.9%;
--primary: 210 20% 98%;
--primary-foreground: 220.9 39.3% 11%;
--secondary: 215 27.9% 16.9%;
--secondary-foreground: 210 20% 98%;
--accent: 215 27.9% 16.9%;
--accent-foreground: 210 20% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 20% 98%;
--ring: 216 12.2% 83.9%;
}
.theme-neutral {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
--muted: 0 0% 96.1%;
--muted-foreground: 0 0% 45.1%;
--popover: 0 0% 100%;
--popover-foreground: 0 0% 3.9%;
--card: 0 0% 100%;
--card-foreground: 0 0% 3.9%;
--border: 0 0% 89.8%;
--input: 0 0% 89.8%;
--primary: 0 0% 9%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 96.1%;
--secondary-foreground: 0 0% 9%;
--accent: 0 0% 96.1%;
--accent-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--ring: 0 0% 3.9%;
--radius: 0.5rem;
}
.dark .theme-neutral {
--background: 0 0% 3.9%;
--foreground: 0 0% 98%;
--muted: 0 0% 14.9%;
--muted-foreground: 0 0% 63.9%;
--popover: 0 0% 3.9%;
--popover-foreground: 0 0% 98%;
--card: 0 0% 3.9%;
--card-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--input: 0 0% 14.9%;
--primary: 0 0% 98%;
--primary-foreground: 0 0% 9%;
--secondary: 0 0% 14.9%;
--secondary-foreground: 0 0% 98%;
--accent: 0 0% 14.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--ring: 0 0% 83.1%;
}
.theme-red {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
--muted: 0 0% 96.1%;
--muted-foreground: 0 0% 45.1%;
--popover: 0 0% 100%;
--popover-foreground: 0 0% 3.9%;
--card: 0 0% 100%;
--card-foreground: 0 0% 3.9%;
--border: 0 0% 89.8%;
--input: 0 0% 89.8%;
--primary: 0 72.2% 50.6%;
--primary-foreground: 0 85.7% 97.3%;
--secondary: 0 0% 96.1%;
--secondary-foreground: 0 0% 9%;
--accent: 0 0% 96.1%;
--accent-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--ring: 0 72.2% 50.6%;
--radius: 0.5rem;
}
.dark .theme-red {
--background: 0 0% 3.9%;
--foreground: 0 0% 98%;
--muted: 0 0% 14.9%;
--muted-foreground: 0 0% 63.9%;
--popover: 0 0% 3.9%;
--popover-foreground: 0 0% 98%;
--card: 0 0% 3.9%;
--card-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--input: 0 0% 14.9%;
--primary: 0 72.2% 50.6%;
--primary-foreground: 0 85.7% 97.3%;
--secondary: 0 0% 14.9%;
--secondary-foreground: 0 0% 98%;
--accent: 0 0% 14.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--ring: 0 72.2% 50.6%;
}
.theme-rose {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--primary: 346.8 77.2% 49.8%;
--primary-foreground: 355.7 100% 97.3%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--ring: 346.8 77.2% 49.8%;
--radius: 0.5rem;
}
.dark .theme-rose {
--background: 20 14.3% 4.1%;
--foreground: 0 0% 95%;
--muted: 0 0% 15%;
--muted-foreground: 240 5% 64.9%;
--popover: 0 0% 9%;
--popover-foreground: 0 0% 95%;
--card: 24 9.8% 10%;
--card-foreground: 0 0% 95%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--primary: 346.8 77.2% 49.8%;
--primary-foreground: 355.7 100% 97.3%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--accent: 12 6.5% 15.1%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 85.7% 97.3%;
--ring: 346.8 77.2% 49.8%;
}
.theme-orange {
--background: 0 0% 100%;
--foreground: 20 14.3% 4.1%;
--muted: 60 4.8% 95.9%;
--muted-foreground: 25 5.3% 44.7%;
--popover: 0 0% 100%;
--popover-foreground: 20 14.3% 4.1%;
--card: 0 0% 100%;
--card-foreground: 20 14.3% 4.1%;
--border: 20 5.9% 90%;
--input: 20 5.9% 90%;
--primary: 24.6 95% 53.1%;
--primary-foreground: 60 9.1% 97.8%;
--secondary: 60 4.8% 95.9%;
--secondary-foreground: 24 9.8% 10%;
--accent: 60 4.8% 95.9%;
--accent-foreground: 24 9.8% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 60 9.1% 97.8%;
--ring: 24.6 95% 53.1%;
--radius: 0.5rem;
}
.dark .theme-orange {
--background: 20 14.3% 4.1%;
--foreground: 60 9.1% 97.8%;
--muted: 12 6.5% 15.1%;
--muted-foreground: 24 5.4% 63.9%;
--popover: 20 14.3% 4.1%;
--popover-foreground: 60 9.1% 97.8%;
--card: 20 14.3% 4.1%;
--card-foreground: 60 9.1% 97.8%;
--border: 12 6.5% 15.1%;
--input: 12 6.5% 15.1%;
--primary: 20.5 90.2% 48.2%;
--primary-foreground: 60 9.1% 97.8%;
--secondary: 12 6.5% 15.1%;
--secondary-foreground: 60 9.1% 97.8%;
--accent: 12 6.5% 15.1%;
--accent-foreground: 60 9.1% 97.8%;
--destructive: 0 72.2% 50.6%;
--destructive-foreground: 60 9.1% 97.8%;
--ring: 20.5 90.2% 48.2%;
}
.theme-green {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--primary: 142.1 76.2% 36.3%;
--primary-foreground: 355.7 100% 97.3%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--ring: 142.1 76.2% 36.3%;
--radius: 0.5rem;
}
.dark .theme-green {
--background: 20 14.3% 4.1%;
--foreground: 0 0% 95%;
--muted: 0 0% 15%;
--muted-foreground: 240 5% 64.9%;
--popover: 0 0% 9%;
--popover-foreground: 0 0% 95%;
--card: 24 9.8% 10%;
--card-foreground: 0 0% 95%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--primary: 142.1 70.6% 45.3%;
--primary-foreground: 144.9 80.4% 10%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--accent: 12 6.5% 15.1%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 85.7% 97.3%;
--ring: 142.4 71.8% 29.2%;
}
.theme-blue {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--ring: 221.2 83.2% 53.3%;
--radius: 0.5rem;
}
.dark .theme-blue {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--primary: 217.2 91.2% 59.8%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--ring: 224.3 76.3% 48%;
}
.theme-yellow {
--background: 0 0% 100%;
--foreground: 20 14.3% 4.1%;
--muted: 60 4.8% 95.9%;
--muted-foreground: 25 5.3% 44.7%;
--popover: 0 0% 100%;
--popover-foreground: 20 14.3% 4.1%;
--card: 0 0% 100%;
--card-foreground: 20 14.3% 4.1%;
--border: 20 5.9% 90%;
--input: 20 5.9% 90%;
--primary: 47.9 95.8% 53.1%;
--primary-foreground: 26 83.3% 14.1%;
--secondary: 60 4.8% 95.9%;
--secondary-foreground: 24 9.8% 10%;
--accent: 60 4.8% 95.9%;
--accent-foreground: 24 9.8% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 60 9.1% 97.8%;
--ring: 20 14.3% 4.1%;
--radius: 0.5rem;
}
.dark .theme-yellow {
--background: 20 14.3% 4.1%;
--foreground: 60 9.1% 97.8%;
--muted: 12 6.5% 15.1%;
--muted-foreground: 24 5.4% 63.9%;
--popover: 20 14.3% 4.1%;
--popover-foreground: 60 9.1% 97.8%;
--card: 20 14.3% 4.1%;
--card-foreground: 60 9.1% 97.8%;
--border: 12 6.5% 15.1%;
--input: 12 6.5% 15.1%;
--primary: 47.9 95.8% 53.1%;
--primary-foreground: 26 83.3% 14.1%;
--secondary: 12 6.5% 15.1%;
--secondary-foreground: 60 9.1% 97.8%;
--accent: 12 6.5% 15.1%;
--accent-foreground: 60 9.1% 97.8%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 60 9.1% 97.8%;
--ring: 35.5 91.7% 32.9%;
}
.theme-violet {
--background: 0 0% 100%;
--foreground: 224 71.4% 4.1%;
--muted: 220 14.3% 95.9%;
--muted-foreground: 220 8.9% 46.1%;
--popover: 0 0% 100%;
--popover-foreground: 224 71.4% 4.1%;
--card: 0 0% 100%;
--card-foreground: 224 71.4% 4.1%;
--border: 220 13% 91%;
--input: 220 13% 91%;
--primary: 262.1 83.3% 57.8%;
--primary-foreground: 210 20% 98%;
--secondary: 220 14.3% 95.9%;
--secondary-foreground: 220.9 39.3% 11%;
--accent: 220 14.3% 95.9%;
--accent-foreground: 220.9 39.3% 11%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 20% 98%;
--ring: 262.1 83.3% 57.8%;
--radius: 0.5rem;
}
.dark .theme-violet {
--background: 224 71.4% 4.1%;
--foreground: 210 20% 98%;
--muted: 215 27.9% 16.9%;
--muted-foreground: 217.9 10.6% 64.9%;
--popover: 224 71.4% 4.1%;
--popover-foreground: 210 20% 98%;
--card: 224 71.4% 4.1%;
--card-foreground: 210 20% 98%;
--border: 215 27.9% 16.9%;
--input: 215 27.9% 16.9%;
--primary: 263.4 70% 50.4%;
--primary-foreground: 210 20% 98%;
--secondary: 215 27.9% 16.9%;
--secondary-foreground: 210 20% 98%;
--accent: 215 27.9% 16.9%;
--accent-foreground: 210 20% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 20% 98%;
--ring: 263.4 70% 50.4%;
}

View File

@ -1,5 +1,6 @@
{ {
"include": ["/**/*.vue", ".vitepress/**/*.vue", "/**/*.ts", ".vitepress/**/*.mts", "src/lib/**/*"], "include": ["/**/*.vue", ".vitepress/**/*.vue", "/**/*.ts", ".vitepress/**/*.mts", "src/lib/**/*"],
"exclude": ["node_modules", "./scripts/build-registry.ts"],
"compilerOptions": { "compilerOptions": {
"target": "esnext", "target": "esnext",
"module": "esnext", "module": "esnext",

View File

@ -0,0 +1,34 @@
{
"extends": "./tsconfig.json",
"include": [".contentlayer/generated", "src/**/*.ts", "scripts/**/*.ts"],
"exclude": ["node_modules"],
"compilerOptions": {
"target": "ES2019",
"lib": [
"es2019",
"DOM"
],
"module": "ESNext",
"declaration": true,
"strict": true,
"strictNullChecks": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": false,
"experimentalDecorators": true,
"strictPropertyInitialization": false,
"isolatedModules": true,
"typeRoots": [
"./node_modules/@types"
],
"resolveJsonModule": true,
"esModuleInterop": true,
"moduleResolution": "node"
},
"ts-node": {
"esm": true,
"experimentalSpecifierResolution": "node",
"transpileOnly": true
}
}

View File

@ -111,6 +111,9 @@ importers:
'@vue/compiler-core': '@vue/compiler-core':
specifier: ^3.3.4 specifier: ^3.3.4
version: 3.3.4 version: 3.3.4
'@vue/compiler-dom':
specifier: ^3.3.4
version: 3.3.4
autoprefixer: autoprefixer:
specifier: ^10.4.14 specifier: ^10.4.14
version: 10.4.14(postcss@8.4.24) version: 10.4.14(postcss@8.4.24)
@ -132,6 +135,9 @@ importers:
tailwindcss: tailwindcss:
specifier: ^3.3.3 specifier: ^3.3.3
version: 3.3.3(ts-node@10.9.1) version: 3.3.3(ts-node@10.9.1)
ts-node:
specifier: ^10.9.1
version: 10.9.1(@types/node@20.5.7)(typescript@5.0.2)
typescript: typescript:
specifier: ^5.0.2 specifier: ^5.0.2
version: 5.0.2 version: 5.0.2
@ -2244,6 +2250,7 @@ packages:
/@types/node@20.4.7: /@types/node@20.4.7:
resolution: {integrity: sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g==} resolution: {integrity: sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g==}
dev: true
/@types/node@20.5.7: /@types/node@20.5.7:
resolution: {integrity: sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==} resolution: {integrity: sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==}
@ -6294,8 +6301,25 @@ packages:
dependencies: dependencies:
lilconfig: 2.1.0 lilconfig: 2.1.0
postcss: 8.4.28 postcss: 8.4.28
ts-node: 10.9.1(@types/node@20.5.7)(typescript@5.0.2)
yaml: 2.3.1
/postcss-load-config@4.0.1(ts-node@10.9.1):
resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==}
engines: {node: '>= 14'}
peerDependencies:
postcss: '>=8.0.9'
ts-node: '>=9.0.0'
peerDependenciesMeta:
postcss:
optional: true
ts-node:
optional: true
dependencies:
lilconfig: 2.1.0
ts-node: 10.9.1(@types/node@20.4.7)(typescript@5.2.2) ts-node: 10.9.1(@types/node@20.4.7)(typescript@5.2.2)
yaml: 2.3.1 yaml: 2.3.1
dev: true
/postcss-nested@6.0.1(postcss@8.4.28): /postcss-nested@6.0.1(postcss@8.4.28):
resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==}
@ -7161,6 +7185,37 @@ packages:
typescript: 5.2.2 typescript: 5.2.2
v8-compile-cache-lib: 3.0.1 v8-compile-cache-lib: 3.0.1
yn: 3.1.1 yn: 3.1.1
dev: true
/ts-node@10.9.1(@types/node@20.5.7)(typescript@5.0.2):
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
peerDependencies:
'@swc/core': '>=1.2.50'
'@swc/wasm': '>=1.2.50'
'@types/node': '*'
typescript: '>=2.7'
peerDependenciesMeta:
'@swc/core':
optional: true
'@swc/wasm':
optional: true
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.9
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4
'@types/node': 20.5.7
acorn: 8.10.0
acorn-walk: 8.2.0
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
typescript: 5.0.2
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
/tsconfig-paths@4.2.0: /tsconfig-paths@4.2.0:
resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==}
@ -7203,7 +7258,7 @@ packages:
execa: 5.1.1 execa: 5.1.1
globby: 11.1.0 globby: 11.1.0
joycon: 3.1.1 joycon: 3.1.1
postcss-load-config: 4.0.1(postcss@8.4.28)(ts-node@10.9.1) postcss-load-config: 4.0.1(ts-node@10.9.1)
resolve-from: 5.0.0 resolve-from: 5.0.0
rollup: 3.28.1 rollup: 3.28.1
source-map: 0.8.0-beta.0 source-map: 0.8.0-beta.0
@ -7368,12 +7423,12 @@ packages:
resolution: {integrity: sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==} resolution: {integrity: sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==}
engines: {node: '>=12.20'} engines: {node: '>=12.20'}
hasBin: true hasBin: true
dev: true
/typescript@5.2.2: /typescript@5.2.2:
resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
engines: {node: '>=14.17'} engines: {node: '>=14.17'}
hasBin: true hasBin: true
dev: true
/ufo@1.2.0: /ufo@1.2.0:
resolution: {integrity: sha512-RsPyTbqORDNDxqAdQPQBpgqhWle1VcTSou/FraClYlHf6TZnQcGslpLcAphNR+sQW4q5lLWLbOsRlh9j24baQg==} resolution: {integrity: sha512-RsPyTbqORDNDxqAdQPQBpgqhWle1VcTSou/FraClYlHf6TZnQcGslpLcAphNR+sQW4q5lLWLbOsRlh9j24baQg==}