refactor: build registry

This commit is contained in:
zernonia 2024-11-21 15:23:29 +08:00
parent ac14ca835a
commit aec80c9342
567 changed files with 3828 additions and 3728 deletions

View File

@ -0,0 +1 @@
// The content of this directory is autogenerated by the registry server.

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,6 @@ import type {
} from '../src/registry/schema'
// @sts-nocheck
import { existsSync, promises as fs } from 'node:fs'
import { tmpdir } from 'node:os'
import path from 'node:path'
import { template } from 'lodash-es'
import { rimraf } from 'rimraf'
@ -21,7 +20,6 @@ import {
registryEntrySchema,
registrySchema,
} from '../src/registry/schema'
import { fixImport } from './fix-import'
const REGISTRY_PATH = path.join(process.cwd(), 'src/public/r')
@ -38,10 +36,10 @@ const REGISTRY_INDEX_WHITELIST: z.infer<typeof registryItemTypeSchema>[] = [
// compilerOptions: {},
// })
async function createTempSourceFile(filename: string) {
const dir = await fs.mkdtemp(path.join(tmpdir(), 'shadcn-'))
return path.join(dir, filename)
}
// async function createTempSourceFile(filename: string) {
// const dir = await fs.mkdtemp(path.join(tmpdir(), 'shadcn-'))
// return path.join(dir, filename)
// }
// ----------------------------------------------------------------------------
// Build __registry__/index.ts.
@ -70,206 +68,207 @@ export const Index: Record<string, any> = {
}
const type = item.type.split(':')[1]
let sourceFilename = ''
const sourceFilename = ''
// const chunks: any = []
if (item.type === 'registry:block') {
const file = resolveFiles[0]
console.log(item, file)
let raw: string
try {
const filename = path.basename(file)
raw = await fs.readFile(file, 'utf8')
}
catch (error) {
continue
}
// const tempFile = await createTempSourceFile(filename)
// const sourceFile = project.createSourceFile(tempFile, raw, {
// scriptKind: ScriptKind.TS,
// })
// if (item.type === 'registry:block') {
// const file = resolveFiles[0]
// let raw: string
// try {
// if (file) {
// const filename = path.basename(file)
// }
// raw = await fs.readFile(file, 'utf8')
// }
// catch (error) {
// continue
// }
// // const tempFile = await createTempSourceFile(filename)
// // const sourceFile = project.createSourceFile(tempFile, raw, {
// // scriptKind: ScriptKind.TS,
// // })
// const description = sourceFile
// .getVariableDeclaration('description')
// ?.getInitializerOrThrow()
// .asKindOrThrow(SyntaxKind.StringLiteral)
// .getLiteralValue()
// // const description = sourceFile
// // .getVariableDeclaration('description')
// // ?.getInitializerOrThrow()
// // .asKindOrThrow(SyntaxKind.StringLiteral)
// // .getLiteralValue()
// item.description = description ?? ''
// // item.description = description ?? ''
// // Find all imports.
// const imports = new Map<
// string,
// {
// module: string
// text: string
// isDefault?: boolean
// }
// >()
// sourceFile.getImportDeclarations().forEach((node) => {
// const module = node.getModuleSpecifier().getLiteralValue()
// node.getNamedImports().forEach((item) => {
// imports.set(item.getText(), {
// module,
// text: node.getText(),
// })
// })
// // // Find all imports.
// // const imports = new Map<
// // string,
// // {
// // module: string
// // text: string
// // isDefault?: boolean
// // }
// // >()
// // sourceFile.getImportDeclarations().forEach((node) => {
// // const module = node.getModuleSpecifier().getLiteralValue()
// // node.getNamedImports().forEach((item) => {
// // imports.set(item.getText(), {
// // module,
// // text: node.getText(),
// // })
// // })
// const defaultImport = node.getDefaultImport()
// if (defaultImport) {
// imports.set(defaultImport.getText(), {
// module,
// text: defaultImport.getText(),
// isDefault: true,
// })
// }
// })
// // const defaultImport = node.getDefaultImport()
// // if (defaultImport) {
// // imports.set(defaultImport.getText(), {
// // module,
// // text: defaultImport.getText(),
// // isDefault: true,
// // })
// // }
// // })
// Find all opening tags with x-chunk attribute.
// const components = sourceFile
// .getDescendantsOfKind(SyntaxKind.JsxOpeningElement)
// .filter((node) => {
// return node.getAttribute('x-chunk') !== undefined
// })
// // Find all opening tags with x-chunk attribute.
// // const components = sourceFile
// // .getDescendantsOfKind(SyntaxKind.JsxOpeningElement)
// // .filter((node) => {
// // return node.getAttribute('x-chunk') !== undefined
// // })
// chunks = await Promise.all(
// components.map(async (component, index) => {
// const chunkName = `${item.name}-chunk-${index}`
// // chunks = await Promise.all(
// // components.map(async (component, index) => {
// // const chunkName = `${item.name}-chunk-${index}`
// // Get the value of x-chunk attribute.
// const attr = component
// .getAttributeOrThrow('x-chunk')
// .asKindOrThrow(SyntaxKind.JsxAttribute)
// // // Get the value of x-chunk attribute.
// // const attr = component
// // .getAttributeOrThrow('x-chunk')
// // .asKindOrThrow(SyntaxKind.JsxAttribute)
// const description = attr
// .getInitializerOrThrow()
// .asKindOrThrow(SyntaxKind.StringLiteral)
// .getLiteralValue()
// // const description = attr
// // .getInitializerOrThrow()
// // .asKindOrThrow(SyntaxKind.StringLiteral)
// // .getLiteralValue()
// // Delete the x-chunk attribute.
// attr.remove()
// // // Delete the x-chunk attribute.
// // attr.remove()
// // Add a new attribute to the component.
// component.addAttribute({
// name: 'x-chunk',
// initializer: `"${chunkName}"`,
// })
// // // Add a new attribute to the component.
// // component.addAttribute({
// // name: 'x-chunk',
// // initializer: `"${chunkName}"`,
// // })
// // Get the value of x-chunk-container attribute.
// const containerAttr = component
// .getAttribute('x-chunk-container')
// ?.asKindOrThrow(SyntaxKind.JsxAttribute)
// // // Get the value of x-chunk-container attribute.
// // const containerAttr = component
// // .getAttribute('x-chunk-container')
// // ?.asKindOrThrow(SyntaxKind.JsxAttribute)
// const containerClassName = containerAttr
// ?.getInitializer()
// ?.asKindOrThrow(SyntaxKind.StringLiteral)
// .getLiteralValue()
// // const containerClassName = containerAttr
// // ?.getInitializer()
// // ?.asKindOrThrow(SyntaxKind.StringLiteral)
// // .getLiteralValue()
// containerAttr?.remove()
// // containerAttr?.remove()
// const parentJsxElement = component.getParentIfKindOrThrow(
// SyntaxKind.JsxElement,
// )
// // const parentJsxElement = component.getParentIfKindOrThrow(
// // SyntaxKind.JsxElement,
// // )
// // Find all opening tags on component.
// const children = parentJsxElement
// .getDescendantsOfKind(SyntaxKind.JsxOpeningElement)
// .map((node) => {
// return node.getTagNameNode().getText()
// })
// .concat(
// parentJsxElement
// .getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement)
// .map((node) => {
// return node.getTagNameNode().getText()
// }),
// )
// // // Find all opening tags on component.
// // const children = parentJsxElement
// // .getDescendantsOfKind(SyntaxKind.JsxOpeningElement)
// // .map((node) => {
// // return node.getTagNameNode().getText()
// // })
// // .concat(
// // parentJsxElement
// // .getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement)
// // .map((node) => {
// // return node.getTagNameNode().getText()
// // }),
// // )
// const componentImports = new Map<
// string,
// string | string[] | Set<string>
// >()
// children.forEach((child) => {
// const importLine = imports.get(child)
// if (importLine) {
// const imports = componentImports.get(importLine.module) || []
// // const componentImports = new Map<
// // string,
// // string | string[] | Set<string>
// // >()
// // children.forEach((child) => {
// // const importLine = imports.get(child)
// // if (importLine) {
// // const imports = componentImports.get(importLine.module) || []
// const newImports = importLine.isDefault
// ? importLine.text
// : new Set([...imports, child])
// // const newImports = importLine.isDefault
// // ? importLine.text
// // : new Set([...imports, child])
// componentImports.set(
// importLine.module,
// importLine?.isDefault ? newImports : Array.from(newImports),
// )
// }
// })
// // componentImports.set(
// // importLine.module,
// // importLine?.isDefault ? newImports : Array.from(newImports),
// // )
// // }
// // })
// const componnetImportLines = Array.from(
// componentImports.keys(),
// ).map((key) => {
// const values = componentImports.get(key)
// const specifier = Array.isArray(values)
// ? `{${values.join(',')}}`
// : values
// // const componnetImportLines = Array.from(
// // componentImports.keys(),
// // ).map((key) => {
// // const values = componentImports.get(key)
// // const specifier = Array.isArray(values)
// // ? `{${values.join(',')}}`
// // : values
// return `import ${specifier} from "${key}"`
// })
// // return `import ${specifier} from "${key}"`
// // })
// const code = `
// 'use client'
// // const code = `
// // 'use client'
// ${componnetImportLines.join('\n')}
// // ${componnetImportLines.join('\n')}
// export default function Component() {
// return (${parentJsxElement.getText()})
// }`
// // export default function Component() {
// // return (${parentJsxElement.getText()})
// // }`
// const targetFile = file.replace(item.name, `${chunkName}`)
// const targetFilePath = path.join(
// cwd(),
// `registry/${style.name}/${type}/${chunkName}.ts`,
// )
// // const targetFile = file.replace(item.name, `${chunkName}`)
// // const targetFilePath = path.join(
// // cwd(),
// // `registry/${style.name}/${type}/${chunkName}.ts`,
// // )
// // Write component file.
// rimraf.sync(targetFilePath)
// await fs.writeFile(targetFilePath, code, 'utf8')
// // // Write component file.
// // rimraf.sync(targetFilePath)
// // await fs.writeFile(targetFilePath, code, 'utf8')
// return {
// name: chunkName,
// description,
// component: `React.lazy(() => import("@/registry/${style.name}/${type}/${chunkName}")),`,
// file: targetFile,
// container: {
// className: containerClassName,
// },
// }
// }),
// )
// // return {
// // name: chunkName,
// // description,
// // component: `React.lazy(() => import("@/registry/${style.name}/${type}/${chunkName}")),`,
// // file: targetFile,
// // container: {
// // className: containerClassName,
// // },
// // }
// // }),
// // )
// // Write the source file for blocks only.
sourceFilename = `__registry__/${style.name}/${type}/${item.name}.ts`
// // // Write the source file for blocks only.
// sourceFilename = `__registry__/${style.name}/${type}/${item.name}.ts`
if (item.files) {
const files = item.files.map(file =>
typeof file === 'string'
? { type: 'registry:page', path: file }
: file,
)
if (files?.length) {
sourceFilename = `__registry__/${style.name}/${files[0].path}`
}
}
// if (item.files) {
// const files = item.files.map(file =>
// typeof file === 'string'
// ? { type: 'registry:page', path: file }
// : file,
// )
// if (files?.length) {
// sourceFilename = `__registry__/${style.name}/${files[0].path}`
// }
// }
const sourcePath = path.join(process.cwd(), sourceFilename)
if (!existsSync(sourcePath)) {
await fs.mkdir(sourcePath, { recursive: true })
}
// const sourcePath = path.join(process.cwd(), sourceFilename)
// if (!existsSync(sourcePath)) {
// await fs.mkdir(sourcePath, { recursive: true })
// }
rimraf.sync(sourcePath)
// await fs.writeFile(sourcePath, sourceFile.getText())
await fs.writeFile(sourcePath, raw)
}
// rimraf.sync(sourcePath)
// // await fs.writeFile(sourcePath, sourceFile.getText())
// await fs.writeFile(sourcePath, raw)
// }
let componentPath = `@/registry/${style.name}/${type}/${item.name}`
@ -340,14 +339,7 @@ export const Index: Record<string, any> = {
return {
...item,
files: item.files?.map((_file) => {
const file
= typeof _file === 'string'
? {
path: _file,
type: item.type,
}
: _file
const file = { path: _file.path, type: item.type }
return file
}),
}
@ -386,27 +378,19 @@ async function buildStyles(registry: Registry) {
if (item.files) {
files = await Promise.all(
item.files.map(async (_file) => {
const file
= typeof _file === 'string'
? {
path: _file,
type: item.type,
content: '',
target: '',
}
: _file
const file = {
path: _file.path,
type: _file.type,
content: '',
target: _file.target ?? '',
}
let content: string
try {
content = await fs.readFile(
path.join(process.cwd(), 'registry', style.name, file.path),
path.join(process.cwd(), 'src', 'registry', style.name, file.path),
'utf8',
)
// Only fix imports for v0- blocks.
if (item.name.startsWith('v0-')) {
content = fixImport(content)
}
}
catch (error) {
return
@ -422,30 +406,30 @@ async function buildStyles(registry: Registry) {
// sourceFile.getVariableDeclaration('containerClassName')?.remove()
// sourceFile.getVariableDeclaration('description')?.remove()
let target = file.target || ''
const target = file.target || ''
if ((!target || target === '') && item.name.startsWith('v0-')) {
const fileName = file.path.split('/').pop()
if (
file.type === 'registry:block'
|| file.type === 'registry:component'
|| file.type === 'registry:example'
) {
target = `components/${fileName}`
}
// if ((!target || target === '') && item.name.startsWith('v0-')) {
// const fileName = file.path.split('/').pop()
// if (
// file.type === 'registry:block'
// || file.type === 'registry:component'
// || file.type === 'registry:example'
// ) {
// target = `components/${fileName}`
// }
if (file.type === 'registry:ui') {
target = `components/ui/${fileName}`
}
// if (file.type === 'registry:ui') {
// target = `components/ui/${fileName}`
// }
if (file.type === 'registry:hook') {
target = `hooks/${fileName}`
}
// if (file.type === 'registry:hook') {
// target = `hooks/${fileName}`
// }
if (file.type === 'registry:lib') {
target = `lib/${fileName}`
}
}
// if (file.type === 'registry:lib') {
// target = `lib/${fileName}`
// }
// }
return {
path: file.path,
@ -458,6 +442,9 @@ async function buildStyles(registry: Registry) {
)
}
// if (item.type === 'registry:block' && item.name === 'Sidebar01')
// console.log(item.name, item.files?.[0], files?.[0])
const payload = registryEntrySchema
.omit({
// source: true,
@ -473,7 +460,7 @@ async function buildStyles(registry: Registry) {
if (payload.success) {
await fs.writeFile(
path.join(targetPath, `${item.name}.json`),
JSON.stringify(payload.data, null, 2),
`${JSON.stringify(payload.data, null, 2)}\r\n`,
'utf8',
)
}
@ -501,10 +488,10 @@ async function buildStylesIndex() {
const dependencies = [
'tailwindcss-animate',
'class-variance-authority',
'lucide-react',
'lucide-vue-next',
]
// TODO: Remove this when we migrate to lucide-react.
// TODO: Remove this when we migrate to lucide-vue-next.
// if (style.name === "new-york") {
// dependencies.push("@radix-ui/react-icons")
// }
@ -575,7 +562,7 @@ async function buildThemes() {
await fs.writeFile(
path.join(colorsTargetPath, 'index.json'),
JSON.stringify(colorsData, null, 2),
`${JSON.stringify(colorsData, null, 2)}\r\n`,
'utf8',
)
@ -697,7 +684,7 @@ async function buildThemes() {
await fs.writeFile(
path.join(REGISTRY_PATH, `colors/${baseColor}.json`),
JSON.stringify(base, null, 2),
`${JSON.stringify(base, null, 2)}\r\n`,
'utf8',
)

View File

@ -1,150 +0,0 @@
{
"AlertCircle": {
"lucide": "AlertCircle",
"radix": "ExclamationTriangleIcon"
},
"ArrowLeft": {
"lucide": "ArrowLeft",
"radix": "ArrowLeftIcon"
},
"ArrowRight": {
"lucide": "ArrowRight",
"radix": "ArrowRightIcon"
},
"ArrowUpDown": {
"lucide": "ArrowUpDown",
"radix": "CaretSortIcon"
},
"BellRing": {
"lucide": "BellRing",
"radix": "BellIcon"
},
"Bold": {
"lucide": "Bold",
"radix": "FontBoldIcon"
},
"Calculator": {
"lucide": "Calculator",
"radix": "ComponentPlaceholderIcon"
},
"Calendar": {
"lucide": "Calendar",
"radix": "CalendarIcon"
},
"Check": {
"lucide": "Check",
"radix": "CheckIcon"
},
"ChevronDown": {
"lucide": "ChevronDown",
"radix": "ChevronDownIcon"
},
"ChevronLeft": {
"lucide": "ChevronLeft",
"radix": "ChevronLeftIcon"
},
"ChevronRight": {
"lucide": "ChevronRight",
"radix": "ChevronRightIcon"
},
"ChevronUp": {
"lucide": "ChevronUp",
"radix": "ChevronUpIcon"
},
"ChevronsUpDown": {
"lucide": "ChevronsUpDown",
"radix": "CaretSortIcon"
},
"Circle": {
"lucide": "Circle",
"radix": "DotFilledIcon"
},
"Copy": {
"lucide": "Copy",
"radix": "CopyIcon"
},
"CreditCard": {
"lucide": "CreditCard",
"radix": "ComponentPlaceholderIcon"
},
"GripVertical": {
"lucide": "GripVertical",
"radix": "DragHandleDots2Icon"
},
"Italic": {
"lucide": "Italic",
"radix": "FontItalicIcon"
},
"Loader2": {
"lucide": "Loader2",
"radix": "ReloadIcon"
},
"Mail": {
"lucide": "Mail",
"radix": "EnvelopeClosedIcon"
},
"MailOpen": {
"lucide": "MailOpen",
"radix": "EnvelopeOpenIcon"
},
"Minus": {
"lucide": "Minus",
"radix": "MinusIcon"
},
"Moon": {
"lucide": "Moon",
"radix": "MoonIcon"
},
"MoreHorizontal": {
"lucide": "MoreHorizontal",
"radix": "DotsHorizontalIcon"
},
"PanelLeft": {
"lucide": "PanelLeft",
"radix": "ViewVerticalIcon"
},
"Plus": {
"lucide": "Plus",
"radix": "PlusIcon"
},
"Search": {
"lucide": "Search",
"radix": "MagnifyingGlassIcon"
},
"Send": {
"lucide": "Send",
"radix": "PaperPlaneIcon"
},
"Settings": {
"lucide": "Settings",
"radix": "GearIcon"
},
"Slash": {
"lucide": "Slash",
"radix": "SlashIcon"
},
"Smile": {
"lucide": "Smile",
"radix": "FaceIcon"
},
"Sun": {
"lucide": "Sun",
"radix": "SunIcon"
},
"Terminal": {
"lucide": "Terminal",
"radix": "RocketIcon"
},
"Underline": {
"lucide": "Underline",
"radix": "UnderlineIcon"
},
"User": {
"lucide": "User",
"radix": "PersonIcon"
},
"X": {
"lucide": "X",
"radix": "Cross2Icon"
}
}

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,18 @@
"name": "Authentication01",
"type": "registry:block",
"dependencies": [],
"registryDependencies": [],
"files": []
"registryDependencies": [
"button",
"card",
"input",
"label"
],
"files": [
{
"path": "block/Authentication01.vue",
"content": "<script lang=\"ts\">\nexport const description\n = 'A simple login form with email and password. The submit button says \\'Sign in\\'.'\nexport const iframeHeight = '600px'\nexport const containerClass = 'w-full h-screen flex items-center justify-center px-4'\n</script>\n\n<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/registry/default/ui/card'\nimport { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\n</script>\n\n<template>\n <Card class=\"w-full max-w-sm\">\n <CardHeader>\n <CardTitle class=\"text-2xl\">\n Login\n </CardTitle>\n <CardDescription>\n Enter your email below to login to your account.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"grid gap-4\">\n <div class=\"grid gap-2\">\n <Label for=\"email\">Email</Label>\n <Input id=\"email\" type=\"email\" placeholder=\"m@example.com\" required />\n </div>\n <div class=\"grid gap-2\">\n <Label for=\"password\">Password</Label>\n <Input id=\"password\" type=\"password\" required />\n </div>\n </CardContent>\n <CardFooter>\n <Button class=\"w-full\">\n Sign in\n </Button>\n </CardFooter>\n </Card>\n</template>\n",
"type": "registry:block",
"target": "Authentication01.vue"
}
]
}

View File

@ -2,6 +2,18 @@
"name": "Authentication02",
"type": "registry:block",
"dependencies": [],
"registryDependencies": [],
"files": []
"registryDependencies": [
"button",
"card",
"input",
"label"
],
"files": [
{
"path": "block/Authentication02.vue",
"content": "<script lang=\"ts\">\nexport const description\n = 'A login form with email and password. There\\'s an option to login with Google and a link to sign up if you don\\'t have an account.'\nexport const iframeHeight = '600px'\nexport const containerClass = 'w-full h-screen flex items-center justify-center px-4'\n</script>\n\n<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/registry/default/ui/card'\nimport { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\n</script>\n\n<template>\n <Card class=\"mx-auto max-w-sm\">\n <CardHeader>\n <CardTitle class=\"text-2xl\">\n Login\n </CardTitle>\n <CardDescription>\n Enter your email below to login to your account\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div class=\"grid gap-4\">\n <div class=\"grid gap-2\">\n <Label for=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"m@example.com\"\n required\n />\n </div>\n <div class=\"grid gap-2\">\n <div class=\"flex items-center\">\n <Label for=\"password\">Password</Label>\n <a href=\"#\" class=\"ml-auto inline-block text-sm underline\">\n Forgot your password?\n </a>\n </div>\n <Input id=\"password\" type=\"password\" required />\n </div>\n <Button type=\"submit\" class=\"w-full\">\n Login\n </Button>\n <Button variant=\"outline\" class=\"w-full\">\n Login with Google\n </Button>\n </div>\n <div class=\"mt-4 text-center text-sm\">\n Don't have an account?\n <a href=\"#\" class=\"underline\">\n Sign up\n </a>\n </div>\n </CardContent>\n </Card>\n</template>\n",
"type": "registry:block",
"target": "Authentication02.vue"
}
]
}

View File

@ -2,6 +2,18 @@
"name": "Authentication03",
"type": "registry:block",
"dependencies": [],
"registryDependencies": [],
"files": []
"registryDependencies": [
"button",
"card",
"input",
"label"
],
"files": [
{
"path": "block/Authentication03.vue",
"content": "<script lang=\"ts\">\nexport const description\n = 'A sign up form with first name, last name, email and password inside a card. There\\'s an option to sign up with GitHub and a link to login if you already have an account'\nexport const iframeHeight = '600px'\nexport const containerClass = 'w-full h-screen flex items-center justify-center px-4'\n</script>\n\n<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/registry/default/ui/card'\nimport { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\n</script>\n\n<template>\n <Card class=\"mx-auto max-w-sm\">\n <CardHeader>\n <CardTitle class=\"text-xl\">\n Sign Up\n </CardTitle>\n <CardDescription>\n Enter your information to create an account\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div class=\"grid gap-4\">\n <div class=\"grid grid-cols-2 gap-4\">\n <div class=\"grid gap-2\">\n <Label for=\"first-name\">First name</Label>\n <Input id=\"first-name\" placeholder=\"Max\" required />\n </div>\n <div class=\"grid gap-2\">\n <Label for=\"last-name\">Last name</Label>\n <Input id=\"last-name\" placeholder=\"Robinson\" required />\n </div>\n </div>\n <div class=\"grid gap-2\">\n <Label for=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"m@example.com\"\n required\n />\n </div>\n <div class=\"grid gap-2\">\n <Label for=\"password\">Password</Label>\n <Input id=\"password\" type=\"password\" />\n </div>\n <Button type=\"submit\" class=\"w-full\">\n Create an account\n </Button>\n <Button variant=\"outline\" class=\"w-full\">\n Sign up with GitHub\n </Button>\n </div>\n <div class=\"mt-4 text-center text-sm\">\n Already have an account?\n <a href=\"#\" class=\"underline\">\n Sign in\n </a>\n </div>\n </CardContent>\n </Card>\n</template>\n",
"type": "registry:block",
"target": "Authentication03.vue"
}
]
}

View File

@ -2,6 +2,17 @@
"name": "Authentication04",
"type": "registry:block",
"dependencies": [],
"registryDependencies": [],
"files": []
"registryDependencies": [
"button",
"input",
"label"
],
"files": [
{
"path": "block/Authentication04.vue",
"content": "<script lang=\"ts\">\nexport const description\n = 'A login page with two columns. The first column has the login form with email and password. There\\'s a Forgot your passwork link and a link to sign up if you do not have an account. The second column has a cover image.'\nexport const iframeHeight = '800px'\nexport const containerClass = 'w-full h-full p-4 lg:p-0'\n</script>\n\n<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\n</script>\n\n<template>\n <div class=\"w-full lg:grid lg:min-h-[600px] lg:grid-cols-2 xl:min-h-[800px]\">\n <div class=\"flex items-center justify-center py-12\">\n <div class=\"mx-auto grid w-[350px] gap-6\">\n <div class=\"grid gap-2 text-center\">\n <h1 class=\"text-3xl font-bold\">\n Login\n </h1>\n <p class=\"text-balance text-muted-foreground\">\n Enter your email below to login to your account\n </p>\n </div>\n <div class=\"grid gap-4\">\n <div class=\"grid gap-2\">\n <Label for=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"m@example.com\"\n required\n />\n </div>\n <div class=\"grid gap-2\">\n <div class=\"flex items-center\">\n <Label for=\"password\">Password</Label>\n <a\n href=\"/forgot-password\"\n class=\"ml-auto inline-block text-sm underline\"\n >\n Forgot your password?\n </a>\n </div>\n <Input id=\"password\" type=\"password\" required />\n </div>\n <Button type=\"submit\" class=\"w-full\">\n Login\n </Button>\n <Button variant=\"outline\" class=\"w-full\">\n Login with Google\n </Button>\n </div>\n <div class=\"mt-4 text-center text-sm\">\n Don't have an account?\n <a href=\"#\" class=\"underline\">\n Sign up\n </a>\n </div>\n </div>\n </div>\n <div class=\"hidden bg-muted lg:block\">\n <img\n src=\"/placeholder.svg\"\n alt=\"Image\"\n width=\"1920\"\n height=\"1080\"\n class=\"h-full w-full object-cover dark:brightness-[0.2] dark:grayscale\"\n >\n </div>\n </div>\n</template>\n",
"type": "registry:block",
"target": "Authentication04.vue"
}
]
}

View File

@ -7,17 +7,17 @@
"zod"
],
"registryDependencies": [
"utils",
"button",
"calendar",
"form",
"popover",
"toast",
"utils"
"toast"
],
"files": [
{
"path": "example/CalendarForm.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Calendar } from '@/registry/default/ui/calendar'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/default/ui/form'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover'\nimport { toast } from '@/registry/default/ui/toast'\nimport { cn } from '@/lib/utils'\nimport { CalendarDate, DateFormatter, getLocalTimeZone, parseDate, today } from '@internationalized/date'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { toDate } from 'reka-ui/date'\nimport { useForm } from 'vee-validate'\nimport { computed, h, ref } from 'vue'\nimport { z } from 'zod'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst formSchema = toTypedSchema(z.object({\n dob: z\n .string()\n .refine(v => v, { message: 'A date of birth is required.' }),\n}))\n\nconst placeholder = ref()\n\nconst { handleSubmit, setFieldValue, values } = useForm({\n validationSchema: formSchema,\n})\n\nconst value = computed({\n get: () => values.dob ? parseDate(values.dob) : undefined,\n set: val => val,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-8\" @submit=\"onSubmit\">\n <FormField name=\"dob\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\" :class=\"cn(\n 'w-[240px] ps-3 text-start font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <span>{{ value ? df.format(toDate(value)) : \"Pick a date\" }}</span>\n <CalendarIcon class=\"ms-auto h-4 w-4 opacity-50\" />\n </Button>\n <input hidden>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar\n v-model:placeholder=\"placeholder\"\n v-model=\"value\"\n calendar-label=\"Date of birth\"\n initial-focus\n :min-value=\"new CalendarDate(1900, 1, 1)\"\n :max-value=\"today(getLocalTimeZone())\"\n @update:model-value=\"(v) => {\n if (v) {\n setFieldValue('dob', v.toString())\n }\n else {\n setFieldValue('dob', undefined)\n }\n }\"\n />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\nimport { Calendar } from '@/registry/default/ui/calendar'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/default/ui/form'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover'\nimport { toast } from '@/registry/default/ui/toast'\nimport { CalendarDate, DateFormatter, getLocalTimeZone, parseDate, today } from '@internationalized/date'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { toDate } from 'reka-ui/date'\nimport { useForm } from 'vee-validate'\nimport { computed, h, ref } from 'vue'\nimport { z } from 'zod'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst formSchema = toTypedSchema(z.object({\n dob: z\n .string()\n .refine(v => v, { message: 'A date of birth is required.' }),\n}))\n\nconst placeholder = ref()\n\nconst { handleSubmit, setFieldValue, values } = useForm({\n validationSchema: formSchema,\n})\n\nconst value = computed({\n get: () => values.dob ? parseDate(values.dob) : undefined,\n set: val => val,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-8\" @submit=\"onSubmit\">\n <FormField name=\"dob\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\" :class=\"cn(\n 'w-[240px] ps-3 text-start font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <span>{{ value ? df.format(toDate(value)) : \"Pick a date\" }}</span>\n <CalendarIcon class=\"ms-auto h-4 w-4 opacity-50\" />\n </Button>\n <input hidden>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar\n v-model:placeholder=\"placeholder\"\n v-model=\"value\"\n calendar-label=\"Date of birth\"\n initial-focus\n :min-value=\"new CalendarDate(1900, 1, 1)\"\n :max-value=\"today(getLocalTimeZone())\"\n @update:model-value=\"(v) => {\n if (v) {\n setFieldValue('dob', v.toString())\n }\n else {\n setFieldValue('dob', undefined)\n }\n }\"\n />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
"type": "registry:example",
"target": "CalendarForm.vue"
}

View File

@ -5,14 +5,14 @@
"@vueuse/core"
],
"registryDependencies": [
"utils",
"calendar",
"select",
"utils"
"select"
],
"files": [
{
"path": "example/CalendarWithSelect.vue",
"content": "<script setup lang=\"ts\">\nimport { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, CalendarGridHead, CalendarGridRow, CalendarHeadCell, CalendarHeader, CalendarHeading } from '@/registry/default/ui/calendar'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/default/ui/select'\nimport { cn } from '@/lib/utils'\nimport { type DateValue, getLocalTimeZone, today } from '@internationalized/date'\nimport { useVModel } from '@vueuse/core'\nimport { CalendarRoot, type CalendarRootEmits, type CalendarRootProps, useDateFormatter, useForwardPropsEmits } from 'reka-ui'\nimport { createDecade, createYear, toDate } from 'reka-ui/date'\nimport { computed, type HTMLAttributes, type Ref } from 'vue'\n\nconst props = withDefaults(defineProps<CalendarRootProps & { class?: HTMLAttributes['class'] }>(), {\n modelValue: undefined,\n placeholder() {\n return today(getLocalTimeZone())\n },\n weekdayFormat: 'short',\n})\nconst emits = defineEmits<CalendarRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, placeholder: __, ...delegated } = props\n\n return delegated\n})\n\nconst placeholder = useVModel(props, 'modelValue', emits, {\n passive: true,\n defaultValue: today(getLocalTimeZone()),\n}) as Ref<DateValue>\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n\nconst formatter = useDateFormatter('en')\n</script>\n\n<template>\n <CalendarRoot\n v-slot=\"{ date, grid, weekDays }\"\n v-model:placeholder=\"placeholder\"\n v-bind=\"forwarded\"\n :class=\"cn('rounded-md border p-3', props.class)\"\n >\n <CalendarHeader>\n <CalendarHeading class=\"flex w-full items-center justify-between gap-2\">\n <Select\n :default-value=\"placeholder.month.toString()\"\n @update:model-value=\"(v) => {\n if (!v || !placeholder) return;\n if (Number(v) === placeholder?.month) return;\n placeholder = placeholder.set({\n month: Number(v),\n })\n }\"\n >\n <SelectTrigger aria-label=\"Select month\" class=\"w-[60%]\">\n <SelectValue placeholder=\"Select month\" />\n </SelectTrigger>\n <SelectContent class=\"max-h-[200px]\">\n <SelectItem\n v-for=\"month in createYear({ dateObj: date })\"\n :key=\"month.toString()\" :value=\"month.month.toString()\"\n >\n {{ formatter.custom(toDate(month), { month: 'long' }) }}\n </SelectItem>\n </SelectContent>\n </Select>\n\n <Select\n :default-value=\"placeholder.year.toString()\"\n @update:model-value=\"(v) => {\n if (!v || !placeholder) return;\n if (Number(v) === placeholder?.year) return;\n placeholder = placeholder.set({\n year: Number(v),\n })\n }\"\n >\n <SelectTrigger aria-label=\"Select year\" class=\"w-[40%]\">\n <SelectValue placeholder=\"Select year\" />\n </SelectTrigger>\n <SelectContent class=\"max-h-[200px]\">\n <SelectItem\n v-for=\"yearValue in createDecade({ dateObj: date, startIndex: -10, endIndex: 10 })\"\n :key=\"yearValue.toString()\" :value=\"yearValue.year.toString()\"\n >\n {{ yearValue.year }}\n </SelectItem>\n </SelectContent>\n </Select>\n </CalendarHeading>\n </CalendarHeader>\n\n <div class=\"flex flex-col space-y-4 pt-4 sm:flex-row sm:gap-x-4 sm:gap-y-0\">\n <CalendarGrid v-for=\"month in grid\" :key=\"month.value.toString()\">\n <CalendarGridHead>\n <CalendarGridRow>\n <CalendarHeadCell\n v-for=\"day in weekDays\" :key=\"day\"\n >\n {{ day }}\n </CalendarHeadCell>\n </CalendarGridRow>\n </CalendarGridHead>\n <CalendarGridBody class=\"grid\">\n <CalendarGridRow v-for=\"(weekDates, index) in month.rows\" :key=\"`weekDate-${index}`\" class=\"mt-2 w-full\">\n <CalendarCell\n v-for=\"weekDate in weekDates\"\n :key=\"weekDate.toString()\"\n :date=\"weekDate\"\n >\n <CalendarCellTrigger\n :day=\"weekDate\"\n :month=\"month.value\"\n />\n </CalendarCell>\n </CalendarGridRow>\n </CalendarGridBody>\n </CalendarGrid>\n </div>\n </CalendarRoot>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, CalendarGridHead, CalendarGridRow, CalendarHeadCell, CalendarHeader, CalendarHeading } from '@/registry/default/ui/calendar'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/default/ui/select'\nimport { type DateValue, getLocalTimeZone, today } from '@internationalized/date'\nimport { useVModel } from '@vueuse/core'\nimport { CalendarRoot, type CalendarRootEmits, type CalendarRootProps, useDateFormatter, useForwardPropsEmits } from 'reka-ui'\nimport { createDecade, createYear, toDate } from 'reka-ui/date'\nimport { computed, type HTMLAttributes, type Ref } from 'vue'\n\nconst props = withDefaults(defineProps<CalendarRootProps & { class?: HTMLAttributes['class'] }>(), {\n modelValue: undefined,\n placeholder() {\n return today(getLocalTimeZone())\n },\n weekdayFormat: 'short',\n})\nconst emits = defineEmits<CalendarRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, placeholder: __, ...delegated } = props\n\n return delegated\n})\n\nconst placeholder = useVModel(props, 'modelValue', emits, {\n passive: true,\n defaultValue: today(getLocalTimeZone()),\n}) as Ref<DateValue>\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n\nconst formatter = useDateFormatter('en')\n</script>\n\n<template>\n <CalendarRoot\n v-slot=\"{ date, grid, weekDays }\"\n v-model:placeholder=\"placeholder\"\n v-bind=\"forwarded\"\n :class=\"cn('rounded-md border p-3', props.class)\"\n >\n <CalendarHeader>\n <CalendarHeading class=\"flex w-full items-center justify-between gap-2\">\n <Select\n :default-value=\"placeholder.month.toString()\"\n @update:model-value=\"(v) => {\n if (!v || !placeholder) return;\n if (Number(v) === placeholder?.month) return;\n placeholder = placeholder.set({\n month: Number(v),\n })\n }\"\n >\n <SelectTrigger aria-label=\"Select month\" class=\"w-[60%]\">\n <SelectValue placeholder=\"Select month\" />\n </SelectTrigger>\n <SelectContent class=\"max-h-[200px]\">\n <SelectItem\n v-for=\"month in createYear({ dateObj: date })\"\n :key=\"month.toString()\" :value=\"month.month.toString()\"\n >\n {{ formatter.custom(toDate(month), { month: 'long' }) }}\n </SelectItem>\n </SelectContent>\n </Select>\n\n <Select\n :default-value=\"placeholder.year.toString()\"\n @update:model-value=\"(v) => {\n if (!v || !placeholder) return;\n if (Number(v) === placeholder?.year) return;\n placeholder = placeholder.set({\n year: Number(v),\n })\n }\"\n >\n <SelectTrigger aria-label=\"Select year\" class=\"w-[40%]\">\n <SelectValue placeholder=\"Select year\" />\n </SelectTrigger>\n <SelectContent class=\"max-h-[200px]\">\n <SelectItem\n v-for=\"yearValue in createDecade({ dateObj: date, startIndex: -10, endIndex: 10 })\"\n :key=\"yearValue.toString()\" :value=\"yearValue.year.toString()\"\n >\n {{ yearValue.year }}\n </SelectItem>\n </SelectContent>\n </Select>\n </CalendarHeading>\n </CalendarHeader>\n\n <div class=\"flex flex-col space-y-4 pt-4 sm:flex-row sm:gap-x-4 sm:gap-y-0\">\n <CalendarGrid v-for=\"month in grid\" :key=\"month.value.toString()\">\n <CalendarGridHead>\n <CalendarGridRow>\n <CalendarHeadCell\n v-for=\"day in weekDays\" :key=\"day\"\n >\n {{ day }}\n </CalendarHeadCell>\n </CalendarGridRow>\n </CalendarGridHead>\n <CalendarGridBody class=\"grid\">\n <CalendarGridRow v-for=\"(weekDates, index) in month.rows\" :key=\"`weekDate-${index}`\" class=\"mt-2 w-full\">\n <CalendarCell\n v-for=\"weekDate in weekDates\"\n :key=\"weekDate.toString()\"\n :date=\"weekDate\"\n >\n <CalendarCellTrigger\n :day=\"weekDate\"\n :month=\"month.value\"\n />\n </CalendarCell>\n </CalendarGridRow>\n </CalendarGridBody>\n </CalendarGrid>\n </div>\n </CalendarRoot>\n</template>\n",
"type": "registry:example",
"target": "CalendarWithSelect.vue"
}

File diff suppressed because one or more lines are too long

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"card",
"switch",
"utils"
"switch"
],
"files": [
{
"path": "example/CardDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n\nimport {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from '@/registry/default/ui/card'\nimport { Switch } from '@/registry/default/ui/switch'\nimport { cn } from '@/lib/utils'\nimport { BellRing, Check } from 'lucide-vue-next'\n\nconst notifications = [\n {\n title: 'Your call has been confirmed.',\n description: '1 hour ago',\n },\n {\n title: 'You have a new message!',\n description: '1 hour ago',\n },\n {\n title: 'Your subscription is expiring soon!',\n description: '2 hours ago',\n },\n]\n</script>\n\n<template>\n <Card :class=\"cn('w-[380px]', $attrs.class ?? '')\">\n <CardHeader>\n <CardTitle>Notifications</CardTitle>\n <CardDescription>You have 3 unread messages.</CardDescription>\n </CardHeader>\n <CardContent class=\"grid gap-4\">\n <div class=\" flex items-center space-x-4 rounded-md border p-4\">\n <BellRing />\n <div class=\"flex-1 space-y-1\">\n <p class=\"text-sm font-medium leading-none\">\n Push Notifications\n </p>\n <p class=\"text-sm text-muted-foreground\">\n Send notifications to device.\n </p>\n </div>\n <Switch />\n </div>\n <div>\n <div\n v-for=\"(notification, index) in notifications\" :key=\"index\"\n class=\"mb-4 grid grid-cols-[25px_minmax(0,1fr)] items-start pb-4 last:mb-0 last:pb-0\"\n >\n <span class=\"flex h-2 w-2 translate-y-1 rounded-full bg-sky-500\" />\n <div class=\"space-y-1\">\n <p class=\"text-sm font-medium leading-none\">\n {{ notification.title }}\n </p>\n <p class=\"text-sm text-muted-foreground\">\n {{ notification.description }}\n </p>\n </div>\n </div>\n </div>\n </CardContent>\n <CardFooter>\n <Button class=\"w-full\">\n <Check class=\"mr-2 h-4 w-4\" /> Mark all as read\n </Button>\n </CardFooter>\n </Card>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from '@/registry/default/ui/card'\nimport { Switch } from '@/registry/default/ui/switch'\nimport { BellRing, Check } from 'lucide-vue-next'\n\nconst notifications = [\n {\n title: 'Your call has been confirmed.',\n description: '1 hour ago',\n },\n {\n title: 'You have a new message!',\n description: '1 hour ago',\n },\n {\n title: 'Your subscription is expiring soon!',\n description: '2 hours ago',\n },\n]\n</script>\n\n<template>\n <Card :class=\"cn('w-[380px]', $attrs.class ?? '')\">\n <CardHeader>\n <CardTitle>Notifications</CardTitle>\n <CardDescription>You have 3 unread messages.</CardDescription>\n </CardHeader>\n <CardContent class=\"grid gap-4\">\n <div class=\" flex items-center space-x-4 rounded-md border p-4\">\n <BellRing />\n <div class=\"flex-1 space-y-1\">\n <p class=\"text-sm font-medium leading-none\">\n Push Notifications\n </p>\n <p class=\"text-sm text-muted-foreground\">\n Send notifications to device.\n </p>\n </div>\n <Switch />\n </div>\n <div>\n <div\n v-for=\"(notification, index) in notifications\" :key=\"index\"\n class=\"mb-4 grid grid-cols-[25px_minmax(0,1fr)] items-start pb-4 last:mb-0 last:pb-0\"\n >\n <span class=\"flex h-2 w-2 translate-y-1 rounded-full bg-sky-500\" />\n <div class=\"space-y-1\">\n <p class=\"text-sm font-medium leading-none\">\n {{ notification.title }}\n </p>\n <p class=\"text-sm text-muted-foreground\">\n {{ notification.description }}\n </p>\n </div>\n </div>\n </div>\n </CardContent>\n <CardFooter>\n <Button class=\"w-full\">\n <Check class=\"mr-2 h-4 w-4\" /> Mark all as read\n </Button>\n </CardFooter>\n </Card>\n</template>\n",
"type": "registry:example",
"target": "CardDemo.vue"
}

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"command",
"popover",
"utils"
"popover"
],
"files": [
{
"path": "example/ComboboxDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/registry/default/ui/command'\n\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\nimport { cn } from '@/lib/utils'\nimport { Check, ChevronsUpDown } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst frameworks = [\n { value: 'next.js', label: 'Next.js' },\n { value: 'sveltekit', label: 'SvelteKit' },\n { value: 'nuxt', label: 'Nuxt' },\n { value: 'remix', label: 'Remix' },\n { value: 'astro', label: 'Astro' },\n]\n\nconst open = ref(false)\nconst value = ref('')\n</script>\n\n<template>\n <Popover v-model:open=\"open\">\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n :aria-expanded=\"open\"\n class=\"w-[200px] justify-between\"\n >\n {{ value\n ? frameworks.find((framework) => framework.value === value)?.label\n : \"Select framework...\" }}\n <ChevronsUpDown class=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-[200px] p-0\">\n <Command>\n <CommandInput class=\"h-9\" placeholder=\"Search framework...\" />\n <CommandEmpty>No framework found.</CommandEmpty>\n <CommandList>\n <CommandGroup>\n <CommandItem\n v-for=\"framework in frameworks\"\n :key=\"framework.value\"\n :value=\"framework.value\"\n @select=\"(ev) => {\n if (typeof ev.detail.value === 'string') {\n value = ev.detail.value\n }\n open = false\n }\"\n >\n {{ framework.label }}\n <Check\n :class=\"cn(\n 'ml-auto h-4 w-4',\n value === framework.value ? 'opacity-100' : 'opacity-0',\n )\"\n />\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\n\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/registry/default/ui/command'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\nimport { Check, ChevronsUpDown } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst frameworks = [\n { value: 'next.js', label: 'Next.js' },\n { value: 'sveltekit', label: 'SvelteKit' },\n { value: 'nuxt', label: 'Nuxt' },\n { value: 'remix', label: 'Remix' },\n { value: 'astro', label: 'Astro' },\n]\n\nconst open = ref(false)\nconst value = ref('')\n</script>\n\n<template>\n <Popover v-model:open=\"open\">\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n :aria-expanded=\"open\"\n class=\"w-[200px] justify-between\"\n >\n {{ value\n ? frameworks.find((framework) => framework.value === value)?.label\n : \"Select framework...\" }}\n <ChevronsUpDown class=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-[200px] p-0\">\n <Command>\n <CommandInput class=\"h-9\" placeholder=\"Search framework...\" />\n <CommandEmpty>No framework found.</CommandEmpty>\n <CommandList>\n <CommandGroup>\n <CommandItem\n v-for=\"framework in frameworks\"\n :key=\"framework.value\"\n :value=\"framework.value\"\n @select=\"(ev) => {\n if (typeof ev.detail.value === 'string') {\n value = ev.detail.value\n }\n open = false\n }\"\n >\n {{ framework.label }}\n <Check\n :class=\"cn(\n 'ml-auto h-4 w-4',\n value === framework.value ? 'opacity-100' : 'opacity-0',\n )\"\n />\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "ComboboxDemo.vue"
}

View File

@ -7,17 +7,17 @@
"zod"
],
"registryDependencies": [
"utils",
"button",
"command",
"form",
"popover",
"toast",
"utils"
"toast"
],
"files": [
{
"path": "example/ComboboxForm.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/registry/default/ui/command'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/default/ui/form'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\n\nimport { toast } from '@/registry/default/ui/toast'\nimport { cn } from '@/lib/utils'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { Check, ChevronsUpDown } from 'lucide-vue-next'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst languages = [\n { label: 'English', value: 'en' },\n { label: 'French', value: 'fr' },\n { label: 'German', value: 'de' },\n { label: 'Spanish', value: 'es' },\n { label: 'Portuguese', value: 'pt' },\n { label: 'Russian', value: 'ru' },\n { label: 'Japanese', value: 'ja' },\n { label: 'Korean', value: 'ko' },\n { label: 'Chinese', value: 'zh' },\n]\n\nconst formSchema = toTypedSchema(z.object({\n language: z.string({\n required_error: 'Please select a language.',\n }),\n}))\n\nconst { handleSubmit, setFieldValue, values } = useForm({\n validationSchema: formSchema,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-6\" @submit=\"onSubmit\">\n <FormField name=\"language\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Language</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n :class=\"cn('w-[200px] justify-between', !values.language && 'text-muted-foreground')\"\n >\n {{ values.language ? languages.find(\n (language) => language.value === values.language,\n )?.label : 'Select language...' }}\n <ChevronsUpDown class=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"w-[200px] p-0\">\n <Command>\n <CommandInput placeholder=\"Search language...\" />\n <CommandEmpty>Nothing found.</CommandEmpty>\n <CommandList>\n <CommandGroup>\n <CommandItem\n v-for=\"language in languages\"\n :key=\"language.value\"\n :value=\"language.label\"\n @select=\"() => {\n setFieldValue('language', language.value)\n }\"\n >\n <Check\n :class=\"cn('mr-2 h-4 w-4', language.value === values.language ? 'opacity-100' : 'opacity-0')\"\n />\n {{ language.label }}\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n <FormDescription>\n This is the language that will be used in the dashboard.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <Button type=\"submit\">\n Submit\n </Button>\n </form>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/registry/default/ui/command'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/default/ui/form'\n\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\nimport { toast } from '@/registry/default/ui/toast'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { Check, ChevronsUpDown } from 'lucide-vue-next'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst languages = [\n { label: 'English', value: 'en' },\n { label: 'French', value: 'fr' },\n { label: 'German', value: 'de' },\n { label: 'Spanish', value: 'es' },\n { label: 'Portuguese', value: 'pt' },\n { label: 'Russian', value: 'ru' },\n { label: 'Japanese', value: 'ja' },\n { label: 'Korean', value: 'ko' },\n { label: 'Chinese', value: 'zh' },\n]\n\nconst formSchema = toTypedSchema(z.object({\n language: z.string({\n required_error: 'Please select a language.',\n }),\n}))\n\nconst { handleSubmit, setFieldValue, values } = useForm({\n validationSchema: formSchema,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-6\" @submit=\"onSubmit\">\n <FormField name=\"language\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Language</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n :class=\"cn('w-[200px] justify-between', !values.language && 'text-muted-foreground')\"\n >\n {{ values.language ? languages.find(\n (language) => language.value === values.language,\n )?.label : 'Select language...' }}\n <ChevronsUpDown class=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"w-[200px] p-0\">\n <Command>\n <CommandInput placeholder=\"Search language...\" />\n <CommandEmpty>Nothing found.</CommandEmpty>\n <CommandList>\n <CommandGroup>\n <CommandItem\n v-for=\"language in languages\"\n :key=\"language.value\"\n :value=\"language.label\"\n @select=\"() => {\n setFieldValue('language', language.value)\n }\"\n >\n <Check\n :class=\"cn('mr-2 h-4 w-4', language.value === values.language ? 'opacity-100' : 'opacity-0')\"\n />\n {{ language.label }}\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n <FormDescription>\n This is the language that will be used in the dashboard.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <Button type=\"submit\">\n Submit\n </Button>\n </form>\n</template>\n",
"type": "registry:example",
"target": "ComboboxForm.vue"
}

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"command",
"popover",
"utils"
"popover"
],
"files": [
{
"path": "example/ComboboxPopover.vue",
"content": "<script setup lang=\"ts\">\nimport type { Icon } from 'lucide-vue-next'\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/registry/default/ui/command'\n\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\nimport { cn } from '@/lib/utils'\nimport {\n ArrowUpCircle,\n CheckCircle2,\n Circle,\n HelpCircle,\n XCircle,\n} from 'lucide-vue-next'\nimport { ref } from 'vue'\n\ninterface Status {\n value: string\n label: string\n icon: Icon\n}\n\nconst statuses: Status[] = [\n {\n value: 'backlog',\n label: 'Backlog',\n icon: HelpCircle,\n },\n {\n value: 'todo',\n label: 'Todo',\n icon: Circle,\n },\n {\n value: 'in progress',\n label: 'In Progress',\n icon: ArrowUpCircle,\n },\n {\n value: 'done',\n label: 'Done',\n icon: CheckCircle2,\n },\n {\n value: 'canceled',\n label: 'Canceled',\n icon: XCircle,\n },\n]\n\nconst open = ref(false)\n// const value = ref<typeof statuses[number]>()\n\nconst selectedStatus = ref<Status>()\n</script>\n\n<template>\n <div class=\"flex items-center space-x-4\">\n <p class=\"text-sm text-muted-foreground\">\n Status\n </p>\n <Popover v-model:open=\"open\">\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n size=\"sm\"\n class=\"w-[150px] justify-start\"\n >\n <template v-if=\"selectedStatus\">\n <component :is=\"selectedStatus?.icon\" class=\"mr-2 h-4 w-4 shrink-0\" />\n {{ selectedStatus?.label }}\n </template>\n <template v-else>\n + Set status\n </template>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"p-0\" side=\"right\" align=\"start\">\n <Command>\n <CommandInput placeholder=\"Change status...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup>\n <CommandItem\n v-for=\"status in statuses\"\n :key=\"status.value\"\n :value=\"status.value\"\n @select=\"(value) => {\n selectedStatus = status\n open = false\n }\"\n >\n <component\n :is=\"status.icon\"\n :key=\"status.value\"\n :class=\"cn('mr-2 h-4 w-4', status.value === selectedStatus?.value ? 'opacity-100' : 'opacity-40',\n )\"\n />\n <span>{{ status.label }}</span>\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { Icon } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\n\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/registry/default/ui/command'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\nimport {\n ArrowUpCircle,\n CheckCircle2,\n Circle,\n HelpCircle,\n XCircle,\n} from 'lucide-vue-next'\nimport { ref } from 'vue'\n\ninterface Status {\n value: string\n label: string\n icon: Icon\n}\n\nconst statuses: Status[] = [\n {\n value: 'backlog',\n label: 'Backlog',\n icon: HelpCircle,\n },\n {\n value: 'todo',\n label: 'Todo',\n icon: Circle,\n },\n {\n value: 'in progress',\n label: 'In Progress',\n icon: ArrowUpCircle,\n },\n {\n value: 'done',\n label: 'Done',\n icon: CheckCircle2,\n },\n {\n value: 'canceled',\n label: 'Canceled',\n icon: XCircle,\n },\n]\n\nconst open = ref(false)\n// const value = ref<typeof statuses[number]>()\n\nconst selectedStatus = ref<Status>()\n</script>\n\n<template>\n <div class=\"flex items-center space-x-4\">\n <p class=\"text-sm text-muted-foreground\">\n Status\n </p>\n <Popover v-model:open=\"open\">\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n size=\"sm\"\n class=\"w-[150px] justify-start\"\n >\n <template v-if=\"selectedStatus\">\n <component :is=\"selectedStatus?.icon\" class=\"mr-2 h-4 w-4 shrink-0\" />\n {{ selectedStatus?.label }}\n </template>\n <template v-else>\n + Set status\n </template>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"p-0\" side=\"right\" align=\"start\">\n <Command>\n <CommandInput placeholder=\"Change status...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup>\n <CommandItem\n v-for=\"status in statuses\"\n :key=\"status.value\"\n :value=\"status.value\"\n @select=\"(value) => {\n selectedStatus = status\n open = false\n }\"\n >\n <component\n :is=\"status.icon\"\n :key=\"status.value\"\n :class=\"cn('mr-2 h-4 w-4', status.value === selectedStatus?.value ? 'opacity-100' : 'opacity-40',\n )\"\n />\n <span>{{ status.label }}</span>\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </div>\n</template>\n",
"type": "registry:example",
"target": "ComboboxPopover.vue"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"calendar",
"popover",
"utils"
"popover"
],
"files": [
{
"path": "example/DatePickerDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Calendar } from '@/registry/default/ui/calendar'\n\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover'\nimport { cn } from '@/lib/utils'\nimport {\n DateFormatter,\n type DateValue,\n getLocalTimeZone,\n} from '@internationalized/date'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst value = ref<DateValue>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n {{ value ? df.format(value.toDate(getLocalTimeZone())) : \"Pick a date\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar v-model=\"value\" initial-focus />\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\n\nimport { Calendar } from '@/registry/default/ui/calendar'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover'\nimport {\n DateFormatter,\n type DateValue,\n getLocalTimeZone,\n} from '@internationalized/date'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst value = ref<DateValue>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n {{ value ? df.format(value.toDate(getLocalTimeZone())) : \"Pick a date\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar v-model=\"value\" initial-focus />\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "DatePickerDemo.vue"
}

View File

@ -7,17 +7,17 @@
"zod"
],
"registryDependencies": [
"utils",
"button",
"calendar",
"form",
"popover",
"toast",
"utils"
"toast"
],
"files": [
{
"path": "example/DatePickerForm.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Calendar } from '@/registry/default/ui/calendar'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/default/ui/form'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover'\nimport { toast } from '@/registry/default/ui/toast'\nimport { cn } from '@/lib/utils'\nimport { CalendarDate, DateFormatter, getLocalTimeZone, parseDate, today } from '@internationalized/date'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { toDate } from 'reka-ui/date'\nimport { useForm } from 'vee-validate'\nimport { computed, h, ref } from 'vue'\nimport { z } from 'zod'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst formSchema = toTypedSchema(z.object({\n dob: z\n .string()\n .refine(v => v, { message: 'A date of birth is required.' }),\n}))\n\nconst placeholder = ref()\n\nconst { handleSubmit, setFieldValue, values } = useForm({\n validationSchema: formSchema,\n initialValues: {\n\n },\n})\n\nconst value = computed({\n get: () => values.dob ? parseDate(values.dob) : undefined,\n set: val => val,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-8\" @submit=\"onSubmit\">\n <FormField name=\"dob\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\" :class=\"cn(\n 'w-[240px] ps-3 text-start font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <span>{{ value ? df.format(toDate(value)) : \"Pick a date\" }}</span>\n <CalendarIcon class=\"ms-auto h-4 w-4 opacity-50\" />\n </Button>\n <input hidden>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar\n v-model:placeholder=\"placeholder\"\n v-model=\"value\"\n calendar-label=\"Date of birth\"\n initial-focus\n :min-value=\"new CalendarDate(1900, 1, 1)\"\n :max-value=\"today(getLocalTimeZone())\"\n @update:model-value=\"(v) => {\n if (v) {\n setFieldValue('dob', v.toString())\n }\n else {\n setFieldValue('dob', undefined)\n }\n\n }\"\n />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\nimport { Calendar } from '@/registry/default/ui/calendar'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/default/ui/form'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover'\nimport { toast } from '@/registry/default/ui/toast'\nimport { CalendarDate, DateFormatter, getLocalTimeZone, parseDate, today } from '@internationalized/date'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { toDate } from 'reka-ui/date'\nimport { useForm } from 'vee-validate'\nimport { computed, h, ref } from 'vue'\nimport { z } from 'zod'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst formSchema = toTypedSchema(z.object({\n dob: z\n .string()\n .refine(v => v, { message: 'A date of birth is required.' }),\n}))\n\nconst placeholder = ref()\n\nconst { handleSubmit, setFieldValue, values } = useForm({\n validationSchema: formSchema,\n initialValues: {\n\n },\n})\n\nconst value = computed({\n get: () => values.dob ? parseDate(values.dob) : undefined,\n set: val => val,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-8\" @submit=\"onSubmit\">\n <FormField name=\"dob\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\" :class=\"cn(\n 'w-[240px] ps-3 text-start font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <span>{{ value ? df.format(toDate(value)) : \"Pick a date\" }}</span>\n <CalendarIcon class=\"ms-auto h-4 w-4 opacity-50\" />\n </Button>\n <input hidden>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar\n v-model:placeholder=\"placeholder\"\n v-model=\"value\"\n calendar-label=\"Date of birth\"\n initial-focus\n :min-value=\"new CalendarDate(1900, 1, 1)\"\n :max-value=\"today(getLocalTimeZone())\"\n @update:model-value=\"(v) => {\n if (v) {\n setFieldValue('dob', v.toString())\n }\n else {\n setFieldValue('dob', undefined)\n }\n\n }\"\n />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
"type": "registry:example",
"target": "DatePickerForm.vue"
}

File diff suppressed because one or more lines are too long

View File

@ -3,16 +3,16 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"calendar",
"popover",
"select",
"utils"
"select"
],
"files": [
{
"path": "example/DatePickerWithPresets.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Calendar } from '@/registry/default/ui/calendar'\n\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/registry/default/ui/select'\nimport { cn } from '@/lib/utils'\nimport {\n DateFormatter,\n type DateValue,\n getLocalTimeZone,\n today,\n} from '@internationalized/date'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst items = [\n { value: 0, label: 'Today' },\n { value: 1, label: 'Tomorrow' },\n { value: 3, label: 'In 3 days' },\n { value: 7, label: 'In a week' },\n]\n\nconst value = ref<DateValue>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n {{ value ? df.format(value.toDate(getLocalTimeZone())) : \"Pick a date\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"flex w-auto flex-col gap-y-2 p-2\">\n <Select\n @update:model-value=\"(v) => {\n if (!v) return;\n value = today(getLocalTimeZone()).add({ days: Number(v) });\n }\"\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Select\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem v-for=\"item in items\" :key=\"item.value\" :value=\"item.value.toString()\">\n {{ item.label }}\n </SelectItem>\n </SelectContent>\n </Select>\n <Calendar v-model=\"value\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\n\nimport { Calendar } from '@/registry/default/ui/calendar'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/registry/default/ui/select'\nimport {\n DateFormatter,\n type DateValue,\n getLocalTimeZone,\n today,\n} from '@internationalized/date'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst items = [\n { value: 0, label: 'Today' },\n { value: 1, label: 'Tomorrow' },\n { value: 3, label: 'In 3 days' },\n { value: 7, label: 'In a week' },\n]\n\nconst value = ref<DateValue>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n {{ value ? df.format(value.toDate(getLocalTimeZone())) : \"Pick a date\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"flex w-auto flex-col gap-y-2 p-2\">\n <Select\n @update:model-value=\"(v) => {\n if (!v) return;\n value = today(getLocalTimeZone()).add({ days: Number(v) });\n }\"\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Select\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem v-for=\"item in items\" :key=\"item.value\" :value=\"item.value.toString()\">\n {{ item.label }}\n </SelectItem>\n </SelectContent>\n </Select>\n <Calendar v-model=\"value\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "DatePickerWithPresets.vue"
}

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"popover",
"range-calendar",
"utils"
"range-calendar"
],
"files": [
{
"path": "example/DatePickerWithRange.vue",
"content": "<script setup lang=\"ts\">\nimport type { DateRange } from 'reka-ui'\nimport { Button } from '@/registry/default/ui/button'\n\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover'\nimport { RangeCalendar } from '@/registry/default/ui/range-calendar'\nimport { cn } from '@/lib/utils'\nimport {\n CalendarDate,\n DateFormatter,\n getLocalTimeZone,\n} from '@internationalized/date'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { type Ref, ref } from 'vue'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'medium',\n})\n\nconst value = ref({\n start: new CalendarDate(2022, 1, 20),\n end: new CalendarDate(2022, 1, 20).add({ days: 20 }),\n}) as Ref<DateRange>\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <template v-if=\"value.start\">\n <template v-if=\"value.end\">\n {{ df.format(value.start.toDate(getLocalTimeZone())) }} - {{ df.format(value.end.toDate(getLocalTimeZone())) }}\n </template>\n\n <template v-else>\n {{ df.format(value.start.toDate(getLocalTimeZone())) }}\n </template>\n </template>\n <template v-else>\n Pick a date\n </template>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <RangeCalendar v-model=\"value\" initial-focus :number-of-months=\"2\" @update:start-value=\"(startDate) => value.start = startDate\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { DateRange } from 'reka-ui'\nimport { cn } from '@/lib/utils'\n\nimport { Button } from '@/registry/default/ui/button'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover'\nimport { RangeCalendar } from '@/registry/default/ui/range-calendar'\nimport {\n CalendarDate,\n DateFormatter,\n getLocalTimeZone,\n} from '@internationalized/date'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { type Ref, ref } from 'vue'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'medium',\n})\n\nconst value = ref({\n start: new CalendarDate(2022, 1, 20),\n end: new CalendarDate(2022, 1, 20).add({ days: 20 }),\n}) as Ref<DateRange>\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <template v-if=\"value.start\">\n <template v-if=\"value.end\">\n {{ df.format(value.start.toDate(getLocalTimeZone())) }} - {{ df.format(value.end.toDate(getLocalTimeZone())) }}\n </template>\n\n <template v-else>\n {{ df.format(value.start.toDate(getLocalTimeZone())) }}\n </template>\n </template>\n <template v-else>\n Pick a date\n </template>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <RangeCalendar v-model=\"value\" initial-focus :number-of-months=\"2\" @update:start-value=\"(startDate) => value.start = startDate\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "DatePickerWithRange.vue"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,13 +3,13 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"slider",
"utils"
"utils",
"slider"
],
"files": [
{
"path": "example/SliderDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { Slider } from '@/registry/default/ui/slider'\nimport { cn } from '@/lib/utils'\nimport { ref } from 'vue'\n\nconst modelValue = ref([50])\n</script>\n\n<template>\n <Slider\n v-model=\"modelValue\"\n :max=\"100\"\n :step=\"1\"\n :class=\"cn('w-3/5', $attrs.class ?? '')\"\n />\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Slider } from '@/registry/default/ui/slider'\nimport { ref } from 'vue'\n\nconst modelValue = ref([50])\n</script>\n\n<template>\n <Slider\n v-model=\"modelValue\"\n :max=\"100\"\n :step=\"1\"\n :class=\"cn('w-3/5', $attrs.class ?? '')\"\n />\n</template>\n",
"type": "registry:example",
"target": "SliderDemo.vue"
}

View File

@ -10,7 +10,7 @@
"files": [
{
"path": "example/SonnerDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { toast } from 'vue-sonner'\n</script>\n\n<template>\n <Button\n variant=\"outline\" @click=\"() => {\n toast('Event has been created', {\n description: 'Sunday, December 03, 2023 at 9:00 AM',\n action: {\n label: 'Undo',\n onClick: () => console.log('Undo'),\n },\n })\n }\"\n >\n Add to calendar\n </Button>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { toast } from 'vue-sonner'\n</script>\n\n<template>\n <Button\n variant=\"outline\"\n @click=\"\n () => {\n toast('Event has been created', {\n description: 'Sunday, December 03, 2023 at 9:00 AM',\n action: {\n label: 'Undo',\n onClick: () => console.log('Undo'),\n },\n });\n }\n \"\n >\n Add to calendar\n </Button>\n</template>\n",
"type": "registry:example",
"target": "SonnerDemo.vue"
}

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"popover",
"v-calendar",
"utils"
"v-calendar"
],
"files": [
{
"path": "example/VDatePickerDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\n\nimport { Calendar } from '@/registry/default/ui/v-calendar'\nimport { cn } from '@/lib/utils'\nimport { format } from 'date-fns'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst date = ref<Date>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <span>{{ date ? format(date, \"PPP\") : \"Pick a date\" }}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar v-model=\"date\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\n\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\nimport { Calendar } from '@/registry/default/ui/v-calendar'\nimport { format } from 'date-fns'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst date = ref<Date>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <span>{{ date ? format(date, \"PPP\") : \"Pick a date\" }}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar v-model=\"date\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "VDatePickerDemo.vue"
}

View File

@ -7,17 +7,17 @@
"zod"
],
"registryDependencies": [
"utils",
"button",
"form",
"popover",
"toast",
"v-calendar",
"utils"
"v-calendar"
],
"files": [
{
"path": "example/VDatePickerForm.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/default/ui/form'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\nimport { toast } from '@/registry/default/ui/toast'\nimport { Calendar } from '@/registry/default/ui/v-calendar'\nimport { cn } from '@/lib/utils'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { format } from 'date-fns'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { useForm } from 'vee-validate'\n\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n dob: z.date({\n required_error: 'A date of birth is required.',\n }),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-8\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField, value }\" name=\"dob\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\" :class=\"cn(\n 'w-[240px] ps-3 text-start font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <span>{{ value ? format(value, \"PPP\") : \"Pick a date\" }}</span>\n <CalendarIcon class=\"ms-auto h-4 w-4 opacity-50\" />\n </Button>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"p-0\">\n <Calendar v-bind=\"componentField\" />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/default/ui/form'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\nimport { toast } from '@/registry/default/ui/toast'\nimport { Calendar } from '@/registry/default/ui/v-calendar'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { format } from 'date-fns'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { useForm } from 'vee-validate'\n\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n dob: z.date({\n required_error: 'A date of birth is required.',\n }),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-8\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField, value }\" name=\"dob\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\" :class=\"cn(\n 'w-[240px] ps-3 text-start font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <span>{{ value ? format(value, \"PPP\") : \"Pick a date\" }}</span>\n <CalendarIcon class=\"ms-auto h-4 w-4 opacity-50\" />\n </Button>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"p-0\">\n <Calendar v-bind=\"componentField\" />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
"type": "registry:example",
"target": "VDatePickerForm.vue"
}

View File

@ -3,16 +3,16 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"popover",
"select",
"v-calendar",
"utils"
"v-calendar"
],
"files": [
{
"path": "example/VDatePickerWithPresets.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\n\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/default/ui/select'\nimport { Calendar } from '@/registry/default/ui/v-calendar'\nimport { cn } from '@/lib/utils'\nimport { addDays, format } from 'date-fns'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst date = ref<Date>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <template v-if=\"date\">\n {{ format(date, \"PPP\") }}\n </template>\n <template v-else>\n <span>Pick a date</span>\n </template>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"flex w-auto flex-col space-y-2 p-2\">\n <Select\n @update:model-value=\"(value) => {\n date = addDays(new Date(), parseInt(value))\n }\"\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Select\" />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectItem value=\"0\">\n Today\n </SelectItem>\n <SelectItem value=\"1\">\n Tomorrow\n </SelectItem>\n <SelectItem value=\"3\">\n In 3 days\n </SelectItem>\n <SelectItem value=\"7\">\n In a week\n </SelectItem>\n </SelectContent>\n </Select>\n <div class=\"rounded-md border\">\n <Calendar v-model=\"date\" mode=\"single\" />\n </div>\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\n\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/default/ui/select'\nimport { Calendar } from '@/registry/default/ui/v-calendar'\nimport { addDays, format } from 'date-fns'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst date = ref<Date>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <template v-if=\"date\">\n {{ format(date, \"PPP\") }}\n </template>\n <template v-else>\n <span>Pick a date</span>\n </template>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"flex w-auto flex-col space-y-2 p-2\">\n <Select\n @update:model-value=\"(value) => {\n date = addDays(new Date(), parseInt(value))\n }\"\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Select\" />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectItem value=\"0\">\n Today\n </SelectItem>\n <SelectItem value=\"1\">\n Tomorrow\n </SelectItem>\n <SelectItem value=\"3\">\n In 3 days\n </SelectItem>\n <SelectItem value=\"7\">\n In a week\n </SelectItem>\n </SelectContent>\n </Select>\n <div class=\"rounded-md border\">\n <Calendar v-model=\"date\" mode=\"single\" />\n </div>\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "VDatePickerWithPresets.vue"
}

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"popover",
"v-calendar",
"utils"
"v-calendar"
],
"files": [
{
"path": "example/VDatePickerWithRange.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\n\nimport { Calendar } from '@/registry/default/ui/v-calendar'\nimport { cn } from '@/lib/utils'\nimport { addDays, format } from 'date-fns'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst date = ref({\n start: new Date(2022, 0, 20),\n end: addDays(new Date(2022, 0, 20), 20),\n})\n</script>\n\n<template>\n <div :class=\"cn('grid gap-2', $attrs.class ?? '')\">\n <Popover>\n <PopoverTrigger as-child>\n <Button\n id=\"date\"\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n\n <span>\n {{ date.start ? (\n date.end ? `${format(date.start, 'LLL dd, y')} - ${format(date.end, 'LLL dd, y')}`\n : format(date.start, 'LLL dd, y')\n ) : 'Pick a date' }}\n </span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\" align=\"start\">\n <Calendar\n v-model.range=\"date\"\n :columns=\"2\"\n />\n </PopoverContent>\n </Popover>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\n\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\nimport { Calendar } from '@/registry/default/ui/v-calendar'\nimport { addDays, format } from 'date-fns'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst date = ref({\n start: new Date(2022, 0, 20),\n end: addDays(new Date(2022, 0, 20), 20),\n})\n</script>\n\n<template>\n <div :class=\"cn('grid gap-2', $attrs.class ?? '')\">\n <Popover>\n <PopoverTrigger as-child>\n <Button\n id=\"date\"\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n\n <span>\n {{ date.start ? (\n date.end ? `${format(date.start, 'LLL dd, y')} - ${format(date.end, 'LLL dd, y')}`\n : format(date.start, 'LLL dd, y')\n ) : 'Pick a date' }}\n </span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\" align=\"start\">\n <Calendar\n v-model.range=\"date\"\n :columns=\"2\"\n />\n </PopoverContent>\n </Popover>\n </div>\n</template>\n",
"type": "registry:example",
"target": "VDatePickerWithRange.vue"
}

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"popover",
"v-calendar",
"utils"
"v-calendar"
],
"files": [
{
"path": "example/VDateTimePickerDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\n\nimport { Calendar } from '@/registry/default/ui/v-calendar'\nimport { cn } from '@/lib/utils'\nimport { format } from 'date-fns'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst date = ref<Date>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <span>{{ date ? format(date, 'PPP - hh:mm') : \"Pick a date\" }}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar v-model=\"date\" mode=\"datetime\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\n\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\nimport { Calendar } from '@/registry/default/ui/v-calendar'\nimport { format } from 'date-fns'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst date = ref<Date>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <span>{{ date ? format(date, 'PPP - hh:mm') : \"Pick a date\" }}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar v-model=\"date\" mode=\"datetime\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "VDateTimePickerDemo.vue"
}

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"popover",
"v-calendar",
"utils"
"v-calendar"
],
"files": [
{
"path": "example/VRangePickerWithSlot.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\n\nimport { Calendar } from '@/registry/default/ui/v-calendar'\nimport { cn } from '@/lib/utils'\nimport { addDays, format } from 'date-fns'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst date = ref({\n start: new Date(2022, 0, 20),\n end: addDays(new Date(2022, 0, 20), 20),\n})\n</script>\n\n<template>\n <div :class=\"cn('grid gap-2', $attrs.class ?? '')\">\n <Popover>\n <PopoverTrigger as-child>\n <Button\n id=\"date\"\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n\n <span>\n {{ date.start ? (\n date.end ? `${format(date.start, 'LLL dd, y')} - ${format(date.end, 'LLL dd, y')}`\n : format(date.start, 'LLL dd, y')\n ) : 'Pick a date' }}\n </span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\" align=\"start\">\n <Calendar\n v-model.range=\"date\"\n mode=\"date\"\n :columns=\"2\"\n >\n <template #footer>\n <div class=\"w-full px-3 pb-3\">\n Entry time\n <Calendar\n v-model=\"date.start\"\n mode=\"time\"\n hide-time-header\n />\n Exit time\n <Calendar\n v-model=\"date.end\"\n mode=\"time\"\n hide-time-header\n />\n </div>\n </template>\n </Calendar>\n </PopoverContent>\n </Popover>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\n\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\nimport { Calendar } from '@/registry/default/ui/v-calendar'\nimport { addDays, format } from 'date-fns'\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst date = ref({\n start: new Date(2022, 0, 20),\n end: addDays(new Date(2022, 0, 20), 20),\n})\n</script>\n\n<template>\n <div :class=\"cn('grid gap-2', $attrs.class ?? '')\">\n <Popover>\n <PopoverTrigger as-child>\n <Button\n id=\"date\"\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n\n <span>\n {{ date.start ? (\n date.end ? `${format(date.start, 'LLL dd, y')} - ${format(date.end, 'LLL dd, y')}`\n : format(date.start, 'LLL dd, y')\n ) : 'Pick a date' }}\n </span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\" align=\"start\">\n <Calendar\n v-model.range=\"date\"\n mode=\"date\"\n :columns=\"2\"\n >\n <template #footer>\n <div class=\"w-full px-3 pb-3\">\n Entry time\n <Calendar\n v-model=\"date.start\"\n mode=\"time\"\n hide-time-header\n />\n Exit time\n <Calendar\n v-model=\"date.end\"\n mode=\"time\"\n hide-time-header\n />\n </div>\n </template>\n </Calendar>\n </PopoverContent>\n </Popover>\n </div>\n</template>\n",
"type": "registry:example",
"target": "VRangePickerWithSlot.vue"
}

View File

@ -3,8 +3,8 @@
"type": "registry:ui",
"dependencies": [],
"registryDependencies": [
"button",
"utils"
"utils",
"button"
],
"files": [
{
@ -15,13 +15,13 @@
},
{
"path": "ui/alert-dialog/AlertDialogAction.vue",
"content": "<script setup lang=\"ts\">\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { AlertDialogAction, type AlertDialogActionProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogActionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AlertDialogAction v-bind=\"delegatedProps\" :class=\"cn(buttonVariants(), props.class)\">\n <slot />\n </AlertDialogAction>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { AlertDialogAction, type AlertDialogActionProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogActionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AlertDialogAction v-bind=\"delegatedProps\" :class=\"cn(buttonVariants(), props.class)\">\n <slot />\n </AlertDialogAction>\n</template>\n",
"type": "registry:ui",
"target": "alert-dialog/AlertDialogAction.vue"
},
{
"path": "ui/alert-dialog/AlertDialogCancel.vue",
"content": "<script setup lang=\"ts\">\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { AlertDialogCancel, type AlertDialogCancelProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogCancelProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AlertDialogCancel\n v-bind=\"delegatedProps\"\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'mt-2 sm:mt-0',\n props.class,\n )\"\n >\n <slot />\n </AlertDialogCancel>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { AlertDialogCancel, type AlertDialogCancelProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogCancelProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AlertDialogCancel\n v-bind=\"delegatedProps\"\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'mt-2 sm:mt-0',\n props.class,\n )\"\n >\n <slot />\n </AlertDialogCancel>\n</template>\n",
"type": "registry:ui",
"target": "alert-dialog/AlertDialogCancel.vue"
},

View File

@ -13,9 +13,9 @@
"separator",
"checkbox",
"switch",
"utils",
"calendar",
"popover",
"utils",
"label",
"radio-group",
"select",
@ -49,7 +49,7 @@
},
{
"path": "ui/auto-form/AutoFormFieldDate.vue",
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { Button } from '@/registry/default/ui/button'\nimport { Calendar } from '@/registry/default/ui/calendar'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/default/ui/form'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover'\nimport { cn } from '@/lib/utils'\n\nimport { DateFormatter, getLocalTimeZone } from '@internationalized/date'\nimport { CalendarIcon } from 'lucide-vue-next'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\ndefineProps<FieldProps>()\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n</script>\n\n<template>\n <FormField v-slot=\"slotProps\" :name=\"fieldName\">\n <FormItem>\n <AutoFormLabel v-if=\"!config?.hideLabel\" :required=\"required\">\n {{ config?.label || beautifyObjectName(label ?? fieldName) }}\n </AutoFormLabel>\n <FormControl>\n <slot v-bind=\"slotProps\">\n <div>\n <Popover>\n <PopoverTrigger as-child :disabled=\"disabled\">\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-full justify-start text-left font-normal',\n !slotProps.componentField.modelValue && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" :size=\"16\" />\n {{ slotProps.componentField.modelValue ? df.format(slotProps.componentField.modelValue.toDate(getLocalTimeZone())) : \"Pick a date\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar initial-focus v-bind=\"slotProps.componentField\" />\n </PopoverContent>\n </Popover>\n </div>\n </slot>\n </FormControl>\n\n <FormDescription v-if=\"config?.description\">\n {{ config.description }}\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\nimport { Calendar } from '@/registry/default/ui/calendar'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/default/ui/form'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover'\n\nimport { DateFormatter, getLocalTimeZone } from '@internationalized/date'\nimport { CalendarIcon } from 'lucide-vue-next'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\ndefineProps<FieldProps>()\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n</script>\n\n<template>\n <FormField v-slot=\"slotProps\" :name=\"fieldName\">\n <FormItem>\n <AutoFormLabel v-if=\"!config?.hideLabel\" :required=\"required\">\n {{ config?.label || beautifyObjectName(label ?? fieldName) }}\n </AutoFormLabel>\n <FormControl>\n <slot v-bind=\"slotProps\">\n <div>\n <Popover>\n <PopoverTrigger as-child :disabled=\"disabled\">\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-full justify-start text-left font-normal',\n !slotProps.componentField.modelValue && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" :size=\"16\" />\n {{ slotProps.componentField.modelValue ? df.format(slotProps.componentField.modelValue.toDate(getLocalTimeZone())) : \"Pick a date\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar initial-focus v-bind=\"slotProps.componentField\" />\n </PopoverContent>\n </Popover>\n </div>\n </slot>\n </FormControl>\n\n <FormDescription v-if=\"config?.description\">\n {{ config.description }}\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n</template>\n",
"type": "registry:ui",
"target": "auto-form/AutoFormFieldDate.vue"
},

View File

@ -21,7 +21,7 @@
},
{
"path": "ui/calendar/CalendarCellTrigger.vue",
"content": "<script lang=\"ts\" setup>\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { CalendarCellTrigger, type CalendarCellTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarCellTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarCellTrigger\n :class=\"cn(\n buttonVariants({ variant: 'ghost' }),\n 'h-9 w-9 p-0 font-normal',\n '[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',\n // Selected\n 'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:opacity-100 data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground',\n // Disabled\n 'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',\n // Unavailable\n 'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',\n // Outside months\n 'data-[outside-view]:text-muted-foreground data-[outside-view]:opacity-50 [&[data-outside-view][data-selected]]:bg-accent/50 [&[data-outside-view][data-selected]]:text-muted-foreground [&[data-outside-view][data-selected]]:opacity-30',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </CalendarCellTrigger>\n</template>\n",
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { CalendarCellTrigger, type CalendarCellTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarCellTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarCellTrigger\n :class=\"cn(\n buttonVariants({ variant: 'ghost' }),\n 'h-9 w-9 p-0 font-normal',\n '[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',\n // Selected\n 'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:opacity-100 data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground',\n // Disabled\n 'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',\n // Unavailable\n 'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',\n // Outside months\n 'data-[outside-view]:text-muted-foreground data-[outside-view]:opacity-50 [&[data-outside-view][data-selected]]:bg-accent/50 [&[data-outside-view][data-selected]]:text-muted-foreground [&[data-outside-view][data-selected]]:opacity-30',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </CalendarCellTrigger>\n</template>\n",
"type": "registry:ui",
"target": "calendar/CalendarCellTrigger.vue"
},
@ -69,13 +69,13 @@
},
{
"path": "ui/calendar/CalendarNextButton.vue",
"content": "<script lang=\"ts\" setup>\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ChevronRight } from 'lucide-vue-next'\nimport { CalendarNext, type CalendarNextProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarNextProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarNext\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronRight class=\"h-4 w-4\" />\n </slot>\n </CalendarNext>\n</template>\n",
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { ChevronRight } from 'lucide-vue-next'\nimport { CalendarNext, type CalendarNextProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarNextProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarNext\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronRight class=\"h-4 w-4\" />\n </slot>\n </CalendarNext>\n</template>\n",
"type": "registry:ui",
"target": "calendar/CalendarNextButton.vue"
},
{
"path": "ui/calendar/CalendarPrevButton.vue",
"content": "<script lang=\"ts\" setup>\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ChevronLeft } from 'lucide-vue-next'\nimport { CalendarPrev, type CalendarPrevProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarPrevProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarPrev\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronLeft class=\"h-4 w-4\" />\n </slot>\n </CalendarPrev>\n</template>\n",
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { ChevronLeft } from 'lucide-vue-next'\nimport { CalendarPrev, type CalendarPrevProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarPrevProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarPrev\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronLeft class=\"h-4 w-4\" />\n </slot>\n </CalendarPrev>\n</template>\n",
"type": "registry:ui",
"target": "calendar/CalendarPrevButton.vue"
},

View File

@ -30,13 +30,13 @@
},
{
"path": "ui/carousel/CarouselNext.vue",
"content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from './interface'\nimport { Button } from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ArrowRight } from 'lucide-vue-next'\nimport { useCarousel } from './useCarousel'\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { orientation, canScrollNext, scrollNext } = useCarousel()\n</script>\n\n<template>\n <Button\n :disabled=\"!canScrollNext\"\n :class=\"cn(\n 'touch-manipulation absolute h-8 w-8 rounded-full p-0',\n orientation === 'horizontal'\n ? '-right-12 top-1/2 -translate-y-1/2'\n : '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',\n props.class,\n )\"\n variant=\"outline\"\n @click=\"scrollNext\"\n >\n <slot>\n <ArrowRight class=\"h-4 w-4 text-current\" />\n <span class=\"sr-only\">Next Slide</span>\n </slot>\n </Button>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\nimport { ArrowRight } from 'lucide-vue-next'\nimport { useCarousel } from './useCarousel'\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { orientation, canScrollNext, scrollNext } = useCarousel()\n</script>\n\n<template>\n <Button\n :disabled=\"!canScrollNext\"\n :class=\"cn(\n 'touch-manipulation absolute h-8 w-8 rounded-full p-0',\n orientation === 'horizontal'\n ? '-right-12 top-1/2 -translate-y-1/2'\n : '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',\n props.class,\n )\"\n variant=\"outline\"\n @click=\"scrollNext\"\n >\n <slot>\n <ArrowRight class=\"h-4 w-4 text-current\" />\n <span class=\"sr-only\">Next Slide</span>\n </slot>\n </Button>\n</template>\n",
"type": "registry:ui",
"target": "carousel/CarouselNext.vue"
},
{
"path": "ui/carousel/CarouselPrevious.vue",
"content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from './interface'\nimport { Button } from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ArrowLeft } from 'lucide-vue-next'\nimport { useCarousel } from './useCarousel'\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { orientation, canScrollPrev, scrollPrev } = useCarousel()\n</script>\n\n<template>\n <Button\n :disabled=\"!canScrollPrev\"\n :class=\"cn(\n 'touch-manipulation absolute h-8 w-8 rounded-full p-0',\n orientation === 'horizontal'\n ? '-left-12 top-1/2 -translate-y-1/2'\n : '-top-12 left-1/2 -translate-x-1/2 rotate-90',\n props.class,\n )\"\n variant=\"outline\"\n @click=\"scrollPrev\"\n >\n <slot>\n <ArrowLeft class=\"h-4 w-4 text-current\" />\n <span class=\"sr-only\">Previous Slide</span>\n </slot>\n </Button>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\nimport { ArrowLeft } from 'lucide-vue-next'\nimport { useCarousel } from './useCarousel'\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { orientation, canScrollPrev, scrollPrev } = useCarousel()\n</script>\n\n<template>\n <Button\n :disabled=\"!canScrollPrev\"\n :class=\"cn(\n 'touch-manipulation absolute h-8 w-8 rounded-full p-0',\n orientation === 'horizontal'\n ? '-left-12 top-1/2 -translate-y-1/2'\n : '-top-12 left-1/2 -translate-x-1/2 rotate-90',\n props.class,\n )\"\n variant=\"outline\"\n @click=\"scrollPrev\"\n >\n <slot>\n <ArrowLeft class=\"h-4 w-4 text-current\" />\n <span class=\"sr-only\">Previous Slide</span>\n </slot>\n </Button>\n</template>\n",
"type": "registry:ui",
"target": "carousel/CarouselPrevious.vue"
},

View File

@ -7,13 +7,13 @@
"@vueuse/core"
],
"registryDependencies": [
"chart",
"utils"
"utils",
"chart"
],
"files": [
{
"path": "ui/chart-area/AreaChart.vue",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BaseChartProps } from '.'\nimport { ChartCrosshair, ChartLegend, defaultColors } from '@/registry/default/ui/chart'\nimport { cn } from '@/lib/utils'\nimport { type BulletLegendItemInterface, CurveType } from '@unovis/ts'\nimport { Area, Axis, Line } from '@unovis/ts'\nimport { VisArea, VisAxis, VisLine, VisXYContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { useId } from 'reka-ui'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<BaseChartProps<T> & {\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n /**\n * Type of curve\n */\n curveType?: CurveType\n /**\n * Controls the visibility of gradient.\n * @default true\n */\n showGradiant?: boolean\n}>(), {\n curveType: CurveType.MonotoneX,\n filterOpacity: 0.2,\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n showXAxis: true,\n showYAxis: true,\n showTooltip: true,\n showLegend: true,\n showGridLine: true,\n showGradiant: true,\n})\n\nconst emits = defineEmits<{\n legendItemClick: [d: BulletLegendItemInterface, i: number]\n}>()\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst chartRef = useId()\n\nconst index = computed(() => props.index as KeyOfT)\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))\n\nconst legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({\n name: category,\n color: colors.value[i],\n inactive: false,\n})))\n\nconst isMounted = useMounted()\n\nfunction handleLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n}\n</script>\n\n<template>\n <div :class=\"cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')\">\n <ChartLegend v-if=\"showLegend\" v-model:items=\"legendItems\" @legend-item-click=\"handleLegendItemClick\" />\n\n <VisXYContainer :style=\"{ height: isMounted ? '100%' : 'auto' }\" :margin=\"{ left: 20, right: 20 }\" :data=\"data\">\n <svg width=\"0\" height=\"0\">\n <defs>\n <linearGradient v-for=\"(color, i) in colors\" :id=\"`${chartRef}-color-${i}`\" :key=\"i\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <template v-if=\"showGradiant\">\n <stop offset=\"5%\" :stop-color=\"color\" stop-opacity=\"0.4\" />\n <stop offset=\"95%\" :stop-color=\"color\" stop-opacity=\"0\" />\n </template>\n <template v-else>\n <stop offset=\"0%\" :stop-color=\"color\" />\n </template>\n </linearGradient>\n </defs>\n </svg>\n\n <ChartCrosshair v-if=\"showTooltip\" :colors=\"colors\" :items=\"legendItems\" :index=\"index\" :custom-tooltip=\"customTooltip\" />\n\n <template v-for=\"(category, i) in categories\" :key=\"category\">\n <VisArea\n :x=\"(d: Data, i: number) => i\"\n :y=\"(d: Data) => d[category]\"\n color=\"auto\"\n :curve-type=\"curveType\"\n :attributes=\"{\n [Area.selectors.area]: {\n fill: `url(#${chartRef}-color-${i})`,\n },\n }\"\n :opacity=\"legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1\"\n />\n </template>\n\n <template v-for=\"(category, i) in categories\" :key=\"category\">\n <VisLine\n :x=\"(d: Data, i: number) => i\"\n :y=\"(d: Data) => d[category]\"\n :color=\"colors[i]\"\n :curve-type=\"curveType\"\n :attributes=\"{\n [Line.selectors.line]: {\n opacity: legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1,\n },\n }\"\n />\n </template>\n\n <VisAxis\n v-if=\"showXAxis\"\n type=\"x\"\n :tick-format=\"xFormatter ?? ((v: number) => data[v]?.[index])\"\n :grid-line=\"false\"\n :tick-line=\"false\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n <VisAxis\n v-if=\"showYAxis\"\n type=\"y\"\n :tick-line=\"false\"\n :tick-format=\"yFormatter\"\n :domain-line=\"false\"\n :grid-line=\"showGridLine\"\n :attributes=\"{\n [Axis.selectors.grid]: {\n class: 'text-muted',\n },\n }\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n\n <slot />\n </VisXYContainer>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BaseChartProps } from '.'\nimport { cn } from '@/lib/utils'\nimport { ChartCrosshair, ChartLegend, defaultColors } from '@/registry/default/ui/chart'\nimport { type BulletLegendItemInterface, CurveType } from '@unovis/ts'\nimport { Area, Axis, Line } from '@unovis/ts'\nimport { VisArea, VisAxis, VisLine, VisXYContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { useId } from 'reka-ui'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<BaseChartProps<T> & {\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n /**\n * Type of curve\n */\n curveType?: CurveType\n /**\n * Controls the visibility of gradient.\n * @default true\n */\n showGradiant?: boolean\n}>(), {\n curveType: CurveType.MonotoneX,\n filterOpacity: 0.2,\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n showXAxis: true,\n showYAxis: true,\n showTooltip: true,\n showLegend: true,\n showGridLine: true,\n showGradiant: true,\n})\n\nconst emits = defineEmits<{\n legendItemClick: [d: BulletLegendItemInterface, i: number]\n}>()\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst chartRef = useId()\n\nconst index = computed(() => props.index as KeyOfT)\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))\n\nconst legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({\n name: category,\n color: colors.value[i],\n inactive: false,\n})))\n\nconst isMounted = useMounted()\n\nfunction handleLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n}\n</script>\n\n<template>\n <div :class=\"cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')\">\n <ChartLegend v-if=\"showLegend\" v-model:items=\"legendItems\" @legend-item-click=\"handleLegendItemClick\" />\n\n <VisXYContainer :style=\"{ height: isMounted ? '100%' : 'auto' }\" :margin=\"{ left: 20, right: 20 }\" :data=\"data\">\n <svg width=\"0\" height=\"0\">\n <defs>\n <linearGradient v-for=\"(color, i) in colors\" :id=\"`${chartRef}-color-${i}`\" :key=\"i\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <template v-if=\"showGradiant\">\n <stop offset=\"5%\" :stop-color=\"color\" stop-opacity=\"0.4\" />\n <stop offset=\"95%\" :stop-color=\"color\" stop-opacity=\"0\" />\n </template>\n <template v-else>\n <stop offset=\"0%\" :stop-color=\"color\" />\n </template>\n </linearGradient>\n </defs>\n </svg>\n\n <ChartCrosshair v-if=\"showTooltip\" :colors=\"colors\" :items=\"legendItems\" :index=\"index\" :custom-tooltip=\"customTooltip\" />\n\n <template v-for=\"(category, i) in categories\" :key=\"category\">\n <VisArea\n :x=\"(d: Data, i: number) => i\"\n :y=\"(d: Data) => d[category]\"\n color=\"auto\"\n :curve-type=\"curveType\"\n :attributes=\"{\n [Area.selectors.area]: {\n fill: `url(#${chartRef}-color-${i})`,\n },\n }\"\n :opacity=\"legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1\"\n />\n </template>\n\n <template v-for=\"(category, i) in categories\" :key=\"category\">\n <VisLine\n :x=\"(d: Data, i: number) => i\"\n :y=\"(d: Data) => d[category]\"\n :color=\"colors[i]\"\n :curve-type=\"curveType\"\n :attributes=\"{\n [Line.selectors.line]: {\n opacity: legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1,\n },\n }\"\n />\n </template>\n\n <VisAxis\n v-if=\"showXAxis\"\n type=\"x\"\n :tick-format=\"xFormatter ?? ((v: number) => data[v]?.[index])\"\n :grid-line=\"false\"\n :tick-line=\"false\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n <VisAxis\n v-if=\"showYAxis\"\n type=\"y\"\n :tick-line=\"false\"\n :tick-format=\"yFormatter\"\n :domain-line=\"false\"\n :grid-line=\"showGridLine\"\n :attributes=\"{\n [Axis.selectors.grid]: {\n class: 'text-muted',\n },\n }\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n\n <slot />\n </VisXYContainer>\n </div>\n</template>\n",
"type": "registry:ui",
"target": "chart-area/AreaChart.vue"
},

View File

@ -7,13 +7,13 @@
"@vueuse/core"
],
"registryDependencies": [
"chart",
"utils"
"utils",
"chart"
],
"files": [
{
"path": "ui/chart-bar/BarChart.vue",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BulletLegendItemInterface } from '@unovis/ts'\nimport type { BaseChartProps } from '.'\nimport { ChartCrosshair, ChartLegend, defaultColors } from '@/registry/default/ui/chart'\nimport { cn } from '@/lib/utils'\nimport { Axis, GroupedBar, StackedBar } from '@unovis/ts'\nimport { VisAxis, VisGroupedBar, VisStackedBar, VisXYContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<BaseChartProps<T> & {\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n /**\n * Change the type of the chart\n * @default \"grouped\"\n */\n type?: 'stacked' | 'grouped'\n /**\n * Rounded bar corners\n * @default 0\n */\n roundedCorners?: number\n}>(), {\n type: 'grouped',\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n filterOpacity: 0.2,\n roundedCorners: 0,\n showXAxis: true,\n showYAxis: true,\n showTooltip: true,\n showLegend: true,\n showGridLine: true,\n})\nconst emits = defineEmits<{\n legendItemClick: [d: BulletLegendItemInterface, i: number]\n}>()\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst index = computed(() => props.index as KeyOfT)\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))\nconst legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({\n name: category,\n color: colors.value[i],\n inactive: false,\n})))\n\nconst isMounted = useMounted()\n\nfunction handleLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n}\n\nconst VisBarComponent = computed(() => props.type === 'grouped' ? VisGroupedBar : VisStackedBar)\nconst selectorsBar = computed(() => props.type === 'grouped' ? GroupedBar.selectors.bar : StackedBar.selectors.bar)\n</script>\n\n<template>\n <div :class=\"cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')\">\n <ChartLegend v-if=\"showLegend\" v-model:items=\"legendItems\" @legend-item-click=\"handleLegendItemClick\" />\n\n <VisXYContainer\n :data=\"data\"\n :style=\"{ height: isMounted ? '100%' : 'auto' }\"\n :margin=\"margin\"\n >\n <ChartCrosshair v-if=\"showTooltip\" :colors=\"colors\" :items=\"legendItems\" :custom-tooltip=\"customTooltip\" :index=\"index\" />\n\n <VisBarComponent\n :x=\"(d: Data, i: number) => i\"\n :y=\"categories.map(category => (d: Data) => d[category]) \"\n :color=\"colors\"\n :rounded-corners=\"roundedCorners\"\n :bar-padding=\"0.05\"\n :attributes=\"{\n [selectorsBar]: {\n opacity: (d: Data, i:number) => {\n const pos = i % categories.length\n return legendItems[pos]?.inactive ? filterOpacity : 1\n },\n },\n }\"\n />\n\n <VisAxis\n v-if=\"showXAxis\"\n type=\"x\"\n :tick-format=\"xFormatter ?? ((v: number) => data[v]?.[index])\"\n :grid-line=\"false\"\n :tick-line=\"false\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n <VisAxis\n v-if=\"showYAxis\"\n type=\"y\"\n :tick-line=\"false\"\n :tick-format=\"yFormatter\"\n :domain-line=\"false\"\n :grid-line=\"showGridLine\"\n :attributes=\"{\n [Axis.selectors.grid]: {\n class: 'text-muted',\n },\n }\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n\n <slot />\n </VisXYContainer>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BulletLegendItemInterface } from '@unovis/ts'\nimport type { BaseChartProps } from '.'\nimport { cn } from '@/lib/utils'\nimport { ChartCrosshair, ChartLegend, defaultColors } from '@/registry/default/ui/chart'\nimport { Axis, GroupedBar, StackedBar } from '@unovis/ts'\nimport { VisAxis, VisGroupedBar, VisStackedBar, VisXYContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<BaseChartProps<T> & {\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n /**\n * Change the type of the chart\n * @default \"grouped\"\n */\n type?: 'stacked' | 'grouped'\n /**\n * Rounded bar corners\n * @default 0\n */\n roundedCorners?: number\n}>(), {\n type: 'grouped',\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n filterOpacity: 0.2,\n roundedCorners: 0,\n showXAxis: true,\n showYAxis: true,\n showTooltip: true,\n showLegend: true,\n showGridLine: true,\n})\nconst emits = defineEmits<{\n legendItemClick: [d: BulletLegendItemInterface, i: number]\n}>()\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst index = computed(() => props.index as KeyOfT)\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))\nconst legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({\n name: category,\n color: colors.value[i],\n inactive: false,\n})))\n\nconst isMounted = useMounted()\n\nfunction handleLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n}\n\nconst VisBarComponent = computed(() => props.type === 'grouped' ? VisGroupedBar : VisStackedBar)\nconst selectorsBar = computed(() => props.type === 'grouped' ? GroupedBar.selectors.bar : StackedBar.selectors.bar)\n</script>\n\n<template>\n <div :class=\"cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')\">\n <ChartLegend v-if=\"showLegend\" v-model:items=\"legendItems\" @legend-item-click=\"handleLegendItemClick\" />\n\n <VisXYContainer\n :data=\"data\"\n :style=\"{ height: isMounted ? '100%' : 'auto' }\"\n :margin=\"margin\"\n >\n <ChartCrosshair v-if=\"showTooltip\" :colors=\"colors\" :items=\"legendItems\" :custom-tooltip=\"customTooltip\" :index=\"index\" />\n\n <VisBarComponent\n :x=\"(d: Data, i: number) => i\"\n :y=\"categories.map(category => (d: Data) => d[category]) \"\n :color=\"colors\"\n :rounded-corners=\"roundedCorners\"\n :bar-padding=\"0.05\"\n :attributes=\"{\n [selectorsBar]: {\n opacity: (d: Data, i:number) => {\n const pos = i % categories.length\n return legendItems[pos]?.inactive ? filterOpacity : 1\n },\n },\n }\"\n />\n\n <VisAxis\n v-if=\"showXAxis\"\n type=\"x\"\n :tick-format=\"xFormatter ?? ((v: number) => data[v]?.[index])\"\n :grid-line=\"false\"\n :tick-line=\"false\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n <VisAxis\n v-if=\"showYAxis\"\n type=\"y\"\n :tick-line=\"false\"\n :tick-format=\"yFormatter\"\n :domain-line=\"false\"\n :grid-line=\"showGridLine\"\n :attributes=\"{\n [Axis.selectors.grid]: {\n class: 'text-muted',\n },\n }\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n\n <slot />\n </VisXYContainer>\n </div>\n</template>\n",
"type": "registry:ui",
"target": "chart-bar/BarChart.vue"
},

View File

@ -7,13 +7,13 @@
"@vueuse/core"
],
"registryDependencies": [
"chart",
"utils"
"utils",
"chart"
],
"files": [
{
"path": "ui/chart-donut/DonutChart.vue",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BaseChartProps } from '.'\nimport { ChartSingleTooltip, defaultColors } from '@/registry/default/ui/chart'\nimport { cn } from '@/lib/utils'\nimport { Donut } from '@unovis/ts'\nimport { VisDonut, VisSingleContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<Pick<BaseChartProps<T>, 'data' | 'colors' | 'index' | 'margin' | 'showLegend' | 'showTooltip' | 'filterOpacity'> & {\n /**\n * Sets the name of the key containing the quantitative chart values.\n */\n category: KeyOfT\n /**\n * Change the type of the chart\n * @default \"donut\"\n */\n type?: 'donut' | 'pie'\n /**\n * Function to sort the segment\n */\n sortFunction?: (a: any, b: any) => number | undefined\n /**\n * Controls the formatting for the label.\n */\n valueFormatter?: (tick: number, i?: number, ticks?: number[]) => string\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n}>(), {\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n sortFunction: () => undefined,\n valueFormatter: (tick: number) => `${tick}`,\n type: 'donut',\n filterOpacity: 0.2,\n showTooltip: true,\n showLegend: true,\n})\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst category = computed(() => props.category as KeyOfT)\nconst index = computed(() => props.index as KeyOfT)\n\nconst isMounted = useMounted()\nconst activeSegmentKey = ref<string>()\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.data.filter(d => d[props.category]).filter(Boolean).length))\nconst legendItems = computed(() => props.data.map((item, i) => ({\n name: item[props.index],\n color: colors.value[i],\n inactive: false,\n})))\n\nconst totalValue = computed(() => props.data.reduce((prev, curr) => {\n return prev + curr[props.category]\n}, 0))\n</script>\n\n<template>\n <div :class=\"cn('w-full h-48 flex flex-col items-end', $attrs.class ?? '')\">\n <VisSingleContainer :style=\"{ height: isMounted ? '100%' : 'auto' }\" :margin=\"{ left: 20, right: 20 }\" :data=\"data\">\n <ChartSingleTooltip\n :selector=\"Donut.selectors.segment\"\n :index=\"category\"\n :items=\"legendItems\"\n :value-formatter=\"valueFormatter\"\n :custom-tooltip=\"customTooltip\"\n />\n\n <VisDonut\n :value=\"(d: Data) => d[category]\"\n :sort-function=\"sortFunction\"\n :color=\"colors\"\n :arc-width=\"type === 'donut' ? 20 : 0\"\n :show-background=\"false\"\n :central-label=\"type === 'donut' ? valueFormatter(totalValue) : ''\"\n :events=\"{\n [Donut.selectors.segment]: {\n click: (d: Data, ev: PointerEvent, i: number, elements: HTMLElement[]) => {\n if (d?.data?.[index] === activeSegmentKey) {\n activeSegmentKey = undefined\n elements.forEach(el => el.style.opacity = '1')\n }\n else {\n activeSegmentKey = d?.data?.[index]\n elements.forEach(el => el.style.opacity = `${filterOpacity}`)\n elements[i].style.opacity = '1'\n }\n },\n },\n }\"\n />\n\n <slot />\n </VisSingleContainer>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BaseChartProps } from '.'\nimport { cn } from '@/lib/utils'\nimport { ChartSingleTooltip, defaultColors } from '@/registry/default/ui/chart'\nimport { Donut } from '@unovis/ts'\nimport { VisDonut, VisSingleContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<Pick<BaseChartProps<T>, 'data' | 'colors' | 'index' | 'margin' | 'showLegend' | 'showTooltip' | 'filterOpacity'> & {\n /**\n * Sets the name of the key containing the quantitative chart values.\n */\n category: KeyOfT\n /**\n * Change the type of the chart\n * @default \"donut\"\n */\n type?: 'donut' | 'pie'\n /**\n * Function to sort the segment\n */\n sortFunction?: (a: any, b: any) => number | undefined\n /**\n * Controls the formatting for the label.\n */\n valueFormatter?: (tick: number, i?: number, ticks?: number[]) => string\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n}>(), {\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n sortFunction: () => undefined,\n valueFormatter: (tick: number) => `${tick}`,\n type: 'donut',\n filterOpacity: 0.2,\n showTooltip: true,\n showLegend: true,\n})\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst category = computed(() => props.category as KeyOfT)\nconst index = computed(() => props.index as KeyOfT)\n\nconst isMounted = useMounted()\nconst activeSegmentKey = ref<string>()\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.data.filter(d => d[props.category]).filter(Boolean).length))\nconst legendItems = computed(() => props.data.map((item, i) => ({\n name: item[props.index],\n color: colors.value[i],\n inactive: false,\n})))\n\nconst totalValue = computed(() => props.data.reduce((prev, curr) => {\n return prev + curr[props.category]\n}, 0))\n</script>\n\n<template>\n <div :class=\"cn('w-full h-48 flex flex-col items-end', $attrs.class ?? '')\">\n <VisSingleContainer :style=\"{ height: isMounted ? '100%' : 'auto' }\" :margin=\"{ left: 20, right: 20 }\" :data=\"data\">\n <ChartSingleTooltip\n :selector=\"Donut.selectors.segment\"\n :index=\"category\"\n :items=\"legendItems\"\n :value-formatter=\"valueFormatter\"\n :custom-tooltip=\"customTooltip\"\n />\n\n <VisDonut\n :value=\"(d: Data) => d[category]\"\n :sort-function=\"sortFunction\"\n :color=\"colors\"\n :arc-width=\"type === 'donut' ? 20 : 0\"\n :show-background=\"false\"\n :central-label=\"type === 'donut' ? valueFormatter(totalValue) : ''\"\n :events=\"{\n [Donut.selectors.segment]: {\n click: (d: Data, ev: PointerEvent, i: number, elements: HTMLElement[]) => {\n if (d?.data?.[index] === activeSegmentKey) {\n activeSegmentKey = undefined\n elements.forEach(el => el.style.opacity = '1')\n }\n else {\n activeSegmentKey = d?.data?.[index]\n elements.forEach(el => el.style.opacity = `${filterOpacity}`)\n elements[i].style.opacity = '1'\n }\n },\n },\n }\"\n />\n\n <slot />\n </VisSingleContainer>\n </div>\n</template>\n",
"type": "registry:ui",
"target": "chart-donut/DonutChart.vue"
},

View File

@ -7,13 +7,13 @@
"@vueuse/core"
],
"registryDependencies": [
"chart",
"utils"
"utils",
"chart"
],
"files": [
{
"path": "ui/chart-line/LineChart.vue",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BaseChartProps } from '.'\nimport { ChartCrosshair, ChartLegend, defaultColors } from '@/registry/default/ui/chart'\nimport { cn } from '@/lib/utils'\nimport { type BulletLegendItemInterface, CurveType } from '@unovis/ts'\nimport { Axis, Line } from '@unovis/ts'\nimport { VisAxis, VisLine, VisXYContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<BaseChartProps<T> & {\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n /**\n * Type of curve\n */\n curveType?: CurveType\n}>(), {\n curveType: CurveType.MonotoneX,\n filterOpacity: 0.2,\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n showXAxis: true,\n showYAxis: true,\n showTooltip: true,\n showLegend: true,\n showGridLine: true,\n})\n\nconst emits = defineEmits<{\n legendItemClick: [d: BulletLegendItemInterface, i: number]\n}>()\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst index = computed(() => props.index as KeyOfT)\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))\n\nconst legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({\n name: category,\n color: colors.value[i],\n inactive: false,\n})))\n\nconst isMounted = useMounted()\n\nfunction handleLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n}\n</script>\n\n<template>\n <div :class=\"cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')\">\n <ChartLegend v-if=\"showLegend\" v-model:items=\"legendItems\" @legend-item-click=\"handleLegendItemClick\" />\n\n <VisXYContainer\n :margin=\"{ left: 20, right: 20 }\"\n :data=\"data\"\n :style=\"{ height: isMounted ? '100%' : 'auto' }\"\n >\n <ChartCrosshair v-if=\"showTooltip\" :colors=\"colors\" :items=\"legendItems\" :index=\"index\" :custom-tooltip=\"customTooltip\" />\n\n <template v-for=\"(category, i) in categories\" :key=\"category\">\n <VisLine\n :x=\"(d: Data, i: number) => i\"\n :y=\"(d: Data) => d[category]\"\n :curve-type=\"curveType\"\n :color=\"colors[i]\"\n :attributes=\"{\n [Line.selectors.line]: {\n opacity: legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1,\n },\n }\"\n />\n </template>\n\n <VisAxis\n v-if=\"showXAxis\"\n type=\"x\"\n :tick-format=\"xFormatter ?? ((v: number) => data[v]?.[index])\"\n :grid-line=\"false\"\n :tick-line=\"false\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n <VisAxis\n v-if=\"showYAxis\"\n type=\"y\"\n :tick-line=\"false\"\n :tick-format=\"yFormatter\"\n :domain-line=\"false\"\n :grid-line=\"showGridLine\"\n :attributes=\"{\n [Axis.selectors.grid]: {\n class: 'text-muted',\n },\n }\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n\n <slot />\n </VisXYContainer>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BaseChartProps } from '.'\nimport { cn } from '@/lib/utils'\nimport { ChartCrosshair, ChartLegend, defaultColors } from '@/registry/default/ui/chart'\nimport { type BulletLegendItemInterface, CurveType } from '@unovis/ts'\nimport { Axis, Line } from '@unovis/ts'\nimport { VisAxis, VisLine, VisXYContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<BaseChartProps<T> & {\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n /**\n * Type of curve\n */\n curveType?: CurveType\n}>(), {\n curveType: CurveType.MonotoneX,\n filterOpacity: 0.2,\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n showXAxis: true,\n showYAxis: true,\n showTooltip: true,\n showLegend: true,\n showGridLine: true,\n})\n\nconst emits = defineEmits<{\n legendItemClick: [d: BulletLegendItemInterface, i: number]\n}>()\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst index = computed(() => props.index as KeyOfT)\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))\n\nconst legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({\n name: category,\n color: colors.value[i],\n inactive: false,\n})))\n\nconst isMounted = useMounted()\n\nfunction handleLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n}\n</script>\n\n<template>\n <div :class=\"cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')\">\n <ChartLegend v-if=\"showLegend\" v-model:items=\"legendItems\" @legend-item-click=\"handleLegendItemClick\" />\n\n <VisXYContainer\n :margin=\"{ left: 20, right: 20 }\"\n :data=\"data\"\n :style=\"{ height: isMounted ? '100%' : 'auto' }\"\n >\n <ChartCrosshair v-if=\"showTooltip\" :colors=\"colors\" :items=\"legendItems\" :index=\"index\" :custom-tooltip=\"customTooltip\" />\n\n <template v-for=\"(category, i) in categories\" :key=\"category\">\n <VisLine\n :x=\"(d: Data, i: number) => i\"\n :y=\"(d: Data) => d[category]\"\n :curve-type=\"curveType\"\n :color=\"colors[i]\"\n :attributes=\"{\n [Line.selectors.line]: {\n opacity: legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1,\n },\n }\"\n />\n </template>\n\n <VisAxis\n v-if=\"showXAxis\"\n type=\"x\"\n :tick-format=\"xFormatter ?? ((v: number) => data[v]?.[index])\"\n :grid-line=\"false\"\n :tick-line=\"false\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n <VisAxis\n v-if=\"showYAxis\"\n type=\"y\"\n :tick-line=\"false\"\n :tick-format=\"yFormatter\"\n :domain-line=\"false\"\n :grid-line=\"showGridLine\"\n :attributes=\"{\n [Axis.selectors.grid]: {\n class: 'text-muted',\n },\n }\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n\n <slot />\n </VisXYContainer>\n </div>\n</template>\n",
"type": "registry:ui",
"target": "chart-line/LineChart.vue"
},

View File

@ -31,7 +31,7 @@
},
{
"path": "ui/form/FormLabel.vue",
"content": "<script lang=\"ts\" setup>\nimport type { LabelProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { Label } from '@/registry/default/ui/label'\nimport { cn } from '@/lib/utils'\nimport { useFormField } from './useFormField'\n\nconst props = defineProps<LabelProps & { class?: HTMLAttributes['class'] }>()\n\nconst { error, formItemId } = useFormField()\n</script>\n\n<template>\n <Label\n :class=\"cn(\n error && 'text-destructive',\n props.class,\n )\"\n :for=\"formItemId\"\n >\n <slot />\n </Label>\n</template>\n",
"content": "<script lang=\"ts\" setup>\nimport type { LabelProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Label } from '@/registry/default/ui/label'\nimport { useFormField } from './useFormField'\n\nconst props = defineProps<LabelProps & { class?: HTMLAttributes['class'] }>()\n\nconst { error, formItemId } = useFormField()\n</script>\n\n<template>\n <Label\n :class=\"cn(\n error && 'text-destructive',\n props.class,\n )\"\n :for=\"formItemId\"\n >\n <slot />\n </Label>\n</template>\n",
"type": "registry:ui",
"target": "form/FormLabel.vue"
},

View File

@ -4,7 +4,7 @@
"dependencies": [
"tailwindcss-animate",
"class-variance-authority",
"lucide-react"
"lucide-vue-next"
],
"registryDependencies": [
"utils"

View File

@ -15,25 +15,25 @@
},
{
"path": "ui/pagination/PaginationFirst.vue",
"content": "<script setup lang=\"ts\">\nimport {\n Button,\n} from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ChevronsLeft } from 'lucide-vue-next'\nimport { PaginationFirst, type PaginationFirstProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<PaginationFirstProps & { class?: HTMLAttributes['class'] }>(), {\n asChild: true,\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <PaginationFirst v-bind=\"delegatedProps\">\n <Button :class=\"cn('w-10 h-10 p-0', props.class)\" variant=\"outline\">\n <slot>\n <ChevronsLeft class=\"h-4 w-4\" />\n </slot>\n </Button>\n </PaginationFirst>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n Button,\n} from '@/registry/default/ui/button'\nimport { ChevronsLeft } from 'lucide-vue-next'\nimport { PaginationFirst, type PaginationFirstProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<PaginationFirstProps & { class?: HTMLAttributes['class'] }>(), {\n asChild: true,\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <PaginationFirst v-bind=\"delegatedProps\">\n <Button :class=\"cn('w-10 h-10 p-0', props.class)\" variant=\"outline\">\n <slot>\n <ChevronsLeft class=\"h-4 w-4\" />\n </slot>\n </Button>\n </PaginationFirst>\n</template>\n",
"type": "registry:ui",
"target": "pagination/PaginationFirst.vue"
},
{
"path": "ui/pagination/PaginationLast.vue",
"content": "<script setup lang=\"ts\">\nimport {\n Button,\n} from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ChevronsRight } from 'lucide-vue-next'\nimport { PaginationLast, type PaginationLastProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<PaginationLastProps & { class?: HTMLAttributes['class'] }>(), {\n asChild: true,\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <PaginationLast v-bind=\"delegatedProps\">\n <Button :class=\"cn('w-10 h-10 p-0', props.class)\" variant=\"outline\">\n <slot>\n <ChevronsRight class=\"h-4 w-4\" />\n </slot>\n </Button>\n </PaginationLast>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n Button,\n} from '@/registry/default/ui/button'\nimport { ChevronsRight } from 'lucide-vue-next'\nimport { PaginationLast, type PaginationLastProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<PaginationLastProps & { class?: HTMLAttributes['class'] }>(), {\n asChild: true,\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <PaginationLast v-bind=\"delegatedProps\">\n <Button :class=\"cn('w-10 h-10 p-0', props.class)\" variant=\"outline\">\n <slot>\n <ChevronsRight class=\"h-4 w-4\" />\n </slot>\n </Button>\n </PaginationLast>\n</template>\n",
"type": "registry:ui",
"target": "pagination/PaginationLast.vue"
},
{
"path": "ui/pagination/PaginationNext.vue",
"content": "<script setup lang=\"ts\">\nimport {\n Button,\n} from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ChevronRight } from 'lucide-vue-next'\nimport { PaginationNext, type PaginationNextProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<PaginationNextProps & { class?: HTMLAttributes['class'] }>(), {\n asChild: true,\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <PaginationNext v-bind=\"delegatedProps\">\n <Button :class=\"cn('w-10 h-10 p-0', props.class)\" variant=\"outline\">\n <slot>\n <ChevronRight class=\"h-4 w-4\" />\n </slot>\n </Button>\n </PaginationNext>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n Button,\n} from '@/registry/default/ui/button'\nimport { ChevronRight } from 'lucide-vue-next'\nimport { PaginationNext, type PaginationNextProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<PaginationNextProps & { class?: HTMLAttributes['class'] }>(), {\n asChild: true,\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <PaginationNext v-bind=\"delegatedProps\">\n <Button :class=\"cn('w-10 h-10 p-0', props.class)\" variant=\"outline\">\n <slot>\n <ChevronRight class=\"h-4 w-4\" />\n </slot>\n </Button>\n </PaginationNext>\n</template>\n",
"type": "registry:ui",
"target": "pagination/PaginationNext.vue"
},
{
"path": "ui/pagination/PaginationPrev.vue",
"content": "<script setup lang=\"ts\">\nimport {\n Button,\n} from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ChevronLeft } from 'lucide-vue-next'\nimport { PaginationPrev, type PaginationPrevProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<PaginationPrevProps & { class?: HTMLAttributes['class'] }>(), {\n asChild: true,\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <PaginationPrev v-bind=\"delegatedProps\">\n <Button :class=\"cn('w-10 h-10 p-0', props.class)\" variant=\"outline\">\n <slot>\n <ChevronLeft class=\"h-4 w-4\" />\n </slot>\n </Button>\n </PaginationPrev>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n Button,\n} from '@/registry/default/ui/button'\nimport { ChevronLeft } from 'lucide-vue-next'\nimport { PaginationPrev, type PaginationPrevProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<PaginationPrevProps & { class?: HTMLAttributes['class'] }>(), {\n asChild: true,\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <PaginationPrev v-bind=\"delegatedProps\">\n <Button :class=\"cn('w-10 h-10 p-0', props.class)\" variant=\"outline\">\n <slot>\n <ChevronLeft class=\"h-4 w-4\" />\n </slot>\n </Button>\n </PaginationPrev>\n</template>\n",
"type": "registry:ui",
"target": "pagination/PaginationPrev.vue"
},

View File

@ -21,7 +21,7 @@
},
{
"path": "ui/range-calendar/RangeCalendarCellTrigger.vue",
"content": "<script lang=\"ts\" setup>\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarCellTrigger, type RangeCalendarCellTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarCellTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <RangeCalendarCellTrigger\n :class=\"cn(\n buttonVariants({ variant: 'ghost' }),\n 'h-9 w-9 p-0 font-normal data-[selected]:opacity-100',\n '[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',\n // Selection Start\n 'data-[selection-start]:bg-primary data-[selection-start]:text-primary-foreground data-[selection-start]:hover:bg-primary data-[selection-start]:hover:text-primary-foreground data-[selection-start]:focus:bg-primary data-[selection-start]:focus:text-primary-foreground',\n // Selection End\n 'data-[selection-end]:bg-primary data-[selection-end]:text-primary-foreground data-[selection-end]:hover:bg-primary data-[selection-end]:hover:text-primary-foreground data-[selection-end]:focus:bg-primary data-[selection-end]:focus:text-primary-foreground',\n // Outside months\n 'data-[outside-view]:text-muted-foreground data-[outside-view]:opacity-50 [&[data-outside-view][data-selected]]:bg-accent/50 [&[data-outside-view][data-selected]]:text-muted-foreground [&[data-outside-view][data-selected]]:opacity-30',\n // Disabled\n 'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',\n // Unavailable\n 'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </RangeCalendarCellTrigger>\n</template>\n",
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { RangeCalendarCellTrigger, type RangeCalendarCellTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarCellTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <RangeCalendarCellTrigger\n :class=\"cn(\n buttonVariants({ variant: 'ghost' }),\n 'h-9 w-9 p-0 font-normal data-[selected]:opacity-100',\n '[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',\n // Selection Start\n 'data-[selection-start]:bg-primary data-[selection-start]:text-primary-foreground data-[selection-start]:hover:bg-primary data-[selection-start]:hover:text-primary-foreground data-[selection-start]:focus:bg-primary data-[selection-start]:focus:text-primary-foreground',\n // Selection End\n 'data-[selection-end]:bg-primary data-[selection-end]:text-primary-foreground data-[selection-end]:hover:bg-primary data-[selection-end]:hover:text-primary-foreground data-[selection-end]:focus:bg-primary data-[selection-end]:focus:text-primary-foreground',\n // Outside months\n 'data-[outside-view]:text-muted-foreground data-[outside-view]:opacity-50 [&[data-outside-view][data-selected]]:bg-accent/50 [&[data-outside-view][data-selected]]:text-muted-foreground [&[data-outside-view][data-selected]]:opacity-30',\n // Disabled\n 'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',\n // Unavailable\n 'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </RangeCalendarCellTrigger>\n</template>\n",
"type": "registry:ui",
"target": "range-calendar/RangeCalendarCellTrigger.vue"
},
@ -69,13 +69,13 @@
},
{
"path": "ui/range-calendar/RangeCalendarNextButton.vue",
"content": "<script lang=\"ts\" setup>\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ChevronRight } from 'lucide-vue-next'\nimport { RangeCalendarNext, type RangeCalendarNextProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarNextProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <RangeCalendarNext\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronRight class=\"h-4 w-4\" />\n </slot>\n </RangeCalendarNext>\n</template>\n",
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { ChevronRight } from 'lucide-vue-next'\nimport { RangeCalendarNext, type RangeCalendarNextProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarNextProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <RangeCalendarNext\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronRight class=\"h-4 w-4\" />\n </slot>\n </RangeCalendarNext>\n</template>\n",
"type": "registry:ui",
"target": "range-calendar/RangeCalendarNextButton.vue"
},
{
"path": "ui/range-calendar/RangeCalendarPrevButton.vue",
"content": "<script lang=\"ts\" setup>\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ChevronLeft } from 'lucide-vue-next'\nimport { RangeCalendarPrev, type RangeCalendarPrevProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarPrevProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <RangeCalendarPrev\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronLeft class=\"h-4 w-4\" />\n </slot>\n </RangeCalendarPrev>\n</template>\n",
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { ChevronLeft } from 'lucide-vue-next'\nimport { RangeCalendarPrev, type RangeCalendarPrevProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarPrevProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <RangeCalendarPrev\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronLeft class=\"h-4 w-4\" />\n </slot>\n </RangeCalendarPrev>\n</template>\n",
"type": "registry:ui",
"target": "range-calendar/RangeCalendarPrevButton.vue"
},

View File

@ -5,9 +5,9 @@
"@vueuse/core"
],
"registryDependencies": [
"utils",
"Sheet.vue",
"SheetContent.vue",
"utils",
"Input.vue",
"Tooltip.vue",
"TooltipContent.vue",
@ -19,7 +19,7 @@
"files": [
{
"path": "ui/sidebar/Sidebar.vue",
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Sheet from '@/registry/default/ui/sheet/Sheet.vue'\nimport SheetContent from '@/registry/default/ui/sheet/SheetContent.vue'\nimport { cn } from '@/lib/utils'\nimport { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n side?: 'left' | 'right'\n variant?: 'sidebar' | 'floating' | 'inset'\n collapsible?: 'offcanvas' | 'icon' | 'none'\n class?: HTMLAttributes['class']\n}>(), {\n side: 'left',\n variant: 'sidebar',\n collapsible: 'offcanvas',\n})\n\nconst { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n</script>\n\n<template>\n <div\n v-if=\"collapsible === 'none'\"\n :class=\"cn('flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground', props.class)\"\n v-bind=\"$attrs\"\n >\n <slot />\n </div>\n\n <Sheet v-else-if=\"isMobile\" :open=\"openMobile\" v-bind=\"$attrs\" @update:open=\"setOpenMobile\">\n <SheetContent\n data-sidebar=\"sidebar\"\n data-mobile=\"true\"\n :side=\"side\"\n class=\"w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH_MOBILE,\n }\"\n >\n <div class=\"flex h-full w-full flex-col\">\n <slot />\n </div>\n </SheetContent>\n </Sheet>\n\n <div\n v-else class=\"group peer hidden md:block\"\n :data-state=\"state\"\n :data-collapsible=\"state === 'collapsed' ? collapsible : ''\"\n :data-variant=\"variant\"\n :data-side=\"side\"\n >\n <!-- This is what handles the sidebar gap on desktop -->\n <div\n :class=\"cn(\n 'duration-200 relative h-svh w-[--sidebar-width] bg-transparent transition-[width] ease-linear',\n 'group-data-[collapsible=offcanvas]:w-0',\n 'group-data-[side=right]:rotate-180',\n variant === 'floating' || variant === 'inset'\n ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]',\n )\"\n />\n <div\n :class=\"cn(\n 'duration-200 fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] ease-linear md:flex',\n side === 'left'\n ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'\n : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',\n // Adjust the padding for floating and inset variants.\n variant === 'floating' || variant === 'inset'\n ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l',\n props.class,\n )\"\n v-bind=\"$attrs\"\n >\n <div\n data-sidebar=\"sidebar\"\n class=\"flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow\"\n >\n <slot />\n </div>\n </div>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport Sheet from '@/registry/default/ui/sheet/Sheet.vue'\nimport SheetContent from '@/registry/default/ui/sheet/SheetContent.vue'\nimport { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n side?: 'left' | 'right'\n variant?: 'sidebar' | 'floating' | 'inset'\n collapsible?: 'offcanvas' | 'icon' | 'none'\n class?: HTMLAttributes['class']\n}>(), {\n side: 'left',\n variant: 'sidebar',\n collapsible: 'offcanvas',\n})\n\nconst { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n</script>\n\n<template>\n <div\n v-if=\"collapsible === 'none'\"\n :class=\"cn('flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground', props.class)\"\n v-bind=\"$attrs\"\n >\n <slot />\n </div>\n\n <Sheet v-else-if=\"isMobile\" :open=\"openMobile\" v-bind=\"$attrs\" @update:open=\"setOpenMobile\">\n <SheetContent\n data-sidebar=\"sidebar\"\n data-mobile=\"true\"\n :side=\"side\"\n class=\"w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH_MOBILE,\n }\"\n >\n <div class=\"flex h-full w-full flex-col\">\n <slot />\n </div>\n </SheetContent>\n </Sheet>\n\n <div\n v-else class=\"group peer hidden md:block\"\n :data-state=\"state\"\n :data-collapsible=\"state === 'collapsed' ? collapsible : ''\"\n :data-variant=\"variant\"\n :data-side=\"side\"\n >\n <!-- This is what handles the sidebar gap on desktop -->\n <div\n :class=\"cn(\n 'duration-200 relative h-svh w-[--sidebar-width] bg-transparent transition-[width] ease-linear',\n 'group-data-[collapsible=offcanvas]:w-0',\n 'group-data-[side=right]:rotate-180',\n variant === 'floating' || variant === 'inset'\n ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]',\n )\"\n />\n <div\n :class=\"cn(\n 'duration-200 fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] ease-linear md:flex',\n side === 'left'\n ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'\n : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',\n // Adjust the padding for floating and inset variants.\n variant === 'floating' || variant === 'inset'\n ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l',\n props.class,\n )\"\n v-bind=\"$attrs\"\n >\n <div\n data-sidebar=\"sidebar\"\n class=\"flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow\"\n >\n <slot />\n </div>\n </div>\n </div>\n</template>\n",
"type": "registry:ui",
"target": "sidebar/Sidebar.vue"
},
@ -67,7 +67,7 @@
},
{
"path": "ui/sidebar/SidebarInput.vue",
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Input from '@/registry/default/ui/input/Input.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Input\n data-sidebar=\"input\"\n :class=\"cn(\n 'h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring',\n props.class,\n )\"\n >\n <slot />\n </Input>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport Input from '@/registry/default/ui/input/Input.vue'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Input\n data-sidebar=\"input\"\n :class=\"cn(\n 'h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring',\n props.class,\n )\"\n >\n <slot />\n </Input>\n</template>\n",
"type": "registry:ui",
"target": "sidebar/SidebarInput.vue"
},
@ -115,7 +115,7 @@
},
{
"path": "ui/sidebar/SidebarMenuSkeleton.vue",
"content": "<script setup lang=\"ts\">\nimport Skeleton from '@/registry/default/ui/skeleton/Skeleton.vue'\nimport { cn } from '@/lib/utils'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n showIcon?: boolean\n class?: HTMLAttributes['class']\n}>()\n\nconst width = computed(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n})\n</script>\n\n<template>\n <div\n data-sidebar=\"menu-skeleton\"\n :class=\"cn('rounded-md h-8 flex gap-2 px-2 items-center', props.class)\"\n >\n <Skeleton\n v-if=\"showIcon\"\n class=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n\n <Skeleton\n class=\"h-4 flex-1 max-w-[--skeleton-width]\"\n data-sidebar=\"menu-skeleton-text\"\n :style=\"{ '--skeleton-width': width }\"\n />\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport Skeleton from '@/registry/default/ui/skeleton/Skeleton.vue'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n showIcon?: boolean\n class?: HTMLAttributes['class']\n}>()\n\nconst width = computed(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n})\n</script>\n\n<template>\n <div\n data-sidebar=\"menu-skeleton\"\n :class=\"cn('rounded-md h-8 flex gap-2 px-2 items-center', props.class)\"\n >\n <Skeleton\n v-if=\"showIcon\"\n class=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n\n <Skeleton\n class=\"h-4 flex-1 max-w-[--skeleton-width]\"\n data-sidebar=\"menu-skeleton-text\"\n :style=\"{ '--skeleton-width': width }\"\n />\n </div>\n</template>\n",
"type": "registry:ui",
"target": "sidebar/SidebarMenuSkeleton.vue"
},
@ -151,13 +151,13 @@
},
{
"path": "ui/sidebar/SidebarSeparator.vue",
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Separator from '@/registry/default/ui/separator/Separator.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Separator\n data-sidebar=\"separator\"\n :class=\"cn('mx-2 w-auto bg-sidebar-border', props.class)\"\n >\n <slot />\n </Separator>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport Separator from '@/registry/default/ui/separator/Separator.vue'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Separator\n data-sidebar=\"separator\"\n :class=\"cn('mx-2 w-auto bg-sidebar-border', props.class)\"\n >\n <slot />\n </Separator>\n</template>\n",
"type": "registry:ui",
"target": "sidebar/SidebarSeparator.vue"
},
{
"path": "ui/sidebar/SidebarTrigger.vue",
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Button from '@/registry/default/ui/button/Button.vue'\nimport { cn } from '@/lib/utils'\nimport { PanelLeft } from 'lucide-vue-next'\nimport { useSidebar } from './utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst { toggleSidebar } = useSidebar()\n</script>\n\n<template>\n <Button\n data-sidebar=\"trigger\"\n variant=\"ghost\"\n size=\"icon\"\n :class=\"cn('h-7 w-7', props.class)\"\n @click=\"toggleSidebar\"\n >\n <PanelLeft />\n <span class=\"sr-only\">Toggle Sidebar</span>\n </Button>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport Button from '@/registry/default/ui/button/Button.vue'\nimport { PanelLeft } from 'lucide-vue-next'\nimport { useSidebar } from './utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst { toggleSidebar } = useSidebar()\n</script>\n\n<template>\n <Button\n data-sidebar=\"trigger\"\n variant=\"ghost\"\n size=\"icon\"\n :class=\"cn('h-7 w-7', props.class)\"\n @click=\"toggleSidebar\"\n >\n <PanelLeft />\n <span class=\"sr-only\">Toggle Sidebar</span>\n </Button>\n</template>\n",
"type": "registry:ui",
"target": "sidebar/SidebarTrigger.vue"
},

View File

@ -15,7 +15,7 @@
},
{
"path": "ui/toggle-group/ToggleGroupItem.vue",
"content": "<script setup lang=\"ts\">\nimport type { VariantProps } from 'class-variance-authority'\nimport { toggleVariants } from '@/registry/default/ui/toggle'\nimport { cn } from '@/lib/utils'\nimport { ToggleGroupItem, type ToggleGroupItemProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes, inject } from 'vue'\n\ntype ToggleGroupVariants = VariantProps<typeof toggleVariants>\n\nconst props = defineProps<ToggleGroupItemProps & {\n class?: HTMLAttributes['class']\n variant?: ToggleGroupVariants['variant']\n size?: ToggleGroupVariants['size']\n}>()\n\nconst context = inject<ToggleGroupVariants>('toggleGroup')\n\nconst delegatedProps = computed(() => {\n const { class: _, variant, size, ...delegated } = props\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <ToggleGroupItem\n v-bind=\"forwardedProps\" :class=\"cn(toggleVariants({\n variant: context?.variant || variant,\n size: context?.size || size,\n }), props.class)\"\n >\n <slot />\n </ToggleGroupItem>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\nimport { toggleVariants } from '@/registry/default/ui/toggle'\nimport { ToggleGroupItem, type ToggleGroupItemProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes, inject } from 'vue'\n\ntype ToggleGroupVariants = VariantProps<typeof toggleVariants>\n\nconst props = defineProps<ToggleGroupItemProps & {\n class?: HTMLAttributes['class']\n variant?: ToggleGroupVariants['variant']\n size?: ToggleGroupVariants['size']\n}>()\n\nconst context = inject<ToggleGroupVariants>('toggleGroup')\n\nconst delegatedProps = computed(() => {\n const { class: _, variant, size, ...delegated } = props\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <ToggleGroupItem\n v-bind=\"forwardedProps\" :class=\"cn(toggleVariants({\n variant: context?.variant || variant,\n size: context?.size || size,\n }), props.class)\"\n >\n <slot />\n </ToggleGroupItem>\n</template>\n",
"type": "registry:ui",
"target": "toggle-group/ToggleGroupItem.vue"
},

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,18 @@
"name": "Authentication01",
"type": "registry:block",
"dependencies": [],
"registryDependencies": [],
"files": []
"registryDependencies": [
"button",
"card",
"input",
"label"
],
"files": [
{
"path": "block/Authentication01.vue",
"content": "<script lang=\"ts\">\nexport const description\n = 'A simple login form with email and password. The submit button says \\'Sign in\\'.'\nexport const iframeHeight = '600px'\nexport const containerClass = 'w-full h-screen flex items-center justify-center px-4'\n</script>\n\n<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/registry/new-york/ui/card'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\n</script>\n\n<template>\n <Card class=\"w-full max-w-sm\">\n <CardHeader>\n <CardTitle class=\"text-2xl\">\n Login\n </CardTitle>\n <CardDescription>\n Enter your email below to login to your account.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"grid gap-4\">\n <div class=\"grid gap-2\">\n <Label for=\"email\">Email</Label>\n <Input id=\"email\" type=\"email\" placeholder=\"m@example.com\" required />\n </div>\n <div class=\"grid gap-2\">\n <Label for=\"password\">Password</Label>\n <Input id=\"password\" type=\"password\" required />\n </div>\n </CardContent>\n <CardFooter>\n <Button class=\"w-full\">\n Sign in\n </Button>\n </CardFooter>\n </Card>\n</template>\n",
"type": "registry:block",
"target": "Authentication01.vue"
}
]
}

View File

@ -2,6 +2,18 @@
"name": "Authentication02",
"type": "registry:block",
"dependencies": [],
"registryDependencies": [],
"files": []
"registryDependencies": [
"button",
"card",
"input",
"label"
],
"files": [
{
"path": "block/Authentication02.vue",
"content": "<script lang=\"ts\">\nexport const description\n = 'A login form with email and password. There\\'s an option to login with Google and a link to sign up if you don\\'t have an account.'\nexport const iframeHeight = '600px'\nexport const containerClass = 'w-full h-screen flex items-center justify-center px-4'\n</script>\n\n<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/registry/new-york/ui/card'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\n</script>\n\n<template>\n <Card class=\"mx-auto max-w-sm\">\n <CardHeader>\n <CardTitle class=\"text-2xl\">\n Login\n </CardTitle>\n <CardDescription>\n Enter your email below to login to your account\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div class=\"grid gap-4\">\n <div class=\"grid gap-2\">\n <Label for=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"m@example.com\"\n required\n />\n </div>\n <div class=\"grid gap-2\">\n <div class=\"flex items-center\">\n <Label for=\"password\">Password</Label>\n <a href=\"#\" class=\"ml-auto inline-block text-sm underline\">\n Forgot your password?\n </a>\n </div>\n <Input id=\"password\" type=\"password\" required />\n </div>\n <Button type=\"submit\" class=\"w-full\">\n Login\n </Button>\n <Button variant=\"outline\" class=\"w-full\">\n Login with Google\n </Button>\n </div>\n <div class=\"mt-4 text-center text-sm\">\n Don't have an account?\n <a href=\"#\" class=\"underline\">\n Sign up\n </a>\n </div>\n </CardContent>\n </Card>\n</template>\n",
"type": "registry:block",
"target": "Authentication02.vue"
}
]
}

View File

@ -2,6 +2,18 @@
"name": "Authentication03",
"type": "registry:block",
"dependencies": [],
"registryDependencies": [],
"files": []
"registryDependencies": [
"button",
"card",
"input",
"label"
],
"files": [
{
"path": "block/Authentication03.vue",
"content": "<script lang=\"ts\">\nexport const description\n = 'A sign up form with first name, last name, email and password inside a card. There\\'s an option to sign up with GitHub and a link to login if you already have an account'\nexport const iframeHeight = '600px'\nexport const containerClass = 'w-full h-screen flex items-center justify-center px-4'\n</script>\n\n<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/registry/new-york/ui/card'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\n</script>\n\n<template>\n <Card class=\"mx-auto max-w-sm\">\n <CardHeader>\n <CardTitle class=\"text-xl\">\n Sign Up\n </CardTitle>\n <CardDescription>\n Enter your information to create an account\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div class=\"grid gap-4\">\n <div class=\"grid grid-cols-2 gap-4\">\n <div class=\"grid gap-2\">\n <Label for=\"first-name\">First name</Label>\n <Input id=\"first-name\" placeholder=\"Max\" required />\n </div>\n <div class=\"grid gap-2\">\n <Label for=\"last-name\">Last name</Label>\n <Input id=\"last-name\" placeholder=\"Robinson\" required />\n </div>\n </div>\n <div class=\"grid gap-2\">\n <Label for=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"m@example.com\"\n required\n />\n </div>\n <div class=\"grid gap-2\">\n <Label for=\"password\">Password</Label>\n <Input id=\"password\" type=\"password\" />\n </div>\n <Button type=\"submit\" class=\"w-full\">\n Create an account\n </Button>\n <Button variant=\"outline\" class=\"w-full\">\n Sign up with GitHub\n </Button>\n </div>\n <div class=\"mt-4 text-center text-sm\">\n Already have an account?\n <a href=\"#\" class=\"underline\">\n Sign in\n </a>\n </div>\n </CardContent>\n </Card>\n</template>\n",
"type": "registry:block",
"target": "Authentication03.vue"
}
]
}

View File

@ -2,6 +2,17 @@
"name": "Authentication04",
"type": "registry:block",
"dependencies": [],
"registryDependencies": [],
"files": []
"registryDependencies": [
"button",
"input",
"label"
],
"files": [
{
"path": "block/Authentication04.vue",
"content": "<script lang=\"ts\">\nexport const description\n = 'A login page with two columns. The first column has the login form with email and password. There\\'s a Forgot your passwork link and a link to sign up if you do not have an account. The second column has a cover image.'\nexport const iframeHeight = '800px'\nexport const containerClass = 'w-full h-full p-4 lg:p-0'\n</script>\n\n<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\n</script>\n\n<template>\n <div class=\"w-full lg:grid lg:min-h-[600px] lg:grid-cols-2 xl:min-h-[800px]\">\n <div class=\"flex items-center justify-center py-12\">\n <div class=\"mx-auto grid w-[350px] gap-6\">\n <div class=\"grid gap-2 text-center\">\n <h1 class=\"text-3xl font-bold\">\n Login\n </h1>\n <p class=\"text-balance text-muted-foreground\">\n Enter your email below to login to your account\n </p>\n </div>\n <div class=\"grid gap-4\">\n <div class=\"grid gap-2\">\n <Label for=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"m@example.com\"\n required\n />\n </div>\n <div class=\"grid gap-2\">\n <div class=\"flex items-center\">\n <Label for=\"password\">Password</Label>\n <a\n href=\"/forgot-password\"\n class=\"ml-auto inline-block text-sm underline\"\n >\n Forgot your password?\n </a>\n </div>\n <Input id=\"password\" type=\"password\" required />\n </div>\n <Button type=\"submit\" class=\"w-full\">\n Login\n </Button>\n <Button variant=\"outline\" class=\"w-full\">\n Login with Google\n </Button>\n </div>\n <div class=\"mt-4 text-center text-sm\">\n Don't have an account?\n <a href=\"#\" class=\"underline\">\n Sign up\n </a>\n </div>\n </div>\n </div>\n <div class=\"hidden bg-muted lg:block\">\n <img\n src=\"/placeholder.svg\"\n alt=\"Image\"\n width=\"1920\"\n height=\"1080\"\n class=\"h-full w-full object-cover dark:brightness-[0.2] dark:grayscale\"\n >\n </div>\n </div>\n</template>\n",
"type": "registry:block",
"target": "Authentication04.vue"
}
]
}

View File

@ -7,17 +7,17 @@
"zod"
],
"registryDependencies": [
"utils",
"button",
"calendar",
"form",
"popover",
"toast",
"utils"
"toast"
],
"files": [
{
"path": "example/CalendarForm.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Calendar } from '@/registry/new-york/ui/calendar'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/new-york/ui/form'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { cn } from '@/lib/utils'\nimport { CalendarDate, DateFormatter, getLocalTimeZone, parseDate, today } from '@internationalized/date'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { toDate } from 'reka-ui/date'\nimport { useForm } from 'vee-validate'\nimport { computed, h, ref } from 'vue'\nimport { z } from 'zod'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst formSchema = toTypedSchema(z.object({\n dob: z\n .string()\n .refine(v => v, { message: 'A date of birth is required.' }),\n}))\n\nconst placeholder = ref()\n\nconst { handleSubmit, setFieldValue, values } = useForm({\n validationSchema: formSchema,\n})\n\nconst value = computed({\n get: () => values.dob ? parseDate(values.dob) : undefined,\n set: val => val,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-8\" @submit=\"onSubmit\">\n <FormField name=\"dob\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\" :class=\"cn(\n 'w-[240px] ps-3 text-start font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <span>{{ value ? df.format(toDate(value)) : \"Pick a date\" }}</span>\n <CalendarIcon class=\"ms-auto h-4 w-4 opacity-50\" />\n </Button>\n <input hidden>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar\n v-model:placeholder=\"placeholder\"\n v-model=\"value\"\n calendar-label=\"Date of birth\"\n initial-focus\n :min-value=\"new CalendarDate(1900, 1, 1)\"\n :max-value=\"today(getLocalTimeZone())\"\n @update:model-value=\"(v) => {\n if (v) {\n setFieldValue('dob', v.toString())\n }\n else {\n setFieldValue('dob', undefined)\n }\n }\"\n />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Calendar } from '@/registry/new-york/ui/calendar'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/new-york/ui/form'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { CalendarDate, DateFormatter, getLocalTimeZone, parseDate, today } from '@internationalized/date'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { toDate } from 'reka-ui/date'\nimport { useForm } from 'vee-validate'\nimport { computed, h, ref } from 'vue'\nimport { z } from 'zod'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst formSchema = toTypedSchema(z.object({\n dob: z\n .string()\n .refine(v => v, { message: 'A date of birth is required.' }),\n}))\n\nconst placeholder = ref()\n\nconst { handleSubmit, setFieldValue, values } = useForm({\n validationSchema: formSchema,\n})\n\nconst value = computed({\n get: () => values.dob ? parseDate(values.dob) : undefined,\n set: val => val,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-8\" @submit=\"onSubmit\">\n <FormField name=\"dob\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\" :class=\"cn(\n 'w-[240px] ps-3 text-start font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <span>{{ value ? df.format(toDate(value)) : \"Pick a date\" }}</span>\n <CalendarIcon class=\"ms-auto h-4 w-4 opacity-50\" />\n </Button>\n <input hidden>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar\n v-model:placeholder=\"placeholder\"\n v-model=\"value\"\n calendar-label=\"Date of birth\"\n initial-focus\n :min-value=\"new CalendarDate(1900, 1, 1)\"\n :max-value=\"today(getLocalTimeZone())\"\n @update:model-value=\"(v) => {\n if (v) {\n setFieldValue('dob', v.toString())\n }\n else {\n setFieldValue('dob', undefined)\n }\n }\"\n />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
"type": "registry:example",
"target": "CalendarForm.vue"
}

View File

@ -5,14 +5,14 @@
"@vueuse/core"
],
"registryDependencies": [
"utils",
"calendar",
"select",
"utils"
"select"
],
"files": [
{
"path": "example/CalendarWithSelect.vue",
"content": "<script setup lang=\"ts\">\nimport { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, CalendarGridHead, CalendarGridRow, CalendarHeadCell, CalendarHeader, CalendarHeading } from '@/registry/new-york/ui/calendar'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/new-york/ui/select'\nimport { cn } from '@/lib/utils'\nimport { type DateValue, getLocalTimeZone, today } from '@internationalized/date'\nimport { useVModel } from '@vueuse/core'\nimport { CalendarRoot, type CalendarRootEmits, type CalendarRootProps, useDateFormatter, useForwardPropsEmits } from 'reka-ui'\nimport { createDecade, createYear, toDate } from 'reka-ui/date'\nimport { computed, type HTMLAttributes, type Ref } from 'vue'\n\nconst props = withDefaults(defineProps<CalendarRootProps & { class?: HTMLAttributes['class'] }>(), {\n modelValue: undefined,\n placeholder() {\n return today(getLocalTimeZone())\n },\n weekdayFormat: 'short',\n})\nconst emits = defineEmits<CalendarRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, placeholder: __, ...delegated } = props\n\n return delegated\n})\n\nconst placeholder = useVModel(props, 'modelValue', emits, {\n passive: true,\n defaultValue: today(getLocalTimeZone()),\n}) as Ref<DateValue>\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n\nconst formatter = useDateFormatter('en')\n</script>\n\n<template>\n <CalendarRoot\n v-slot=\"{ date, grid, weekDays }\"\n v-model:placeholder=\"placeholder\"\n v-bind=\"forwarded\"\n :class=\"cn('rounded-md border p-3', props.class)\"\n >\n <CalendarHeader>\n <CalendarHeading class=\"flex w-full items-center justify-between gap-2\">\n <Select\n :default-value=\"placeholder.month.toString()\"\n @update:model-value=\"(v) => {\n if (!v || !placeholder) return;\n if (Number(v) === placeholder?.month) return;\n placeholder = placeholder.set({\n month: Number(v),\n })\n }\"\n >\n <SelectTrigger aria-label=\"Select month\" class=\"w-[60%]\">\n <SelectValue placeholder=\"Select month\" />\n </SelectTrigger>\n <SelectContent class=\"max-h-[200px]\">\n <SelectItem\n v-for=\"month in createYear({ dateObj: date })\"\n :key=\"month.toString()\" :value=\"month.month.toString()\"\n >\n {{ formatter.custom(toDate(month), { month: 'long' }) }}\n </SelectItem>\n </SelectContent>\n </Select>\n\n <Select\n :default-value=\"placeholder.year.toString()\"\n @update:model-value=\"(v) => {\n if (!v || !placeholder) return;\n if (Number(v) === placeholder?.year) return;\n placeholder = placeholder.set({\n year: Number(v),\n })\n }\"\n >\n <SelectTrigger aria-label=\"Select year\" class=\"w-[40%]\">\n <SelectValue placeholder=\"Select year\" />\n </SelectTrigger>\n <SelectContent class=\"max-h-[200px]\">\n <SelectItem\n v-for=\"yearValue in createDecade({ dateObj: date, startIndex: -10, endIndex: 10 })\"\n :key=\"yearValue.toString()\" :value=\"yearValue.year.toString()\"\n >\n {{ yearValue.year }}\n </SelectItem>\n </SelectContent>\n </Select>\n </CalendarHeading>\n </CalendarHeader>\n\n <div class=\"flex flex-col space-y-4 pt-4 sm:flex-row sm:gap-x-4 sm:gap-y-0\">\n <CalendarGrid v-for=\"month in grid\" :key=\"month.value.toString()\">\n <CalendarGridHead>\n <CalendarGridRow>\n <CalendarHeadCell\n v-for=\"day in weekDays\" :key=\"day\"\n >\n {{ day }}\n </CalendarHeadCell>\n </CalendarGridRow>\n </CalendarGridHead>\n <CalendarGridBody class=\"grid\">\n <CalendarGridRow v-for=\"(weekDates, index) in month.rows\" :key=\"`weekDate-${index}`\" class=\"mt-2 w-full\">\n <CalendarCell\n v-for=\"weekDate in weekDates\"\n :key=\"weekDate.toString()\"\n :date=\"weekDate\"\n >\n <CalendarCellTrigger\n :day=\"weekDate\"\n :month=\"month.value\"\n />\n </CalendarCell>\n </CalendarGridRow>\n </CalendarGridBody>\n </CalendarGrid>\n </div>\n </CalendarRoot>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, CalendarGridHead, CalendarGridRow, CalendarHeadCell, CalendarHeader, CalendarHeading } from '@/registry/new-york/ui/calendar'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/new-york/ui/select'\nimport { type DateValue, getLocalTimeZone, today } from '@internationalized/date'\nimport { useVModel } from '@vueuse/core'\nimport { CalendarRoot, type CalendarRootEmits, type CalendarRootProps, useDateFormatter, useForwardPropsEmits } from 'reka-ui'\nimport { createDecade, createYear, toDate } from 'reka-ui/date'\nimport { computed, type HTMLAttributes, type Ref } from 'vue'\n\nconst props = withDefaults(defineProps<CalendarRootProps & { class?: HTMLAttributes['class'] }>(), {\n modelValue: undefined,\n placeholder() {\n return today(getLocalTimeZone())\n },\n weekdayFormat: 'short',\n})\nconst emits = defineEmits<CalendarRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, placeholder: __, ...delegated } = props\n\n return delegated\n})\n\nconst placeholder = useVModel(props, 'modelValue', emits, {\n passive: true,\n defaultValue: today(getLocalTimeZone()),\n}) as Ref<DateValue>\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n\nconst formatter = useDateFormatter('en')\n</script>\n\n<template>\n <CalendarRoot\n v-slot=\"{ date, grid, weekDays }\"\n v-model:placeholder=\"placeholder\"\n v-bind=\"forwarded\"\n :class=\"cn('rounded-md border p-3', props.class)\"\n >\n <CalendarHeader>\n <CalendarHeading class=\"flex w-full items-center justify-between gap-2\">\n <Select\n :default-value=\"placeholder.month.toString()\"\n @update:model-value=\"(v) => {\n if (!v || !placeholder) return;\n if (Number(v) === placeholder?.month) return;\n placeholder = placeholder.set({\n month: Number(v),\n })\n }\"\n >\n <SelectTrigger aria-label=\"Select month\" class=\"w-[60%]\">\n <SelectValue placeholder=\"Select month\" />\n </SelectTrigger>\n <SelectContent class=\"max-h-[200px]\">\n <SelectItem\n v-for=\"month in createYear({ dateObj: date })\"\n :key=\"month.toString()\" :value=\"month.month.toString()\"\n >\n {{ formatter.custom(toDate(month), { month: 'long' }) }}\n </SelectItem>\n </SelectContent>\n </Select>\n\n <Select\n :default-value=\"placeholder.year.toString()\"\n @update:model-value=\"(v) => {\n if (!v || !placeholder) return;\n if (Number(v) === placeholder?.year) return;\n placeholder = placeholder.set({\n year: Number(v),\n })\n }\"\n >\n <SelectTrigger aria-label=\"Select year\" class=\"w-[40%]\">\n <SelectValue placeholder=\"Select year\" />\n </SelectTrigger>\n <SelectContent class=\"max-h-[200px]\">\n <SelectItem\n v-for=\"yearValue in createDecade({ dateObj: date, startIndex: -10, endIndex: 10 })\"\n :key=\"yearValue.toString()\" :value=\"yearValue.year.toString()\"\n >\n {{ yearValue.year }}\n </SelectItem>\n </SelectContent>\n </Select>\n </CalendarHeading>\n </CalendarHeader>\n\n <div class=\"flex flex-col space-y-4 pt-4 sm:flex-row sm:gap-x-4 sm:gap-y-0\">\n <CalendarGrid v-for=\"month in grid\" :key=\"month.value.toString()\">\n <CalendarGridHead>\n <CalendarGridRow>\n <CalendarHeadCell\n v-for=\"day in weekDays\" :key=\"day\"\n >\n {{ day }}\n </CalendarHeadCell>\n </CalendarGridRow>\n </CalendarGridHead>\n <CalendarGridBody class=\"grid\">\n <CalendarGridRow v-for=\"(weekDates, index) in month.rows\" :key=\"`weekDate-${index}`\" class=\"mt-2 w-full\">\n <CalendarCell\n v-for=\"weekDate in weekDates\"\n :key=\"weekDate.toString()\"\n :date=\"weekDate\"\n >\n <CalendarCellTrigger\n :day=\"weekDate\"\n :month=\"month.value\"\n />\n </CalendarCell>\n </CalendarGridRow>\n </CalendarGridBody>\n </CalendarGrid>\n </div>\n </CalendarRoot>\n</template>\n",
"type": "registry:example",
"target": "CalendarWithSelect.vue"
}

File diff suppressed because one or more lines are too long

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"card",
"switch",
"utils"
"switch"
],
"files": [
{
"path": "example/CardDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from '@/registry/new-york/ui/card'\nimport { Switch } from '@/registry/new-york/ui/switch'\nimport { cn } from '@/lib/utils'\nimport { BellIcon, CheckIcon } from '@radix-icons/vue'\n\nconst notifications = [\n {\n title: 'Your call has been confirmed.',\n description: '1 hour ago',\n },\n {\n title: 'You have a new message!',\n description: '1 hour ago',\n },\n {\n title: 'Your subscription is expiring soon!',\n description: '2 hours ago',\n },\n]\n</script>\n\n<template>\n <Card :class=\"cn('w-[380px]', $attrs.class ?? '')\">\n <CardHeader>\n <CardTitle>Notifications</CardTitle>\n <CardDescription>You have 3 unread messages.</CardDescription>\n </CardHeader>\n <CardContent class=\"grid gap-4\">\n <div class=\" flex items-center space-x-4 rounded-md border p-4\">\n <BellIcon />\n <div class=\"flex-1 space-y-1\">\n <p class=\"text-sm font-medium leading-none\">\n Push Notifications\n </p>\n <p class=\"text-sm text-muted-foreground\">\n Send notifications to device.\n </p>\n </div>\n <Switch />\n </div>\n <div>\n <div\n v-for=\"(notification, index) in notifications\" :key=\"index\"\n class=\"mb-4 grid grid-cols-[25px_minmax(0,1fr)] items-start pb-4 last:mb-0 last:pb-0\"\n >\n <span class=\"flex h-2 w-2 translate-y-1 rounded-full bg-sky-500\" />\n <div class=\"space-y-1\">\n <p class=\"text-sm font-medium leading-none\">\n {{ notification.title }}\n </p>\n <p class=\"text-sm text-muted-foreground\">\n {{ notification.description }}\n </p>\n </div>\n </div>\n </div>\n </CardContent>\n <CardFooter>\n <Button class=\"w-full\">\n <CheckIcon class=\"mr-2 h-4 w-4\" /> Mark all as read\n </Button>\n </CardFooter>\n </Card>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from '@/registry/new-york/ui/card'\nimport { Switch } from '@/registry/new-york/ui/switch'\nimport { BellIcon, CheckIcon } from '@radix-icons/vue'\n\nconst notifications = [\n {\n title: 'Your call has been confirmed.',\n description: '1 hour ago',\n },\n {\n title: 'You have a new message!',\n description: '1 hour ago',\n },\n {\n title: 'Your subscription is expiring soon!',\n description: '2 hours ago',\n },\n]\n</script>\n\n<template>\n <Card :class=\"cn('w-[380px]', $attrs.class ?? '')\">\n <CardHeader>\n <CardTitle>Notifications</CardTitle>\n <CardDescription>You have 3 unread messages.</CardDescription>\n </CardHeader>\n <CardContent class=\"grid gap-4\">\n <div class=\" flex items-center space-x-4 rounded-md border p-4\">\n <BellIcon />\n <div class=\"flex-1 space-y-1\">\n <p class=\"text-sm font-medium leading-none\">\n Push Notifications\n </p>\n <p class=\"text-sm text-muted-foreground\">\n Send notifications to device.\n </p>\n </div>\n <Switch />\n </div>\n <div>\n <div\n v-for=\"(notification, index) in notifications\" :key=\"index\"\n class=\"mb-4 grid grid-cols-[25px_minmax(0,1fr)] items-start pb-4 last:mb-0 last:pb-0\"\n >\n <span class=\"flex h-2 w-2 translate-y-1 rounded-full bg-sky-500\" />\n <div class=\"space-y-1\">\n <p class=\"text-sm font-medium leading-none\">\n {{ notification.title }}\n </p>\n <p class=\"text-sm text-muted-foreground\">\n {{ notification.description }}\n </p>\n </div>\n </div>\n </div>\n </CardContent>\n <CardFooter>\n <Button class=\"w-full\">\n <CheckIcon class=\"mr-2 h-4 w-4\" /> Mark all as read\n </Button>\n </CardFooter>\n </Card>\n</template>\n",
"type": "registry:example",
"target": "CardDemo.vue"
}

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"command",
"popover",
"utils"
"popover"
],
"files": [
{
"path": "example/ComboboxDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/registry/new-york/ui/command'\n\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\nimport { cn } from '@/lib/utils'\nimport { CaretSortIcon, CheckIcon } from '@radix-icons/vue'\nimport { ref } from 'vue'\n\nconst frameworks = [\n { value: 'next.js', label: 'Next.js' },\n { value: 'sveltekit', label: 'SvelteKit' },\n { value: 'nuxt', label: 'Nuxt' },\n { value: 'remix', label: 'Remix' },\n { value: 'astro', label: 'Astro' },\n]\n\nconst open = ref(false)\nconst value = ref('')\n</script>\n\n<template>\n <Popover v-model:open=\"open\">\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n :aria-expanded=\"open\"\n class=\"w-[200px] justify-between\"\n >\n {{ value\n ? frameworks.find((framework) => framework.value === value)?.label\n : \"Select framework...\" }}\n <CaretSortIcon class=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-[200px] p-0\">\n <Command>\n <CommandInput class=\"h-9\" placeholder=\"Search framework...\" />\n <CommandEmpty>No framework found.</CommandEmpty>\n <CommandList>\n <CommandGroup>\n <CommandItem\n v-for=\"framework in frameworks\"\n :key=\"framework.value\"\n :value=\"framework.value\"\n @select=\"(ev) => {\n if (typeof ev.detail.value === 'string') {\n value = ev.detail.value\n }\n open = false\n }\"\n >\n {{ framework.label }}\n <CheckIcon\n :class=\"cn(\n 'ml-auto h-4 w-4',\n value === framework.value ? 'opacity-100' : 'opacity-0',\n )\"\n />\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\n\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/registry/new-york/ui/command'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\nimport { CaretSortIcon, CheckIcon } from '@radix-icons/vue'\nimport { ref } from 'vue'\n\nconst frameworks = [\n { value: 'next.js', label: 'Next.js' },\n { value: 'sveltekit', label: 'SvelteKit' },\n { value: 'nuxt', label: 'Nuxt' },\n { value: 'remix', label: 'Remix' },\n { value: 'astro', label: 'Astro' },\n]\n\nconst open = ref(false)\nconst value = ref('')\n</script>\n\n<template>\n <Popover v-model:open=\"open\">\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n :aria-expanded=\"open\"\n class=\"w-[200px] justify-between\"\n >\n {{ value\n ? frameworks.find((framework) => framework.value === value)?.label\n : \"Select framework...\" }}\n <CaretSortIcon class=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-[200px] p-0\">\n <Command>\n <CommandInput class=\"h-9\" placeholder=\"Search framework...\" />\n <CommandEmpty>No framework found.</CommandEmpty>\n <CommandList>\n <CommandGroup>\n <CommandItem\n v-for=\"framework in frameworks\"\n :key=\"framework.value\"\n :value=\"framework.value\"\n @select=\"(ev) => {\n if (typeof ev.detail.value === 'string') {\n value = ev.detail.value\n }\n open = false\n }\"\n >\n {{ framework.label }}\n <CheckIcon\n :class=\"cn(\n 'ml-auto h-4 w-4',\n value === framework.value ? 'opacity-100' : 'opacity-0',\n )\"\n />\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "ComboboxDemo.vue"
}

View File

@ -7,17 +7,17 @@
"zod"
],
"registryDependencies": [
"utils",
"button",
"command",
"form",
"popover",
"toast",
"utils"
"toast"
],
"files": [
{
"path": "example/ComboboxForm.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/registry/new-york/ui/command'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/new-york/ui/form'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\n\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { cn } from '@/lib/utils'\nimport { CaretSortIcon, CheckIcon } from '@radix-icons/vue'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst languages = [\n { label: 'English', value: 'en' },\n { label: 'French', value: 'fr' },\n { label: 'German', value: 'de' },\n { label: 'Spanish', value: 'es' },\n { label: 'Portuguese', value: 'pt' },\n { label: 'Russian', value: 'ru' },\n { label: 'Japanese', value: 'ja' },\n { label: 'Korean', value: 'ko' },\n { label: 'Chinese', value: 'zh' },\n] as const\n\nconst formSchema = toTypedSchema(z.object({\n language: z.string({\n required_error: 'Please select a language.',\n }),\n}))\n\nconst { handleSubmit, setFieldValue, values } = useForm({\n validationSchema: formSchema,\n initialValues: {\n language: '',\n },\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-6\" @submit=\"onSubmit\">\n <FormField name=\"language\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Language</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n :class=\"cn('w-[200px] justify-between', !values.language && 'text-muted-foreground')\"\n >\n {{ values.language ? languages.find(\n (language) => language.value === values.language,\n )?.label : 'Select language...' }}\n <CaretSortIcon class=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"w-[200px] p-0\">\n <Command>\n <CommandInput placeholder=\"Search language...\" />\n <CommandEmpty>Nothing found.</CommandEmpty>\n <CommandList>\n <CommandGroup>\n <CommandItem\n v-for=\"language in languages\"\n :key=\"language.value\"\n :value=\"language.label\"\n @select=\"() => {\n setFieldValue('language', language.value)\n }\"\n >\n {{ language.label }}\n <CheckIcon\n :class=\"cn('ml-auto h-4 w-4', language.value === values.language ? 'opacity-100' : 'opacity-0')\"\n />\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n <FormDescription>\n This is the language that will be used in the dashboard.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <Button type=\"submit\">\n Submit\n </Button>\n </form>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/registry/new-york/ui/command'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/new-york/ui/form'\n\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { CaretSortIcon, CheckIcon } from '@radix-icons/vue'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst languages = [\n { label: 'English', value: 'en' },\n { label: 'French', value: 'fr' },\n { label: 'German', value: 'de' },\n { label: 'Spanish', value: 'es' },\n { label: 'Portuguese', value: 'pt' },\n { label: 'Russian', value: 'ru' },\n { label: 'Japanese', value: 'ja' },\n { label: 'Korean', value: 'ko' },\n { label: 'Chinese', value: 'zh' },\n] as const\n\nconst formSchema = toTypedSchema(z.object({\n language: z.string({\n required_error: 'Please select a language.',\n }),\n}))\n\nconst { handleSubmit, setFieldValue, values } = useForm({\n validationSchema: formSchema,\n initialValues: {\n language: '',\n },\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-6\" @submit=\"onSubmit\">\n <FormField name=\"language\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Language</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n :class=\"cn('w-[200px] justify-between', !values.language && 'text-muted-foreground')\"\n >\n {{ values.language ? languages.find(\n (language) => language.value === values.language,\n )?.label : 'Select language...' }}\n <CaretSortIcon class=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"w-[200px] p-0\">\n <Command>\n <CommandInput placeholder=\"Search language...\" />\n <CommandEmpty>Nothing found.</CommandEmpty>\n <CommandList>\n <CommandGroup>\n <CommandItem\n v-for=\"language in languages\"\n :key=\"language.value\"\n :value=\"language.label\"\n @select=\"() => {\n setFieldValue('language', language.value)\n }\"\n >\n {{ language.label }}\n <CheckIcon\n :class=\"cn('ml-auto h-4 w-4', language.value === values.language ? 'opacity-100' : 'opacity-0')\"\n />\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n <FormDescription>\n This is the language that will be used in the dashboard.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <Button type=\"submit\">\n Submit\n </Button>\n </form>\n</template>\n",
"type": "registry:example",
"target": "ComboboxForm.vue"
}

View File

@ -3,10 +3,10 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"command",
"popover",
"utils"
"popover"
],
"files": [
{

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"calendar",
"popover",
"utils"
"popover"
],
"files": [
{
"path": "example/DatePickerDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Calendar } from '@/registry/new-york/ui/calendar'\n\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'\nimport { cn } from '@/lib/utils'\nimport {\n DateFormatter,\n type DateValue,\n getLocalTimeZone,\n} from '@internationalized/date'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { ref } from 'vue'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst value = ref<DateValue>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n {{ value ? df.format(value.toDate(getLocalTimeZone())) : \"Pick a date\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar v-model=\"value\" initial-focus />\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\n\nimport { Calendar } from '@/registry/new-york/ui/calendar'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'\nimport {\n DateFormatter,\n type DateValue,\n getLocalTimeZone,\n} from '@internationalized/date'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { ref } from 'vue'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst value = ref<DateValue>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n {{ value ? df.format(value.toDate(getLocalTimeZone())) : \"Pick a date\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar v-model=\"value\" initial-focus />\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "DatePickerDemo.vue"
}

View File

@ -7,17 +7,17 @@
"zod"
],
"registryDependencies": [
"utils",
"button",
"calendar",
"form",
"popover",
"toast",
"utils"
"toast"
],
"files": [
{
"path": "example/DatePickerForm.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Calendar } from '@/registry/new-york/ui/calendar'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/new-york/ui/form'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { cn } from '@/lib/utils'\nimport { CalendarDate, DateFormatter, getLocalTimeZone, parseDate, today } from '@internationalized/date'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { toDate } from 'reka-ui/date'\nimport { useForm } from 'vee-validate'\nimport { computed, h, ref } from 'vue'\nimport { z } from 'zod'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst formSchema = toTypedSchema(z.object({\n dob: z\n .string()\n .refine(v => v, { message: 'A date of birth is required.' }),\n}))\n\nconst placeholder = ref()\n\nconst { handleSubmit, setFieldValue, values } = useForm({\n validationSchema: formSchema,\n initialValues: {\n\n },\n})\n\nconst value = computed({\n get: () => values.dob ? parseDate(values.dob) : undefined,\n set: val => val,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-8\" @submit=\"onSubmit\">\n <FormField name=\"dob\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\" :class=\"cn(\n 'w-[240px] ps-3 text-start font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <span>{{ value ? df.format(toDate(value)) : \"Pick a date\" }}</span>\n <CalendarIcon class=\"ms-auto h-4 w-4 opacity-50\" />\n </Button>\n <input hidden>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar\n v-model:placeholder=\"placeholder\"\n v-model=\"value\"\n calendar-label=\"Date of birth\"\n initial-focus\n :min-value=\"new CalendarDate(1900, 1, 1)\"\n :max-value=\"today(getLocalTimeZone())\"\n @update:model-value=\"(v) => {\n if (v) {\n setFieldValue('dob', v.toString())\n }\n else {\n setFieldValue('dob', undefined)\n }\n }\"\n />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Calendar } from '@/registry/new-york/ui/calendar'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/new-york/ui/form'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { CalendarDate, DateFormatter, getLocalTimeZone, parseDate, today } from '@internationalized/date'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { toDate } from 'reka-ui/date'\nimport { useForm } from 'vee-validate'\nimport { computed, h, ref } from 'vue'\nimport { z } from 'zod'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst formSchema = toTypedSchema(z.object({\n dob: z\n .string()\n .refine(v => v, { message: 'A date of birth is required.' }),\n}))\n\nconst placeholder = ref()\n\nconst { handleSubmit, setFieldValue, values } = useForm({\n validationSchema: formSchema,\n initialValues: {\n\n },\n})\n\nconst value = computed({\n get: () => values.dob ? parseDate(values.dob) : undefined,\n set: val => val,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-8\" @submit=\"onSubmit\">\n <FormField name=\"dob\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\" :class=\"cn(\n 'w-[240px] ps-3 text-start font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <span>{{ value ? df.format(toDate(value)) : \"Pick a date\" }}</span>\n <CalendarIcon class=\"ms-auto h-4 w-4 opacity-50\" />\n </Button>\n <input hidden>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar\n v-model:placeholder=\"placeholder\"\n v-model=\"value\"\n calendar-label=\"Date of birth\"\n initial-focus\n :min-value=\"new CalendarDate(1900, 1, 1)\"\n :max-value=\"today(getLocalTimeZone())\"\n @update:model-value=\"(v) => {\n if (v) {\n setFieldValue('dob', v.toString())\n }\n else {\n setFieldValue('dob', undefined)\n }\n }\"\n />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
"type": "registry:example",
"target": "DatePickerForm.vue"
}

File diff suppressed because one or more lines are too long

View File

@ -3,16 +3,16 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"calendar",
"popover",
"select",
"utils"
"select"
],
"files": [
{
"path": "example/DatePickerWithPresets.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Calendar } from '@/registry/new-york/ui/calendar'\n\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/registry/new-york/ui/select'\nimport { cn } from '@/lib/utils'\nimport {\n DateFormatter,\n type DateValue,\n getLocalTimeZone,\n today,\n} from '@internationalized/date'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { ref } from 'vue'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst items = [\n { value: 0, label: 'Today' },\n { value: 1, label: 'Tomorrow' },\n { value: 3, label: 'In 3 days' },\n { value: 7, label: 'In a week' },\n]\n\nconst value = ref<DateValue>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n {{ value ? df.format(value.toDate(getLocalTimeZone())) : \"Pick a date\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"flex w-auto flex-col gap-y-2 p-2\">\n <Select\n @update:model-value=\"(v) => {\n if (!v) return;\n value = today(getLocalTimeZone()).add({ days: Number(v) });\n }\"\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Select\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem v-for=\"item in items\" :key=\"item.value\" :value=\"item.value.toString()\">\n {{ item.label }}\n </SelectItem>\n </SelectContent>\n </Select>\n <Calendar v-model=\"value\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\n\nimport { Calendar } from '@/registry/new-york/ui/calendar'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/registry/new-york/ui/select'\nimport {\n DateFormatter,\n type DateValue,\n getLocalTimeZone,\n today,\n} from '@internationalized/date'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { ref } from 'vue'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n\nconst items = [\n { value: 0, label: 'Today' },\n { value: 1, label: 'Tomorrow' },\n { value: 3, label: 'In 3 days' },\n { value: 7, label: 'In a week' },\n]\n\nconst value = ref<DateValue>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n {{ value ? df.format(value.toDate(getLocalTimeZone())) : \"Pick a date\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"flex w-auto flex-col gap-y-2 p-2\">\n <Select\n @update:model-value=\"(v) => {\n if (!v) return;\n value = today(getLocalTimeZone()).add({ days: Number(v) });\n }\"\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Select\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem v-for=\"item in items\" :key=\"item.value\" :value=\"item.value.toString()\">\n {{ item.label }}\n </SelectItem>\n </SelectContent>\n </Select>\n <Calendar v-model=\"value\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "DatePickerWithPresets.vue"
}

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"popover",
"range-calendar",
"utils"
"range-calendar"
],
"files": [
{
"path": "example/DatePickerWithRange.vue",
"content": "<script setup lang=\"ts\">\nimport type { DateRange } from 'reka-ui'\nimport { Button } from '@/registry/new-york/ui/button'\n\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'\nimport { RangeCalendar } from '@/registry/new-york/ui/range-calendar'\nimport { cn } from '@/lib/utils'\nimport {\n CalendarDate,\n DateFormatter,\n getLocalTimeZone,\n} from '@internationalized/date'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { type Ref, ref } from 'vue'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'medium',\n})\n\nconst value = ref({\n start: new CalendarDate(2022, 1, 20),\n end: new CalendarDate(2022, 1, 20).add({ days: 20 }),\n}) as Ref<DateRange>\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <template v-if=\"value.start\">\n <template v-if=\"value.end\">\n {{ df.format(value.start.toDate(getLocalTimeZone())) }} - {{ df.format(value.end.toDate(getLocalTimeZone())) }}\n </template>\n\n <template v-else>\n {{ df.format(value.start.toDate(getLocalTimeZone())) }}\n </template>\n </template>\n <template v-else>\n Pick a date\n </template>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <RangeCalendar v-model=\"value\" initial-focus :number-of-months=\"2\" @update:start-value=\"(startDate) => value.start = startDate\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { DateRange } from 'reka-ui'\nimport { cn } from '@/lib/utils'\n\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'\nimport { RangeCalendar } from '@/registry/new-york/ui/range-calendar'\nimport {\n CalendarDate,\n DateFormatter,\n getLocalTimeZone,\n} from '@internationalized/date'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { type Ref, ref } from 'vue'\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'medium',\n})\n\nconst value = ref({\n start: new CalendarDate(2022, 1, 20),\n end: new CalendarDate(2022, 1, 20).add({ days: 20 }),\n}) as Ref<DateRange>\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <template v-if=\"value.start\">\n <template v-if=\"value.end\">\n {{ df.format(value.start.toDate(getLocalTimeZone())) }} - {{ df.format(value.end.toDate(getLocalTimeZone())) }}\n </template>\n\n <template v-else>\n {{ df.format(value.start.toDate(getLocalTimeZone())) }}\n </template>\n </template>\n <template v-else>\n Pick a date\n </template>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <RangeCalendar v-model=\"value\" initial-focus :number-of-months=\"2\" @update:start-value=\"(startDate) => value.start = startDate\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "DatePickerWithRange.vue"
}

View File

@ -8,7 +8,7 @@
"files": [
{
"path": "example/DonutChartDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { DonutChart } from '@/registry/new-york/ui/chart-donut'\n\nconst data = [\n { name: 'Jan', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n { name: 'Feb', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n { name: 'Mar', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n { name: 'Apr', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n { name: 'May', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n { name: 'Jun', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n]\n\nconst valueFormatter = (tick: number | Date) => typeof tick === 'number' ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}` : ''\n</script>\n\n<template>\n <DonutChart\n index=\"name\"\n :category=\"'total'\"\n :data=\"data\"\n :value-formatter=\"valueFormatter\"\n />\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { DonutChart } from '@/registry/new-york/ui/chart-donut'\n\nconst data = [\n {\n name: 'Jan',\n total: Math.floor(Math.random() * 2000) + 500,\n predicted: Math.floor(Math.random() * 2000) + 500,\n },\n {\n name: 'Feb',\n total: Math.floor(Math.random() * 2000) + 500,\n predicted: Math.floor(Math.random() * 2000) + 500,\n },\n {\n name: 'Mar',\n total: Math.floor(Math.random() * 2000) + 500,\n predicted: Math.floor(Math.random() * 2000) + 500,\n },\n {\n name: 'Apr',\n total: Math.floor(Math.random() * 2000) + 500,\n predicted: Math.floor(Math.random() * 2000) + 500,\n },\n {\n name: 'May',\n total: Math.floor(Math.random() * 2000) + 500,\n predicted: Math.floor(Math.random() * 2000) + 500,\n },\n {\n name: 'Jun',\n total: Math.floor(Math.random() * 2000) + 500,\n predicted: Math.floor(Math.random() * 2000) + 500,\n },\n]\n\nfunction valueFormatter(tick: number | Date) {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n}\n</script>\n\n<template>\n <DonutChart\n index=\"name\"\n :category=\"'total'\"\n :data=\"data\"\n :value-formatter=\"valueFormatter\"\n />\n</template>\n",
"type": "registry:example",
"target": "DonutChartDemo.vue"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,13 +3,13 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"slider",
"utils"
"utils",
"slider"
],
"files": [
{
"path": "example/SliderDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { Slider } from '@/registry/new-york/ui/slider'\nimport { cn } from '@/lib/utils'\nimport { ref } from 'vue'\n\nconst modelValue = ref([50])\n</script>\n\n<template>\n <Slider\n v-model=\"modelValue\"\n :max=\"100\"\n :step=\"1\"\n :class=\"cn('w-3/5', $attrs.class ?? '')\"\n />\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Slider } from '@/registry/new-york/ui/slider'\nimport { ref } from 'vue'\n\nconst modelValue = ref([50])\n</script>\n\n<template>\n <Slider\n v-model=\"modelValue\"\n :max=\"100\"\n :step=\"1\"\n :class=\"cn('w-3/5', $attrs.class ?? '')\"\n />\n</template>\n",
"type": "registry:example",
"target": "SliderDemo.vue"
}

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"popover",
"v-calendar",
"utils"
"v-calendar"
],
"files": [
{
"path": "example/VDatePickerDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\nimport { Calendar } from '@/registry/new-york/ui/v-calendar'\n\nimport { cn } from '@/lib/utils'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { format } from 'date-fns'\nimport { ref } from 'vue'\n\nconst date = ref<Date>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <span>{{ date ? format(date, \"PPP\") : \"Pick a date\" }}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar v-model=\"date\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\n\nimport { Calendar } from '@/registry/new-york/ui/v-calendar'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { format } from 'date-fns'\nimport { ref } from 'vue'\n\nconst date = ref<Date>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <span>{{ date ? format(date, \"PPP\") : \"Pick a date\" }}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar v-model=\"date\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "VDatePickerDemo.vue"
}

View File

@ -7,17 +7,17 @@
"zod"
],
"registryDependencies": [
"utils",
"button",
"form",
"popover",
"toast",
"v-calendar",
"utils"
"v-calendar"
],
"files": [
{
"path": "example/VDatePickerForm.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/new-york/ui/form'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { Calendar } from '@/registry/new-york/ui/v-calendar'\nimport { cn } from '@/lib/utils'\n\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { format } from 'date-fns'\nimport { useForm } from 'vee-validate'\n\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n dob: z.date({\n required_error: 'A date of birth is required.',\n }),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-8\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField, value }\" name=\"dob\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\" :class=\"cn(\n 'w-[240px] ps-3 text-start font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <span>{{ value ? format(value, \"PPP\") : \"Pick a date\" }}</span>\n <CalendarIcon class=\"ms-auto h-4 w-4 opacity-50\" />\n </Button>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"p-0\">\n <Calendar v-bind=\"componentField\" />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/new-york/ui/form'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { Calendar } from '@/registry/new-york/ui/v-calendar'\n\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { format } from 'date-fns'\nimport { useForm } from 'vee-validate'\n\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n dob: z.date({\n required_error: 'A date of birth is required.',\n }),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n})\n\nconst onSubmit = handleSubmit((values) => {\n toast({\n title: 'You submitted the following values:',\n description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),\n })\n})\n</script>\n\n<template>\n <form class=\"space-y-8\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField, value }\" name=\"dob\">\n <FormItem class=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger as-child>\n <FormControl>\n <Button\n variant=\"outline\" :class=\"cn(\n 'w-[240px] ps-3 text-start font-normal',\n !value && 'text-muted-foreground',\n )\"\n >\n <span>{{ value ? format(value, \"PPP\") : \"Pick a date\" }}</span>\n <CalendarIcon class=\"ms-auto h-4 w-4 opacity-50\" />\n </Button>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent class=\"p-0\">\n <Calendar v-bind=\"componentField\" />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
"type": "registry:example",
"target": "VDatePickerForm.vue"
}

View File

@ -3,16 +3,16 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"popover",
"select",
"v-calendar",
"utils"
"v-calendar"
],
"files": [
{
"path": "example/VDatePickerWithPresets.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\n\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/new-york/ui/select'\nimport { Calendar } from '@/registry/new-york/ui/v-calendar'\nimport { cn } from '@/lib/utils'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { addDays, format } from 'date-fns'\nimport { ref } from 'vue'\n\nconst date = ref<Date>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <template v-if=\"date\">\n {{ format(date, \"PPP\") }}\n </template>\n <template v-else>\n <span>Pick a date</span>\n </template>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"flex w-auto flex-col space-y-2 p-2\">\n <Select\n @update:model-value=\"(value) => {\n date = addDays(new Date(), parseInt(value))\n }\"\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Select\" />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectItem value=\"0\">\n Today\n </SelectItem>\n <SelectItem value=\"1\">\n Tomorrow\n </SelectItem>\n <SelectItem value=\"3\">\n In 3 days\n </SelectItem>\n <SelectItem value=\"7\">\n In a week\n </SelectItem>\n </SelectContent>\n </Select>\n <div class=\"rounded-md border\">\n <Calendar v-model=\"date\" mode=\"single\" />\n </div>\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\n\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/new-york/ui/select'\nimport { Calendar } from '@/registry/new-york/ui/v-calendar'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { addDays, format } from 'date-fns'\nimport { ref } from 'vue'\n\nconst date = ref<Date>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <template v-if=\"date\">\n {{ format(date, \"PPP\") }}\n </template>\n <template v-else>\n <span>Pick a date</span>\n </template>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"flex w-auto flex-col space-y-2 p-2\">\n <Select\n @update:model-value=\"(value) => {\n date = addDays(new Date(), parseInt(value))\n }\"\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Select\" />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectItem value=\"0\">\n Today\n </SelectItem>\n <SelectItem value=\"1\">\n Tomorrow\n </SelectItem>\n <SelectItem value=\"3\">\n In 3 days\n </SelectItem>\n <SelectItem value=\"7\">\n In a week\n </SelectItem>\n </SelectContent>\n </Select>\n <div class=\"rounded-md border\">\n <Calendar v-model=\"date\" mode=\"single\" />\n </div>\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "VDatePickerWithPresets.vue"
}

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"popover",
"v-calendar",
"utils"
"v-calendar"
],
"files": [
{
"path": "example/VDatePickerWithRange.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\nimport { Calendar } from '@/registry/new-york/ui/v-calendar'\n\nimport { cn } from '@/lib/utils'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { addDays, format } from 'date-fns'\nimport { ref } from 'vue'\n\nconst date = ref({\n start: new Date(2022, 0, 20),\n end: addDays(new Date(2022, 0, 20), 20),\n})\n</script>\n\n<template>\n <div :class=\"cn('grid gap-2', $attrs.class ?? '')\">\n <Popover>\n <PopoverTrigger as-child>\n <Button\n id=\"date\"\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n\n <span>\n {{ date.start ? (\n date.end ? `${format(date.start, 'LLL dd, y')} - ${format(date.end, 'LLL dd, y')}`\n : format(date.start, 'LLL dd, y')\n ) : 'Pick a date' }}\n </span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\" align=\"start\">\n <Calendar\n v-model.range=\"date\"\n :columns=\"2\"\n />\n </PopoverContent>\n </Popover>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\n\nimport { Calendar } from '@/registry/new-york/ui/v-calendar'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { addDays, format } from 'date-fns'\nimport { ref } from 'vue'\n\nconst date = ref({\n start: new Date(2022, 0, 20),\n end: addDays(new Date(2022, 0, 20), 20),\n})\n</script>\n\n<template>\n <div :class=\"cn('grid gap-2', $attrs.class ?? '')\">\n <Popover>\n <PopoverTrigger as-child>\n <Button\n id=\"date\"\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n\n <span>\n {{ date.start ? (\n date.end ? `${format(date.start, 'LLL dd, y')} - ${format(date.end, 'LLL dd, y')}`\n : format(date.start, 'LLL dd, y')\n ) : 'Pick a date' }}\n </span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\" align=\"start\">\n <Calendar\n v-model.range=\"date\"\n :columns=\"2\"\n />\n </PopoverContent>\n </Popover>\n </div>\n</template>\n",
"type": "registry:example",
"target": "VDatePickerWithRange.vue"
}

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"popover",
"v-calendar",
"utils"
"v-calendar"
],
"files": [
{
"path": "example/VDateTimePickerDemo.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\n\nimport { Calendar } from '@/registry/new-york/ui/v-calendar'\nimport { cn } from '@/lib/utils'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { format } from 'date-fns'\nimport { ref } from 'vue'\n\nconst date = ref<Date>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <span>{{ date ? format(date, 'PPP - hh:mm') : \"Pick a date\" }}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar v-model=\"date\" mode=\"datetime\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\n\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\nimport { Calendar } from '@/registry/new-york/ui/v-calendar'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { format } from 'date-fns'\nimport { ref } from 'vue'\n\nconst date = ref<Date>()\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <span>{{ date ? format(date, 'PPP - hh:mm') : \"Pick a date\" }}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar v-model=\"date\" mode=\"datetime\" />\n </PopoverContent>\n </Popover>\n</template>\n",
"type": "registry:example",
"target": "VDateTimePickerDemo.vue"
}

View File

@ -3,15 +3,15 @@
"type": "registry:example",
"dependencies": [],
"registryDependencies": [
"utils",
"button",
"popover",
"v-calendar",
"utils"
"v-calendar"
],
"files": [
{
"path": "example/VRangePickerWithSlot.vue",
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\nimport { Calendar } from '@/registry/new-york/ui/v-calendar'\n\nimport { cn } from '@/lib/utils'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { addDays, format } from 'date-fns'\nimport { ref } from 'vue'\n\nconst date = ref({\n start: new Date(2022, 0, 20),\n end: addDays(new Date(2022, 0, 20), 20),\n})\n</script>\n\n<template>\n <div :class=\"cn('grid gap-2', $attrs.class ?? '')\">\n <Popover>\n <PopoverTrigger as-child>\n <Button\n id=\"date\"\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n\n <span>\n {{ date.start ? (\n date.end ? `${format(date.start, 'LLL dd, y')} - ${format(date.end, 'LLL dd, y')}`\n : format(date.start, 'LLL dd, y')\n ) : 'Pick a date' }}\n </span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\" align=\"start\">\n <Calendar\n v-model.range=\"date\"\n mode=\"date\"\n :columns=\"2\"\n >\n <template #footer>\n <div class=\"flex w-full mt-6 border-t border-accent pt-4\">\n <div class=\"w-1/2\">\n <strong>Entry time</strong>\n <Calendar\n v-model=\"date.start\"\n mode=\"time\"\n hide-time-header\n />\n </div>\n <div class=\"w-1/2\">\n <strong>Exit time</strong>\n <Calendar\n v-model=\"date.end\"\n mode=\"time\"\n hide-time-header\n />\n </div>\n </div>\n </template>\n </Calendar>\n </PopoverContent>\n </Popover>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\n\nimport { Calendar } from '@/registry/new-york/ui/v-calendar'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport { addDays, format } from 'date-fns'\nimport { ref } from 'vue'\n\nconst date = ref({\n start: new Date(2022, 0, 20),\n end: addDays(new Date(2022, 0, 20), 20),\n})\n</script>\n\n<template>\n <div :class=\"cn('grid gap-2', $attrs.class ?? '')\">\n <Popover>\n <PopoverTrigger as-child>\n <Button\n id=\"date\"\n :variant=\"'outline'\"\n :class=\"cn(\n 'w-[280px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n\n <span>\n {{ date.start ? (\n date.end ? `${format(date.start, 'LLL dd, y')} - ${format(date.end, 'LLL dd, y')}`\n : format(date.start, 'LLL dd, y')\n ) : 'Pick a date' }}\n </span>\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\" align=\"start\">\n <Calendar\n v-model.range=\"date\"\n mode=\"date\"\n :columns=\"2\"\n >\n <template #footer>\n <div class=\"flex w-full mt-6 border-t border-accent pt-4\">\n <div class=\"w-1/2\">\n <strong>Entry time</strong>\n <Calendar\n v-model=\"date.start\"\n mode=\"time\"\n hide-time-header\n />\n </div>\n <div class=\"w-1/2\">\n <strong>Exit time</strong>\n <Calendar\n v-model=\"date.end\"\n mode=\"time\"\n hide-time-header\n />\n </div>\n </div>\n </template>\n </Calendar>\n </PopoverContent>\n </Popover>\n </div>\n</template>\n",
"type": "registry:example",
"target": "VRangePickerWithSlot.vue"
}

View File

@ -3,8 +3,8 @@
"type": "registry:ui",
"dependencies": [],
"registryDependencies": [
"button",
"utils"
"utils",
"button"
],
"files": [
{
@ -15,13 +15,13 @@
},
{
"path": "ui/alert-dialog/AlertDialogAction.vue",
"content": "<script setup lang=\"ts\">\nimport { buttonVariants } from '@/registry/new-york/ui/button'\nimport { cn } from '@/lib/utils'\nimport { AlertDialogAction, type AlertDialogActionProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogActionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AlertDialogAction v-bind=\"delegatedProps\" :class=\"cn(buttonVariants(), props.class)\">\n <slot />\n </AlertDialogAction>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/new-york/ui/button'\nimport { AlertDialogAction, type AlertDialogActionProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogActionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AlertDialogAction v-bind=\"delegatedProps\" :class=\"cn(buttonVariants(), props.class)\">\n <slot />\n </AlertDialogAction>\n</template>\n",
"type": "registry:ui",
"target": "alert-dialog/AlertDialogAction.vue"
},
{
"path": "ui/alert-dialog/AlertDialogCancel.vue",
"content": "<script setup lang=\"ts\">\nimport { buttonVariants } from '@/registry/new-york/ui/button'\nimport { cn } from '@/lib/utils'\nimport { AlertDialogCancel, type AlertDialogCancelProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogCancelProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AlertDialogCancel\n v-bind=\"delegatedProps\"\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'mt-2 sm:mt-0',\n props.class,\n )\"\n >\n <slot />\n </AlertDialogCancel>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/new-york/ui/button'\nimport { AlertDialogCancel, type AlertDialogCancelProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogCancelProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AlertDialogCancel\n v-bind=\"delegatedProps\"\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'mt-2 sm:mt-0',\n props.class,\n )\"\n >\n <slot />\n </AlertDialogCancel>\n</template>\n",
"type": "registry:ui",
"target": "alert-dialog/AlertDialogCancel.vue"
},

View File

@ -13,9 +13,9 @@
"separator",
"checkbox",
"switch",
"utils",
"calendar",
"popover",
"utils",
"label",
"radio-group",
"select",
@ -49,7 +49,7 @@
},
{
"path": "ui/auto-form/AutoFormFieldDate.vue",
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Calendar } from '@/registry/new-york/ui/calendar'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/new-york/ui/form'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'\nimport { cn } from '@/lib/utils'\n\nimport { DateFormatter, getLocalTimeZone } from '@internationalized/date'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\ndefineProps<FieldProps>()\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n</script>\n\n<template>\n <FormField v-slot=\"slotProps\" :name=\"fieldName\">\n <FormItem>\n <AutoFormLabel v-if=\"!config?.hideLabel\" :required=\"required\">\n {{ config?.label || beautifyObjectName(label ?? fieldName) }}\n </AutoFormLabel>\n <FormControl>\n <slot v-bind=\"slotProps\">\n <div>\n <Popover>\n <PopoverTrigger as-child :disabled=\"disabled\">\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-full justify-start text-left font-normal',\n !slotProps.componentField.modelValue && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n {{ slotProps.componentField.modelValue ? df.format(slotProps.componentField.modelValue.toDate(getLocalTimeZone())) : \"Pick a date\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar initial-focus v-bind=\"slotProps.componentField\" />\n </PopoverContent>\n </Popover>\n </div>\n </slot>\n </FormControl>\n\n <FormDescription v-if=\"config?.description\">\n {{ config.description }}\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Calendar } from '@/registry/new-york/ui/calendar'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/new-york/ui/form'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'\n\nimport { DateFormatter, getLocalTimeZone } from '@internationalized/date'\nimport { CalendarIcon } from '@radix-icons/vue'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\ndefineProps<FieldProps>()\n\nconst df = new DateFormatter('en-US', {\n dateStyle: 'long',\n})\n</script>\n\n<template>\n <FormField v-slot=\"slotProps\" :name=\"fieldName\">\n <FormItem>\n <AutoFormLabel v-if=\"!config?.hideLabel\" :required=\"required\">\n {{ config?.label || beautifyObjectName(label ?? fieldName) }}\n </AutoFormLabel>\n <FormControl>\n <slot v-bind=\"slotProps\">\n <div>\n <Popover>\n <PopoverTrigger as-child :disabled=\"disabled\">\n <Button\n variant=\"outline\"\n :class=\"cn(\n 'w-full justify-start text-left font-normal',\n !slotProps.componentField.modelValue && 'text-muted-foreground',\n )\"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n {{ slotProps.componentField.modelValue ? df.format(slotProps.componentField.modelValue.toDate(getLocalTimeZone())) : \"Pick a date\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-auto p-0\">\n <Calendar initial-focus v-bind=\"slotProps.componentField\" />\n </PopoverContent>\n </Popover>\n </div>\n </slot>\n </FormControl>\n\n <FormDescription v-if=\"config?.description\">\n {{ config.description }}\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n</template>\n",
"type": "registry:ui",
"target": "auto-form/AutoFormFieldDate.vue"
},

View File

@ -21,7 +21,7 @@
},
{
"path": "ui/calendar/CalendarCellTrigger.vue",
"content": "<script lang=\"ts\" setup>\nimport { buttonVariants } from '@/registry/new-york/ui/button'\nimport { cn } from '@/lib/utils'\nimport { CalendarCellTrigger, type CalendarCellTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarCellTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarCellTrigger\n :class=\"cn(\n buttonVariants({ variant: 'ghost' }),\n 'h-8 w-8 p-0 font-normal',\n '[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',\n // Selected\n 'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:opacity-100 data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground',\n // Disabled\n 'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',\n // Unavailable\n 'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',\n // Outside months\n 'data-[outside-view]:text-muted-foreground data-[outside-view]:opacity-50 [&[data-outside-view][data-selected]]:bg-accent/50 [&[data-outside-view][data-selected]]:text-muted-foreground [&[data-outside-view][data-selected]]:opacity-30',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </CalendarCellTrigger>\n</template>\n",
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/new-york/ui/button'\nimport { CalendarCellTrigger, type CalendarCellTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarCellTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarCellTrigger\n :class=\"cn(\n buttonVariants({ variant: 'ghost' }),\n 'h-8 w-8 p-0 font-normal',\n '[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',\n // Selected\n 'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:opacity-100 data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground',\n // Disabled\n 'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',\n // Unavailable\n 'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',\n // Outside months\n 'data-[outside-view]:text-muted-foreground data-[outside-view]:opacity-50 [&[data-outside-view][data-selected]]:bg-accent/50 [&[data-outside-view][data-selected]]:text-muted-foreground [&[data-outside-view][data-selected]]:opacity-30',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </CalendarCellTrigger>\n</template>\n",
"type": "registry:ui",
"target": "calendar/CalendarCellTrigger.vue"
},
@ -69,13 +69,13 @@
},
{
"path": "ui/calendar/CalendarNextButton.vue",
"content": "<script lang=\"ts\" setup>\nimport { buttonVariants } from '@/registry/new-york/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ChevronRightIcon } from '@radix-icons/vue'\nimport { CalendarNext, type CalendarNextProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarNextProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarNext\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronRightIcon class=\"h-4 w-4\" />\n </slot>\n </CalendarNext>\n</template>\n",
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/new-york/ui/button'\nimport { ChevronRightIcon } from '@radix-icons/vue'\nimport { CalendarNext, type CalendarNextProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarNextProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarNext\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronRightIcon class=\"h-4 w-4\" />\n </slot>\n </CalendarNext>\n</template>\n",
"type": "registry:ui",
"target": "calendar/CalendarNextButton.vue"
},
{
"path": "ui/calendar/CalendarPrevButton.vue",
"content": "<script lang=\"ts\" setup>\nimport { buttonVariants } from '@/registry/new-york/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ChevronLeftIcon } from '@radix-icons/vue'\nimport { CalendarPrev, type CalendarPrevProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarPrevProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarPrev\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronLeftIcon class=\"h-4 w-4\" />\n </slot>\n </CalendarPrev>\n</template>\n",
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/new-york/ui/button'\nimport { ChevronLeftIcon } from '@radix-icons/vue'\nimport { CalendarPrev, type CalendarPrevProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarPrevProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <CalendarPrev\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n props.class,\n )\"\n v-bind=\"forwardedProps\"\n >\n <slot>\n <ChevronLeftIcon class=\"h-4 w-4\" />\n </slot>\n </CalendarPrev>\n</template>\n",
"type": "registry:ui",
"target": "calendar/CalendarPrevButton.vue"
},

View File

@ -30,13 +30,13 @@
},
{
"path": "ui/carousel/CarouselNext.vue",
"content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from './interface'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ArrowRightIcon } from '@radix-icons/vue'\nimport { useCarousel } from './useCarousel'\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { orientation, canScrollNext, scrollNext } = useCarousel()\n</script>\n\n<template>\n <Button\n :disabled=\"!canScrollNext\"\n :class=\"cn(\n 'touch-manipulation absolute h-8 w-8 rounded-full p-0',\n orientation === 'horizontal'\n ? '-right-12 top-1/2 -translate-y-1/2'\n : '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',\n props.class,\n )\"\n variant=\"outline\"\n @click=\"scrollNext\"\n >\n <slot>\n <ArrowRightIcon class=\"h-4 w-4 text-current\" />\n <span class=\"sr-only\">Next Slide</span>\n </slot>\n </Button>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { ArrowRightIcon } from '@radix-icons/vue'\nimport { useCarousel } from './useCarousel'\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { orientation, canScrollNext, scrollNext } = useCarousel()\n</script>\n\n<template>\n <Button\n :disabled=\"!canScrollNext\"\n :class=\"cn(\n 'touch-manipulation absolute h-8 w-8 rounded-full p-0',\n orientation === 'horizontal'\n ? '-right-12 top-1/2 -translate-y-1/2'\n : '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',\n props.class,\n )\"\n variant=\"outline\"\n @click=\"scrollNext\"\n >\n <slot>\n <ArrowRightIcon class=\"h-4 w-4 text-current\" />\n <span class=\"sr-only\">Next Slide</span>\n </slot>\n </Button>\n</template>\n",
"type": "registry:ui",
"target": "carousel/CarouselNext.vue"
},
{
"path": "ui/carousel/CarouselPrevious.vue",
"content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from './interface'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { cn } from '@/lib/utils'\nimport { ArrowLeftIcon } from '@radix-icons/vue'\nimport { useCarousel } from './useCarousel'\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { orientation, canScrollPrev, scrollPrev } = useCarousel()\n</script>\n\n<template>\n <Button\n :disabled=\"!canScrollPrev\"\n :class=\"cn(\n 'touch-manipulation absolute h-8 w-8 rounded-full p-0',\n orientation === 'horizontal'\n ? '-left-12 top-1/2 -translate-y-1/2'\n : '-top-12 left-1/2 -translate-x-1/2 rotate-90',\n props.class,\n )\"\n variant=\"outline\"\n @click=\"scrollPrev\"\n >\n <slot>\n <ArrowLeftIcon class=\"h-4 w-4 text-current\" />\n <span class=\"sr-only\">Previous Slide</span>\n </slot>\n </Button>\n</template>\n",
"content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { ArrowLeftIcon } from '@radix-icons/vue'\nimport { useCarousel } from './useCarousel'\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { orientation, canScrollPrev, scrollPrev } = useCarousel()\n</script>\n\n<template>\n <Button\n :disabled=\"!canScrollPrev\"\n :class=\"cn(\n 'touch-manipulation absolute h-8 w-8 rounded-full p-0',\n orientation === 'horizontal'\n ? '-left-12 top-1/2 -translate-y-1/2'\n : '-top-12 left-1/2 -translate-x-1/2 rotate-90',\n props.class,\n )\"\n variant=\"outline\"\n @click=\"scrollPrev\"\n >\n <slot>\n <ArrowLeftIcon class=\"h-4 w-4 text-current\" />\n <span class=\"sr-only\">Previous Slide</span>\n </slot>\n </Button>\n</template>\n",
"type": "registry:ui",
"target": "carousel/CarouselPrevious.vue"
},

View File

@ -7,13 +7,13 @@
"@vueuse/core"
],
"registryDependencies": [
"chart",
"utils"
"utils",
"chart"
],
"files": [
{
"path": "ui/chart-area/AreaChart.vue",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BaseChartProps } from '.'\nimport { ChartCrosshair, ChartLegend, defaultColors } from '@/registry/new-york/ui/chart'\nimport { cn } from '@/lib/utils'\nimport { type BulletLegendItemInterface, CurveType } from '@unovis/ts'\nimport { Area, Axis, Line } from '@unovis/ts'\nimport { VisArea, VisAxis, VisLine, VisXYContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { useId } from 'reka-ui'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<BaseChartProps<T> & {\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n /**\n * Type of curve\n */\n curveType?: CurveType\n /**\n * Controls the visibility of gradient.\n * @default true\n */\n showGradiant?: boolean\n}>(), {\n curveType: CurveType.MonotoneX,\n filterOpacity: 0.2,\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n showXAxis: true,\n showYAxis: true,\n showTooltip: true,\n showLegend: true,\n showGridLine: true,\n showGradiant: true,\n})\n\nconst emits = defineEmits<{\n legendItemClick: [d: BulletLegendItemInterface, i: number]\n}>()\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst chartRef = useId()\n\nconst index = computed(() => props.index as KeyOfT)\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))\n\nconst legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({\n name: category,\n color: colors.value[i],\n inactive: false,\n})))\n\nconst isMounted = useMounted()\n\nfunction handleLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n}\n</script>\n\n<template>\n <div :class=\"cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')\">\n <ChartLegend v-if=\"showLegend\" v-model:items=\"legendItems\" @legend-item-click=\"handleLegendItemClick\" />\n\n <VisXYContainer :style=\"{ height: isMounted ? '100%' : 'auto' }\" :margin=\"{ left: 20, right: 20 }\" :data=\"data\">\n <svg width=\"0\" height=\"0\">\n <defs>\n <linearGradient v-for=\"(color, i) in colors\" :id=\"`${chartRef}-color-${i}`\" :key=\"i\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <template v-if=\"showGradiant\">\n <stop offset=\"5%\" :stop-color=\"color\" stop-opacity=\"0.4\" />\n <stop offset=\"95%\" :stop-color=\"color\" stop-opacity=\"0\" />\n </template>\n <template v-else>\n <stop offset=\"0%\" :stop-color=\"color\" />\n </template>\n </linearGradient>\n </defs>\n </svg>\n\n <ChartCrosshair v-if=\"showTooltip\" :colors=\"colors\" :items=\"legendItems\" :index=\"index\" :custom-tooltip=\"customTooltip\" />\n\n <template v-for=\"(category, i) in categories\" :key=\"category\">\n <VisArea\n :x=\"(d: Data, i: number) => i\"\n :y=\"(d: Data) => d[category]\"\n color=\"auto\"\n :curve-type=\"curveType\"\n :attributes=\"{\n [Area.selectors.area]: {\n fill: `url(#${chartRef}-color-${i})`,\n },\n }\"\n :opacity=\"legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1\"\n />\n </template>\n\n <template v-for=\"(category, i) in categories\" :key=\"category\">\n <VisLine\n :x=\"(d: Data, i: number) => i\"\n :y=\"(d: Data) => d[category]\"\n :color=\"colors[i]\"\n :curve-type=\"curveType\"\n :attributes=\"{\n [Line.selectors.line]: {\n opacity: legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1,\n },\n }\"\n />\n </template>\n\n <VisAxis\n v-if=\"showXAxis\"\n type=\"x\"\n :tick-format=\"xFormatter ?? ((v: number) => data[v]?.[index])\"\n :grid-line=\"false\"\n :tick-line=\"false\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n <VisAxis\n v-if=\"showYAxis\"\n type=\"y\"\n :tick-line=\"false\"\n :tick-format=\"yFormatter\"\n :domain-line=\"false\"\n :grid-line=\"showGridLine\"\n :attributes=\"{\n [Axis.selectors.grid]: {\n class: 'text-muted',\n },\n }\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n\n <slot />\n </VisXYContainer>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BaseChartProps } from '.'\nimport { cn } from '@/lib/utils'\nimport { ChartCrosshair, ChartLegend, defaultColors } from '@/registry/new-york/ui/chart'\nimport { type BulletLegendItemInterface, CurveType } from '@unovis/ts'\nimport { Area, Axis, Line } from '@unovis/ts'\nimport { VisArea, VisAxis, VisLine, VisXYContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { useId } from 'reka-ui'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<BaseChartProps<T> & {\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n /**\n * Type of curve\n */\n curveType?: CurveType\n /**\n * Controls the visibility of gradient.\n * @default true\n */\n showGradiant?: boolean\n}>(), {\n curveType: CurveType.MonotoneX,\n filterOpacity: 0.2,\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n showXAxis: true,\n showYAxis: true,\n showTooltip: true,\n showLegend: true,\n showGridLine: true,\n showGradiant: true,\n})\n\nconst emits = defineEmits<{\n legendItemClick: [d: BulletLegendItemInterface, i: number]\n}>()\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst chartRef = useId()\n\nconst index = computed(() => props.index as KeyOfT)\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))\n\nconst legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({\n name: category,\n color: colors.value[i],\n inactive: false,\n})))\n\nconst isMounted = useMounted()\n\nfunction handleLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n}\n</script>\n\n<template>\n <div :class=\"cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')\">\n <ChartLegend v-if=\"showLegend\" v-model:items=\"legendItems\" @legend-item-click=\"handleLegendItemClick\" />\n\n <VisXYContainer :style=\"{ height: isMounted ? '100%' : 'auto' }\" :margin=\"{ left: 20, right: 20 }\" :data=\"data\">\n <svg width=\"0\" height=\"0\">\n <defs>\n <linearGradient v-for=\"(color, i) in colors\" :id=\"`${chartRef}-color-${i}`\" :key=\"i\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <template v-if=\"showGradiant\">\n <stop offset=\"5%\" :stop-color=\"color\" stop-opacity=\"0.4\" />\n <stop offset=\"95%\" :stop-color=\"color\" stop-opacity=\"0\" />\n </template>\n <template v-else>\n <stop offset=\"0%\" :stop-color=\"color\" />\n </template>\n </linearGradient>\n </defs>\n </svg>\n\n <ChartCrosshair v-if=\"showTooltip\" :colors=\"colors\" :items=\"legendItems\" :index=\"index\" :custom-tooltip=\"customTooltip\" />\n\n <template v-for=\"(category, i) in categories\" :key=\"category\">\n <VisArea\n :x=\"(d: Data, i: number) => i\"\n :y=\"(d: Data) => d[category]\"\n color=\"auto\"\n :curve-type=\"curveType\"\n :attributes=\"{\n [Area.selectors.area]: {\n fill: `url(#${chartRef}-color-${i})`,\n },\n }\"\n :opacity=\"legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1\"\n />\n </template>\n\n <template v-for=\"(category, i) in categories\" :key=\"category\">\n <VisLine\n :x=\"(d: Data, i: number) => i\"\n :y=\"(d: Data) => d[category]\"\n :color=\"colors[i]\"\n :curve-type=\"curveType\"\n :attributes=\"{\n [Line.selectors.line]: {\n opacity: legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1,\n },\n }\"\n />\n </template>\n\n <VisAxis\n v-if=\"showXAxis\"\n type=\"x\"\n :tick-format=\"xFormatter ?? ((v: number) => data[v]?.[index])\"\n :grid-line=\"false\"\n :tick-line=\"false\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n <VisAxis\n v-if=\"showYAxis\"\n type=\"y\"\n :tick-line=\"false\"\n :tick-format=\"yFormatter\"\n :domain-line=\"false\"\n :grid-line=\"showGridLine\"\n :attributes=\"{\n [Axis.selectors.grid]: {\n class: 'text-muted',\n },\n }\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n\n <slot />\n </VisXYContainer>\n </div>\n</template>\n",
"type": "registry:ui",
"target": "chart-area/AreaChart.vue"
},

View File

@ -7,13 +7,13 @@
"@vueuse/core"
],
"registryDependencies": [
"chart",
"utils"
"utils",
"chart"
],
"files": [
{
"path": "ui/chart-bar/BarChart.vue",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BulletLegendItemInterface } from '@unovis/ts'\nimport type { BaseChartProps } from '.'\nimport { ChartCrosshair, ChartLegend, defaultColors } from '@/registry/new-york/ui/chart'\nimport { cn } from '@/lib/utils'\nimport { Axis, GroupedBar, StackedBar } from '@unovis/ts'\nimport { VisAxis, VisGroupedBar, VisStackedBar, VisXYContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<BaseChartProps<T> & {\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n /**\n * Change the type of the chart\n * @default \"grouped\"\n */\n type?: 'stacked' | 'grouped'\n /**\n * Rounded bar corners\n * @default 0\n */\n roundedCorners?: number\n}>(), {\n type: 'grouped',\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n filterOpacity: 0.2,\n roundedCorners: 0,\n showXAxis: true,\n showYAxis: true,\n showTooltip: true,\n showLegend: true,\n showGridLine: true,\n})\nconst emits = defineEmits<{\n legendItemClick: [d: BulletLegendItemInterface, i: number]\n}>()\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst index = computed(() => props.index as KeyOfT)\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))\nconst legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({\n name: category,\n color: colors.value[i],\n inactive: false,\n})))\n\nconst isMounted = useMounted()\n\nfunction handleLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n}\n\nconst VisBarComponent = computed(() => props.type === 'grouped' ? VisGroupedBar : VisStackedBar)\nconst selectorsBar = computed(() => props.type === 'grouped' ? GroupedBar.selectors.bar : StackedBar.selectors.bar)\n</script>\n\n<template>\n <div :class=\"cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')\">\n <ChartLegend v-if=\"showLegend\" v-model:items=\"legendItems\" @legend-item-click=\"handleLegendItemClick\" />\n\n <VisXYContainer\n :data=\"data\"\n :style=\"{ height: isMounted ? '100%' : 'auto' }\"\n :margin=\"margin\"\n >\n <ChartCrosshair v-if=\"showTooltip\" :colors=\"colors\" :items=\"legendItems\" :custom-tooltip=\"customTooltip\" :index=\"index\" />\n\n <VisBarComponent\n :x=\"(d: Data, i: number) => i\"\n :y=\"categories.map(category => (d: Data) => d[category]) \"\n :color=\"colors\"\n :rounded-corners=\"roundedCorners\"\n :bar-padding=\"0.05\"\n :attributes=\"{\n [selectorsBar]: {\n opacity: (d: Data, i:number) => {\n const pos = i % categories.length\n return legendItems[pos]?.inactive ? filterOpacity : 1\n },\n },\n }\"\n />\n\n <VisAxis\n v-if=\"showXAxis\"\n type=\"x\"\n :tick-format=\"xFormatter ?? ((v: number) => data[v]?.[index])\"\n :grid-line=\"false\"\n :tick-line=\"false\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n <VisAxis\n v-if=\"showYAxis\"\n type=\"y\"\n :tick-line=\"false\"\n :tick-format=\"yFormatter\"\n :domain-line=\"false\"\n :grid-line=\"showGridLine\"\n :attributes=\"{\n [Axis.selectors.grid]: {\n class: 'text-muted',\n },\n }\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n\n <slot />\n </VisXYContainer>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BulletLegendItemInterface } from '@unovis/ts'\nimport type { BaseChartProps } from '.'\nimport { cn } from '@/lib/utils'\nimport { ChartCrosshair, ChartLegend, defaultColors } from '@/registry/new-york/ui/chart'\nimport { Axis, GroupedBar, StackedBar } from '@unovis/ts'\nimport { VisAxis, VisGroupedBar, VisStackedBar, VisXYContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<BaseChartProps<T> & {\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n /**\n * Change the type of the chart\n * @default \"grouped\"\n */\n type?: 'stacked' | 'grouped'\n /**\n * Rounded bar corners\n * @default 0\n */\n roundedCorners?: number\n}>(), {\n type: 'grouped',\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n filterOpacity: 0.2,\n roundedCorners: 0,\n showXAxis: true,\n showYAxis: true,\n showTooltip: true,\n showLegend: true,\n showGridLine: true,\n})\nconst emits = defineEmits<{\n legendItemClick: [d: BulletLegendItemInterface, i: number]\n}>()\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst index = computed(() => props.index as KeyOfT)\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))\nconst legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({\n name: category,\n color: colors.value[i],\n inactive: false,\n})))\n\nconst isMounted = useMounted()\n\nfunction handleLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n}\n\nconst VisBarComponent = computed(() => props.type === 'grouped' ? VisGroupedBar : VisStackedBar)\nconst selectorsBar = computed(() => props.type === 'grouped' ? GroupedBar.selectors.bar : StackedBar.selectors.bar)\n</script>\n\n<template>\n <div :class=\"cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')\">\n <ChartLegend v-if=\"showLegend\" v-model:items=\"legendItems\" @legend-item-click=\"handleLegendItemClick\" />\n\n <VisXYContainer\n :data=\"data\"\n :style=\"{ height: isMounted ? '100%' : 'auto' }\"\n :margin=\"margin\"\n >\n <ChartCrosshair v-if=\"showTooltip\" :colors=\"colors\" :items=\"legendItems\" :custom-tooltip=\"customTooltip\" :index=\"index\" />\n\n <VisBarComponent\n :x=\"(d: Data, i: number) => i\"\n :y=\"categories.map(category => (d: Data) => d[category]) \"\n :color=\"colors\"\n :rounded-corners=\"roundedCorners\"\n :bar-padding=\"0.05\"\n :attributes=\"{\n [selectorsBar]: {\n opacity: (d: Data, i:number) => {\n const pos = i % categories.length\n return legendItems[pos]?.inactive ? filterOpacity : 1\n },\n },\n }\"\n />\n\n <VisAxis\n v-if=\"showXAxis\"\n type=\"x\"\n :tick-format=\"xFormatter ?? ((v: number) => data[v]?.[index])\"\n :grid-line=\"false\"\n :tick-line=\"false\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n <VisAxis\n v-if=\"showYAxis\"\n type=\"y\"\n :tick-line=\"false\"\n :tick-format=\"yFormatter\"\n :domain-line=\"false\"\n :grid-line=\"showGridLine\"\n :attributes=\"{\n [Axis.selectors.grid]: {\n class: 'text-muted',\n },\n }\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n\n <slot />\n </VisXYContainer>\n </div>\n</template>\n",
"type": "registry:ui",
"target": "chart-bar/BarChart.vue"
},

View File

@ -7,13 +7,13 @@
"@vueuse/core"
],
"registryDependencies": [
"chart",
"utils"
"utils",
"chart"
],
"files": [
{
"path": "ui/chart-donut/DonutChart.vue",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BaseChartProps } from '.'\nimport { ChartSingleTooltip, defaultColors } from '@/registry/new-york/ui/chart'\nimport { cn } from '@/lib/utils'\nimport { Donut } from '@unovis/ts'\nimport { VisDonut, VisSingleContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<Pick<BaseChartProps<T>, 'data' | 'colors' | 'index' | 'margin' | 'showLegend' | 'showTooltip' | 'filterOpacity'> & {\n /**\n * Sets the name of the key containing the quantitative chart values.\n */\n category: KeyOfT\n /**\n * Change the type of the chart\n * @default \"donut\"\n */\n type?: 'donut' | 'pie'\n /**\n * Function to sort the segment\n */\n sortFunction?: (a: any, b: any) => number | undefined\n /**\n * Controls the formatting for the label.\n */\n valueFormatter?: (tick: number, i?: number, ticks?: number[]) => string\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n}>(), {\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n sortFunction: () => undefined,\n valueFormatter: (tick: number) => `${tick}`,\n type: 'donut',\n filterOpacity: 0.2,\n showTooltip: true,\n showLegend: true,\n})\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst category = computed(() => props.category as KeyOfT)\nconst index = computed(() => props.index as KeyOfT)\n\nconst isMounted = useMounted()\nconst activeSegmentKey = ref<string>()\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.data.filter(d => d[props.category]).filter(Boolean).length))\nconst legendItems = computed(() => props.data.map((item, i) => ({\n name: item[props.index],\n color: colors.value[i],\n inactive: false,\n})))\n\nconst totalValue = computed(() => props.data.reduce((prev, curr) => {\n return prev + curr[props.category]\n}, 0))\n</script>\n\n<template>\n <div :class=\"cn('w-full h-48 flex flex-col items-end', $attrs.class ?? '')\">\n <VisSingleContainer :style=\"{ height: isMounted ? '100%' : 'auto' }\" :margin=\"{ left: 20, right: 20 }\" :data=\"data\">\n <ChartSingleTooltip\n :selector=\"Donut.selectors.segment\"\n :index=\"category\"\n :items=\"legendItems\"\n :value-formatter=\"valueFormatter\"\n :custom-tooltip=\"customTooltip\"\n />\n\n <VisDonut\n :value=\"(d: Data) => d[category]\"\n :sort-function=\"sortFunction\"\n :color=\"colors\"\n :arc-width=\"type === 'donut' ? 20 : 0\"\n :show-background=\"false\"\n :central-label=\"type === 'donut' ? valueFormatter(totalValue) : ''\"\n :events=\"{\n [Donut.selectors.segment]: {\n click: (d: Data, ev: PointerEvent, i: number, elements: HTMLElement[]) => {\n if (d?.data?.[index] === activeSegmentKey) {\n activeSegmentKey = undefined\n elements.forEach(el => el.style.opacity = '1')\n }\n else {\n activeSegmentKey = d?.data?.[index]\n elements.forEach(el => el.style.opacity = `${filterOpacity}`)\n elements[i].style.opacity = '1'\n }\n },\n },\n }\"\n />\n\n <slot />\n </VisSingleContainer>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BaseChartProps } from '.'\nimport { cn } from '@/lib/utils'\nimport { ChartSingleTooltip, defaultColors } from '@/registry/new-york/ui/chart'\nimport { Donut } from '@unovis/ts'\nimport { VisDonut, VisSingleContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<Pick<BaseChartProps<T>, 'data' | 'colors' | 'index' | 'margin' | 'showLegend' | 'showTooltip' | 'filterOpacity'> & {\n /**\n * Sets the name of the key containing the quantitative chart values.\n */\n category: KeyOfT\n /**\n * Change the type of the chart\n * @default \"donut\"\n */\n type?: 'donut' | 'pie'\n /**\n * Function to sort the segment\n */\n sortFunction?: (a: any, b: any) => number | undefined\n /**\n * Controls the formatting for the label.\n */\n valueFormatter?: (tick: number, i?: number, ticks?: number[]) => string\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n}>(), {\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n sortFunction: () => undefined,\n valueFormatter: (tick: number) => `${tick}`,\n type: 'donut',\n filterOpacity: 0.2,\n showTooltip: true,\n showLegend: true,\n})\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst category = computed(() => props.category as KeyOfT)\nconst index = computed(() => props.index as KeyOfT)\n\nconst isMounted = useMounted()\nconst activeSegmentKey = ref<string>()\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.data.filter(d => d[props.category]).filter(Boolean).length))\nconst legendItems = computed(() => props.data.map((item, i) => ({\n name: item[props.index],\n color: colors.value[i],\n inactive: false,\n})))\n\nconst totalValue = computed(() => props.data.reduce((prev, curr) => {\n return prev + curr[props.category]\n}, 0))\n</script>\n\n<template>\n <div :class=\"cn('w-full h-48 flex flex-col items-end', $attrs.class ?? '')\">\n <VisSingleContainer :style=\"{ height: isMounted ? '100%' : 'auto' }\" :margin=\"{ left: 20, right: 20 }\" :data=\"data\">\n <ChartSingleTooltip\n :selector=\"Donut.selectors.segment\"\n :index=\"category\"\n :items=\"legendItems\"\n :value-formatter=\"valueFormatter\"\n :custom-tooltip=\"customTooltip\"\n />\n\n <VisDonut\n :value=\"(d: Data) => d[category]\"\n :sort-function=\"sortFunction\"\n :color=\"colors\"\n :arc-width=\"type === 'donut' ? 20 : 0\"\n :show-background=\"false\"\n :central-label=\"type === 'donut' ? valueFormatter(totalValue) : ''\"\n :events=\"{\n [Donut.selectors.segment]: {\n click: (d: Data, ev: PointerEvent, i: number, elements: HTMLElement[]) => {\n if (d?.data?.[index] === activeSegmentKey) {\n activeSegmentKey = undefined\n elements.forEach(el => el.style.opacity = '1')\n }\n else {\n activeSegmentKey = d?.data?.[index]\n elements.forEach(el => el.style.opacity = `${filterOpacity}`)\n elements[i].style.opacity = '1'\n }\n },\n },\n }\"\n />\n\n <slot />\n </VisSingleContainer>\n </div>\n</template>\n",
"type": "registry:ui",
"target": "chart-donut/DonutChart.vue"
},

View File

@ -7,13 +7,13 @@
"@vueuse/core"
],
"registryDependencies": [
"chart",
"utils"
"utils",
"chart"
],
"files": [
{
"path": "ui/chart-line/LineChart.vue",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BaseChartProps } from '.'\nimport { ChartCrosshair, ChartLegend, defaultColors } from '@/registry/new-york/ui/chart'\nimport { cn } from '@/lib/utils'\nimport { type BulletLegendItemInterface, CurveType } from '@unovis/ts'\nimport { Axis, Line } from '@unovis/ts'\nimport { VisAxis, VisLine, VisXYContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<BaseChartProps<T> & {\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n /**\n * Type of curve\n */\n curveType?: CurveType\n}>(), {\n curveType: CurveType.MonotoneX,\n filterOpacity: 0.2,\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n showXAxis: true,\n showYAxis: true,\n showTooltip: true,\n showLegend: true,\n showGridLine: true,\n})\n\nconst emits = defineEmits<{\n legendItemClick: [d: BulletLegendItemInterface, i: number]\n}>()\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst index = computed(() => props.index as KeyOfT)\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))\n\nconst legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({\n name: category,\n color: colors.value[i],\n inactive: false,\n})))\n\nconst isMounted = useMounted()\n\nfunction handleLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n}\n</script>\n\n<template>\n <div :class=\"cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')\">\n <ChartLegend v-if=\"showLegend\" v-model:items=\"legendItems\" @legend-item-click=\"handleLegendItemClick\" />\n\n <VisXYContainer\n :margin=\"{ left: 20, right: 20 }\"\n :data=\"data\"\n :style=\"{ height: isMounted ? '100%' : 'auto' }\"\n >\n <ChartCrosshair v-if=\"showTooltip\" :colors=\"colors\" :items=\"legendItems\" :index=\"index\" :custom-tooltip=\"customTooltip\" />\n\n <template v-for=\"(category, i) in categories\" :key=\"category\">\n <VisLine\n :x=\"(d: Data, i: number) => i\"\n :y=\"(d: Data) => d[category]\"\n :curve-type=\"curveType\"\n :color=\"colors[i]\"\n :attributes=\"{\n [Line.selectors.line]: {\n opacity: legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1,\n },\n }\"\n />\n </template>\n\n <VisAxis\n v-if=\"showXAxis\"\n type=\"x\"\n :tick-format=\"xFormatter ?? ((v: number) => data[v]?.[index])\"\n :grid-line=\"false\"\n :tick-line=\"false\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n <VisAxis\n v-if=\"showYAxis\"\n type=\"y\"\n :tick-line=\"false\"\n :tick-format=\"yFormatter\"\n :domain-line=\"false\"\n :grid-line=\"showGridLine\"\n :attributes=\"{\n [Axis.selectors.grid]: {\n class: 'text-muted',\n },\n }\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n\n <slot />\n </VisXYContainer>\n </div>\n</template>\n",
"content": "<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport type { BaseChartProps } from '.'\nimport { cn } from '@/lib/utils'\nimport { ChartCrosshair, ChartLegend, defaultColors } from '@/registry/new-york/ui/chart'\nimport { type BulletLegendItemInterface, CurveType } from '@unovis/ts'\nimport { Axis, Line } from '@unovis/ts'\nimport { VisAxis, VisLine, VisXYContainer } from '@unovis/vue'\nimport { useMounted } from '@vueuse/core'\nimport { type Component, computed, ref } from 'vue'\n\nconst props = withDefaults(defineProps<BaseChartProps<T> & {\n /**\n * Render custom tooltip component.\n */\n customTooltip?: Component\n /**\n * Type of curve\n */\n curveType?: CurveType\n}>(), {\n curveType: CurveType.MonotoneX,\n filterOpacity: 0.2,\n margin: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),\n showXAxis: true,\n showYAxis: true,\n showTooltip: true,\n showLegend: true,\n showGridLine: true,\n})\n\nconst emits = defineEmits<{\n legendItemClick: [d: BulletLegendItemInterface, i: number]\n}>()\n\ntype KeyOfT = Extract<keyof T, string>\ntype Data = typeof props.data[number]\n\nconst index = computed(() => props.index as KeyOfT)\nconst colors = computed(() => props.colors?.length ? props.colors : defaultColors(props.categories.length))\n\nconst legendItems = ref<BulletLegendItemInterface[]>(props.categories.map((category, i) => ({\n name: category,\n color: colors.value[i],\n inactive: false,\n})))\n\nconst isMounted = useMounted()\n\nfunction handleLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n}\n</script>\n\n<template>\n <div :class=\"cn('w-full h-[400px] flex flex-col items-end', $attrs.class ?? '')\">\n <ChartLegend v-if=\"showLegend\" v-model:items=\"legendItems\" @legend-item-click=\"handleLegendItemClick\" />\n\n <VisXYContainer\n :margin=\"{ left: 20, right: 20 }\"\n :data=\"data\"\n :style=\"{ height: isMounted ? '100%' : 'auto' }\"\n >\n <ChartCrosshair v-if=\"showTooltip\" :colors=\"colors\" :items=\"legendItems\" :index=\"index\" :custom-tooltip=\"customTooltip\" />\n\n <template v-for=\"(category, i) in categories\" :key=\"category\">\n <VisLine\n :x=\"(d: Data, i: number) => i\"\n :y=\"(d: Data) => d[category]\"\n :curve-type=\"curveType\"\n :color=\"colors[i]\"\n :attributes=\"{\n [Line.selectors.line]: {\n opacity: legendItems.find(item => item.name === category)?.inactive ? filterOpacity : 1,\n },\n }\"\n />\n </template>\n\n <VisAxis\n v-if=\"showXAxis\"\n type=\"x\"\n :tick-format=\"xFormatter ?? ((v: number) => data[v]?.[index])\"\n :grid-line=\"false\"\n :tick-line=\"false\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n <VisAxis\n v-if=\"showYAxis\"\n type=\"y\"\n :tick-line=\"false\"\n :tick-format=\"yFormatter\"\n :domain-line=\"false\"\n :grid-line=\"showGridLine\"\n :attributes=\"{\n [Axis.selectors.grid]: {\n class: 'text-muted',\n },\n }\"\n tick-text-color=\"hsl(var(--vis-text-color))\"\n />\n\n <slot />\n </VisXYContainer>\n </div>\n</template>\n",
"type": "registry:ui",
"target": "chart-line/LineChart.vue"
},

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