15102 lines
2.1 MiB
15102 lines
2.1 MiB
[
|
|
{
|
|
"name": "utils",
|
|
"type": "registry:lib",
|
|
"dependencies": [
|
|
"clsx",
|
|
"tailwind-merge"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "lib/utils.ts",
|
|
"type": "registry:lib"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "theme-daylight",
|
|
"type": "registry:theme",
|
|
"cssVars": {
|
|
"light": {
|
|
"background": "36 39% 88%",
|
|
"foreground": "36 45% 15%",
|
|
"primary": "36 45% 70%",
|
|
"primary-foreground": "36 45% 11%",
|
|
"secondary": "40 35% 77%",
|
|
"secondary-foreground": "36 45% 25%",
|
|
"accent": "36 64% 57%",
|
|
"accent-foreground": "36 72% 17%",
|
|
"destructive": "0 84% 37%",
|
|
"destructive-foreground": "0 0% 98%",
|
|
"muted": "36 33% 75%",
|
|
"muted-foreground": "36 45% 25%",
|
|
"card": "36 46% 82%",
|
|
"card-foreground": "36 45% 20%",
|
|
"popover": "0 0% 100%",
|
|
"popover-foreground": "240 10% 3.9%",
|
|
"border": "36 45% 60%",
|
|
"input": "36 45% 60%",
|
|
"ring": "36 45% 30%",
|
|
"chart-1": "25 34% 28%",
|
|
"chart-2": "26 36% 34%",
|
|
"chart-3": "28 40% 40%",
|
|
"chart-4": "31 41% 48%",
|
|
"chart-5": "35 43% 53%"
|
|
},
|
|
"dark": {
|
|
"background": "36 39% 88%",
|
|
"foreground": "36 45% 15%",
|
|
"primary": "36 45% 70%",
|
|
"primary-foreground": "36 45% 11%",
|
|
"secondary": "40 35% 77%",
|
|
"secondary-foreground": "36 45% 25%",
|
|
"accent": "36 64% 57%",
|
|
"accent-foreground": "36 72% 17%",
|
|
"destructive": "0 84% 37%",
|
|
"destructive-foreground": "0 0% 98%",
|
|
"muted": "36 33% 75%",
|
|
"muted-foreground": "36 45% 25%",
|
|
"card": "36 46% 82%",
|
|
"card-foreground": "36 45% 20%",
|
|
"popover": "0 0% 100%",
|
|
"popover-foreground": "240 10% 3.9%",
|
|
"border": "36 45% 60%",
|
|
"input": "36 45% 60%",
|
|
"ring": "36 45% 30%",
|
|
"chart-1": "25 34% 28%",
|
|
"chart-2": "26 36% 34%",
|
|
"chart-3": "28 40% 40%",
|
|
"chart-4": "31 41% 48%",
|
|
"chart-5": "35 43% 53%"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "theme-midnight",
|
|
"type": "registry:theme",
|
|
"cssVars": {
|
|
"light": {
|
|
"background": "240 5% 6%",
|
|
"foreground": "60 5% 90%",
|
|
"primary": "240 0% 90%",
|
|
"primary-foreground": "60 0% 0%",
|
|
"secondary": "240 4% 15%",
|
|
"secondary-foreground": "60 5% 85%",
|
|
"accent": "240 0% 13%",
|
|
"accent-foreground": "60 0% 100%",
|
|
"destructive": "0 60% 50%",
|
|
"destructive-foreground": "0 0% 98%",
|
|
"muted": "240 5% 25%",
|
|
"muted-foreground": "60 5% 85%",
|
|
"card": "240 4% 10%",
|
|
"card-foreground": "60 5% 90%",
|
|
"popover": "240 5% 15%",
|
|
"popover-foreground": "60 5% 85%",
|
|
"border": "240 6% 20%",
|
|
"input": "240 6% 20%",
|
|
"ring": "240 5% 90%",
|
|
"chart-1": "359 2% 90%",
|
|
"chart-2": "240 1% 74%",
|
|
"chart-3": "240 1% 58%",
|
|
"chart-4": "240 1% 42%",
|
|
"chart-5": "240 2% 26%"
|
|
},
|
|
"dark": {
|
|
"background": "240 5% 6%",
|
|
"foreground": "60 5% 90%",
|
|
"primary": "240 0% 90%",
|
|
"primary-foreground": "60 0% 0%",
|
|
"secondary": "240 4% 15%",
|
|
"secondary-foreground": "60 5% 85%",
|
|
"accent": "240 0% 13%",
|
|
"accent-foreground": "60 0% 100%",
|
|
"destructive": "0 60% 50%",
|
|
"destructive-foreground": "0 0% 98%",
|
|
"muted": "240 5% 25%",
|
|
"muted-foreground": "60 5% 85%",
|
|
"card": "240 4% 10%",
|
|
"card-foreground": "60 5% 90%",
|
|
"popover": "240 5% 15%",
|
|
"popover-foreground": "60 5% 85%",
|
|
"border": "240 6% 20%",
|
|
"input": "240 6% 20%",
|
|
"ring": "240 5% 90%",
|
|
"chart-1": "359 2% 90%",
|
|
"chart-2": "240 1% 74%",
|
|
"chart-3": "240 1% 58%",
|
|
"chart-4": "240 1% 42%",
|
|
"chart-5": "240 2% 26%"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "theme-emerald",
|
|
"type": "registry:theme",
|
|
"cssVars": {
|
|
"light": {
|
|
"background": "0 0% 100%",
|
|
"foreground": "240 10% 3.9%",
|
|
"card": "0 0% 100%",
|
|
"card-foreground": "240 10% 3.9%",
|
|
"popover": "0 0% 100%",
|
|
"popover-foreground": "240 10% 3.9%",
|
|
"primary": "142 86% 28%",
|
|
"primary-foreground": "356 29% 98%",
|
|
"secondary": "240 4.8% 95.9%",
|
|
"secondary-foreground": "240 5.9% 10%",
|
|
"muted": "240 4.8% 95.9%",
|
|
"muted-foreground": "240 3.8% 45%",
|
|
"accent": "240 4.8% 95.9%",
|
|
"accent-foreground": "240 5.9% 10%",
|
|
"destructive": "0 72% 51%",
|
|
"destructive-foreground": "0 0% 98%",
|
|
"border": "240 5.9% 90%",
|
|
"input": "240 5.9% 90%",
|
|
"ring": "142 86% 28%",
|
|
"chart-1": "139 65% 20%",
|
|
"chart-2": "140 74% 44%",
|
|
"chart-3": "142 88% 28%",
|
|
"chart-4": "137 55% 15%",
|
|
"chart-5": "141 40% 9%"
|
|
},
|
|
"dark": {
|
|
"background": "240 10% 3.9%",
|
|
"foreground": "0 0% 98%",
|
|
"card": "240 10% 3.9%",
|
|
"card-foreground": "0 0% 98%",
|
|
"popover": "240 10% 3.9%",
|
|
"popover-foreground": "0 0% 98%",
|
|
"primary": "142 86% 28%",
|
|
"primary-foreground": "356 29% 98%",
|
|
"secondary": "240 4.8% 95.9%",
|
|
"secondary-foreground": "240 5.9% 10%",
|
|
"muted": "240 3.7% 15.9%",
|
|
"muted-foreground": "240 5% 64.9%",
|
|
"accent": "240 3.7% 15.9%",
|
|
"accent-foreground": "0 0% 98%",
|
|
"destructive": "0 72% 51%",
|
|
"destructive-foreground": "0 0% 98%",
|
|
"border": "240 3.7% 15.9%",
|
|
"input": "240 3.7% 15.9%",
|
|
"ring": "142 86% 28%",
|
|
"chart-1": "142 88% 28%",
|
|
"chart-2": "139 65% 20%",
|
|
"chart-3": "140 74% 24%",
|
|
"chart-4": "137 55% 15%",
|
|
"chart-5": "141 40% 9%"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "accordion",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/accordion/Accordion.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n AccordionRoot,\n type AccordionRootEmits,\n type AccordionRootProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<AccordionRootProps>()\nconst emits = defineEmits<AccordionRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <AccordionRoot v-bind=\"forwarded\">\n <slot />\n </AccordionRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/accordion/AccordionContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { AccordionContent, type AccordionContentProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AccordionContentProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AccordionContent\n v-bind=\"delegatedProps\"\n class=\"overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\"\n >\n <div :class=\"cn('pb-4 pt-0', props.class)\">\n <slot />\n </div>\n </AccordionContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/accordion/AccordionItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { AccordionItem, type AccordionItemProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AccordionItemProps & { 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 <AccordionItem\n v-bind=\"forwardedProps\"\n :class=\"cn('border-b', props.class)\"\n >\n <slot />\n </AccordionItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/accordion/AccordionTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronDownIcon } from '@radix-icons/vue'\nimport {\n AccordionHeader,\n AccordionTrigger,\n type AccordionTriggerProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AccordionTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AccordionHeader class=\"flex\">\n <AccordionTrigger\n v-bind=\"delegatedProps\"\n :class=\"\n cn(\n 'flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',\n props.class,\n )\n \"\n >\n <slot />\n <slot name=\"icon\">\n <ChevronDownIcon\n class=\"h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200\"\n />\n </slot>\n </AccordionTrigger>\n </AccordionHeader>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/accordion/index.ts",
|
|
"content": "export { default as Accordion } from './Accordion.vue'\nexport { default as AccordionContent } from './AccordionContent.vue'\nexport { default as AccordionItem } from './AccordionItem.vue'\nexport { default as AccordionTrigger } from './AccordionTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "alert",
|
|
"type": "registry:ui",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/alert/Alert.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { type AlertVariants, alertVariants } from '.'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n variant?: AlertVariants['variant']\n}>()\n</script>\n\n<template>\n <div :class=\"cn(alertVariants({ variant }), props.class)\" role=\"alert\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert/AlertDescription.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('text-sm [&_p]:leading-relaxed', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert/AlertTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <h5 :class=\"cn('mb-1 font-medium leading-none tracking-tight', props.class)\">\n <slot />\n </h5>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert/index.ts",
|
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Alert } from './Alert.vue'\nexport { default as AlertDescription } from './AlertDescription.vue'\nexport { default as AlertTitle } from './AlertTitle.vue'\n\nexport const alertVariants = cva(\n 'relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7',\n {\n variants: {\n variant: {\n default: 'bg-background text-foreground',\n destructive:\n 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n)\n\nexport type AlertVariants = VariantProps<typeof alertVariants>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "alert-dialog",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialog.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { type AlertDialogEmits, type AlertDialogProps, AlertDialogRoot, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<AlertDialogProps>()\nconst emits = defineEmits<AlertDialogEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <AlertDialogRoot v-bind=\"forwarded\">\n <slot />\n </AlertDialogRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogAction.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogCancel.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n AlertDialogContent,\n type AlertDialogContentEmits,\n type AlertDialogContentProps,\n AlertDialogOverlay,\n AlertDialogPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<AlertDialogContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <AlertDialogPortal>\n <AlertDialogOverlay\n class=\"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n />\n <AlertDialogContent\n v-bind=\"forwarded\"\n :class=\"\n cn(\n 'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',\n props.class,\n )\n \"\n >\n <slot />\n </AlertDialogContent>\n </AlertDialogPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogDescription.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n AlertDialogDescription,\n type AlertDialogDescriptionProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogDescriptionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AlertDialogDescription\n v-bind=\"delegatedProps\"\n :class=\"cn('text-sm text-muted-foreground', props.class)\"\n >\n <slot />\n </AlertDialogDescription>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n :class=\"\n cn(\n 'flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-x-2',\n props.class,\n )\n \"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n :class=\"cn('flex flex-col gap-y-2 text-center sm:text-left', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { AlertDialogTitle, type AlertDialogTitleProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogTitleProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AlertDialogTitle\n v-bind=\"delegatedProps\"\n :class=\"cn('text-lg font-semibold', props.class)\"\n >\n <slot />\n </AlertDialogTitle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AlertDialogTrigger, type AlertDialogTriggerProps } from 'reka-ui'\n\nconst props = defineProps<AlertDialogTriggerProps>()\n</script>\n\n<template>\n <AlertDialogTrigger v-bind=\"props\">\n <slot />\n </AlertDialogTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/index.ts",
|
|
"content": "export { default as AlertDialog } from './AlertDialog.vue'\nexport { default as AlertDialogAction } from './AlertDialogAction.vue'\nexport { default as AlertDialogCancel } from './AlertDialogCancel.vue'\nexport { default as AlertDialogContent } from './AlertDialogContent.vue'\nexport { default as AlertDialogDescription } from './AlertDialogDescription.vue'\nexport { default as AlertDialogFooter } from './AlertDialogFooter.vue'\nexport { default as AlertDialogHeader } from './AlertDialogHeader.vue'\nexport { default as AlertDialogTitle } from './AlertDialogTitle.vue'\nexport { default as AlertDialogTrigger } from './AlertDialogTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "aspect-ratio",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "ui/aspect-ratio/AspectRatio.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AspectRatio, type AspectRatioProps } from 'reka-ui'\n\nconst props = defineProps<AspectRatioProps>()\n</script>\n\n<template>\n <AspectRatio v-bind=\"props\">\n <slot />\n </AspectRatio>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/aspect-ratio/index.ts",
|
|
"content": "export { default as AspectRatio } from './AspectRatio.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "auto-form",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod",
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"form",
|
|
"accordion",
|
|
"button",
|
|
"separator",
|
|
"checkbox",
|
|
"switch",
|
|
"utils",
|
|
"calendar",
|
|
"popover",
|
|
"label",
|
|
"radio-group",
|
|
"select",
|
|
"input",
|
|
"textarea"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/auto-form/AutoForm.vue",
|
|
"content": "<script setup lang=\"ts\" generic=\"T extends ZodObjectOrWrapped\">\nimport type { FormContext, GenericObject } from 'vee-validate'\nimport type { z, ZodAny } from 'zod'\nimport type { Config, ConfigItem, Dependency, Shape } from './interface'\nimport { Form } from '@/registry/new-york/ui/form'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { computed, toRefs } from 'vue'\nimport AutoFormField from './AutoFormField.vue'\nimport { provideDependencies } from './dependencies'\nimport { getBaseSchema, getBaseType, getDefaultValueInZodStack, getObjectFormSchema, type ZodObjectOrWrapped } from './utils'\n\nconst props = defineProps<{\n schema: T\n form?: FormContext<GenericObject>\n fieldConfig?: Config<z.infer<T>>\n dependencies?: Dependency<z.infer<T>>[]\n}>()\n\nconst emits = defineEmits<{\n submit: [event: z.infer<T>]\n}>()\n\nconst { dependencies } = toRefs(props)\nprovideDependencies(dependencies)\n\nconst shapes = computed(() => {\n // @ts-expect-error ignore {} not assignable to object\n const val: { [key in keyof T]: Shape } = {}\n const baseSchema = getObjectFormSchema(props.schema)\n const shape = baseSchema.shape\n Object.keys(shape).forEach((name) => {\n const item = shape[name] as ZodAny\n const baseItem = getBaseSchema(item) as ZodAny\n let options = (baseItem && 'values' in baseItem._def) ? baseItem._def.values as string[] : undefined\n if (!Array.isArray(options) && typeof options === 'object')\n options = Object.values(options)\n\n val[name as keyof T] = {\n type: getBaseType(item),\n default: getDefaultValueInZodStack(item),\n options,\n required: !['ZodOptional', 'ZodNullable'].includes(item._def.typeName),\n schema: baseItem,\n }\n })\n return val\n})\n\nconst fields = computed(() => {\n // @ts-expect-error ignore {} not assignable to object\n const val: { [key in keyof z.infer<T>]: { shape: Shape, fieldName: string, config: ConfigItem } } = {}\n for (const key in shapes.value) {\n const shape = shapes.value[key]\n val[key as keyof z.infer<T>] = {\n shape,\n config: props.fieldConfig?.[key] as ConfigItem,\n fieldName: key,\n }\n }\n return val\n})\n\nconst formComponent = computed(() => props.form ? 'form' : Form)\nconst formComponentProps = computed(() => {\n if (props.form) {\n return {\n onSubmit: props.form.handleSubmit(val => emits('submit', val)),\n }\n }\n else {\n const formSchema = toTypedSchema(props.schema)\n return {\n keepValues: true,\n validationSchema: formSchema,\n onSubmit: (val: GenericObject) => emits('submit', val),\n }\n }\n})\n</script>\n\n<template>\n <component\n :is=\"formComponent\"\n v-bind=\"formComponentProps\"\n >\n <slot name=\"customAutoForm\" :fields=\"fields\">\n <template v-for=\"(shape, key) of shapes\" :key=\"key\">\n <slot\n :shape=\"shape\"\n :name=\"key.toString() as keyof z.infer<T>\"\n :field-name=\"key.toString()\"\n :config=\"fieldConfig?.[key as keyof typeof fieldConfig] as ConfigItem\"\n >\n <AutoFormField\n :config=\"fieldConfig?.[key as keyof typeof fieldConfig] as ConfigItem\"\n :field-name=\"key.toString()\"\n :shape=\"shape\"\n />\n </slot>\n </template>\n </slot>\n\n <slot :shapes=\"shapes\" />\n </component>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormField.vue",
|
|
"content": "<script setup lang=\"ts\" generic=\"U extends ZodAny\">\nimport type { ZodAny } from 'zod'\nimport type { Config, ConfigItem, Shape } from './interface'\nimport { computed } from 'vue'\nimport { DEFAULT_ZOD_HANDLERS, INPUT_COMPONENTS } from './constant'\nimport useDependencies from './dependencies'\n\nconst props = defineProps<{\n fieldName: string\n shape: Shape\n config?: ConfigItem | Config<U>\n}>()\n\nfunction isValidConfig(config: any): config is ConfigItem {\n return !!config?.component\n}\n\nconst delegatedProps = computed(() => {\n if (['ZodObject', 'ZodArray'].includes(props.shape?.type))\n return { schema: props.shape?.schema }\n return undefined\n})\n\nconst { isDisabled, isHidden, isRequired, overrideOptions } = useDependencies(props.fieldName)\n</script>\n\n<template>\n <component\n :is=\"isValidConfig(config)\n ? typeof config.component === 'string'\n ? INPUT_COMPONENTS[config.component!]\n : config.component\n : INPUT_COMPONENTS[DEFAULT_ZOD_HANDLERS[shape.type]] \"\n v-if=\"!isHidden\"\n :field-name=\"fieldName\"\n :label=\"shape.schema?.description\"\n :required=\"isRequired || shape.required\"\n :options=\"overrideOptions || shape.options\"\n :disabled=\"isDisabled\"\n :config=\"config\"\n v-bind=\"delegatedProps\"\n >\n <slot />\n </component>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldArray.vue",
|
|
"content": "<script setup lang=\"ts\" generic=\"T extends z.ZodAny\">\nimport type { Config, ConfigItem } from './interface'\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/registry/new-york/ui/accordion'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { FormItem, FormMessage } from '@/registry/new-york/ui/form'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport { PlusIcon, TrashIcon } from 'lucide-vue-next'\nimport { FieldArray, FieldContextKey, useField } from 'vee-validate'\nimport { computed, provide } from 'vue'\nimport * as z from 'zod'\nimport AutoFormField from './AutoFormField.vue'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName, getBaseType } from './utils'\n\nconst props = defineProps<{\n fieldName: string\n required?: boolean\n config?: Config<T>\n schema?: z.ZodArray<T>\n disabled?: boolean\n}>()\n\nfunction isZodArray(\n item: z.ZodArray<any> | z.ZodDefault<any>,\n): item is z.ZodArray<any> {\n return item instanceof z.ZodArray\n}\n\nfunction isZodDefault(\n item: z.ZodArray<any> | z.ZodDefault<any>,\n): item is z.ZodDefault<any> {\n return item instanceof z.ZodDefault\n}\n\nconst itemShape = computed(() => {\n if (!props.schema)\n return\n\n const schema: z.ZodAny = isZodArray(props.schema)\n ? props.schema._def.type\n : isZodDefault(props.schema)\n // @ts-expect-error missing schema\n ? props.schema._def.innerType._def.type\n : null\n\n return {\n type: getBaseType(schema),\n schema,\n }\n})\n\nconst fieldContext = useField(props.fieldName)\n// @ts-expect-error ignore missing `id`\nprovide(FieldContextKey, fieldContext)\n</script>\n\n<template>\n <FieldArray v-slot=\"{ fields, remove, push }\" as=\"section\" :name=\"fieldName\">\n <slot v-bind=\"props\">\n <Accordion type=\"multiple\" class=\"w-full\" collapsible :disabled=\"disabled\" as-child>\n <FormItem>\n <AccordionItem :value=\"fieldName\" class=\"border-none\">\n <AccordionTrigger>\n <AutoFormLabel class=\"text-base\" :required=\"required\">\n {{ schema?.description || beautifyObjectName(fieldName) }}\n </AutoFormLabel>\n </AccordionTrigger>\n\n <AccordionContent>\n <template v-for=\"(field, index) of fields\" :key=\"field.key\">\n <div class=\"mb-4 p-1\">\n <AutoFormField\n :field-name=\"`${fieldName}[${index}]`\"\n :label=\"fieldName\"\n :shape=\"itemShape!\"\n :config=\"config as ConfigItem\"\n />\n\n <div class=\"!my-4 flex justify-end\">\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"secondary\"\n @click=\"remove(index)\"\n >\n <TrashIcon :size=\"16\" />\n </Button>\n </div>\n <Separator v-if=\"!field.isLast\" />\n </div>\n </template>\n\n <Button\n type=\"button\"\n variant=\"secondary\"\n class=\"mt-4 flex items-center\"\n @click=\"push(null)\"\n >\n <PlusIcon class=\"mr-2\" :size=\"16\" />\n Add\n </Button>\n </AccordionContent>\n\n <FormMessage />\n </AccordionItem>\n </FormItem>\n </Accordion>\n </slot>\n </FieldArray>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldBoolean.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { Checkbox } from '@/registry/new-york/ui/checkbox'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/new-york/ui/form'\nimport { Switch } from '@/registry/new-york/ui/switch'\nimport { computed } from 'vue'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\nconst props = defineProps<FieldProps>()\n\nconst booleanComponent = computed(() => props.config?.component === 'switch' ? Switch : Checkbox)\n</script>\n\n<template>\n <FormField v-slot=\"slotProps\" :name=\"fieldName\">\n <FormItem>\n <div class=\"space-y-0 mb-3 flex items-center gap-3\">\n <FormControl>\n <slot v-bind=\"slotProps\">\n <component\n :is=\"booleanComponent\"\n v-bind=\"{ ...slotProps.componentField }\"\n :disabled=\"disabled\"\n :model-value=\"slotProps.componentField.modelValue\"\n @update:model-value=\"slotProps.componentField['onUpdate:modelValue']\"\n />\n </slot>\n </FormControl>\n <AutoFormLabel v-if=\"!config?.hideLabel\" :required=\"required\">\n {{ config?.label || beautifyObjectName(label ?? fieldName) }}\n </AutoFormLabel>\n </div>\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": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldDate.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldEnum.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/new-york/ui/form'\nimport { Label } from '@/registry/new-york/ui/label'\nimport { RadioGroup, RadioGroupItem } from '@/registry/new-york/ui/radio-group'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/registry/new-york/ui/select'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\ndefineProps<FieldProps & {\n options?: string[]\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 <RadioGroup v-if=\"config?.component === 'radio'\" :disabled=\"disabled\" :orientation=\"'vertical'\" v-bind=\"{ ...slotProps.componentField }\">\n <div v-for=\"(option, index) in options\" :key=\"option\" class=\"mb-2 flex items-center gap-3 space-y-0\">\n <RadioGroupItem :id=\"`${option}-${index}`\" :value=\"option\" />\n <Label :for=\"`${option}-${index}`\">{{ beautifyObjectName(option) }}</Label>\n </div>\n </RadioGroup>\n\n <Select v-else :disabled=\"disabled\" v-bind=\"{ ...slotProps.componentField }\">\n <SelectTrigger class=\"w-full\">\n <SelectValue :placeholder=\"config?.inputProps?.placeholder\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem v-for=\"option in options\" :key=\"option\" :value=\"option\">\n {{ beautifyObjectName(option) }}\n </SelectItem>\n </SelectContent>\n </Select>\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": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldFile.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/new-york/ui/form'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { TrashIcon } from '@radix-icons/vue'\nimport { ref } from 'vue'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\ndefineProps<FieldProps>()\n\nconst inputFile = ref<File>()\nasync function parseFileAsString(file: File | undefined): Promise<string> {\n return new Promise((resolve, reject) => {\n if (file) {\n const reader = new FileReader()\n reader.onloadend = () => {\n resolve(reader.result as string)\n }\n reader.onerror = (err) => {\n reject(err)\n }\n reader.readAsDataURL(file)\n }\n })\n}\n</script>\n\n<template>\n <FormField v-slot=\"slotProps\" :name=\"fieldName\">\n <FormItem v-bind=\"$attrs\">\n <AutoFormLabel v-if=\"!config?.hideLabel\" :required=\"required\">\n {{ config?.label || beautifyObjectName(label ?? fieldName) }}\n </AutoFormLabel>\n <FormControl>\n <slot v-bind=\"slotProps\">\n <Input\n v-if=\"!inputFile\"\n type=\"file\"\n v-bind=\"{ ...config?.inputProps }\"\n :disabled=\"disabled\"\n @change=\"async (ev: InputEvent) => {\n const file = (ev.target as HTMLInputElement).files?.[0]\n inputFile = file\n const parsed = await parseFileAsString(file)\n slotProps.componentField.onInput(parsed)\n }\"\n />\n <div v-else class=\"flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent pl-3 pr-1 py-1 text-sm shadow-sm transition-colors\">\n <p>{{ inputFile?.name }}</p>\n <Button\n :size=\"'icon'\"\n :variant=\"'ghost'\"\n class=\"h-[26px] w-[26px]\"\n aria-label=\"Remove file\"\n type=\"button\"\n @click=\"() => {\n inputFile = undefined\n slotProps.componentField.onInput(undefined)\n }\"\n >\n <TrashIcon />\n </Button>\n </div>\n </slot>\n </FormControl>\n <FormDescription v-if=\"config?.description\">\n {{ config.description }}\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/new-york/ui/form'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Textarea } from '@/registry/new-york/ui/textarea'\nimport { computed } from 'vue'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\nconst props = defineProps<FieldProps>()\nconst inputComponent = computed(() => props.config?.component === 'textarea' ? Textarea : Input)\n</script>\n\n<template>\n <FormField v-slot=\"slotProps\" :name=\"fieldName\">\n <FormItem v-bind=\"$attrs\">\n <AutoFormLabel v-if=\"!config?.hideLabel\" :required=\"required\">\n {{ config?.label || beautifyObjectName(label ?? fieldName) }}\n </AutoFormLabel>\n <FormControl>\n <slot v-bind=\"slotProps\">\n <component\n :is=\"inputComponent\"\n type=\"text\"\n v-bind=\"{ ...slotProps.componentField, ...config?.inputProps }\"\n :disabled=\"disabled\"\n />\n </slot>\n </FormControl>\n <FormDescription v-if=\"config?.description\">\n {{ config.description }}\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldNumber.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/new-york/ui/form'\nimport { Input } from '@/registry/new-york/ui/input'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\ndefineProps<FieldProps>()\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 <Input type=\"number\" v-bind=\"{ ...slotProps.componentField, ...config?.inputProps }\" :disabled=\"disabled\" />\n </slot>\n </FormControl>\n <FormDescription v-if=\"config?.description\">\n {{ config.description }}\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldObject.vue",
|
|
"content": "<script setup lang=\"ts\" generic=\"T extends ZodRawShape\">\nimport type { ZodAny, ZodObject, ZodRawShape } from 'zod'\nimport type { Config, ConfigItem, Shape } from './interface'\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/registry/new-york/ui/accordion'\nimport { FormItem } from '@/registry/new-york/ui/form'\nimport { FieldContextKey, useField } from 'vee-validate'\nimport { computed, provide } from 'vue'\nimport AutoFormField from './AutoFormField.vue'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName, getBaseSchema, getBaseType, getDefaultValueInZodStack } from './utils'\n\nconst props = defineProps<{\n fieldName: string\n required?: boolean\n config?: Config<T>\n schema?: ZodObject<T>\n disabled?: boolean\n}>()\n\nconst shapes = computed(() => {\n // @ts-expect-error ignore {} not assignable to object\n const val: { [key in keyof T]: Shape } = {}\n\n if (!props.schema)\n return\n const shape = getBaseSchema(props.schema)?.shape\n if (!shape)\n return\n Object.keys(shape).forEach((name) => {\n const item = shape[name] as ZodAny\n const baseItem = getBaseSchema(item) as ZodAny\n let options = (baseItem && 'values' in baseItem._def) ? baseItem._def.values as string[] : undefined\n if (!Array.isArray(options) && typeof options === 'object')\n options = Object.values(options)\n\n val[name as keyof T] = {\n type: getBaseType(item),\n default: getDefaultValueInZodStack(item),\n options,\n required: !['ZodOptional', 'ZodNullable'].includes(item._def.typeName),\n schema: item,\n }\n })\n return val\n})\n\nconst fieldContext = useField(props.fieldName)\n// @ts-expect-error ignore missing `id`\nprovide(FieldContextKey, fieldContext)\n</script>\n\n<template>\n <section>\n <slot v-bind=\"props\">\n <Accordion type=\"single\" as-child class=\"w-full\" collapsible :disabled=\"disabled\">\n <FormItem>\n <AccordionItem :value=\"fieldName\" class=\"border-none\">\n <AccordionTrigger>\n <AutoFormLabel class=\"text-base\" :required=\"required\">\n {{ schema?.description || beautifyObjectName(fieldName) }}\n </AutoFormLabel>\n </AccordionTrigger>\n <AccordionContent class=\"p-1 space-y-5\">\n <template v-for=\"(shape, key) in shapes\" :key=\"key\">\n <AutoFormField\n :config=\"config?.[key as keyof typeof config] as ConfigItem\"\n :field-name=\"`${fieldName}.${key.toString()}`\"\n :label=\"key.toString()\"\n :shape=\"shape\"\n />\n </template>\n </AccordionContent>\n </AccordionItem>\n </FormItem>\n </Accordion>\n </slot>\n </section>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { FormLabel } from '@/registry/new-york/ui/form'\n\ndefineProps<{\n required?: boolean\n}>()\n</script>\n\n<template>\n <FormLabel>\n <slot />\n <span v-if=\"required\" class=\"text-destructive\"> *</span>\n </FormLabel>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/constant.ts",
|
|
"content": "import type { InputComponents } from './interface'\nimport AutoFormFieldArray from './AutoFormFieldArray.vue'\nimport AutoFormFieldBoolean from './AutoFormFieldBoolean.vue'\nimport AutoFormFieldDate from './AutoFormFieldDate.vue'\nimport AutoFormFieldEnum from './AutoFormFieldEnum.vue'\nimport AutoFormFieldFile from './AutoFormFieldFile.vue'\nimport AutoFormFieldInput from './AutoFormFieldInput.vue'\nimport AutoFormFieldNumber from './AutoFormFieldNumber.vue'\nimport AutoFormFieldObject from './AutoFormFieldObject.vue'\n\nexport const INPUT_COMPONENTS: InputComponents = {\n date: AutoFormFieldDate,\n select: AutoFormFieldEnum,\n radio: AutoFormFieldEnum,\n checkbox: AutoFormFieldBoolean,\n switch: AutoFormFieldBoolean,\n textarea: AutoFormFieldInput,\n number: AutoFormFieldNumber,\n string: AutoFormFieldInput,\n file: AutoFormFieldFile,\n array: AutoFormFieldArray,\n object: AutoFormFieldObject,\n}\n\n/**\n * Define handlers for specific Zod types.\n * You can expand this object to support more types.\n */\nexport const DEFAULT_ZOD_HANDLERS: {\n [key: string]: keyof typeof INPUT_COMPONENTS\n} = {\n ZodString: 'string',\n ZodBoolean: 'checkbox',\n ZodDate: 'date',\n ZodEnum: 'select',\n ZodNativeEnum: 'select',\n ZodNumber: 'number',\n ZodArray: 'array',\n ZodObject: 'object',\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/dependencies.ts",
|
|
"content": "import type { Ref } from 'vue'\nimport type * as z from 'zod'\nimport { createContext } from 'reka-ui'\nimport { useFieldValue, useFormValues } from 'vee-validate'\nimport { computed, ref, watch } from 'vue'\nimport { type Dependency, DependencyType, type EnumValues } from './interface'\nimport { getFromPath, getIndexIfArray } from './utils'\n\nexport const [injectDependencies, provideDependencies] = createContext<Ref<Dependency<z.infer<z.ZodObject<any>>>[] | undefined>>('AutoFormDependencies')\n\nexport default function useDependencies(\n fieldName: string,\n) {\n const form = useFormValues()\n // parsed test[0].age => test.age\n const currentFieldName = fieldName.replace(/\\[\\d+\\]/g, '')\n const currentFieldValue = useFieldValue<any>(fieldName)\n\n if (!form)\n throw new Error('useDependencies should be used within <AutoForm>')\n\n const dependencies = injectDependencies()\n const isDisabled = ref(false)\n const isHidden = ref(false)\n const isRequired = ref(false)\n const overrideOptions = ref<EnumValues | undefined>()\n\n const currentFieldDependencies = computed(() => dependencies.value?.filter(\n dependency => dependency.targetField === currentFieldName,\n ))\n\n function getSourceValue(dep: Dependency<any>) {\n const source = dep.sourceField as string\n const index = getIndexIfArray(fieldName) ?? -1\n const [sourceLast, ...sourceInitial] = source.split('.').toReversed()\n const [_targetLast, ...targetInitial] = (dep.targetField as string).split('.').toReversed()\n\n if (index >= 0 && sourceInitial.join(',') === targetInitial.join(',')) {\n const [_currentLast, ...currentInitial] = fieldName.split('.').toReversed()\n return getFromPath(form.value, currentInitial.join('.') + sourceLast)\n }\n\n return getFromPath(form.value, source)\n }\n\n const sourceFieldValues = computed(() => currentFieldDependencies.value?.map(dep => getSourceValue(dep)))\n\n const resetConditionState = () => {\n isDisabled.value = false\n isHidden.value = false\n isRequired.value = false\n overrideOptions.value = undefined\n }\n\n watch([sourceFieldValues, dependencies], () => {\n resetConditionState()\n currentFieldDependencies.value?.forEach((dep) => {\n const sourceValue = getSourceValue(dep)\n const conditionMet = dep.when(sourceValue, currentFieldValue.value)\n\n switch (dep.type) {\n case DependencyType.DISABLES:\n if (conditionMet)\n isDisabled.value = true\n\n break\n case DependencyType.REQUIRES:\n if (conditionMet)\n isRequired.value = true\n\n break\n case DependencyType.HIDES:\n if (conditionMet)\n isHidden.value = true\n\n break\n case DependencyType.SETS_OPTIONS:\n if (conditionMet)\n overrideOptions.value = dep.options\n\n break\n }\n })\n }, { immediate: true, deep: true })\n\n return {\n isDisabled,\n isHidden,\n isRequired,\n overrideOptions,\n }\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/index.ts",
|
|
"content": "export { default as AutoForm } from './AutoForm.vue'\nexport { default as AutoFormField } from './AutoFormField.vue'\n\nexport { default as AutoFormFieldArray } from './AutoFormFieldArray.vue'\nexport { default as AutoFormFieldBoolean } from './AutoFormFieldBoolean.vue'\nexport { default as AutoFormFieldDate } from './AutoFormFieldDate.vue'\n\nexport { default as AutoFormFieldEnum } from './AutoFormFieldEnum.vue'\nexport { default as AutoFormFieldFile } from './AutoFormFieldFile.vue'\nexport { default as AutoFormFieldInput } from './AutoFormFieldInput.vue'\nexport { default as AutoFormFieldNumber } from './AutoFormFieldNumber.vue'\nexport { default as AutoFormFieldObject } from './AutoFormFieldObject.vue'\nexport { default as AutoFormLabel } from './AutoFormLabel.vue'\nexport type { Config, ConfigItem, FieldProps } from './interface'\nexport { getBaseSchema, getBaseType, getObjectFormSchema } from './utils'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/interface.ts",
|
|
"content": "import type { Component, InputHTMLAttributes } from 'vue'\nimport type { z, ZodAny } from 'zod'\nimport type { INPUT_COMPONENTS } from './constant'\n\nexport interface FieldProps {\n fieldName: string\n label?: string\n required?: boolean\n config?: ConfigItem\n disabled?: boolean\n}\n\nexport interface Shape {\n type: string\n default?: any\n required?: boolean\n options?: string[]\n schema?: ZodAny\n}\n\nexport interface InputComponents {\n date: Component\n select: Component\n radio: Component\n checkbox: Component\n switch: Component\n textarea: Component\n number: Component\n string: Component\n file: Component\n array: Component\n object: Component\n};\n\nexport interface ConfigItem {\n /** Value for the `FormLabel` */\n label?: string\n /** Value for the `FormDescription` */\n description?: string\n /** Pick which component to be rendered. */\n component?: keyof typeof INPUT_COMPONENTS | Component\n /** Hide `FormLabel`. */\n hideLabel?: boolean\n inputProps?: InputHTMLAttributes\n}\n\n// Define a type to unwrap an array\ntype UnwrapArray<T> = T extends (infer U)[] ? U : never\n\nexport type Config<SchemaType extends object> = {\n // If SchemaType.key is an object, create a nested Config, otherwise ConfigItem\n [Key in keyof SchemaType]?:\n SchemaType[Key] extends any[]\n ? UnwrapArray<Config<SchemaType[Key]>>\n : SchemaType[Key] extends object\n ? Config<SchemaType[Key]>\n : ConfigItem;\n}\n\nexport enum DependencyType {\n DISABLES,\n REQUIRES,\n HIDES,\n SETS_OPTIONS,\n}\n\ninterface BaseDependency<SchemaType extends z.infer<z.ZodObject<any, any>>> {\n sourceField: keyof SchemaType\n type: DependencyType\n targetField: keyof SchemaType\n when: (sourceFieldValue: any, targetFieldValue: any) => boolean\n}\n\nexport type ValueDependency<SchemaType extends z.infer<z.ZodObject<any, any>>> =\n BaseDependency<SchemaType> & {\n type:\n | DependencyType.DISABLES\n | DependencyType.REQUIRES\n | DependencyType.HIDES\n }\n\nexport type EnumValues = readonly [string, ...string[]]\n\nexport type OptionsDependency<\n SchemaType extends z.infer<z.ZodObject<any, any>>,\n> = BaseDependency<SchemaType> & {\n type: DependencyType.SETS_OPTIONS\n\n // Partial array of values from sourceField that will trigger the dependency\n options: EnumValues\n}\n\nexport type Dependency<SchemaType extends z.infer<z.ZodObject<any, any>>> =\n | ValueDependency<SchemaType>\n | OptionsDependency<SchemaType>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/utils.ts",
|
|
"content": "import type { z } from 'zod'\n\n// TODO: This should support recursive ZodEffects but TypeScript doesn't allow circular type definitions.\nexport type ZodObjectOrWrapped =\n | z.ZodObject<any, any>\n | z.ZodEffects<z.ZodObject<any, any>>\n\n/**\n * Beautify a camelCase string.\n * e.g. \"myString\" -> \"My String\"\n */\nexport function beautifyObjectName(string: string) {\n // Remove bracketed indices\n // if numbers only return the string\n let output = string.replace(/\\[\\d+\\]/g, '').replace(/([A-Z])/g, ' $1')\n output = output.charAt(0).toUpperCase() + output.slice(1)\n return output\n}\n\n/**\n * Parse string and extract the index\n * @param string\n * @returns index or undefined\n */\nexport function getIndexIfArray(string: string) {\n const indexRegex = /\\[(\\d+)\\]/\n // Match the index\n const match = string.match(indexRegex)\n // Extract the index (number)\n const index = match ? Number.parseInt(match[1]) : undefined\n return index\n}\n\n/**\n * Get the lowest level Zod type.\n * This will unpack optionals, refinements, etc.\n */\nexport function getBaseSchema<\n ChildType extends z.ZodAny | z.AnyZodObject = z.ZodAny,\n>(schema: ChildType | z.ZodEffects<ChildType>): ChildType | null {\n if (!schema)\n return null\n if ('innerType' in schema._def)\n return getBaseSchema(schema._def.innerType as ChildType)\n\n if ('schema' in schema._def)\n return getBaseSchema(schema._def.schema as ChildType)\n\n return schema as ChildType\n}\n\n/**\n * Get the type name of the lowest level Zod type.\n * This will unpack optionals, refinements, etc.\n */\nexport function getBaseType(schema: z.ZodAny) {\n const baseSchema = getBaseSchema(schema)\n return baseSchema ? baseSchema._def.typeName : ''\n}\n\n/**\n * Search for a \"ZodDefault\" in the Zod stack and return its value.\n */\nexport function getDefaultValueInZodStack(schema: z.ZodAny): any {\n const typedSchema = schema as unknown as z.ZodDefault<\n z.ZodNumber | z.ZodString\n >\n\n if (typedSchema._def.typeName === 'ZodDefault')\n return typedSchema._def.defaultValue()\n\n if ('innerType' in typedSchema._def) {\n return getDefaultValueInZodStack(\n typedSchema._def.innerType as unknown as z.ZodAny,\n )\n }\n if ('schema' in typedSchema._def) {\n return getDefaultValueInZodStack(\n (typedSchema._def as any).schema as z.ZodAny,\n )\n }\n\n return undefined\n}\n\nexport function getObjectFormSchema(\n schema: ZodObjectOrWrapped,\n): z.ZodObject<any, any> {\n if (schema?._def.typeName === 'ZodEffects') {\n const typedSchema = schema as z.ZodEffects<z.ZodObject<any, any>>\n return getObjectFormSchema(typedSchema._def.schema)\n }\n return schema as z.ZodObject<any, any>\n}\n\nfunction isIndex(value: unknown): value is number {\n return Number(value) >= 0\n}\n/**\n * Constructs a path with dot paths for arrays to use brackets to be compatible with vee-validate path syntax\n */\nexport function normalizeFormPath(path: string): string {\n const pathArr = path.split('.')\n if (!pathArr.length)\n return ''\n\n let fullPath = String(pathArr[0])\n for (let i = 1; i < pathArr.length; i++) {\n if (isIndex(pathArr[i])) {\n fullPath += `[${pathArr[i]}]`\n continue\n }\n\n fullPath += `.${pathArr[i]}`\n }\n\n return fullPath\n}\n\ntype NestedRecord = Record<string, unknown> | { [k: string]: NestedRecord }\n/**\n * Checks if the path opted out of nested fields using `[fieldName]` syntax\n */\nexport function isNotNestedPath(path: string) {\n return /^\\[.+\\]$/.test(path)\n}\nfunction isObject(obj: unknown): obj is Record<string, unknown> {\n return obj !== null && !!obj && typeof obj === 'object' && !Array.isArray(obj)\n}\nfunction isContainerValue(value: unknown): value is Record<string, unknown> {\n return isObject(value) || Array.isArray(value)\n}\nfunction cleanupNonNestedPath(path: string) {\n if (isNotNestedPath(path))\n return path.replace(/\\[|\\]/g, '')\n\n return path\n}\n\n/**\n * Gets a nested property value from an object\n */\nexport function getFromPath<TValue = unknown>(object: NestedRecord | undefined, path: string): TValue | undefined\nexport function getFromPath<TValue = unknown, TFallback = TValue>(\n object: NestedRecord | undefined,\n path: string,\n fallback?: TFallback,\n): TValue | TFallback\nexport function getFromPath<TValue = unknown, TFallback = TValue>(\n object: NestedRecord | undefined,\n path: string,\n fallback?: TFallback,\n): TValue | TFallback | undefined {\n if (!object)\n return fallback\n\n if (isNotNestedPath(path))\n return object[cleanupNonNestedPath(path)] as TValue | undefined\n\n const resolvedValue = (path || '')\n .split(/\\.|\\[(\\d+)\\]/)\n .filter(Boolean)\n .reduce((acc, propKey) => {\n if (isContainerValue(acc) && propKey in acc)\n return acc[propKey]\n\n return fallback\n }, object as unknown)\n\n return resolvedValue as TValue | undefined\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "avatar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/avatar/Avatar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { AvatarRoot } from 'reka-ui'\nimport { avatarVariant, type AvatarVariants } from '.'\n\nconst props = withDefaults(defineProps<{\n class?: HTMLAttributes['class']\n size?: AvatarVariants['size']\n shape?: AvatarVariants['shape']\n}>(), {\n size: 'sm',\n shape: 'circle',\n})\n</script>\n\n<template>\n <AvatarRoot :class=\"cn(avatarVariant({ size, shape }), props.class)\">\n <slot />\n </AvatarRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/avatar/AvatarFallback.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AvatarFallback, type AvatarFallbackProps } from 'reka-ui'\n\nconst props = defineProps<AvatarFallbackProps>()\n</script>\n\n<template>\n <AvatarFallback v-bind=\"props\">\n <slot />\n </AvatarFallback>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/avatar/AvatarImage.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AvatarImage, type AvatarImageProps } from 'reka-ui'\n\nconst props = defineProps<AvatarImageProps>()\n</script>\n\n<template>\n <AvatarImage v-bind=\"props\" class=\"h-full w-full object-cover\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/avatar/index.ts",
|
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Avatar } from './Avatar.vue'\nexport { default as AvatarFallback } from './AvatarFallback.vue'\nexport { default as AvatarImage } from './AvatarImage.vue'\n\nexport const avatarVariant = cva(\n 'inline-flex items-center justify-center font-normal text-foreground select-none shrink-0 bg-secondary overflow-hidden',\n {\n variants: {\n size: {\n sm: 'h-10 w-10 text-xs',\n base: 'h-16 w-16 text-2xl',\n lg: 'h-32 w-32 text-5xl',\n },\n shape: {\n circle: 'rounded-full',\n square: 'rounded-md',\n },\n },\n },\n)\n\nexport type AvatarVariants = VariantProps<typeof avatarVariant>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "badge",
|
|
"type": "registry:ui",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/badge/Badge.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { type BadgeVariants, badgeVariants } from '.'\n\nconst props = defineProps<{\n variant?: BadgeVariants['variant']\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn(badgeVariants({ variant }), props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/badge/index.ts",
|
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Badge } from './Badge.vue'\n\nexport const badgeVariants = cva(\n 'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',\n {\n variants: {\n variant: {\n default:\n 'border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80',\n secondary:\n 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',\n destructive:\n 'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80',\n outline: 'text-foreground',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n)\n\nexport type BadgeVariants = VariantProps<typeof badgeVariants>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "breadcrumb",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/breadcrumb/Breadcrumb.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <nav aria-label=\"breadcrumb\" :class=\"props.class\">\n <slot />\n </nav>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/BreadcrumbEllipsis.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { DotsHorizontalIcon } from '@radix-icons/vue'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n :class=\"cn('flex h-9 w-9 items-center justify-center', props.class)\"\n >\n <slot>\n <DotsHorizontalIcon class=\"h-4 w-4\" />\n </slot>\n <span class=\"sr-only\">More</span>\n </span>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/BreadcrumbItem.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n :class=\"cn('inline-flex items-center gap-1.5', props.class)\"\n >\n <slot />\n </li>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/BreadcrumbLink.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps } from 'reka-ui'\n\nconst props = withDefaults(defineProps<PrimitiveProps & { class?: HTMLAttributes['class'] }>(), {\n as: 'a',\n})\n</script>\n\n<template>\n <Primitive\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn('transition-colors hover:text-foreground', props.class)\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/BreadcrumbList.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <ol\n :class=\"cn('flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5', props.class)\"\n >\n <slot />\n </ol>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/BreadcrumbPage.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n :class=\"cn('font-normal text-foreground', props.class)\"\n >\n <slot />\n </span>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/BreadcrumbSeparator.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { ChevronRightIcon } from '@radix-icons/vue'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n :class=\"cn('[&>svg]:size-3.5', props.class)\"\n >\n <slot>\n <ChevronRightIcon />\n </slot>\n </li>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/index.ts",
|
|
"content": "export { default as Breadcrumb } from './Breadcrumb.vue'\nexport { default as BreadcrumbEllipsis } from './BreadcrumbEllipsis.vue'\nexport { default as BreadcrumbItem } from './BreadcrumbItem.vue'\nexport { default as BreadcrumbLink } from './BreadcrumbLink.vue'\nexport { default as BreadcrumbList } from './BreadcrumbList.vue'\nexport { default as BreadcrumbPage } from './BreadcrumbPage.vue'\nexport { default as BreadcrumbSeparator } from './BreadcrumbSeparator.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "button",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/button/Button.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps } from 'reka-ui'\nimport { type ButtonVariants, buttonVariants } from '.'\n\ninterface Props extends PrimitiveProps {\n variant?: ButtonVariants['variant']\n size?: ButtonVariants['size']\n class?: HTMLAttributes['class']\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n as: 'button',\n})\n</script>\n\n<template>\n <Primitive\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn(buttonVariants({ variant, size }), props.class)\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/button/index.ts",
|
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Button } from './Button.vue'\n\nexport const buttonVariants = cva(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground shadow hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',\n outline:\n 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2',\n xs: 'h-7 rounded px-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-8',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "calendar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/calendar/Calendar.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarRoot, type CalendarRootEmits, type CalendarRootProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, CalendarGridHead, CalendarGridRow, CalendarHeadCell, CalendarHeader, CalendarHeading, CalendarNextButton, CalendarPrevButton } from '.'\n\nconst props = defineProps<CalendarRootProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<CalendarRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <CalendarRoot\n v-slot=\"{ grid, weekDays }\"\n :class=\"cn('p-3', props.class)\"\n v-bind=\"forwarded\"\n >\n <CalendarHeader>\n <CalendarPrevButton />\n <CalendarHeading />\n <CalendarNextButton />\n </CalendarHeader>\n\n <div class=\"flex flex-col gap-y-4 mt-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>\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:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarCell.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarCell, type CalendarCellProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarCellProps & { 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 <CalendarCell\n :class=\"cn('relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([data-selected])]:rounded-md [&:has([data-selected])]:bg-accent [&:has([data-selected][data-outside-view])]:bg-accent/50', props.class)\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </CalendarCell>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarCellTrigger.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarGrid.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarGrid, type CalendarGridProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarGridProps & { 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 <CalendarGrid\n :class=\"cn('w-full border-collapse space-y-1', props.class)\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </CalendarGrid>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarGridBody.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { CalendarGridBody, type CalendarGridBodyProps } from 'reka-ui'\n\nconst props = defineProps<CalendarGridBodyProps>()\n</script>\n\n<template>\n <CalendarGridBody v-bind=\"props\">\n <slot />\n </CalendarGridBody>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarGridHead.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { CalendarGridHead, type CalendarGridHeadProps } from 'reka-ui'\n\nconst props = defineProps<CalendarGridHeadProps & { class?: HTMLAttributes['class'] }>()\n</script>\n\n<template>\n <CalendarGridHead v-bind=\"props\">\n <slot />\n </CalendarGridHead>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarGridRow.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarGridRow, type CalendarGridRowProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarGridRowProps & { 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 <CalendarGridRow :class=\"cn('flex', props.class)\" v-bind=\"forwardedProps\">\n <slot />\n </CalendarGridRow>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarHeadCell.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarHeadCell, type CalendarHeadCellProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarHeadCellProps & { 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 <CalendarHeadCell :class=\"cn('w-8 rounded-md text-[0.8rem] font-normal text-muted-foreground', props.class)\" v-bind=\"forwardedProps\">\n <slot />\n </CalendarHeadCell>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarHeader.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarHeader, type CalendarHeaderProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarHeaderProps & { 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 <CalendarHeader :class=\"cn('relative flex w-full items-center justify-between pt-1', props.class)\" v-bind=\"forwardedProps\">\n <slot />\n </CalendarHeader>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarHeading.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarHeading, type CalendarHeadingProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarHeadingProps & { 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 <CalendarHeading\n v-slot=\"{ headingValue }\"\n :class=\"cn('text-sm font-medium', props.class)\"\n v-bind=\"forwardedProps\"\n >\n <slot :heading-value>\n {{ headingValue }}\n </slot>\n </CalendarHeading>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarNextButton.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarPrevButton.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/index.ts",
|
|
"content": "export { default as Calendar } from './Calendar.vue'\nexport { default as CalendarCell } from './CalendarCell.vue'\nexport { default as CalendarCellTrigger } from './CalendarCellTrigger.vue'\nexport { default as CalendarGrid } from './CalendarGrid.vue'\nexport { default as CalendarGridBody } from './CalendarGridBody.vue'\nexport { default as CalendarGridHead } from './CalendarGridHead.vue'\nexport { default as CalendarGridRow } from './CalendarGridRow.vue'\nexport { default as CalendarHeadCell } from './CalendarHeadCell.vue'\nexport { default as CalendarHeader } from './CalendarHeader.vue'\nexport { default as CalendarHeading } from './CalendarHeading.vue'\nexport { default as CalendarNextButton } from './CalendarNextButton.vue'\nexport { default as CalendarPrevButton } from './CalendarPrevButton.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "card",
|
|
"type": "registry:ui",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/card/Card.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n :class=\"\n cn(\n 'rounded-xl border bg-card text-card-foreground shadow',\n props.class,\n )\n \"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/card/CardContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('p-6 pt-0', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/card/CardDescription.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <p :class=\"cn('text-sm text-muted-foreground', props.class)\">\n <slot />\n </p>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/card/CardFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('flex items-center p-6 pt-0', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/card/CardHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('flex flex-col gap-y-1.5 p-6', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/card/CardTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <h3\n :class=\"\n cn('font-semibold leading-none tracking-tight', props.class)\n \"\n >\n <slot />\n </h3>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/card/index.ts",
|
|
"content": "export { default as Card } from './Card.vue'\nexport { default as CardContent } from './CardContent.vue'\nexport { default as CardDescription } from './CardDescription.vue'\nexport { default as CardFooter } from './CardFooter.vue'\nexport { default as CardHeader } from './CardHeader.vue'\nexport { default as CardTitle } from './CardTitle.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "carousel",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"embla-carousel-vue",
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/carousel/Carousel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { CarouselEmits, CarouselProps, WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\nimport { useProvideCarousel } from './useCarousel'\n\nconst props = withDefaults(defineProps<CarouselProps & WithClassAsProps>(), {\n orientation: 'horizontal',\n})\n\nconst emits = defineEmits<CarouselEmits>()\n\nconst { canScrollNext, canScrollPrev, carouselApi, carouselRef, orientation, scrollNext, scrollPrev } = useProvideCarousel(props, emits)\n\ndefineExpose({\n canScrollNext,\n canScrollPrev,\n carouselApi,\n carouselRef,\n orientation,\n scrollNext,\n scrollPrev,\n})\n\nfunction onKeyDown(event: KeyboardEvent) {\n const prevKey = props.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft'\n const nextKey = props.orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight'\n\n if (event.key === prevKey) {\n event.preventDefault()\n scrollPrev()\n\n return\n }\n\n if (event.key === nextKey) {\n event.preventDefault()\n scrollNext()\n }\n}\n</script>\n\n<template>\n <div\n :class=\"cn('relative', props.class)\"\n role=\"region\"\n aria-roledescription=\"carousel\"\n tabindex=\"0\"\n @keydown=\"onKeyDown\"\n >\n <slot :can-scroll-next :can-scroll-prev :carousel-api :carousel-ref :orientation :scroll-next :scroll-prev />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/CarouselContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\nimport { useCarousel } from './useCarousel'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { carouselRef, orientation } = useCarousel()\n</script>\n\n<template>\n <div ref=\"carouselRef\" class=\"overflow-hidden\">\n <div\n :class=\"\n cn(\n 'flex',\n orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col',\n props.class,\n )\"\n v-bind=\"$attrs\"\n >\n <slot />\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/CarouselItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\nimport { useCarousel } from './useCarousel'\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { orientation } = useCarousel()\n</script>\n\n<template>\n <div\n role=\"group\"\n aria-roledescription=\"slide\"\n :class=\"cn(\n 'min-w-0 shrink-0 grow-0 basis-full',\n orientation === 'horizontal' ? 'pl-4' : 'pt-4',\n props.class,\n )\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/CarouselNext.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/CarouselPrevious.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/index.ts",
|
|
"content": "export { default as Carousel } from './Carousel.vue'\nexport { default as CarouselContent } from './CarouselContent.vue'\nexport { default as CarouselItem } from './CarouselItem.vue'\nexport { default as CarouselNext } from './CarouselNext.vue'\nexport { default as CarouselPrevious } from './CarouselPrevious.vue'\nexport type {\n UnwrapRefCarouselApi as CarouselApi,\n} from './interface'\n\nexport { useCarousel } from './useCarousel'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/interface.ts",
|
|
"content": "import type useEmblaCarousel from 'embla-carousel-vue'\nimport type {\n EmblaCarouselVueType,\n} from 'embla-carousel-vue'\nimport type { HTMLAttributes, UnwrapRef } from 'vue'\n\ntype CarouselApi = EmblaCarouselVueType[1]\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>\ntype CarouselOptions = UseCarouselParameters[0]\ntype CarouselPlugin = UseCarouselParameters[1]\n\nexport type UnwrapRefCarouselApi = UnwrapRef<CarouselApi>\n\nexport interface CarouselProps {\n opts?: CarouselOptions\n plugins?: CarouselPlugin\n orientation?: 'horizontal' | 'vertical'\n}\n\nexport interface CarouselEmits {\n (e: 'init-api', payload: UnwrapRefCarouselApi): void\n}\n\nexport interface WithClassAsProps {\n class?: HTMLAttributes['class']\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/useCarousel.ts",
|
|
"content": "import type { UnwrapRefCarouselApi as CarouselApi, CarouselEmits, CarouselProps } from './interface'\nimport { createInjectionState } from '@vueuse/core'\nimport emblaCarouselVue from 'embla-carousel-vue'\nimport { onMounted, ref } from 'vue'\n\nconst [useProvideCarousel, useInjectCarousel] = createInjectionState(\n ({\n opts,\n orientation,\n plugins,\n }: CarouselProps, emits: CarouselEmits) => {\n const [emblaNode, emblaApi] = emblaCarouselVue({\n ...opts,\n axis: orientation === 'horizontal' ? 'x' : 'y',\n }, plugins)\n\n function scrollPrev() {\n emblaApi.value?.scrollPrev()\n }\n function scrollNext() {\n emblaApi.value?.scrollNext()\n }\n\n const canScrollNext = ref(false)\n const canScrollPrev = ref(false)\n\n function onSelect(api: CarouselApi) {\n canScrollNext.value = api?.canScrollNext() || false\n canScrollPrev.value = api?.canScrollPrev() || false\n }\n\n onMounted(() => {\n if (!emblaApi.value)\n return\n\n emblaApi.value?.on('init', onSelect)\n emblaApi.value?.on('reInit', onSelect)\n emblaApi.value?.on('select', onSelect)\n\n emits('init-api', emblaApi.value)\n })\n\n return { carouselRef: emblaNode, carouselApi: emblaApi, canScrollPrev, canScrollNext, scrollPrev, scrollNext, orientation }\n },\n)\n\nfunction useCarousel() {\n const carouselState = useInjectCarousel()\n\n if (!carouselState)\n throw new Error('useCarousel must be used within a <Carousel />')\n\n return carouselState\n}\n\nexport { useCarousel, useProvideCarousel }\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "chart",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/chart/ChartCrosshair.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { BulletLegendItemInterface } from '@unovis/ts'\nimport { omit } from '@unovis/ts'\nimport { VisCrosshair, VisTooltip } from '@unovis/vue'\nimport { type Component, createApp } from 'vue'\nimport { ChartTooltip } from '.'\n\nconst props = withDefaults(defineProps<{\n colors: string[]\n index: string\n items: BulletLegendItemInterface[]\n customTooltip?: Component\n}>(), {\n colors: () => [],\n})\n\n// Use weakmap to store reference to each datapoint for Tooltip\nconst wm = new WeakMap()\nfunction template(d: any) {\n if (wm.has(d)) {\n return wm.get(d)\n }\n else {\n const componentDiv = document.createElement('div')\n const omittedData = Object.entries(omit(d, [props.index])).map(([key, value]) => {\n const legendReference = props.items.find(i => i.name === key)\n return { ...legendReference, value }\n })\n const TooltipComponent = props.customTooltip ?? ChartTooltip\n createApp(TooltipComponent, { title: d[props.index].toString(), data: omittedData }).mount(componentDiv)\n wm.set(d, componentDiv.innerHTML)\n return componentDiv.innerHTML\n }\n}\n\nfunction color(d: unknown, i: number) {\n return props.colors[i] ?? 'transparent'\n}\n</script>\n\n<template>\n <VisTooltip :horizontal-shift=\"20\" :vertical-shift=\"20\" />\n <VisCrosshair :template=\"template\" :color=\"color\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/chart/ChartLegend.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { BulletLegendItemInterface } from '@unovis/ts'\nimport { buttonVariants } from '@/registry/new-york/ui/button'\nimport { BulletLegend } from '@unovis/ts'\nimport { VisBulletLegend } from '@unovis/vue'\nimport { nextTick, onMounted, ref } from 'vue'\n\nconst props = withDefaults(defineProps<{ items: BulletLegendItemInterface[] }>(), {\n items: () => [],\n})\n\nconst emits = defineEmits<{\n 'legendItemClick': [d: BulletLegendItemInterface, i: number]\n 'update:items': [payload: BulletLegendItemInterface[]]\n}>()\n\nconst elRef = ref<HTMLElement>()\n\nonMounted(() => {\n const selector = `.${BulletLegend.selectors.item}`\n nextTick(() => {\n const elements = elRef.value?.querySelectorAll(selector)\n const classes = buttonVariants({ variant: 'ghost', size: 'xs' }).split(' ')\n\n elements?.forEach(el => el.classList.add(...classes, '!inline-flex', '!mr-2'))\n })\n})\n\nfunction onLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n const isBulletActive = !props.items[i].inactive\n const isFilterApplied = props.items.some(i => i.inactive)\n if (isFilterApplied && isBulletActive) {\n // reset filter\n emits('update:items', props.items.map(item => ({ ...item, inactive: false })))\n }\n else {\n // apply selection, set other item as inactive\n emits('update:items', props.items.map(item => item.name === d.name ? ({ ...d, inactive: false }) : { ...item, inactive: true }))\n }\n}\n</script>\n\n<template>\n <div ref=\"elRef\" class=\"w-max\">\n <VisBulletLegend\n :items=\"items\"\n :on-legend-item-click=\"onLegendItemClick\"\n />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/chart/ChartSingleTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { BulletLegendItemInterface } from '@unovis/ts'\nimport { omit } from '@unovis/ts'\nimport { VisTooltip } from '@unovis/vue'\nimport { type Component, createApp } from 'vue'\nimport { ChartTooltip } from '.'\n\nconst props = withDefaults(defineProps<{\n selector: string\n index: string\n items?: BulletLegendItemInterface[]\n valueFormatter?: (tick: number, i?: number, ticks?: number[]) => string\n customTooltip?: Component\n}>(), {\n valueFormatter: (tick: number) => `${tick}`,\n})\n\n// Use weakmap to store reference to each datapoint for Tooltip\nconst wm = new WeakMap()\nfunction template(d: any, i: number, elements: (HTMLElement | SVGElement)[]) {\n if (props.index in d) {\n if (wm.has(d)) {\n return wm.get(d)\n }\n else {\n const componentDiv = document.createElement('div')\n const omittedData = Object.entries(omit(d, [props.index])).map(([key, value]) => {\n const legendReference = props.items?.find(i => i.name === key)\n return { ...legendReference, value: props.valueFormatter(value) }\n })\n const TooltipComponent = props.customTooltip ?? ChartTooltip\n createApp(TooltipComponent, { title: d[props.index], data: omittedData }).mount(componentDiv)\n wm.set(d, componentDiv.innerHTML)\n return componentDiv.innerHTML\n }\n }\n\n else {\n const data = d.data\n\n if (wm.has(data)) {\n return wm.get(data)\n }\n else {\n const style = getComputedStyle(elements[i])\n const omittedData = [{ name: data.name, value: props.valueFormatter(data[props.index]), color: style.fill }]\n const componentDiv = document.createElement('div')\n const TooltipComponent = props.customTooltip ?? ChartTooltip\n createApp(TooltipComponent, { title: d[props.index], data: omittedData }).mount(componentDiv)\n wm.set(d, componentDiv.innerHTML)\n return componentDiv.innerHTML\n }\n }\n}\n</script>\n\n<template>\n <VisTooltip\n :horizontal-shift=\"20\" :vertical-shift=\"20\" :triggers=\"{\n [selector]: template,\n }\"\n />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/chart/ChartTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent, CardHeader, CardTitle } from '@/registry/new-york/ui/card'\n\ndefineProps<{\n title?: string\n data: {\n name: string\n color: string\n value: any\n }[]\n}>()\n</script>\n\n<template>\n <Card class=\"text-sm\">\n <CardHeader v-if=\"title\" class=\"p-3 border-b\">\n <CardTitle>\n {{ title }}\n </CardTitle>\n </CardHeader>\n <CardContent class=\"p-3 min-w-[180px] flex flex-col gap-1\">\n <div v-for=\"(item, key) in data\" :key=\"key\" class=\"flex justify-between\">\n <div class=\"flex items-center\">\n <span class=\"w-2.5 h-2.5 mr-2\">\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 30 30\">\n <path\n d=\" M 15 15 m -14, 0 a 14,14 0 1,1 28,0 a 14,14 0 1,1 -28,0\"\n :stroke=\"item.color\"\n :fill=\"item.color\"\n stroke-width=\"1\"\n />\n </svg>\n </span>\n <span>{{ item.name }}</span>\n </div>\n <span class=\"font-semibold ml-4\">{{ item.value }}</span>\n </div>\n </CardContent>\n </Card>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/chart/index.ts",
|
|
"content": "export { default as ChartCrosshair } from './ChartCrosshair.vue'\nexport { default as ChartLegend } from './ChartLegend.vue'\nexport { default as ChartSingleTooltip } from './ChartSingleTooltip.vue'\nexport { default as ChartTooltip } from './ChartTooltip.vue'\n\nexport function defaultColors(count: number = 3) {\n const quotient = Math.floor(count / 2)\n const remainder = count % 2\n\n const primaryCount = quotient + remainder\n const secondaryCount = quotient\n return [\n ...Array.from(new Array(primaryCount).keys()).map(i => `hsl(var(--vis-primary-color) / ${1 - (1 / primaryCount) * i})`),\n ...Array.from(new Array(secondaryCount).keys()).map(i => `hsl(var(--vis-secondary-color) / ${1 - (1 / secondaryCount) * i})`),\n ]\n}\n\nexport * from './interface'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/chart/interface.ts",
|
|
"content": "import type { Spacing } from '@unovis/ts'\n\ntype KeyOf<T extends Record<string, any>> = Extract<keyof T, string>\n\nexport interface BaseChartProps<T extends Record<string, any>> {\n /**\n * The source data, in which each entry is a dictionary.\n */\n data: T[]\n /**\n * Select the categories from your data. Used to populate the legend and toolip.\n */\n categories: KeyOf<T>[]\n /**\n * Sets the key to map the data to the axis.\n */\n index: KeyOf<T>\n /**\n * Change the default colors.\n */\n colors?: string[]\n /**\n * Margin of each the container\n */\n margin?: Spacing\n /**\n * Change the opacity of the non-selected field\n * @default 0.2\n */\n filterOpacity?: number\n /**\n * Function to format X label\n */\n xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Function to format Y label\n */\n yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Controls the visibility of the X axis.\n * @default true\n */\n showXAxis?: boolean\n /**\n * Controls the visibility of the Y axis.\n * @default true\n */\n showYAxis?: boolean\n /**\n * Controls the visibility of tooltip.\n * @default true\n */\n showTooltip?: boolean\n /**\n * Controls the visibility of legend.\n * @default true\n */\n showLegend?: boolean\n /**\n * Controls the visibility of gridline.\n * @default true\n */\n showGridLine?: boolean\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "chart-area",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts",
|
|
"@vueuse/core",
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"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 { 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": ""
|
|
},
|
|
{
|
|
"path": "ui/chart-area/index.ts",
|
|
"content": "export { default as AreaChart } from './AreaChart.vue'\n\nimport type { Spacing } from '@unovis/ts'\n\ntype KeyOf<T extends Record<string, any>> = Extract<keyof T, string>\n\nexport interface BaseChartProps<T extends Record<string, any>> {\n /**\n * The source data, in which each entry is a dictionary.\n */\n data: T[]\n /**\n * Select the categories from your data. Used to populate the legend and toolip.\n */\n categories: KeyOf<T>[]\n /**\n * Sets the key to map the data to the axis.\n */\n index: KeyOf<T>\n /**\n * Change the default colors.\n */\n colors?: string[]\n /**\n * Margin of each the container\n */\n margin?: Spacing\n /**\n * Change the opacity of the non-selected field\n * @default 0.2\n */\n filterOpacity?: number\n /**\n * Function to format X label\n */\n xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Function to format Y label\n */\n yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Controls the visibility of the X axis.\n * @default true\n */\n showXAxis?: boolean\n /**\n * Controls the visibility of the Y axis.\n * @default true\n */\n showYAxis?: boolean\n /**\n * Controls the visibility of tooltip.\n * @default true\n */\n showTooltip?: boolean\n /**\n * Controls the visibility of legend.\n * @default true\n */\n showLegend?: boolean\n /**\n * Controls the visibility of gridline.\n * @default true\n */\n showGridLine?: boolean\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "chart-bar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts",
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"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 { 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": ""
|
|
},
|
|
{
|
|
"path": "ui/chart-bar/index.ts",
|
|
"content": "export { default as BarChart } from './BarChart.vue'\n\nimport type { Spacing } from '@unovis/ts'\n\ntype KeyOf<T extends Record<string, any>> = Extract<keyof T, string>\n\nexport interface BaseChartProps<T extends Record<string, any>> {\n /**\n * The source data, in which each entry is a dictionary.\n */\n data: T[]\n /**\n * Select the categories from your data. Used to populate the legend and toolip.\n */\n categories: KeyOf<T>[]\n /**\n * Sets the key to map the data to the axis.\n */\n index: KeyOf<T>\n /**\n * Change the default colors.\n */\n colors?: string[]\n /**\n * Margin of each the container\n */\n margin?: Spacing\n /**\n * Change the opacity of the non-selected field\n * @default 0.2\n */\n filterOpacity?: number\n /**\n * Function to format X label\n */\n xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Function to format Y label\n */\n yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Controls the visibility of the X axis.\n * @default true\n */\n showXAxis?: boolean\n /**\n * Controls the visibility of the Y axis.\n * @default true\n */\n showYAxis?: boolean\n /**\n * Controls the visibility of tooltip.\n * @default true\n */\n showTooltip?: boolean\n /**\n * Controls the visibility of legend.\n * @default true\n */\n showLegend?: boolean\n /**\n * Controls the visibility of gridline.\n * @default true\n */\n showGridLine?: boolean\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "chart-donut",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts",
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"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 { 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": ""
|
|
},
|
|
{
|
|
"path": "ui/chart-donut/index.ts",
|
|
"content": "export { default as DonutChart } from './DonutChart.vue'\n\nimport type { Spacing } from '@unovis/ts'\n\ntype KeyOf<T extends Record<string, any>> = Extract<keyof T, string>\n\nexport interface BaseChartProps<T extends Record<string, any>> {\n /**\n * The source data, in which each entry is a dictionary.\n */\n data: T[]\n /**\n * Sets the key to map the data to the axis.\n */\n index: KeyOf<T>\n /**\n * Change the default colors.\n */\n colors?: string[]\n /**\n * Margin of each the container\n */\n margin?: Spacing\n /**\n * Change the opacity of the non-selected field\n * @default 0.2\n */\n filterOpacity?: number\n /**\n * Controls the visibility of tooltip.\n * @default true\n */\n showTooltip?: boolean\n /**\n * Controls the visibility of legend.\n * @default true\n */\n showLegend?: boolean\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "chart-line",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts",
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"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 { 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": ""
|
|
},
|
|
{
|
|
"path": "ui/chart-line/index.ts",
|
|
"content": "export { default as LineChart } from './LineChart.vue'\n\nimport type { Spacing } from '@unovis/ts'\n\ntype KeyOf<T extends Record<string, any>> = Extract<keyof T, string>\n\nexport interface BaseChartProps<T extends Record<string, any>> {\n /**\n * The source data, in which each entry is a dictionary.\n */\n data: T[]\n /**\n * Select the categories from your data. Used to populate the legend and toolip.\n */\n categories: KeyOf<T>[]\n /**\n * Sets the key to map the data to the axis.\n */\n index: KeyOf<T>\n /**\n * Change the default colors.\n */\n colors?: string[]\n /**\n * Margin of each the container\n */\n margin?: Spacing\n /**\n * Change the opacity of the non-selected field\n * @default 0.2\n */\n filterOpacity?: number\n /**\n * Function to format X label\n */\n xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Function to format Y label\n */\n yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Controls the visibility of the X axis.\n * @default true\n */\n showXAxis?: boolean\n /**\n * Controls the visibility of the Y axis.\n * @default true\n */\n showYAxis?: boolean\n /**\n * Controls the visibility of tooltip.\n * @default true\n */\n showTooltip?: boolean\n /**\n * Controls the visibility of legend.\n * @default true\n */\n showLegend?: boolean\n /**\n * Controls the visibility of gridline.\n * @default true\n */\n showGridLine?: boolean\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "checkbox",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/checkbox/Checkbox.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { CheckboxRootEmits, CheckboxRootProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { CheckIcon } from '@radix-icons/vue'\nimport { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CheckboxRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<CheckboxRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <CheckboxRoot\n v-bind=\"forwarded\"\n :class=\"\n cn('peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',\n props.class)\"\n >\n <CheckboxIndicator class=\"flex h-full w-full items-center justify-center text-current\">\n <slot>\n <CheckIcon class=\"h-4 w-4\" />\n </slot>\n </CheckboxIndicator>\n </CheckboxRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/checkbox/index.ts",
|
|
"content": "export { default as Checkbox } from './Checkbox.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "collapsible",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "ui/collapsible/Collapsible.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { CollapsibleRootEmits, CollapsibleRootProps } from 'reka-ui'\nimport { CollapsibleRoot, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<CollapsibleRootProps>()\nconst emits = defineEmits<CollapsibleRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <CollapsibleRoot v-slot=\"{ open }\" v-bind=\"forwarded\">\n <slot :open=\"open\" />\n </CollapsibleRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/collapsible/CollapsibleContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { CollapsibleContent, type CollapsibleContentProps } from 'reka-ui'\n\nconst props = defineProps<CollapsibleContentProps>()\n</script>\n\n<template>\n <CollapsibleContent v-bind=\"props\" class=\"overflow-hidden transition-all data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down\">\n <slot />\n </CollapsibleContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/collapsible/CollapsibleTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { CollapsibleTrigger, type CollapsibleTriggerProps } from 'reka-ui'\n\nconst props = defineProps<CollapsibleTriggerProps>()\n</script>\n\n<template>\n <CollapsibleTrigger v-bind=\"props\">\n <slot />\n </CollapsibleTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/collapsible/index.ts",
|
|
"content": "export { default as Collapsible } from './Collapsible.vue'\nexport { default as CollapsibleContent } from './CollapsibleContent.vue'\nexport { default as CollapsibleTrigger } from './CollapsibleTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "command",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"dialog"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/command/Command.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ComboboxRootEmits, ComboboxRootProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { ComboboxRoot, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<ComboboxRootProps & { class?: HTMLAttributes['class'] }>(), {\n open: true,\n modelValue: '',\n})\n\nconst emits = defineEmits<ComboboxRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ComboboxRoot\n v-bind=\"forwarded\"\n :class=\"cn('flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground', props.class)\"\n >\n <slot />\n </ComboboxRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandDialog.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { DialogRootEmits, DialogRootProps } from 'reka-ui'\nimport { Dialog, DialogContent } from '@/registry/new-york/ui/dialog'\nimport { useForwardPropsEmits } from 'reka-ui'\nimport Command from './Command.vue'\n\nconst props = defineProps<DialogRootProps>()\nconst emits = defineEmits<DialogRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <Dialog v-bind=\"forwarded\">\n <DialogContent class=\"overflow-hidden p-0 shadow-lg\">\n <Command class=\"[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n <slot />\n </Command>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandEmpty.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ComboboxEmptyProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { ComboboxEmpty } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ComboboxEmptyProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ComboboxEmpty v-bind=\"delegatedProps\" :class=\"cn('py-6 text-center text-sm', props.class)\">\n <slot />\n </ComboboxEmpty>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ComboboxGroupProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { ComboboxGroup, ComboboxLabel } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ComboboxGroupProps & {\n class?: HTMLAttributes['class']\n heading?: string\n}>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ComboboxGroup\n v-bind=\"delegatedProps\"\n :class=\"cn('overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground', props.class)\"\n >\n <ComboboxLabel v-if=\"heading\" class=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n {{ heading }}\n </ComboboxLabel>\n <slot />\n </ComboboxGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { MagnifyingGlassIcon } from '@radix-icons/vue'\nimport { ComboboxInput, type ComboboxInputProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = defineProps<ComboboxInputProps & {\n class?: HTMLAttributes['class']\n}>()\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 <div class=\"flex items-center border-b px-3\" cmdk-input-wrapper>\n <MagnifyingGlassIcon class=\"mr-2 h-4 w-4 shrink-0 opacity-50\" />\n <ComboboxInput\n v-bind=\"{ ...forwardedProps, ...$attrs }\"\n auto-focus\n :class=\"cn('flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50', props.class)\"\n />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ComboboxItemEmits, ComboboxItemProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { ComboboxItem, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ComboboxItemProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<ComboboxItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ComboboxItem\n v-bind=\"forwarded\"\n :class=\"cn('relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', props.class)\"\n >\n <slot />\n </ComboboxItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandList.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ComboboxContentEmits, ComboboxContentProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { ComboboxContent, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<ComboboxContentProps & { class?: HTMLAttributes['class'] }>(), {\n dismissable: false,\n})\nconst emits = defineEmits<ComboboxContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ComboboxContent v-bind=\"forwarded\" :class=\"cn('max-h-[300px] overflow-y-auto overflow-x-hidden', props.class)\">\n <div role=\"presentation\">\n <slot />\n </div>\n </ComboboxContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ComboboxSeparatorProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { ComboboxSeparator } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ComboboxSeparatorProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ComboboxSeparator\n v-bind=\"delegatedProps\"\n :class=\"cn('-mx-1 h-px bg-border', props.class)\"\n >\n <slot />\n </ComboboxSeparator>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandShortcut.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span :class=\"cn('ml-auto text-xs tracking-widest text-muted-foreground', props.class)\">\n <slot />\n </span>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/index.ts",
|
|
"content": "export { default as Command } from './Command.vue'\nexport { default as CommandDialog } from './CommandDialog.vue'\nexport { default as CommandEmpty } from './CommandEmpty.vue'\nexport { default as CommandGroup } from './CommandGroup.vue'\nexport { default as CommandInput } from './CommandInput.vue'\nexport { default as CommandItem } from './CommandItem.vue'\nexport { default as CommandList } from './CommandList.vue'\nexport { default as CommandSeparator } from './CommandSeparator.vue'\nexport { default as CommandShortcut } from './CommandShortcut.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "context-menu",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/context-menu/ContextMenu.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ContextMenuRootEmits, ContextMenuRootProps } from 'reka-ui'\nimport { ContextMenuRoot, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<ContextMenuRootProps>()\nconst emits = defineEmits<ContextMenuRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <ContextMenuRoot v-bind=\"forwarded\">\n <slot />\n </ContextMenuRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuCheckboxItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { CheckIcon } from '@radix-icons/vue'\nimport {\n ContextMenuCheckboxItem,\n type ContextMenuCheckboxItemEmits,\n type ContextMenuCheckboxItemProps,\n ContextMenuItemIndicator,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuCheckboxItemProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<ContextMenuCheckboxItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ContextMenuCheckboxItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <ContextMenuItemIndicator>\n <CheckIcon class=\"h-4 w-4\" />\n </ContextMenuItemIndicator>\n </span>\n <slot />\n </ContextMenuCheckboxItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n ContextMenuContent,\n type ContextMenuContentEmits,\n type ContextMenuContentProps,\n ContextMenuPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<ContextMenuContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ContextMenuPortal>\n <ContextMenuContent\n v-bind=\"forwarded\"\n :class=\"cn(\n 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\"\n >\n <slot />\n </ContextMenuContent>\n </ContextMenuPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ContextMenuGroup, type ContextMenuGroupProps } from 'reka-ui'\n\nconst props = defineProps<ContextMenuGroupProps>()\n</script>\n\n<template>\n <ContextMenuGroup v-bind=\"props\">\n <slot />\n </ContextMenuGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n ContextMenuItem,\n type ContextMenuItemEmits,\n type ContextMenuItemProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuItemProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\nconst emits = defineEmits<ContextMenuItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ContextMenuItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n </ContextMenuItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ContextMenuLabel, type ContextMenuLabelProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuLabelProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ContextMenuLabel\n v-bind=\"delegatedProps\"\n :class=\"\n cn('px-2 py-1.5 text-sm font-semibold text-foreground',\n inset && 'pl-8', props.class,\n )\"\n >\n <slot />\n </ContextMenuLabel>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuPortal.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ContextMenuPortal, type ContextMenuPortalProps } from 'reka-ui'\n\nconst props = defineProps<ContextMenuPortalProps>()\n</script>\n\n<template>\n <ContextMenuPortal v-bind=\"props\">\n <slot />\n </ContextMenuPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuRadioGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenuRadioGroup,\n type ContextMenuRadioGroupEmits,\n type ContextMenuRadioGroupProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<ContextMenuRadioGroupProps>()\nconst emits = defineEmits<ContextMenuRadioGroupEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <ContextMenuRadioGroup v-bind=\"forwarded\">\n <slot />\n </ContextMenuRadioGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuRadioItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DotFilledIcon } from '@radix-icons/vue'\nimport {\n ContextMenuItemIndicator,\n ContextMenuRadioItem,\n type ContextMenuRadioItemEmits,\n type ContextMenuRadioItemProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuRadioItemProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<ContextMenuRadioItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ContextMenuRadioItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <ContextMenuItemIndicator>\n <DotFilledIcon class=\"h-4 w-4 fill-current\" />\n </ContextMenuItemIndicator>\n </span>\n <slot />\n </ContextMenuRadioItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n ContextMenuSeparator,\n type ContextMenuSeparatorProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuSeparatorProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ContextMenuSeparator v-bind=\"delegatedProps\" :class=\"cn('-mx-1 my-1 h-px bg-border', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuShortcut.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span :class=\"cn('ml-auto text-xs tracking-widest text-muted-foreground', props.class)\">\n <slot />\n </span>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuSub.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenuSub,\n type ContextMenuSubEmits,\n type ContextMenuSubProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<ContextMenuSubProps>()\nconst emits = defineEmits<ContextMenuSubEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <ContextMenuSub v-bind=\"forwarded\">\n <slot />\n </ContextMenuSub>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuSubContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n ContextMenuSubContent,\n type DropdownMenuSubContentEmits,\n type DropdownMenuSubContentProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuSubContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<DropdownMenuSubContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ContextMenuSubContent\n v-bind=\"forwarded\"\n :class=\"\n cn(\n 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </ContextMenuSubContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuSubTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronRightIcon } from '@radix-icons/vue'\nimport {\n ContextMenuSubTrigger,\n type ContextMenuSubTriggerProps,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuSubTriggerProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\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 <ContextMenuSubTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n <ChevronRightIcon class=\"ml-auto h-4 w-4\" />\n </ContextMenuSubTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ContextMenuTrigger, type ContextMenuTriggerProps, useForwardProps } from 'reka-ui'\n\nconst props = defineProps<ContextMenuTriggerProps>()\n\nconst forwardedProps = useForwardProps(props)\n</script>\n\n<template>\n <ContextMenuTrigger v-bind=\"forwardedProps\">\n <slot />\n </ContextMenuTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/index.ts",
|
|
"content": "export { default as ContextMenu } from './ContextMenu.vue'\nexport { default as ContextMenuCheckboxItem } from './ContextMenuCheckboxItem.vue'\nexport { default as ContextMenuContent } from './ContextMenuContent.vue'\nexport { default as ContextMenuGroup } from './ContextMenuGroup.vue'\nexport { default as ContextMenuItem } from './ContextMenuItem.vue'\nexport { default as ContextMenuLabel } from './ContextMenuLabel.vue'\nexport { default as ContextMenuRadioGroup } from './ContextMenuRadioGroup.vue'\nexport { default as ContextMenuRadioItem } from './ContextMenuRadioItem.vue'\nexport { default as ContextMenuSeparator } from './ContextMenuSeparator.vue'\nexport { default as ContextMenuShortcut } from './ContextMenuShortcut.vue'\nexport { default as ContextMenuSub } from './ContextMenuSub.vue'\nexport { default as ContextMenuSubContent } from './ContextMenuSubContent.vue'\nexport { default as ContextMenuSubTrigger } from './ContextMenuSubTrigger.vue'\nexport { default as ContextMenuTrigger } from './ContextMenuTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "dialog",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/dialog/Dialog.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DialogRoot, type DialogRootEmits, type DialogRootProps, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<DialogRootProps>()\nconst emits = defineEmits<DialogRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DialogRoot v-bind=\"forwarded\">\n <slot />\n </DialogRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogClose.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DialogClose, type DialogCloseProps } from 'reka-ui'\n\nconst props = defineProps<DialogCloseProps>()\n</script>\n\n<template>\n <DialogClose v-bind=\"props\">\n <slot />\n </DialogClose>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Cross2Icon } from '@radix-icons/vue'\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<DialogContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay\n class=\"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n />\n <DialogContent\n v-bind=\"forwarded\"\n :class=\"\n cn(\n 'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',\n props.class,\n )\"\n >\n <slot />\n\n <DialogClose\n class=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground\"\n >\n <Cross2Icon class=\"w-4 h-4\" />\n <span class=\"sr-only\">Close</span>\n </DialogClose>\n </DialogContent>\n </DialogPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogDescription.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DialogDescription, type DialogDescriptionProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogDescriptionProps & { 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 <DialogDescription\n v-bind=\"forwardedProps\"\n :class=\"cn('text-sm text-muted-foreground', props.class)\"\n >\n <slot />\n </DialogDescription>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: HTMLAttributes['class'] }>()\n</script>\n\n<template>\n <div\n :class=\"\n cn(\n 'flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-x-2',\n props.class,\n )\n \"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n :class=\"cn('flex flex-col gap-y-1.5 text-center sm:text-left', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogScrollContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Cross2Icon } from '@radix-icons/vue'\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<DialogContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay\n class=\"fixed inset-0 z-50 grid place-items-center overflow-y-auto bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n >\n <DialogContent\n :class=\"\n cn(\n 'relative z-50 grid w-full max-w-lg my-8 gap-4 border border-border bg-background p-6 shadow-lg duration-200 sm:rounded-lg md:w-full',\n props.class,\n )\n \"\n v-bind=\"forwarded\"\n @pointer-down-outside=\"(event) => {\n const originalEvent = event.detail.originalEvent;\n const target = originalEvent.target as HTMLElement;\n if (originalEvent.offsetX > target.clientWidth || originalEvent.offsetY > target.clientHeight) {\n event.preventDefault();\n }\n }\"\n >\n <slot />\n\n <DialogClose\n class=\"absolute top-4 right-4 p-0.5 transition-colors rounded-md hover:bg-secondary\"\n >\n <Cross2Icon class=\"w-4 h-4\" />\n <span class=\"sr-only\">Close</span>\n </DialogClose>\n </DialogContent>\n </DialogOverlay>\n </DialogPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DialogTitle, type DialogTitleProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogTitleProps & { 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 <DialogTitle\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'text-lg font-semibold leading-none tracking-tight',\n props.class,\n )\n \"\n >\n <slot />\n </DialogTitle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DialogTrigger, type DialogTriggerProps } from 'reka-ui'\n\nconst props = defineProps<DialogTriggerProps>()\n</script>\n\n<template>\n <DialogTrigger v-bind=\"props\">\n <slot />\n </DialogTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/index.ts",
|
|
"content": "export { default as Dialog } from './Dialog.vue'\nexport { default as DialogClose } from './DialogClose.vue'\nexport { default as DialogContent } from './DialogContent.vue'\nexport { default as DialogDescription } from './DialogDescription.vue'\nexport { default as DialogFooter } from './DialogFooter.vue'\nexport { default as DialogHeader } from './DialogHeader.vue'\nexport { default as DialogScrollContent } from './DialogScrollContent.vue'\nexport { default as DialogTitle } from './DialogTitle.vue'\nexport { default as DialogTrigger } from './DialogTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "drawer",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"vaul-vue",
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/drawer/Drawer.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { DrawerRootEmits, DrawerRootProps } from 'vaul-vue'\nimport { useForwardPropsEmits } from 'reka-ui'\nimport { DrawerRoot } from 'vaul-vue'\n\nconst props = withDefaults(defineProps<DrawerRootProps>(), {\n shouldScaleBackground: true,\n})\n\nconst emits = defineEmits<DrawerRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DrawerRoot v-bind=\"forwarded\">\n <slot />\n </DrawerRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/DrawerContent.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { DialogContentEmits, DialogContentProps } from 'reka-ui'\nimport type { HtmlHTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { useForwardPropsEmits } from 'reka-ui'\nimport { DrawerContent, DrawerPortal } from 'vaul-vue'\nimport DrawerOverlay from './DrawerOverlay.vue'\n\nconst props = defineProps<DialogContentProps & { class?: HtmlHTMLAttributes['class'] }>()\nconst emits = defineEmits<DialogContentEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DrawerPortal>\n <DrawerOverlay />\n <DrawerContent\n v-bind=\"forwarded\" :class=\"cn(\n 'fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background',\n props.class,\n )\"\n >\n <div class=\"mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted\" />\n <slot />\n </DrawerContent>\n </DrawerPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/DrawerDescription.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { DrawerDescriptionProps } from 'vaul-vue'\nimport { cn } from '@/lib/utils'\nimport { DrawerDescription } from 'vaul-vue'\nimport { computed, type HtmlHTMLAttributes } from 'vue'\n\nconst props = defineProps<DrawerDescriptionProps & { class?: HtmlHTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DrawerDescription v-bind=\"delegatedProps\" :class=\"cn('text-sm text-muted-foreground', props.class)\">\n <slot />\n </DrawerDescription>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/DrawerFooter.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HtmlHTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HtmlHTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('mt-auto flex flex-col gap-2 p-4', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/DrawerHeader.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HtmlHTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HtmlHTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('grid gap-1.5 p-4 text-center sm:text-left', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/DrawerOverlay.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { DialogOverlayProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { DrawerOverlay } from 'vaul-vue'\nimport { computed, type HtmlHTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogOverlayProps & { class?: HtmlHTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DrawerOverlay v-bind=\"delegatedProps\" :class=\"cn('fixed inset-0 z-50 bg-black/80', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/DrawerTitle.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { DrawerTitleProps } from 'vaul-vue'\nimport { cn } from '@/lib/utils'\nimport { DrawerTitle } from 'vaul-vue'\nimport { computed, type HtmlHTMLAttributes } from 'vue'\n\nconst props = defineProps<DrawerTitleProps & { class?: HtmlHTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DrawerTitle v-bind=\"delegatedProps\" :class=\"cn('text-lg font-semibold leading-none tracking-tight', props.class)\">\n <slot />\n </DrawerTitle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/index.ts",
|
|
"content": "export { default as Drawer } from './Drawer.vue'\nexport { default as DrawerContent } from './DrawerContent.vue'\nexport { default as DrawerDescription } from './DrawerDescription.vue'\nexport { default as DrawerFooter } from './DrawerFooter.vue'\nexport { default as DrawerHeader } from './DrawerHeader.vue'\nexport { default as DrawerOverlay } from './DrawerOverlay.vue'\nexport { default as DrawerTitle } from './DrawerTitle.vue'\nexport { DrawerClose, DrawerPortal, DrawerTrigger } from 'vaul-vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "dropdown-menu",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenu.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DropdownMenuRoot, type DropdownMenuRootEmits, type DropdownMenuRootProps, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<DropdownMenuRootProps>()\nconst emits = defineEmits<DropdownMenuRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DropdownMenuRoot v-bind=\"forwarded\">\n <slot />\n </DropdownMenuRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuCheckboxItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { CheckIcon } from '@radix-icons/vue'\nimport {\n DropdownMenuCheckboxItem,\n type DropdownMenuCheckboxItemEmits,\n type DropdownMenuCheckboxItemProps,\n DropdownMenuItemIndicator,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuCheckboxItemProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<DropdownMenuCheckboxItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DropdownMenuCheckboxItem\n v-bind=\"forwarded\"\n :class=\" cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuItemIndicator>\n <CheckIcon class=\"w-4 h-4\" />\n </DropdownMenuItemIndicator>\n </span>\n <slot />\n </DropdownMenuCheckboxItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n DropdownMenuContent,\n type DropdownMenuContentEmits,\n type DropdownMenuContentProps,\n DropdownMenuPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(\n defineProps<DropdownMenuContentProps & { class?: HTMLAttributes['class'] }>(),\n {\n sideOffset: 4,\n },\n)\nconst emits = defineEmits<DropdownMenuContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DropdownMenuPortal>\n <DropdownMenuContent\n v-bind=\"forwarded\"\n :class=\"cn('z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', props.class)\"\n >\n <slot />\n </DropdownMenuContent>\n </DropdownMenuPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DropdownMenuGroup, type DropdownMenuGroupProps } from 'reka-ui'\n\nconst props = defineProps<DropdownMenuGroupProps>()\n</script>\n\n<template>\n <DropdownMenuGroup v-bind=\"props\">\n <slot />\n </DropdownMenuGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DropdownMenuItem, type DropdownMenuItemProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuItemProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\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 <DropdownMenuItem\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm gap-2 px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n </DropdownMenuItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DropdownMenuLabel, type DropdownMenuLabelProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuLabelProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\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 <DropdownMenuLabel\n v-bind=\"forwardedProps\"\n :class=\"cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', props.class)\"\n >\n <slot />\n </DropdownMenuLabel>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuRadioGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenuRadioGroup,\n type DropdownMenuRadioGroupEmits,\n type DropdownMenuRadioGroupProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<DropdownMenuRadioGroupProps>()\nconst emits = defineEmits<DropdownMenuRadioGroupEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DropdownMenuRadioGroup v-bind=\"forwarded\">\n <slot />\n </DropdownMenuRadioGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuRadioItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DotFilledIcon } from '@radix-icons/vue'\nimport {\n DropdownMenuItemIndicator,\n DropdownMenuRadioItem,\n type DropdownMenuRadioItemEmits,\n type DropdownMenuRadioItemProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuRadioItemProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<DropdownMenuRadioItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DropdownMenuRadioItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuItemIndicator>\n <DotFilledIcon class=\"h-4 w-4 fill-current\" />\n </DropdownMenuItemIndicator>\n </span>\n <slot />\n </DropdownMenuRadioItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n DropdownMenuSeparator,\n type DropdownMenuSeparatorProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuSeparatorProps & {\n class?: HTMLAttributes['class']\n}>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DropdownMenuSeparator v-bind=\"delegatedProps\" :class=\"cn('-mx-1 my-1 h-px bg-muted', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuShortcut.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span :class=\"cn('ml-auto text-xs tracking-widest opacity-60', props.class)\">\n <slot />\n </span>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuSub.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenuSub,\n type DropdownMenuSubEmits,\n type DropdownMenuSubProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<DropdownMenuSubProps>()\nconst emits = defineEmits<DropdownMenuSubEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DropdownMenuSub v-bind=\"forwarded\">\n <slot />\n </DropdownMenuSub>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuSubContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n DropdownMenuSubContent,\n type DropdownMenuSubContentEmits,\n type DropdownMenuSubContentProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuSubContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<DropdownMenuSubContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DropdownMenuSubContent\n v-bind=\"forwarded\"\n :class=\"cn('z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', props.class)\"\n >\n <slot />\n </DropdownMenuSubContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuSubTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronRightIcon } from '@radix-icons/vue'\nimport {\n DropdownMenuSubTrigger,\n type DropdownMenuSubTriggerProps,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuSubTriggerProps & { 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 <DropdownMenuSubTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent',\n props.class,\n )\"\n >\n <slot />\n <ChevronRightIcon class=\"ml-auto h-4 w-4\" />\n </DropdownMenuSubTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DropdownMenuTrigger, type DropdownMenuTriggerProps, useForwardProps } from 'reka-ui'\n\nconst props = defineProps<DropdownMenuTriggerProps>()\n\nconst forwardedProps = useForwardProps(props)\n</script>\n\n<template>\n <DropdownMenuTrigger class=\"outline-none\" v-bind=\"forwardedProps\">\n <slot />\n </DropdownMenuTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/index.ts",
|
|
"content": "export { default as DropdownMenu } from './DropdownMenu.vue'\n\nexport { default as DropdownMenuCheckboxItem } from './DropdownMenuCheckboxItem.vue'\nexport { default as DropdownMenuContent } from './DropdownMenuContent.vue'\nexport { default as DropdownMenuGroup } from './DropdownMenuGroup.vue'\nexport { default as DropdownMenuItem } from './DropdownMenuItem.vue'\nexport { default as DropdownMenuLabel } from './DropdownMenuLabel.vue'\nexport { default as DropdownMenuRadioGroup } from './DropdownMenuRadioGroup.vue'\nexport { default as DropdownMenuRadioItem } from './DropdownMenuRadioItem.vue'\nexport { default as DropdownMenuSeparator } from './DropdownMenuSeparator.vue'\nexport { default as DropdownMenuShortcut } from './DropdownMenuShortcut.vue'\nexport { default as DropdownMenuSub } from './DropdownMenuSub.vue'\nexport { default as DropdownMenuSubContent } from './DropdownMenuSubContent.vue'\nexport { default as DropdownMenuSubTrigger } from './DropdownMenuSubTrigger.vue'\nexport { default as DropdownMenuTrigger } from './DropdownMenuTrigger.vue'\nexport { DropdownMenuPortal } from 'reka-ui'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "form",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui",
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/form/FormControl.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { Slot } from 'reka-ui'\nimport { useFormField } from './useFormField'\n\nconst { error, formItemId, formDescriptionId, formMessageId } = useFormField()\n</script>\n\n<template>\n <Slot\n :id=\"formItemId\"\n :aria-describedby=\"!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`\"\n :aria-invalid=\"!!error\"\n >\n <slot />\n </Slot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/form/FormDescription.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { useFormField } from './useFormField'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst { formDescriptionId } = useFormField()\n</script>\n\n<template>\n <p\n :id=\"formDescriptionId\"\n :class=\"cn('text-sm text-muted-foreground', props.class)\"\n >\n <slot />\n </p>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/form/FormItem.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { useId } from 'reka-ui'\nimport { type HTMLAttributes, provide } from 'vue'\nimport { FORM_ITEM_INJECTION_KEY } from './injectionKeys'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst id = useId()\nprovide(FORM_ITEM_INJECTION_KEY, id)\n</script>\n\n<template>\n <div :class=\"cn('space-y-2', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/form/FormLabel.vue",
|
|
"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/new-york/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": ""
|
|
},
|
|
{
|
|
"path": "ui/form/FormMessage.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { ErrorMessage } from 'vee-validate'\nimport { toValue } from 'vue'\nimport { useFormField } from './useFormField'\n\nconst { name, formMessageId } = useFormField()\n</script>\n\n<template>\n <ErrorMessage\n :id=\"formMessageId\"\n as=\"p\"\n :name=\"toValue(name)\"\n class=\"text-[0.8rem] font-medium text-destructive\"\n />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/form/index.ts",
|
|
"content": "export { default as FormControl } from './FormControl.vue'\nexport { default as FormDescription } from './FormDescription.vue'\nexport { default as FormItem } from './FormItem.vue'\nexport { default as FormLabel } from './FormLabel.vue'\nexport { default as FormMessage } from './FormMessage.vue'\nexport { FORM_ITEM_INJECTION_KEY } from './injectionKeys'\nexport { Field as FormField, FieldArray as FormFieldArray, Form } from 'vee-validate'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/form/injectionKeys.ts",
|
|
"content": "import type { InjectionKey } from 'vue'\n\nexport const FORM_ITEM_INJECTION_KEY\n = Symbol() as InjectionKey<string>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/form/useFormField.ts",
|
|
"content": "import { FieldContextKey, useFieldError, useIsFieldDirty, useIsFieldTouched, useIsFieldValid } from 'vee-validate'\nimport { inject } from 'vue'\nimport { FORM_ITEM_INJECTION_KEY } from './injectionKeys'\n\nexport function useFormField() {\n const fieldContext = inject(FieldContextKey)\n const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY)\n\n if (!fieldContext)\n throw new Error('useFormField should be used within <FormField>')\n\n const { name } = fieldContext\n const id = fieldItemContext\n\n const fieldState = {\n valid: useIsFieldValid(name),\n isDirty: useIsFieldDirty(name),\n isTouched: useIsFieldTouched(name),\n error: useFieldError(name),\n }\n\n return {\n id,\n name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n }\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "hover-card",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/hover-card/HoverCard.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { HoverCardRoot, type HoverCardRootEmits, type HoverCardRootProps, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<HoverCardRootProps>()\nconst emits = defineEmits<HoverCardRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <HoverCardRoot v-bind=\"forwarded\">\n <slot />\n </HoverCardRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/hover-card/HoverCardContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n HoverCardContent,\n type HoverCardContentProps,\n HoverCardPortal,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(\n defineProps<HoverCardContentProps & { class?: HTMLAttributes['class'] }>(),\n {\n sideOffset: 4,\n },\n)\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 <HoverCardPortal>\n <HoverCardContent\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </HoverCardContent>\n </HoverCardPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/hover-card/HoverCardTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { HoverCardTrigger, type HoverCardTriggerProps } from 'reka-ui'\n\nconst props = defineProps<HoverCardTriggerProps>()\n</script>\n\n<template>\n <HoverCardTrigger v-bind=\"props\">\n <slot />\n </HoverCardTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/hover-card/index.ts",
|
|
"content": "export { default as HoverCard } from './HoverCard.vue'\nexport { default as HoverCardContent } from './HoverCardContent.vue'\nexport { default as HoverCardTrigger } from './HoverCardTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "input",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/input/Input.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { useVModel } from '@vueuse/core'\n\nconst props = defineProps<{\n defaultValue?: string | number\n modelValue?: string | number\n class?: HTMLAttributes['class']\n}>()\n\nconst emits = defineEmits<{\n (e: 'update:modelValue', payload: string | number): void\n}>()\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n passive: true,\n defaultValue: props.defaultValue,\n})\n</script>\n\n<template>\n <input v-model=\"modelValue\" :class=\"cn('flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50', props.class)\">\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/input/index.ts",
|
|
"content": "export { default as Input } from './Input.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "label",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/label/Label.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Label, type LabelProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<LabelProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <Label\n v-bind=\"delegatedProps\"\n :class=\"\n cn(\n 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',\n props.class,\n )\n \"\n >\n <slot />\n </Label>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/label/index.ts",
|
|
"content": "export { default as Label } from './Label.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "menubar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/menubar/Menubar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n MenubarRoot,\n type MenubarRootEmits,\n type MenubarRootProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<MenubarRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <MenubarRoot\n v-bind=\"forwarded\"\n :class=\"\n cn(\n 'flex h-9 items-center space-x-1 rounded-md border bg-background p-1 shadow-sm',\n props.class,\n )\n \"\n >\n <slot />\n </MenubarRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarCheckboxItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { CheckIcon } from '@radix-icons/vue'\nimport {\n MenubarCheckboxItem,\n type MenubarCheckboxItemEmits,\n type MenubarCheckboxItemProps,\n MenubarItemIndicator,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarCheckboxItemProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<MenubarCheckboxItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <MenubarCheckboxItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <MenubarItemIndicator>\n <CheckIcon class=\"w-4 h-4\" />\n </MenubarItemIndicator>\n </span>\n <slot />\n </MenubarCheckboxItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n MenubarContent,\n type MenubarContentProps,\n MenubarPortal,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(\n defineProps<MenubarContentProps & { class?: HTMLAttributes['class'] }>(),\n {\n align: 'start',\n alignOffset: -4,\n sideOffset: 8,\n },\n)\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 <MenubarPortal>\n <MenubarContent\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'z-50 min-w-48 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </MenubarContent>\n </MenubarPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { MenubarGroup, type MenubarGroupProps } from 'reka-ui'\n\nconst props = defineProps<MenubarGroupProps>()\n</script>\n\n<template>\n <MenubarGroup v-bind=\"props\">\n <slot />\n </MenubarGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n MenubarItem,\n type MenubarItemEmits,\n type MenubarItemProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarItemProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\n\nconst emits = defineEmits<MenubarItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <MenubarItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n </MenubarItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { MenubarLabel, type MenubarLabelProps } from 'reka-ui'\n\nconst props = defineProps<MenubarLabelProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\n</script>\n\n<template>\n <MenubarLabel :class=\"cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', props.class)\">\n <slot />\n </MenubarLabel>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarMenu.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { MenubarMenu, type MenubarMenuProps } from 'reka-ui'\n\nconst props = defineProps<MenubarMenuProps>()\n</script>\n\n<template>\n <MenubarMenu v-bind=\"props\">\n <slot />\n </MenubarMenu>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarRadioGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n MenubarRadioGroup,\n type MenubarRadioGroupEmits,\n type MenubarRadioGroupProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<MenubarRadioGroupProps>()\n\nconst emits = defineEmits<MenubarRadioGroupEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <MenubarRadioGroup v-bind=\"forwarded\">\n <slot />\n </MenubarRadioGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarRadioItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DotFilledIcon } from '@radix-icons/vue'\nimport {\n MenubarItemIndicator,\n MenubarRadioItem,\n type MenubarRadioItemEmits,\n type MenubarRadioItemProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarRadioItemProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<MenubarRadioItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <MenubarRadioItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <MenubarItemIndicator>\n <DotFilledIcon class=\"h-4 w-4 fill-current\" />\n </MenubarItemIndicator>\n </span>\n <slot />\n </MenubarRadioItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { MenubarSeparator, type MenubarSeparatorProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarSeparatorProps & { 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 <MenubarSeparator :class=\" cn('-mx-1 my-1 h-px bg-muted', props.class)\" v-bind=\"forwardedProps\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarShortcut.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span :class=\"cn('ml-auto text-xs tracking-widest text-muted-foreground', props.class)\">\n <slot />\n </span>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarSub.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { MenubarSub, type MenubarSubEmits, useForwardPropsEmits } from 'reka-ui'\n\ninterface MenubarSubRootProps {\n defaultOpen?: boolean\n open?: boolean\n}\n\nconst props = defineProps<MenubarSubRootProps>()\nconst emits = defineEmits<MenubarSubEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <MenubarSub v-bind=\"forwarded\">\n <slot />\n </MenubarSub>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarSubContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n MenubarPortal,\n MenubarSubContent,\n type MenubarSubContentEmits,\n type MenubarSubContentProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarSubContentProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<MenubarSubContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <MenubarPortal>\n <MenubarSubContent\n v-bind=\"forwarded\"\n :class=\"\n cn(\n 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </MenubarSubContent>\n </MenubarPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarSubTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronRightIcon } from '@radix-icons/vue'\nimport { MenubarSubTrigger, type MenubarSubTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarSubTriggerProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\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 <MenubarSubTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n <ChevronRightIcon class=\"ml-auto h-4 w-4\" />\n </MenubarSubTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { MenubarTrigger, type MenubarTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarTriggerProps & { 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 <MenubarTrigger\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'flex cursor-default select-none items-center rounded-sm px-3 py-1 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',\n props.class,\n )\n \"\n >\n <slot />\n </MenubarTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/index.ts",
|
|
"content": "export { default as Menubar } from './Menubar.vue'\nexport { default as MenubarCheckboxItem } from './MenubarCheckboxItem.vue'\nexport { default as MenubarContent } from './MenubarContent.vue'\nexport { default as MenubarGroup } from './MenubarGroup.vue'\nexport { default as MenubarItem } from './MenubarItem.vue'\nexport { default as MenubarLabel } from './MenubarLabel.vue'\nexport { default as MenubarMenu } from './MenubarMenu.vue'\nexport { default as MenubarRadioGroup } from './MenubarRadioGroup.vue'\nexport { default as MenubarRadioItem } from './MenubarRadioItem.vue'\nexport { default as MenubarSeparator } from './MenubarSeparator.vue'\nexport { default as MenubarShortcut } from './MenubarShortcut.vue'\nexport { default as MenubarSub } from './MenubarSub.vue'\nexport { default as MenubarSubContent } from './MenubarSubContent.vue'\nexport { default as MenubarSubTrigger } from './MenubarSubTrigger.vue'\nexport { default as MenubarTrigger } from './MenubarTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "navigation-menu",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenu.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n NavigationMenuRoot,\n type NavigationMenuRootEmits,\n type NavigationMenuRootProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport NavigationMenuViewport from './NavigationMenuViewport.vue'\n\nconst props = defineProps<NavigationMenuRootProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<NavigationMenuRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <NavigationMenuRoot\n v-bind=\"forwarded\"\n :class=\"cn('relative z-10 flex max-w-max flex-1 items-center justify-center', props.class)\"\n >\n <slot />\n <NavigationMenuViewport />\n </NavigationMenuRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n NavigationMenuContent,\n type NavigationMenuContentEmits,\n type NavigationMenuContentProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NavigationMenuContentProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<NavigationMenuContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <NavigationMenuContent\n v-bind=\"forwarded\"\n :class=\"cn(\n 'left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto',\n props.class,\n )\"\n >\n <slot />\n </NavigationMenuContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuIndicator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { NavigationMenuIndicator, type NavigationMenuIndicatorProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NavigationMenuIndicatorProps & { 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 <NavigationMenuIndicator\n v-bind=\"forwardedProps\"\n :class=\"cn('top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in', props.class)\"\n >\n <div class=\"relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md\" />\n </NavigationMenuIndicator>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { NavigationMenuItem, type NavigationMenuItemProps } from 'reka-ui'\n\nconst props = defineProps<NavigationMenuItemProps>()\n</script>\n\n<template>\n <NavigationMenuItem v-bind=\"props\">\n <slot />\n </NavigationMenuItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuLink.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n NavigationMenuLink,\n type NavigationMenuLinkEmits,\n type NavigationMenuLinkProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<NavigationMenuLinkProps>()\nconst emits = defineEmits<NavigationMenuLinkEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <NavigationMenuLink v-bind=\"forwarded\">\n <slot />\n </NavigationMenuLink>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuList.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { NavigationMenuList, type NavigationMenuListProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NavigationMenuListProps & { 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 <NavigationMenuList\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'group flex flex-1 list-none items-center justify-center gap-x-1',\n props.class,\n )\n \"\n >\n <slot />\n </NavigationMenuList>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronDownIcon } from '@radix-icons/vue'\nimport {\n NavigationMenuTrigger,\n type NavigationMenuTriggerProps,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { navigationMenuTriggerStyle } from '.'\n\nconst props = defineProps<NavigationMenuTriggerProps & { 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 <NavigationMenuTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(navigationMenuTriggerStyle(), 'group', props.class)\"\n >\n <slot />\n <ChevronDownIcon\n class=\"relative top-px ml-1 h-3 w-3 transition duration-300 group-data-[state=open]:rotate-180\"\n aria-hidden=\"true\"\n />\n </NavigationMenuTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuViewport.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n NavigationMenuViewport,\n type NavigationMenuViewportProps,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NavigationMenuViewportProps & { 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 <div class=\"absolute left-0 top-full flex justify-center\">\n <NavigationMenuViewport\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'origin-top-center relative mt-1.5 h-[--reka-navigation-menu-viewport-height] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[--reka-navigation-menu-viewport-width]',\n props.class,\n )\n \"\n />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/index.ts",
|
|
"content": "import { cva } from 'class-variance-authority'\n\nexport { default as NavigationMenu } from './NavigationMenu.vue'\nexport { default as NavigationMenuContent } from './NavigationMenuContent.vue'\nexport { default as NavigationMenuItem } from './NavigationMenuItem.vue'\nexport { default as NavigationMenuLink } from './NavigationMenuLink.vue'\nexport { default as NavigationMenuList } from './NavigationMenuList.vue'\nexport { default as NavigationMenuTrigger } from './NavigationMenuTrigger.vue'\nexport { default as NavigationMenuViewport } from './NavigationMenuViewport.vue'\n\nexport const navigationMenuTriggerStyle = cva(\n 'group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50',\n)\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "number-field",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/number-field/NumberField.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { NumberFieldRootEmits, NumberFieldRootProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { NumberFieldRoot, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NumberFieldRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<NumberFieldRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <NumberFieldRoot v-bind=\"forwarded\" :class=\"cn('grid gap-1.5', props.class)\">\n <slot />\n </NumberFieldRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/number-field/NumberFieldContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('relative [&>[data-slot=input]]:has-[[data-slot=increment]]:pr-5 [&>[data-slot=input]]:has-[[data-slot=decrement]]:pl-5', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/number-field/NumberFieldDecrement.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { NumberFieldDecrementProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { Minus } from 'lucide-vue-next'\nimport { NumberFieldDecrement, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NumberFieldDecrementProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <NumberFieldDecrement data-slot=\"decrement\" v-bind=\"forwarded\" :class=\"cn('absolute top-1/2 -translate-y-1/2 left-0 p-3 disabled:cursor-not-allowed disabled:opacity-20', props.class)\">\n <slot>\n <Minus class=\"h-4 w-4\" />\n </slot>\n </NumberFieldDecrement>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/number-field/NumberFieldIncrement.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { NumberFieldIncrementProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { Plus } from 'lucide-vue-next'\nimport { NumberFieldIncrement, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NumberFieldIncrementProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <NumberFieldIncrement data-slot=\"increment\" v-bind=\"forwarded\" :class=\"cn('absolute top-1/2 -translate-y-1/2 right-0 disabled:cursor-not-allowed disabled:opacity-20 p-3', props.class)\">\n <slot>\n <Plus class=\"h-4 w-4\" />\n </slot>\n </NumberFieldIncrement>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/number-field/NumberFieldInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { NumberFieldInput } from 'reka-ui'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <NumberFieldInput\n data-slot=\"input\"\n :class=\"cn('flex h-9 w-full rounded-md border border-input bg-transparent py-1 text-sm text-center shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50', props.class)\"\n />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/number-field/index.ts",
|
|
"content": "export { default as NumberField } from './NumberField.vue'\nexport { default as NumberFieldContent } from './NumberFieldContent.vue'\nexport { default as NumberFieldDecrement } from './NumberFieldDecrement.vue'\nexport { default as NumberFieldIncrement } from './NumberFieldIncrement.vue'\nexport { default as NumberFieldInput } from './NumberFieldInput.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "pagination",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/pagination/PaginationEllipsis.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DotsHorizontalIcon } from '@radix-icons/vue'\nimport { PaginationEllipsis, type PaginationEllipsisProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<PaginationEllipsisProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <PaginationEllipsis v-bind=\"delegatedProps\" :class=\"cn('w-9 h-9 flex items-center justify-center', props.class)\">\n <slot>\n <DotsHorizontalIcon />\n </slot>\n </PaginationEllipsis>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pagination/PaginationFirst.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n Button,\n} from '@/registry/new-york/ui/button'\nimport { DoubleArrowLeftIcon } from '@radix-icons/vue'\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-9 h-9 p-0', props.class)\" variant=\"outline\">\n <slot>\n <DoubleArrowLeftIcon />\n </slot>\n </Button>\n </PaginationFirst>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pagination/PaginationLast.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n Button,\n} from '@/registry/new-york/ui/button'\nimport { DoubleArrowRightIcon } from '@radix-icons/vue'\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-9 h-9 p-0', props.class)\" variant=\"outline\">\n <slot>\n <DoubleArrowRightIcon />\n </slot>\n </Button>\n </PaginationLast>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pagination/PaginationNext.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n Button,\n} from '@/registry/new-york/ui/button'\nimport { ChevronRightIcon } from '@radix-icons/vue'\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-9 h-9 p-0', props.class)\" variant=\"outline\">\n <slot>\n <ChevronRightIcon />\n </slot>\n </Button>\n </PaginationNext>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pagination/PaginationPrev.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n Button,\n} from '@/registry/new-york/ui/button'\nimport { ChevronLeftIcon } from '@radix-icons/vue'\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-9 h-9 p-0', props.class)\" variant=\"outline\">\n <slot>\n <ChevronLeftIcon />\n </slot>\n </Button>\n </PaginationPrev>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pagination/index.ts",
|
|
"content": "export { default as PaginationEllipsis } from './PaginationEllipsis.vue'\nexport { default as PaginationFirst } from './PaginationFirst.vue'\nexport { default as PaginationLast } from './PaginationLast.vue'\nexport { default as PaginationNext } from './PaginationNext.vue'\nexport { default as PaginationPrev } from './PaginationPrev.vue'\nexport {\n PaginationList,\n PaginationListItem,\n PaginationRoot as Pagination,\n} from 'reka-ui'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "pin-input",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/pin-input/PinInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { PinInputRoot, type PinInputRootEmits, type PinInputRootProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<PinInputRootProps & { class?: HTMLAttributes['class'] }>(), {\n modelValue: () => [],\n})\nconst emits = defineEmits<PinInputRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <PinInputRoot v-bind=\"forwarded\" :class=\"cn('flex gap-2 items-center', props.class)\">\n <slot />\n </PinInputRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pin-input/PinInputGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<PrimitiveProps & { class?: HTMLAttributes['class'] }>()\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <Primitive v-bind=\"forwardedProps\" :class=\"cn('flex items-center', props.class)\">\n <slot />\n </primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pin-input/PinInputInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { PinInputInput, type PinInputInputProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<PinInputInputProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <PinInputInput v-bind=\"forwardedProps\" :class=\"cn('relative text-center focus:outline-none focus:ring-2 focus:ring-ring focus:relative focus:z-10 flex h-9 w-9 items-center justify-center border-y border-r border-input text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pin-input/PinInputSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DashIcon } from '@radix-icons/vue'\nimport { Primitive, type PrimitiveProps, useForwardProps } from 'reka-ui'\n\nconst props = defineProps<PrimitiveProps>()\nconst forwardedProps = useForwardProps(props)\n</script>\n\n<template>\n <Primitive v-bind=\"forwardedProps\">\n <slot>\n <DashIcon />\n </slot>\n </primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pin-input/index.ts",
|
|
"content": "export { default as PinInput } from './PinInput.vue'\nexport { default as PinInputGroup } from './PinInputGroup.vue'\nexport { default as PinInputInput } from './PinInputInput.vue'\nexport { default as PinInputSeparator } from './PinInputSeparator.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "popover",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/popover/Popover.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { PopoverRootEmits, PopoverRootProps } from 'reka-ui'\nimport { PopoverRoot, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<PopoverRootProps>()\nconst emits = defineEmits<PopoverRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <PopoverRoot v-bind=\"forwarded\">\n <slot />\n </PopoverRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/popover/PopoverContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n PopoverContent,\n type PopoverContentEmits,\n type PopoverContentProps,\n PopoverPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(\n defineProps<PopoverContentProps & { class?: HTMLAttributes['class'] }>(),\n {\n align: 'center',\n sideOffset: 4,\n },\n)\nconst emits = defineEmits<PopoverContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <PopoverPortal>\n <PopoverContent\n v-bind=\"{ ...forwarded, ...$attrs }\"\n :class=\"\n cn(\n 'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </PopoverContent>\n </PopoverPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/popover/PopoverTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { PopoverTrigger, type PopoverTriggerProps } from 'reka-ui'\n\nconst props = defineProps<PopoverTriggerProps>()\n</script>\n\n<template>\n <PopoverTrigger v-bind=\"props\">\n <slot />\n </PopoverTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/popover/index.ts",
|
|
"content": "export { default as Popover } from './Popover.vue'\nexport { default as PopoverContent } from './PopoverContent.vue'\nexport { default as PopoverTrigger } from './PopoverTrigger.vue'\nexport { PopoverAnchor } from 'reka-ui'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "progress",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/progress/Progress.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n ProgressIndicator,\n ProgressRoot,\n type ProgressRootProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(\n defineProps<ProgressRootProps & { class?: HTMLAttributes['class'] }>(),\n {\n modelValue: 0,\n },\n)\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ProgressRoot\n v-bind=\"delegatedProps\"\n :class=\"\n cn(\n 'relative h-2 w-full overflow-hidden rounded-full bg-primary/20',\n props.class,\n )\n \"\n >\n <ProgressIndicator\n class=\"h-full w-full flex-1 bg-primary transition-all\"\n :style=\"`transform: translateX(-${100 - (props.modelValue ?? 0)}%);`\"\n />\n </ProgressRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/progress/index.ts",
|
|
"content": "export { default as Progress } from './Progress.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "radio-group",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/radio-group/RadioGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { RadioGroupRoot, type RadioGroupRootEmits, type RadioGroupRootProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RadioGroupRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<RadioGroupRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <RadioGroupRoot\n :class=\"cn('grid gap-2', props.class)\"\n v-bind=\"forwarded\"\n >\n <slot />\n </RadioGroupRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/radio-group/RadioGroupItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { CheckIcon } from '@radix-icons/vue'\nimport {\n RadioGroupIndicator,\n RadioGroupItem,\n type RadioGroupItemProps,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RadioGroupItemProps & { 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 <RadioGroupItem\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'aspect-square h-4 w-4 rounded-full border border-primary text-primary shadow focus:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n props.class,\n )\n \"\n >\n <RadioGroupIndicator class=\"flex items-center justify-center\">\n <CheckIcon class=\"h-3.5 w-3.5 fill-primary\" />\n </RadioGroupIndicator>\n </RadioGroupItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/radio-group/index.ts",
|
|
"content": "export { default as RadioGroup } from './RadioGroup.vue'\nexport { default as RadioGroupItem } from './RadioGroupItem.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "range-calendar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendar.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarRoot, type RangeCalendarRootEmits, type RangeCalendarRootProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { RangeCalendarCell, RangeCalendarCellTrigger, RangeCalendarGrid, RangeCalendarGridBody, RangeCalendarGridHead, RangeCalendarGridRow, RangeCalendarHeadCell, RangeCalendarHeader, RangeCalendarHeading, RangeCalendarNextButton, RangeCalendarPrevButton } from '.'\n\nconst props = defineProps<RangeCalendarRootProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<RangeCalendarRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <RangeCalendarRoot\n v-slot=\"{ grid, weekDays }\"\n :class=\"cn('p-3', props.class)\"\n v-bind=\"forwarded\"\n >\n <RangeCalendarHeader>\n <RangeCalendarPrevButton />\n <RangeCalendarHeading />\n <RangeCalendarNextButton />\n </RangeCalendarHeader>\n\n <div class=\"flex flex-col gap-y-4 mt-4 sm:flex-row sm:gap-x-4 sm:gap-y-0\">\n <RangeCalendarGrid v-for=\"month in grid\" :key=\"month.value.toString()\">\n <RangeCalendarGridHead>\n <RangeCalendarGridRow>\n <RangeCalendarHeadCell\n v-for=\"day in weekDays\" :key=\"day\"\n >\n {{ day }}\n </RangeCalendarHeadCell>\n </RangeCalendarGridRow>\n </RangeCalendarGridHead>\n <RangeCalendarGridBody>\n <RangeCalendarGridRow v-for=\"(weekDates, index) in month.rows\" :key=\"`weekDate-${index}`\" class=\"mt-2 w-full\">\n <RangeCalendarCell\n v-for=\"weekDate in weekDates\"\n :key=\"weekDate.toString()\"\n :date=\"weekDate\"\n >\n <RangeCalendarCellTrigger\n :day=\"weekDate\"\n :month=\"month.value\"\n />\n </RangeCalendarCell>\n </RangeCalendarGridRow>\n </RangeCalendarGridBody>\n </RangeCalendarGrid>\n </div>\n </RangeCalendarRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarCell.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarCell, type RangeCalendarCellProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarCellProps & { 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 <RangeCalendarCell\n :class=\"cn('relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([data-selected])]:bg-accent first:[&:has([data-selected])]:rounded-l-md last:[&:has([data-selected])]:rounded-r-md [&:has([data-selected][data-outside-view])]:bg-accent/50 [&:has([data-selected][data-selection-end])]:rounded-r-md [&:has([data-selected][data-selection-start])]:rounded-l-md', props.class)\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </RangeCalendarCell>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarCellTrigger.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/new-york/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-8 w-8 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]]: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": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarGrid.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarGrid, type RangeCalendarGridProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarGridProps & { 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 <RangeCalendarGrid\n :class=\"cn('w-full border-collapse space-y-1', props.class)\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </RangeCalendarGrid>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarGridBody.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { RangeCalendarGridBody, type RangeCalendarGridBodyProps } from 'reka-ui'\n\nconst props = defineProps<RangeCalendarGridBodyProps>()\n</script>\n\n<template>\n <RangeCalendarGridBody v-bind=\"props\">\n <slot />\n </RangeCalendarGridBody>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarGridHead.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { RangeCalendarGridHead, type RangeCalendarGridHeadProps } from 'reka-ui'\n\nconst props = defineProps<RangeCalendarGridHeadProps>()\n</script>\n\n<template>\n <RangeCalendarGridHead v-bind=\"props\">\n <slot />\n </RangeCalendarGridHead>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarGridRow.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarGridRow, type RangeCalendarGridRowProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarGridRowProps & { 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 <RangeCalendarGridRow :class=\"cn('flex', props.class)\" v-bind=\"forwardedProps\">\n <slot />\n </RangeCalendarGridRow>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarHeadCell.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarHeadCell, type RangeCalendarHeadCellProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarHeadCellProps & { 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 <RangeCalendarHeadCell\n :class=\"cn('w-8 rounded-md text-[0.8rem] font-normal text-muted-foreground', props.class)\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </RangeCalendarHeadCell>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarHeader.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarHeader, type RangeCalendarHeaderProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarHeaderProps & { 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 <RangeCalendarHeader :class=\"cn('relative flex w-full items-center justify-between pt-1', props.class)\" v-bind=\"forwardedProps\">\n <slot />\n </RangeCalendarHeader>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarHeading.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarHeading, type RangeCalendarHeadingProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarHeadingProps & { 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 <RangeCalendarHeading\n v-slot=\"{ headingValue }\"\n :class=\"cn('text-sm font-medium', props.class)\"\n v-bind=\"forwardedProps\"\n >\n <slot :heading-value>\n {{ headingValue }}\n </slot>\n </RangeCalendarHeading>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarNextButton.vue",
|
|
"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 { 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 <ChevronRightIcon class=\"h-4 w-4\" />\n </slot>\n </RangeCalendarNext>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarPrevButton.vue",
|
|
"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 { 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 <ChevronLeftIcon class=\"h-4 w-4\" />\n </slot>\n </RangeCalendarPrev>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/index.ts",
|
|
"content": "export { default as RangeCalendar } from './RangeCalendar.vue'\nexport { default as RangeCalendarCell } from './RangeCalendarCell.vue'\nexport { default as RangeCalendarCellTrigger } from './RangeCalendarCellTrigger.vue'\nexport { default as RangeCalendarGrid } from './RangeCalendarGrid.vue'\nexport { default as RangeCalendarGridBody } from './RangeCalendarGridBody.vue'\nexport { default as RangeCalendarGridHead } from './RangeCalendarGridHead.vue'\nexport { default as RangeCalendarGridRow } from './RangeCalendarGridRow.vue'\nexport { default as RangeCalendarHeadCell } from './RangeCalendarHeadCell.vue'\nexport { default as RangeCalendarHeader } from './RangeCalendarHeader.vue'\nexport { default as RangeCalendarHeading } from './RangeCalendarHeading.vue'\nexport { default as RangeCalendarNextButton } from './RangeCalendarNextButton.vue'\nexport { default as RangeCalendarPrevButton } from './RangeCalendarPrevButton.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "resizable",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/resizable/ResizableHandle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DragHandleDots2Icon } from '@radix-icons/vue'\nimport { SplitterResizeHandle, type SplitterResizeHandleEmits, type SplitterResizeHandleProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SplitterResizeHandleProps & { class?: HTMLAttributes['class'], withHandle?: boolean }>()\nconst emits = defineEmits<SplitterResizeHandleEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SplitterResizeHandle v-bind=\"forwarded\" :class=\"cn('relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 [&[data-orientation=vertical]]:h-px [&[data-orientation=vertical]]:w-full [&[data-orientation=vertical]]:after:left-0 [&[data-orientation=vertical]]:after:h-1 [&[data-orientation=vertical]]:after:w-full [&[data-orientation=vertical]]:after:-translate-y-1/2 [&[data-orientation=vertical]]:after:translate-x-0 [&[data-orientation=vertical]>div]:rotate-90', props.class)\">\n <template v-if=\"props.withHandle\">\n <div class=\"z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border\">\n <DragHandleDots2Icon class=\"h-2.5 w-2.5\" />\n </div>\n </template>\n </SplitterResizeHandle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/resizable/ResizablePanelGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { SplitterGroup, type SplitterGroupEmits, type SplitterGroupProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SplitterGroupProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<SplitterGroupEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SplitterGroup v-bind=\"forwarded\" :class=\"cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', props.class)\">\n <slot />\n </SplitterGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/resizable/index.ts",
|
|
"content": "export { default as ResizableHandle } from './ResizableHandle.vue'\nexport { default as ResizablePanelGroup } from './ResizablePanelGroup.vue'\nexport { SplitterPanel as ResizablePanel } from 'reka-ui'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "scroll-area",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/scroll-area/ScrollArea.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n ScrollAreaCorner,\n ScrollAreaRoot,\n type ScrollAreaRootProps,\n ScrollAreaViewport,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport ScrollBar from './ScrollBar.vue'\n\nconst props = defineProps<ScrollAreaRootProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ScrollAreaRoot v-bind=\"delegatedProps\" :class=\"cn('relative overflow-hidden', props.class)\">\n <ScrollAreaViewport class=\"h-full w-full rounded-[inherit]\">\n <slot />\n </ScrollAreaViewport>\n <ScrollBar />\n <ScrollAreaCorner />\n </ScrollAreaRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/scroll-area/ScrollBar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ScrollAreaScrollbar, type ScrollAreaScrollbarProps, ScrollAreaThumb } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<ScrollAreaScrollbarProps & { class?: HTMLAttributes['class'] }>(), {\n orientation: 'vertical',\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ScrollAreaScrollbar\n v-bind=\"delegatedProps\"\n :class=\"\n cn('flex touch-none select-none transition-colors',\n orientation === 'vertical'\n && 'h-full w-2.5 border-l border-l-transparent p-px',\n orientation === 'horizontal'\n && 'h-2.5 flex-col border-t border-t-transparent p-px',\n props.class)\"\n >\n <ScrollAreaThumb class=\"relative flex-1 rounded-full bg-border\" />\n </ScrollAreaScrollbar>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/scroll-area/index.ts",
|
|
"content": "export { default as ScrollArea } from './ScrollArea.vue'\nexport { default as ScrollBar } from './ScrollBar.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "select",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/select/Select.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { SelectRootEmits, SelectRootProps } from 'reka-ui'\nimport { SelectRoot, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<SelectRootProps>()\nconst emits = defineEmits<SelectRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <SelectRoot v-bind=\"forwarded\">\n <slot />\n </SelectRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n SelectContent,\n type SelectContentEmits,\n type SelectContentProps,\n SelectPortal,\n SelectViewport,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { SelectScrollDownButton, SelectScrollUpButton } from '.'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(\n defineProps<SelectContentProps & { class?: HTMLAttributes['class'] }>(),\n {\n position: 'popper',\n },\n)\nconst emits = defineEmits<SelectContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SelectPortal>\n <SelectContent\n v-bind=\"{ ...forwarded, ...$attrs }\" :class=\"cn(\n 'relative z-50 max-h-96 min-w-32 overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n position === 'popper'\n && 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',\n props.class,\n )\n \"\n >\n <SelectScrollUpButton />\n <SelectViewport :class=\"cn('p-1', position === 'popper' && 'h-[--reka-select-trigger-height] w-full min-w-[--reka-select-trigger-width]')\">\n <slot />\n </SelectViewport>\n <SelectScrollDownButton />\n </SelectContent>\n </SelectPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { SelectGroup, type SelectGroupProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SelectGroupProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <SelectGroup :class=\"cn('p-1 w-full', props.class)\" v-bind=\"delegatedProps\">\n <slot />\n </SelectGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { CheckIcon } from '@radix-icons/vue'\nimport {\n SelectItem,\n SelectItemIndicator,\n type SelectItemProps,\n SelectItemText,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SelectItemProps & { 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 <SelectItem\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\n \"\n >\n <span class=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectItemIndicator>\n <CheckIcon class=\"h-4 w-4\" />\n </SelectItemIndicator>\n </span>\n\n <SelectItemText>\n <slot />\n </SelectItemText>\n </SelectItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectItemText.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { SelectItemText, type SelectItemTextProps } from 'reka-ui'\n\nconst props = defineProps<SelectItemTextProps>()\n</script>\n\n<template>\n <SelectItemText v-bind=\"props\">\n <slot />\n </SelectItemText>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { SelectLabel, type SelectLabelProps } from 'reka-ui'\n\nconst props = defineProps<SelectLabelProps & { class?: HTMLAttributes['class'] }>()\n</script>\n\n<template>\n <SelectLabel :class=\"cn('px-2 py-1.5 text-sm font-semibold', props.class)\">\n <slot />\n </SelectLabel>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectScrollDownButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronDownIcon } from '@radix-icons/vue'\nimport { SelectScrollDownButton, type SelectScrollDownButtonProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SelectScrollDownButtonProps & { 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 <SelectScrollDownButton v-bind=\"forwardedProps\" :class=\"cn('flex cursor-default items-center justify-center py-1', props.class)\">\n <slot>\n <ChevronDownIcon />\n </slot>\n </SelectScrollDownButton>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectScrollUpButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronUpIcon } from '@radix-icons/vue'\nimport { SelectScrollUpButton, type SelectScrollUpButtonProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SelectScrollUpButtonProps & { 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 <SelectScrollUpButton v-bind=\"forwardedProps\" :class=\"cn('flex cursor-default items-center justify-center py-1', props.class)\">\n <slot>\n <ChevronUpIcon />\n </slot>\n </SelectScrollUpButton>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { SelectSeparator, type SelectSeparatorProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SelectSeparatorProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <SelectSeparator v-bind=\"delegatedProps\" :class=\"cn('-mx-1 my-1 h-px bg-muted', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { CaretSortIcon } from '@radix-icons/vue'\nimport { SelectIcon, SelectTrigger, type SelectTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SelectTriggerProps & { 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 <SelectTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:truncate text-start',\n props.class,\n )\"\n >\n <slot />\n <SelectIcon as-child>\n <CaretSortIcon class=\"w-4 h-4 opacity-50 shrink-0\" />\n </SelectIcon>\n </SelectTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectValue.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { SelectValue, type SelectValueProps } from 'reka-ui'\n\nconst props = defineProps<SelectValueProps>()\n</script>\n\n<template>\n <SelectValue v-bind=\"props\">\n <slot />\n </SelectValue>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/index.ts",
|
|
"content": "export { default as Select } from './Select.vue'\nexport { default as SelectContent } from './SelectContent.vue'\nexport { default as SelectGroup } from './SelectGroup.vue'\nexport { default as SelectItem } from './SelectItem.vue'\nexport { default as SelectItemText } from './SelectItemText.vue'\nexport { default as SelectLabel } from './SelectLabel.vue'\nexport { default as SelectScrollDownButton } from './SelectScrollDownButton.vue'\nexport { default as SelectScrollUpButton } from './SelectScrollUpButton.vue'\nexport { default as SelectSeparator } from './SelectSeparator.vue'\nexport { default as SelectTrigger } from './SelectTrigger.vue'\nexport { default as SelectValue } from './SelectValue.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "separator",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/separator/Separator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Separator, type SeparatorProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<\n SeparatorProps & { class?: HTMLAttributes['class'], label?: string }\n>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <Separator\n v-bind=\"delegatedProps\"\n :class=\"\n cn(\n 'shrink-0 bg-border relative',\n props.orientation === 'vertical' ? 'w-px h-full' : 'h-px w-full',\n props.class,\n )\n \"\n >\n <span\n v-if=\"props.label\"\n :class=\"\n cn(\n 'text-xs text-muted-foreground bg-background absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex justify-center items-center',\n props.orientation === 'vertical' ? 'w-[1px] px-1 py-2' : 'h-[1px] py-1 px-2',\n )\n \"\n >{{ props.label }}</span>\n </Separator>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/separator/index.ts",
|
|
"content": "export { default as Separator } from './Separator.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "sheet",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/sheet/Sheet.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DialogRoot, type DialogRootEmits, type DialogRootProps, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<DialogRootProps>()\nconst emits = defineEmits<DialogRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DialogRoot v-bind=\"forwarded\">\n <slot />\n </DialogRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetClose.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DialogClose, type DialogCloseProps } from 'reka-ui'\n\nconst props = defineProps<DialogCloseProps>()\n</script>\n\n<template>\n <DialogClose v-bind=\"props\">\n <slot />\n </DialogClose>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Cross2Icon } from '@radix-icons/vue'\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { type SheetVariants, sheetVariants } from '.'\n\ninterface SheetContentProps extends DialogContentProps {\n class?: HTMLAttributes['class']\n side?: SheetVariants['side']\n}\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = defineProps<SheetContentProps>()\n\nconst emits = defineEmits<DialogContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, side, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay\n class=\"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n />\n <DialogContent\n :class=\"cn(sheetVariants({ side }), props.class)\"\n v-bind=\"{ ...forwarded, ...$attrs }\"\n >\n <slot />\n\n <DialogClose\n class=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary\"\n >\n <Cross2Icon class=\"w-4 h-4\" />\n </DialogClose>\n </DialogContent>\n </DialogPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetDescription.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DialogDescription, type DialogDescriptionProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DialogDescription\n :class=\"cn('text-sm text-muted-foreground', props.class)\"\n v-bind=\"delegatedProps\"\n >\n <slot />\n </DialogDescription>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: HTMLAttributes['class'] }>()\n</script>\n\n<template>\n <div\n :class=\"\n cn(\n 'flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-x-2',\n props.class,\n )\n \"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: HTMLAttributes['class'] }>()\n</script>\n\n<template>\n <div\n :class=\"\n cn('flex flex-col gap-y-2 text-center sm:text-left', props.class)\n \"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DialogTitle, type DialogTitleProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogTitleProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DialogTitle\n :class=\"cn('text-lg font-semibold text-foreground', props.class)\"\n v-bind=\"delegatedProps\"\n >\n <slot />\n </DialogTitle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DialogTrigger, type DialogTriggerProps } from 'reka-ui'\n\nconst props = defineProps<DialogTriggerProps>()\n</script>\n\n<template>\n <DialogTrigger v-bind=\"props\">\n <slot />\n </DialogTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/index.ts",
|
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Sheet } from './Sheet.vue'\nexport { default as SheetClose } from './SheetClose.vue'\nexport { default as SheetContent } from './SheetContent.vue'\nexport { default as SheetDescription } from './SheetDescription.vue'\nexport { default as SheetFooter } from './SheetFooter.vue'\nexport { default as SheetHeader } from './SheetHeader.vue'\nexport { default as SheetTitle } from './SheetTitle.vue'\nexport { default as SheetTrigger } from './SheetTrigger.vue'\n\nexport const sheetVariants = cva(\n 'fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500',\n {\n variants: {\n side: {\n top: 'inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',\n bottom:\n 'inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',\n left: 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm',\n right:\n 'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm',\n },\n },\n defaultVariants: {\n side: 'right',\n },\n },\n)\n\nexport type SheetVariants = VariantProps<typeof sheetVariants>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "sidebar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui",
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"sheet",
|
|
"input",
|
|
"tooltip",
|
|
"skeleton",
|
|
"separator",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/sidebar/Sidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { SidebarProps } from '.'\nimport { cn } from '@/lib/utils'\nimport { Sheet, SheetContent } from '@/registry/new-york/ui/sheet'\nimport { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<SidebarProps>(), {\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": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"content\"\n :class=\"cn('flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"footer\"\n :class=\"cn('flex flex-col gap-2 p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"group\"\n :class=\"cn('relative flex w-full min-w-0 flex-col p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarGroupAction.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive } from 'reka-ui'\n\nconst props = defineProps<PrimitiveProps & {\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"group-action\"\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn(\n 'absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 after:md:hidden',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarGroupContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"group-content\"\n :class=\"cn('w-full text-sm', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarGroupLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive } from 'reka-ui'\n\nconst props = defineProps<PrimitiveProps & {\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"group-label\"\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn(\n 'duration-200 flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',\n props.class)\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"header\"\n :class=\"cn('flex flex-col gap-2 p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Input } from '@/registry/new-york/ui/input'\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": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarInset.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <main\n :class=\"cn(\n 'relative flex min-h-svh flex-1 flex-col bg-background',\n 'peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow',\n props.class,\n )\"\n >\n <slot />\n </main>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenu.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <ul\n data-sidebar=\"menu\"\n :class=\"cn('flex w-full min-w-0 flex-col gap-1', props.class)\"\n >\n <slot />\n </ul>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuAction.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps } from 'reka-ui'\n\nconst props = withDefaults(defineProps<PrimitiveProps & {\n showOnHover?: boolean\n class?: HTMLAttributes['class']\n}>(), {\n as: 'button',\n})\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"menu-action\"\n :class=\"cn(\n 'absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 after:md:hidden',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n showOnHover\n && 'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0',\n props.class,\n )\"\n :as=\"as\"\n :as-child=\"asChild\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuBadge.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"menu-badge\"\n :class=\"cn(\n 'absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground select-none pointer-events-none',\n 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/registry/new-york/ui/tooltip'\nimport { type Component, computed } from 'vue'\nimport SidebarMenuButtonChild, { type SidebarMenuButtonProps } from './SidebarMenuButtonChild.vue'\nimport { useSidebar } from './utils'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<SidebarMenuButtonProps & {\n tooltip?: string | Component\n}>(), {\n as: 'button',\n variant: 'default',\n size: 'default',\n})\n\nconst { isMobile, state } = useSidebar()\n\nconst delegatedProps = computed(() => {\n const { tooltip, ...delegated } = props\n return delegated\n})\n</script>\n\n<template>\n <SidebarMenuButtonChild v-if=\"!tooltip\" v-bind=\"{ ...delegatedProps, ...$attrs }\">\n <slot />\n </SidebarMenuButtonChild>\n\n <Tooltip v-else>\n <TooltipTrigger as-child>\n <SidebarMenuButtonChild v-bind=\"{ ...delegatedProps, ...$attrs }\">\n <slot />\n </SidebarMenuButtonChild>\n </TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n :hidden=\"state !== 'collapsed' || isMobile\"\n >\n <template v-if=\"typeof tooltip === 'string'\">\n {{ tooltip }}\n </template>\n <component :is=\"tooltip\" v-else />\n </TooltipContent>\n </Tooltip>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuButtonChild.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps } from 'reka-ui'\nimport { type SidebarMenuButtonVariants, sidebarMenuButtonVariants } from '.'\n\nexport interface SidebarMenuButtonProps extends PrimitiveProps {\n variant?: SidebarMenuButtonVariants['variant']\n size?: SidebarMenuButtonVariants['size']\n isActive?: boolean\n class?: HTMLAttributes['class']\n}\n\nconst props = withDefaults(defineProps<SidebarMenuButtonProps>(), {\n as: 'button',\n variant: 'default',\n size: 'default',\n})\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"menu-button\"\n :data-size=\"size\"\n :data-active=\"isActive\"\n :class=\"cn(sidebarMenuButtonVariants({ variant, size }), props.class)\"\n :as=\"as\"\n :as-child=\"asChild\"\n v-bind=\"$attrs\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n data-sidebar=\"menu-item\"\n :class=\"cn('group/menu-item relative', props.class)\"\n >\n <slot />\n </li>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuSkeleton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Skeleton } from '@/registry/new-york/ui/skeleton'\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": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuSub.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <ul\n data-sidebar=\"menu-badge\"\n :class=\"cn(\n 'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </ul>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuSubButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive } from 'reka-ui'\n\nconst props = withDefaults(defineProps<PrimitiveProps & {\n size?: 'sm' | 'md'\n isActive?: boolean\n class?: HTMLAttributes['class']\n}>(), {\n as: 'a',\n size: 'md',\n})\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"menu-sub-button\"\n :as=\"as\"\n :as-child=\"asChild\"\n :data-size=\"size\"\n :data-active=\"isActive\"\n :class=\"cn(\n 'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',\n 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuSubItem.vue",
|
|
"content": "<script setup lang=\"ts\">\n</script>\n\n<template>\n <li>\n <slot />\n </li>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarProvider.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { useEventListener, useMediaQuery, useVModel } from '@vueuse/core'\nimport { TooltipProvider } from 'reka-ui'\nimport { computed, type HTMLAttributes, type Ref, ref } from 'vue'\nimport { provideSidebarContext, SIDEBAR_COOKIE_MAX_AGE, SIDEBAR_COOKIE_NAME, SIDEBAR_KEYBOARD_SHORTCUT, SIDEBAR_WIDTH, SIDEBAR_WIDTH_ICON } from './utils'\n\nconst props = withDefaults(defineProps<{\n defaultOpen?: boolean\n open?: boolean\n class?: HTMLAttributes['class']\n}>(), {\n defaultOpen: true,\n open: undefined,\n})\n\nconst emits = defineEmits<{\n 'update:open': [open: boolean]\n}>()\n\nconst isMobile = useMediaQuery('(max-width: 768px)')\nconst openMobile = ref(false)\n\nconst open = useVModel(props, 'open', emits, {\n defaultValue: props.defaultOpen ?? false,\n passive: (props.open === undefined) as false,\n}) as Ref<boolean>\n\nfunction setOpen(value: boolean) {\n open.value = value // emits('update:open', value)\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${open.value}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n}\n\nfunction setOpenMobile(value: boolean) {\n openMobile.value = value\n}\n\n// Helper to toggle the sidebar.\nfunction toggleSidebar() {\n return isMobile.value ? setOpenMobile(!openMobile.value) : setOpen(!open.value)\n}\n\nuseEventListener('keydown', (event: KeyboardEvent) => {\n if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n toggleSidebar()\n }\n})\n\n// We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n// This makes it easier to style the sidebar with Tailwind classes.\nconst state = computed(() => open.value ? 'expanded' : 'collapsed')\n\nprovideSidebarContext({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n})\n</script>\n\n<template>\n <TooltipProvider :delay-duration=\"0\">\n <div\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH,\n '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,\n }\"\n :class=\"cn('group/sidebar-wrapper flex min-h-svh w-full text-sidebar-foreground has-[[data-variant=inset]]:bg-sidebar', props.class)\"\n v-bind=\"$attrs\"\n >\n <slot />\n </div>\n </TooltipProvider>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarRail.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\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=\"rail\"\n aria-label=\"Toggle Sidebar\"\n :tabindex=\"-1\"\n title=\"Toggle Sidebar\"\n :class=\"cn(\n 'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex',\n '[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize',\n '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\n 'group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar',\n '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',\n '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',\n props.class,\n )\"\n @click=\"toggleSidebar\"\n >\n <slot />\n </button>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Separator } from '@/registry/new-york/ui/separator'\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": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\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": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/index.ts",
|
|
"content": "import type { HTMLAttributes } from 'vue'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nexport interface SidebarProps {\n side?: 'left' | 'right'\n variant?: 'sidebar' | 'floating' | 'inset'\n collapsible?: 'offcanvas' | 'icon' | 'none'\n class?: HTMLAttributes['class']\n}\n\nexport { default as Sidebar } from './Sidebar.vue'\nexport { default as SidebarContent } from './SidebarContent.vue'\nexport { default as SidebarFooter } from './SidebarFooter.vue'\nexport { default as SidebarGroup } from './SidebarGroup.vue'\nexport { default as SidebarGroupAction } from './SidebarGroupAction.vue'\nexport { default as SidebarGroupContent } from './SidebarGroupContent.vue'\nexport { default as SidebarGroupLabel } from './SidebarGroupLabel.vue'\nexport { default as SidebarHeader } from './SidebarHeader.vue'\nexport { default as SidebarInput } from './SidebarInput.vue'\nexport { default as SidebarInset } from './SidebarInset.vue'\nexport { default as SidebarMenu } from './SidebarMenu.vue'\nexport { default as SidebarMenuAction } from './SidebarMenuAction.vue'\nexport { default as SidebarMenuBadge } from './SidebarMenuBadge.vue'\nexport { default as SidebarMenuButton } from './SidebarMenuButton.vue'\nexport { default as SidebarMenuItem } from './SidebarMenuItem.vue'\nexport { default as SidebarMenuSkeleton } from './SidebarMenuSkeleton.vue'\nexport { default as SidebarMenuSub } from './SidebarMenuSub.vue'\nexport { default as SidebarMenuSubButton } from './SidebarMenuSubButton.vue'\nexport { default as SidebarMenuSubItem } from './SidebarMenuSubItem.vue'\nexport { default as SidebarProvider } from './SidebarProvider.vue'\nexport { default as SidebarRail } from './SidebarRail.vue'\nexport { default as SidebarSeparator } from './SidebarSeparator.vue'\nexport { default as SidebarTrigger } from './SidebarTrigger.vue'\n\nexport { useSidebar } from './utils'\n\nexport const sidebarMenuButtonVariants = cva(\n 'peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',\n {\n variants: {\n variant: {\n default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',\n outline:\n 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',\n },\n size: {\n default: 'h-8 text-sm',\n sm: 'h-7 text-xs',\n lg: 'h-12 text-sm group-data-[collapsible=icon]:!p-0',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type SidebarMenuButtonVariants = VariantProps<typeof sidebarMenuButtonVariants>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/utils.ts",
|
|
"content": "import type { ComputedRef, Ref } from 'vue'\nimport { createContext } from 'reka-ui'\n\nexport const SIDEBAR_COOKIE_NAME = 'sidebar:state'\nexport const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nexport const SIDEBAR_WIDTH = '16rem'\nexport const SIDEBAR_WIDTH_MOBILE = '18rem'\nexport const SIDEBAR_WIDTH_ICON = '3rem'\nexport const SIDEBAR_KEYBOARD_SHORTCUT = 'b'\n\nexport const [useSidebar, provideSidebarContext] = createContext<{\n state: ComputedRef<'expanded' | 'collapsed'>\n open: Ref<boolean>\n setOpen: (value: boolean) => void\n isMobile: Ref<boolean>\n openMobile: Ref<boolean>\n setOpenMobile: (value: boolean) => void\n toggleSidebar: () => void\n}>('Sidebar')\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "skeleton",
|
|
"type": "registry:ui",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/skeleton/Skeleton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\ninterface SkeletonProps {\n class?: HTMLAttributes['class']\n}\n\nconst props = defineProps<SkeletonProps>()\n</script>\n\n<template>\n <div :class=\"cn('animate-pulse rounded-md bg-primary/10', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/skeleton/index.ts",
|
|
"content": "export { default as Skeleton } from './Skeleton.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "slider",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/slider/Slider.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { SliderRootEmits, SliderRootProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { SliderRange, SliderRoot, SliderThumb, SliderTrack, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SliderRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<SliderRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SliderRoot\n :class=\"cn(\n 'relative flex w-full touch-none select-none items-center data-[orientation=vertical]:flex-col data-[orientation=vertical]:w-1.5 data-[orientation=vertical]:h-full',\n props.class,\n )\"\n v-bind=\"forwarded\"\n >\n <SliderTrack class=\"relative h-1.5 w-full data-[orientation=vertical]:w-1.5 grow overflow-hidden rounded-full bg-primary/20\">\n <SliderRange class=\"absolute h-full data-[orientation=vertical]:w-full bg-primary\" />\n </SliderTrack>\n <SliderThumb\n v-for=\"(_, key) in modelValue\"\n :key=\"key\"\n class=\"block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\"\n />\n </SliderRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/slider/index.ts",
|
|
"content": "export { default as Slider } from './Slider.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "sonner",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"vue-sonner"
|
|
],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "ui/sonner/Sonner.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { Toaster as Sonner, type ToasterProps } from 'vue-sonner'\n\nconst props = defineProps<ToasterProps>()\n</script>\n\n<template>\n <Sonner\n class=\"toaster group\"\n v-bind=\"props\"\n :toast-options=\"{\n classes: {\n toast: 'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg',\n description: 'group-[.toast]:text-muted-foreground',\n actionButton:\n 'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',\n cancelButton:\n 'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',\n },\n }\"\n />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sonner/index.ts",
|
|
"content": "export { default as Toaster } from './Sonner.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "stepper",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/stepper/Stepper.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperRootEmits, StepperRootProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperRoot, useForwardPropsEmits } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<StepperRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <StepperRoot\n v-slot=\"slotProps\"\n :class=\"cn(\n 'flex gap-2',\n props.class,\n )\"\n v-bind=\"forwarded\"\n >\n <slot v-bind=\"slotProps\" />\n </StepperRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/StepperDescription.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperDescriptionProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperDescription, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperDescriptionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <StepperDescription v-slot=\"slotProps\" v-bind=\"forwarded\" :class=\"cn('text-xs text-muted-foreground', props.class)\">\n <slot v-bind=\"slotProps\" />\n </StepperDescription>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/StepperIndicator.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperIndicatorProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperIndicator, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperIndicatorProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <StepperIndicator\n v-bind=\"forwarded\"\n :class=\"cn(\n 'inline-flex items-center justify-center rounded-full text-muted-foreground/50 w-8 h-8',\n // Disabled\n 'group-data-[disabled]:text-muted-foreground group-data-[disabled]:opacity-50',\n // Active\n 'group-data-[state=active]:bg-primary group-data-[state=active]:text-primary-foreground',\n // Completed\n 'group-data-[state=completed]:bg-accent group-data-[state=completed]:text-accent-foreground',\n props.class,\n )\"\n >\n <slot />\n </StepperIndicator>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/StepperItem.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperItemProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperItem, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperItemProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <StepperItem\n v-slot=\"slotProps\"\n v-bind=\"forwarded\"\n :class=\"cn('flex items-center gap-2 group data-[disabled]:pointer-events-none', props.class)\"\n >\n <slot v-bind=\"slotProps\" />\n </StepperItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/StepperSeparator.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperSeparatorProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperSeparator, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperSeparatorProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <StepperSeparator\n v-bind=\"forwarded\"\n :class=\"cn(\n 'bg-muted',\n // Disabled\n 'group-data-[disabled]:bg-muted group-data-[disabled]:opacity-50',\n // Completed\n 'group-data-[state=completed]:bg-accent-foreground',\n props.class,\n )\"\n />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/StepperTitle.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperTitleProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperTitle, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperTitleProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <StepperTitle v-bind=\"forwarded\" :class=\"cn('text-md font-semibold whitespace-nowrap', props.class)\">\n <slot />\n </StepperTitle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/StepperTrigger.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperTriggerProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperTrigger, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <StepperTrigger\n v-bind=\"forwarded\"\n :class=\"cn('p-1 flex flex-col items-center text-center gap-1 rounded-md', props.class)\"\n >\n <slot />\n </StepperTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/index.ts",
|
|
"content": "export { default as Stepper } from './Stepper.vue'\nexport { default as StepperDescription } from './StepperDescription.vue'\nexport { default as StepperIndicator } from './StepperIndicator.vue'\nexport { default as StepperItem } from './StepperItem.vue'\nexport { default as StepperSeparator } from './StepperSeparator.vue'\nexport { default as StepperTitle } from './StepperTitle.vue'\nexport { default as StepperTrigger } from './StepperTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "switch",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/switch/Switch.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n SwitchRoot,\n type SwitchRootEmits,\n type SwitchRootProps,\n SwitchThumb,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SwitchRootProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<SwitchRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SwitchRoot\n v-bind=\"forwarded\"\n :class=\"cn(\n 'peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',\n props.class,\n )\"\n >\n <SwitchThumb\n :class=\"cn('pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0')\"\n >\n <slot name=\"thumb\" />\n </SwitchThumb>\n </SwitchRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/switch/index.ts",
|
|
"content": "export { default as Switch } from './Switch.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "table",
|
|
"type": "registry:ui",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/table/Table.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div class=\"relative w-full overflow-auto\">\n <table :class=\"cn('w-full caption-bottom text-sm', props.class)\">\n <slot />\n </table>\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableBody.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <tbody :class=\"cn('[&_tr:last-child]:border-0', props.class)\">\n <slot />\n </tbody>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableCaption.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <caption :class=\"cn('mt-4 text-sm text-muted-foreground', props.class)\">\n <slot />\n </caption>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableCell.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <td\n :class=\"\n cn(\n 'p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-0.5',\n props.class,\n )\n \"\n >\n <slot />\n </td>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableEmpty.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { computed, type HTMLAttributes } from 'vue'\nimport TableCell from './TableCell.vue'\nimport TableRow from './TableRow.vue'\n\nconst props = withDefaults(defineProps<{\n class?: HTMLAttributes['class']\n colspan?: number\n}>(), {\n colspan: 1,\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <TableRow>\n <TableCell\n :class=\"\n cn(\n 'p-4 whitespace-nowrap align-middle text-sm text-foreground',\n props.class,\n )\n \"\n v-bind=\"delegatedProps\"\n >\n <div class=\"flex items-center justify-center py-10\">\n <slot />\n </div>\n </TableCell>\n </TableRow>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <tfoot :class=\"cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', props.class)\">\n <slot />\n </tfoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableHead.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <th :class=\"cn('h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-0.5', props.class)\">\n <slot />\n </th>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <thead :class=\"cn('[&_tr]:border-b', props.class)\">\n <slot />\n </thead>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableRow.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <tr :class=\"cn('border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted', props.class)\">\n <slot />\n </tr>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/index.ts",
|
|
"content": "export { default as Table } from './Table.vue'\nexport { default as TableBody } from './TableBody.vue'\nexport { default as TableCaption } from './TableCaption.vue'\nexport { default as TableCell } from './TableCell.vue'\nexport { default as TableEmpty } from './TableEmpty.vue'\nexport { default as TableFooter } from './TableFooter.vue'\nexport { default as TableHead } from './TableHead.vue'\nexport { default as TableHeader } from './TableHeader.vue'\nexport { default as TableRow } from './TableRow.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "tabs",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/tabs/Tabs.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { TabsRootEmits, TabsRootProps } from 'reka-ui'\nimport { TabsRoot, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<TabsRootProps>()\nconst emits = defineEmits<TabsRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <TabsRoot v-bind=\"forwarded\">\n <slot />\n </TabsRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tabs/TabsContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TabsContent, type TabsContentProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TabsContentProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <TabsContent\n :class=\"cn('mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2', props.class)\"\n v-bind=\"delegatedProps\"\n >\n <slot />\n </TabsContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tabs/TabsList.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TabsList, type TabsListProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TabsListProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <TabsList\n v-bind=\"delegatedProps\"\n :class=\"cn(\n 'inline-flex items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground',\n props.class,\n )\"\n >\n <slot />\n </TabsList>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tabs/TabsTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TabsTrigger, type TabsTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TabsTriggerProps & { 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 <TabsTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow',\n props.class,\n )\"\n >\n <span class=\"truncate\">\n <slot />\n </span>\n </TabsTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tabs/index.ts",
|
|
"content": "export { default as Tabs } from './Tabs.vue'\nexport { default as TabsContent } from './TabsContent.vue'\nexport { default as TabsList } from './TabsList.vue'\nexport { default as TabsTrigger } from './TabsTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "tags-input",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/tags-input/TagsInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TagsInputRoot, type TagsInputRootEmits, type TagsInputRootProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TagsInputRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<TagsInputRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <TagsInputRoot v-bind=\"forwarded\" :class=\"cn('flex flex-wrap gap-2 items-center rounded-md border border-input bg-background px-3 py-1.5 text-sm', props.class)\">\n <slot />\n </TagsInputRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tags-input/TagsInputInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TagsInputInput, type TagsInputInputProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TagsInputInputProps & { 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 <TagsInputInput v-bind=\"forwardedProps\" :class=\"cn('text-sm min-h-5 focus:outline-none flex-1 bg-transparent px-1', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tags-input/TagsInputItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TagsInputItem, type TagsInputItemProps, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TagsInputItemProps & { 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 <TagsInputItem v-bind=\"forwardedProps\" :class=\"cn('flex h-5 items-center rounded-md bg-secondary data-[state=active]:ring-ring data-[state=active]:ring-2 data-[state=active]:ring-offset-2 ring-offset-background', props.class)\">\n <slot />\n </TagsInputItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tags-input/TagsInputItemDelete.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Cross2Icon } from '@radix-icons/vue'\nimport { TagsInputItemDelete, type TagsInputItemDeleteProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TagsInputItemDeleteProps & { 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 <TagsInputItemDelete v-bind=\"forwardedProps\" :class=\"cn('flex rounded bg-transparent mr-1', props.class)\">\n <slot>\n <Cross2Icon class=\"w-4 h-4\" />\n </slot>\n </TagsInputItemDelete>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tags-input/TagsInputItemText.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TagsInputItemText, type TagsInputItemTextProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TagsInputItemTextProps & { 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 <TagsInputItemText v-bind=\"forwardedProps\" :class=\"cn('py-0.5 px-2 text-sm rounded bg-transparent', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tags-input/index.ts",
|
|
"content": "export { default as TagsInput } from './TagsInput.vue'\nexport { default as TagsInputInput } from './TagsInputInput.vue'\nexport { default as TagsInputItem } from './TagsInputItem.vue'\nexport { default as TagsInputItemDelete } from './TagsInputItemDelete.vue'\nexport { default as TagsInputItemText } from './TagsInputItemText.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "textarea",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/textarea/Textarea.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { useVModel } from '@vueuse/core'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n defaultValue?: string | number\n modelValue?: string | number\n}>()\n\nconst emits = defineEmits<{\n (e: 'update:modelValue', payload: string | number): void\n}>()\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n passive: true,\n defaultValue: props.defaultValue,\n})\n</script>\n\n<template>\n <textarea v-model=\"modelValue\" :class=\"cn('flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/textarea/index.ts",
|
|
"content": "export { default as Textarea } from './Textarea.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "toast",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/toast/Toast.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ToastRoot, type ToastRootEmits, useForwardPropsEmits } from 'reka-ui'\nimport { computed } from 'vue'\nimport { type ToastProps, toastVariants } from '.'\n\nconst props = defineProps<ToastProps>()\n\nconst emits = defineEmits<ToastRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ToastRoot\n v-bind=\"forwarded\"\n :class=\"cn(toastVariants({ variant }), props.class)\"\n @update:open=\"onOpenChange\"\n >\n <slot />\n </ToastRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/ToastAction.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ToastAction, type ToastActionProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ToastActionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ToastAction v-bind=\"delegatedProps\" :class=\"cn('inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive', props.class)\">\n <slot />\n </ToastAction>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/ToastClose.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Cross2Icon } from '@radix-icons/vue'\nimport { ToastClose, type ToastCloseProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ToastCloseProps & {\n class?: HTMLAttributes['class']\n}>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ToastClose v-bind=\"delegatedProps\" :class=\"cn('absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600', props.class)\">\n <Cross2Icon class=\"h-4 w-4\" />\n </ToastClose>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/ToastDescription.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ToastDescription, type ToastDescriptionProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ToastDescriptionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ToastDescription :class=\"cn('text-sm opacity-90', props.class)\" v-bind=\"delegatedProps\">\n <slot />\n </ToastDescription>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/ToastProvider.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToastProvider, type ToastProviderProps } from 'reka-ui'\n\nconst props = defineProps<ToastProviderProps>()\n</script>\n\n<template>\n <ToastProvider v-bind=\"props\">\n <slot />\n </ToastProvider>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/ToastTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ToastTitle, type ToastTitleProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ToastTitleProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ToastTitle v-bind=\"delegatedProps\" :class=\"cn('text-sm font-semibold [&+div]:text-xs', props.class)\">\n <slot />\n </ToastTitle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/ToastViewport.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ToastViewport, type ToastViewportProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ToastViewportProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ToastViewport v-bind=\"delegatedProps\" :class=\"cn('fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/Toaster.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { isVNode } from 'vue'\nimport { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from '.'\nimport { useToast } from './use-toast'\n\nconst { toasts } = useToast()\n</script>\n\n<template>\n <ToastProvider>\n <Toast v-for=\"toast in toasts\" :key=\"toast.id\" v-bind=\"toast\">\n <div class=\"grid gap-1\">\n <ToastTitle v-if=\"toast.title\">\n {{ toast.title }}\n </ToastTitle>\n <template v-if=\"toast.description\">\n <ToastDescription v-if=\"isVNode(toast.description)\">\n <component :is=\"toast.description\" />\n </ToastDescription>\n <ToastDescription v-else>\n {{ toast.description }}\n </ToastDescription>\n </template>\n <ToastClose />\n </div>\n <component :is=\"toast.action\" />\n </Toast>\n <ToastViewport />\n </ToastProvider>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/index.ts",
|
|
"content": "import type { ToastRootProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\n\nexport { default as Toast } from './Toast.vue'\nexport { default as ToastAction } from './ToastAction.vue'\nexport { default as ToastClose } from './ToastClose.vue'\nexport { default as ToastDescription } from './ToastDescription.vue'\nexport { default as Toaster } from './Toaster.vue'\nexport { default as ToastProvider } from './ToastProvider.vue'\nexport { default as ToastTitle } from './ToastTitle.vue'\nexport { default as ToastViewport } from './ToastViewport.vue'\nexport { toast, useToast } from './use-toast'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nexport const toastVariants = cva(\n 'group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--reka-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--reka-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full',\n {\n variants: {\n variant: {\n default: 'border bg-background text-foreground',\n destructive:\n 'destructive group border-destructive bg-destructive text-destructive-foreground',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n)\n\ntype ToastVariants = VariantProps<typeof toastVariants>\n\nexport interface ToastProps extends ToastRootProps {\n class?: HTMLAttributes['class']\n variant?: ToastVariants['variant']\n onOpenChange?: ((value: boolean) => void) | undefined\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/use-toast.ts",
|
|
"content": "import type { Component, VNode } from 'vue'\nimport type { ToastProps } from '.'\nimport { computed, ref } from 'vue'\n\nconst TOAST_LIMIT = 1\nconst TOAST_REMOVE_DELAY = 1000000\n\nexport type StringOrVNode =\n | string\n | VNode\n | (() => VNode)\n\ntype ToasterToast = ToastProps & {\n id: string\n title?: string\n description?: StringOrVNode\n action?: Component\n}\n\nconst actionTypes = {\n ADD_TOAST: 'ADD_TOAST',\n UPDATE_TOAST: 'UPDATE_TOAST',\n DISMISS_TOAST: 'DISMISS_TOAST',\n REMOVE_TOAST: 'REMOVE_TOAST',\n} as const\n\nlet count = 0\n\nfunction genId() {\n count = (count + 1) % Number.MAX_VALUE\n return count.toString()\n}\n\ntype ActionType = typeof actionTypes\n\ntype Action =\n | {\n type: ActionType['ADD_TOAST']\n toast: ToasterToast\n }\n | {\n type: ActionType['UPDATE_TOAST']\n toast: Partial<ToasterToast>\n }\n | {\n type: ActionType['DISMISS_TOAST']\n toastId?: ToasterToast['id']\n }\n | {\n type: ActionType['REMOVE_TOAST']\n toastId?: ToasterToast['id']\n }\n\ninterface State {\n toasts: ToasterToast[]\n}\n\nconst toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()\n\nfunction addToRemoveQueue(toastId: string) {\n if (toastTimeouts.has(toastId))\n return\n\n const timeout = setTimeout(() => {\n toastTimeouts.delete(toastId)\n dispatch({\n type: actionTypes.REMOVE_TOAST,\n toastId,\n })\n }, TOAST_REMOVE_DELAY)\n\n toastTimeouts.set(toastId, timeout)\n}\n\nconst state = ref<State>({\n toasts: [],\n})\n\nfunction dispatch(action: Action) {\n switch (action.type) {\n case actionTypes.ADD_TOAST:\n state.value.toasts = [action.toast, ...state.value.toasts].slice(0, TOAST_LIMIT)\n break\n\n case actionTypes.UPDATE_TOAST:\n state.value.toasts = state.value.toasts.map(t =>\n t.id === action.toast.id ? { ...t, ...action.toast } : t,\n )\n break\n\n case actionTypes.DISMISS_TOAST: {\n const { toastId } = action\n\n if (toastId) {\n addToRemoveQueue(toastId)\n }\n else {\n state.value.toasts.forEach((toast) => {\n addToRemoveQueue(toast.id)\n })\n }\n\n state.value.toasts = state.value.toasts.map(t =>\n t.id === toastId || toastId === undefined\n ? {\n ...t,\n open: false,\n }\n : t,\n )\n break\n }\n\n case actionTypes.REMOVE_TOAST:\n if (action.toastId === undefined)\n state.value.toasts = []\n else\n state.value.toasts = state.value.toasts.filter(t => t.id !== action.toastId)\n\n break\n }\n}\n\nfunction useToast() {\n return {\n toasts: computed(() => state.value.toasts),\n toast,\n dismiss: (toastId?: string) => dispatch({ type: actionTypes.DISMISS_TOAST, toastId }),\n }\n}\n\ntype Toast = Omit<ToasterToast, 'id'>\n\nfunction toast(props: Toast) {\n const id = genId()\n\n const update = (props: ToasterToast) =>\n dispatch({\n type: actionTypes.UPDATE_TOAST,\n toast: { ...props, id },\n })\n\n const dismiss = () => dispatch({ type: actionTypes.DISMISS_TOAST, toastId: id })\n\n dispatch({\n type: actionTypes.ADD_TOAST,\n toast: {\n ...props,\n id,\n open: true,\n onOpenChange: (open: boolean) => {\n if (!open)\n dismiss()\n },\n },\n })\n\n return {\n id,\n dismiss,\n update,\n }\n}\n\nexport { toast, useToast }\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "toggle",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/toggle/Toggle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Toggle, type ToggleEmits, type ToggleProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { type ToggleVariants, toggleVariants } from '.'\n\nconst props = withDefaults(defineProps<ToggleProps & {\n class?: HTMLAttributes['class']\n variant?: ToggleVariants['variant']\n size?: ToggleVariants['size']\n}>(), {\n variant: 'default',\n size: 'default',\n disabled: false,\n})\n\nconst emits = defineEmits<ToggleEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, size, variant, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <Toggle\n v-bind=\"forwarded\"\n :class=\"cn(toggleVariants({ variant, size }), props.class)\"\n >\n <slot />\n </Toggle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toggle/index.ts",
|
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Toggle } from './Toggle.vue'\n\nexport const toggleVariants = cva(\n 'inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n default: 'bg-transparent',\n outline:\n 'border border-input bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground',\n },\n size: {\n default: 'h-9 px-2 min-w-9',\n sm: 'h-8 px-1.5 min-w-8',\n lg: 'h-10 px-2.5 min-w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type ToggleVariants = VariantProps<typeof toggleVariants>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "toggle-group",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"toggle",
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/toggle-group/ToggleGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { toggleVariants } from '@/registry/new-york/ui/toggle'\nimport type { VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\nimport { ToggleGroupRoot, type ToggleGroupRootEmits, type ToggleGroupRootProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes, provide } from 'vue'\n\ntype ToggleGroupVariants = VariantProps<typeof toggleVariants>\n\nconst props = defineProps<ToggleGroupRootProps & {\n class?: HTMLAttributes['class']\n variant?: ToggleGroupVariants['variant']\n size?: ToggleGroupVariants['size']\n}>()\nconst emits = defineEmits<ToggleGroupRootEmits>()\n\nprovide('toggleGroup', {\n variant: props.variant,\n size: props.size,\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ToggleGroupRoot v-bind=\"forwarded\" :class=\"cn('flex items-center justify-center gap-1', props.class)\">\n <slot />\n </ToggleGroupRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toggle-group/ToggleGroupItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\nimport { toggleVariants } from '@/registry/new-york/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": ""
|
|
},
|
|
{
|
|
"path": "ui/toggle-group/index.ts",
|
|
"content": "export { default as ToggleGroup } from './ToggleGroup.vue'\nexport { default as ToggleGroupItem } from './ToggleGroupItem.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "tooltip",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/tooltip/Tooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { TooltipRoot, type TooltipRootEmits, type TooltipRootProps, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<TooltipRootProps>()\nconst emits = defineEmits<TooltipRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <TooltipRoot v-bind=\"forwarded\">\n <slot />\n </TooltipRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tooltip/TooltipContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TooltipContent, type TooltipContentEmits, type TooltipContentProps, TooltipPortal, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<TooltipContentProps & { class?: HTMLAttributes['class'] }>(), {\n sideOffset: 4,\n})\n\nconst emits = defineEmits<TooltipContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <TooltipPortal>\n <TooltipContent v-bind=\"{ ...forwarded, ...$attrs }\" :class=\"cn('z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', props.class)\">\n <slot />\n </TooltipContent>\n </TooltipPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tooltip/TooltipProvider.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { TooltipProvider, type TooltipProviderProps } from 'reka-ui'\n\nconst props = defineProps<TooltipProviderProps>()\n</script>\n\n<template>\n <TooltipProvider v-bind=\"props\">\n <slot />\n </TooltipProvider>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tooltip/TooltipTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { TooltipTrigger, type TooltipTriggerProps } from 'reka-ui'\n\nconst props = defineProps<TooltipTriggerProps>()\n</script>\n\n<template>\n <TooltipTrigger v-bind=\"props\">\n <slot />\n </TooltipTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tooltip/index.ts",
|
|
"content": "export { default as Tooltip } from './Tooltip.vue'\nexport { default as TooltipContent } from './TooltipContent.vue'\nexport { default as TooltipProvider } from './TooltipProvider.vue'\nexport { default as TooltipTrigger } from './TooltipTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "v-calendar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"v-calendar@next",
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/v-calendar/Calendar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { Calendar } from 'v-calendar'\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/new-york/ui/button'\nimport { ChevronLeftIcon, ChevronRightIcon } from '@radix-icons/vue'\nimport { useVModel } from '@vueuse/core'\nimport { DatePicker } from 'v-calendar'\nimport { computed, nextTick, onMounted, ref, useSlots } from 'vue'\nimport { isVCalendarSlot } from '.'\n\n/* Extracted from v-calendar */\ntype DatePickerModel = DatePickerDate | DatePickerRangeObject\ntype DateSource = Date | string | number\ntype DatePickerDate = DateSource | Partial<SimpleDateParts> | null\ninterface DatePickerRangeObject {\n start: Exclude<DatePickerDate, null>\n end: Exclude<DatePickerDate, null>\n}\ninterface SimpleDateParts {\n year: number\n month: number\n day: number\n hours: number\n minutes: number\n seconds: number\n milliseconds: number\n}\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n modelValue?: string | number | Date | DatePickerModel\n modelModifiers?: object\n columns?: number\n type?: 'single' | 'range'\n}>(), {\n type: 'single',\n columns: 1,\n})\nconst emits = defineEmits<{\n (e: 'update:modelValue', payload: typeof props.modelValue): void\n}>()\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n passive: true,\n})\n\nconst datePicker = ref<InstanceType<typeof DatePicker>>()\n// @ts-expect-error in this current version of v-calendar has the calendaRef instance, which is required to handle arrow nav.\nconst calendarRef = computed<InstanceType<typeof Calendar>>(() => datePicker.value.calendarRef)\n\nfunction handleNav(direction: 'prev' | 'next') {\n if (!calendarRef.value)\n return\n\n if (direction === 'prev')\n calendarRef.value.movePrev()\n else calendarRef.value.moveNext()\n}\n\nonMounted(async () => {\n await nextTick()\n if (modelValue.value instanceof Date && calendarRef.value)\n calendarRef.value.focusDate(modelValue.value)\n})\n\nconst $slots = useSlots()\nconst vCalendarSlots = computed(() => {\n return Object.keys($slots)\n .filter(name => isVCalendarSlot(name))\n .reduce((obj: Record<string, any>, key: string) => {\n obj[key] = $slots[key]\n return obj\n }, {})\n})\n</script>\n\n<template>\n <div class=\"relative\">\n <div v-if=\"$attrs.mode !== 'time'\" class=\"absolute flex justify-between w-full px-4 top-3 z-[1]\">\n <button\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n )\"\n @click=\"handleNav('prev')\"\n >\n <ChevronLeftIcon class=\"w-4 h-4\" />\n </button>\n <button\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n )\"\n @click=\"handleNav('next')\"\n >\n <ChevronRightIcon class=\"w-4 h-4\" />\n </button>\n </div>\n\n <DatePicker\n ref=\"datePicker\"\n v-model=\"modelValue\"\n v-bind=\"$attrs\"\n :model-modifiers=\"modelModifiers\"\n class=\"calendar\"\n trim-weeks\n :transition=\"'none'\"\n :columns=\"columns\"\n >\n <template v-for=\"(_, slot) of vCalendarSlots\" #[slot]=\"scope\">\n <slot :name=\"slot\" v-bind=\"scope\" />\n </template>\n\n <template #nav-prev-button>\n <ChevronLeftIcon />\n </template>\n\n <template #nav-next-button>\n <ChevronRightIcon />\n </template>\n </DatePicker>\n </div>\n</template>\n\n<style lang=\"css\">\n.calendar {\n @apply p-3 text-center;\n}\n.calendar .vc-pane-layout {\n @apply grid gap-4 max-sm:!grid-cols-1;\n}\n.calendar .vc-title {\n @apply text-sm font-medium relative z-20;\n}\n.vc-popover-content-wrapper .vc-popover-content {\n @apply mt-3 rounded-md max-w-xs border bg-background;\n}\n.vc-popover-content-wrapper .vc-nav-header {\n @apply flex justify-between items-center p-2;\n}\n.vc-popover-content-wrapper .vc-nav-items {\n @apply grid grid-cols-4 gap-2 p-2;\n}\n.vc-popover-content-wrapper .vc-nav-items .vc-nav-item {\n @apply rounded-md px-2 py-1;\n}\n.vc-popover-content-wrapper .vc-nav-items .vc-nav-item:hover {\n @apply text-muted-foreground bg-muted;\n}\n.vc-popover-content-wrapper .vc-nav-items .vc-nav-item.is-active {\n @apply bg-primary text-primary-foreground;\n}\n.calendar .vc-pane-header-wrapper {\n @apply hidden;\n}\n.calendar .vc-weeks {\n @apply mt-4;\n}\n.calendar .vc-weekdays {\n @apply justify-items-center;\n}\n.calendar .vc-weekday {\n @apply text-muted-foreground rounded-md font-normal text-[0.8rem];\n}\n.calendar .vc-weeks {\n @apply w-full space-y-2 flex flex-col [&>_div]:grid [&>_div]:grid-cols-7;\n}\n.calendar .vc-day:has(.vc-highlights) {\n @apply first:rounded-l-md last:rounded-r-md;\n}\n.calendar .vc-day.is-today:not(:has(.vc-day-layer)) .vc-day-content {\n @apply bg-secondary text-primary rounded-md;\n}\n.calendar .vc-day:has(.vc-highlight-base-start) {\n @apply rounded-l-md;\n}\n.calendar .vc-day:has(.vc-highlight-base-end) {\n @apply rounded-r-md;\n}\n.calendar .vc-day:has(.vc-highlight-bg-outline):not(:has(.vc-highlight-base-start)):not(:has(.vc-highlight-base-end)) {\n @apply rounded-md;\n}\n.calendar .vc-day-content {\n @apply text-center text-sm p-0 relative focus-within:relative focus-within:z-20 inline-flex items-center justify-center ring-offset-background hover:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 hover:bg-accent hover:text-accent-foreground h-9 w-9 font-normal aria-selected:opacity-100 select-none;\n}\n.calendar .vc-day-content:not(.vc-highlight-content-light) {\n @apply rounded-md;\n}\n.calendar .is-not-in-month:not(:has(.vc-highlight-content-solid)):not(:has(.vc-highlight-content-light)):not(:has(.vc-highlight-content-outline)),\n.calendar .vc-disabled {\n @apply text-muted-foreground opacity-50;\n}\n.calendar .vc-highlight-content-solid, .calendar .vc-highlight-content-outline {\n @apply bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground;\n}\n.calendar .vc-highlight-content-light {\n @apply bg-accent text-accent-foreground;\n}\n.calendar .vc-pane-container.in-transition {\n @apply overflow-hidden;\n}\n.calendar .vc-pane-container {\n @apply w-full relative;\n}\n:root {\n\t--vc-slide-translate: 22px;\n\t--vc-slide-duration: 0.15s;\n\t--vc-slide-timing: ease;\n}\n.calendar .vc-fade-enter-active,\n.calendar .vc-fade-leave-active,\n.calendar .vc-slide-left-enter-active,\n.calendar .vc-slide-left-leave-active,\n.calendar .vc-slide-right-enter-active,\n.calendar .vc-slide-right-leave-active,\n.calendar .vc-slide-up-enter-active,\n.calendar .vc-slide-up-leave-active,\n.calendar .vc-slide-down-enter-active,\n.calendar .vc-slide-down-leave-active,\n.calendar .vc-slide-fade-enter-active,\n.calendar .vc-slide-fade-leave-active {\n\ttransition:\n\t\topacity var(--vc-slide-duration) var(--vc-slide-timing),\n\t\t-webkit-transform var(--vc-slide-duration) var(--vc-slide-timing);\n\ttransition:\n\t\ttransform var(--vc-slide-duration) var(--vc-slide-timing),\n\t\topacity var(--vc-slide-duration) var(--vc-slide-timing);\n\ttransition:\n\t\ttransform var(--vc-slide-duration) var(--vc-slide-timing),\n\t\topacity var(--vc-slide-duration) var(--vc-slide-timing),\n\t\t-webkit-transform var(--vc-slide-duration) var(--vc-slide-timing);\n\t-webkit-backface-visibility: hidden;\n\tbackface-visibility: hidden;\n\tpointer-events: none;\n}\n.calendar .vc-none-leave-active,\n.calendar .vc-fade-leave-active,\n.calendar .vc-slide-left-leave-active,\n.calendar .vc-slide-right-leave-active,\n.calendar .vc-slide-up-leave-active,\n.calendar .vc-slide-down-leave-active {\n\tposition: absolute !important;\n\twidth: 100%;\n}\n.calendar .vc-none-enter-from,\n.calendar .vc-none-leave-to,\n.calendar .vc-fade-enter-from,\n.calendar .vc-fade-leave-to,\n.calendar .vc-slide-left-enter-from,\n.calendar .vc-slide-left-leave-to,\n.calendar .vc-slide-right-enter-from,\n.calendar .vc-slide-right-leave-to,\n.calendar .vc-slide-up-enter-from,\n.calendar .vc-slide-up-leave-to,\n.calendar .vc-slide-down-enter-from,\n.calendar .vc-slide-down-leave-to,\n.calendar .vc-slide-fade-enter-from,\n.calendar .vc-slide-fade-leave-to {\n\topacity: 0;\n}\n.calendar .vc-slide-left-enter-from,\n.calendar .vc-slide-right-leave-to,\n.calendar .vc-slide-fade-enter-from.direction-left,\n.calendar .vc-slide-fade-leave-to.direction-left {\n\t-webkit-transform: translateX(var(--vc-slide-translate));\n\ttransform: translateX(var(--vc-slide-translate));\n}\n.calendar .vc-slide-right-enter-from,\n.calendar .vc-slide-left-leave-to,\n.calendar .vc-slide-fade-enter-from.direction-right,\n.calendar .vc-slide-fade-leave-to.direction-right {\n\t-webkit-transform: translateX(calc(-1 * var(--vc-slide-translate)));\n\ttransform: translateX(calc(-1 * var(--vc-slide-translate)));\n}\n.calendar .vc-slide-up-enter-from,\n.calendar .vc-slide-down-leave-to,\n.calendar .vc-slide-fade-enter-from.direction-top,\n.calendar .vc-slide-fade-leave-to.direction-top {\n\t-webkit-transform: translateY(var(--vc-slide-translate));\n\ttransform: translateY(var(--vc-slide-translate));\n}\n.calendar .vc-slide-down-enter-from,\n.calendar .vc-slide-up-leave-to,\n.calendar .vc-slide-fade-enter-from.direction-bottom,\n.calendar .vc-slide-fade-leave-to.direction-bottom {\n\t-webkit-transform: translateY(calc(-1 * var(--vc-slide-translate)));\n\ttransform: translateY(calc(-1 * var(--vc-slide-translate)));\n}\n/**\n * Timepicker styles\n */\n.vc-time-picker {\n @apply flex flex-col items-center p-2;\n}\n.vc-time-picker.vc-invalid {\n @apply pointer-events-none opacity-50;\n}\n.vc-time-picker.vc-attached {\n @apply border-t border-solid border-secondary mt-2;\n}\n.vc-time-picker > * + * {\n @apply mt-1;\n}\n.vc-time-header {\n @apply flex items-center text-sm font-semibold uppercase mt-1 px-1 leading-6;\n}\n.vc-time-select-group {\n @apply inline-flex items-center px-1 rounded-md bg-primary-foreground border border-solid border-secondary;\n}\n.vc-time-select-group .vc-base-icon {\n @apply mr-1 text-primary stroke-primary;\n}\n.vc-time-select-group select {\n @apply bg-primary-foreground p-1 appearance-none outline-none text-center;\n}\n.vc-time-weekday {\n @apply text-muted-foreground tracking-wide;\n}\n.vc-time-month {\n @apply text-primary ml-2;\n}\n.vc-time-day {\n @apply text-primary ml-1;\n}\n.vc-time-year {\n @apply text-muted-foreground ml-2;\n}\n.vc-time-colon {\n @apply mb-0.5;\n}\n.vc-time-decimal {\n @apply ml-0.5;\n}\n</style>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/v-calendar/index.ts",
|
|
"content": "export { default as Calendar } from './Calendar.vue'\nimport type { CalendarSlotName } from 'v-calendar/dist/types/src/components/Calendar/CalendarSlot.vue.d.ts'\n\nexport function isVCalendarSlot(slotName: string): slotName is CalendarSlotName {\n const validSlots: CalendarSlotName[] = [\n 'day-content',\n 'day-popover',\n 'dp-footer',\n 'footer',\n 'header-title-wrapper',\n 'header-title',\n 'header-prev-button',\n 'header-next-button',\n 'nav',\n 'nav-prev-button',\n 'nav-next-button',\n 'page',\n 'time-header',\n ]\n\n return validSlots.includes(slotName as CalendarSlotName)\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AccordionDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"accordion"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AccordionDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/registry/new-york/ui/accordion'\n\nconst defaultValue = 'item-1'\n\nconst accordionItems = [\n { value: 'item-1', title: 'Is it accessible?', content: 'Yes. It adheres to the WAI-ARIA design pattern.' },\n { value: 'item-2', title: 'Is it unstyled?', content: 'Yes. It\\'s unstyled by default, giving you freedom over the look and feel.' },\n { value: 'item-3', title: 'Can it be animated?', content: 'Yes! You can use the transition prop to configure the animation.' },\n]\n</script>\n\n<template>\n <Accordion type=\"single\" class=\"w-full\" collapsible :default-value=\"defaultValue\">\n <AccordionItem v-for=\"item in accordionItems\" :key=\"item.value\" :value=\"item.value\">\n <AccordionTrigger>{{ item.title }}</AccordionTrigger>\n <AccordionContent>\n {{ item.content }}\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AlertDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"alert"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AlertDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Alert, AlertDescription, AlertTitle } from '@/registry/new-york/ui/alert'\nimport { RocketIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Alert>\n <RocketIcon class=\"h-4 w-4\" />\n <AlertTitle>Heads up!</AlertTitle>\n <AlertDescription>\n You can add components to your app using the cli.\n </AlertDescription>\n </Alert>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AlertDestructiveDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"alert"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AlertDestructiveDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Alert, AlertDescription, AlertTitle } from '@/registry/new-york/ui/alert'\nimport { ExclamationTriangleIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Alert variant=\"destructive\">\n <ExclamationTriangleIcon class=\"w-4 h-4\" />\n <AlertTitle>Error</AlertTitle>\n <AlertDescription>\n Your session has expired. Please log in again.\n </AlertDescription>\n </Alert>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AlertDialogDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"alert-dialog",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AlertDialogDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from '@/registry/new-york/ui/alert-dialog'\nimport { Button } from '@/registry/new-york/ui/button'\n</script>\n\n<template>\n <AlertDialog>\n <AlertDialogTrigger as-child>\n <Button variant=\"outline\">\n Show Dialog\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>\n <AlertDialogDescription>\n This action cannot be undone. This will permanently delete your\n account and remove your data from our servers.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction>Continue</AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AreaChartCustomTooltip",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-area"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AreaChartCustomTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AreaChart } from '@/registry/new-york/ui/chart-area'\nimport CustomChartTooltip from './CustomChartTooltip.vue'\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 { name: 'Jul', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n]\n</script>\n\n<template>\n <AreaChart\n index=\"name\"\n :data=\"data\"\n :categories=\"['total', 'predicted']\"\n :custom-tooltip=\"CustomChartTooltip\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AreaChartDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-area"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AreaChartDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AreaChart } from '@/registry/new-york/ui/chart-area'\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 { name: 'Jul', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n]\n</script>\n\n<template>\n <AreaChart :data=\"data\" index=\"name\" :categories=\"['total', 'predicted']\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AreaChartSparkline",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-area"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AreaChartSparkline.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AreaChart } from '@/registry/new-york/ui/chart-area'\nimport { CurveType } from '@unovis/ts'\n\nconst data = [\n { name: 'Jan', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Feb', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Mar', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Apr', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'May', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Jun', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Jul', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Aug', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Sep', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Oct', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Nov', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Dec', total: Math.floor(Math.random() * 2000) + 1000 },\n]\n</script>\n\n<template>\n <AreaChart\n class=\"h-[100px] w-[400px]\"\n index=\"name\"\n :data=\"data\"\n :categories=\"['total']\"\n :show-grid-line=\"false\"\n :show-legend=\"false\"\n :show-x-axis=\"false\"\n :show-y-axis=\"false\"\n :curve-type=\"CurveType.Linear\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AspectRatioDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"aspect-ratio"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AspectRatioDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AspectRatio } from '@/registry/new-york/ui/aspect-ratio'\n</script>\n\n<template>\n <AspectRatio :ratio=\"16 / 9\" class=\"bg-muted\">\n <img\n src=\"https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&dpr=2&q=80\"\n alt=\"Photo by Drew Beamer\"\n class=\"rounded-md object-cover w-full h-full\"\n >\n </AspectRatio>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormApi",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormApi.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm } from '@/registry/new-york/ui/auto-form'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { h, onMounted, shallowRef } from 'vue'\nimport * as z from 'zod'\n\nconst schema = shallowRef<z.ZodObject< any, any, any > | null>(null)\n\nonMounted(() => {\n fetch('https://jsonplaceholder.typicode.com/users')\n .then(response => response.json())\n .then((data) => {\n schema.value = z.object({\n user: z.enum(data.map((user: any) => user.name)),\n })\n })\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <div class=\"flex justify-center w-full\">\n <AutoForm\n v-if=\"schema\"\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n @submit=\"onSubmit\"\n >\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n\n <div v-else>\n Loading...\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormArray",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormArray.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm } from '@/registry/new-york/ui/auto-form'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst schema = z.object({\n guestListName: z.string(),\n invitedGuests: z\n .array(\n z.object({\n name: z.string(),\n age: z.coerce.number(),\n }),\n )\n .describe('Guests invited to the party'),\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n @submit=\"onSubmit\"\n >\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormBasic",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormBasic.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm, AutoFormField } from '@/registry/new-york/ui/auto-form'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nenum Sports {\n Football = 'Football/Soccer',\n Basketball = 'Basketball',\n Baseball = 'Baseball',\n Hockey = 'Hockey (Ice)',\n None = 'I don\\'t like sports',\n}\n\nconst schema = z.object({\n username: z\n .string({\n required_error: 'Username is required.',\n })\n .min(2, {\n message: 'Username must be at least 2 characters.',\n }),\n\n password: z\n .string({\n required_error: 'Password is required.',\n })\n .min(8, {\n message: 'Password must be at least 8 characters.',\n }),\n\n favouriteNumber: z.coerce\n .number({\n invalid_type_error: 'Favourite number must be a number.',\n })\n .min(1, {\n message: 'Favourite number must be at least 1.',\n })\n .max(10, {\n message: 'Favourite number must be at most 10.',\n })\n .default(1)\n .optional(),\n\n acceptTerms: z\n .boolean()\n .refine(value => value, {\n message: 'You must accept the terms and conditions.',\n path: ['acceptTerms'],\n }),\n\n sendMeMails: z.boolean().optional(),\n\n birthday: z.coerce.date().optional(),\n\n color: z.enum(['red', 'green', 'blue']).optional(),\n\n // Another enum example\n marshmallows: z\n .enum(['not many', 'a few', 'a lot', 'too many']),\n\n // Native enum example\n sports: z.nativeEnum(Sports).describe('What is your favourite sport?'),\n\n bio: z\n .string()\n .min(10, {\n message: 'Bio must be at least 10 characters.',\n })\n .max(160, {\n message: 'Bio must not be longer than 30 characters.',\n })\n .optional(),\n\n customParent: z.string().optional(),\n\n file: z.string().optional(),\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n :field-config=\"{\n password: {\n label: 'Your secure password',\n inputProps: {\n type: 'password',\n placeholder: '••••••••',\n },\n },\n favouriteNumber: {\n description: 'Your favourite number between 1 and 10.',\n },\n acceptTerms: {\n label: 'Accept terms and conditions.',\n inputProps: {\n required: true,\n },\n },\n\n birthday: {\n description: 'We need your birthday to send you a gift.',\n },\n\n sendMeMails: {\n component: 'switch',\n },\n\n bio: {\n component: 'textarea',\n },\n\n marshmallows: {\n label: 'How many marshmallows fit in your mouth?',\n component: 'radio',\n },\n\n file: {\n label: 'Text file',\n component: 'file',\n },\n }\"\n @submit=\"onSubmit\"\n >\n <template #acceptTerms=\"slotProps\">\n <AutoFormField v-bind=\"slotProps\" />\n <div class=\"!mt-2 text-sm\">\n I agree to the <button class=\"text-primary underline\">\n terms and conditions\n </button>.\n </div>\n </template>\n\n <template #customParent=\"slotProps\">\n <div class=\"flex items-end space-x-2\">\n <AutoFormField v-bind=\"slotProps\" class=\"w-full\" />\n <Button type=\"button\">\n Check\n </Button>\n </div>\n </template>\n\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormConfirmPassword",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormConfirmPassword.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm } from '@/registry/new-york/ui/auto-form'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst schema = z\n .object({\n password: z.string(),\n confirm: z.string(),\n })\n .refine(data => data.password === data.confirm, {\n message: 'Passwords must match.',\n path: ['confirm'],\n })\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n @submit=\"onSubmit\"\n >\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormControlled",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormControlled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm } from '@/registry/new-york/ui/auto-form'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst schema = z.object({\n username: z.string(),\n})\n\nconst form = useForm({\n validationSchema: toTypedSchema(schema),\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n :form=\"form\"\n @submit=\"onSubmit\"\n >\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormDependencies",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormDependencies.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm } from '@/registry/new-york/ui/auto-form'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { h } from 'vue'\nimport * as z from 'zod'\nimport { DependencyType } from '../ui/auto-form/interface'\n\nconst schema = z.object({\n age: z.number(),\n parentsAllowed: z.boolean().optional(),\n vegetarian: z.boolean().optional(),\n mealOptions: z.enum(['Pasta', 'Salad', 'Beef Wellington']).optional(),\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n :field-config=\"{\n age: {\n description:\n 'Setting this below 18 will require parents consent.',\n },\n parentsAllowed: {\n label: 'Did your parents allow you to register?',\n },\n vegetarian: {\n label: 'Are you a vegetarian?',\n description:\n 'Setting this to true will remove non-vegetarian food options.',\n },\n mealOptions: {\n component: 'radio',\n },\n }\"\n :dependencies=\"[\n {\n sourceField: 'age',\n type: DependencyType.HIDES,\n targetField: 'parentsAllowed',\n when: (age) => age >= 18,\n },\n {\n sourceField: 'age',\n type: DependencyType.REQUIRES,\n targetField: 'parentsAllowed',\n when: (age) => age < 18,\n },\n {\n sourceField: 'vegetarian',\n type: DependencyType.SETS_OPTIONS,\n targetField: 'mealOptions',\n when: (vegetarian) => vegetarian,\n options: ['Pasta', 'Salad'],\n },\n ]\"\n @submit=\"onSubmit\"\n >\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormInputWithoutLabel",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormInputWithoutLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm, AutoFormField } from '@/registry/new-york/ui/auto-form'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst schema = z.object({\n username: z.string(),\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n :field-config=\"{\n username: {\n hideLabel: true,\n },\n }\"\n @submit=\"onSubmit\"\n >\n <template #username=\"slotProps\">\n <div class=\"flex items-center gap-3\">\n <div class=\"flex-1\">\n <AutoFormField v-bind=\"slotProps\" />\n </div>\n <div>\n <Button type=\"submit\">\n Update\n </Button>\n </div>\n </div>\n </template>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormSubObject",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormSubObject.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm } from '@/registry/new-york/ui/auto-form'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst schema = z.object({\n subObject: z.object({\n subField: z.string().optional().default('Sub Field'),\n numberField: z.number().optional().default(1),\n\n subSubObject: z\n .object({\n subSubField: z.string().default('Sub Sub Field'),\n })\n .describe('Sub Sub Object Description'),\n }),\n optionalSubObject: z\n .object({\n optionalSubField: z.string(),\n otherOptionalSubField: z.string(),\n })\n .optional(),\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n :field-config=\"{\n subObject: {\n numberField: {\n inputProps: {\n type: 'number',\n },\n },\n },\n }\"\n @submit=\"onSubmit\"\n >\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AvatarDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"avatar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AvatarDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback, AvatarImage } from '@/registry/new-york/ui/avatar'\n</script>\n\n<template>\n <Avatar>\n <AvatarImage src=\"https://github.com/unovue.png\" alt=\"@unovue\" />\n <AvatarFallback>CN</AvatarFallback>\n </Avatar>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BadgeDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BadgeDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Badge } from '@/registry/new-york/ui/badge'\n</script>\n\n<template>\n <Badge>Badge</Badge>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BadgeDestructiveDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BadgeDestructiveDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Badge } from '@/registry/new-york/ui/badge'\n</script>\n\n<template>\n <Badge variant=\"destructive\">\n Destructive\n </Badge>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BadgeOutlineDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BadgeOutlineDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Badge } from '@/registry/new-york/ui/badge'\n</script>\n\n<template>\n <Badge variant=\"outline\">\n Outline\n </Badge>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BadgeSecondaryDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BadgeSecondaryDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Badge } from '@/registry/new-york/ui/badge'\n</script>\n\n<template>\n <Badge variant=\"secondary\">\n Secondary\n </Badge>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BarChartCustomTooltip",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-bar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BarChartCustomTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { BarChart } from '@/registry/new-york/ui/chart-bar'\nimport CustomChartTooltip from './CustomChartTooltip.vue'\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 { name: 'Jul', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n]\n</script>\n\n<template>\n <BarChart\n :data=\"data\"\n index=\"name\"\n :categories=\"['total', 'predicted']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n :custom-tooltip=\"CustomChartTooltip\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BarChartDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-bar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BarChartDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { BarChart } from '@/registry/new-york/ui/chart-bar'\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 { name: 'Jul', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n]\n</script>\n\n<template>\n <BarChart\n :data=\"data\"\n index=\"name\"\n :categories=\"['total', 'predicted']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BarChartRounded",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-bar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BarChartRounded.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { BarChart } from '@/registry/new-york/ui/chart-bar'\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 { name: 'Jul', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n]\n</script>\n\n<template>\n <BarChart\n index=\"name\"\n :data=\"data\"\n :categories=\"['total', 'predicted']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n :rounded-corners=\"4\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BarChartStacked",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-bar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BarChartStacked.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { BarChart } from '@/registry/new-york/ui/chart-bar'\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 { name: 'Jul', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n]\n</script>\n\n<template>\n <BarChart\n index=\"name\"\n :data=\"data\"\n :categories=\"['total', 'predicted']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n :type=\"'stacked'\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BreadcrumbDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BreadcrumbDemo.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n</script>\n\n<template>\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink href=\"/\">\n Home\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <DropdownMenu>\n <DropdownMenuTrigger class=\"flex items-center gap-1\">\n <BreadcrumbEllipsis class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n <DropdownMenuItem>Documentation</DropdownMenuItem>\n <DropdownMenuItem>Themes</DropdownMenuItem>\n <DropdownMenuItem>GitHub</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink href=\"/docs/components/accordion.html\">\n Components\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BreadcrumbDropdown",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BreadcrumbDropdown.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\nimport { ChevronDownIcon, SlashIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink href=\"/\">\n Home\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator>\n <SlashIcon />\n </BreadcrumbSeparator>\n <BreadcrumbItem>\n <DropdownMenu>\n <DropdownMenuTrigger class=\"flex items-center gap-1\">\n Components\n <ChevronDownIcon class=\"h-4 w-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n <DropdownMenuItem>Documentation</DropdownMenuItem>\n <DropdownMenuItem>Themes</DropdownMenuItem>\n <DropdownMenuItem>GitHub</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </BreadcrumbItem>\n <BreadcrumbSeparator>\n <SlashIcon />\n </BreadcrumbSeparator>\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BreadcrumbEllipsisDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BreadcrumbEllipsisDemo.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\n</script>\n\n<template>\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"/\">\n Home\n </a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbEllipsis />\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"/docs/components/accordion.html\">\n Components\n </a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BreadcrumbLinkDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BreadcrumbLinkDemo.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\n</script>\n\n<template>\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink>\n <a href=\"/\">\n Home\n </a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink>\n <a href=\"/docs/components/accordion.html\">\n Components\n </a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BreadcrumbResponsive",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"button",
|
|
"drawer",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BreadcrumbResponsive.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from '@/registry/new-york/ui/drawer'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\nimport { useMediaQuery } from '@vueuse/core'\nimport { computed, ref } from 'vue'\n\nconst isDesktop = useMediaQuery('(min-width: 768px)')\nconst isOpen = ref(false)\nconst items = ref([\n { href: '#', label: 'Home' },\n { href: '#', label: 'Documentation' },\n { href: '#', label: 'Building Your Application' },\n { href: '#', label: 'Data Fetching' },\n { label: 'Caching and Revalidating' },\n])\n\nconst itemsToDisplay = 3\nconst firstLabel = computed(() => items.value[0]?.label)\n\nconst allButLastTwoItems = computed(() => items.value.slice(1, -2))\nconst remainingItems = computed(() => items.value.slice(-itemsToDisplay + 1))\n</script>\n\n<template>\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink href=\"{items[0].href}\">\n {{ firstLabel }}\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <template v-if=\"items.length > itemsToDisplay\">\n <BreadcrumbItem>\n <DropdownMenu v-if=\"isDesktop\" v-model:open=\"isOpen\">\n <DropdownMenuTrigger\n class=\"flex items-center gap-1\"\n aria-label=\"Toggle menu\"\n >\n <BreadcrumbEllipsis class=\"h-4 w-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n <DropdownMenuItem v-for=\"item of allButLastTwoItems\" :key=\"item.label\">\n <a :href=\"item.href || '#'\">\n {{ item.label }}\n </a>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n <Drawer v-else v-model:open=\"isOpen\">\n <DrawerTrigger aria-label=\"Toggle Menu\">\n <BreadcrumbEllipsis class=\"h-4 w-4\" />\n </DrawerTrigger>\n <DrawerContent>\n <DrawerHeader class=\"text-left\">\n <DrawerTitle>Navigate to</DrawerTitle>\n <DrawerDescription>\n Select a page to navigate to.\n </DrawerDescription>\n </DrawerHeader>\n <div class=\"grid gap-1 px-4\">\n <a\n v-for=\"item of allButLastTwoItems\"\n :key=\"item.label\"\n :href=\"item.href\"\n class=\"py-1 text-sm\"\n >\n {{ item.label }}\n </a>\n </div>\n <DrawerFooter class=\"pt-4\">\n <DrawerClose as-child>\n <Button variant=\"outline\">\n Close\n </Button>\n </DrawerClose>\n </DrawerFooter>\n </DrawerContent>\n </Drawer>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n </template>\n <BreadcrumbItem v-for=\" item of remainingItems\" :key=\"item.label\">\n <template v-if=\"item.href\">\n <BreadcrumbLink\n as-child\n class=\"max-w-20 truncate md:max-w-none\"\n >\n <a :href=\"item.href\">\n {{ item.label }}\n </a>\n </BreadcrumbLink>\n <BreadcrumbSeparator />\n </template>\n <BreadcrumbPage v-else class=\"max-w-20 truncate md:max-w-none\">\n {{ item.label }}\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BreadcrumbSeparatorDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BreadcrumbSeparatorDemo.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { SlashIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink href=\"/\">\n Home\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator>\n <SlashIcon />\n </BreadcrumbSeparator>\n <BreadcrumbItem>\n <BreadcrumbLink href=\"/docs/components/accordion.html\">\n Components\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator>\n <SlashIcon />\n </BreadcrumbSeparator>\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonAsChildDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonAsChildDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\n</script>\n\n<template>\n <Button as-child>\n <a href=\"/login\">\n Login\n </a>\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\n</script>\n\n<template>\n <Button>Button</Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonDestructiveDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonDestructiveDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\n</script>\n\n<template>\n <Button variant=\"destructive\">\n Destructive\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonGhostDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonGhostDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\n</script>\n\n<template>\n <Button variant=\"ghost\">\n Ghost\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonIconDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonIconDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { ChevronRightIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Button variant=\"outline\" size=\"icon\">\n <ChevronRightIcon class=\"w-4 h-4\" />\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonLinkDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonLinkDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\n</script>\n\n<template>\n <Button variant=\"link\">\n Link\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonLoadingDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonLoadingDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { ReloadIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Button disabled>\n <ReloadIcon class=\"w-4 h-4 mr-2 animate-spin\" />\n Please wait\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonOutlineDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonOutlineDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\n</script>\n\n<template>\n <Button variant=\"outline\">\n Outline\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonSecondaryDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonSecondaryDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\n</script>\n\n<template>\n <Button variant=\"secondary\">\n Secondary\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonWithIconDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonWithIconDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { EnvelopeOpenIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Button>\n <EnvelopeOpenIcon class=\"w-4 h-4 mr-2\" /> Login with Email\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CalendarDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CalendarDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Calendar } from '@/registry/new-york/ui/calendar'\nimport { type DateValue, getLocalTimeZone, today } from '@internationalized/date'\nimport { type Ref, ref } from 'vue'\n\nconst value = ref(today(getLocalTimeZone())) as Ref<DateValue>\n</script>\n\n<template>\n <Calendar v-model=\"value\" :weekday-format=\"'short'\" class=\"rounded-md border\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CalendarForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"calendar",
|
|
"form",
|
|
"popover",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CalendarForm.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CalendarWithSelect",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core",
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"calendar",
|
|
"select"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CalendarWithSelect.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CardChat",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"avatar",
|
|
"button",
|
|
"card",
|
|
"command",
|
|
"dialog",
|
|
"input",
|
|
"tooltip"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CardChat.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Avatar, AvatarFallback, AvatarImage } from '@/registry/new-york/ui/avatar'\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Card,\n CardContent,\n CardFooter,\n CardHeader,\n} from '@/registry/new-york/ui/card'\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/registry/new-york/ui/command'\n\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/registry/new-york/ui/dialog'\nimport { Input } from '@/registry/new-york/ui/input'\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@/registry/new-york/ui/tooltip'\nimport { CheckIcon, PaperPlaneIcon, PlusIcon } from '@radix-icons/vue'\nimport { computed, ref } from 'vue'\n\nconst input = ref('')\nconst inputLength = computed(() => input.value.trim().length)\nconst users = ref([\n {\n name: 'Olivia Martin',\n email: 'm@example.com',\n avatar: '/avatars/01.png',\n },\n {\n name: 'Isabella Nguyen',\n email: 'isabella.nguyen@email.com',\n avatar: '/avatars/03.png',\n },\n {\n name: 'Emma Wilson',\n email: 'emma@example.com',\n avatar: '/avatars/05.png',\n },\n {\n name: 'Jackson Lee',\n email: 'lee@example.com',\n avatar: '/avatars/02.png',\n },\n {\n name: 'William Kim',\n email: 'will@email.com',\n avatar: '/avatars/04.png',\n },\n])\n\ntype User = (typeof users.value)[number]\n\nconst messages = ref([\n { role: 'agent', content: 'Hi, how can I help you today?' },\n { role: 'user', content: 'Hey, I\\'m having trouble with my account.' },\n { role: 'agent', content: 'What seems to be the problem?' },\n { role: 'user', content: 'I can\\'t log in.' },\n])\n\nconst open = ref(false)\nconst selectedUsers = ref<User[]>([])\n</script>\n\n<template>\n <Card>\n <CardHeader class=\"flex flex-row items-center justify-between\">\n <div class=\"flex items-center space-x-4\">\n <Avatar>\n <AvatarImage src=\"/avatars/01.png\" alt=\"Image\" />\n <AvatarFallback>OM</AvatarFallback>\n </Avatar>\n <div>\n <p class=\"text-sm font-medium leading-none\">\n Sofia Davis\n </p>\n <p class=\"text-sm text-muted-foreground\">\n m@example.com\n </p>\n </div>\n </div>\n <TooltipProvider>\n <Tooltip :delay-duration=\"200\">\n <TooltipTrigger as-child>\n <Button\n variant=\"outline\"\n class=\"rounded-full p-2.5 flex items-center justify-center\"\n @click=\"open = true\"\n >\n <PlusIcon class=\"w-4 h-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent :side-offset=\"10\">\n New message\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </CardHeader>\n <CardContent>\n <div class=\"space-y-4\">\n <div\n v-for=\"(message, index) in messages\"\n :key=\"index\"\n :class=\"cn(\n 'flex w-max max-w-[75%] flex-col gap-2 rounded-lg px-3 py-2 text-sm',\n message.role === 'user' ? 'ml-auto bg-primary text-primary-foreground' : 'bg-muted',\n )\"\n >\n {{ message.content }}\n </div>\n </div>\n </CardContent>\n <CardFooter>\n <form\n class=\"flex w-full items-center space-x-2\"\n @submit.prevent=\"() => {\n if (inputLength === 0) return\n messages.push({\n role: 'user',\n content: input,\n })\n }\"\n >\n <Input v-model=\"input\" placeholder=\"Type a message...\" class=\"flex-1\" />\n <Button class=\"p-2.5 flex items-center justify-center\" :disabled=\"inputLength === 0\">\n <PaperPlaneIcon class=\"w-4 h-4\" />\n <span class=\"sr-only\">Send</span>\n </Button>\n </form>\n </CardFooter>\n </Card>\n\n <Dialog v-model:open=\"open\">\n <DialogContent class=\"gap-0 p-0 outline-none\">\n <DialogHeader class=\"px-4 pb-4 pt-5\">\n <DialogTitle>New message</DialogTitle>\n <DialogDescription>\n Invite a user to this thread. This will create a new group\n message.\n </DialogDescription>\n </DialogHeader>\n <Command class=\"overflow-hidden rounded-t-none border-t\">\n <CommandInput placeholder=\"Search user...\" />\n <CommandList>\n <CommandEmpty>No users found.</CommandEmpty>\n <CommandGroup class=\"p-2\">\n <CommandItem\n v-for=\"user in users\"\n :key=\"user.email\"\n :value=\"user\"\n class=\"flex items-center px-2\"\n @select=\"() => {\n const index = selectedUsers.findIndex(u => u === user)\n if (index !== -1) {\n selectedUsers.splice(index, 1)\n }\n else {\n selectedUsers.push(user)\n }\n }\"\n >\n <Avatar>\n <AvatarImage :src=\"user.avatar\" alt=\"Image\" />\n <AvatarFallback>{{ user.name[0] }}</AvatarFallback>\n </Avatar>\n <div class=\"ml-2\">\n <p class=\"text-sm font-medium leading-none\">\n {{ user.name }}\n </p>\n <p class=\"text-sm text-muted-foreground\">\n {{ user.email }}\n </p>\n </div>\n <CheckIcon v-if=\"selectedUsers.includes(user)\" class=\"ml-auto flex h-5 w-5 text-primary\" />\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n <DialogFooter class=\"flex items-center border-t p-4 sm:justify-between\">\n <div v-if=\"selectedUsers.length > 0\" class=\"flex -space-x-2 overflow-hidden\">\n <Avatar\n v-for=\"user in selectedUsers\"\n :key=\"user.email\"\n class=\"inline-block border-2 border-background\"\n >\n <AvatarImage :src=\"user.avatar\" />\n <AvatarFallback>{{ user.name[0] }}</AvatarFallback>\n </Avatar>\n </div>\n\n <p v-else class=\"text-sm text-muted-foreground\">\n Select users to add to this thread.\n </p>\n\n <Button\n :disabled=\"selectedUsers.length < 2\"\n @click=\"open = false\"\n >\n Continue\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CardDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"card",
|
|
"switch"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CardDemo.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CardFormDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card",
|
|
"input",
|
|
"label",
|
|
"select"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CardFormDemo.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 { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/new-york/ui/select'\n</script>\n\n<template>\n <Card class=\"w-[350px]\">\n <CardHeader>\n <CardTitle>Create project</CardTitle>\n <CardDescription>Deploy your new project in one-click.</CardDescription>\n </CardHeader>\n <CardContent>\n <form>\n <div class=\"grid items-center w-full gap-4\">\n <div class=\"flex flex-col space-y-1.5\">\n <Label for=\"name\">Name</Label>\n <Input id=\"name\" placeholder=\"Name of your project\" />\n </div>\n <div class=\"flex flex-col space-y-1.5\">\n <Label for=\"framework\">Framework</Label>\n <Select>\n <SelectTrigger id=\"framework\">\n <SelectValue placeholder=\"Select\" />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectItem value=\"nuxt\">\n Nuxt\n </SelectItem>\n <SelectItem value=\"next\">\n Next.js\n </SelectItem>\n <SelectItem value=\"sveltekit\">\n SvelteKit\n </SelectItem>\n <SelectItem value=\"astro\">\n Astro\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n </form>\n </CardContent>\n <CardFooter class=\"flex justify-between px-6 pb-6\">\n <Button variant=\"outline\">\n Cancel\n </Button>\n <Button>Deploy</Button>\n </CardFooter>\n </Card>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CardStats",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts"
|
|
],
|
|
"registryDependencies": [
|
|
"card",
|
|
"chart-bar",
|
|
"chart-line"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CardStats.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent, CardHeader, CardTitle } from '@/registry/new-york/ui/card'\nimport { BarChart } from '@/registry/new-york/ui/chart-bar'\nimport { LineChart } from '@/registry/new-york/ui/chart-line'\nimport { VisScatter } from '@unovis/vue'\n\ntype Data = typeof data[number]\nconst data = [\n { revenue: 10400, subscription: 240 },\n { revenue: 14405, subscription: 300 },\n { revenue: 9400, subscription: 200 },\n { revenue: 8200, subscription: 278 },\n { revenue: 7000, subscription: 189 },\n { revenue: 9600, subscription: 239 },\n { revenue: 11244, subscription: 278 },\n { revenue: 26475, subscription: 189 },\n]\n</script>\n\n<template>\n <div class=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-2\">\n <Card>\n <CardHeader class=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle class=\"text-sm font-normal\">\n Total Revenue\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div class=\"text-2xl font-bold\">\n $15,231.89\n </div>\n <p class=\"text-xs text-muted-foreground\">\n +20.1% from last month\n </p>\n\n <div class=\"h-20\">\n <LineChart\n class=\"h-[80px]\"\n :data=\"data\"\n :margin=\"{ top: 5, right: 10, left: 10, bottom: 0 }\"\n :categories=\"['revenue']\"\n :index=\"'revenue'\"\n :show-grid-line=\"false\"\n :show-legend=\"false\"\n :show-tooltip=\"false\"\n :show-x-axis=\"false\"\n :show-y-axis=\"false\"\n >\n <VisScatter\n color=\"white\"\n stroke-color=\"hsl(var(--primary))\"\n :x=\"(d: Data, i: number) => i\"\n :y=\"(d: Data) => d.revenue\"\n :size=\"6\"\n :stroke-width=\"2\"\n />\n </LineChart>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader class=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle class=\"text-sm font-normal\">\n Subscriptions\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div class=\"text-2xl font-bold\">\n +2350\n </div>\n <p class=\"text-xs text-muted-foreground\">\n +54.8% from last month\n </p>\n\n <div class=\"mt-4 h-20\">\n <BarChart\n class=\"h-[80px]\"\n :data=\"data\"\n :categories=\"['subscription']\"\n :index=\"'subscription'\"\n :show-grid-line=\"false\"\n :show-legend=\"false\"\n :show-x-axis=\"false\"\n :show-y-axis=\"false\"\n :show-tooltip=\"false\"\n />\n <!-- <VisXYContainer\n height=\"80px\" :data=\"data\"\n >\n <VisStackedBar\n :x=\"(d: Data, i:number) => i\"\n :y=\"(d: Data) => d.subscription\"\n :bar-padding=\"0.1\"\n :rounded-corners=\"0\" color=\"hsl(var(--primary))\"\n />\n </VisXYContainer> -->\n </div>\n </CardContent>\n </Card>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CardWithForm",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card",
|
|
"input",
|
|
"label",
|
|
"select"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CardWithForm.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 { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/new-york/ui/select'\n</script>\n\n<template>\n <Card class=\"w-[350px]\">\n <CardHeader>\n <CardTitle>Create project</CardTitle>\n <CardDescription>Deploy your new project in one-click.</CardDescription>\n </CardHeader>\n <CardContent>\n <form>\n <div class=\"grid w-full items-center gap-4\">\n <div class=\"flex flex-col space-y-1.5\">\n <Label for=\"name\">Name</Label>\n <Input id=\"name\" placeholder=\"Name of your project\" />\n </div>\n <div class=\"flex flex-col space-y-1.5\">\n <Label for=\"framework\">Framework</Label>\n <Select>\n <SelectTrigger id=\"framework\">\n <SelectValue placeholder=\"Select\" />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectItem value=\"next\">\n Next.js\n </SelectItem>\n <SelectItem value=\"sveltekit\">\n SvelteKit\n </SelectItem>\n <SelectItem value=\"astro\">\n Astro\n </SelectItem>\n <SelectItem value=\"nuxt\">\n Nuxt\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n </form>\n </CardContent>\n <CardFooter class=\"flex justify-between\">\n <Button variant=\"outline\">\n Cancel\n </Button>\n <Button>Deploy</Button>\n </CardFooter>\n </Card>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselApi",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"carousel",
|
|
"card"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselApi.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { CarouselApi } from '@/registry/new-york/ui/carousel'\nimport { Card, CardContent } from '@/registry/new-york/ui/card'\nimport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/new-york/ui/carousel'\nimport { watchOnce } from '@vueuse/core'\nimport { ref } from 'vue'\n\nconst api = ref<CarouselApi>()\nconst totalCount = ref(0)\nconst current = ref(0)\n\nfunction setApi(val: CarouselApi) {\n api.value = val\n}\n\nwatchOnce(api, (api) => {\n if (!api)\n return\n\n totalCount.value = api.scrollSnapList().length\n current.value = api.selectedScrollSnap() + 1\n\n api.on('select', () => {\n current.value = api.selectedScrollSnap() + 1\n })\n})\n</script>\n\n<template>\n <div class=\"w-full sm:w-auto\">\n <Carousel class=\"relative w-full max-w-xs\" @init-api=\"setApi\">\n <CarouselContent>\n <CarouselItem v-for=\"(_, index) in 5\" :key=\"index\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-4xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n\n <div class=\"py-2 text-center text-sm text-muted-foreground\">\n Slide {{ current }} of {{ totalCount }}\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"card",
|
|
"carousel"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/new-york/ui/card'\nimport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/new-york/ui/carousel'\n</script>\n\n<template>\n <Carousel class=\"relative w-full max-w-xs\">\n <CarouselContent>\n <CarouselItem v-for=\"(_, index) in 5\" :key=\"index\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-4xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselOrientation",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"card",
|
|
"carousel"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselOrientation.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/new-york/ui/card'\nimport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/new-york/ui/carousel'\n</script>\n\n<template>\n <Carousel\n orientation=\"vertical\"\n class=\"relative w-full max-w-xs\"\n :opts=\"{\n align: 'start',\n }\"\n >\n <CarouselContent class=\"-mt-1 h-[200px]\">\n <CarouselItem v-for=\"(_, index) in 5\" :key=\"index\" class=\"p-1 md:basis-1/2\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex items-center justify-center p-6\">\n <span class=\"text-3xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselPlugin",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"card",
|
|
"carousel"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselPlugin.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/new-york/ui/card'\nimport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/new-york/ui/carousel'\nimport Autoplay from 'embla-carousel-autoplay'\n\nconst plugin = Autoplay({\n delay: 2000,\n stopOnMouseEnter: true,\n stopOnInteraction: false,\n})\n</script>\n\n<template>\n <Carousel\n class=\"relative w-full max-w-xs\"\n :plugins=\"[plugin]\"\n @mouseenter=\"plugin.stop\"\n @mouseleave=\"[plugin.reset(), plugin.play(), console.log('Running')];\"\n >\n <CarouselContent>\n <CarouselItem v-for=\"(_, index) in 5\" :key=\"index\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-4xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselSize",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"card",
|
|
"carousel"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselSize.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/new-york/ui/card'\nimport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/new-york/ui/carousel'\n</script>\n\n<template>\n <Carousel\n class=\"relative w-full max-w-xs\"\n :opts=\"{\n align: 'start',\n }\"\n >\n <CarouselContent>\n <CarouselItem v-for=\"(_, index) in 5\" :key=\"index\" class=\"md:basis-1/2 lg:basis-1/3\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-3xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselSpacing",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"card",
|
|
"carousel"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselSpacing.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/new-york/ui/card'\nimport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/new-york/ui/carousel'\n</script>\n\n<template>\n <Carousel\n class=\"w-full max-w-sm\"\n :opts=\"{\n align: 'start',\n }\"\n >\n <CarouselContent class=\"-ml-1\">\n <CarouselItem v-for=\"(_, index) in 5\" :key=\"index\" class=\"pl-1 md:basis-1/2 lg:basis-1/3\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-2xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselThumbnails",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"card",
|
|
"carousel"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselThumbnails.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/new-york/ui/card'\nimport { Carousel, type CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/new-york/ui/carousel'\nimport { watchOnce } from '@vueuse/core'\nimport { ref } from 'vue'\n\nconst emblaMainApi = ref<CarouselApi>()\nconst emblaThumbnailApi = ref<CarouselApi>()\nconst selectedIndex = ref(0)\n\nfunction onSelect() {\n if (!emblaMainApi.value || !emblaThumbnailApi.value)\n return\n selectedIndex.value = emblaMainApi.value.selectedScrollSnap()\n emblaThumbnailApi.value.scrollTo(emblaMainApi.value.selectedScrollSnap())\n}\n\nfunction onThumbClick(index: number) {\n if (!emblaMainApi.value || !emblaThumbnailApi.value)\n return\n emblaMainApi.value.scrollTo(index)\n}\n\nwatchOnce(emblaMainApi, (emblaMainApi) => {\n if (!emblaMainApi)\n return\n\n onSelect()\n emblaMainApi.on('select', onSelect)\n emblaMainApi.on('reInit', onSelect)\n})\n</script>\n\n<template>\n <div class=\"w-full sm:w-auto\">\n <Carousel\n class=\"relative w-full max-w-xs\"\n @init-api=\"(val) => emblaMainApi = val\"\n >\n <CarouselContent>\n <CarouselItem v-for=\"(_, index) in 10\" :key=\"index\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-4xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n\n <Carousel\n class=\"relative w-full max-w-xs\"\n @init-api=\"(val) => emblaThumbnailApi = val\"\n >\n <CarouselContent class=\"flex gap-1 ml-0\">\n <CarouselItem v-for=\"(_, index) in 10\" :key=\"index\" class=\"pl-0 basis-1/4 cursor-pointer\" @click=\"onThumbClick(index)\">\n <div class=\"p-1\" :class=\"index === selectedIndex ? '' : 'opacity-50'\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-4xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n </Carousel>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CheckboxDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"checkbox"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CheckboxDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@/registry/new-york/ui/checkbox'\n</script>\n\n<template>\n <div class=\"flex items-center space-x-2\">\n <Checkbox id=\"terms\" />\n <label\n for=\"terms\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Accept terms and conditions\n </label>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CheckboxDisabled",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"checkbox"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CheckboxDisabled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@/registry/new-york/ui/checkbox'\n</script>\n\n<template>\n <div class=\"items-top flex space-x-2\">\n <Checkbox id=\"terms1\" disabled />\n <label\n for=\"terms2\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Accept terms and conditions\n </label>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CheckboxFormMultiple",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"checkbox",
|
|
"form",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CheckboxFormMultiple.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Checkbox } from '@/registry/new-york/ui/checkbox'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/new-york/ui/form'\nimport { toast } from '@/registry/new-york/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst items = [\n {\n id: 'recents',\n label: 'Recents',\n },\n {\n id: 'home',\n label: 'Home',\n },\n {\n id: 'applications',\n label: 'Applications',\n },\n {\n id: 'desktop',\n label: 'Desktop',\n },\n {\n id: 'downloads',\n label: 'Downloads',\n },\n {\n id: 'documents',\n label: 'Documents',\n },\n] as const\n\nconst formSchema = toTypedSchema(z.object({\n items: z.array(z.string()).refine(value => value.some(item => item), {\n message: 'You have to select at least one item.',\n }),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n initialValues: {\n items: ['recents', 'home'],\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 @submit=\"onSubmit\">\n <FormField name=\"items\">\n <FormItem>\n <div class=\"mb-4\">\n <FormLabel class=\"text-base\">\n Sidebar\n </FormLabel>\n <FormDescription>\n Select the items you want to display in the sidebar.\n </FormDescription>\n </div>\n\n <FormField v-for=\"item in items\" v-slot=\"{ value, handleChange }\" :key=\"item.id\" type=\"checkbox\" :value=\"item.id\" :unchecked-value=\"false\" name=\"items\">\n <FormItem class=\"flex flex-row items-start space-x-3 space-y-0\">\n <FormControl>\n <Checkbox\n :model-value=\"value.includes(item.id)\"\n @update:model-value=\"handleChange\"\n />\n </FormControl>\n <FormLabel class=\"font-normal\">\n {{ item.label }}\n </FormLabel>\n </FormItem>\n </FormField>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <div class=\"flex justify-start mt-4\">\n <Button type=\"submit\">\n Submit\n </Button>\n </div>\n </form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CheckboxFormSingle",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"checkbox",
|
|
"form",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CheckboxFormSingle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Checkbox } from '@/registry/new-york/ui/checkbox'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/new-york/ui/form'\nimport { toast } from '@/registry/new-york/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n mobile: z.boolean().default(false).optional(),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n initialValues: {\n mobile: true,\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 v-slot=\"{ value, handleChange }\" type=\"checkbox\" name=\"mobile\">\n <FormItem class=\"flex flex-row items-start gap-x-3 space-y-0 rounded-md border p-4 shadow\">\n <FormControl>\n <Checkbox :model-value=\"value\" @update:model-value=\"handleChange\" />\n </FormControl>\n <div class=\"space-y-1 leading-none\">\n <FormLabel>Use different settings for my mobile devices</FormLabel>\n <FormDescription>\n You can manage your mobile notifications in the\n <a href=\"/examples/forms\">mobile settings</a> page.\n </FormDescription>\n <FormMessage />\n </div>\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CheckboxWithText",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"checkbox"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CheckboxWithText.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@/registry/new-york/ui/checkbox'\n</script>\n\n<template>\n <div class=\"items-top flex gap-x-2\">\n <Checkbox id=\"terms1\" />\n <div class=\"grid gap-1.5 leading-none\">\n <label\n for=\"terms1\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Accept terms and conditions\n </label>\n <p class=\"text-sm text-muted-foreground\">\n You agree to our Terms of Service and Privacy Policy.\n </p>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CollapsibleDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"collapsible"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CollapsibleDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/new-york/ui/collapsible'\n\nimport { CaretSortIcon } from '@radix-icons/vue'\nimport { ref } from 'vue'\n\nconst isOpen = ref(false)\n</script>\n\n<template>\n <Collapsible\n v-model:open=\"isOpen\"\n class=\"w-[350px] space-y-2\"\n >\n <div class=\"flex items-center justify-between space-x-4 px-4\">\n <h4 class=\"text-sm font-semibold\">\n @peduarte starred 3 repositories\n </h4>\n <CollapsibleTrigger as-child>\n <Button variant=\"ghost\" size=\"sm\" class=\"w-9 p-0\">\n <CaretSortIcon class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle</span>\n </Button>\n </CollapsibleTrigger>\n </div>\n <div class=\"rounded-md border px-4 py-3 font-mono text-sm\">\n @radix-ui/primitives\n </div>\n <CollapsibleContent class=\"space-y-2\">\n <div class=\"rounded-md border px-4 py-3 font-mono text-sm\">\n @radix-ui/colors\n </div>\n <div class=\"rounded-md border px-4 py-3 font-mono text-sm\">\n @stitches/react\n </div>\n </CollapsibleContent>\n </Collapsible>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ComboboxDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"command",
|
|
"popover"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ComboboxDemo.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ComboboxDropdownMenu",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"command",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ComboboxDropdownMenu.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 DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\nimport { DotsHorizontalIcon } from '@radix-icons/vue'\nimport { ref } from 'vue'\n\nconst labels = [\n 'feature',\n 'bug',\n 'enhancement',\n 'documentation',\n 'design',\n 'question',\n 'maintenance',\n]\n\nconst labelRef = ref('feature')\nconst open = ref(false)\n</script>\n\n<template>\n <div class=\"flex w-full flex-col items-start justify-between rounded-md border px-4 py-3 sm:flex-row sm:items-center\">\n <p class=\"text-sm font-medium leading-none\">\n <span class=\"mr-2 rounded-lg bg-primary px-2 py-1 text-xs text-primary-foreground\">\n {{ labelRef }}\n </span>\n <span class=\"text-muted-foreground\">Create a new project</span>\n </p>\n <DropdownMenu v-model:open=\"open\">\n <DropdownMenuTrigger as-child>\n <Button variant=\"ghost\" size=\"sm\">\n <DotsHorizontalIcon />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" class=\"w-[200px]\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuGroup>\n <DropdownMenuItem>\n Assign to...\n </DropdownMenuItem>\n <DropdownMenuItem>\n Set due date...\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuSub>\n <DropdownMenuSubTrigger>\n Apply label\n </DropdownMenuSubTrigger>\n <DropdownMenuSubContent class=\"p-0\">\n <Command>\n <CommandInput\n placeholder=\"Filter label...\"\n auto-focus\n />\n <CommandList>\n <CommandEmpty>No label found.</CommandEmpty>\n <CommandGroup>\n <CommandItem\n v-for=\"label in labels\"\n :key=\"label\"\n :value=\"label\"\n @select=\"(ev) => {\n labelRef = ev.detail.value as string\n open = false\n }\"\n >\n {{ label }}\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n <DropdownMenuSeparator />\n <DropdownMenuItem class=\"text-red-600\">\n Delete\n <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ComboboxForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"command",
|
|
"form",
|
|
"popover",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ComboboxForm.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ComboboxPopover",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"command",
|
|
"popover"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ComboboxPopover.vue",
|
|
"content": "<script setup lang=\"ts\">\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 { ref } from 'vue'\n\ninterface Status {\n value: string\n label: string\n}\n\nconst statuses: Status[] = [\n {\n value: 'backlog',\n label: 'Backlog',\n },\n {\n value: 'todo',\n label: 'Todo',\n },\n {\n value: 'in progress',\n label: 'In Progress',\n },\n {\n value: 'done',\n label: 'Done',\n },\n {\n value: 'canceled',\n label: 'Canceled',\n },\n]\n\nconst open = ref(false)\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 {{ 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=\"() => {\n selectedStatus = status\n open = false\n }\"\n >\n {{ status.label }}\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ComboboxResponsive",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"command",
|
|
"drawer",
|
|
"popover"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ComboboxResponsive.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/registry/new-york/ui/command'\nimport { Drawer, DrawerContent, DrawerTrigger } from '@/registry/new-york/ui/drawer'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/new-york/ui/popover'\nimport { createReusableTemplate, useMediaQuery } from '@vueuse/core'\nimport { ref } from 'vue'\n\ninterface Status {\n value: string\n label: string\n}\n\nconst statuses: Status[] = [\n {\n value: 'backlog',\n label: 'Backlog',\n },\n {\n value: 'todo',\n label: 'Todo',\n },\n {\n value: 'in progress',\n label: 'In Progress',\n },\n {\n value: 'done',\n label: 'Done',\n },\n {\n value: 'canceled',\n label: 'Canceled',\n },\n]\n\nconst [UseTemplate, StatusList] = createReusableTemplate()\nconst isDesktop = useMediaQuery('(min-width: 768px)')\n\nconst isOpen = ref(false)\nconst selectedStatus = ref<Status | null>(null)\n\nfunction onStatusSelect(status: Status) {\n selectedStatus.value = status\n isOpen.value = false\n}\n</script>\n\n<template>\n <div>\n <UseTemplate>\n <Command>\n <CommandInput placeholder=\"Filter status...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup>\n <CommandItem\n v-for=\"status of statuses\"\n :key=\"status.value\"\n :value=\"status.value\"\n @select=\"onStatusSelect(status)\"\n >\n {{ status.label }}\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </UseTemplate>\n\n <Popover v-if=\"isDesktop\" v-model:open=\"isOpen\">\n <PopoverTrigger as-child>\n <Button variant=\"outline\" class=\"w-[150px] justify-start\">\n {{ selectedStatus ? selectedStatus.label : \"+ Set status\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-[200px] p-0\" align=\"start\">\n <StatusList />\n </PopoverContent>\n </Popover>\n\n <Drawer v-else v-model:open=\"isOpen\">\n <DrawerTrigger as-child>\n <Button variant=\"outline\" class=\"w-[150px] justify-start\">\n {{ selectedStatus ? selectedStatus.label : \"+ Set status\" }}\n </Button>\n </DrawerTrigger>\n <DrawerContent>\n <div class=\"mt-4 border-t\">\n <StatusList />\n </div>\n </DrawerContent>\n </Drawer>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CommandDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"command"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CommandDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n CommandShortcut,\n} from '@/registry/new-york/ui/command'\n\nimport {\n CalendarIcon,\n EnvelopeClosedIcon,\n FaceIcon,\n GearIcon,\n PersonIcon,\n RocketIcon,\n} from '@radix-icons/vue'\n</script>\n\n<template>\n <Command class=\"rounded-lg border shadow-md max-w-[450px]\">\n <CommandInput placeholder=\"Type a command or search...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup heading=\"Suggestions\">\n <CommandItem value=\"Calendar\">\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <span>Calendar</span>\n </CommandItem>\n <CommandItem value=\"Search Emoji\">\n <FaceIcon class=\"mr-2 h-4 w-4\" />\n <span>Search Emoji</span>\n </CommandItem>\n <CommandItem value=\"Launch\">\n <RocketIcon class=\"mr-2 h-4 w-4\" />\n <span>Launch</span>\n </CommandItem>\n </CommandGroup>\n <CommandSeparator />\n <CommandGroup heading=\"Settings\">\n <CommandItem value=\"Profile\">\n <PersonIcon class=\"mr-2 h-4 w-4\" />\n <span>Profile</span>\n <CommandShortcut>⌘P</CommandShortcut>\n </CommandItem>\n <CommandItem value=\"Mail\">\n <EnvelopeClosedIcon class=\"mr-2 h-4 w-4\" />\n <span>Mail</span>\n <CommandShortcut>⌘B</CommandShortcut>\n </CommandItem>\n <CommandItem value=\"Settings\">\n <GearIcon class=\"mr-2 h-4 w-4\" />\n <span>Settings</span>\n <CommandShortcut>⌘S</CommandShortcut>\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CommandDialogDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"command"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CommandDialogDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n} from '@/registry/new-york/ui/command'\n\nimport { useMagicKeys } from '@vueuse/core'\nimport { ref, watch } from 'vue'\n\nconst open = ref(false)\n\nconst { Meta_J, Ctrl_J } = useMagicKeys({\n passive: false,\n onEventFired(e) {\n if (e.key === 'j' && (e.metaKey || e.ctrlKey))\n e.preventDefault()\n },\n})\n\nwatch([Meta_J, Ctrl_J], (v) => {\n if (v[0] || v[1])\n handleOpenChange()\n})\n\nfunction handleOpenChange() {\n open.value = !open.value\n}\n</script>\n\n<template>\n <div>\n <p class=\"text-sm text-muted-foreground\">\n Press\n <kbd\n class=\"pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100\"\n >\n <span class=\"text-xs\">⌘</span>J\n </kbd>\n </p>\n <CommandDialog v-model:open=\"open\">\n <CommandInput placeholder=\"Type a command or search...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup heading=\"Suggestions\">\n <CommandItem value=\"calendar\">\n Calendar\n </CommandItem>\n <CommandItem value=\"search-emoji\">\n Search Emoji\n </CommandItem>\n <CommandItem value=\"calculator\">\n Calculator\n </CommandItem>\n </CommandGroup>\n <CommandSeparator />\n <CommandGroup heading=\"Settings\">\n <CommandItem value=\"profile\">\n Profile\n </CommandItem>\n <CommandItem value=\"billing\">\n Billing\n </CommandItem>\n <CommandItem value=\"settings\">\n Settings\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </CommandDialog>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ContextMenuDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"context-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ContextMenuDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenu,\n ContextMenuCheckboxItem,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuLabel,\n ContextMenuRadioGroup,\n ContextMenuRadioItem,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuTrigger,\n} from '@/registry/new-york/ui/context-menu'\n</script>\n\n<template>\n <ContextMenu>\n <ContextMenuTrigger class=\"flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm\">\n Right click here\n </ContextMenuTrigger>\n <ContextMenuContent class=\"w-64\">\n <ContextMenuItem inset>\n Back\n <ContextMenuShortcut>⌘[</ContextMenuShortcut>\n </ContextMenuItem>\n <ContextMenuItem inset disabled>\n Forward\n <ContextMenuShortcut>⌘]</ContextMenuShortcut>\n </ContextMenuItem>\n <ContextMenuItem inset>\n Reload\n <ContextMenuShortcut>⌘R</ContextMenuShortcut>\n </ContextMenuItem>\n <ContextMenuSub>\n <ContextMenuSubTrigger inset>\n More Tools\n </ContextMenuSubTrigger>\n <ContextMenuSubContent class=\"w-48\">\n <ContextMenuItem>\n Save Page As...\n <ContextMenuShortcut>⇧⌘S</ContextMenuShortcut>\n </ContextMenuItem>\n <ContextMenuItem>Create Shortcut...</ContextMenuItem>\n <ContextMenuItem>Name Window...</ContextMenuItem>\n <ContextMenuSeparator />\n <ContextMenuItem>Developer Tools</ContextMenuItem>\n </ContextMenuSubContent>\n </ContextMenuSub>\n <ContextMenuSeparator />\n <ContextMenuCheckboxItem checked>\n Show Bookmarks Bar\n <ContextMenuShortcut>⌘⇧B</ContextMenuShortcut>\n </ContextMenuCheckboxItem>\n <ContextMenuCheckboxItem>Show Full URLs</ContextMenuCheckboxItem>\n <ContextMenuSeparator />\n <ContextMenuRadioGroup model-value=\"pedro\">\n <ContextMenuLabel inset>\n People\n </ContextMenuLabel>\n <ContextMenuSeparator />\n <ContextMenuRadioItem value=\"pedro\">\n Pedro Duarte\n </ContextMenuRadioItem>\n <ContextMenuRadioItem value=\"colm\">\n Colm Tuite\n </ContextMenuRadioItem>\n </ContextMenuRadioGroup>\n </ContextMenuContent>\n </ContextMenu>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CustomChartTooltip",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"card"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CustomChartTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/new-york/ui/card'\n\ndefineProps<{\n title?: string\n data: {\n name: string\n color: string\n value: any\n }[]\n}>()\n</script>\n\n<template>\n <Card class=\"text-sm\">\n <CardContent class=\"p-3 min-w-[180px] flex flex-col gap-2\">\n <div v-for=\"(item, key) in data\" :key=\"key\" class=\"flex justify-between items-center\">\n <div class=\"flex items-center\">\n <span class=\"w-1 h-7 mr-4 rounded-full\" :style=\"{ background: item.color }\" />\n <span>{{ item.name }}</span>\n </div>\n <span class=\"font-semibold ml-4\">{{ item.value }}</span>\n </div>\n </CardContent>\n </Card>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DataTableColumnPinningDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@tanstack/vue-table"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"checkbox",
|
|
"dropdown-menu",
|
|
"input",
|
|
"table"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DataTableColumnPinningDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type {\n ColumnFiltersState,\n ExpandedState,\n SortingState,\n VisibilityState,\n} from '@tanstack/vue-table'\nimport { cn, valueUpdater } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\n\nimport { Checkbox } from '@/registry/new-york/ui/checkbox'\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\nimport { Input } from '@/registry/new-york/ui/input'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/new-york/ui/table'\nimport { CaretSortIcon, ChevronDownIcon } from '@radix-icons/vue'\nimport {\n createColumnHelper,\n FlexRender,\n getCoreRowModel,\n getExpandedRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useVueTable,\n} from '@tanstack/vue-table'\nimport { h, ref } from 'vue'\nimport DropdownAction from './DataTableDemoColumn.vue'\n\nexport interface Payment {\n id: string\n amount: number\n status: 'pending' | 'processing' | 'success' | 'failed'\n email: string\n}\n\nconst data: Payment[] = [\n {\n id: 'm5gr84i9',\n amount: 316,\n status: 'success',\n email: 'ken99@yahoo.com',\n },\n {\n id: '3u1reuv4',\n amount: 242,\n status: 'success',\n email: 'Abe45@gmail.com',\n },\n {\n id: 'derv1ws0',\n amount: 837,\n status: 'processing',\n email: 'Monserrat44@gmail.com',\n },\n {\n id: '5kma53ae',\n amount: 874,\n status: 'success',\n email: 'Silas22@gmail.com',\n },\n {\n id: 'bhqecj4p',\n amount: 721,\n status: 'failed',\n email: 'carmella@hotmail.com',\n },\n]\n\nconst columnHelper = createColumnHelper<Payment>()\n\nconst columns = [\n columnHelper.display({\n id: 'select',\n header: ({ table }) => h(Checkbox, {\n 'modelValue': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),\n 'onUpdate:modelValue': value => table.toggleAllPageRowsSelected(!!value),\n 'ariaLabel': 'Select all',\n }),\n cell: ({ row }) => {\n return h(Checkbox, {\n 'modelValue': row.getIsSelected(),\n 'onUpdate:modelValue': value => row.toggleSelected(!!value),\n 'ariaLabel': 'Select row',\n })\n },\n enableSorting: false,\n enableHiding: false,\n }),\n columnHelper.accessor('status', {\n enablePinning: true,\n header: 'Status',\n cell: ({ row }) => h('div', { class: 'capitalize' }, row.getValue('status')),\n }),\n columnHelper.accessor('email', {\n header: ({ column }) => {\n return h(Button, {\n variant: 'ghost',\n onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'),\n }, () => ['Email', h(CaretSortIcon, { class: 'ml-2 h-4 w-4' })])\n },\n cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),\n }),\n columnHelper.accessor('amount', {\n header: () => h('div', { class: 'text-right' }, 'Amount'),\n cell: ({ row }) => {\n const amount = Number.parseFloat(row.getValue('amount'))\n\n // Format the amount as a dollar amount\n const formatted = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n }).format(amount)\n\n return h('div', { class: 'text-right font-medium' }, formatted)\n },\n }),\n columnHelper.display({\n id: 'actions',\n enableHiding: false,\n cell: ({ row }) => {\n const payment = row.original\n\n return h('div', { class: 'relative' }, h(DropdownAction, {\n payment,\n onExpand: row.toggleExpanded,\n }))\n },\n }),\n]\n\nconst sorting = ref<SortingState>([])\nconst columnFilters = ref<ColumnFiltersState>([])\nconst columnVisibility = ref<VisibilityState>({})\nconst rowSelection = ref({})\nconst expanded = ref<ExpandedState>({})\n\nconst table = useVueTable({\n data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getExpandedRowModel: getExpandedRowModel(),\n onSortingChange: updaterOrValue => valueUpdater(updaterOrValue, sorting),\n onColumnFiltersChange: updaterOrValue => valueUpdater(updaterOrValue, columnFilters),\n onColumnVisibilityChange: updaterOrValue => valueUpdater(updaterOrValue, columnVisibility),\n onRowSelectionChange: updaterOrValue => valueUpdater(updaterOrValue, rowSelection),\n onExpandedChange: updaterOrValue => valueUpdater(updaterOrValue, expanded),\n state: {\n get sorting() { return sorting.value },\n get columnFilters() { return columnFilters.value },\n get columnVisibility() { return columnVisibility.value },\n get rowSelection() { return rowSelection.value },\n get expanded() { return expanded.value },\n columnPinning: {\n left: ['status'],\n },\n },\n})\n</script>\n\n<template>\n <div class=\"w-full\">\n <div class=\"flex gap-2 items-center py-4\">\n <Input\n class=\"max-w-sm\"\n placeholder=\"Filter emails...\"\n :model-value=\"table.getColumn('email')?.getFilterValue() as string\"\n @update:model-value=\" table.getColumn('email')?.setFilterValue($event)\"\n />\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\" class=\"ml-auto\">\n Columns <ChevronDownIcon class=\"ml-2 h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuCheckboxItem\n v-for=\"column in table.getAllColumns().filter((column) => column.getCanHide())\"\n :key=\"column.id\"\n class=\"capitalize\"\n :model-value=\"column.getIsVisible()\"\n @update:model-value=\"(value) => {\n column.toggleVisibility(!!value)\n }\"\n >\n {{ column.id }}\n </DropdownMenuCheckboxItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n <div class=\"rounded-md border\">\n <Table>\n <TableHeader>\n <TableRow v-for=\"headerGroup in table.getHeaderGroups()\" :key=\"headerGroup.id\">\n <TableHead\n v-for=\"header in headerGroup.headers\" :key=\"header.id\" :data-pinned=\"header.column.getIsPinned()\"\n :class=\"cn(\n { 'sticky bg-background/95': header.column.getIsPinned() },\n header.column.getIsPinned() === 'left' ? 'left-0' : 'right-0',\n )\"\n >\n <FlexRender v-if=\"!header.isPlaceholder\" :render=\"header.column.columnDef.header\" :props=\"header.getContext()\" />\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <template v-if=\"table.getRowModel().rows?.length\">\n <template v-for=\"row in table.getRowModel().rows\" :key=\"row.id\">\n <TableRow :data-state=\"row.getIsSelected() && 'selected'\">\n <TableCell\n v-for=\"cell in row.getVisibleCells()\" :key=\"cell.id\" :data-pinned=\"cell.column.getIsPinned()\"\n :class=\"cn(\n { 'sticky bg-background/95': cell.column.getIsPinned() },\n cell.column.getIsPinned() === 'left' ? 'left-0' : 'right-0',\n )\"\n >\n <FlexRender :render=\"cell.column.columnDef.cell\" :props=\"cell.getContext()\" />\n </TableCell>\n </TableRow>\n <TableRow v-if=\"row.getIsExpanded()\">\n <TableCell :colspan=\"row.getAllCells().length\">\n {{ JSON.stringify(row.original) }}\n </TableCell>\n </TableRow>\n </template>\n </template>\n\n <TableRow v-else>\n <TableCell\n :colspan=\"columns.length\"\n class=\"h-24 text-center\"\n >\n No results.\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </div>\n\n <div class=\"flex items-center justify-end space-x-2 py-4\">\n <div class=\"flex-1 text-sm text-muted-foreground\">\n {{ table.getFilteredSelectedRowModel().rows.length }} of\n {{ table.getFilteredRowModel().rows.length }} row(s) selected.\n </div>\n <div class=\"space-x-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"!table.getCanPreviousPage()\"\n @click=\"table.previousPage()\"\n >\n Previous\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"!table.getCanNextPage()\"\n @click=\"table.nextPage()\"\n >\n Next\n </Button>\n </div>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DataTableDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@tanstack/vue-table"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"checkbox",
|
|
"dropdown-menu",
|
|
"input",
|
|
"table"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DataTableDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type {\n ColumnDef,\n ColumnFiltersState,\n ExpandedState,\n SortingState,\n VisibilityState,\n} from '@tanstack/vue-table'\nimport { valueUpdater } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Checkbox } from '@/registry/new-york/ui/checkbox'\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n\nimport { Input } from '@/registry/new-york/ui/input'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/new-york/ui/table'\nimport { CaretSortIcon, ChevronDownIcon } from '@radix-icons/vue'\nimport {\n FlexRender,\n getCoreRowModel,\n getExpandedRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useVueTable,\n} from '@tanstack/vue-table'\nimport { h, ref } from 'vue'\nimport DropdownAction from './DataTableDemoColumn.vue'\n\nexport interface Payment {\n id: string\n amount: number\n status: 'pending' | 'processing' | 'success' | 'failed'\n email: string\n}\n\nconst data: Payment[] = [\n {\n id: 'm5gr84i9',\n amount: 316,\n status: 'success',\n email: 'ken99@yahoo.com',\n },\n {\n id: '3u1reuv4',\n amount: 242,\n status: 'success',\n email: 'Abe45@gmail.com',\n },\n {\n id: 'derv1ws0',\n amount: 837,\n status: 'processing',\n email: 'Monserrat44@gmail.com',\n },\n {\n id: '5kma53ae',\n amount: 874,\n status: 'success',\n email: 'Silas22@gmail.com',\n },\n {\n id: 'bhqecj4p',\n amount: 721,\n status: 'failed',\n email: 'carmella@hotmail.com',\n },\n]\n\nconst columns: ColumnDef<Payment>[] = [\n {\n id: 'select',\n header: ({ table }) => h(Checkbox, {\n 'modelValue': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),\n 'onUpdate:modelValue': value => table.toggleAllPageRowsSelected(!!value),\n 'ariaLabel': 'Select all',\n }),\n cell: ({ row }) => h(Checkbox, {\n 'modelValue': row.getIsSelected(),\n 'onUpdate:modelValue': value => row.toggleSelected(!!value),\n 'ariaLabel': 'Select row',\n }),\n enableSorting: false,\n enableHiding: false,\n },\n {\n accessorKey: 'status',\n header: 'Status',\n cell: ({ row }) => h('div', { class: 'capitalize' }, row.getValue('status')),\n },\n {\n accessorKey: 'email',\n header: ({ column }) => {\n return h(Button, {\n variant: 'ghost',\n onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'),\n }, () => ['Email', h(CaretSortIcon, { class: 'ml-2 h-4 w-4' })])\n },\n cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),\n },\n {\n accessorKey: 'amount',\n header: () => h('div', { class: 'text-right' }, 'Amount'),\n cell: ({ row }) => {\n const amount = Number.parseFloat(row.getValue('amount'))\n\n // Format the amount as a dollar amount\n const formatted = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n }).format(amount)\n\n return h('div', { class: 'text-right font-medium' }, formatted)\n },\n },\n {\n id: 'actions',\n enableHiding: false,\n cell: ({ row }) => {\n const payment = row.original\n\n return h(DropdownAction, {\n payment,\n onExpand: row.toggleExpanded,\n })\n },\n },\n]\n\nconst sorting = ref<SortingState>([])\nconst columnFilters = ref<ColumnFiltersState>([])\nconst columnVisibility = ref<VisibilityState>({})\nconst rowSelection = ref({})\nconst expanded = ref<ExpandedState>({})\n\nconst table = useVueTable({\n data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getExpandedRowModel: getExpandedRowModel(),\n onSortingChange: updaterOrValue => valueUpdater(updaterOrValue, sorting),\n onColumnFiltersChange: updaterOrValue => valueUpdater(updaterOrValue, columnFilters),\n onColumnVisibilityChange: updaterOrValue => valueUpdater(updaterOrValue, columnVisibility),\n onRowSelectionChange: updaterOrValue => valueUpdater(updaterOrValue, rowSelection),\n onExpandedChange: updaterOrValue => valueUpdater(updaterOrValue, expanded),\n state: {\n get sorting() { return sorting.value },\n get columnFilters() { return columnFilters.value },\n get columnVisibility() { return columnVisibility.value },\n get rowSelection() { return rowSelection.value },\n get expanded() { return expanded.value },\n },\n})\n</script>\n\n<template>\n <div class=\"w-full\">\n <div class=\"flex items-center py-4\">\n <Input\n class=\"max-w-sm\"\n placeholder=\"Filter emails...\"\n :model-value=\"table.getColumn('email')?.getFilterValue() as string\"\n @update:model-value=\" table.getColumn('email')?.setFilterValue($event)\"\n />\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\" class=\"ml-auto\">\n Columns <ChevronDownIcon class=\"ml-2 h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuCheckboxItem\n v-for=\"column in table.getAllColumns().filter((column) => column.getCanHide())\"\n :key=\"column.id\"\n class=\"capitalize\"\n :model-value=\"column.getIsVisible()\"\n @update:model-value=\"(value) => {\n column.toggleVisibility(!!value)\n }\"\n >\n {{ column.id }}\n </DropdownMenuCheckboxItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n <div class=\"rounded-md border\">\n <Table>\n <TableHeader>\n <TableRow v-for=\"headerGroup in table.getHeaderGroups()\" :key=\"headerGroup.id\">\n <TableHead v-for=\"header in headerGroup.headers\" :key=\"header.id\">\n <FlexRender v-if=\"!header.isPlaceholder\" :render=\"header.column.columnDef.header\" :props=\"header.getContext()\" />\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <template v-if=\"table.getRowModel().rows?.length\">\n <template v-for=\"row in table.getRowModel().rows\" :key=\"row.id\">\n <TableRow :data-state=\"row.getIsSelected() && 'selected'\">\n <TableCell v-for=\"cell in row.getVisibleCells()\" :key=\"cell.id\">\n <FlexRender :render=\"cell.column.columnDef.cell\" :props=\"cell.getContext()\" />\n </TableCell>\n </TableRow>\n <TableRow v-if=\"row.getIsExpanded()\">\n <TableCell :colspan=\"row.getAllCells().length\">\n {{ JSON.stringify(row.original) }}\n </TableCell>\n </TableRow>\n </template>\n </template>\n\n <TableRow v-else>\n <TableCell\n :colspan=\"columns.length\"\n class=\"h-24 text-center\"\n >\n No results.\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </div>\n\n <div class=\"flex items-center justify-end space-x-2 py-4\">\n <div class=\"flex-1 text-sm text-muted-foreground\">\n {{ table.getFilteredSelectedRowModel().rows.length }} of\n {{ table.getFilteredRowModel().rows.length }} row(s) selected.\n </div>\n <div class=\"space-x-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"!table.getCanPreviousPage()\"\n @click=\"table.previousPage()\"\n >\n Previous\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"!table.getCanNextPage()\"\n @click=\"table.nextPage()\"\n >\n Next\n </Button>\n </div>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DataTableDemoColumn",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DataTableDemoColumn.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/new-york/ui/dropdown-menu'\nimport { DotsHorizontalIcon } from '@radix-icons/vue'\n\ndefineProps<{\n payment: {\n id: string\n }\n}>()\n\ndefineEmits<{\n (e: 'expand'): void\n}>()\n\nfunction copy(id: string) {\n navigator.clipboard.writeText(id)\n}\n</script>\n\n<template>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"ghost\" class=\"h-8 w-8 p-0\">\n <span class=\"sr-only\">Open menu</span>\n <DotsHorizontalIcon class=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem @click=\"copy(payment.id)\">\n Copy payment ID\n </DropdownMenuItem>\n <DropdownMenuItem @click=\"$emit('expand')\">\n Expand\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>View customer</DropdownMenuItem>\n <DropdownMenuItem>View payment details</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DataTableReactiveDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@tanstack/vue-table"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"checkbox",
|
|
"dropdown-menu",
|
|
"input",
|
|
"table"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DataTableReactiveDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type {\n ColumnDef,\n ColumnFiltersState,\n ExpandedState,\n SortingState,\n VisibilityState,\n} from '@tanstack/vue-table'\nimport { valueUpdater } from '@/lib/utils'\nimport { Button } from '@/registry/new-york/ui/button'\n\nimport { Checkbox } from '@/registry/new-york/ui/checkbox'\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\nimport { Input } from '@/registry/new-york/ui/input'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/new-york/ui/table'\nimport {\n FlexRender,\n getCoreRowModel,\n getExpandedRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useVueTable,\n} from '@tanstack/vue-table'\nimport { ArrowUpDown, ChevronDown } from 'lucide-vue-next'\nimport { h, ref, shallowRef } from 'vue'\nimport DropdownAction from './DataTableDemoColumn.vue'\n\nexport interface Payment {\n id: string\n amount: number\n status: 'pending' | 'processing' | 'success' | 'failed'\n email: string\n}\n\nconst data = shallowRef<Payment[]>([\n {\n id: 'm5gr84i9',\n amount: 316,\n status: 'success',\n email: 'ken99@yahoo.com',\n },\n {\n id: '3u1reuv4',\n amount: 242,\n status: 'success',\n email: 'Abe45@gmail.com',\n },\n {\n id: 'derv1ws0',\n amount: 837,\n status: 'processing',\n email: 'Monserrat44@gmail.com',\n },\n {\n id: '5kma53ae',\n amount: 874,\n status: 'success',\n email: 'Silas22@gmail.com',\n },\n {\n id: 'bhqecj4p',\n amount: 721,\n status: 'failed',\n email: 'carmella@hotmail.com',\n },\n])\n\nconst columns: ColumnDef<Payment>[] = [\n {\n id: 'select',\n header: ({ table }) => h(Checkbox, {\n 'modelValue': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),\n 'onUpdate:modelValue': value => table.toggleAllPageRowsSelected(!!value),\n 'ariaLabel': 'Select all',\n }),\n cell: ({ row }) => h(Checkbox, {\n 'modelValue': row.getIsSelected(),\n 'onUpdate:modelValue': value => row.toggleSelected(!!value),\n 'ariaLabel': 'Select row',\n }),\n enableSorting: false,\n enableHiding: false,\n },\n {\n accessorKey: 'status',\n header: 'Status',\n cell: ({ row }) => h('div', { class: 'capitalize' }, row.getValue('status')),\n },\n {\n accessorKey: 'email',\n header: ({ column }) => {\n return h(Button, {\n variant: 'ghost',\n onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'),\n }, () => ['Email', h(ArrowUpDown, { class: 'ml-2 h-4 w-4' })])\n },\n cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),\n },\n {\n accessorKey: 'amount',\n header: () => h('div', { class: 'text-right' }, 'Amount'),\n cell: ({ row }) => {\n const amount = Number.parseFloat(row.getValue('amount'))\n\n // Format the amount as a dollar amount\n const formatted = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n }).format(amount)\n\n return h('div', { class: 'text-right font-medium' }, formatted)\n },\n },\n {\n id: 'actions',\n enableHiding: false,\n cell: ({ row }) => {\n const payment = row.original\n\n return h('div', { class: 'relative' }, h(DropdownAction, {\n payment,\n onExpand: row.toggleExpanded,\n }))\n },\n },\n]\n\nconst sorting = ref<SortingState>([])\nconst columnFilters = ref<ColumnFiltersState>([])\nconst columnVisibility = ref<VisibilityState>({})\nconst rowSelection = ref({})\nconst expanded = ref<ExpandedState>({})\n\nconst table = useVueTable({\n data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getExpandedRowModel: getExpandedRowModel(),\n onSortingChange: updaterOrValue => valueUpdater(updaterOrValue, sorting),\n onColumnFiltersChange: updaterOrValue => valueUpdater(updaterOrValue, columnFilters),\n onColumnVisibilityChange: updaterOrValue => valueUpdater(updaterOrValue, columnVisibility),\n onRowSelectionChange: updaterOrValue => valueUpdater(updaterOrValue, rowSelection),\n onExpandedChange: updaterOrValue => valueUpdater(updaterOrValue, expanded),\n state: {\n get sorting() { return sorting.value },\n get columnFilters() { return columnFilters.value },\n get columnVisibility() { return columnVisibility.value },\n get rowSelection() { return rowSelection.value },\n get expanded() { return expanded.value },\n },\n})\n\nconst statuses: Payment['status'][] = ['pending', 'processing', 'success', 'failed']\nfunction randomize() {\n data.value = data.value.map(item => ({\n ...item,\n status: statuses[Math.floor(Math.random() * statuses.length)],\n }))\n}\n</script>\n\n<template>\n <div class=\"w-full\">\n <div class=\"flex gap-2 items-center py-4\">\n <Input\n class=\"max-w-52\"\n placeholder=\"Filter emails...\"\n :model-value=\"table.getColumn('email')?.getFilterValue() as string\"\n @update:model-value=\" table.getColumn('email')?.setFilterValue($event)\"\n />\n <Button @click=\"randomize\">\n Randomize\n </Button>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\" class=\"ml-auto\">\n Columns <ChevronDown class=\"ml-2 h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuCheckboxItem\n v-for=\"column in table.getAllColumns().filter((column) => column.getCanHide())\"\n :key=\"column.id\"\n class=\"capitalize\"\n :model-value=\"column.getIsVisible()\"\n @update:model-value=\"(value) => {\n column.toggleVisibility(!!value)\n }\"\n >\n {{ column.id }}\n </DropdownMenuCheckboxItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n <div class=\"rounded-md border\">\n <Table>\n <TableHeader>\n <TableRow v-for=\"headerGroup in table.getHeaderGroups()\" :key=\"headerGroup.id\">\n <TableHead v-for=\"header in headerGroup.headers\" :key=\"header.id\">\n <FlexRender v-if=\"!header.isPlaceholder\" :render=\"header.column.columnDef.header\" :props=\"header.getContext()\" />\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <template v-if=\"table.getRowModel().rows?.length\">\n <template v-for=\"row in table.getRowModel().rows\" :key=\"row.id\">\n <TableRow :data-state=\"row.getIsSelected() && 'selected'\">\n <TableCell v-for=\"cell in row.getVisibleCells()\" :key=\"cell.id\">\n <FlexRender :render=\"cell.column.columnDef.cell\" :props=\"cell.getContext()\" />\n </TableCell>\n </TableRow>\n <TableRow v-if=\"row.getIsExpanded()\">\n <TableCell :colspan=\"row.getAllCells().length\">\n {{ JSON.stringify(row.original) }}\n </TableCell>\n </TableRow>\n </template>\n </template>\n\n <TableRow v-else>\n <TableCell\n :colspan=\"columns.length\"\n class=\"h-24 text-center\"\n >\n No results.\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </div>\n\n <div class=\"flex items-center justify-end space-x-2 py-4\">\n <div class=\"flex-1 text-sm text-muted-foreground\">\n {{ table.getFilteredSelectedRowModel().rows.length }} of\n {{ table.getFilteredRowModel().rows.length }} row(s) selected.\n </div>\n <div class=\"space-x-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"!table.getCanPreviousPage()\"\n @click=\"table.previousPage()\"\n >\n Previous\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"!table.getCanNextPage()\"\n @click=\"table.nextPage()\"\n >\n Next\n </Button>\n </div>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DatePickerDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"calendar",
|
|
"popover"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DatePickerDemo.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DatePickerForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"calendar",
|
|
"form",
|
|
"popover",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DatePickerForm.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DatePickerWithIndependentMonths",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"range-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DatePickerWithIndependentMonths.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nimport { Button, buttonVariants } from '@/registry/new-york/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\n\nimport {\n RangeCalendarCell,\n RangeCalendarCellTrigger,\n RangeCalendarGrid,\n RangeCalendarGridBody,\n RangeCalendarGridHead,\n RangeCalendarGridRow,\n RangeCalendarHeadCell,\n} from '@/registry/new-york/ui/range-calendar'\nimport {\n CalendarDate,\n type DateValue,\n isEqualMonth,\n} from '@internationalized/date'\nimport {\n CalendarIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n} from '@radix-icons/vue'\nimport { type DateRange, RangeCalendarRoot, useDateFormatter } from 'reka-ui'\nimport { createMonth, type Grid, toDate } from 'reka-ui/date'\nimport { type Ref, ref, watch } from 'vue'\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\nconst locale = ref('en-US')\nconst formatter = useDateFormatter(locale.value)\n\nconst placeholder = ref(value.value.start) as Ref<DateValue>\nconst secondMonthPlaceholder = ref(value.value.end) as Ref<DateValue>\n\nconst firstMonth = ref(\n createMonth({\n dateObj: placeholder.value,\n locale: locale.value,\n fixedWeeks: true,\n weekStartsOn: 0,\n }),\n) as Ref<Grid<DateValue>>\nconst secondMonth = ref(\n createMonth({\n dateObj: secondMonthPlaceholder.value,\n locale: locale.value,\n fixedWeeks: true,\n weekStartsOn: 0,\n }),\n) as Ref<Grid<DateValue>>\n\nfunction updateMonth(reference: 'first' | 'second', months: number) {\n if (reference === 'first') {\n placeholder.value = placeholder.value.add({ months })\n }\n else {\n secondMonthPlaceholder.value = secondMonthPlaceholder.value.add({\n months,\n })\n }\n}\n\nwatch(placeholder, (_placeholder) => {\n firstMonth.value = createMonth({\n dateObj: _placeholder,\n weekStartsOn: 0,\n fixedWeeks: false,\n locale: locale.value,\n })\n if (isEqualMonth(secondMonthPlaceholder.value, _placeholder)) {\n secondMonthPlaceholder.value = secondMonthPlaceholder.value.add({\n months: 1,\n })\n }\n})\n\nwatch(secondMonthPlaceholder, (_secondMonthPlaceholder) => {\n secondMonth.value = createMonth({\n dateObj: _secondMonthPlaceholder,\n weekStartsOn: 0,\n fixedWeeks: false,\n locale: locale.value,\n })\n if (isEqualMonth(_secondMonthPlaceholder, placeholder.value))\n placeholder.value = placeholder.value.subtract({ months: 1 })\n})\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"\n cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\n \"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <template v-if=\"value.start\">\n <template v-if=\"value.end\">\n {{\n formatter.custom(toDate(value.start), {\n dateStyle: \"medium\",\n })\n }}\n -\n {{\n formatter.custom(toDate(value.end), {\n dateStyle: \"medium\",\n })\n }}\n </template>\n\n <template v-else>\n {{\n formatter.custom(toDate(value.start), {\n dateStyle: \"medium\",\n })\n }}\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 <RangeCalendarRoot v-slot=\"{ weekDays }\" v-model=\"value\" v-model:placeholder=\"placeholder\" class=\"p-3\">\n <div\n class=\"flex flex-col gap-y-4 mt-4 sm:flex-row sm:gap-x-4 sm:gap-y-0\"\n >\n <div class=\"flex flex-col gap-4\">\n <div class=\"flex items-center justify-between\">\n <button\n :class=\"\n cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n )\n \"\n @click=\"updateMonth('first', -1)\"\n >\n <ChevronLeftIcon class=\"h-4 w-4\" />\n </button>\n <div :class=\"cn('text-sm font-medium')\">\n {{\n formatter.fullMonthAndYear(\n toDate(firstMonth.value),\n )\n }}\n </div>\n <button\n :class=\"\n cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n )\n \"\n @click=\"updateMonth('first', 1)\"\n >\n <ChevronRightIcon class=\"h-4 w-4\" />\n </button>\n </div>\n <RangeCalendarGrid>\n <RangeCalendarGridHead>\n <RangeCalendarGridRow>\n <RangeCalendarHeadCell\n v-for=\"day in weekDays\"\n :key=\"day\"\n class=\"w-full\"\n >\n {{ day }}\n </RangeCalendarHeadCell>\n </RangeCalendarGridRow>\n </RangeCalendarGridHead>\n <RangeCalendarGridBody>\n <RangeCalendarGridRow\n v-for=\"(\n weekDates, index\n ) in firstMonth.rows\"\n :key=\"`weekDate-${index}`\"\n class=\"mt-2 w-full\"\n >\n <RangeCalendarCell\n v-for=\"weekDate in weekDates\"\n :key=\"weekDate.toString()\"\n :date=\"weekDate\"\n >\n <RangeCalendarCellTrigger\n :day=\"weekDate\"\n :month=\"firstMonth.value\"\n />\n </RangeCalendarCell>\n </RangeCalendarGridRow>\n </RangeCalendarGridBody>\n </RangeCalendarGrid>\n </div>\n <div class=\"flex flex-col gap-4\">\n <div class=\"flex items-center justify-between\">\n <button\n :class=\"\n cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n )\n \"\n @click=\"updateMonth('second', -1)\"\n >\n <ChevronLeftIcon class=\"h-4 w-4\" />\n </button>\n <div :class=\"cn('text-sm font-medium')\">\n {{\n formatter.fullMonthAndYear(\n toDate(secondMonth.value),\n )\n }}\n </div>\n\n <button\n :class=\"\n cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n )\n \"\n @click=\"updateMonth('second', 1)\"\n >\n <ChevronRightIcon class=\"h-4 w-4\" />\n </button>\n </div>\n <RangeCalendarGrid>\n <RangeCalendarGridHead>\n <RangeCalendarGridRow>\n <RangeCalendarHeadCell\n v-for=\"day in weekDays\"\n :key=\"day\"\n class=\"w-full\"\n >\n {{ day }}\n </RangeCalendarHeadCell>\n </RangeCalendarGridRow>\n </RangeCalendarGridHead>\n <RangeCalendarGridBody>\n <RangeCalendarGridRow\n v-for=\"(\n weekDates, index\n ) in secondMonth.rows\"\n :key=\"`weekDate-${index}`\"\n class=\"mt-2 w-full\"\n >\n <RangeCalendarCell\n v-for=\"weekDate in weekDates\"\n :key=\"weekDate.toString()\"\n :date=\"weekDate\"\n >\n <RangeCalendarCellTrigger\n :day=\"weekDate\"\n :month=\"secondMonth.value\"\n />\n </RangeCalendarCell>\n </RangeCalendarGridRow>\n </RangeCalendarGridBody>\n </RangeCalendarGrid>\n </div>\n </div>\n </RangeCalendarRoot>\n </PopoverContent>\n </Popover>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DatePickerWithPresets",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"calendar",
|
|
"popover",
|
|
"select"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DatePickerWithPresets.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DatePickerWithRange",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"range-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DatePickerWithRange.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DialogCustomCloseButton",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog",
|
|
"input",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DialogCustomCloseButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/new-york/ui/dialog'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\nimport { CopyIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Dialog>\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Share\n </Button>\n </DialogTrigger>\n <DialogContent class=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>Share link</DialogTitle>\n <DialogDescription>\n Anyone who has this link will be able to view this.\n </DialogDescription>\n </DialogHeader>\n <div class=\"flex items-center space-x-2\">\n <div class=\"grid flex-1 gap-2\">\n <Label for=\"link\" class=\"sr-only\">\n Link\n </Label>\n <Input\n id=\"link\"\n default-value=\"https://shadcn-vue.com/docs/installation\"\n read-only\n />\n </div>\n <Button type=\"submit\" size=\"sm\" class=\"px-3\">\n <span class=\"sr-only\">Copy</span>\n <CopyIcon class=\"w-4 h-4\" />\n </Button>\n </div>\n <DialogFooter class=\"sm:justify-start\">\n <DialogClose as-child>\n <Button type=\"button\" variant=\"secondary\">\n Close\n </Button>\n </DialogClose>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DialogDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog",
|
|
"input",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DialogDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/new-york/ui/dialog'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\n</script>\n\n<template>\n <Dialog>\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Edit Profile\n </Button>\n </DialogTrigger>\n <DialogContent class=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Edit profile</DialogTitle>\n <DialogDescription>\n Make changes to your profile here. Click save when you're done.\n </DialogDescription>\n </DialogHeader>\n <div class=\"grid gap-4 py-4\">\n <div class=\"grid grid-cols-4 items-center gap-4\">\n <Label for=\"name\" class=\"text-right\">\n Name\n </Label>\n <Input id=\"name\" value=\"Pedro Duarte\" class=\"col-span-3\" />\n </div>\n <div class=\"grid grid-cols-4 items-center gap-4\">\n <Label for=\"username\" class=\"text-right\">\n Username\n </Label>\n <Input id=\"username\" value=\"@peduarte\" class=\"col-span-3\" />\n </div>\n </div>\n <DialogFooter>\n <Button type=\"submit\">\n Save changes\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DialogForm",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog",
|
|
"form",
|
|
"input",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DialogForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/new-york/ui/dialog'\nimport {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/new-york/ui/form'\n\nimport { Input } from '@/registry/new-york/ui/input'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n username: z.string().min(2).max(50),\n}))\n\nfunction onSubmit(values: any) {\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 v-slot=\"{ handleSubmit }\" as=\"\" keep-values :validation-schema=\"formSchema\">\n <Dialog>\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Edit Profile\n </Button>\n </DialogTrigger>\n <DialogContent class=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Edit profile</DialogTitle>\n <DialogDescription>\n Make changes to your profile here. Click save when you're done.\n </DialogDescription>\n </DialogHeader>\n\n <form id=\"dialogForm\" @submit=\"handleSubmit($event, onSubmit)\">\n <FormField v-slot=\"{ componentField }\" name=\"username\">\n <FormItem>\n <FormLabel>Username</FormLabel>\n <FormControl>\n <Input type=\"text\" placeholder=\"shadcn\" v-bind=\"componentField\" />\n </FormControl>\n <FormDescription>\n This is your public display name.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n </form>\n\n <DialogFooter>\n <Button type=\"submit\" form=\"dialogForm\">\n Save changes\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </Form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DialogScrollBodyDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DialogScrollBodyDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/new-york/ui/dialog'\n</script>\n\n<template>\n <Dialog>\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Edit Profile\n </Button>\n </DialogTrigger>\n <DialogContent class=\"sm:max-w-[425px] grid-rows-[auto_minmax(0,1fr)_auto] p-0 max-h-[90dvh]\">\n <DialogHeader class=\"p-6 pb-0\">\n <DialogTitle>Edit profile</DialogTitle>\n <DialogDescription>\n Make changes to your profile here. Click save when you're done.\n </DialogDescription>\n </DialogHeader>\n <div class=\"grid gap-4 py-4 overflow-y-auto px-6\">\n <div class=\"flex flex-col justify-between h-[300dvh]\">\n <p>\n This is some placeholder content to show the scrolling behavior for modals. We use repeated line breaks to demonstrate how content can exceed minimum inner height, thereby showing inner scrolling. When content becomes longer than the predefined max-height of modal, content will be cropped and scrollable within the modal.\n </p>\n\n <p>This content should appear at the bottom after you scroll.</p>\n </div>\n </div>\n <DialogFooter class=\"p-6 pt-0\">\n <Button type=\"submit\">\n Save changes\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DialogScrollOverlayDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DialogScrollOverlayDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Dialog,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogScrollContent,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/new-york/ui/dialog'\n</script>\n\n<template>\n <Dialog>\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Edit Profile\n </Button>\n </DialogTrigger>\n <DialogScrollContent class=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Modal title</DialogTitle>\n <DialogDescription>\n Here is modal with overlay scroll\n </DialogDescription>\n </DialogHeader>\n <div class=\"grid gap-4 py-4 h-[300dvh]\">\n <p>\n This is some placeholder content to show the scrolling behavior for modals. Instead of repeating the text in the modal, we use an inline style to set a minimum height, thereby extending the length of the overall modal and demonstrating the overflow scrolling. When content becomes longer than the height of the viewport, scrolling will move the modal as needed.\n </p>\n </div>\n <DialogFooter>\n <Button type=\"submit\">\n Save changes\n </Button>\n </DialogFooter>\n </DialogScrollContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DonutChartColor",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-donut"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DonutChartColor.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 :colors=\"['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'purple']\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DonutChartCustomTooltip",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-donut"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DonutChartCustomTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DonutChart } from '@/registry/new-york/ui/chart-donut'\nimport CustomChartTooltip from './CustomChartTooltip.vue'\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</script>\n\n<template>\n <DonutChart\n index=\"name\"\n :category=\"'total'\"\n :data=\"data\"\n :custom-tooltip=\"CustomChartTooltip\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DonutChartDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-donut"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DonutChartDemo.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DonutChartPie",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-donut"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DonutChartPie.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</script>\n\n<template>\n <DonutChart\n index=\"name\"\n :category=\"'total'\"\n :data=\"data\"\n :type=\"'pie'\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DrawerDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"drawer"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DrawerDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from '@/registry/new-york/ui/drawer'\nimport { MinusIcon, PlusIcon } from '@radix-icons/vue'\nimport { VisStackedBar, VisXYContainer } from '@unovis/vue'\nimport { ref } from 'vue'\n\nconst goal = ref(350)\n\ntype Data = typeof data[number]\nconst data = [\n { goal: 400 },\n { goal: 300 },\n { goal: 200 },\n { goal: 300 },\n { goal: 200 },\n { goal: 278 },\n { goal: 189 },\n { goal: 239 },\n { goal: 300 },\n { goal: 200 },\n { goal: 278 },\n { goal: 189 },\n { goal: 349 },\n]\n</script>\n\n<template>\n <Drawer>\n <DrawerTrigger as-child>\n <Button variant=\"outline\">\n Open Drawer\n </Button>\n </DrawerTrigger>\n <DrawerContent>\n <div class=\"mx-auto w-full max-w-sm\">\n <DrawerHeader>\n <DrawerTitle>Move Goal</DrawerTitle>\n <DrawerDescription>Set your daily activity goal.</DrawerDescription>\n </DrawerHeader>\n <div class=\"p-4 pb-0\">\n <div class=\"flex items-center justify-center space-x-2\">\n <Button\n variant=\"outline\"\n size=\"icon\"\n class=\"h-8 w-8 shrink-0 rounded-full\"\n :disabled=\"goal <= 200\"\n @click=\"goal -= 10\"\n >\n <MinusIcon class=\"h-4 w-4\" />\n <span class=\"sr-only\">Decrease</span>\n </Button>\n <div class=\"flex-1 text-center\">\n <div class=\"text-7xl font-bold tracking-tighter\">\n {{ goal }}\n </div>\n <div class=\"text-[0.70rem] uppercase text-muted-foreground\">\n Calories/day\n </div>\n </div>\n <Button\n variant=\"outline\"\n size=\"icon\"\n class=\"h-8 w-8 shrink-0 rounded-full\"\n :disabled=\"goal >= 400\"\n @click=\"goal += 10\"\n >\n <PlusIcon class=\"h-4 w-4\" />\n <span class=\"sr-only\">Increase</span>\n </Button>\n </div>\n <div class=\"my-3 px-3 h-[120px]\">\n <VisXYContainer\n :data=\"data\"\n class=\"h-[120px]\"\n :style=\"{\n 'opacity': 0.9,\n '--theme-primary': `hsl(var(--foreground))`,\n }\"\n >\n <VisStackedBar\n :x=\"(d: Data, i :number) => i\"\n :y=\"(d: Data) => d.goal\"\n color=\"var(--theme-primary)\"\n :bar-padding=\"0.1\"\n :rounded-corners=\"0\"\n />\n </VisXYContainer>\n </div>\n </div>\n <DrawerFooter>\n <Button>Submit</Button>\n <DrawerClose as-child>\n <Button variant=\"outline\">\n Cancel\n </Button>\n </DrawerClose>\n </DrawerFooter>\n </div>\n </DrawerContent>\n </Drawer>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DrawerDialog",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog",
|
|
"drawer",
|
|
"input",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DrawerDialog.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/new-york/ui/dialog'\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from '@/registry/new-york/ui/drawer'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\nimport { createReusableTemplate, useMediaQuery } from '@vueuse/core'\nimport { ref } from 'vue'\n\n// Reuse `form` section\nconst [UseTemplate, GridForm] = createReusableTemplate()\nconst isDesktop = useMediaQuery('(min-width: 768px)')\n\nconst isOpen = ref(false)\n</script>\n\n<template>\n <UseTemplate>\n <form class=\"grid items-start gap-4 px-4\">\n <div class=\"grid gap-2\">\n <Label html-for=\"email\">Email</Label>\n <Input id=\"email\" type=\"email\" default-value=\"shadcn@example.com\" />\n </div>\n <div class=\"grid gap-2\">\n <Label html-for=\"username\">Username</Label>\n <Input id=\"username\" default-value=\"@shadcn\" />\n </div>\n <Button type=\"submit\">\n Save changes\n </Button>\n </form>\n </UseTemplate>\n\n <Dialog v-if=\"isDesktop\" v-model:open=\"isOpen\">\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Edit Profile\n </Button>\n </DialogTrigger>\n <DialogContent class=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Edit profile</DialogTitle>\n <DialogDescription>\n Make changes to your profile here. Click save when you're done.\n </DialogDescription>\n </DialogHeader>\n <GridForm />\n </DialogContent>\n </Dialog>\n\n <Drawer v-else v-model:open=\"isOpen\">\n <DrawerTrigger as-child>\n <Button variant=\"outline\">\n Edit Profile\n </Button>\n </DrawerTrigger>\n <DrawerContent>\n <DrawerHeader class=\"text-left\">\n <DrawerTitle>Edit profile</DrawerTitle>\n <DrawerDescription>\n Make changes to your profile here. Click save when you're done.\n </DrawerDescription>\n </DrawerHeader>\n <GridForm />\n <DrawerFooter class=\"pt-2\">\n <DrawerClose as-child>\n <Button variant=\"outline\">\n Cancel\n </Button>\n </DrawerClose>\n </DrawerFooter>\n </DrawerContent>\n </Drawer>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DropdownMenuCheckboxes",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DropdownMenuCheckboxes.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { DropdownMenuCheckboxItemProps } from 'reka-ui'\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\nimport { ref } from 'vue'\n\ntype Checked = DropdownMenuCheckboxItemProps['modelValue']\n\nconst showStatusBar = ref<Checked>(true)\nconst showActivityBar = ref<Checked>(false)\nconst showPanel = ref<Checked>(false)\n</script>\n\n<template>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\">\n Open\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent class=\"w-56\">\n <DropdownMenuLabel>Appearance</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuCheckboxItem\n v-model:model-value=\"showStatusBar\"\n >\n Status Bar\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n v-model:model-value=\"showActivityBar\"\n disabled\n >\n Activity Bar\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n v-model:model-value=\"showPanel\"\n >\n Panel\n </DropdownMenuCheckboxItem>\n </DropdownMenuContent>\n </DropdownMenu>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DropdownMenuDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DropdownMenuDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuPortal,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n</script>\n\n<template>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\">\n Open\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent class=\"w-56\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <span>Profile</span>\n <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <span>Billing</span>\n <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <span>Settings</span>\n <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <span>Keyboard shortcuts</span>\n <DropdownMenuShortcut>⌘K</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <span>Team</span>\n </DropdownMenuItem>\n <DropdownMenuSub>\n <DropdownMenuSubTrigger>\n <span>Invite users</span>\n </DropdownMenuSubTrigger>\n <DropdownMenuPortal>\n <DropdownMenuSubContent>\n <DropdownMenuItem>\n <span>Email</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <span>Message</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <span>More...</span>\n </DropdownMenuItem>\n </DropdownMenuSubContent>\n </DropdownMenuPortal>\n </DropdownMenuSub>\n <DropdownMenuItem>\n <span>New Team</span>\n <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <span>GitHub</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <span>Support</span>\n </DropdownMenuItem>\n <DropdownMenuItem disabled>\n <span>API</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <span>Log out</span>\n <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DropdownMenuRadioGroup",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DropdownMenuRadioGroup.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\nimport { ref } from 'vue'\n\nconst position = ref('bottom')\n</script>\n\n<template>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\">\n Open\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent class=\"w-56\">\n <DropdownMenuLabel>Panel Position</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuRadioGroup v-model=\"position\">\n <DropdownMenuRadioItem value=\"top\">\n Top\n </DropdownMenuRadioItem>\n <DropdownMenuRadioItem value=\"bottom\">\n Bottom\n </DropdownMenuRadioItem>\n <DropdownMenuRadioItem value=\"right\">\n Right\n </DropdownMenuRadioItem>\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "HoverCardDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"avatar",
|
|
"button",
|
|
"hover-card"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/HoverCardDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/registry/new-york/ui/avatar'\n\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n HoverCard,\n HoverCardContent,\n HoverCardTrigger,\n} from '@/registry/new-york/ui/hover-card'\nimport { CalendarIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <HoverCard>\n <HoverCardTrigger as-child>\n <Button variant=\"link\">\n @vuejs\n </Button>\n </HoverCardTrigger>\n <HoverCardContent class=\"w-80\">\n <div class=\"flex justify-between space-x-4\">\n <Avatar>\n <AvatarImage src=\"https://github.com/vuejs.png\" />\n <AvatarFallback>VC</AvatarFallback>\n </Avatar>\n <div class=\"space-y-1\">\n <h4 class=\"text-sm font-semibold\">\n @vuejs\n </h4>\n <p class=\"text-sm\">\n Progressive JavaScript framework for building modern web interfaces.\n </p>\n <div class=\"flex items-center pt-2\">\n <CalendarIcon class=\"mr-2 h-4 w-4 opacity-70\" />\n <span class=\"text-xs text-muted-foreground\">\n Joined January 2014\n </span>\n </div>\n </div>\n </div>\n </HoverCardContent>\n </HoverCard>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Input } from '@/registry/new-york/ui/input'\n</script>\n\n<template>\n <Input type=\"email\" placeholder=\"Email\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputDisabled",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputDisabled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Input } from '@/registry/new-york/ui/input'\n</script>\n\n<template>\n <Input disabled type=\"email\" placeholder=\"Email\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputFile",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"input",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputFile.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\n</script>\n\n<template>\n <div class=\"grid w-full max-w-sm items-center gap-1.5\">\n <Label for=\"picture\">Picture</Label>\n <Input id=\"picture\" type=\"file\" />\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"input",
|
|
"use-toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputForm.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 { Input } from '@/registry/new-york/ui/input'\nimport { toast } from '@/registry/new-york/ui/toast/use-toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n username: z.string().min(2).max(50),\n}))\n\nconst { isFieldDirty, 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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField }\" name=\"username\" :validate-on-blur=\"!isFieldDirty\">\n <FormItem>\n <FormLabel>Username</FormLabel>\n <FormControl>\n <Input type=\"text\" placeholder=\"shadcn\" v-bind=\"componentField\" />\n </FormControl>\n <FormDescription>\n This is your public display name.\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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputFormAutoAnimate",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"input",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputFormAutoAnimate.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 { Input } from '@/registry/new-york/ui/input'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { vAutoAnimate } from '@formkit/auto-animate/vue'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n username: z.string().min(2).max(50),\n}))\n\nconst { isFieldDirty, 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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField }\" name=\"username\" :validate-on-blur=\"!isFieldDirty\">\n <FormItem v-auto-animate>\n <FormLabel>Username</FormLabel>\n <FormControl>\n <Input type=\"text\" placeholder=\"shadcn\" v-bind=\"componentField\" />\n </FormControl>\n <FormDescription>\n This is your public display name.\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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputWithButton",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputWithButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Input } from '@/registry/new-york/ui/input'\n</script>\n\n<template>\n <div class=\"flex w-full max-w-sm items-center gap-1.5\">\n <Input id=\"email\" type=\"email\" placeholder=\"Email\" />\n <Button type=\"submit\">\n Subscribe\n </Button>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputWithIcon",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputWithIcon.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Input } from '@/registry/new-york/ui/input'\nimport { MagnifyingGlassIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <div class=\"relative w-full max-w-sm items-center\">\n <Input id=\"search\" type=\"text\" placeholder=\"Search...\" class=\"pl-10\" />\n <span class=\"absolute start-0 inset-y-0 flex items-center justify-center px-2\">\n <MagnifyingGlassIcon class=\"size-6 text-muted-foreground\" />\n </span>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputWithLabel",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"input",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputWithLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\n</script>\n\n<template>\n <div class=\"grid w-full max-w-sm items-center gap-1.5\">\n <Label for=\"email\">Email</Label>\n <Input id=\"email\" type=\"email\" placeholder=\"Email\" />\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "LabelDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"checkbox",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/LabelDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@/registry/new-york/ui/checkbox'\nimport { Label } from '@/registry/new-york/ui/label'\n</script>\n\n<template>\n <div>\n <div class=\"flex items-center space-x-2\">\n <Checkbox id=\"terms\" />\n <Label for=\"terms\">Accept terms and conditions</Label>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "LineChartCustomTooltip",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-line"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/LineChartCustomTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { LineChart } from '@/registry/new-york/ui/chart-line'\nimport CustomChartTooltip from './CustomChartTooltip.vue'\n\nconst data = [\n {\n 'year': 1970,\n 'Export Growth Rate': 2.04,\n 'Import Growth Rate': 1.53,\n },\n {\n 'year': 1971,\n 'Export Growth Rate': 1.96,\n 'Import Growth Rate': 1.58,\n },\n {\n 'year': 1972,\n 'Export Growth Rate': 1.96,\n 'Import Growth Rate': 1.61,\n },\n {\n 'year': 1973,\n 'Export Growth Rate': 1.93,\n 'Import Growth Rate': 1.61,\n },\n {\n 'year': 1974,\n 'Export Growth Rate': 1.88,\n 'Import Growth Rate': 1.67,\n },\n {\n 'year': 1975,\n 'Export Growth Rate': 1.79,\n 'Import Growth Rate': 1.64,\n },\n {\n 'year': 1976,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.62,\n },\n {\n 'year': 1977,\n 'Export Growth Rate': 1.74,\n 'Import Growth Rate': 1.69,\n },\n {\n 'year': 1978,\n 'Export Growth Rate': 1.74,\n 'Import Growth Rate': 1.7,\n },\n {\n 'year': 1979,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.67,\n },\n {\n 'year': 1980,\n 'Export Growth Rate': 1.79,\n 'Import Growth Rate': 1.7,\n },\n {\n 'year': 1981,\n 'Export Growth Rate': 1.81,\n 'Import Growth Rate': 1.72,\n },\n {\n 'year': 1982,\n 'Export Growth Rate': 1.84,\n 'Import Growth Rate': 1.73,\n },\n {\n 'year': 1983,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.73,\n },\n {\n 'year': 1984,\n 'Export Growth Rate': 1.78,\n 'Import Growth Rate': 1.78,\n },\n {\n 'year': 1985,\n 'Export Growth Rate': 1.78,\n 'Import Growth Rate': 1.81,\n },\n {\n 'year': 1986,\n 'Export Growth Rate': 1.82,\n 'Import Growth Rate': 1.89,\n },\n {\n 'year': 1987,\n 'Export Growth Rate': 1.82,\n 'Import Growth Rate': 1.91,\n },\n {\n 'year': 1988,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.94,\n },\n {\n 'year': 1989,\n 'Export Growth Rate': 1.76,\n 'Import Growth Rate': 1.94,\n },\n {\n 'year': 1990,\n 'Export Growth Rate': 1.75,\n 'Import Growth Rate': 1.97,\n },\n {\n 'year': 1991,\n 'Export Growth Rate': 1.62,\n 'Import Growth Rate': 1.99,\n },\n {\n 'year': 1992,\n 'Export Growth Rate': 1.56,\n 'Import Growth Rate': 2.12,\n },\n {\n 'year': 1993,\n 'Export Growth Rate': 1.5,\n 'Import Growth Rate': 2.13,\n },\n {\n 'year': 1994,\n 'Export Growth Rate': 1.46,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 1995,\n 'Export Growth Rate': 1.43,\n 'Import Growth Rate': 2.17,\n },\n {\n 'year': 1996,\n 'Export Growth Rate': 1.4,\n 'Import Growth Rate': 2.2,\n },\n {\n 'year': 1997,\n 'Export Growth Rate': 1.37,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 1998,\n 'Export Growth Rate': 1.34,\n 'Import Growth Rate': 2.07,\n },\n {\n 'year': 1999,\n 'Export Growth Rate': 1.32,\n 'Import Growth Rate': 2.05,\n },\n {\n 'year': 2000,\n 'Export Growth Rate': 1.33,\n 'Import Growth Rate': 2.07,\n },\n {\n 'year': 2001,\n 'Export Growth Rate': 1.31,\n 'Import Growth Rate': 2.08,\n },\n {\n 'year': 2002,\n 'Export Growth Rate': 1.29,\n 'Import Growth Rate': 2.1,\n },\n {\n 'year': 2003,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 2004,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.21,\n },\n {\n 'year': 2005,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.23,\n },\n {\n 'year': 2006,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.29,\n },\n {\n 'year': 2007,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.34,\n },\n {\n 'year': 2008,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.36,\n },\n {\n 'year': 2009,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.36,\n },\n {\n 'year': 2010,\n 'Export Growth Rate': 1.25,\n 'Import Growth Rate': 2.35,\n },\n {\n 'year': 2011,\n 'Export Growth Rate': 1.24,\n 'Import Growth Rate': 2.34,\n },\n {\n 'year': 2012,\n 'Export Growth Rate': 1.25,\n 'Import Growth Rate': 2.39,\n },\n {\n 'year': 2013,\n 'Export Growth Rate': 1.22,\n 'Import Growth Rate': 2.3,\n },\n {\n 'year': 2014,\n 'Export Growth Rate': 1.2,\n 'Import Growth Rate': 2.35,\n },\n {\n 'year': 2015,\n 'Export Growth Rate': 1.17,\n 'Import Growth Rate': 2.39,\n },\n {\n 'year': 2016,\n 'Export Growth Rate': 1.16,\n 'Import Growth Rate': 2.41,\n },\n {\n 'year': 2017,\n 'Export Growth Rate': 1.13,\n 'Import Growth Rate': 2.44,\n },\n {\n 'year': 2018,\n 'Export Growth Rate': 1.07,\n 'Import Growth Rate': 2.45,\n },\n {\n 'year': 2019,\n 'Export Growth Rate': 1.03,\n 'Import Growth Rate': 2.47,\n },\n {\n 'year': 2020,\n 'Export Growth Rate': 0.92,\n 'Import Growth Rate': 2.48,\n },\n {\n 'year': 2021,\n 'Export Growth Rate': 0.82,\n 'Import Growth Rate': 2.51,\n },\n]\n</script>\n\n<template>\n <LineChart\n :data=\"data\"\n index=\"year\"\n :categories=\"['Export Growth Rate', 'Import Growth Rate']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n :custom-tooltip=\"CustomChartTooltip\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "LineChartDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-line"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/LineChartDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { LineChart } from '@/registry/new-york/ui/chart-line'\n\nconst data = [\n {\n 'year': 1970,\n 'Export Growth Rate': 2.04,\n 'Import Growth Rate': 1.53,\n },\n {\n 'year': 1971,\n 'Export Growth Rate': 1.96,\n 'Import Growth Rate': 1.58,\n },\n {\n 'year': 1972,\n 'Export Growth Rate': 1.96,\n 'Import Growth Rate': 1.61,\n },\n {\n 'year': 1973,\n 'Export Growth Rate': 1.93,\n 'Import Growth Rate': 1.61,\n },\n {\n 'year': 1974,\n 'Export Growth Rate': 1.88,\n 'Import Growth Rate': 1.67,\n },\n {\n 'year': 1975,\n 'Export Growth Rate': 1.79,\n 'Import Growth Rate': 1.64,\n },\n {\n 'year': 1976,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.62,\n },\n {\n 'year': 1977,\n 'Export Growth Rate': 1.74,\n 'Import Growth Rate': 1.69,\n },\n {\n 'year': 1978,\n 'Export Growth Rate': 1.74,\n 'Import Growth Rate': 1.7,\n },\n {\n 'year': 1979,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.67,\n },\n {\n 'year': 1980,\n 'Export Growth Rate': 1.79,\n 'Import Growth Rate': 1.7,\n },\n {\n 'year': 1981,\n 'Export Growth Rate': 1.81,\n 'Import Growth Rate': 1.72,\n },\n {\n 'year': 1982,\n 'Export Growth Rate': 1.84,\n 'Import Growth Rate': 1.73,\n },\n {\n 'year': 1983,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.73,\n },\n {\n 'year': 1984,\n 'Export Growth Rate': 1.78,\n 'Import Growth Rate': 1.78,\n },\n {\n 'year': 1985,\n 'Export Growth Rate': 1.78,\n 'Import Growth Rate': 1.81,\n },\n {\n 'year': 1986,\n 'Export Growth Rate': 1.82,\n 'Import Growth Rate': 1.89,\n },\n {\n 'year': 1987,\n 'Export Growth Rate': 1.82,\n 'Import Growth Rate': 1.91,\n },\n {\n 'year': 1988,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.94,\n },\n {\n 'year': 1989,\n 'Export Growth Rate': 1.76,\n 'Import Growth Rate': 1.94,\n },\n {\n 'year': 1990,\n 'Export Growth Rate': 1.75,\n 'Import Growth Rate': 1.97,\n },\n {\n 'year': 1991,\n 'Export Growth Rate': 1.62,\n 'Import Growth Rate': 1.99,\n },\n {\n 'year': 1992,\n 'Export Growth Rate': 1.56,\n 'Import Growth Rate': 2.12,\n },\n {\n 'year': 1993,\n 'Export Growth Rate': 1.5,\n 'Import Growth Rate': 2.13,\n },\n {\n 'year': 1994,\n 'Export Growth Rate': 1.46,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 1995,\n 'Export Growth Rate': 1.43,\n 'Import Growth Rate': 2.17,\n },\n {\n 'year': 1996,\n 'Export Growth Rate': 1.4,\n 'Import Growth Rate': 2.2,\n },\n {\n 'year': 1997,\n 'Export Growth Rate': 1.37,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 1998,\n 'Export Growth Rate': 1.34,\n 'Import Growth Rate': 2.07,\n },\n {\n 'year': 1999,\n 'Export Growth Rate': 1.32,\n 'Import Growth Rate': 2.05,\n },\n {\n 'year': 2000,\n 'Export Growth Rate': 1.33,\n 'Import Growth Rate': 2.07,\n },\n {\n 'year': 2001,\n 'Export Growth Rate': 1.31,\n 'Import Growth Rate': 2.08,\n },\n {\n 'year': 2002,\n 'Export Growth Rate': 1.29,\n 'Import Growth Rate': 2.1,\n },\n {\n 'year': 2003,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 2004,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.21,\n },\n {\n 'year': 2005,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.23,\n },\n {\n 'year': 2006,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.29,\n },\n {\n 'year': 2007,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.34,\n },\n {\n 'year': 2008,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.36,\n },\n {\n 'year': 2009,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.36,\n },\n {\n 'year': 2010,\n 'Export Growth Rate': 1.25,\n 'Import Growth Rate': 2.35,\n },\n {\n 'year': 2011,\n 'Export Growth Rate': 1.24,\n 'Import Growth Rate': 2.34,\n },\n {\n 'year': 2012,\n 'Export Growth Rate': 1.25,\n 'Import Growth Rate': 2.39,\n },\n {\n 'year': 2013,\n 'Export Growth Rate': 1.22,\n 'Import Growth Rate': 2.3,\n },\n {\n 'year': 2014,\n 'Export Growth Rate': 1.2,\n 'Import Growth Rate': 2.35,\n },\n {\n 'year': 2015,\n 'Export Growth Rate': 1.17,\n 'Import Growth Rate': 2.39,\n },\n {\n 'year': 2016,\n 'Export Growth Rate': 1.16,\n 'Import Growth Rate': 2.41,\n },\n {\n 'year': 2017,\n 'Export Growth Rate': 1.13,\n 'Import Growth Rate': 2.44,\n },\n {\n 'year': 2018,\n 'Export Growth Rate': 1.07,\n 'Import Growth Rate': 2.45,\n },\n {\n 'year': 2019,\n 'Export Growth Rate': 1.03,\n 'Import Growth Rate': 2.47,\n },\n {\n 'year': 2020,\n 'Export Growth Rate': 0.92,\n 'Import Growth Rate': 2.48,\n },\n {\n 'year': 2021,\n 'Export Growth Rate': 0.82,\n 'Import Growth Rate': 2.51,\n },\n]\n</script>\n\n<template>\n <LineChart\n :data=\"data\"\n index=\"year\"\n :categories=\"['Export Growth Rate', 'Import Growth Rate']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "LineChartSparkline",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-line"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/LineChartSparkline.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { LineChart } from '@/registry/new-york/ui/chart-line'\n\nconst data = [\n {\n 'year': 1970,\n 'Export Growth Rate': 2.04,\n 'Import Growth Rate': 1.53,\n },\n {\n 'year': 1971,\n 'Export Growth Rate': 1.96,\n 'Import Growth Rate': 1.58,\n },\n {\n 'year': 1972,\n 'Export Growth Rate': 1.96,\n 'Import Growth Rate': 1.61,\n },\n {\n 'year': 1973,\n 'Export Growth Rate': 1.93,\n 'Import Growth Rate': 1.61,\n },\n {\n 'year': 1974,\n 'Export Growth Rate': 1.88,\n 'Import Growth Rate': 1.67,\n },\n {\n 'year': 1975,\n 'Export Growth Rate': 1.79,\n 'Import Growth Rate': 1.64,\n },\n {\n 'year': 1976,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.62,\n },\n {\n 'year': 1977,\n 'Export Growth Rate': 1.74,\n 'Import Growth Rate': 1.69,\n },\n {\n 'year': 1978,\n 'Export Growth Rate': 1.74,\n 'Import Growth Rate': 1.7,\n },\n {\n 'year': 1979,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.67,\n },\n {\n 'year': 1980,\n 'Export Growth Rate': 1.79,\n 'Import Growth Rate': 1.7,\n },\n {\n 'year': 1981,\n 'Export Growth Rate': 1.81,\n 'Import Growth Rate': 1.72,\n },\n {\n 'year': 1982,\n 'Export Growth Rate': 1.84,\n 'Import Growth Rate': 1.73,\n },\n {\n 'year': 1983,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.73,\n },\n {\n 'year': 1984,\n 'Export Growth Rate': 1.78,\n 'Import Growth Rate': 1.78,\n },\n {\n 'year': 1985,\n 'Export Growth Rate': 1.78,\n 'Import Growth Rate': 1.81,\n },\n {\n 'year': 1986,\n 'Export Growth Rate': 1.82,\n 'Import Growth Rate': 1.89,\n },\n {\n 'year': 1987,\n 'Export Growth Rate': 1.82,\n 'Import Growth Rate': 1.91,\n },\n {\n 'year': 1988,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.94,\n },\n {\n 'year': 1989,\n 'Export Growth Rate': 1.76,\n 'Import Growth Rate': 1.94,\n },\n {\n 'year': 1990,\n 'Export Growth Rate': 1.75,\n 'Import Growth Rate': 1.97,\n },\n {\n 'year': 1991,\n 'Export Growth Rate': 1.62,\n 'Import Growth Rate': 1.99,\n },\n {\n 'year': 1992,\n 'Export Growth Rate': 1.56,\n 'Import Growth Rate': 2.12,\n },\n {\n 'year': 1993,\n 'Export Growth Rate': 1.5,\n 'Import Growth Rate': 2.13,\n },\n {\n 'year': 1994,\n 'Export Growth Rate': 1.46,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 1995,\n 'Export Growth Rate': 1.43,\n 'Import Growth Rate': 2.17,\n },\n {\n 'year': 1996,\n 'Export Growth Rate': 1.4,\n 'Import Growth Rate': 2.2,\n },\n {\n 'year': 1997,\n 'Export Growth Rate': 1.37,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 1998,\n 'Export Growth Rate': 1.34,\n 'Import Growth Rate': 2.07,\n },\n {\n 'year': 1999,\n 'Export Growth Rate': 1.32,\n 'Import Growth Rate': 2.05,\n },\n {\n 'year': 2000,\n 'Export Growth Rate': 1.33,\n 'Import Growth Rate': 2.07,\n },\n {\n 'year': 2001,\n 'Export Growth Rate': 1.31,\n 'Import Growth Rate': 2.08,\n },\n {\n 'year': 2002,\n 'Export Growth Rate': 1.29,\n 'Import Growth Rate': 2.1,\n },\n {\n 'year': 2003,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 2004,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.21,\n },\n {\n 'year': 2005,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.23,\n },\n {\n 'year': 2006,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.29,\n },\n {\n 'year': 2007,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.34,\n },\n {\n 'year': 2008,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.36,\n },\n {\n 'year': 2009,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.36,\n },\n {\n 'year': 2010,\n 'Export Growth Rate': 1.25,\n 'Import Growth Rate': 2.35,\n },\n {\n 'year': 2011,\n 'Export Growth Rate': 1.24,\n 'Import Growth Rate': 2.34,\n },\n {\n 'year': 2012,\n 'Export Growth Rate': 1.25,\n 'Import Growth Rate': 2.39,\n },\n {\n 'year': 2013,\n 'Export Growth Rate': 1.22,\n 'Import Growth Rate': 2.3,\n },\n {\n 'year': 2014,\n 'Export Growth Rate': 1.2,\n 'Import Growth Rate': 2.35,\n },\n {\n 'year': 2015,\n 'Export Growth Rate': 1.17,\n 'Import Growth Rate': 2.39,\n },\n {\n 'year': 2016,\n 'Export Growth Rate': 1.16,\n 'Import Growth Rate': 2.41,\n },\n {\n 'year': 2017,\n 'Export Growth Rate': 1.13,\n 'Import Growth Rate': 2.44,\n },\n {\n 'year': 2018,\n 'Export Growth Rate': 1.07,\n 'Import Growth Rate': 2.45,\n },\n {\n 'year': 2019,\n 'Export Growth Rate': 1.03,\n 'Import Growth Rate': 2.47,\n },\n {\n 'year': 2020,\n 'Export Growth Rate': 0.92,\n 'Import Growth Rate': 2.48,\n },\n {\n 'year': 2021,\n 'Export Growth Rate': 0.82,\n 'Import Growth Rate': 2.51,\n },\n]\n</script>\n\n<template>\n <LineChart\n index=\"year\"\n class=\"h-[100px] w-[400px]\"\n :data=\"data\"\n :categories=\"['Export Growth Rate']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n :show-tooltip=\"false\"\n :show-grid-line=\"false\"\n :show-legend=\"false\"\n :show-x-axis=\"false\"\n :show-y-axis=\"false\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "MenubarDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"menubar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/MenubarDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Menubar,\n MenubarCheckboxItem,\n MenubarContent,\n MenubarItem,\n MenubarMenu,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarSeparator,\n MenubarShortcut,\n MenubarSub,\n MenubarSubContent,\n MenubarSubTrigger,\n MenubarTrigger,\n} from '@/registry/new-york/ui/menubar'\n</script>\n\n<template>\n <Menubar>\n <MenubarMenu>\n <MenubarTrigger>File</MenubarTrigger>\n <MenubarContent>\n <MenubarItem>\n New Tab <MenubarShortcut>⌘T</MenubarShortcut>\n </MenubarItem>\n <MenubarItem>\n New Window <MenubarShortcut>⌘N</MenubarShortcut>\n </MenubarItem>\n <MenubarItem disabled>\n New Incognito Window\n </MenubarItem>\n <MenubarSeparator />\n <MenubarSub>\n <MenubarSubTrigger>Share</MenubarSubTrigger>\n <MenubarSubContent>\n <MenubarItem>Email link</MenubarItem>\n <MenubarItem>Messages</MenubarItem>\n <MenubarItem>Notes</MenubarItem>\n </MenubarSubContent>\n </MenubarSub>\n <MenubarSeparator />\n <MenubarItem>\n Print... <MenubarShortcut>⌘P</MenubarShortcut>\n </MenubarItem>\n </MenubarContent>\n </MenubarMenu>\n <MenubarMenu>\n <MenubarTrigger>Edit</MenubarTrigger>\n <MenubarContent>\n <MenubarItem>\n Undo <MenubarShortcut>⌘Z</MenubarShortcut>\n </MenubarItem>\n <MenubarItem>\n Redo <MenubarShortcut>⇧⌘Z</MenubarShortcut>\n </MenubarItem>\n <MenubarSeparator />\n <MenubarSub>\n <MenubarSubTrigger>Find</MenubarSubTrigger>\n <MenubarSubContent>\n <MenubarItem>Search the web</MenubarItem>\n <MenubarSeparator />\n <MenubarItem>Find...</MenubarItem>\n <MenubarItem>Find Next</MenubarItem>\n <MenubarItem>Find Previous</MenubarItem>\n </MenubarSubContent>\n </MenubarSub>\n <MenubarSeparator />\n <MenubarItem>Cut</MenubarItem>\n <MenubarItem>Copy</MenubarItem>\n <MenubarItem>Paste</MenubarItem>\n </MenubarContent>\n </MenubarMenu>\n <MenubarMenu>\n <MenubarTrigger>View</MenubarTrigger>\n <MenubarContent>\n <MenubarCheckboxItem>Always Show Bookmarks Bar</MenubarCheckboxItem>\n <MenubarCheckboxItem checked>\n Always Show Full URLs\n </MenubarCheckboxItem>\n <MenubarSeparator />\n <MenubarItem inset>\n Reload <MenubarShortcut>⌘R</MenubarShortcut>\n </MenubarItem>\n <MenubarItem disabled inset>\n Force Reload <MenubarShortcut>⇧⌘R</MenubarShortcut>\n </MenubarItem>\n <MenubarSeparator />\n <MenubarItem inset>\n Toggle Fullscreen\n </MenubarItem>\n <MenubarSeparator />\n <MenubarItem inset>\n Hide Sidebar\n </MenubarItem>\n </MenubarContent>\n </MenubarMenu>\n <MenubarMenu>\n <MenubarTrigger>Profiles</MenubarTrigger>\n <MenubarContent>\n <MenubarRadioGroup value=\"benoit\">\n <MenubarRadioItem value=\"andy\">\n Andy\n </MenubarRadioItem>\n <MenubarRadioItem value=\"benoit\">\n Benoit\n </MenubarRadioItem>\n <MenubarRadioItem value=\"Luis\">\n Luis\n </MenubarRadioItem>\n </MenubarRadioGroup>\n <MenubarSeparator />\n <MenubarItem inset>\n Edit...\n </MenubarItem>\n <MenubarSeparator />\n <MenubarItem inset>\n Add Profile...\n </MenubarItem>\n </MenubarContent>\n </MenubarMenu>\n </Menubar>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NavigationMenuDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"navigation-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NavigationMenuDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n navigationMenuTriggerStyle,\n} from '@/registry/new-york/ui/navigation-menu'\n\nconst components: { title: string, href: string, description: string }[] = [\n {\n title: 'Alert Dialog',\n href: '/docs/components/alert-dialog',\n description:\n 'A modal dialog that interrupts the user with important content and expects a response.',\n },\n {\n title: 'Hover Card',\n href: '/docs/components/hover-card',\n description:\n 'For sighted users to preview content available behind a link.',\n },\n {\n title: 'Progress',\n href: '/docs/components/progress',\n description:\n 'Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.',\n },\n {\n title: 'Scroll-area',\n href: '/docs/components/scroll-area',\n description: 'Visually or semantically separates content.',\n },\n {\n title: 'Tabs',\n href: '/docs/components/tabs',\n description:\n 'A set of layered sections of content—known as tab panels—that are displayed one at a time.',\n },\n {\n title: 'Tooltip',\n href: '/docs/components/tooltip',\n description:\n 'A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.',\n },\n]\n</script>\n\n<template>\n <NavigationMenu>\n <NavigationMenuList>\n <NavigationMenuItem>\n <NavigationMenuTrigger>Getting started</NavigationMenuTrigger>\n <NavigationMenuContent>\n <ul class=\"grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[minmax(0,.75fr)_minmax(0,1fr)]\">\n <li class=\"row-span-3\">\n <NavigationMenuLink as-child>\n <a\n class=\"flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md\"\n href=\"/\"\n >\n <img src=\"https://www.reka-ui.com/logo.svg\" class=\"h-6 w-6\">\n <div class=\"mb-2 mt-4 text-lg font-medium\">\n shadcn/ui\n </div>\n <p class=\"text-sm leading-tight text-muted-foreground\">\n Beautifully designed components built with Radix UI and\n Tailwind CSS.\n </p>\n </a>\n </NavigationMenuLink>\n </li>\n\n <li>\n <NavigationMenuLink as-child>\n <a\n href=\"/docs/introduction\"\n class=\"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\"\n >\n <div class=\"text-sm font-medium leading-none\">Introduction</div>\n <p class=\"line-clamp-2 text-sm leading-snug text-muted-foreground\">\n Re-usable components built using Radix UI and Tailwind CSS.\n </p>\n </a>\n </NavigationMenuLink>\n </li>\n <li>\n <NavigationMenuLink as-child>\n <a\n href=\"/docs/installation\"\n class=\"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\"\n >\n <div class=\"text-sm font-medium leading-none\">Installation</div>\n <p class=\"line-clamp-2 text-sm leading-snug text-muted-foreground\">\n How to install dependencies and structure your app.\n </p>\n </a>\n </NavigationMenuLink>\n </li>\n <li>\n <NavigationMenuLink as-child>\n <a\n href=\"/docs/typography\"\n class=\"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\"\n >\n <div class=\"text-sm font-medium leading-none\">Typography</div>\n <p class=\"line-clamp-2 text-sm leading-snug text-muted-foreground\">\n Styles for headings, paragraphs, lists...etc\n </p>\n </a>\n </NavigationMenuLink>\n </li>\n </ul>\n </NavigationMenuContent>\n </NavigationMenuItem>\n <NavigationMenuItem>\n <NavigationMenuTrigger>Components</NavigationMenuTrigger>\n <NavigationMenuContent>\n <ul class=\"grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] \">\n <li v-for=\"component in components\" :key=\"component.title\">\n <NavigationMenuLink as-child>\n <a\n :href=\"component.href\"\n class=\"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\"\n >\n <div class=\"text-sm font-medium leading-none\">{{ component.title }}</div>\n <p class=\"line-clamp-2 text-sm leading-snug text-muted-foreground\">\n {{ component.description }}\n </p>\n </a>\n </NavigationMenuLink>\n </li>\n </ul>\n </NavigationMenuContent>\n </NavigationMenuItem>\n <NavigationMenuItem>\n <NavigationMenuLink href=\"/docs/introduction\" :class=\"navigationMenuTriggerStyle()\">\n Documentation\n </NavigationMenuLink>\n </NavigationMenuItem>\n </NavigationMenuList>\n </NavigationMenu>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NumberFieldCurrency",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"number-field"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NumberFieldCurrency.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n NumberField,\n NumberFieldContent,\n NumberFieldDecrement,\n NumberFieldIncrement,\n NumberFieldInput,\n} from '@/registry/new-york/ui/number-field'\n</script>\n\n<template>\n <NumberField\n id=\"balance\"\n :default-value=\"1500\"\n :format-options=\"{\n style: 'currency',\n currency: 'EUR',\n currencyDisplay: 'code',\n currencySign: 'accounting',\n }\"\n >\n <Label for=\"balance\">Balance</Label>\n <NumberFieldContent>\n <NumberFieldDecrement />\n <NumberFieldInput />\n <NumberFieldIncrement />\n </NumberFieldContent>\n </NumberField>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NumberFieldDecimal",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"number-field"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NumberFieldDecimal.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n NumberField,\n NumberFieldContent,\n NumberFieldDecrement,\n NumberFieldIncrement,\n NumberFieldInput,\n} from '@/registry/new-york/ui/number-field'\n</script>\n\n<template>\n <NumberField\n id=\"number\"\n :default-value=\"5\"\n :format-options=\"{\n signDisplay: 'exceptZero',\n minimumFractionDigits: 1,\n }\"\n >\n <Label for=\"number\">Number</Label>\n <NumberFieldContent>\n <NumberFieldDecrement />\n <NumberFieldInput />\n <NumberFieldIncrement />\n </NumberFieldContent>\n </NumberField>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NumberFieldDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"number-field"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NumberFieldDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n NumberField,\n NumberFieldContent,\n NumberFieldDecrement,\n NumberFieldIncrement,\n NumberFieldInput,\n} from '@/registry/new-york/ui/number-field'\n</script>\n\n<template>\n <NumberField id=\"age\" :default-value=\"18\" :min=\"0\">\n <Label for=\"age\">Age</Label>\n <NumberFieldContent>\n <NumberFieldDecrement />\n <NumberFieldInput />\n <NumberFieldIncrement />\n </NumberFieldContent>\n </NumberField>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NumberFieldDisabled",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"number-field"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NumberFieldDisabled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n NumberField,\n NumberFieldContent,\n NumberFieldDecrement,\n NumberFieldIncrement,\n NumberFieldInput,\n} from '@/registry/new-york/ui/number-field'\n</script>\n\n<template>\n <NumberField id=\"age-disabled\" :default-value=\"18\" disabled>\n <Label for=\"age-disabled\">Age</Label>\n <NumberFieldContent>\n <NumberFieldDecrement />\n <NumberFieldInput />\n <NumberFieldIncrement />\n </NumberFieldContent>\n </NumberField>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NumberFieldForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"number-field",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NumberFieldForm.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 NumberField,\n NumberFieldContent,\n NumberFieldDecrement,\n NumberFieldIncrement,\n NumberFieldInput,\n} from '@/registry/new-york/ui/number-field'\nimport { toast } from '@/registry/new-york/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n payment: z.number().min(10, 'Min 10 euros to send payment').max(5000, 'Max 5000 euros to send payment'),\n}))\n\nconst { handleSubmit, setFieldValue } = useForm({\n validationSchema: formSchema,\n initialValues: {\n payment: 10,\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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ value }\" name=\"payment\">\n <FormItem>\n <FormLabel>Payment</FormLabel>\n <NumberField\n class=\"gap-2\"\n :min=\"0\"\n :format-options=\"{\n style: 'currency',\n currency: 'EUR',\n currencyDisplay: 'code',\n currencySign: 'accounting',\n }\"\n :model-value=\"value\"\n @update:model-value=\"(v) => {\n if (v) {\n setFieldValue('payment', v)\n }\n else {\n setFieldValue('payment', undefined)\n }\n }\"\n >\n <NumberFieldContent>\n <NumberFieldDecrement />\n <FormControl>\n <NumberFieldInput />\n </FormControl>\n <NumberFieldIncrement />\n </NumberFieldContent>\n </NumberField>\n <FormDescription>\n Enter value between 10 and 5000.\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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NumberFieldPercentage",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"number-field"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NumberFieldPercentage.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n NumberField,\n NumberFieldContent,\n NumberFieldDecrement,\n NumberFieldIncrement,\n NumberFieldInput,\n} from '@/registry/new-york/ui/number-field'\n</script>\n\n<template>\n <NumberField\n id=\"percent\"\n :default-value=\"0.05\"\n :step=\"0.01\"\n :format-options=\"{\n style: 'percent',\n }\"\n >\n <Label for=\"percent\">Percent</Label>\n <NumberFieldContent>\n <NumberFieldDecrement />\n <NumberFieldInput />\n <NumberFieldIncrement />\n </NumberFieldContent>\n </NumberField>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PaginationDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"pagination"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PaginationDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Button,\n} from '@/registry/new-york/ui/button'\n\nimport {\n Pagination,\n PaginationEllipsis,\n PaginationFirst,\n PaginationLast,\n PaginationList,\n PaginationListItem,\n PaginationNext,\n PaginationPrev,\n} from '@/registry/new-york/ui/pagination'\n</script>\n\n<template>\n <Pagination v-slot=\"{ page }\" :items-per-page=\"10\" :total=\"100\" :sibling-count=\"1\" show-edges :default-page=\"2\">\n <PaginationList v-slot=\"{ items }\" class=\"flex items-center gap-1\">\n <PaginationFirst />\n <PaginationPrev />\n\n <template v-for=\"(item, index) in items\">\n <PaginationListItem v-if=\"item.type === 'page'\" :key=\"index\" :value=\"item.value\" as-child>\n <Button class=\"w-9 h-9 p-0\" :variant=\"item.value === page ? 'default' : 'outline'\">\n {{ item.value }}\n </Button>\n </PaginationListItem>\n <PaginationEllipsis v-else :key=\"item.type\" :index=\"index\" />\n </template>\n\n <PaginationNext />\n <PaginationLast />\n </PaginationList>\n </Pagination>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PinInputControlled",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"pin-input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PinInputControlled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n PinInput,\n PinInputGroup,\n PinInputInput,\n} from '@/registry/new-york/ui/pin-input'\nimport { ref } from 'vue'\n\nconst value = ref<string[]>(['1', '2', '3'])\nconst handleComplete = (e: string[]) => alert(e.join(''))\n</script>\n\n<template>\n <div>\n <PinInput\n id=\"pin-input\"\n v-model=\"value\"\n placeholder=\"○\"\n @complete=\"handleComplete\"\n >\n <PinInputGroup>\n <PinInputInput\n v-for=\"(id, index) in 5\"\n :key=\"id\"\n :index=\"index\"\n />\n </PinInputGroup>\n </PinInput>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PinInputDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"pin-input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PinInputDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n PinInput,\n PinInputGroup,\n PinInputInput,\n} from '@/registry/new-york/ui/pin-input'\nimport { ref } from 'vue'\n\nconst value = ref<string[]>([])\nconst handleComplete = (e: string[]) => alert(e.join(''))\n</script>\n\n<template>\n <div>\n <PinInput\n id=\"pin-input\"\n v-model=\"value\"\n placeholder=\"○\"\n @complete=\"handleComplete\"\n >\n <PinInputGroup>\n <PinInputInput\n v-for=\"(id, index) in 5\"\n :key=\"id\"\n :index=\"index\"\n />\n </PinInputGroup>\n </PinInput>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PinInputDisabled",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"pin-input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PinInputDisabled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n PinInput,\n PinInputGroup,\n PinInputInput,\n} from '@/registry/new-york/ui/pin-input'\nimport { ref } from 'vue'\n\nconst value = ref<string[]>([])\n</script>\n\n<template>\n <div>\n <PinInput\n id=\"pin-input\"\n v-model=\"value\"\n placeholder=\"○\"\n disabled\n >\n <PinInputGroup>\n <PinInputInput\n v-for=\"(id, index) in 5\"\n :key=\"id\"\n :index=\"index\"\n />\n </PinInputGroup>\n </PinInput>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PinInputFormDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"pin-input",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PinInputFormDemo.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 PinInput,\n PinInputGroup,\n PinInputInput,\n} from '@/registry/new-york/ui/pin-input'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n pin: z.array(z.coerce.string()).length(5, { message: 'Invalid input' }),\n}))\n\nconst { handleSubmit, setFieldValue } = useForm({\n validationSchema: formSchema,\n initialValues: {\n pin: ['1', '2', '3'],\n },\n})\n\nconst onSubmit = handleSubmit(({ pin }) => {\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(pin.join(''), null, 2))),\n })\n})\n\nconst handleComplete = (e: string[]) => console.log(e.join(''))\n</script>\n\n<template>\n <form class=\"w-2/3 space-y-6 mx-auto\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField, value }\" name=\"pin\">\n <FormItem>\n <FormLabel>OTP</FormLabel>\n <FormControl>\n <PinInput\n id=\"pin-input\"\n :model-value=\"value\"\n placeholder=\"○\"\n class=\"flex gap-2 items-center mt-1\"\n otp\n type=\"number\"\n :name=\"componentField.name\"\n @complete=\"handleComplete\"\n @update:model-value=\"(arrStr) => {\n setFieldValue('pin', arrStr.filter(Boolean))\n }\"\n >\n <PinInputGroup>\n <PinInputInput\n v-for=\"(id, index) in 5\"\n :key=\"id\"\n :index=\"index\"\n />\n </PinInputGroup>\n </PinInput>\n </FormControl>\n <FormDescription>\n Allows users to input a sequence of one-character alphanumeric inputs.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <Button>Submit</Button>\n </form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PinInputSeparatorDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"pin-input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PinInputSeparatorDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n PinInput,\n PinInputGroup,\n PinInputInput,\n PinInputSeparator,\n} from '@/registry/new-york/ui/pin-input'\nimport { ref } from 'vue'\n\nconst value = ref<string[]>([])\nconst handleComplete = (e: string[]) => alert(e.join(''))\n</script>\n\n<template>\n <div>\n <PinInput\n id=\"pin-input\"\n v-model=\"value\"\n placeholder=\"○\"\n @complete=\"handleComplete\"\n >\n <PinInputGroup class=\"gap-1\">\n <template v-for=\"(id, index) in 5\" :key=\"id\">\n <PinInputInput\n class=\"rounded-md border\"\n :index=\"index\"\n />\n <template v-if=\"index !== 4\">\n <PinInputSeparator />\n </template>\n </template>\n </PinInputGroup>\n </PinInput>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PopoverDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"input",
|
|
"label",
|
|
"popover"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PopoverDemo.vue",
|
|
"content": "<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'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/new-york/ui/popover'\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button variant=\"outline\">\n Open popover\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-80\">\n <div class=\"grid gap-4\">\n <div class=\"space-y-2\">\n <h4 class=\"font-medium leading-none\">\n Dimensions\n </h4>\n <p class=\"text-sm text-muted-foreground\">\n Set the dimensions for the layer.\n </p>\n </div>\n <div class=\"grid gap-2\">\n <div class=\"grid grid-cols-3 items-center gap-4\">\n <Label for=\"width\">Width</Label>\n <Input\n id=\"width\"\n type=\"text\"\n default-value=\"100%\"\n class=\"col-span-2 h-8\"\n />\n </div>\n <div class=\"grid grid-cols-3 items-center gap-4\">\n <Label for=\"maxWidth\">Max. width</Label>\n <Input\n id=\"maxWidth\"\n type=\"text\"\n default-value=\"300px\"\n class=\"col-span-2 h-8\"\n />\n </div>\n <div class=\"grid grid-cols-3 items-center gap-4\">\n <Label for=\"height\">Height</Label>\n <Input\n id=\"height\"\n type=\"text\"\n default-value=\"25px\"\n class=\"col-span-2 h-8\"\n />\n </div>\n <div class=\"grid grid-cols-3 items-center gap-4\">\n <Label for=\"maxHeight\">Max. height</Label>\n <Input\n id=\"maxHeight\"\n type=\"text\"\n default-value=\"none\"\n class=\"col-span-2 h-8\"\n />\n </div>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ProgressDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"progress"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ProgressDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Progress } from '@/registry/new-york/ui/progress'\nimport { ref, watchEffect } from 'vue'\n\nconst progress = ref(13)\n\nwatchEffect((cleanupFn) => {\n const timer = setTimeout(() => progress.value = 66, 500)\n cleanupFn(() => clearTimeout(timer))\n})\n</script>\n\n<template>\n <Progress v-model=\"progress\" class=\"w-3/5\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "RadioGroupDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"radio-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/RadioGroupDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/new-york/ui/label'\nimport { RadioGroup, RadioGroupItem } from '@/registry/new-york/ui/radio-group'\n</script>\n\n<template>\n <RadioGroup default-value=\"comfortable\" :orientation=\"'vertical'\">\n <div class=\"flex items-center space-x-2\">\n <RadioGroupItem id=\"r1\" value=\"default\" />\n <Label for=\"r1\">Default</Label>\n </div>\n <div class=\"flex items-center space-x-2\">\n <RadioGroupItem id=\"r2\" value=\"comfortable\" />\n <Label for=\"r2\">Comfortable</Label>\n </div>\n <div class=\"flex items-center space-x-2\">\n <RadioGroupItem id=\"r3\" value=\"compact\" />\n <Label for=\"r3\">Compact</Label>\n </div>\n </RadioGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "RadioGroupForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"radio-group",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/RadioGroupForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/new-york/ui/form'\nimport { RadioGroup, RadioGroupItem } from '@/registry/new-york/ui/radio-group'\nimport { toast } from '@/registry/new-york/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n type: z.enum(['all', 'mentions', 'none'], {\n required_error: 'You need to select a notification type.',\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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField }\" type=\"radio\" name=\"type\">\n <FormItem class=\"space-y-3\">\n <FormLabel>Notify me about...</FormLabel>\n\n <FormControl>\n <RadioGroup\n class=\"flex flex-col space-y-1\"\n v-bind=\"componentField\"\n >\n <FormItem class=\"flex items-center space-y-0 gap-x-3\">\n <FormControl>\n <RadioGroupItem value=\"all\" />\n </FormControl>\n <FormLabel class=\"font-normal\">\n All new messages\n </FormLabel>\n </FormItem>\n <FormItem class=\"flex items-center space-y-0 gap-x-3\">\n <FormControl>\n <RadioGroupItem value=\"mentions\" />\n </FormControl>\n <FormLabel class=\"font-normal\">\n Direct messages and mentions\n </FormLabel>\n </FormItem>\n <FormItem class=\"flex items-center space-y-0 gap-x-3\">\n <FormControl>\n <RadioGroupItem value=\"none\" />\n </FormControl>\n <FormLabel class=\"font-normal\">\n Nothing\n </FormLabel>\n </FormItem>\n </RadioGroup>\n </FormControl>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <Button type=\"submit\">\n Submit\n </Button>\n </form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "RangeCalendarDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"range-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/RangeCalendarDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { DateRange } from 'reka-ui'\nimport { RangeCalendar } from '@/registry/new-york/ui/range-calendar'\nimport { getLocalTimeZone, today } from '@internationalized/date'\nimport { type Ref, ref } from 'vue'\n\nconst start = today(getLocalTimeZone())\nconst end = start.add({ days: 7 })\n\nconst value = ref({\n start,\n end,\n}) as Ref<DateRange>\n</script>\n\n<template>\n <RangeCalendar v-model=\"value\" class=\"rounded-md border\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ResizableDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"resizable"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ResizableDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from '@/registry/new-york/ui/resizable'\n</script>\n\n<template>\n <ResizablePanelGroup\n id=\"demo-group-1\"\n direction=\"horizontal\"\n class=\"max-w-md rounded-lg border\"\n >\n <ResizablePanel id=\"demo-panel-1\" :default-size=\"50\">\n <div class=\"flex h-[200px] items-center justify-center p-6\">\n <span class=\"font-semibold\">One</span>\n </div>\n </ResizablePanel>\n <ResizableHandle id=\"demo-handle-1\" />\n <ResizablePanel id=\"demo-panel-2\" :default-size=\"50\">\n <ResizablePanelGroup id=\"demo-group-2\" direction=\"vertical\">\n <ResizablePanel id=\"demo-panel-3\" :default-size=\"25\">\n <div class=\"flex h-full items-center justify-center p-6\">\n <span class=\"font-semibold\">Two</span>\n </div>\n </ResizablePanel>\n <ResizableHandle id=\"demo-handle-2\" />\n <ResizablePanel id=\"demo-panel-4\" :default-size=\"75\">\n <div class=\"flex h-full items-center justify-center p-6\">\n <span class=\"font-semibold\">Three</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n </ResizablePanelGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ResizableHandleDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"resizable"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ResizableHandleDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from '@/registry/new-york/ui/resizable'\n</script>\n\n<template>\n <ResizablePanelGroup\n id=\"handle-demo-group-1\"\n direction=\"horizontal\"\n class=\"min-h-[200px] max-w-md rounded-lg border\"\n >\n <ResizablePanel id=\"handle-demo-panel-1\" :default-size=\"25\">\n <div class=\"flex h-full items-center justify-center p-6\">\n <span class=\"font-semibold\">Sidebar</span>\n </div>\n </ResizablePanel>\n <ResizableHandle id=\"handle-demo-handle-1\" with-handle />\n <ResizablePanel id=\"handle-demo-panel-2\" :default-size=\"75\">\n <div class=\"flex h-full items-center justify-center p-6\">\n <span class=\"font-semibold\">Content</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ResizableVerticalDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"resizable"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ResizableVerticalDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from '@/registry/new-york/ui/resizable'\n</script>\n\n<template>\n <ResizablePanelGroup\n id=\"vertical-demo-group-1\"\n direction=\"vertical\"\n class=\"min-h-[200px] max-w-md rounded-lg border\"\n >\n <ResizablePanel id=\"vertical-demo-panel-1\" :default-size=\"25\">\n <div class=\"flex h-full items-center justify-center p-6\">\n <span class=\"font-semibold\">Header</span>\n </div>\n </ResizablePanel>\n <ResizableHandle id=\"vertical-demo-handle-1\" />\n <ResizablePanel id=\"vertical-demo-panel-2\" :default-size=\"75\">\n <div class=\"flex h-full items-center justify-center p-6\">\n <span class=\"font-semibold\">Content</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ScrollAreaDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"scroll-area",
|
|
"separator"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ScrollAreaDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ScrollArea } from '@/registry/new-york/ui/scroll-area'\nimport { Separator } from '@/registry/new-york/ui/separator'\n\nconst tags = Array.from({ length: 50 }).map(\n (_, i, a) => `v1.2.0-beta.${a.length - i}`,\n)\n</script>\n\n<template>\n <ScrollArea class=\"h-72 w-48 rounded-md border\">\n <div class=\"p-4\">\n <h4 class=\"mb-4 text-sm font-medium leading-none\">\n Tags\n </h4>\n\n <div v-for=\"tag in tags\" :key=\"tag\">\n <div class=\"text-sm\">\n {{ tag }}\n </div>\n <Separator class=\"my-2\" />\n </div>\n </div>\n </ScrollArea>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ScrollAreaHorizontalDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"scroll-area"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ScrollAreaHorizontalDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ScrollArea, ScrollBar } from '@/registry/new-york/ui/scroll-area'\n\ninterface Artwork {\n id: string\n artist: string\n art: string\n}\n\nconst works: Artwork[] = [\n {\n id: '1',\n artist: 'Ornella Binni',\n art: 'https://images.unsplash.com/photo-1465869185982-5a1a7522cbcb?auto=format&fit=crop&w=300&q=80',\n },\n {\n id: '2',\n artist: 'Tom Byrom',\n art: 'https://images.unsplash.com/photo-1548516173-3cabfa4607e9?auto=format&fit=crop&w=300&q=80',\n },\n {\n id: '3',\n artist: 'Vladimir Malyavko',\n art: 'https://images.unsplash.com/photo-1494337480532-3725c85fd2ab?auto=format&fit=crop&w=300&q=80',\n },\n]\n</script>\n\n<template>\n <ScrollArea class=\"border rounded-md w-96 whitespace-nowrap\">\n <div class=\"flex p-4 space-x-4 w-max\">\n <div v-for=\"artwork in works\" :key=\"artwork.id\">\n <figure class=\"shrink-0\">\n <div class=\"overflow-hidden rounded-md\">\n <img\n :src=\"artwork.art\"\n :alt=\"`Photo by ${artwork.artist}`\"\n class=\"aspect-[3/4] w-36 h-56 object-cover\"\n >\n </div>\n <figcaption class=\"pt-2 text-xs text-muted-foreground\">\n Photo by\n <span class=\"font-semibold text-foreground\">\n {{ artwork.artist }}\n </span>\n </figcaption>\n </figure>\n </div>\n </div>\n <ScrollBar orientation=\"horizontal\" />\n </ScrollArea>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SelectDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"select"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SelectDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n} from '@/registry/new-york/ui/select'\n</script>\n\n<template>\n <Select>\n <SelectTrigger class=\"w-[180px]\">\n <SelectValue placeholder=\"Select a fruit\" />\n </SelectTrigger>\n <SelectContent>\n <SelectGroup>\n <SelectLabel>Fruits</SelectLabel>\n <SelectItem value=\"apple\">\n Apple\n </SelectItem>\n <SelectItem value=\"banana\">\n Banana\n </SelectItem>\n <SelectItem value=\"blueberry\">\n Blueberry\n </SelectItem>\n <SelectItem value=\"grapes\">\n Grapes\n </SelectItem>\n <SelectItem value=\"pineapple\">\n Pineapple\n </SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SelectForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"select",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SelectForm.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 Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/new-york/ui/select'\nimport { toast } from '@/registry/new-york/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n email: z\n .string({\n required_error: 'Please select an email to display.',\n })\n .email(),\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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField }\" name=\"email\">\n <FormItem>\n <FormLabel>Email</FormLabel>\n\n <Select v-bind=\"componentField\">\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select a verified email to display\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n <SelectGroup>\n <SelectItem value=\"m@example.com\">\n m@example.com\n </SelectItem>\n <SelectItem value=\"m@google.com\">\n m@google.com\n </SelectItem>\n <SelectItem value=\"m@support.com\">\n m@support.com\n </SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n <FormDescription>\n You can manage email addresses in your\n <a href=\"/examples/forms\">email settings</a>.\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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SelectScrollable",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"select"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SelectScrollable.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n} from '@/registry/new-york/ui/select'\n</script>\n\n<template>\n <Select>\n <SelectTrigger class=\"w-[280px]\">\n <SelectValue placeholder=\"Select a timezone\" />\n </SelectTrigger>\n <SelectContent>\n <SelectGroup>\n <SelectLabel>North America</SelectLabel>\n <SelectItem value=\"est\">\n Eastern Standard Time (EST)\n </SelectItem>\n <SelectItem value=\"cst\">\n Central Standard Time (CST)\n </SelectItem>\n <SelectItem value=\"mst\">\n Mountain Standard Time (MST)\n </SelectItem>\n <SelectItem value=\"pst\">\n Pacific Standard Time (PST)\n </SelectItem>\n <SelectItem value=\"akst\">\n Alaska Standard Time (AKST)\n </SelectItem>\n <SelectItem value=\"hst\">\n Hawaii Standard Time (HST)\n </SelectItem>\n </SelectGroup>\n <SelectGroup>\n <SelectLabel>Europe & Africa</SelectLabel>\n <SelectItem value=\"gmt\">\n Greenwich Mean Time (GMT)\n </SelectItem>\n <SelectItem value=\"cet\">\n Central European Time (CET)\n </SelectItem>\n <SelectItem value=\"eet\">\n Eastern European Time (EET)\n </SelectItem>\n <SelectItem value=\"west\">\n Western European Summer Time (WEST)\n </SelectItem>\n <SelectItem value=\"cat\">\n Central Africa Time (CAT)\n </SelectItem>\n <SelectItem value=\"eat\">\n East Africa Time (EAT)\n </SelectItem>\n </SelectGroup>\n <SelectGroup>\n <SelectLabel>Asia</SelectLabel>\n <SelectItem value=\"msk\">\n Moscow Time (MSK)\n </SelectItem>\n <SelectItem value=\"ist\">\n India Standard Time (IST)\n </SelectItem>\n <SelectItem value=\"cst_china\">\n China Standard Time (CST)\n </SelectItem>\n <SelectItem value=\"jst\">\n Japan Standard Time (JST)\n </SelectItem>\n <SelectItem value=\"kst\">\n Korea Standard Time (KST)\n </SelectItem>\n <SelectItem value=\"ist_indonesia\">\n Indonesia Central Standard Time (WITA)\n </SelectItem>\n </SelectGroup>\n <SelectGroup>\n <SelectLabel>Australia & Pacific</SelectLabel>\n <SelectItem value=\"awst\">\n Australian Western Standard Time (AWST)\n </SelectItem>\n <SelectItem value=\"acst\">\n Australian Central Standard Time (ACST)\n </SelectItem>\n <SelectItem value=\"aest\">\n Australian Eastern Standard Time (AEST)\n </SelectItem>\n <SelectItem value=\"nzst\">\n New Zealand Standard Time (NZST)\n </SelectItem>\n <SelectItem value=\"fjt\">\n Fiji Time (FJT)\n </SelectItem>\n </SelectGroup>\n <SelectGroup>\n <SelectLabel>South America</SelectLabel>\n <SelectItem value=\"art\">\n Argentina Time (ART)\n </SelectItem>\n <SelectItem value=\"bot\">\n Bolivia Time (BOT)\n </SelectItem>\n <SelectItem value=\"brt\">\n Brasilia Time (BRT)\n </SelectItem>\n <SelectItem value=\"clt\">\n Chile Standard Time (CLT)\n </SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SeparatorDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"separator"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SeparatorDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Separator } from '@/registry/new-york/ui/separator'\n</script>\n\n<template>\n <div>\n <div class=\"space-y-1\">\n <h4 class=\"text-sm font-medium leading-none\">\n Radix Primitives\n </h4>\n <p class=\"text-sm text-muted-foreground\">\n An open-source UI component library.\n </p>\n </div>\n <Separator class=\"my-4\" label=\"Or\" />\n <div class=\"flex h-5 items-center space-x-4 text-sm\">\n <div>Blog</div>\n <Separator orientation=\"vertical\" />\n <div>Docs</div>\n <Separator orientation=\"vertical\" />\n <div>Source</div>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SheetDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"input",
|
|
"label",
|
|
"sheet"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SheetDemo.vue",
|
|
"content": "<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'\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from '@/registry/new-york/ui/sheet'\n</script>\n\n<template>\n <Sheet>\n <SheetTrigger as-child>\n <Button variant=\"outline\">\n Open\n </Button>\n </SheetTrigger>\n <SheetContent>\n <SheetHeader>\n <SheetTitle>Edit profile</SheetTitle>\n <SheetDescription>\n Make changes to your profile here. Click save when you're done.\n </SheetDescription>\n </SheetHeader>\n <div class=\"grid gap-4 py-4\">\n <div class=\"grid grid-cols-4 items-center gap-4\">\n <Label for=\"name\" class=\"text-right\">\n Name\n </Label>\n <Input id=\"name\" value=\"Pedro Duarte\" class=\"col-span-3\" />\n </div>\n <div class=\"grid grid-cols-4 items-center gap-4\">\n <Label for=\"username\" class=\"text-right\">\n Username\n </Label>\n <Input id=\"username\" value=\"@peduarte\" class=\"col-span-3\" />\n </div>\n </div>\n <SheetFooter>\n <SheetClose as-child>\n <Button type=\"submit\">\n Save changes\n </Button>\n </SheetClose>\n </SheetFooter>\n </SheetContent>\n </Sheet>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SheetSideDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"input",
|
|
"label",
|
|
"sheet"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SheetSideDemo.vue",
|
|
"content": "<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'\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from '@/registry/new-york/ui/sheet'\nimport { ref } from 'vue'\n\nconst SHEET_SIDES = ['top', 'right', 'bottom', 'left'] as const\n\nconst username = ref('')\n</script>\n\n<template>\n <div class=\"grid grid-cols-2 gap-2\">\n <Sheet v-for=\"side in SHEET_SIDES\" :key=\"side\">\n <SheetTrigger as-child>\n <Button variant=\"outline\">\n {{ side }}\n </Button>\n </SheetTrigger>\n <SheetContent :side=\"side\">\n <SheetHeader>\n <SheetTitle>Edit profile</SheetTitle>\n <SheetDescription>\n Make changes to your profile here. Click save when you're done.\n </SheetDescription>\n </SheetHeader>\n <div class=\"grid gap-4 py-4\">\n <div class=\"grid items-center grid-cols-4 gap-4\">\n <Label for=\"name\" class=\"text-right\">Name</Label>\n <Input id=\"name\" v-model=\"username\" class=\"col-span-3\" />\n </div>\n <div class=\"grid items-center grid-cols-4 gap-4\">\n <Label for=\"username\" class=\"text-right\">Username</Label>\n <Input id=\"username\" v-model=\"username\" class=\"col-span-3\" />\n </div>\n </div>\n <SheetFooter>\n <SheetClose as-child>\n <Button type=\"submit\">\n Save changes\n </Button>\n </SheetClose>\n </SheetFooter>\n </SheetContent>\n </Sheet>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SkeletonCard",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"skeleton"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SkeletonCard.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { Skeleton } from '@/registry/new-york/ui/skeleton'\n</script>\n\n<template>\n <div class=\"flex flex-col space-y-3\">\n <Skeleton class=\"h-[125px] w-[250px] rounded-xl\" />\n <div class=\"space-y-2\">\n <Skeleton class=\"h-4 w-[250px]\" />\n <Skeleton class=\"h-4 w-[200px]\" />\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SkeletonDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"skeleton"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SkeletonDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Skeleton } from '@/registry/new-york/ui/skeleton'\n</script>\n\n<template>\n <div class=\"flex items-center space-x-4\">\n <Skeleton class=\"h-12 w-12 rounded-full\" />\n <div class=\"space-y-2\">\n <Skeleton class=\"h-4 w-[250px]\" />\n <Skeleton class=\"h-4 w-[200px]\" />\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SliderDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"slider"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SliderDemo.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SliderForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"slider",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SliderForm.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 { Slider } from '@/registry/new-york/ui/slider'\nimport { toast } from '@/registry/new-york/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n duration: z.array(\n z.number().min(0).max(60),\n ),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n initialValues: {\n duration: [30],\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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField, value }\" name=\"duration\">\n <FormItem>\n <FormLabel>Duration</FormLabel>\n <FormControl>\n <Slider\n v-bind=\"componentField\"\n :default-value=\"[30]\"\n :max=\"100\"\n :min=\"0\"\n :step=\"5\"\n />\n <FormDescription class=\"flex justify-between\">\n <span>How many minutes are you available?</span>\n <span>{{ value?.[0] }} min</span>\n </FormDescription>\n </FormControl>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <Button type=\"submit\">\n Submit\n </Button>\n </form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SonnerDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vue-sonner"
|
|
],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SonnerDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/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",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SonnerWithDialog",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vue-sonner"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SonnerWithDialog.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/new-york/ui/dialog'\nimport { toast } from 'vue-sonner'\n</script>\n\n<template>\n <Dialog>\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Dialog with toast\n </Button>\n </DialogTrigger>\n <DialogContent\n class=\"sm:max-w-md\"\n @interact-outside=\"event => {\n const target = event.target as HTMLElement;\n if (target?.closest('[data-sonner-toaster]')) return event.preventDefault()\n }\"\n >\n <DialogHeader>\n <DialogTitle>Vue Sonner Toast</DialogTitle>\n <DialogDescription> Dialog with toast </DialogDescription>\n </DialogHeader>\n <div class=\"grid gap-4\">\n <Button\n size=\"sm\"\n class=\"px-3\"\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 Toast\n </Button>\n </div>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "StepperDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"stepper"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/StepperDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Stepper, StepperDescription, StepperIndicator, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/registry/new-york/ui/stepper'\n\nimport { BookUser, Check, CreditCard, Truck } from 'lucide-vue-next'\n\nconst steps = [{\n step: 1,\n title: 'Address',\n description: 'Add your address here',\n icon: BookUser,\n}, {\n step: 2,\n title: 'Shipping',\n description: 'Set your preferred shipping method',\n icon: Truck,\n}, {\n step: 3,\n title: 'Payment',\n description: 'Add any payment information you have',\n icon: CreditCard,\n}, {\n step: 4,\n title: 'Checkout',\n description: 'Confirm your order',\n icon: Check,\n}]\n</script>\n\n<template>\n <Stepper>\n <StepperItem\n v-for=\"item in steps\"\n :key=\"item.step\"\n class=\"basis-1/4\"\n :step=\"item.step\"\n >\n <StepperTrigger>\n <StepperIndicator>\n <component :is=\"item.icon\" class=\"w-4 h-4\" />\n </StepperIndicator>\n <div class=\"flex flex-col\">\n <StepperTitle>\n {{ item.title }}\n </StepperTitle>\n <StepperDescription>\n {{ item.description }}\n </StepperDescription>\n </div>\n </StepperTrigger>\n <StepperSeparator\n v-if=\"item.step !== steps[steps.length - 1].step\"\n class=\"w-full h-px\"\n />\n </StepperItem>\n </Stepper>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "StepperForm",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"input",
|
|
"select",
|
|
"stepper",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/StepperForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/registry/new-york/ui/form'\nimport { Input } from '@/registry/new-york/ui/input'\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/new-york/ui/select'\nimport { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/registry/new-york/ui/stepper'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { CheckIcon, CircleIcon, DotIcon } from '@radix-icons/vue'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { h, ref } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = [\n z.object({\n fullName: z.string(),\n email: z.string().email(),\n }),\n z.object({\n password: z.string().min(2).max(50),\n confirmPassword: z.string(),\n }).refine(\n (values) => {\n return values.password === values.confirmPassword\n },\n {\n message: 'Passwords must match!',\n path: ['confirmPassword'],\n },\n ),\n z.object({\n favoriteDrink: z.union([z.literal('coffee'), z.literal('tea'), z.literal('soda')]),\n }),\n]\n\nconst stepIndex = ref(1)\nconst steps = [\n {\n step: 1,\n title: 'Your details',\n description: 'Provide your name and email',\n },\n {\n step: 2,\n title: 'Your password',\n description: 'Choose a password',\n },\n {\n step: 3,\n title: 'Your Favorite Drink',\n description: 'Choose a drink',\n },\n]\n\nfunction onSubmit(values: any) {\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\n v-slot=\"{ meta, values, validate }\"\n as=\"\" keep-values :validation-schema=\"toTypedSchema(formSchema[stepIndex - 1])\"\n >\n <Stepper v-slot=\"{ isNextDisabled, isPrevDisabled, nextStep, prevStep }\" v-model=\"stepIndex\" class=\"block w-full\">\n <form\n @submit=\"(e) => {\n e.preventDefault()\n validate()\n\n if (stepIndex === steps.length && meta.valid) {\n onSubmit(values)\n }\n }\"\n >\n <div class=\"flex w-full flex-start gap-2\">\n <StepperItem\n v-for=\"step in steps\"\n :key=\"step.step\"\n v-slot=\"{ state }\"\n class=\"relative flex w-full flex-col items-center justify-center\"\n :step=\"step.step\"\n >\n <StepperSeparator\n v-if=\"step.step !== steps[steps.length - 1].step\"\n class=\"absolute left-[calc(50%+20px)] right-[calc(-50%+10px)] top-5 block h-0.5 shrink-0 rounded-full bg-muted group-data-[state=completed]:bg-primary\"\n />\n\n <StepperTrigger as-child>\n <Button\n :variant=\"state === 'completed' || state === 'active' ? 'default' : 'outline'\"\n size=\"icon\"\n class=\"z-10 rounded-full shrink-0\"\n :class=\"[state === 'active' && 'ring-2 ring-ring ring-offset-2 ring-offset-background']\"\n :disabled=\"state !== 'completed' && !meta.valid\"\n >\n <CheckIcon v-if=\"state === 'completed'\" class=\"size-5\" />\n <CircleIcon v-if=\"state === 'active'\" />\n <DotIcon v-if=\"state === 'inactive'\" />\n </Button>\n </StepperTrigger>\n\n <div class=\"mt-5 flex flex-col items-center text-center\">\n <StepperTitle\n :class=\"[state === 'active' && 'text-primary']\"\n class=\"text-sm font-semibold transition lg:text-base\"\n >\n {{ step.title }}\n </StepperTitle>\n <StepperDescription\n :class=\"[state === 'active' && 'text-primary']\"\n class=\"sr-only text-xs text-muted-foreground transition md:not-sr-only lg:text-sm\"\n >\n {{ step.description }}\n </StepperDescription>\n </div>\n </StepperItem>\n </div>\n\n <div class=\"flex flex-col gap-4 mt-4\">\n <template v-if=\"stepIndex === 1\">\n <FormField v-slot=\"{ componentField }\" name=\"fullName\">\n <FormItem>\n <FormLabel>Full Name</FormLabel>\n <FormControl>\n <Input type=\"text\" v-bind=\"componentField\" />\n </FormControl>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <FormField v-slot=\"{ componentField }\" name=\"email\">\n <FormItem>\n <FormLabel>Email</FormLabel>\n <FormControl>\n <Input type=\"email \" v-bind=\"componentField\" />\n </FormControl>\n <FormMessage />\n </FormItem>\n </FormField>\n </template>\n\n <template v-if=\"stepIndex === 2\">\n <FormField v-slot=\"{ componentField }\" name=\"password\">\n <FormItem>\n <FormLabel>Password</FormLabel>\n <FormControl>\n <Input type=\"password\" v-bind=\"componentField\" />\n </FormControl>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <FormField v-slot=\"{ componentField }\" name=\"confirmPassword\">\n <FormItem>\n <FormLabel>Confirm Password</FormLabel>\n <FormControl>\n <Input type=\"password\" v-bind=\"componentField\" />\n </FormControl>\n <FormMessage />\n </FormItem>\n </FormField>\n </template>\n\n <template v-if=\"stepIndex === 3\">\n <FormField v-slot=\"{ componentField }\" name=\"favoriteDrink\">\n <FormItem>\n <FormLabel>Drink</FormLabel>\n\n <Select v-bind=\"componentField\">\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select a drink\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n <SelectGroup>\n <SelectItem value=\"coffee\">\n Coffe\n </SelectItem>\n <SelectItem value=\"tea\">\n Tea\n </SelectItem>\n <SelectItem value=\"soda\">\n Soda\n </SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n <FormMessage />\n </FormItem>\n </FormField>\n </template>\n </div>\n\n <div class=\"flex items-center justify-between mt-4\">\n <Button :disabled=\"isPrevDisabled\" variant=\"outline\" size=\"sm\" @click=\"prevStep()\">\n Back\n </Button>\n <div class=\"flex items-center gap-3\">\n <Button v-if=\"stepIndex !== 3\" :type=\"meta.valid ? 'button' : 'submit'\" :disabled=\"isNextDisabled\" size=\"sm\" @click=\"meta.valid && nextStep()\">\n Next\n </Button>\n <Button\n v-if=\"stepIndex === 3\" size=\"sm\" type=\"submit\"\n >\n Submit\n </Button>\n </div>\n </div>\n </form>\n </Stepper>\n </Form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "StepperHorizental",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"stepper"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/StepperHorizental.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\n\nimport { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/registry/new-york/ui/stepper'\nimport { CheckIcon, CircleIcon, DotIcon } from '@radix-icons/vue'\n\nconst steps = [\n {\n step: 1,\n title: 'Your details',\n description: 'Provide your name and email',\n },\n {\n step: 2,\n title: 'Company details',\n description: 'A few details about your company',\n },\n {\n step: 3,\n title: 'Invite your team',\n description: 'Start collaborating with your team',\n },\n]\n</script>\n\n<template>\n <Stepper class=\"flex w-full items-start gap-2\">\n <StepperItem\n v-for=\"step in steps\"\n :key=\"step.step\"\n v-slot=\"{ state }\"\n class=\"relative flex w-full flex-col items-center justify-center\"\n :step=\"step.step\"\n >\n <StepperSeparator\n v-if=\"step.step !== steps[steps.length - 1].step\"\n class=\"absolute left-[calc(50%+20px)] right-[calc(-50%+10px)] top-5 block h-0.5 shrink-0 rounded-full bg-muted group-data-[state=completed]:bg-primary\"\n />\n\n <StepperTrigger as-child>\n <Button\n :variant=\"state === 'completed' || state === 'active' ? 'default' : 'outline'\"\n size=\"icon\"\n class=\"z-10 rounded-full shrink-0\"\n :class=\"[state === 'active' && 'ring-2 ring-ring ring-offset-2 ring-offset-background']\"\n >\n <CheckIcon v-if=\"state === 'completed'\" class=\"size-5\" />\n <CircleIcon v-if=\"state === 'active'\" />\n <DotIcon v-if=\"state === 'inactive'\" />\n </Button>\n </StepperTrigger>\n\n <div class=\"mt-5 flex flex-col items-center text-center\">\n <StepperTitle\n :class=\"[state === 'active' && 'text-primary']\"\n class=\"text-sm font-semibold transition lg:text-base\"\n >\n {{ step.title }}\n </StepperTitle>\n <StepperDescription\n :class=\"[state === 'active' && 'text-primary']\"\n class=\"sr-only text-xs text-muted-foreground transition md:not-sr-only lg:text-sm\"\n >\n {{ step.description }}\n </StepperDescription>\n </div>\n </StepperItem>\n </Stepper>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "StepperVertical",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"stepper"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/StepperVertical.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\n\nimport { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/registry/new-york/ui/stepper'\nimport { CheckIcon, CircleIcon, DotIcon } from '@radix-icons/vue'\n\nconst steps = [\n {\n step: 1,\n title: 'Your details',\n description:\n 'Provide your name and email address. We will use this information to create your account',\n },\n {\n step: 2,\n title: 'Company details',\n description: 'A few details about your company will help us personalize your experience',\n },\n {\n step: 3,\n title: 'Invite your team',\n description:\n 'Start collaborating with your team by inviting them to join your account. You can skip this step and invite them later',\n },\n]\n</script>\n\n<template>\n <Stepper orientation=\"vertical\" class=\"mx-auto flex w-full max-w-md flex-col justify-start gap-10\">\n <StepperItem\n v-for=\"step in steps\"\n :key=\"step.step\"\n v-slot=\"{ state }\"\n class=\"relative flex w-full items-start gap-6\"\n :step=\"step.step\"\n >\n <StepperSeparator\n v-if=\"step.step !== steps[steps.length - 1].step\"\n class=\"absolute left-[18px] top-[38px] block h-[105%] w-0.5 shrink-0 rounded-full bg-muted group-data-[state=completed]:bg-primary\"\n />\n\n <StepperTrigger as-child>\n <Button\n :variant=\"state === 'completed' || state === 'active' ? 'default' : 'outline'\"\n size=\"icon\"\n class=\"z-10 rounded-full shrink-0\"\n :class=\"[state === 'active' && 'ring-2 ring-ring ring-offset-2 ring-offset-background']\"\n >\n <CheckIcon v-if=\"state === 'completed'\" class=\"size-5\" />\n <CircleIcon v-if=\"state === 'active'\" />\n <DotIcon v-if=\"state === 'inactive'\" />\n </Button>\n </StepperTrigger>\n\n <div class=\"flex flex-col gap-1\">\n <StepperTitle\n :class=\"[state === 'active' && 'text-primary']\"\n class=\"text-sm font-semibold transition lg:text-base\"\n >\n {{ step.title }}\n </StepperTitle>\n <StepperDescription\n :class=\"[state === 'active' && 'text-primary']\"\n class=\"sr-only text-xs text-muted-foreground transition md:not-sr-only lg:text-sm\"\n >\n {{ step.description }}\n </StepperDescription>\n </div>\n </StepperItem>\n </Stepper>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SwitchDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"switch"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SwitchDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/new-york/ui/label'\nimport { Switch } from '@/registry/new-york/ui/switch'\n</script>\n\n<template>\n <div class=\"flex items-center space-x-2\">\n <Switch id=\"airplane-mode\" />\n <Label for=\"airplane-mode\">Airplane Mode</Label>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SwitchForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"switch",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SwitchForm.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} from '@/registry/new-york/ui/form'\nimport { Switch } from '@/registry/new-york/ui/switch'\nimport { toast } from '@/registry/new-york/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n marketing_emails: z.boolean().default(false).optional(),\n security_emails: z.boolean(),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n initialValues: {\n security_emails: true,\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=\"w-full space-y-6\" @submit=\"onSubmit\">\n <div>\n <h3 class=\"mb-4 text-lg font-medium\">\n Email Notifications\n </h3>\n\n <div class=\"space-y-4\">\n <FormField v-slot=\"{ value, handleChange }\" name=\"marketing_emails\">\n <FormItem class=\"flex flex-row items-center justify-between rounded-lg border p-4\">\n <div class=\"space-y-0.5\">\n <FormLabel class=\"text-base\">\n Marketing emails\n </FormLabel>\n <FormDescription>\n Receive emails about new products, features, and more.\n </FormDescription>\n </div>\n <FormControl>\n <Switch\n :model-value=\"value\"\n @update:model-value=\"handleChange\"\n />\n </FormControl>\n </FormItem>\n </FormField>\n <FormField v-slot=\"{ value, handleChange }\" name=\"security_emails\">\n <FormItem class=\"flex flex-row items-center justify-between rounded-lg border p-4\">\n <div class=\"space-y-0.5\">\n <FormLabel class=\"text-base\">\n Security emails\n </FormLabel>\n <FormDescription>\n Receive emails about your account security.\n </FormDescription>\n </div>\n <FormControl>\n <Switch\n :model-value=\"value\"\n disabled\n aria-readonly\n @update:model-value=\"handleChange\"\n />\n </FormControl>\n </FormItem>\n </FormField>\n </div>\n </div>\n <Button type=\"submit\">\n Submit\n </Button>\n </form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TableDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"table"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TableDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Table,\n TableBody,\n TableCaption,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/new-york/ui/table'\n\nconst invoices = [\n {\n invoice: 'INV001',\n paymentStatus: 'Paid',\n totalAmount: '$250.00',\n paymentMethod: 'Credit Card',\n },\n {\n invoice: 'INV002',\n paymentStatus: 'Pending',\n totalAmount: '$150.00',\n paymentMethod: 'PayPal',\n },\n {\n invoice: 'INV003',\n paymentStatus: 'Unpaid',\n totalAmount: '$350.00',\n paymentMethod: 'Bank Transfer',\n },\n {\n invoice: 'INV004',\n paymentStatus: 'Paid',\n totalAmount: '$450.00',\n paymentMethod: 'Credit Card',\n },\n {\n invoice: 'INV005',\n paymentStatus: 'Paid',\n totalAmount: '$550.00',\n paymentMethod: 'PayPal',\n },\n {\n invoice: 'INV006',\n paymentStatus: 'Pending',\n totalAmount: '$200.00',\n paymentMethod: 'Bank Transfer',\n },\n {\n invoice: 'INV007',\n paymentStatus: 'Unpaid',\n totalAmount: '$300.00',\n paymentMethod: 'Credit Card',\n },\n]\n</script>\n\n<template>\n <Table>\n <TableCaption>A list of your recent invoices.</TableCaption>\n <TableHeader>\n <TableRow>\n <TableHead class=\"w-[100px]\">\n Invoice\n </TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Method</TableHead>\n <TableHead class=\"text-right\">\n Amount\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <TableRow v-for=\"invoice in invoices\" :key=\"invoice.invoice\">\n <TableCell class=\"font-medium\">\n {{ invoice.invoice }}\n </TableCell>\n <TableCell>{{ invoice.paymentStatus }}</TableCell>\n <TableCell>{{ invoice.paymentMethod }}</TableCell>\n <TableCell class=\"text-right\">\n {{ invoice.totalAmount }}\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TabsDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card",
|
|
"input",
|
|
"label",
|
|
"tabs"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TabsDemo.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 { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@/registry/new-york/ui/tabs'\n</script>\n\n<template>\n <Tabs default-value=\"account\" class=\"w-[400px]\">\n <TabsList class=\"grid w-full grid-cols-2\">\n <TabsTrigger value=\"account\">\n Account\n </TabsTrigger>\n <TabsTrigger value=\"password\">\n Password\n </TabsTrigger>\n </TabsList>\n <TabsContent value=\"account\">\n <Card>\n <CardHeader>\n <CardTitle>Account</CardTitle>\n <CardDescription>\n Make changes to your account here. Click save when you're done.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"space-y-2\">\n <div class=\"space-y-1\">\n <Label for=\"name\">Name</Label>\n <Input id=\"name\" default-value=\"Pedro Duarte\" />\n </div>\n <div class=\"space-y-1\">\n <Label for=\"username\">Username</Label>\n <Input id=\"username\" default-value=\"@peduarte\" />\n </div>\n </CardContent>\n <CardFooter>\n <Button>Save changes</Button>\n </CardFooter>\n </Card>\n </TabsContent>\n <TabsContent value=\"password\">\n <Card>\n <CardHeader>\n <CardTitle>Password</CardTitle>\n <CardDescription>\n Change your password here. After saving, you'll be logged out.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"space-y-2\">\n <div class=\"space-y-1\">\n <Label for=\"current\">Current password</Label>\n <Input id=\"current\" type=\"password\" />\n </div>\n <div class=\"space-y-1\">\n <Label for=\"new\">New password</Label>\n <Input id=\"new\" type=\"password\" />\n </div>\n </CardContent>\n <CardFooter>\n <Button>Save password</Button>\n </CardFooter>\n </Card>\n </TabsContent>\n </Tabs>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TabsVerticalDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card",
|
|
"input",
|
|
"label",
|
|
"tabs"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TabsVerticalDemo.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 { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@/registry/new-york/ui/tabs'\n</script>\n\n<template>\n <Tabs default-value=\"account\" class=\"w-[400px]\" orientation=\"vertical\">\n <TabsList class=\"grid w-full grid-cols-1\">\n <TabsTrigger value=\"account\">\n Account\n </TabsTrigger>\n <TabsTrigger value=\"password\">\n Password\n </TabsTrigger>\n </TabsList>\n <TabsContent value=\"account\">\n <Card>\n <CardHeader>\n <CardTitle>Account</CardTitle>\n <CardDescription>\n Make changes to your account here. Click save when you're done.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"space-y-2\">\n <div class=\"space-y-1\">\n <Label for=\"name\">Name</Label>\n <Input id=\"name\" default-value=\"Pedro Duarte\" />\n </div>\n <div class=\"space-y-1\">\n <Label for=\"username\">Username</Label>\n <Input id=\"username\" default-value=\"@peduarte\" />\n </div>\n </CardContent>\n <CardFooter>\n <Button>Save changes</Button>\n </CardFooter>\n </Card>\n </TabsContent>\n <TabsContent value=\"password\">\n <Card>\n <CardHeader>\n <CardTitle>Password</CardTitle>\n <CardDescription>\n Change your password here. After saving, you'll be logged out.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"space-y-2\">\n <div class=\"space-y-1\">\n <Label for=\"current\">Current password</Label>\n <Input id=\"current\" type=\"password\" />\n </div>\n <div class=\"space-y-1\">\n <Label for=\"new\">New password</Label>\n <Input id=\"new\" type=\"password\" />\n </div>\n </CardContent>\n <CardFooter>\n <Button>Save password</Button>\n </CardFooter>\n </Card>\n </TabsContent>\n </Tabs>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TagsInputComboboxDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"command",
|
|
"tags-input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TagsInputComboboxDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { CommandEmpty, CommandGroup, CommandItem, CommandList } from '@/registry/new-york/ui/command'\nimport { TagsInput, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText } from '@/registry/new-york/ui/tags-input'\nimport { ComboboxAnchor, ComboboxContent, ComboboxInput, ComboboxPortal, ComboboxRoot } from 'reka-ui'\nimport { computed, 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 modelValue = ref<string[]>([])\nconst open = ref(false)\nconst searchTerm = ref('')\n\nconst filteredFrameworks = computed(() => frameworks.filter(i => !modelValue.value.includes(i.label)))\n</script>\n\n<template>\n <TagsInput class=\"px-0 gap-0 w-80\" :model-value=\"modelValue\">\n <div class=\"flex gap-2 flex-wrap items-center px-3\">\n <TagsInputItem v-for=\"item in modelValue\" :key=\"item\" :value=\"item\">\n <TagsInputItemText />\n <TagsInputItemDelete />\n </TagsInputItem>\n </div>\n\n <ComboboxRoot v-model=\"modelValue\" v-model:open=\"open\" v-model:search-term=\"searchTerm\" class=\"w-full\">\n <ComboboxAnchor as-child>\n <ComboboxInput placeholder=\"Framework...\" as-child>\n <TagsInputInput class=\"w-full px-3\" :class=\"modelValue.length > 0 ? 'mt-2' : ''\" @keydown.enter.prevent />\n </ComboboxInput>\n </ComboboxAnchor>\n\n <ComboboxPortal>\n <ComboboxContent>\n <CommandList\n position=\"popper\"\n class=\"w-[--reka-popper-anchor-width] rounded-md mt-2 border bg-popover text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\"\n >\n <CommandEmpty />\n <CommandGroup>\n <CommandItem\n v-for=\"framework in filteredFrameworks\" :key=\"framework.value\" :value=\"framework.label\"\n @select.prevent=\"(ev) => {\n if (typeof ev.detail.value === 'string') {\n searchTerm = ''\n modelValue.push(ev.detail.value)\n }\n\n if (filteredFrameworks.length === 0) {\n open = false\n }\n }\"\n >\n {{ framework.label }}\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n </TagsInput>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TagsInputDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"tags-input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TagsInputDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { TagsInput, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText } from '@/registry/new-york/ui/tags-input'\nimport { ref } from 'vue'\n\nconst modelValue = ref(['Apple', 'Banana'])\n</script>\n\n<template>\n <TagsInput v-model=\"modelValue\">\n <TagsInputItem v-for=\"item in modelValue\" :key=\"item\" :value=\"item\">\n <TagsInputItemText />\n <TagsInputItemDelete />\n </TagsInputItem>\n\n <TagsInputInput placeholder=\"Fruits...\" />\n </TagsInput>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TagsInputFormDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"tags-input",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TagsInputFormDemo.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 { TagsInput, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText } from '@/registry/new-york/ui/tags-input'\nimport { toast } from '@/registry/new-york/ui/toast'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport { z } from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n fruits: z.array(z.string()).min(1).max(3),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n initialValues: {\n fruits: ['Apple', 'Banana'],\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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ value }\" name=\"fruits\">\n <FormItem>\n <FormLabel>Fruits</FormLabel>\n <FormControl>\n <TagsInput :model-value=\"value\">\n <TagsInputItem v-for=\"item in value\" :key=\"item\" :value=\"item\">\n <TagsInputItemText />\n <TagsInputItemDelete />\n </TagsInputItem>\n\n <TagsInputInput placeholder=\"Fruits...\" />\n </TagsInput>\n </FormControl>\n <FormDescription>\n Select your favorite fruits.\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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TextareaDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"textarea"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TextareaDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Textarea } from '@/registry/new-york/ui/textarea'\n</script>\n\n<template>\n <Textarea placeholder=\"Type your message here.\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TextareaDisabled",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"textarea"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TextareaDisabled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Textarea } from '@/registry/new-york/ui/textarea'\n</script>\n\n<template>\n <Textarea placeholder=\"Type your message here.\" disabled />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TextareaForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"textarea",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TextareaForm.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 { Textarea } from '@/registry/new-york/ui/textarea'\nimport { toast } from '@/registry/new-york/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n bio: z\n .string()\n .min(10, {\n message: 'Bio must be at least 10 characters.',\n })\n .max(160, {\n message: 'Bio must not be longer than 30 characters.',\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=\"w-full space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField }\" name=\"bio\">\n <FormItem>\n <FormLabel>Bio</FormLabel>\n <FormControl>\n <Textarea\n placeholder=\"Tell us a little bit about yourself\"\n class=\"resize-none\"\n v-bind=\"componentField\"\n />\n </FormControl>\n <FormDescription>\n You can <span>@mention</span> other users and organizations.\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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TextareaWithButton",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"textarea"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TextareaWithButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Textarea } from '@/registry/new-york/ui/textarea'\n</script>\n\n<template>\n <div class=\"grid w-full gap-2\">\n <Textarea placeholder=\"Type your message here.\" />\n <Button>Send message</Button>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TextareaWithLabel",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"textarea"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TextareaWithLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/new-york/ui/label'\nimport { Textarea } from '@/registry/new-york/ui/textarea'\n</script>\n\n<template>\n <div class=\"grid w-full gap-1.5\">\n <Label for=\"message\">Your message</Label>\n <Textarea id=\"message\" placeholder=\"Type your message here.\" />\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TextareaWithText",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"textarea"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TextareaWithText.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/new-york/ui/label'\nimport { Textarea } from '@/registry/new-york/ui/textarea'\n</script>\n\n<template>\n <div class=\"grid w-full gap-1.5\">\n <Label for=\"message-2\">Your message</Label>\n <Textarea id=\"message-2\" placeholder=\"Type your message here.\" />\n <p class=\"text-sm text-muted-foreground\">\n Your message will be copied to the support team.\n </p>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToastDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"use-toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToastDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { useToast } from '@/registry/new-york/ui/toast/use-toast'\n\nconst { toast } = useToast()\n</script>\n\n<template>\n <Button\n variant=\"outline\" @click=\"() => {\n toast({\n title: 'Scheduled: Catch up',\n description: 'Friday, February 10, 2023 at 5:57 PM',\n });\n }\"\n >\n Add to calendar\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToastDestructive",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"toast",
|
|
"use-toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToastDestructive.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { ToastAction } from '@/registry/new-york/ui/toast'\nimport { useToast } from '@/registry/new-york/ui/toast/use-toast'\nimport { h } from 'vue'\n\nconst { toast } = useToast()\n</script>\n\n<template>\n <Button\n variant=\"outline\" @click=\"() => {\n toast({\n title: 'Uh oh! Something went wrong.',\n description: 'There was a problem with your request.',\n variant: 'destructive',\n action: h(ToastAction, {\n altText: 'Try again',\n }, {\n default: () => 'Try again',\n }),\n });\n }\"\n >\n Show Toast\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToastSimple",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"use-toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToastSimple.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { useToast } from '@/registry/new-york/ui/toast/use-toast'\n\nconst { toast } = useToast()\n</script>\n\n<template>\n <Button\n variant=\"outline\" @click=\"() => {\n toast({\n description: 'Your message has been sent.',\n });\n }\"\n >\n Show Toast\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToastWithAction",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"toast",
|
|
"use-toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToastWithAction.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { ToastAction } from '@/registry/new-york/ui/toast'\nimport { useToast } from '@/registry/new-york/ui/toast/use-toast'\nimport { h } from 'vue'\n\nconst { toast } = useToast()\n</script>\n\n<template>\n <Button\n variant=\"outline\" @click=\"() => {\n toast({\n title: 'Uh oh! Something went wrong.',\n description: 'There was a problem with your request.',\n action: h(ToastAction, {\n altText: 'Try again',\n }, {\n default: () => 'Try again',\n }),\n });\n }\"\n >\n Show Toast\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToastWithTitle",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"use-toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToastWithTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport { useToast } from '@/registry/new-york/ui/toast/use-toast'\n\nconst { toast } = useToast()\n</script>\n\n<template>\n <Button\n variant=\"outline\" @click=\"() => {\n toast({\n title: 'Uh oh! Something went wrong.',\n description: 'There was a problem with your request.',\n });\n }\"\n >\n Show Toast\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Toggle } from '@/registry/new-york/ui/toggle'\n\nimport { FontBoldIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Toggle aria-label=\"Toggle italic\">\n <FontBoldIcon class=\"h-4 w-4\" />\n </Toggle>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleDisabledDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleDisabledDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Toggle } from '@/registry/new-york/ui/toggle'\n\nimport { UnderlineIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Toggle aria-label=\"Toggle italic\" disabled>\n <UnderlineIcon class=\"w-4 h-4\" />\n </Toggle>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleGroupDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleGroupDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/new-york/ui/toggle-group'\n\nimport {\n FontBoldIcon,\n FontItalicIcon,\n UnderlineIcon,\n} from '@radix-icons/vue'\n</script>\n\n<template>\n <ToggleGroup type=\"multiple\">\n <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n <FontBoldIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n <FontItalicIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n <UnderlineIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n </ToggleGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleGroupDisabledDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleGroupDisabledDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/new-york/ui/toggle-group'\n\nimport {\n FontBoldIcon,\n FontItalicIcon,\n UnderlineIcon,\n} from '@radix-icons/vue'\n</script>\n\n<template>\n <ToggleGroup type=\"multiple\" disabled>\n <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n <FontBoldIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n <FontItalicIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n <UnderlineIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n </ToggleGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleGroupLargeDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleGroupLargeDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/new-york/ui/toggle-group'\n\nimport {\n FontBoldIcon,\n FontItalicIcon,\n UnderlineIcon,\n} from '@radix-icons/vue'\n</script>\n\n<template>\n <ToggleGroup type=\"multiple\" size=\"lg\">\n <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n <FontBoldIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n <FontItalicIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n <UnderlineIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n </ToggleGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleGroupOutlineDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleGroupOutlineDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/new-york/ui/toggle-group'\n\nimport {\n FontBoldIcon,\n FontItalicIcon,\n UnderlineIcon,\n} from '@radix-icons/vue'\n</script>\n\n<template>\n <ToggleGroup type=\"multiple\" variant=\"outline\">\n <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n <FontBoldIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n <FontItalicIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n <UnderlineIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n </ToggleGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleGroupSingleDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleGroupSingleDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/new-york/ui/toggle-group'\n\nimport {\n FontBoldIcon,\n FontItalicIcon,\n UnderlineIcon,\n} from '@radix-icons/vue'\n</script>\n\n<template>\n <ToggleGroup type=\"single\">\n <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n <FontBoldIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n <FontItalicIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n <UnderlineIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n </ToggleGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleGroupSmallDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleGroupSmallDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/new-york/ui/toggle-group'\n\nimport {\n FontBoldIcon,\n FontItalicIcon,\n UnderlineIcon,\n} from '@radix-icons/vue'\n</script>\n\n<template>\n <ToggleGroup type=\"multiple\" size=\"sm\">\n <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n <FontBoldIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n <FontItalicIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n <UnderlineIcon class=\"h-4 w-4\" />\n </ToggleGroupItem>\n </ToggleGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleItalicDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleItalicDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Toggle } from '@/registry/new-york/ui/toggle'\n\nimport { FontItalicIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Toggle variant=\"outline\" aria-label=\"Toggle italic\">\n <FontItalicIcon class=\"w-4 h-4\" />\n </Toggle>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleItalicWithTextDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleItalicWithTextDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Toggle } from '@/registry/new-york/ui/toggle'\n\nimport { FontItalicIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Toggle aria-label=\"Toggle italic\">\n <FontItalicIcon class=\"w-4 h-4 mr-2\" />\n Italic\n </Toggle>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleLargeDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleLargeDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Toggle } from '@/registry/new-york/ui/toggle'\n\nimport { FontItalicIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Toggle size=\"lg\" aria-label=\"Toggle italic\">\n <FontItalicIcon class=\"w-4 h-4\" />\n </Toggle>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleSmallDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleSmallDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Toggle } from '@/registry/new-york/ui/toggle'\n\nimport { FontItalicIcon } from '@radix-icons/vue'\n</script>\n\n<template>\n <Toggle size=\"sm\" aria-label=\"Toggle italic\">\n <FontItalicIcon class=\"w-4 h-4\" />\n </Toggle>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TooltipDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"tooltip"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TooltipDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@/registry/new-york/ui/tooltip'\n</script>\n\n<template>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button variant=\"outline\">\n Hover\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n <p>Add to library</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyBlockquote",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyBlockquote.vue",
|
|
"content": "<template>\n <blockquote class=\"mt-6 border-l-2 pl-6 italic\">\n \"After all,\" he said, \"everyone enjoys a good joke, so it's only fair that\n they should pay for the privilege.\"\n </blockquote>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyDemo.vue",
|
|
"content": "<template>\n <div>\n <h1 class=\"scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl\">\n The Joke Tax Chronicles\n </h1>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n Once upon a time, in a far-off land, there was a very lazy king who\n spent all day lounging on his throne. One day, his advisors came to him\n with a problem: the kingdom was running out of money.\n </p>\n <h2\n class=\"mt-10 scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight transition-colors first:mt-0\"\n >\n The King's Plan\n </h2>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n The king thought long and hard, and finally came up with\n <a\n href=\"#\"\n class=\"font-medium text-primary underline underline-offset-4\"\n >\n a brilliant plan\n </a>\n : he would tax the jokes in the kingdom.\n </p>\n <blockquote class=\"mt-6 border-l-2 pl-6 italic\">\n \"After all,\" he said, \"everyone enjoys a good joke, so it's only fair\n that they should pay for the privilege.\"\n </blockquote>\n <h3 class=\"mt-8 scroll-m-20 text-2xl font-semibold tracking-tight\">\n The Joke Tax\n </h3>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n The king's subjects were not amused. They grumbled and complained, but\n the king was firm:\n </p>\n <ul class=\"my-6 ml-6 list-disc [&>li]:mt-2\">\n <li>1st level of puns: 5 gold coins</li>\n <li>2nd level of jokes: 10 gold coins</li>\n <li>3rd level of one-liners : 20 gold coins</li>\n </ul>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n As a result, people stopped telling jokes, and the kingdom fell into a\n gloom. But there was one person who refused to let the king's\n foolishness get him down: a court jester named Jokester.\n </p>\n <h3 class=\"mt-8 scroll-m-20 text-2xl font-semibold tracking-tight\">\n Jokester's Revolt\n </h3>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n Jokester began sneaking into the castle in the middle of the night and\n leaving jokes all over the place: under the king's pillow, in his soup,\n even in the royal toilet. The king was furious, but he couldn't seem to\n stop Jokester.\n </p>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n And then, one day, the people of the kingdom discovered that the jokes\n left by Jokester were so funny that they couldn't help but laugh. And\n once they started laughing, they couldn't stop.\n </p>\n <h3 class=\"mt-8 scroll-m-20 text-2xl font-semibold tracking-tight\">\n The People's Rebellion\n </h3>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n The people of the kingdom, feeling uplifted by the laughter, started to\n tell jokes and puns again, and soon the entire kingdom was in on the\n joke.\n </p>\n <div class=\"my-6 w-full overflow-y-auto\">\n <table class=\"w-full\">\n <thead>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <th\n class=\"border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n King's Treasury\n </th>\n <th\n class=\"border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n People's happiness\n </th>\n </tr>\n </thead>\n <tbody>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Empty\n </td>\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Overflowing\n </td>\n </tr>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Modest\n </td>\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Satisfied\n </td>\n </tr>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Full\n </td>\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Ecstatic\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n The king, seeing how much happier his subjects were, realized the error\n of his ways and repealed the joke tax. Jokester was declared a hero, and\n the kingdom lived happily ever after.\n </p>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n The moral of the story is: never underestimate the power of a good laugh\n and always be careful of bad ideas.\n </p>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyH1",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyH1.vue",
|
|
"content": "<template>\n <h1 class=\"scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl\">\n Taxing Laughter: The Joke Tax Chronicles\n </h1>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyH2",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyH2.vue",
|
|
"content": "<template>\n <h2\n class=\"scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight transition-colors first:mt-0\"\n >\n The People of the Kingdom\n </h2>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyH3",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyH3.vue",
|
|
"content": "<template>\n <h3 class=\"scroll-m-20 text-2xl font-semibold tracking-tight\">\n The Joke Tax\n </h3>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyH4",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyH4.vue",
|
|
"content": "<template>\n <h4 class=\"scroll-m-20 text-xl font-semibold tracking-tight\">\n People stopped telling jokes\n </h4>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyInlineCode",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyInlineCode.vue",
|
|
"content": "<template>\n <code\n class=\"relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold\"\n >\n reka-ui\n </code>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyLarge",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyLarge.vue",
|
|
"content": "<template>\n <div class=\"text-lg font-semibold\">\n Are you absolutely sure?\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyLead",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyLead.vue",
|
|
"content": "<template>\n <p class=\"text-xl text-muted-foreground\">\n A modal dialog that interrupts the user with important content and expects a\n response.\n </p>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyList",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyList.vue",
|
|
"content": "<template>\n <ul class=\"my-6 ml-6 list-disc [&>li]:mt-2\">\n <li>1st level of puns: 5 gold coins</li>\n <li>2nd level of jokes: 10 gold coins</li>\n <li>3rd level of one-liners : 20 gold coins</li>\n </ul>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyMuted",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyMuted.vue",
|
|
"content": "<template>\n <p class=\"text-sm text-muted-foreground\">\n Enter your email address.\n </p>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyP",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyP.vue",
|
|
"content": "<template>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n The king, seeing how much happier his subjects were, realized the error of\n his ways and repealed the joke tax.\n </p>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographySmall",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographySmall.vue",
|
|
"content": "<template>\n <small class=\"text-sm font-medium leading-none\">\n Email address\n </small>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyTable",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyTable.vue",
|
|
"content": "<template>\n <div class=\"my-6 w-full overflow-y-auto\">\n <table class=\"w-full\">\n <thead>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <th\n class=\"border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n King's Treasury\n </th>\n <th\n class=\"border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n People's happiness\n </th>\n </tr>\n </thead>\n <tbody>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Empty\n </td>\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Overflowing\n </td>\n </tr>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Modest\n </td>\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Satisfied\n </td>\n </tr>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Full\n </td>\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Ecstatic\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VCalendarDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VCalendarDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Calendar } from '@/registry/new-york/ui/v-calendar'\nimport { ref } from 'vue'\n\nconst date = ref(new Date())\n</script>\n\n<template>\n <Calendar v-model=\"date\" class=\"rounded-md border\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VDatePickerDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VDatePickerDemo.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VDatePickerForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"form",
|
|
"popover",
|
|
"toast",
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VDatePickerForm.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VDatePickerWithPresets",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"select",
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VDatePickerWithPresets.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VDatePickerWithRange",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VDatePickerWithRange.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VDateTimePickerDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VDateTimePickerDemo.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VRangePickerWithSlot",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VRangePickerWithSlot.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Authentication01",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"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": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Authentication02",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"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": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Authentication03",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"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": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Authentication04",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"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": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard01",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"avatar",
|
|
"badge",
|
|
"button",
|
|
"card",
|
|
"dropdown-menu",
|
|
"input",
|
|
"sheet",
|
|
"table"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard01.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'An application shell with a header and main content area. The header has a navbar, a search input and and a user nav dropdown. The user nav is toggled by a button with an avatar image. The main content area is divided into two rows. The first row has a grid of cards with statistics. The second row has a grid of cards with a table of recent transactions and a list of recent sales.'\nexport const iframeHeight = '825px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback, AvatarImage } from '@/registry/new-york/ui/avatar'\nimport { Badge } from '@/registry/new-york/ui/badge'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/registry/new-york/ui/card'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/new-york/ui/dropdown-menu'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Sheet, SheetContent, SheetTrigger } from '@/registry/new-york/ui/sheet'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/registry/new-york/ui/table'\nimport { Activity, ArrowUpRight, CircleUser, CreditCard, DollarSign, Menu, Package2, Search, Users } from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"flex min-h-screen w-full flex-col\">\n <header class=\"sticky top-0 flex h-16 items-center gap-4 border-b bg-background px-4 md:px-6\">\n <nav class=\"hidden flex-col gap-6 text-lg font-medium md:flex md:flex-row md:items-center md:gap-5 md:text-sm lg:gap-6\">\n <a\n href=\"#\"\n class=\"flex items-center gap-2 text-lg font-semibold md:text-base\"\n >\n <Package2 class=\"h-6 w-6\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"text-foreground transition-colors hover:text-foreground\"\n >\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Orders\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Products\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Customers\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Analytics\n </a>\n </nav>\n <Sheet>\n <SheetTrigger as-child>\n <Button\n variant=\"outline\"\n size=\"icon\"\n class=\"shrink-0 md:hidden\"\n >\n <Menu class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle navigation menu</span>\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\">\n <nav class=\"grid gap-6 text-lg font-medium\">\n <a\n href=\"#\"\n class=\"flex items-center gap-2 text-lg font-semibold\"\n >\n <Package2 class=\"h-6 w-6\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a href=\"#\" class=\"hover:text-foreground\">\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Orders\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Products\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Customers\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Analytics\n </a>\n </nav>\n </SheetContent>\n </Sheet>\n <div class=\"flex w-full items-center gap-4 md:ml-auto md:gap-2 lg:gap-4\">\n <form class=\"ml-auto flex-1 sm:flex-initial\">\n <div class=\"relative\">\n <Search class=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n type=\"search\"\n placeholder=\"Search products...\"\n class=\"pl-8 sm:w-[300px] md:w-[200px] lg:w-[300px]\"\n />\n </div>\n </form>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"secondary\" size=\"icon\" class=\"rounded-full\">\n <CircleUser class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle user menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Settings</DropdownMenuItem>\n <DropdownMenuItem>Support</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Logout</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </header>\n <main class=\"flex flex-1 flex-col gap-4 p-4 md:gap-8 md:p-8\">\n <div class=\"grid gap-4 md:grid-cols-2 md:gap-8 lg:grid-cols-4\">\n <Card>\n <CardHeader class=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle class=\"text-sm font-medium\">\n Total Revenue\n </CardTitle>\n <DollarSign class=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div class=\"text-2xl font-bold\">\n $45,231.89\n </div>\n <p class=\"text-xs text-muted-foreground\">\n +20.1% from last month\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader class=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle class=\"text-sm font-medium\">\n Subscriptions\n </CardTitle>\n <Users class=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div class=\"text-2xl font-bold\">\n +2350\n </div>\n <p class=\"text-xs text-muted-foreground\">\n +180.1% from last month\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader class=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle class=\"text-sm font-medium\">\n Sales\n </CardTitle>\n <CreditCard class=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div class=\"text-2xl font-bold\">\n +12,234\n </div>\n <p class=\"text-xs text-muted-foreground\">\n +19% from last month\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader class=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle class=\"text-sm font-medium\">\n Active Now\n </CardTitle>\n <Activity class=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div class=\"text-2xl font-bold\">\n +573\n </div>\n <p class=\"text-xs text-muted-foreground\">\n +201 since last hour\n </p>\n </CardContent>\n </Card>\n </div>\n <div class=\"grid gap-4 md:gap-8 lg:grid-cols-2 xl:grid-cols-3\">\n <Card class=\"xl:col-span-2\">\n <CardHeader class=\"flex flex-row items-center\">\n <div class=\"grid gap-2\">\n <CardTitle>Transactions</CardTitle>\n <CardDescription>\n Recent transactions from your store.\n </CardDescription>\n </div>\n <Button as-child size=\"sm\" class=\"ml-auto gap-1\">\n <a href=\"#\">\n View All\n <ArrowUpRight class=\"h-4 w-4\" />\n </a>\n </Button>\n </CardHeader>\n <CardContent>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Customer</TableHead>\n <TableHead class=\"hidden xl:table-column\">\n Type\n </TableHead>\n <TableHead class=\"hidden xl:table-column\">\n Status\n </TableHead>\n <TableHead class=\"hidden xl:table-column\">\n Date\n </TableHead>\n <TableHead class=\"text-right\">\n Amount\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Liam Johnson\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n liam@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n Sale\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Approved\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell lg:hidden xl:table-column\">\n 2023-06-23\n </TableCell>\n <TableCell class=\"text-right\">\n $250.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Olivia Smith\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n olivia@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n Refund\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Declined\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell lg:hidden xl:table-column\">\n 2023-06-24\n </TableCell>\n <TableCell class=\"text-right\">\n $150.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Noah Williams\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n noah@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n Subscription\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Approved\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell lg:hidden xl:table-column\">\n 2023-06-25\n </TableCell>\n <TableCell class=\"text-right\">\n $350.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Emma Brown\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n emma@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n Sale\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Approved\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell lg:hidden xl:table-column\">\n 2023-06-26\n </TableCell>\n <TableCell class=\"text-right\">\n $450.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Liam Johnson\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n liam@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n Sale\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Approved\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell lg:hidden xl:table-column\">\n 2023-06-27\n </TableCell>\n <TableCell class=\"text-right\">\n $550.00\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Recent Sales</CardTitle>\n </CardHeader>\n <CardContent class=\"grid gap-8\">\n <div class=\"flex items-center gap-4\">\n <Avatar class=\"hidden h-9 w-9 sm:flex\">\n <AvatarImage src=\"/avatars/01.png\" alt=\"Avatar\" />\n <AvatarFallback>OM</AvatarFallback>\n </Avatar>\n <div class=\"grid gap-1\">\n <p class=\"text-sm font-medium leading-none\">\n Olivia Martin\n </p>\n <p class=\"text-sm text-muted-foreground\">\n olivia.martin@email.com\n </p>\n </div>\n <div class=\"ml-auto font-medium\">\n +$1,999.00\n </div>\n </div>\n <div class=\"flex items-center gap-4\">\n <Avatar class=\"hidden h-9 w-9 sm:flex\">\n <AvatarImage src=\"/avatars/02.png\" alt=\"Avatar\" />\n <AvatarFallback>JL</AvatarFallback>\n </Avatar>\n <div class=\"grid gap-1\">\n <p class=\"text-sm font-medium leading-none\">\n Jackson Lee\n </p>\n <p class=\"text-sm text-muted-foreground\">\n jackson.lee@email.com\n </p>\n </div>\n <div class=\"ml-auto font-medium\">\n +$39.00\n </div>\n </div>\n <div class=\"flex items-center gap-4\">\n <Avatar class=\"hidden h-9 w-9 sm:flex\">\n <AvatarImage src=\"/avatars/03.png\" alt=\"Avatar\" />\n <AvatarFallback>IN</AvatarFallback>\n </Avatar>\n <div class=\"grid gap-1\">\n <p class=\"text-sm font-medium leading-none\">\n Isabella Nguyen\n </p>\n <p class=\"text-sm text-muted-foreground\">\n isabella.nguyen@email.com\n </p>\n </div>\n <div class=\"ml-auto font-medium\">\n +$299.00\n </div>\n </div>\n <div class=\"flex items-center gap-4\">\n <Avatar class=\"hidden h-9 w-9 sm:flex\">\n <AvatarImage src=\"/avatars/04.png\" alt=\"Avatar\" />\n <AvatarFallback>WK</AvatarFallback>\n </Avatar>\n <div class=\"grid gap-1\">\n <p class=\"text-sm font-medium leading-none\">\n William Kim\n </p>\n <p class=\"text-sm text-muted-foreground\">\n will@email.com\n </p>\n </div>\n <div class=\"ml-auto font-medium\">\n +$99.00\n </div>\n </div>\n <div class=\"flex items-center gap-4\">\n <Avatar class=\"hidden h-9 w-9 sm:flex\">\n <AvatarImage src=\"/avatars/05.png\" alt=\"Avatar\" />\n <AvatarFallback>SD</AvatarFallback>\n </Avatar>\n <div class=\"grid gap-1\">\n <p class=\"text-sm font-medium leading-none\">\n Sofia Davis\n </p>\n <p class=\"text-sm text-muted-foreground\">\n sofia.davis@email.com\n </p>\n </div>\n <div class=\"ml-auto font-medium\">\n +$39.00\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n </main>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard02",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge",
|
|
"button",
|
|
"card",
|
|
"dropdown-menu",
|
|
"input",
|
|
"sheet"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard02.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A products dashboard with a sidebar navigation and a main content area. The dashboard has a header with a search input and a user menu. The sidebar has a logo, navigation links, and a card with a call to action. The main content area shows an empty state with a call to action.'\nexport const iframeHeight = '800px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Badge } from '@/registry/new-york/ui/badge'\n\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/registry/new-york/ui/card'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/new-york/ui/dropdown-menu'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Sheet, SheetContent, SheetTrigger } from '@/registry/new-york/ui/sheet'\nimport { Bell, CircleUser, Home, LineChart, Menu, Package, Package2, Search, ShoppingCart, Users } from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"grid min-h-screen w-full md:grid-cols-[220px_1fr] lg:grid-cols-[280px_1fr]\">\n <div class=\"hidden border-r bg-muted/40 md:block\">\n <div class=\"flex h-full max-h-screen flex-col gap-2\">\n <div class=\"flex h-14 items-center border-b px-4 lg:h-[60px] lg:px-6\">\n <a href=\"/\" class=\"flex items-center gap-2 font-semibold\">\n <Package2 class=\"h-6 w-6\" />\n <span class=\"\">Acme Inc</span>\n </a>\n <Button variant=\"outline\" size=\"icon\" class=\"ml-auto h-8 w-8\">\n <Bell class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle notifications</span>\n </Button>\n </div>\n <div class=\"flex-1\">\n <nav class=\"grid items-start px-2 text-sm font-medium lg:px-4\">\n <a\n href=\"/\"\n class=\"flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary\"\n >\n <Home class=\"h-4 w-4\" />\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary\"\n >\n <ShoppingCart class=\"h-4 w-4\" />\n Orders\n <Badge class=\"ml-auto flex h-6 w-6 shrink-0 items-center justify-center rounded-full\">\n 6\n </Badge>\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-3 rounded-lg bg-muted px-3 py-2 text-primary transition-all hover:text-primary\"\n >\n <Package class=\"h-4 w-4\" />\n Products\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary\"\n >\n <Users class=\"h-4 w-4\" />\n Customers\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary\"\n >\n <LineChart class=\"h-4 w-4\" />\n Analytics\n </a>\n </nav>\n </div>\n <div class=\"mt-auto p-4\">\n <Card>\n <CardHeader class=\"p-2 pt-0 md:p-4\">\n <CardTitle>Upgrade to Pro</CardTitle>\n <CardDescription>\n Unlock all features and get unlimited access to our support\n team.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"p-2 pt-0 md:p-4 md:pt-0\">\n <Button size=\"sm\" class=\"w-full\">\n Upgrade\n </Button>\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n <div class=\"flex flex-col\">\n <header class=\"flex h-14 items-center gap-4 border-b bg-muted/40 px-4 lg:h-[60px] lg:px-6\">\n <Sheet>\n <SheetTrigger as-child>\n <Button\n variant=\"outline\"\n size=\"icon\"\n class=\"shrink-0 md:hidden\"\n >\n <Menu class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle navigation menu</span>\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\" class=\"flex flex-col\">\n <nav class=\"grid gap-2 text-lg font-medium\">\n <a\n href=\"#\"\n class=\"flex items-center gap-2 text-lg font-semibold\"\n >\n <Package2 class=\"h-6 w-6\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 text-muted-foreground hover:text-foreground\"\n >\n <Home class=\"h-5 w-5\" />\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"mx-[-0.65rem] flex items-center gap-4 rounded-xl bg-muted px-3 py-2 text-foreground hover:text-foreground\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n Orders\n <Badge class=\"ml-auto flex h-6 w-6 shrink-0 items-center justify-center rounded-full\">\n 6\n </Badge>\n </a>\n <a\n href=\"#\"\n class=\"mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 text-muted-foreground hover:text-foreground\"\n >\n <Package class=\"h-5 w-5\" />\n Products\n </a>\n <a\n href=\"#\"\n class=\"mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 text-muted-foreground hover:text-foreground\"\n >\n <Users class=\"h-5 w-5\" />\n Customers\n </a>\n <a\n href=\"#\"\n class=\"mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 text-muted-foreground hover:text-foreground\"\n >\n <LineChart class=\"h-5 w-5\" />\n Analytics\n </a>\n </nav>\n <div class=\"mt-auto\">\n <Card>\n <CardHeader>\n <CardTitle>Upgrade to Pro</CardTitle>\n <CardDescription>\n Unlock all features and get unlimited access to our\n support team.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Button size=\"sm\" class=\"w-full\">\n Upgrade\n </Button>\n </CardContent>\n </Card>\n </div>\n </SheetContent>\n </Sheet>\n <div class=\"w-full flex-1\">\n <form>\n <div class=\"relative\">\n <Search class=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n type=\"search\"\n placeholder=\"Search products...\"\n class=\"w-full appearance-none bg-background pl-8 shadow-none md:w-2/3 lg:w-1/3\"\n />\n </div>\n </form>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"secondary\" size=\"icon\" class=\"rounded-full\">\n <CircleUser class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle user menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Settings</DropdownMenuItem>\n <DropdownMenuItem>Support</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Logout</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </header>\n <main class=\"flex flex-1 flex-col gap-4 p-4 lg:gap-6 lg:p-6\">\n <div class=\"flex items-center\">\n <h1 class=\"text-lg font-semibold md:text-2xl\">\n Inventory\n </h1>\n </div>\n <div class=\"flex flex-1 items-center justify-center rounded-lg border border-dashed shadow-sm\">\n <div class=\"flex flex-col items-center gap-1 text-center\">\n <h3 class=\"text-2xl font-bold tracking-tight\">\n You have no products\n </h3>\n <p class=\"text-sm text-muted-foreground\">\n You can start selling as soon as you add a product.\n </p>\n <Button class=\"mt-4\">\n Add Product\n </Button>\n </div>\n </div>\n </main>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard03",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge",
|
|
"button",
|
|
"drawer",
|
|
"input",
|
|
"label",
|
|
"select",
|
|
"textarea",
|
|
"tooltip"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard03.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'An AI playground with a sidebar navigation and a main content area. The playground has a header with a settings drawer and a share button. The sidebar has navigation links and a user menu. The main content area shows a form to configure the model and messages.'\nexport const iframeHeight = '740px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Badge } from '@/registry/new-york/ui/badge'\n\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Drawer, DrawerContent, DrawerDescription, DrawerHeader, DrawerTitle, DrawerTrigger } from '@/registry/new-york/ui/drawer'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/registry/new-york/ui/select'\nimport { Textarea } from '@/registry/new-york/ui/textarea'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/registry/new-york/ui/tooltip'\nimport { Bird, Book, Bot, Code2, CornerDownLeft, LifeBuoy, Mic, Paperclip, Rabbit, Settings, Settings2, Share, SquareTerminal, SquareUser, Triangle, Turtle } from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"grid h-screen w-full pl-[53px]\">\n <aside class=\"inset-y fixed left-0 z-20 flex h-full flex-col border-r\">\n <div class=\"border-b p-2\">\n <Button variant=\"outline\" size=\"icon\" aria-label=\"Home\">\n <Triangle class=\"size-5 fill-foreground\" />\n </Button>\n </div>\n <nav class=\"grid gap-1 p-2\">\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"rounded-lg bg-muted\"\n aria-label=\"Playground\"\n >\n <SquareTerminal class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n Playground\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"rounded-lg\"\n aria-label=\"Models\"\n >\n <Bot class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n Models\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"rounded-lg\"\n aria-label=\"API\"\n >\n <Code2 class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n API\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"rounded-lg\"\n aria-label=\"Documentation\"\n >\n <Book class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n Documentation\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"rounded-lg\"\n aria-label=\"Settings\"\n >\n <Settings2 class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n Settings\n </TooltipContent>\n </Tooltip>\n </nav>\n <nav class=\"mt-auto grid gap-1 p-2\">\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mt-auto rounded-lg\"\n aria-label=\"Help\"\n >\n <LifeBuoy class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n Help\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mt-auto rounded-lg\"\n aria-label=\"Account\"\n >\n <SquareUser class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n Account\n </TooltipContent>\n </Tooltip>\n </nav>\n </aside>\n <div class=\"flex flex-col\">\n <header class=\"sticky top-0 z-10 flex h-[53px] items-center gap-1 border-b bg-background px-4\">\n <h1 class=\"text-xl font-semibold\">\n Playground\n </h1>\n <Drawer>\n <DrawerTrigger as-child>\n <Button variant=\"ghost\" size=\"icon\" class=\"md:hidden\">\n <Settings class=\"size-4\" />\n <span class=\"sr-only\">Settings</span>\n </Button>\n </DrawerTrigger>\n <DrawerContent class=\"max-h-[80vh]\">\n <DrawerHeader>\n <DrawerTitle>Configuration</DrawerTitle>\n <DrawerDescription>\n Configure the settings for the model and messages.\n </DrawerDescription>\n </DrawerHeader>\n <form class=\"grid w-full items-start gap-6 overflow-auto p-4 pt-0\">\n <fieldset class=\"grid gap-6 rounded-lg border p-4\">\n <legend class=\"-ml-1 px-1 text-sm font-medium\">\n Settings\n </legend>\n <div class=\"grid gap-3\">\n <Label for=\"model\">Model</Label>\n <Select>\n <SelectTrigger\n id=\"model\"\n class=\"items-start [&_[data-description]]:hidden\"\n >\n <SelectValue placeholder=\"Select a model\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"genesis\">\n <div class=\"flex items-start gap-3 text-muted-foreground\">\n <Rabbit class=\"size-5\" />\n <div class=\"grid gap-0.5\">\n <p>\n Neural\n <span class=\"font-medium text-foreground\">\n Genesis\n </span>\n </p>\n <p class=\"text-xs\" data-description>\n Our fastest model for general use cases.\n </p>\n </div>\n </div>\n </SelectItem>\n <SelectItem value=\"explorer\">\n <div class=\"flex items-start gap-3 text-muted-foreground\">\n <Bird class=\"size-5\" />\n <div class=\"grid gap-0.5\">\n <p>\n Neural\n <span class=\"font-medium text-foreground\">\n Explorer\n </span>\n </p>\n <p class=\"text-xs\" data-description>\n Performance and speed for efficiency.\n </p>\n </div>\n </div>\n </SelectItem>\n <SelectItem value=\"quantum\">\n <div class=\"flex items-start gap-3 text-muted-foreground\">\n <Turtle class=\"size-5\" />\n <div class=\"grid gap-0.5\">\n <p>\n Neural\n <span class=\"font-medium text-foreground\">\n Quantum\n </span>\n </p>\n <p class=\"text-xs\" data-description>\n The most powerful model for complex\n computations.\n </p>\n </div>\n </div>\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"temperature\">Temperature</Label>\n <Input id=\"temperature\" type=\"number\" placeholder=\"0.4\" />\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"top-p\">Top P</Label>\n <Input id=\"top-p\" type=\"number\" placeholder=\"0.7\" />\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"top-k\">Top K</Label>\n <Input id=\"top-k\" type=\"number\" placeholder=\"0.0\" />\n </div>\n </fieldset>\n <fieldset class=\"grid gap-6 rounded-lg border p-4\">\n <legend class=\"-ml-1 px-1 text-sm font-medium\">\n Messages\n </legend>\n <div class=\"grid gap-3\">\n <Label for=\"role\">Role</Label>\n <Select default-value=\"system\">\n <SelectTrigger>\n <SelectValue placeholder=\"Select a role\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"system\">\n System\n </SelectItem>\n <SelectItem value=\"user\">\n User\n </SelectItem>\n <SelectItem value=\"assistant\">\n Assistant\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"content\">Content</Label>\n <Textarea id=\"content\" placeholder=\"You are a...\" />\n </div>\n </fieldset>\n </form>\n </DrawerContent>\n </Drawer>\n <Button\n variant=\"outline\"\n size=\"sm\"\n class=\"ml-auto gap-1.5 text-sm\"\n >\n <Share class=\"size-3.5\" />\n Share\n </Button>\n </header>\n <main class=\"grid flex-1 gap-4 overflow-auto p-4 md:grid-cols-2 lg:grid-cols-3\">\n <div class=\"relative hidden flex-col items-start gap-8 md:flex\">\n <form class=\"grid w-full items-start gap-6\">\n <fieldset class=\"grid gap-6 rounded-lg border p-4\">\n <legend class=\"-ml-1 px-1 text-sm font-medium\">\n Settings\n </legend>\n <div class=\"grid gap-3\">\n <Label for=\"model\">Model</Label>\n <Select>\n <SelectTrigger\n id=\"model\"\n class=\"items-start [&_[data-description]]:hidden\"\n >\n <SelectValue placeholder=\"Select a model\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"genesis\">\n <div class=\"flex items-start gap-3 text-muted-foreground\">\n <Rabbit class=\"size-5\" />\n <div class=\"grid gap-0.5\">\n <p>\n Neural\n <span class=\"font-medium text-foreground\">\n Genesis\n </span>\n </p>\n <p class=\"text-xs\" data-description>\n Our fastest model for general use cases.\n </p>\n </div>\n </div>\n </SelectItem>\n <SelectItem value=\"explorer\">\n <div class=\"flex items-start gap-3 text-muted-foreground\">\n <Bird class=\"size-5\" />\n <div class=\"grid gap-0.5\">\n <p>\n Neural\n <span class=\"font-medium text-foreground\">\n Explorer\n </span>\n </p>\n <p class=\"text-xs\" data-description>\n Performance and speed for efficiency.\n </p>\n </div>\n </div>\n </SelectItem>\n <SelectItem value=\"quantum\">\n <div class=\"flex items-start gap-3 text-muted-foreground\">\n <Turtle class=\"size-5\" />\n <div class=\"grid gap-0.5\">\n <p>\n Neural\n <span class=\"font-medium text-foreground\">\n Quantum\n </span>\n </p>\n <p class=\"text-xs\" data-description>\n The most powerful model for complex computations.\n </p>\n </div>\n </div>\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"temperature\">Temperature</Label>\n <Input id=\"temperature\" type=\"number\" placeholder=\"0.4\" />\n </div>\n <div class=\"grid grid-cols-2 gap-4\">\n <div class=\"grid gap-3\">\n <Label for=\"top-p\">Top P</Label>\n <Input id=\"top-p\" type=\"number\" placeholder=\"0.7\" />\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"top-k\">Top K</Label>\n <Input id=\"top-k\" type=\"number\" placeholder=\"0.0\" />\n </div>\n </div>\n </fieldset>\n <fieldset class=\"grid gap-6 rounded-lg border p-4\">\n <legend class=\"-ml-1 px-1 text-sm font-medium\">\n Messages\n </legend>\n <div class=\"grid gap-3\">\n <Label for=\"role\">Role</Label>\n <Select default-value=\"system\">\n <SelectTrigger>\n <SelectValue placeholder=\"Select a role\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"system\">\n System\n </SelectItem>\n <SelectItem value=\"user\">\n User\n </SelectItem>\n <SelectItem value=\"assistant\">\n Assistant\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"content\">Content</Label>\n <Textarea\n id=\"content\"\n placeholder=\"You are a...\"\n class=\"min-h-[9.5rem]\"\n />\n </div>\n </fieldset>\n </form>\n </div>\n <div class=\"relative flex h-full min-h-[50vh] flex-col rounded-xl bg-muted/50 p-4 lg:col-span-2\">\n <Badge variant=\"outline\" class=\"absolute right-3 top-3\">\n Output\n </Badge>\n <div class=\"flex-1\" />\n <form class=\"relative overflow-hidden rounded-lg border bg-background focus-within:ring-1 focus-within:ring-ring\">\n <Label for=\"message\" class=\"sr-only\">\n Message\n </Label>\n <Textarea\n id=\"message\"\n placeholder=\"Type your message here...\"\n class=\"min-h-12 resize-none border-0 p-3 shadow-none focus-visible:ring-0\"\n />\n <div class=\"flex items-center p-3 pt-0\">\n <Tooltip>\n <TooltipTrigger as-child>\n <Button variant=\"ghost\" size=\"icon\">\n <Paperclip class=\"size-4\" />\n <span class=\"sr-only\">Attach file</span>\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"top\">\n Attach File\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button variant=\"ghost\" size=\"icon\">\n <Mic class=\"size-4\" />\n <span class=\"sr-only\">Use Microphone</span>\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"top\">\n Use Microphone\n </TooltipContent>\n </Tooltip>\n <Button type=\"submit\" size=\"sm\" class=\"ml-auto gap-1.5\">\n Send Message\n <CornerDownLeft class=\"size-3.5\" />\n </Button>\n </div>\n </form>\n </div>\n </main>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard04",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card",
|
|
"checkbox",
|
|
"dropdown-menu",
|
|
"input",
|
|
"sheet"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard04.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A settings page. The settings page has a sidebar navigation and a main content area. The main content area has a form to update the store name and a form to update the plugins directory. The sidebar navigation has links to general, security, integrations, support, organizations, and advanced settings.'\nexport const iframeHeight = '780px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\n\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/registry/new-york/ui/card'\nimport { Checkbox } from '@/registry/new-york/ui/checkbox'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/new-york/ui/dropdown-menu'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Sheet, SheetContent, SheetTrigger } from '@/registry/new-york/ui/sheet'\nimport { CircleUser, Menu, Package2, Search } from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"flex min-h-screen w-full flex-col\">\n <header class=\"sticky top-0 flex h-16 items-center gap-4 border-b bg-background px-4 md:px-6\">\n <nav class=\"hidden flex-col gap-6 text-lg font-medium md:flex md:flex-row md:items-center md:gap-5 md:text-sm lg:gap-6\">\n <a\n href=\"#\"\n class=\"flex items-center gap-2 text-lg font-semibold md:text-base\"\n >\n <Package2 class=\"h-6 w-6\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Orders\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Products\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Customers\n </a>\n <a\n href=\"#\"\n class=\"text-foreground transition-colors hover:text-foreground\"\n >\n Settings\n </a>\n </nav>\n <Sheet>\n <SheetTrigger as-child>\n <Button\n variant=\"outline\"\n size=\"icon\"\n class=\"shrink-0 md:hidden\"\n >\n <Menu class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle navigation menu</span>\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\">\n <nav class=\"grid gap-6 text-lg font-medium\">\n <a\n href=\"#\"\n class=\"flex items-center gap-2 text-lg font-semibold\"\n >\n <Package2 class=\"h-6 w-6\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Orders\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Products\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Customers\n </a>\n <a href=\"#\" class=\"hover:text-foreground\">\n Settings\n </a>\n </nav>\n </SheetContent>\n </Sheet>\n <div class=\"flex w-full items-center gap-4 md:ml-auto md:gap-2 lg:gap-4\">\n <form class=\"ml-auto flex-1 sm:flex-initial\">\n <div class=\"relative\">\n <Search class=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n type=\"search\"\n placeholder=\"Search products...\"\n class=\"pl-8 sm:w-[300px] md:w-[200px] lg:w-[300px]\"\n />\n </div>\n </form>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"secondary\" size=\"icon\" class=\"rounded-full\">\n <CircleUser class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle user menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Settings</DropdownMenuItem>\n <DropdownMenuItem>Support</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Logout</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </header>\n <main class=\"flex min-h-[calc(100vh_-_theme(spacing.16))] flex-1 flex-col gap-4 bg-muted/40 p-4 md:gap-8 md:p-10\">\n <div class=\"mx-auto grid w-full max-w-6xl gap-2\">\n <h1 class=\"text-3xl font-semibold\">\n Settings\n </h1>\n </div>\n <div class=\"mx-auto grid w-full max-w-6xl items-start gap-6 md:grid-cols-[180px_1fr] lg:grid-cols-[250px_1fr]\">\n <nav class=\"grid gap-4 text-sm text-muted-foreground\">\n <a href=\"#\" class=\"font-semibold text-primary\">\n General\n </a>\n <a href=\"#\">\n Security\n </a>\n <a href=\"#\">\n Integrations\n </a>\n <a href=\"#\">\n Support\n </a>\n <a href=\"#\">\n Organizations\n </a>\n <a href=\"#\">\n Advanced\n </a>\n </nav>\n <div class=\"grid gap-6\">\n <Card>\n <CardHeader>\n <CardTitle>Store Name</CardTitle>\n <CardDescription>\n Used to identify your store in the marketplace.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <form>\n <Input placeholder=\"Store Name\" />\n </form>\n </CardContent>\n <CardFooter class=\"border-t px-6 py-4\">\n <Button>Save</Button>\n </CardFooter>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Plugins Directory</CardTitle>\n <CardDescription>\n The directory within your project, in which your plugins are\n located.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <form class=\"flex flex-col gap-4\">\n <Input\n placeholder=\"Project Name\"\n default-value=\"/content/plugins\"\n />\n <div class=\"flex items-center space-x-2\">\n <Checkbox id=\"include\" default-checked />\n <label\n for=\"include\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Allow administrators to change the directory.\n </label>\n </div>\n </form>\n </CardContent>\n <CardFooter class=\"border-t px-6 py-4\">\n <Button>Save</Button>\n </CardFooter>\n </Card>\n </div>\n </div>\n </main>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard05",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge",
|
|
"breadcrumb",
|
|
"button",
|
|
"card",
|
|
"checkbox",
|
|
"dropdown-menu",
|
|
"input",
|
|
"pagination",
|
|
"progress",
|
|
"separator",
|
|
"sheet",
|
|
"table",
|
|
"tabs",
|
|
"tooltip"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard05.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'An orders dashboard with a sidebar navigation. The sidebar has icon navigation. The content area has a breadcrumb and search in the header. The main area has a list of recent orders with a filter and export button. The main area also has a detailed view of a single order with order details, shipping information, billing information, customer information, and payment information.'\nexport const iframeHeight = '1112px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Badge } from '@/registry/new-york/ui/badge'\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/registry/new-york/ui/card'\nimport { Checkbox } from '@/registry/new-york/ui/checkbox'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/new-york/ui/dropdown-menu'\nimport { Input } from '@/registry/new-york/ui/input'\nimport {\n Pagination,\n PaginationList,\n PaginationNext,\n PaginationPrev,\n} from '@/registry/new-york/ui/pagination'\nimport { Progress } from '@/registry/new-york/ui/progress'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport { Sheet, SheetContent, SheetTrigger } from '@/registry/new-york/ui/sheet'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/new-york/ui/table'\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@/registry/new-york/ui/tabs'\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '@/registry/new-york/ui/tooltip'\nimport {\n CircleUser,\n Copy,\n CreditCard,\n File,\n Home,\n LineChart,\n ListFilter,\n MoreVertical,\n Package,\n Package2,\n PanelLeft,\n Search,\n Settings,\n ShoppingCart,\n Truck,\n Users2,\n} from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"flex min-h-screen w-full flex-col bg-muted/40\">\n <aside class=\"fixed inset-y-0 left-0 z-10 hidden w-14 flex-col border-r bg-background sm:flex\">\n <nav class=\"flex flex-col items-center gap-4 px-2 sm:py-5\">\n <a\n href=\"#\"\n class=\"group flex h-9 w-9 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:h-8 md:w-8 md:text-base\"\n >\n <Package2 class=\"h-4 w-4 transition-all group-hover:scale-110\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Home class=\"h-5 w-5\" />\n <span class=\"sr-only\">Dashboard</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Dashboard\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg bg-accent text-accent-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n <span class=\"sr-only\">Orders</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Orders\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Package class=\"h-5 w-5\" />\n <span class=\"sr-only\">Products</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Products\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Users2 class=\"h-5 w-5\" />\n <span class=\"sr-only\">Customers</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Customers\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <LineChart class=\"h-5 w-5\" />\n <span class=\"sr-only\">Analytics</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Analytics\n </TooltipContent>\n </Tooltip>\n </nav>\n <nav class=\"mt-auto flex flex-col items-center gap-4 px-2 sm:py-5\">\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Settings class=\"h-5 w-5\" />\n <span class=\"sr-only\">Settings</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Settings\n </TooltipContent>\n </Tooltip>\n </nav>\n </aside>\n <div class=\"flex flex-col sm:gap-4 sm:py-4 sm:pl-14\">\n <header class=\"sticky top-0 z-30 flex h-14 items-center gap-4 border-b bg-background px-4 sm:static sm:h-auto sm:border-0 sm:bg-transparent sm:px-6\">\n <Sheet>\n <SheetTrigger as-child>\n <Button size=\"icon\" variant=\"outline\" class=\"sm:hidden\">\n <PanelLeft class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle Menu</span>\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\" class=\"sm:max-w-xs\">\n <nav class=\"grid gap-6 text-lg font-medium\">\n <a\n href=\"#\"\n class=\"group flex h-10 w-10 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:text-base\"\n >\n <Package2 class=\"h-5 w-5 transition-all group-hover:scale-110\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Home class=\"h-5 w-5\" />\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-foreground\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n Orders\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Package class=\"h-5 w-5\" />\n Products\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Users2 class=\"h-5 w-5\" />\n Customers\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <LineChart class=\"h-5 w-5\" />\n Settings\n </a>\n </nav>\n </SheetContent>\n </Sheet>\n <Breadcrumb class=\"hidden md:flex\">\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"#\">Dashboard</a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"#\">Orders</a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Recent Orders</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n <div class=\"relative ml-auto flex-1 md:grow-0\">\n <Search class=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n type=\"search\"\n placeholder=\"Search...\"\n class=\"w-full rounded-lg bg-background pl-8 md:w-[200px] lg:w-[336px]\"\n />\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"secondary\" size=\"icon\" class=\"rounded-full\">\n <CircleUser class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle user menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Settings</DropdownMenuItem>\n <DropdownMenuItem>Support</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Logout</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </header>\n <main class=\"grid flex-1 items-start gap-4 p-4 sm:px-6 sm:py-0 md:gap-8 lg:grid-cols-3 xl:grid-cols-3\">\n <div class=\"grid auto-rows-max items-start gap-4 md:gap-8 lg:col-span-2\">\n <div class=\"grid gap-4 sm:grid-cols-2 md:grid-cols-4 lg:grid-cols-2 xl:grid-cols-4\">\n <Card class=\"sm:col-span-2\">\n <CardHeader class=\"pb-3\">\n <CardTitle>Your Orders</CardTitle>\n <CardDescription class=\"max-w-lg text-balance leading-relaxed\">\n Introducing Our Dynamic Orders Dashboard for Seamless\n Management and Insightful Analysis.\n </CardDescription>\n </CardHeader>\n <CardFooter>\n <Button>Create New Order</Button>\n </CardFooter>\n </Card>\n <Card>\n <CardHeader class=\"pb-2\">\n <CardDescription>This Week</CardDescription>\n <CardTitle class=\"text-4xl\">\n $1329\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div class=\"text-xs text-muted-foreground\">\n +25% from last week\n </div>\n </CardContent>\n <CardFooter>\n <Progress :model-value=\"25\" aria-label=\"25% increase\" />\n </CardFooter>\n </Card>\n <Card>\n <CardHeader class=\"pb-2\">\n <CardDescription>This Month</CardDescription>\n <CardTitle class=\"text-3xl\">\n $5,329\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div class=\"text-xs text-muted-foreground\">\n +10% from last month\n </div>\n </CardContent>\n <CardFooter>\n <Progress :model-value=\"12\" aria-label=\"12% increase\" />\n </CardFooter>\n </Card>\n </div>\n <Tabs default-value=\"week\">\n <div class=\"flex items-center\">\n <TabsList>\n <TabsTrigger value=\"week\">\n Week\n </TabsTrigger>\n <TabsTrigger value=\"month\">\n Month\n </TabsTrigger>\n <TabsTrigger value=\"year\">\n Year\n </TabsTrigger>\n </TabsList>\n <div class=\"ml-auto flex items-center gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\" size=\"sm\" class=\"h-7 gap-1 rounded-md px-3\">\n <ListFilter class=\"h-3.5 w-3.5\" />\n <span class=\"sr-only sm:not-sr-only\">Filter</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Filter by</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <div class=\"items-top flex space-x-2\">\n <Checkbox id=\"terms1\" />\n <label\n for=\"terms2\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Fulfilled\n </label>\n </div>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <div class=\"items-top flex space-x-2\">\n <Checkbox id=\"terms1\" />\n <label\n for=\"terms2\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Declined\n </label>\n </div>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <div class=\"items-top flex space-x-2\">\n <Checkbox id=\"terms1\" />\n <label\n for=\"terms2\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Refunded\n </label>\n </div>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n <Button variant=\"outline\" size=\"sm\" class=\"h-7 gap-1 rounded-md px-3\">\n <File class=\"h-3.5 w-3.5\" />\n <span class=\"sr-only sm:not-sr-only\">Export</span>\n </Button>\n </div>\n </div>\n <TabsContent value=\"week\">\n <Card>\n <CardHeader class=\"px-7\">\n <CardTitle>Orders</CardTitle>\n <CardDescription>\n Recent orders from your store.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Customer</TableHead>\n <TableHead class=\"hidden sm:table-cell\">\n Type\n </TableHead>\n <TableHead class=\"hidden sm:table-cell\">\n Status\n </TableHead>\n <TableHead class=\"hidden md:table-cell\">\n Date\n </TableHead>\n <TableHead class=\"text-right\">\n Amount\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <TableRow class=\"bg-accent\">\n <TableCell>\n <div class=\"font-medium\">\n Liam Johnson\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n liam@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Sale\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"secondary\">\n Fulfilled\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-23\n </TableCell>\n <TableCell class=\"text-right\">\n $250.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Olivia Smith\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n olivia@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Refund\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Declined\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-24\n </TableCell>\n <TableCell class=\"text-right\">\n $150.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Noah Williams\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n noah@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Subscription\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"secondary\">\n Fulfilled\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-25\n </TableCell>\n <TableCell class=\"text-right\">\n $350.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Emma Brown\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n emma@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Sale\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"secondary\">\n Fulfilled\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-26\n </TableCell>\n <TableCell class=\"text-right\">\n $450.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Liam Johnson\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n liam@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Sale\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"secondary\">\n Fulfilled\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-23\n </TableCell>\n <TableCell class=\"text-right\">\n $250.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Liam Johnson\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n liam@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Sale\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"secondary\">\n Fulfilled\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-23\n </TableCell>\n <TableCell class=\"text-right\">\n $250.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Olivia Smith\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n olivia@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Refund\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Declined\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-24\n </TableCell>\n <TableCell class=\"text-right\">\n $150.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Emma Brown\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n emma@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Sale\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"secondary\">\n Fulfilled\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-26\n </TableCell>\n <TableCell class=\"text-right\">\n $450.00\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </div>\n <div>\n <Card class=\"overflow-hidden\">\n <CardHeader class=\"flex flex-row items-start bg-muted/50\">\n <div class=\"grid gap-0.5\">\n <CardTitle class=\"group flex items-center gap-2 text-lg\">\n Order ID: Oe31b70H\n <Button\n size=\"icon\"\n variant=\"outline\"\n class=\"h-6 w-6 opacity-0 transition-opacity group-hover:opacity-100\"\n >\n <Copy class=\"h-3 w-3\" />\n <span class=\"sr-only\">Copy Order ID</span>\n </Button>\n </CardTitle>\n <CardDescription>Date: November 23, 2023</CardDescription>\n </div>\n <div class=\"ml-auto flex items-center gap-1\">\n <Button size=\"sm\" variant=\"outline\" class=\"h-8 gap-1\">\n <Truck class=\"h-3.5 w-3.5\" />\n <span class=\"lg:sr-only xl:not-sr-only xl:whitespace-nowrap\">\n Track Order\n </span>\n </Button>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button size=\"icon\" variant=\"outline\" class=\"h-8 w-8\">\n <MoreVertical class=\"h-3.5 w-3.5\" />\n <span class=\"sr-only\">More</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Export</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Trash</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </CardHeader>\n <CardContent class=\"p-6 text-sm\">\n <div class=\"grid gap-3\">\n <div class=\"font-semibold\">\n Order Details\n </div>\n <ul class=\"grid gap-3\">\n <li class=\"flex items-center justify-between\">\n <span class=\"text-muted-foreground\">\n Glimmer Lamps x <span>2</span>\n </span>\n <span>$250.00</span>\n </li>\n <li class=\"flex items-center justify-between\">\n <span class=\"text-muted-foreground\">\n Aqua Filters x <span>1</span>\n </span>\n <span>$49.00</span>\n </li>\n </ul>\n <Separator class=\"my-2\" />\n <ul class=\"grid gap-3\">\n <li class=\"flex items-center justify-between\">\n <span class=\"text-muted-foreground\">Subtotal</span>\n <span>$299.00</span>\n </li>\n <li class=\"flex items-center justify-between\">\n <span class=\"text-muted-foreground\">Shipping</span>\n <span>$5.00</span>\n </li>\n <li class=\"flex items-center justify-between\">\n <span class=\"text-muted-foreground\">Tax</span>\n <span>$25.00</span>\n </li>\n <li class=\"flex items-center justify-between font-semibold\">\n <span class=\"text-muted-foreground\">Total</span>\n <span>$329.00</span>\n </li>\n </ul>\n </div>\n <Separator class=\"my-4\" />\n <div class=\"grid grid-cols-2 gap-4\">\n <div class=\"grid gap-3\">\n <div class=\"font-semibold\">\n Shipping Information\n </div>\n <address class=\"grid gap-0.5 not-italic text-muted-foreground\">\n <span>Liam Johnson</span>\n <span>1234 Main St.</span>\n <span>Anytown, CA 12345</span>\n </address>\n </div>\n <div class=\"grid auto-rows-max gap-3\">\n <div class=\"font-semibold\">\n Billing Information\n </div>\n <div class=\"text-muted-foreground\">\n Same as shipping address\n </div>\n </div>\n </div>\n <Separator class=\"my-4\" />\n <div class=\"grid gap-3\">\n <div class=\"font-semibold\">\n Customer Information\n </div>\n <dl class=\"grid gap-3\">\n <div class=\"flex items-center justify-between\">\n <dt class=\"text-muted-foreground\">\n Customer\n </dt>\n <dd>Liam Johnson</dd>\n </div>\n <div class=\"flex items-center justify-between\">\n <dt class=\"text-muted-foreground\">\n Email\n </dt>\n <dd>\n <a href=\"mailto:\">liam@acme.com</a>\n </dd>\n </div>\n <div class=\"flex items-center justify-between\">\n <dt class=\"text-muted-foreground\">\n Phone\n </dt>\n <dd>\n <a href=\"tel:\">+1 234 567 890</a>\n </dd>\n </div>\n </dl>\n </div>\n <Separator class=\"my-4\" />\n <div class=\"grid gap-3\">\n <div class=\"font-semibold\">\n Payment Information\n </div>\n <dl class=\"grid gap-3\">\n <div class=\"flex items-center justify-between\">\n <dt class=\"flex items-center gap-1 text-muted-foreground\">\n <CreditCard class=\"h-4 w-4\" />\n Visa\n </dt>\n <dd>**** **** **** 4532</dd>\n </div>\n </dl>\n </div>\n </CardContent>\n <CardFooter class=\"flex flex-row items-center border-t bg-muted/50 px-6 py-3\">\n <div class=\"text-xs text-muted-foreground\">\n Updated <time dateTime=\"2023-11-23\">November 23, 2023</time>\n </div>\n <Pagination class=\"ml-auto mr-0 w-auto\" :items-per-page=\"10\">\n <PaginationList class=\"gap-1\">\n <PaginationPrev variant=\"outline\" class=\"h-6 w-6\" />\n <PaginationNext variant=\"outline\" class=\"h-6 w-6\" />\n </PaginationList>\n </Pagination>\n </CardFooter>\n </Card>\n </div>\n </main>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard06",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge",
|
|
"breadcrumb",
|
|
"button",
|
|
"card",
|
|
"dropdown-menu",
|
|
"input",
|
|
"sheet",
|
|
"table",
|
|
"tabs",
|
|
"tooltip"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard06.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'An products dashboard with a sidebar navigation. The sidebar has icon navigation. The content area has a breadcrumb and search in the header. It displays a list of products in a table with actions.'\nexport const iframeHeight = '938px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Badge } from '@/registry/new-york/ui/badge'\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/registry/new-york/ui/card'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/new-york/ui/dropdown-menu'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Sheet, SheetContent, SheetTrigger } from '@/registry/new-york/ui/sheet'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/new-york/ui/table'\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@/registry/new-york/ui/tabs'\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '@/registry/new-york/ui/tooltip'\nimport {\n CircleUser,\n File,\n Home,\n LineChart,\n ListFilter,\n MoreHorizontal,\n Package,\n Package2,\n PanelLeft,\n PlusCircle,\n Search,\n Settings,\n ShoppingCart,\n Users2,\n} from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"flex min-h-screen w-full flex-col bg-muted/40\">\n <aside class=\"fixed inset-y-0 left-0 z-10 hidden w-14 flex-col border-r bg-background sm:flex\">\n <nav class=\"flex flex-col items-center gap-4 px-2 py-4\">\n <a\n href=\"#\"\n class=\"group flex h-9 w-9 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:h-8 md:w-8 md:text-base\"\n >\n <Package2 class=\"h-4 w-4 transition-all group-hover:scale-110\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Home class=\"h-5 w-5\" />\n <span class=\"sr-only\">Dashboard</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Dashboard\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n <span class=\"sr-only\">Orders</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Orders\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg bg-accent text-accent-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Package class=\"h-5 w-5\" />\n <span class=\"sr-only\">Products</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Products\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Users2 class=\"h-5 w-5\" />\n <span class=\"sr-only\">Customers</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Customers\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <LineChart class=\"h-5 w-5\" />\n <span class=\"sr-only\">Analytics</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Analytics\n </TooltipContent>\n </Tooltip>\n </nav>\n <nav class=\"mt-auto flex flex-col items-center gap-4 px-2 py-4\">\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Settings class=\"h-5 w-5\" />\n <span class=\"sr-only\">Settings</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Settings\n </TooltipContent>\n </Tooltip>\n </nav>\n </aside>\n <div class=\"flex flex-col sm:gap-4 sm:py-4 sm:pl-14\">\n <header class=\"sticky top-0 z-30 flex h-14 items-center gap-4 border-b bg-background px-4 sm:static sm:h-auto sm:border-0 sm:bg-transparent sm:px-6\">\n <Sheet>\n <SheetTrigger as-child>\n <Button size=\"icon\" variant=\"outline\" class=\"sm:hidden\">\n <PanelLeft class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle Menu</span>\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\" class=\"sm:max-w-xs\">\n <nav class=\"grid gap-6 text-lg font-medium\">\n <a\n href=\"#\"\n class=\"group flex h-10 w-10 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:text-base\"\n >\n <Package2 class=\"h-5 w-5 transition-all group-hover:scale-110\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Home class=\"h-5 w-5\" />\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n Orders\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-foreground\"\n >\n <Package class=\"h-5 w-5\" />\n Products\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Users2 class=\"h-5 w-5\" />\n Customers\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <LineChart class=\"h-5 w-5\" />\n Settings\n </a>\n </nav>\n </SheetContent>\n </Sheet>\n <Breadcrumb class=\"hidden md:flex\">\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"#\">Dashboard</a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"#\">Products</a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>All Products</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n <div class=\"relative ml-auto flex-1 md:grow-0\">\n <Search class=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n type=\"search\"\n placeholder=\"Search...\"\n class=\"w-full rounded-lg bg-background pl-8 md:w-[200px] lg:w-[320px]\"\n />\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"secondary\" size=\"icon\" class=\"rounded-full\">\n <CircleUser class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle user menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Settings</DropdownMenuItem>\n <DropdownMenuItem>Support</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Logout</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </header>\n <main class=\"grid flex-1 items-start gap-4 p-4 sm:px-6 sm:py-0 md:gap-8\">\n <Tabs default-value=\"all\">\n <div class=\"flex items-center\">\n <TabsList>\n <TabsTrigger value=\"all\">\n All\n </TabsTrigger>\n <TabsTrigger value=\"active\">\n Active\n </TabsTrigger>\n <TabsTrigger value=\"draft\">\n Draft\n </TabsTrigger>\n <TabsTrigger value=\"archived\" class=\"hidden sm:flex\">\n Archived\n </TabsTrigger>\n </TabsList>\n <div class=\"ml-auto flex items-center gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\" size=\"sm\" class=\"h-7 gap-1\">\n <ListFilter class=\"h-3.5 w-3.5\" />\n <span class=\"sr-only sm:not-sr-only sm:whitespace-nowrap\">\n Filter\n </span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Filter by</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem checked>\n Active\n </DropdownMenuItem>\n <DropdownMenuItem>Draft</DropdownMenuItem>\n <DropdownMenuItem>\n Archived\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n <Button size=\"sm\" variant=\"outline\" class=\"h-7 gap-1\">\n <File class=\"h-3.5 w-3.5\" />\n <span class=\"sr-only sm:not-sr-only sm:whitespace-nowrap\">\n Export\n </span>\n </Button>\n <Button size=\"sm\" class=\"h-7 gap-1\">\n <PlusCircle class=\"h-3.5 w-3.5\" />\n <span class=\"sr-only sm:not-sr-only sm:whitespace-nowrap\">\n Add Product\n </span>\n </Button>\n </div>\n </div>\n <TabsContent value=\"all\">\n <Card>\n <CardHeader>\n <CardTitle>Products</CardTitle>\n <CardDescription>\n Manage your products and view their sales performance.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead class=\"hidden w-[100px] sm:table-cell\">\n <span class=\"sr-only\">img</span>\n </TableHead>\n <TableHead>Name</TableHead>\n <TableHead>Status</TableHead>\n <TableHead class=\"hidden md:table-cell\">\n Price\n </TableHead>\n <TableHead class=\"hidden md:table-cell\">\n Total Sales\n </TableHead>\n <TableHead class=\"hidden md:table-cell\">\n Created at\n </TableHead>\n <TableHead>\n <span class=\"sr-only\">Actions</span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <TableRow>\n <TableCell class=\"hidden sm:table-cell\">\n <img\n alt=\"Product image\"\n class=\"aspect-square rounded-md object-cover\"\n height=\"64\"\n src=\"/placeholder.svg\"\n width=\"64\"\n >\n </TableCell>\n <TableCell class=\"font-medium\">\n Laser Lemonade Machine\n </TableCell>\n <TableCell>\n <Badge variant=\"outline\">\n Draft\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n $499.99\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 25\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-07-12 10:42 AM\n </TableCell>\n <TableCell>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button\n aria-haspopup=\"true\"\n size=\"icon\"\n variant=\"ghost\"\n >\n <MoreHorizontal class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Delete</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"hidden sm:table-cell\">\n <img\n alt=\"Product image\"\n class=\"aspect-square rounded-md object-cover\"\n height=\"64\"\n src=\"/placeholder.svg\"\n width=\"64\"\n >\n </TableCell>\n <TableCell class=\"font-medium\">\n Hypernova Headphones\n </TableCell>\n <TableCell>\n <Badge variant=\"outline\">\n Active\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n $129.99\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 100\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-10-18 03:21 PM\n </TableCell>\n <TableCell>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button\n aria-haspopup=\"true\"\n size=\"icon\"\n variant=\"ghost\"\n >\n <MoreHorizontal class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Delete</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"hidden sm:table-cell\">\n <img\n alt=\"Product image\"\n class=\"aspect-square rounded-md object-cover\"\n height=\"64\"\n src=\"/placeholder.svg\"\n width=\"64\"\n >\n </TableCell>\n <TableCell class=\"font-medium\">\n AeroGlow Desk Lamp\n </TableCell>\n <TableCell>\n <Badge variant=\"outline\">\n Active\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n $39.99\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 50\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-11-29 08:15 AM\n </TableCell>\n <TableCell>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button\n aria-haspopup=\"true\"\n size=\"icon\"\n variant=\"ghost\"\n >\n <MoreHorizontal class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Delete</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"hidden sm:table-cell\">\n <img\n alt=\"Product image\"\n class=\"aspect-square rounded-md object-cover\"\n height=\"64\"\n src=\"/placeholder.svg\"\n width=\"64\"\n >\n </TableCell>\n <TableCell class=\"font-medium\">\n TechTonic Energy Drink\n </TableCell>\n <TableCell>\n <Badge variant=\"secondary\">\n Draft\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n $2.99\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 0\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-12-25 11:59 PM\n </TableCell>\n <TableCell>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button\n aria-haspopup=\"true\"\n size=\"icon\"\n variant=\"ghost\"\n >\n <MoreHorizontal class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Delete</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"hidden sm:table-cell\">\n <img\n alt=\"Product image\"\n class=\"aspect-square rounded-md object-cover\"\n height=\"64\"\n src=\"/placeholder.svg\"\n width=\"64\"\n >\n </TableCell>\n <TableCell class=\"font-medium\">\n Gamer Gear Pro Controller\n </TableCell>\n <TableCell>\n <Badge variant=\"outline\">\n Active\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n $59.99\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 75\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2024-01-01 12:00 AM\n </TableCell>\n <TableCell>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button\n aria-haspopup=\"true\"\n size=\"icon\"\n variant=\"ghost\"\n >\n <MoreHorizontal class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Delete</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"hidden sm:table-cell\">\n <img\n alt=\"Product image\"\n class=\"aspect-square rounded-md object-cover\"\n height=\"64\"\n src=\"/placeholder.svg\"\n width=\"64\"\n >\n </TableCell>\n <TableCell class=\"font-medium\">\n Luminous VR Headset\n </TableCell>\n <TableCell>\n <Badge variant=\"outline\">\n Active\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n $199.99\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 30\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2024-02-14 02:14 PM\n </TableCell>\n <TableCell>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button\n aria-haspopup=\"true\"\n size=\"icon\"\n variant=\"ghost\"\n >\n <MoreHorizontal class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Delete</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </CardContent>\n <CardFooter>\n <div class=\"text-xs text-muted-foreground\">\n Showing <strong>1-10</strong> of <strong>32</strong>\n products\n </div>\n </CardFooter>\n </Card>\n </TabsContent>\n </Tabs>\n </main>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard07",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge",
|
|
"breadcrumb",
|
|
"button",
|
|
"card",
|
|
"dropdown-menu",
|
|
"input",
|
|
"label",
|
|
"select",
|
|
"sheet",
|
|
"table",
|
|
"textarea",
|
|
"toggle-group",
|
|
"tooltip"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard07.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A product edit page. The product edit page has a form to edit the product details, stock, product category, product status, and product images. The product edit page has a sidebar navigation and a main content area. The main content area has a form to edit the product details, stock, product category, product status, and product images. The sidebar navigation has links to product details, stock, product category, product status, and product images.'\nexport const iframeHeight = '1200px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Badge } from '@/registry/new-york/ui/badge'\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Button } from '@/registry/new-york/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/registry/new-york/ui/card'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/new-york/ui/dropdown-menu'\nimport { Input } from '@/registry/new-york/ui/input'\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/new-york/ui/select'\nimport { Sheet, SheetContent, SheetTrigger } from '@/registry/new-york/ui/sheet'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/new-york/ui/table'\nimport { Textarea } from '@/registry/new-york/ui/textarea'\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/new-york/ui/toggle-group'\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '@/registry/new-york/ui/tooltip'\nimport {\n ChevronLeft,\n CircleUser,\n Home,\n LineChart,\n Package,\n Package2,\n PanelLeft,\n PlusCircle,\n Search,\n Settings,\n ShoppingCart,\n Upload,\n Users2,\n} from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"flex min-h-screen w-full flex-col bg-muted/40\">\n <aside class=\"fixed inset-y-0 left-0 z-10 hidden w-14 flex-col border-r bg-background sm:flex\">\n <nav class=\"flex flex-col items-center gap-4 px-2 sm:py-5\">\n <a\n href=\"#\"\n class=\"group flex h-9 w-9 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:h-8 md:w-8 md:text-base\"\n >\n <Package2 class=\"h-4 w-4 transition-all group-hover:scale-110\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Home class=\"h-5 w-5\" />\n <span class=\"sr-only\">Dashboard</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Dashboard\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg bg-accent text-accent-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n <span class=\"sr-only\">Orders</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Orders\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Package class=\"h-5 w-5\" />\n <span class=\"sr-only\">Products</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Products\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Users2 class=\"h-5 w-5\" />\n <span class=\"sr-only\">Customers</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Customers\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <LineChart class=\"h-5 w-5\" />\n <span class=\"sr-only\">Analytics</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Analytics\n </TooltipContent>\n </Tooltip>\n </nav>\n <nav class=\"mt-auto flex flex-col items-center gap-4 px-2 sm:py-5\">\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Settings class=\"h-5 w-5\" />\n <span class=\"sr-only\">Settings</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Settings\n </TooltipContent>\n </Tooltip>\n </nav>\n </aside>\n <div class=\"flex flex-col sm:gap-4 sm:py-4 sm:pl-14\">\n <header class=\"sticky top-0 z-30 flex h-14 items-center gap-4 border-b bg-background px-4 sm:static sm:h-auto sm:border-0 sm:bg-transparent sm:px-6\">\n <Sheet>\n <SheetTrigger as-child>\n <Button size=\"icon\" variant=\"outline\" class=\"sm:hidden\">\n <PanelLeft class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle Menu</span>\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\" class=\"sm:max-w-xs\">\n <nav class=\"grid gap-6 text-lg font-medium\">\n <a\n href=\"#\"\n class=\"group flex h-10 w-10 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:text-base\"\n >\n <Package2 class=\"h-5 w-5 transition-all group-hover:scale-110\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Home class=\"h-5 w-5\" />\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n Orders\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-foreground\"\n >\n <Package class=\"h-5 w-5\" />\n Products\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Users2 class=\"h-5 w-5\" />\n Customers\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <LineChart class=\"h-5 w-5\" />\n Settings\n </a>\n </nav>\n </SheetContent>\n </Sheet>\n <Breadcrumb class=\"hidden md:flex\">\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"#\">Dashboard</a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"#\">Products</a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Edit Product</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n <div class=\"relative ml-auto flex-1 md:grow-0\">\n <Search class=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n type=\"search\"\n placeholder=\"Search...\"\n class=\"w-full rounded-lg bg-background pl-8 md:w-[200px] lg:w-[336px]\"\n />\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"secondary\" size=\"icon\" class=\"rounded-full\">\n <CircleUser class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle user menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Settings</DropdownMenuItem>\n <DropdownMenuItem>Support</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Logout</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </header>\n <main class=\"grid flex-1 items-start gap-4 p-4 sm:px-6 sm:py-0 md:gap-8\">\n <div class=\"mx-auto grid max-w-[59rem] flex-1 auto-rows-max gap-4\">\n <div class=\"flex items-center gap-4\">\n <Button variant=\"outline\" size=\"icon\" class=\"h-7 w-7\">\n <ChevronLeft class=\"h-4 w-4\" />\n <span class=\"sr-only\">Back</span>\n </Button>\n <h1 class=\"flex-1 shrink-0 whitespace-nowrap text-xl font-semibold tracking-tight sm:grow-0\">\n Pro Controller\n </h1>\n <Badge variant=\"outline\" class=\"ml-auto sm:ml-0\">\n In stock\n </Badge>\n <div class=\"hidden items-center gap-2 md:ml-auto md:flex\">\n <Button variant=\"outline\" size=\"sm\">\n Discard\n </Button>\n <Button size=\"sm\">\n Save Product\n </Button>\n </div>\n </div>\n <div class=\"grid gap-4 md:grid-cols-[1fr_250px] lg:grid-cols-3 lg:gap-8\">\n <div class=\"grid auto-rows-max items-start gap-4 lg:col-span-2 lg:gap-8\">\n <Card>\n <CardHeader>\n <CardTitle>Product Details</CardTitle>\n <CardDescription>\n Lipsum dolor sit amet, consectetur adipiscing elit\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div class=\"grid gap-6\">\n <div class=\"grid gap-3\">\n <Label for=\"name\">Name</Label>\n <Input\n id=\"name\"\n type=\"text\"\n class=\"w-full\"\n default-value=\"Gamer Gear Pro Controller\"\n />\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"description\">Description</Label>\n <Textarea\n id=\"description\"\n default-value=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam auctor, nisl nec ultricies ultricies, nunc nisl ultricies nunc, nec ultricies nunc nisl nec nunc.\"\n class=\"min-h-32\"\n />\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Stock</CardTitle>\n <CardDescription>\n Lipsum dolor sit amet, consectetur adipiscing elit\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead class=\"w-[100px]\">\n SKU\n </TableHead>\n <TableHead>Stock</TableHead>\n <TableHead>Price</TableHead>\n <TableHead class=\"w-[100px]\">\n Size\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <TableRow>\n <TableCell class=\"font-semibold\">\n GGPC-001\n </TableCell>\n <TableCell>\n <Label for=\"stock-1\" class=\"sr-only\">\n Stock\n </Label>\n <Input\n id=\"stock-1\"\n type=\"number\"\n default-value=\"100\"\n />\n </TableCell>\n <TableCell>\n <Label for=\"price-1\" class=\"sr-only\">\n Price\n </Label>\n <Input\n id=\"price-1\"\n type=\"number\"\n default-value=\"99.99\"\n />\n </TableCell>\n <TableCell>\n <ToggleGroup\n type=\"single\"\n default-value=\"s\"\n variant=\"outline\"\n >\n <ToggleGroupItem value=\"s\">\n S\n </ToggleGroupItem>\n <ToggleGroupItem value=\"m\">\n M\n </ToggleGroupItem>\n <ToggleGroupItem value=\"l\">\n L\n </ToggleGroupItem>\n </ToggleGroup>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"font-semibold\">\n GGPC-002\n </TableCell>\n <TableCell>\n <Label for=\"stock-2\" class=\"sr-only\">\n Stock\n </Label>\n <Input\n id=\"stock-2\"\n type=\"number\"\n default-value=\"143\"\n />\n </TableCell>\n <TableCell>\n <Label for=\"price-2\" class=\"sr-only\">\n Price\n </Label>\n <Input\n id=\"price-2\"\n type=\"number\"\n default-value=\"99.99\"\n />\n </TableCell>\n <TableCell>\n <ToggleGroup\n type=\"single\"\n default-value=\"m\"\n variant=\"outline\"\n >\n <ToggleGroupItem value=\"s\">\n S\n </ToggleGroupItem>\n <ToggleGroupItem value=\"m\">\n M\n </ToggleGroupItem>\n <ToggleGroupItem value=\"l\">\n L\n </ToggleGroupItem>\n </ToggleGroup>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"font-semibold\">\n GGPC-003\n </TableCell>\n <TableCell>\n <Label for=\"stock-3\" class=\"sr-only\">\n Stock\n </Label>\n <Input\n id=\"stock-3\"\n type=\"number\"\n default-value=\"32\"\n />\n </TableCell>\n <TableCell>\n <Label for=\"price-3\" class=\"sr-only\">\n Stock\n </Label>\n <Input\n id=\"price-3\"\n type=\"number\"\n default-value=\"99.99\"\n />\n </TableCell>\n <TableCell>\n <ToggleGroup\n type=\"single\"\n default-value=\"s\"\n variant=\"outline\"\n >\n <ToggleGroupItem value=\"s\">\n S\n </ToggleGroupItem>\n <ToggleGroupItem value=\"m\">\n M\n </ToggleGroupItem>\n <ToggleGroupItem value=\"l\">\n L\n </ToggleGroupItem>\n </ToggleGroup>\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </CardContent>\n <CardFooter class=\"justify-center border-t p-4\">\n <Button size=\"sm\" variant=\"ghost\" class=\"gap-1\">\n <PlusCircle class=\"h-3.5 w-3.5\" />\n Add Variant\n </Button>\n </CardFooter>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Product Category</CardTitle>\n </CardHeader>\n <CardContent>\n <div class=\"grid gap-6 sm:grid-cols-3\">\n <div class=\"grid gap-3\">\n <Label for=\"category\">Category</Label>\n <Select>\n <SelectTrigger\n id=\"category\"\n aria-label=\"Select category\"\n >\n <SelectValue placeholder=\"Select category\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"clothing\">\n Clothing\n </SelectItem>\n <SelectItem value=\"electronics\">\n Electronics\n </SelectItem>\n <SelectItem value=\"accessories\">\n Accessories\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"subcategory\">\n Subcategory (optional)\n </Label>\n <Select>\n <SelectTrigger\n id=\"subcategory\"\n aria-label=\"Select subcategory\"\n >\n <SelectValue placeholder=\"Select subcategory\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"t-shirts\">\n T-Shirts\n </SelectItem>\n <SelectItem value=\"hoodies\">\n Hoodies\n </SelectItem>\n <SelectItem value=\"sweatshirts\">\n Sweatshirts\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n <div class=\"grid auto-rows-max items-start gap-4 lg:gap-8\">\n <Card>\n <CardHeader>\n <CardTitle>Product Status</CardTitle>\n </CardHeader>\n <CardContent>\n <div class=\"grid gap-6\">\n <div class=\"grid gap-3\">\n <Label for=\"status\">Status</Label>\n <Select>\n <SelectTrigger id=\"status\" aria-label=\"Select status\">\n <SelectValue placeholder=\"Select status\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"draft\">\n Draft\n </SelectItem>\n <SelectItem value=\"published\">\n Active\n </SelectItem>\n <SelectItem value=\"archived\">\n Archived\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card class=\"overflow-hidden\">\n <CardHeader>\n <CardTitle>Product imgs</CardTitle>\n <CardDescription>\n Lipsum dolor sit amet, consectetur adipiscing elit\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div class=\"grid gap-2\">\n <img\n alt=\"Product image\"\n class=\"aspect-square w-full rounded-md object-cover\"\n height=\"300\"\n src=\"/placeholder.svg\"\n width=\"300\"\n >\n <div class=\"grid grid-cols-3 gap-2\">\n <button>\n <img\n alt=\"Product image\"\n class=\"aspect-square w-full rounded-md object-cover\"\n height=\"84\"\n src=\"/placeholder.svg\"\n width=\"84\"\n >\n </button>\n <button>\n <img\n alt=\"Product image\"\n class=\"aspect-square w-full rounded-md object-cover\"\n height=\"84\"\n src=\"/placeholder.svg\"\n width=\"84\"\n >\n </button>\n <button class=\"flex aspect-square w-full items-center justify-center rounded-md border border-dashed\">\n <Upload class=\"h-4 w-4 text-muted-foreground\" />\n <span class=\"sr-only\">Upload</span>\n </button>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Archive Product</CardTitle>\n <CardDescription>\n Lipsum dolor sit amet, consectetur adipiscing elit.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div />\n <Button size=\"sm\" variant=\"secondary\">\n Archive Product\n </Button>\n </CardContent>\n </Card>\n </div>\n </div>\n <div class=\"flex items-center justify-center gap-2 md:hidden\">\n <Button variant=\"outline\" size=\"sm\">\n Discard\n </Button>\n <Button size=\"sm\">\n Save Product\n </Button>\n </div>\n </div>\n </main>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebar",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarInset,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n\nimport { Calendar, Home, Inbox, Search, Settings } from 'lucide-vue-next'\n\n// Menu items.\nconst items = [\n {\n title: 'Home',\n url: '#',\n icon: Home,\n },\n {\n title: 'Inbox',\n url: '#',\n icon: Inbox,\n },\n {\n title: 'Calendar',\n url: '#',\n icon: Calendar,\n },\n {\n title: 'Search',\n url: '#',\n icon: Search,\n },\n {\n title: 'Settings',\n url: '#',\n icon: Settings,\n },\n]\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Application</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n <SidebarInset>\n <header class=\"flex items-center justify-between px-4 h-12\">\n <SidebarTrigger />\n </header>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarControlled",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarControlled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarInset,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n Frame,\n LifeBuoy,\n Map,\n PanelLeftClose,\n PanelLeftOpen,\n PieChart,\n Send,\n} from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst projects = [\n {\n name: 'Design Engineering',\n url: '#',\n icon: Frame,\n },\n {\n name: 'Sales & Marketing',\n url: '#',\n icon: PieChart,\n },\n {\n name: 'Travel',\n url: '#',\n icon: Map,\n },\n {\n name: 'Support',\n url: '#',\n icon: LifeBuoy,\n },\n {\n name: 'Feedback',\n url: '#',\n icon: Send,\n },\n]\n\nconst open = ref(true)\n</script>\n\n<template>\n <SidebarProvider v-model:open=\"open\">\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"project in projects\" :key=\"project.name\">\n <SidebarMenuButton as-child>\n <a :href=\"project.url\">\n <component :is=\"project.icon\" />\n <span>{{ project.name }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n <SidebarInset>\n <header className=\"flex items-center h-12 px-4 justify-between\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n @click=\"open = !open\"\n >\n <PanelLeftClose v-if=\"open\" />\n <PanelLeftOpen v-else />\n <span>{{ open ? 'Close' : 'Open' }} Sidebar</span>\n </Button>\n </header>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarFooter",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"dropdown-menu",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarInset,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\nimport { ChevronUp } from 'lucide-vue-next'\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarHeader />\n <SidebarContent />\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\">\n Username\n <ChevronUp class=\"ml-auto\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n side=\"top\"\n class=\"w-[--reka-popper-anchor-width]\"\n >\n <DropdownMenuItem>\n <span>Account</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <span>Billing</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <span>Sign out</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n </Sidebar>\n <SidebarInset>\n <header class=\"flex items-center justify-between px-4 h-12\">\n <SidebarTrigger />\n </header>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarGroup",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/new-york/ui/sidebar'\n\nimport { LifeBuoy, Send } from 'lucide-vue-next'\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Help</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <LifeBuoy />\n Support\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <Send />\n Feedback\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarGroupAction",
|
|
"type": "registry:block",
|
|
"dependencies": [
|
|
"vue-sonner"
|
|
],
|
|
"registryDependencies": [
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarGroupAction.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n Frame,\n Map,\n PieChart,\n Plus,\n} from 'lucide-vue-next'\n\nimport { toast, Toaster } from 'vue-sonner'\n</script>\n\n<template>\n <SidebarProvider>\n <Toaster\n position=\"bottom-left\"\n :toast-options=\"{\n class: 'ml-[160px]',\n }\"\n />\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarGroupAction\n title=\"Add Project\"\n @click=\"() => toast('You clicked the group action!')\"\n >\n <Plus /> <span class=\"sr-only\">Add Project</span>\n </SidebarGroupAction>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton as-child>\n <a href=\"#\">\n <Frame />\n <span>Design Engineering</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton as-child>\n <a href=\"#\">\n <PieChart />\n <span>Sales & Marketing</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton as-child>\n <a href=\"#\">\n <Map />\n <span>Travel</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarGroupCollapsible",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"collapsible",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarGroupCollapsible.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/new-york/ui/collapsible'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/new-york/ui/sidebar'\nimport { ChevronDown, LifeBuoy, Send } from 'lucide-vue-next'\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <Collapsible :default-open=\"true\" class=\"group/collapsible\">\n <SidebarGroup>\n <SidebarGroupLabel\n as-child\n class=\"text-sm hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\"\n >\n <CollapsibleTrigger>\n Help\n <ChevronDown class=\"ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180\" />\n </CollapsibleTrigger>\n </SidebarGroupLabel>\n <CollapsibleContent>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <LifeBuoy />\n Support\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <Send />\n Feedback\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </CollapsibleContent>\n </SidebarGroup>\n </Collapsible>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarHeader",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"dropdown-menu",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n\nimport {\n Sidebar,\n SidebarHeader,\n SidebarInset,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\nimport { ChevronDown } from 'lucide-vue-next'\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\">\n Select Workspace\n <ChevronDown class=\"ml-auto\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent class=\"w-[--reka-popper-anchor-width]\">\n <DropdownMenuItem>\n <span>Acme Inc</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <span>Acme Corp.</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarHeader>\n </Sidebar>\n <SidebarInset>\n <header class=\"flex items-center justify-between px-4 h-12\">\n <SidebarTrigger />\n </header>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarMenu",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarMenu.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/new-york/ui/sidebar'\n\nimport { Frame, LifeBuoy, Map, PieChart, Send } from 'lucide-vue-next'\n\nconst projects = [\n {\n name: 'Design Engineering',\n url: '#',\n icon: Frame,\n },\n {\n name: 'Sales & Marketing',\n url: '#',\n icon: PieChart,\n },\n {\n name: 'Travel',\n url: '#',\n icon: Map,\n },\n {\n name: 'Support',\n url: '#',\n icon: LifeBuoy,\n },\n {\n name: 'Feedback',\n url: '#',\n icon: Send,\n },\n]\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"project in projects\" :key=\"project.name\">\n <SidebarMenuButton as-child>\n <a :href=\"project.url\">\n <component :is=\"project.icon\" />\n <span>{{ project.name }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarMenuAction",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"dropdown-menu",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarMenuAction.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n Frame,\n LifeBuoy,\n Map,\n MoreHorizontal,\n PieChart,\n Send,\n} from 'lucide-vue-next'\n\nconst projects = [\n {\n name: 'Design Engineering',\n url: '#',\n icon: Frame,\n },\n {\n name: 'Sales & Marketing',\n url: '#',\n icon: PieChart,\n },\n {\n name: 'Travel',\n url: '#',\n icon: Map,\n },\n {\n name: 'Support',\n url: '#',\n icon: LifeBuoy,\n },\n {\n name: 'Feedback',\n url: '#',\n icon: Send,\n },\n]\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"project in projects\" :key=\"project.name\">\n <SidebarMenuButton\n as-child\n class=\"group-has-[[data-state=open]]/menu-item:bg-sidebar-accent\"\n >\n <a :href=\"project.url\">\n <component :is=\"project.icon\" />\n <span>{{ project.name }}</span>\n </a>\n </SidebarMenuButton>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuAction>\n <MoreHorizontal />\n <span class=\"sr-only\">More</span>\n </SidebarMenuAction>\n </DropdownMenuTrigger>\n <DropdownMenuContent side=\"right\" align=\"start\">\n <DropdownMenuItem>\n <span>Edit Project</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <span>Delete Project</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarMenuBadge",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarMenuBadge.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/new-york/ui/sidebar'\n\nimport { Frame, LifeBuoy, Map, PieChart, Send } from 'lucide-vue-next'\n\nconst projects = [\n {\n name: 'Design Engineering',\n url: '#',\n icon: Frame,\n badge: '24',\n },\n {\n name: 'Sales & Marketing',\n url: '#',\n icon: PieChart,\n badge: '12',\n },\n {\n name: 'Travel',\n url: '#',\n icon: Map,\n badge: '3',\n },\n {\n name: 'Support',\n url: '#',\n icon: LifeBuoy,\n badge: '21',\n },\n {\n name: 'Feedback',\n url: '#',\n icon: Send,\n badge: '8',\n },\n]\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"project in projects\" :key=\"project.name\">\n <SidebarMenuButton\n as-child\n class=\"group-has-[[data-state=open]]/menu-item:bg-sidebar-accent\"\n >\n <a :href=\"project.url\">\n <component :is=\"project.icon\" />\n <span>{{ project.name }}</span>\n </a>\n </SidebarMenuButton>\n <SidebarMenuBadge>{{ project.badge }}</SidebarMenuBadge>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarMenuCollapsible",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"collapsible",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarMenuCollapsible.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/new-york/ui/collapsible'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n} from '@/registry/new-york/ui/sidebar'\nimport { ChevronRight } from 'lucide-vue-next'\n\nconst items = [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n]\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupContent>\n <SidebarMenu>\n <Collapsible\n v-for=\"(item, index) in items\"\n :key=\"index\"\n class=\"group/collapsible\"\n :default-open=\"index === 0\"\n >\n <SidebarMenuItem>\n <CollapsibleTrigger as-child>\n <SidebarMenuButton>\n <span>{{ item.title }}</span>\n <ChevronRight class=\"transition-transform ml-auto group-data-[state=open]/collapsible:rotate-90\" />\n </SidebarMenuButton>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"(subItem, subIndex) in item.items\" :key=\"subIndex\">\n <SidebarMenuSubButton as-child>\n <a :href=\"subItem.url\">\n <span>{{ subItem.title }}</span>\n </a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarMenuSub",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarMenuSub.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n} from '@/registry/new-york/ui/sidebar'\n\nconst items = [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n]\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"(item, index) in items\" :key=\"index\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\">\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"(subItem, subIndex) in item.items\" :key=\"subIndex\">\n <SidebarMenuSubButton as-child>\n <a :href=\"subItem.url\">\n <span>{{ subItem.title }}</span>\n </a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Login01",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card",
|
|
"input",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Login01/page.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 = '870px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport LoginForm from '@/registry/new-york/block/Login01/components/LoginForm.vue'\n</script>\n\n<template>\n <div className=\"flex h-screen w-full items-center justify-center px-4\">\n <LoginForm />\n </div>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Login01/components/LoginForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} 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:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar01",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"label",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar01/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description\n = 'A simple sidebar with navigation grouped by section.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/new-york/block/Sidebar01/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 border-b px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar01/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport SearchForm from '@/registry/new-york/block/Sidebar01/components/SearchForm.vue'\nimport VersionSwitcher from '@/registry/new-york/block/Sidebar01/components/VersionSwitcher.vue'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/new-york/ui/sidebar'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n versions: ['1.0.1', '1.1.0-alpha', '2.0.0-beta1'],\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <VersionSwitcher\n :versions=\"data.versions\"\n :default-version=\"data.versions[0]\"\n />\n <SearchForm />\n </SidebarHeader>\n <SidebarContent>\n <SidebarGroup v-for=\"item in data.navMain\" :key=\"item.title\">\n <SidebarGroupLabel>{{ item.title }}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"childItem in item.items\" :key=\"childItem.title\">\n <SidebarMenuButton as-child :is-active=\"childItem.isActive\">\n <a :href=\"childItem.url\">{{ childItem.title }}</a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar01/components/SearchForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarInput,\n} from '@/registry/new-york/ui/sidebar'\nimport { Search } from 'lucide-vue-next'\n</script>\n\n<template>\n <form>\n <SidebarGroup class=\"py-0\">\n <SidebarGroupContent class=\"relative\">\n <Label for=\"search\" class=\"sr-only\">\n Search\n </Label>\n <SidebarInput\n id=\"search\"\n placeholder=\"Search the docs...\"\n class=\"pl-8\"\n />\n <Search class=\"pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 select-none opacity-50\" />\n </SidebarGroupContent>\n </SidebarGroup>\n </form>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar01/components/VersionSwitcher.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/new-york/ui/sidebar'\nimport { Check, ChevronsUpDown, GalleryVerticalEnd } from 'lucide-vue-next'\n\nimport { ref } from 'vue'\n\nconst props = defineProps<{\n versions: string[]\n defaultVersion: string\n}>()\n\nconst selectedVersion = ref(props.defaultVersion)\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <GalleryVerticalEnd class=\"size-4\" />\n </div>\n <div class=\"flex flex-col gap-0.5 leading-none\">\n <span class=\"font-semibold\">Documentation</span>\n <span class=\"\">v{{ selectedVersion }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width]\"\n align=\"start\"\n >\n <DropdownMenuItem\n v-for=\"version in versions\"\n :key=\"version\"\n @select=\"selectedVersion = version\"\n >\n v{{ version }}\n <Check v-if=\"version === selectedVersion\" class=\"ml-auto\" />\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar02",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible",
|
|
"label",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar02/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A sidebar with collapsible sections.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/new-york/block/Sidebar02/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex sticky top-0 bg-background h-16 shrink-0 items-center gap-2 border-b px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div\n v-for=\"i in 24\"\n :key=\"i\"\n class=\"aspect-video h-12 w-full rounded-lg bg-muted/50\"\n />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar02/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport SearchForm from '@/registry/new-york/block/Sidebar02/components/SearchForm.vue'\nimport VersionSwitcher from '@/registry/new-york/block/Sidebar02/components/VersionSwitcher.vue'\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/new-york/ui/collapsible'\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/new-york/ui/sidebar'\nimport { ChevronRight } from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n versions: ['1.0.1', '1.1.0-alpha', '2.0.0-beta1'],\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n {\n title: 'Community',\n url: '#',\n items: [\n {\n title: 'Contribution Guide',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <VersionSwitcher\n :versions=\"data.versions\"\n :default-version=\"data.versions[0]\"\n />\n <SearchForm />\n </SidebarHeader>\n <SidebarContent class=\"gap-0\">\n <Collapsible\n v-for=\"item in data.navMain\"\n :key=\"item.title\"\n :title=\"item.title\"\n default-open\n class=\"group/collapsible\"\n >\n <SidebarGroup>\n <SidebarGroupLabel\n as-child\n class=\"group/label text-sm text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\"\n >\n <CollapsibleTrigger>\n {{ item.title }}\n <ChevronRight class=\"ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90\" />\n </CollapsibleTrigger>\n </SidebarGroupLabel>\n <CollapsibleContent>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"childItem in item.items\" :key=\"childItem.title\">\n <SidebarMenuButton as-child :is-active=\"childItem.isActive\">\n <a :href=\"item.url\">{{ childItem.title }}</a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </CollapsibleContent>\n </SidebarGroup>\n </Collapsible>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar02/components/SearchForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarInput,\n} from '@/registry/new-york/ui/sidebar'\nimport { Search } from 'lucide-vue-next'\n</script>\n\n<template>\n <form>\n <SidebarGroup class=\"py-0\">\n <SidebarGroupContent class=\"relative\">\n <Label for=\"search\" class=\"sr-only\">\n Search\n </Label>\n <SidebarInput\n id=\"search\"\n placeholder=\"Search the docs...\"\n class=\"pl-8\"\n />\n <Search class=\"pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 select-none opacity-50\" />\n </SidebarGroupContent>\n </SidebarGroup>\n </form>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar02/components/VersionSwitcher.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/new-york/ui/sidebar'\nimport { Check, ChevronsUpDown, GalleryVerticalEnd } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst props = defineProps<{\n versions: string[]\n defaultVersion: string\n}>()\n\nconst selectedVersion = ref(props.defaultVersion)\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <GalleryVerticalEnd class=\"size-4\" />\n </div>\n <div class=\"flex flex-col gap-0.5 leading-none\">\n <span class=\"font-semibold\">Documentation</span>\n <span class=\"\">v{{ selectedVersion }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width]\"\n align=\"start\"\n >\n <DropdownMenuItem\n v-for=\"version in versions\"\n :key=\"version\"\n @select=\"selectedVersion = version\"\n >\n v{{ version }}\n <Check v-if=\"selectedVersion === version\" class=\"ml-auto\" />\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar03",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar03/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A sidebar with submenus.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/new-york/block/Sidebar03/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 border-b\">\n <div class=\"flex items-center gap-2 px-3\">\n <SidebarTrigger />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar03/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/new-york/ui/sidebar'\n\nimport { GalleryVerticalEnd } from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n {\n title: 'Community',\n url: '#',\n items: [\n {\n title: 'Contribution Guide',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton size=\"lg\" as-child>\n <a href=\"#\">\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <GalleryVerticalEnd class=\"size-4\" />\n </div>\n <div class=\"flex flex-col gap-0.5 leading-none\">\n <span class=\"font-semibold\">Documentation</span>\n <span class=\"\">v1.0.0</span>\n </div>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarHeader>\n <SidebarContent>\n <SidebarGroup>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in data.navMain\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\" class=\"font-medium\">\n {{ item.title }}\n </a>\n </SidebarMenuButton>\n <SidebarMenuSub v-if=\"item.items.length\">\n <SidebarMenuSubItem v-for=\"childItem in item.items\" :key=\"childItem.title\">\n <SidebarMenuSubButton as-child :is-active=\"childItem.isActive\">\n <a :href=\"childItem.url\">{{ childItem.title }}</a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar04",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar04/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A floating sidebar with submenus.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/new-york/block/Sidebar04/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider :style=\"{ '--sidebar-width': '19rem' }\">\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4 pt-0\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar04/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n type SidebarProps,\n} from '@/registry/new-york/ui/sidebar'\n\nimport { GalleryVerticalEnd } from 'lucide-vue-next'\n\nconst props = withDefaults(defineProps<SidebarProps>(), {\n variant: 'floating',\n})\n\n// This is sample data.\nconst data = {\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n {\n title: 'Community',\n url: '#',\n items: [\n {\n title: 'Contribution Guide',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton size=\"lg\" as-child>\n <a href=\"#\">\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <GalleryVerticalEnd class=\"size-4\" />\n </div>\n <div class=\"flex flex-col gap-0.5 leading-none\">\n <span class=\"font-semibold\">Documentation</span>\n <span class=\"\">v1.0.0</span>\n </div>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarHeader>\n <SidebarContent>\n <SidebarGroup>\n <SidebarMenu class=\"gap-2\">\n <SidebarMenuItem v-for=\"item in data.navMain\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\" class=\"font-medium\">\n {{ item.title }}\n </a>\n </SidebarMenuButton>\n <SidebarMenuSub v-if=\"item.items.length\">\n <SidebarMenuSubItem v-for=\"childItem in item.items\" :key=\"childItem.title\">\n <SidebarMenuSubButton as-child :is-active=\"childItem.isActive\">\n <a :href=\"childItem.url\">{{ childItem.title }}</a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar05",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar05/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A sidebar with collapsible submenus.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/new-york/block/Sidebar05/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 border-b px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar05/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport SearchForm from '@/registry/new-york/block/Sidebar05/components/SearchForm.vue'\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/new-york/ui/collapsible'\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/new-york/ui/sidebar'\nimport { GalleryVerticalEnd, Minus, Plus } from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n {\n title: 'Community',\n url: '#',\n items: [\n {\n title: 'Contribution Guide',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton size=\"lg\" as-child>\n <a href=\"#\">\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <GalleryVerticalEnd class=\"size-4\" />\n </div>\n <div class=\"flex flex-col gap-0.5 leading-none\">\n <span class=\"font-semibold\">Documentation</span>\n <span class=\"\">v1.0.0</span>\n </div>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n <SearchForm />\n </SidebarHeader>\n <SidebarContent>\n <SidebarGroup>\n <SidebarMenu>\n <Collapsible\n v-for=\"(item, index) in data.navMain\"\n :key=\"item.title\"\n :default-open=\"index === 1\"\n class=\"group/collapsible\"\n >\n <SidebarMenuItem>\n <CollapsibleTrigger as-child>\n <SidebarMenuButton>\n {{ item.title }}\n <Plus class=\"ml-auto group-data-[state=open]/collapsible:hidden\" />\n <Minus class=\"ml-auto group-data-[state=closed]/collapsible:hidden\" />\n </SidebarMenuButton>\n </CollapsibleTrigger>\n <CollapsibleContent v-if=\"item.items.length\">\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"childItem in item.items\" :key=\"childItem.title\">\n <SidebarMenuSubButton\n as-child\n :is-active=\"childItem.isActive\"\n >\n <a :href=\"childItem.url\">{{ childItem.title }}</a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n </SidebarMenu>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar05/components/SearchForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarInput,\n} from '@/registry/new-york/ui/sidebar'\nimport { Search } from 'lucide-vue-next'\n</script>\n\n<template>\n <form>\n <SidebarGroup class=\"py-0\">\n <SidebarGroupContent class=\"relative\">\n <Label for=\"search\" class=\"sr-only\">\n Search\n </Label>\n <SidebarInput\n id=\"search\"\n placeholder=\"Search the docs...\"\n class=\"pl-8\"\n />\n <Search class=\"pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 select-none opacity-50\" />\n </SidebarGroupContent>\n </SidebarGroup>\n </form>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar06",
|
|
"type": "registry:block",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"dropdown-menu",
|
|
"button",
|
|
"card"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar06/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A sidebar with submenus as dropdowns.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/new-york/block/Sidebar06/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 border-b px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar06/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport NavMain from '@/registry/new-york/block/Sidebar06/components/NavMain.vue'\nimport SidebarOptInForm from '@/registry/new-york/block/Sidebar06/components/SidebarOptInForm.vue'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/new-york/ui/sidebar'\nimport { GalleryVerticalEnd } from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton size=\"lg\" as-child>\n <a href=\"#\">\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <GalleryVerticalEnd class=\"size-4\" />\n </div>\n <div class=\"flex flex-col gap-0.5 leading-none\">\n <span class=\"font-semibold\">Documentation</span>\n <span class=\"\">v1.0.0</span>\n </div>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarHeader>\n <SidebarContent>\n <NavMain :items=\"data.navMain\" />\n </SidebarContent>\n <SidebarFooter>\n <div class=\"p-1\">\n <SidebarOptInForm />\n </div>\n </SidebarFooter>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar06/components/NavMain.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n\nimport {\n SidebarGroup,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/new-york/ui/sidebar'\nimport { useMediaQuery } from '@vueuse/core'\nimport { type LucideIcon, MoreHorizontal } from 'lucide-vue-next'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon?: LucideIcon\n isActive?: boolean\n items?: {\n title: string\n url: string\n }[]\n }[]\n}>()\n\nconst isMobile = useMediaQuery('(max-width: 768px)')\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarMenu>\n <DropdownMenu v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuItem>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\">\n {{ item.title }} <MoreHorizontal class=\"ml-auto\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n v-if=\"item.items?.length\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n :align=\"isMobile ? 'end' : 'start'\"\n class=\"min-w-56 rounded-lg\"\n >\n <DropdownMenuItem v-for=\"childItem in item.items\" :key=\"childItem.title\" as-child>\n <a :href=\"childItem.url\">{{ childItem.title }}</a>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </SidebarMenuItem>\n </DropdownMenu>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar06/components/SidebarOptInForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@/registry/new-york/ui/card'\nimport { SidebarInput } from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <Card class=\"shadow-none\">\n <form>\n <CardHeader class=\"p-4 pb-0\">\n <CardTitle class=\"text-sm\">\n Subscribe to our newsletter\n </CardTitle>\n <CardDescription>\n Opt-in to receive updates and news about the sidebar.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"grid gap-2.5 p-4\">\n <SidebarInput type=\"email\" placeholder=\"Email\" />\n <Button\n class=\"w-full bg-sidebar-primary text-sidebar-primary-foreground shadow-none\"\n size=\"sm\"\n >\n Subscribe\n </Button>\n </CardContent>\n </form>\n </Card>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar07",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible",
|
|
"dropdown-menu",
|
|
"avatar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar07/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description\n = 'A sidebar that collapses to icons.'\nexport const iframeHeight = '800px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/new-york/block/Sidebar07/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12\">\n <div class=\"flex items-center gap-2 px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4 pt-0\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar07/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { SidebarProps } from '@/registry/new-york/ui/sidebar'\n\nimport NavMain from '@/registry/new-york/block/Sidebar07/components/NavMain.vue'\nimport NavProjects from '@/registry/new-york/block/Sidebar07/components/NavProjects.vue'\nimport NavUser from '@/registry/new-york/block/Sidebar07/components/NavUser.vue'\nimport TeamSwitcher from '@/registry/new-york/block/Sidebar07/components/TeamSwitcher.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarRail,\n} from '@/registry/new-york/ui/sidebar'\n\nimport {\n AudioWaveform,\n BookOpen,\n Bot,\n Command,\n Frame,\n GalleryVerticalEnd,\n Map,\n PieChart,\n Settings2,\n SquareTerminal,\n} from 'lucide-vue-next'\n\nconst props = withDefaults(defineProps<SidebarProps>(), {\n collapsible: 'icon',\n})\n\n// This is sample data.\nconst data = {\n user: {\n name: 'shadcn',\n email: 'm@example.com',\n avatar: '/avatars/shadcn.jpg',\n },\n teams: [\n {\n name: 'Acme Inc',\n logo: GalleryVerticalEnd,\n plan: 'Enterprise',\n },\n {\n name: 'Acme Corp.',\n logo: AudioWaveform,\n plan: 'Startup',\n },\n {\n name: 'Evil Corp.',\n logo: Command,\n plan: 'Free',\n },\n ],\n navMain: [\n {\n title: 'Playground',\n url: '#',\n icon: SquareTerminal,\n isActive: true,\n items: [\n {\n title: 'History',\n url: '#',\n },\n {\n title: 'Starred',\n url: '#',\n },\n {\n title: 'Settings',\n url: '#',\n },\n ],\n },\n {\n title: 'Models',\n url: '#',\n icon: Bot,\n items: [\n {\n title: 'Genesis',\n url: '#',\n },\n {\n title: 'Explorer',\n url: '#',\n },\n {\n title: 'Quantum',\n url: '#',\n },\n ],\n },\n {\n title: 'Documentation',\n url: '#',\n icon: BookOpen,\n items: [\n {\n title: 'Introduction',\n url: '#',\n },\n {\n title: 'Get Started',\n url: '#',\n },\n {\n title: 'Tutorials',\n url: '#',\n },\n {\n title: 'Changelog',\n url: '#',\n },\n ],\n },\n {\n title: 'Settings',\n url: '#',\n icon: Settings2,\n items: [\n {\n title: 'General',\n url: '#',\n },\n {\n title: 'Team',\n url: '#',\n },\n {\n title: 'Billing',\n url: '#',\n },\n {\n title: 'Limits',\n url: '#',\n },\n ],\n },\n ],\n projects: [\n {\n name: 'Design Engineering',\n url: '#',\n icon: Frame,\n },\n {\n name: 'Sales & Marketing',\n url: '#',\n icon: PieChart,\n },\n {\n name: 'Travel',\n url: '#',\n icon: Map,\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <TeamSwitcher :teams=\"data.teams\" />\n </SidebarHeader>\n <SidebarContent>\n <NavMain :items=\"data.navMain\" />\n <NavProjects :projects=\"data.projects\" />\n </SidebarContent>\n <SidebarFooter>\n <NavUser :user=\"data.user\" />\n </SidebarFooter>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar07/components/NavMain.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/new-york/ui/collapsible'\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n} from '@/registry/new-york/ui/sidebar'\nimport { ChevronRight, type LucideIcon } from 'lucide-vue-next'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon?: LucideIcon\n isActive?: boolean\n items?: {\n title: string\n url: string\n }[]\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupLabel>Platform</SidebarGroupLabel>\n <SidebarMenu>\n <Collapsible\n v-for=\"item in items\"\n :key=\"item.title\"\n as-child\n :default-open=\"item.isActive\"\n class=\"group/collapsible\"\n >\n <SidebarMenuItem>\n <CollapsibleTrigger as-child>\n <SidebarMenuButton :tooltip=\"item.title\">\n <component :is=\"item.icon\" v-if=\"item.icon\" />\n <span>{{ item.title }}</span>\n <ChevronRight class=\"ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90\" />\n </SidebarMenuButton>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"subItem in item.items\" :key=\"subItem.title\">\n <SidebarMenuSubButton as-child>\n <a :href=\"subItem.url\">\n <span>{{ subItem.title }}</span>\n </a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar07/components/NavProjects.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n Folder,\n Forward,\n type LucideIcon,\n MoreHorizontal,\n Trash2,\n} from 'lucide-vue-next'\n\ndefineProps<{\n projects: {\n name: string\n url: string\n icon: LucideIcon\n }[]\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarGroup class=\"group-data-[collapsible=icon]:hidden\">\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in projects\" :key=\"item.name\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.name }}</span>\n </a>\n </SidebarMenuButton>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuAction show-on-hover>\n <MoreHorizontal />\n <span class=\"sr-only\">More</span>\n </SidebarMenuAction>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-48 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n :align=\"isMobile ? 'end' : 'start'\"\n >\n <DropdownMenuItem>\n <Folder class=\"text-muted-foreground\" />\n <span>View Project</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Forward class=\"text-muted-foreground\" />\n <span>Share Project</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Trash2 class=\"text-muted-foreground\" />\n <span>Delete Project</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton class=\"text-sidebar-foreground/70\">\n <MoreHorizontal class=\"text-sidebar-foreground/70\" />\n <span>More</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar07/components/NavUser.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/registry/new-york/ui/avatar'\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n BadgeCheck,\n Bell,\n ChevronsUpDown,\n CreditCard,\n LogOut,\n Sparkles,\n} from 'lucide-vue-next'\n\nconst props = defineProps<{\n user: {\n name: string\n email: string\n avatar: string\n }\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto size-4\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n align=\"end\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"p-0 font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <Sparkles />\n Upgrade to Pro\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <BadgeCheck />\n Account\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CreditCard />\n Billing\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Bell />\n Notifications\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut />\n Log out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar07/components/TeamSwitcher.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/new-york/ui/sidebar'\nimport { ChevronsUpDown, Plus } from 'lucide-vue-next'\n\nimport { type Component, ref } from 'vue'\n\nconst props = defineProps<{\n teams: {\n name: string\n logo: Component\n plan: string\n }[]\n}>()\n\nconst { isMobile } = useSidebar()\nconst activeTeam = ref(props.teams[0])\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <component :is=\"activeTeam.logo\" class=\"size-4\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">\n {{ activeTeam.name }}\n </span>\n <span class=\"truncate text-xs\">{{ activeTeam.plan }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n align=\"start\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"text-xs text-muted-foreground\">\n Teams\n </DropdownMenuLabel>\n <DropdownMenuItem\n v-for=\"(team, index) in teams\"\n :key=\"team.name\"\n class=\"gap-2 p-2\"\n @click=\"activeTeam = team\"\n >\n <div class=\"flex size-6 items-center justify-center rounded-sm border\">\n <component :is=\"team.logo\" class=\"size-4 shrink-0\" />\n </div>\n {{ team.name }}\n <DropdownMenuShortcut>⌘{{ index + 1 }}</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem class=\"gap-2 p-2\">\n <div class=\"flex size-6 items-center justify-center rounded-md border bg-background\">\n <Plus class=\"size-4\" />\n </div>\n <div class=\"font-medium text-muted-foreground\">\n Add team\n </div>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar08",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible",
|
|
"dropdown-menu",
|
|
"avatar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar08/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'An inset sidebar with secondary navigation.'\nexport const iframeHeight = '800px'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/new-york/block/Sidebar08/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2\">\n <div class=\"flex items-center gap-2 px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4 pt-0\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar08/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport NavMain from '@/registry/new-york/block/Sidebar08/components/NavMain.vue'\n\nimport NavProjects from '@/registry/new-york/block/Sidebar08/components/NavProjects.vue'\nimport NavSecondary from '@/registry/new-york/block/Sidebar08/components/NavSecondary.vue'\nimport NavUser from '@/registry/new-york/block/Sidebar08/components/NavUser.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n BookOpen,\n Bot,\n Command,\n Frame,\n LifeBuoy,\n Map,\n PieChart,\n Send,\n Settings2,\n SquareTerminal,\n} from 'lucide-vue-next'\n\nconst props = withDefaults(defineProps<SidebarProps>(), {\n variant: 'inset',\n})\n\nconst data = {\n user: {\n name: 'shadcn',\n email: 'm@example.com',\n avatar: '/avatars/shadcn.jpg',\n },\n navMain: [\n {\n title: 'Playground',\n url: '#',\n icon: SquareTerminal,\n isActive: true,\n items: [\n {\n title: 'History',\n url: '#',\n },\n {\n title: 'Starred',\n url: '#',\n },\n {\n title: 'Settings',\n url: '#',\n },\n ],\n },\n {\n title: 'Models',\n url: '#',\n icon: Bot,\n items: [\n {\n title: 'Genesis',\n url: '#',\n },\n {\n title: 'Explorer',\n url: '#',\n },\n {\n title: 'Quantum',\n url: '#',\n },\n ],\n },\n {\n title: 'Documentation',\n url: '#',\n icon: BookOpen,\n items: [\n {\n title: 'Introduction',\n url: '#',\n },\n {\n title: 'Get Started',\n url: '#',\n },\n {\n title: 'Tutorials',\n url: '#',\n },\n {\n title: 'Changelog',\n url: '#',\n },\n ],\n },\n {\n title: 'Settings',\n url: '#',\n icon: Settings2,\n items: [\n {\n title: 'General',\n url: '#',\n },\n {\n title: 'Team',\n url: '#',\n },\n {\n title: 'Billing',\n url: '#',\n },\n {\n title: 'Limits',\n url: '#',\n },\n ],\n },\n ],\n navSecondary: [\n {\n title: 'Support',\n url: '#',\n icon: LifeBuoy,\n },\n {\n title: 'Feedback',\n url: '#',\n icon: Send,\n },\n ],\n projects: [\n {\n name: 'Design Engineering',\n url: '#',\n icon: Frame,\n },\n {\n name: 'Sales & Marketing',\n url: '#',\n icon: PieChart,\n },\n {\n name: 'Travel',\n url: '#',\n icon: Map,\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton size=\"lg\" as-child>\n <a href=\"#\">\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <Command class=\"size-4\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">Acme Inc</span>\n <span class=\"truncate text-xs\">Enterprise</span>\n </div>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarHeader>\n <SidebarContent>\n <NavMain :items=\"data.navMain\" />\n <NavProjects :projects=\"data.projects\" />\n <NavSecondary :items=\"data.navSecondary\" class=\"mt-auto\" />\n </SidebarContent>\n <SidebarFooter>\n <NavUser :user=\"data.user\" />\n </SidebarFooter>\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar08/components/NavMain.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/new-york/ui/collapsible'\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n} from '@/registry/new-york/ui/sidebar'\nimport { ChevronRight, type LucideIcon } from 'lucide-vue-next'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon: LucideIcon\n isActive?: boolean\n items?: {\n title: string\n url: string\n }[]\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupLabel>Platform</SidebarGroupLabel>\n <SidebarMenu>\n <Collapsible v-for=\"item in items\" :key=\"item.title\" as-child :default-open=\"item.isActive\">\n <SidebarMenuItem>\n <SidebarMenuButton as-child :tooltip=\"item.title\">\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n <template v-if=\"item.items?.length\">\n <CollapsibleTrigger as-child>\n <SidebarMenuAction class=\"data-[state=open]:rotate-90\">\n <ChevronRight />\n <span class=\"sr-only\">Toggle</span>\n </SidebarMenuAction>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"subItem in item.items\" :key=\"subItem.title\">\n <SidebarMenuSubButton as-child>\n <a :href=\"subItem.url\">\n <span>{{ subItem.title }}</span>\n </a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </CollapsibleContent>\n </template>\n </SidebarMenuItem>\n </Collapsible>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar08/components/NavProjects.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n Folder,\n Forward,\n type LucideIcon,\n MoreHorizontal,\n Trash2,\n} from 'lucide-vue-next'\n\ndefineProps<{\n projects: {\n name: string\n url: string\n icon: LucideIcon\n }[]\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarGroup class=\"group-data-[collapsible=icon]:hidden\">\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in projects\" :key=\"item.name\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.name }}</span>\n </a>\n </SidebarMenuButton>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuAction show-on-hover>\n <MoreHorizontal />\n <span class=\"sr-only\">More</span>\n </SidebarMenuAction>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-48 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n :align=\"isMobile ? 'end' : 'start'\"\n >\n <DropdownMenuItem>\n <Folder class=\"text-muted-foreground\" />\n <span>View Project</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Forward class=\"text-muted-foreground\" />\n <span>Share Project</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Trash2 class=\"text-muted-foreground\" />\n <span>Delete Project</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton class=\"text-sidebar-foreground/70\">\n <MoreHorizontal class=\"text-sidebar-foreground/70\" />\n <span>More</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar08/components/NavSecondary.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { LucideIcon } from 'lucide-vue-next'\n\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/new-york/ui/sidebar'\n\nconst props = defineProps<{\n items: {\n title: string\n url: string\n icon: LucideIcon\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuButton as-child size=\"sm\">\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar08/components/NavUser.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/registry/new-york/ui/avatar'\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n BadgeCheck,\n Bell,\n ChevronsUpDown,\n CreditCard,\n LogOut,\n Sparkles,\n} from 'lucide-vue-next'\n\nconst props = defineProps<{\n user: {\n name: string\n email: string\n avatar: string\n }\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto size-4\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n align=\"end\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"p-0 font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <Sparkles />\n Upgrade to Pro\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <BadgeCheck />\n Account\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CreditCard />\n Billing\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Bell />\n Notifications\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut />\n Log out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar09",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"label",
|
|
"switch",
|
|
"avatar",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar09/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'Collapsible nested sidebars.'\nexport const iframeHeight = '800px'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/new-york/block/Sidebar09/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider\n :style=\"{\n '--sidebar-width': '350px',\n }\"\n >\n <AppSidebar />\n <SidebarInset>\n <header class=\"sticky top-0 flex shrink-0 items-center gap-2 border-b bg-background p-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n All Inboxes\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Inbox</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div\n v-for=\"index in 24\"\n :key=\"index\"\n class=\"aspect-video h-12 w-full rounded-lg bg-muted/50\"\n />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar09/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport NavUser from '@/registry/new-york/block/Sidebar09/components/NavUser.vue'\n\nimport { Label } from '@/registry/new-york/ui/label'\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupContent,\n SidebarHeader,\n SidebarInput,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n useSidebar,\n} from '@/registry/new-york/ui/sidebar'\nimport { Switch } from '@/registry/new-york/ui/switch'\nimport { ArchiveX, Command, File, Inbox, Send, Trash2 } from 'lucide-vue-next'\nimport { h, ref } from 'vue'\n\nconst props = withDefaults(defineProps<SidebarProps>(), {\n collapsible: 'icon',\n})\n\n// This is sample data\nconst data = {\n user: {\n name: 'shadcn',\n email: 'm@example.com',\n avatar: '/avatars/shadcn.jpg',\n },\n navMain: [\n {\n title: 'Inbox',\n url: '#',\n icon: Inbox,\n isActive: true,\n },\n {\n title: 'Drafts',\n url: '#',\n icon: File,\n isActive: false,\n },\n {\n title: 'Sent',\n url: '#',\n icon: Send,\n isActive: false,\n },\n {\n title: 'Junk',\n url: '#',\n icon: ArchiveX,\n isActive: false,\n },\n {\n title: 'Trash',\n url: '#',\n icon: Trash2,\n isActive: false,\n },\n ],\n mails: [\n {\n name: 'William Smith',\n email: 'williamsmith@example.com',\n subject: 'Meeting Tomorrow',\n date: '09:34 AM',\n teaser:\n 'Hi team, just a reminder about our meeting tomorrow at 10 AM.\\nPlease come prepared with your project updates.',\n },\n {\n name: 'Alice Smith',\n email: 'alicesmith@example.com',\n subject: 'Re: Project Update',\n date: 'Yesterday',\n teaser:\n 'Thanks for the update. The progress looks great so far.\\nLet\\'s schedule a call to discuss the next steps.',\n },\n {\n name: 'Bob Johnson',\n email: 'bobjohnson@example.com',\n subject: 'Weekend Plans',\n date: '2 days ago',\n teaser:\n 'Hey everyone! I\\'m thinking of organizing a team outing this weekend.\\nWould you be interested in a hiking trip or a beach day?',\n },\n {\n name: 'Emily Davis',\n email: 'emilydavis@example.com',\n subject: 'Re: Question about Budget',\n date: '2 days ago',\n teaser:\n 'I\\'ve reviewed the budget numbers you sent over.\\nCan we set up a quick call to discuss some potential adjustments?',\n },\n {\n name: 'Michael Wilson',\n email: 'michaelwilson@example.com',\n subject: 'Important Announcement',\n date: '1 week ago',\n teaser:\n 'Please join us for an all-hands meeting this Friday at 3 PM.\\nWe have some exciting news to share about the company\\'s future.',\n },\n {\n name: 'Sarah Brown',\n email: 'sarahbrown@example.com',\n subject: 'Re: Feedback on Proposal',\n date: '1 week ago',\n teaser:\n 'Thank you for sending over the proposal. I\\'ve reviewed it and have some thoughts.\\nCould we schedule a meeting to discuss my feedback in detail?',\n },\n {\n name: 'David Lee',\n email: 'davidlee@example.com',\n subject: 'New Project Idea',\n date: '1 week ago',\n teaser:\n 'I\\'ve been brainstorming and came up with an interesting project concept.\\nDo you have time this week to discuss its potential impact and feasibility?',\n },\n {\n name: 'Olivia Wilson',\n email: 'oliviawilson@example.com',\n subject: 'Vacation Plans',\n date: '1 week ago',\n teaser:\n 'Just a heads up that I\\'ll be taking a two-week vacation next month.\\nI\\'ll make sure all my projects are up to date before I leave.',\n },\n {\n name: 'James Martin',\n email: 'jamesmartin@example.com',\n subject: 'Re: Conference Registration',\n date: '1 week ago',\n teaser:\n 'I\\'ve completed the registration for the upcoming tech conference.\\nLet me know if you need any additional information from my end.',\n },\n {\n name: 'Sophia White',\n email: 'sophiawhite@example.com',\n subject: 'Team Dinner',\n date: '1 week ago',\n teaser:\n 'To celebrate our recent project success, I\\'d like to organize a team dinner.\\nAre you available next Friday evening? Please let me know your preferences.',\n },\n ],\n}\n\nconst activeItem = ref(data.navMain[0])\nconst mails = ref(data.mails)\nconst { setOpen } = useSidebar()\n</script>\n\n<template>\n <Sidebar\n class=\"overflow-hidden [&>[data-sidebar=sidebar]]:flex-row\"\n v-bind=\"props\"\n >\n <!-- This is the first sidebar -->\n <!-- We disable collapsible and adjust width to icon. -->\n <!-- This will make the sidebar appear as icons. -->\n <Sidebar\n collapsible=\"none\"\n class=\"!w-[calc(var(--sidebar-width-icon)_+_1px)] border-r\"\n >\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton size=\"lg\" as-child class=\"md:h-8 md:p-0\">\n <a href=\"#\">\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <Command class=\"size-4\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">Acme Inc</span>\n <span class=\"truncate text-xs\">Enterprise</span>\n </div>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarHeader>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupContent class=\"px-1.5 md:px-0\">\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in data.navMain\" :key=\"item.title\">\n <SidebarMenuButton\n :tooltip=\"h('div', { hidden: false }, item.title)\"\n :is-active=\"activeItem.title === item.title\"\n class=\"px-2.5 md:px-2\"\n @click=\"() => {\n activeItem = item\n\n const mail = data.mails.sort(() => Math.random() - 0.5)\n mails = mail.slice(0, Math.max(5, Math.floor(Math.random() * 10) + 1))\n setOpen(true)\n }\"\n >\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n <SidebarFooter>\n <NavUser :user=\"data.user\" />\n </SidebarFooter>\n </Sidebar>\n\n <!-- This is the second sidebar -->\n <!-- We disable collapsible and let it fill remaining space -->\n <Sidebar collapsible=\"none\" class=\"hidden flex-1 md:flex\">\n <SidebarHeader class=\"gap-3.5 border-b p-4\">\n <div class=\"flex w-full items-center justify-between\">\n <div class=\"text-base font-medium text-foreground\">\n {{ activeItem.title }}\n </div>\n <Label class=\"flex items-center gap-2 text-sm\">\n <span>Unreads</span>\n <Switch class=\"shadow-none\" />\n </Label>\n </div>\n <SidebarInput placeholder=\"Type to search...\" />\n </SidebarHeader>\n <SidebarContent>\n <SidebarGroup class=\"px-0\">\n <SidebarGroupContent>\n <a\n v-for=\"mail in mails\"\n :key=\"mail.email\"\n href=\"#\"\n class=\"flex flex-col items-start gap-2 whitespace-nowrap border-b p-4 text-sm leading-tight last:border-b-0 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\"\n >\n <div class=\"flex w-full items-center gap-2\">\n <span>{{ mail.name }}</span>\n <span class=\"ml-auto text-xs\">{{ mail.date }}</span>\n </div>\n <span class=\"font-medium\">{{ mail.subject }}</span>\n <span class=\"line-clamp-2 w-[260px] whitespace-break-spaces text-xs\">\n {{ mail.teaser }}\n </span>\n </a>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar09/components/NavUser.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/registry/new-york/ui/avatar'\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n BadgeCheck,\n Bell,\n ChevronsUpDown,\n CreditCard,\n LogOut,\n Sparkles,\n} from 'lucide-vue-next'\n\nconst props = defineProps<{\n user: {\n name: string\n email: string\n avatar: string\n }\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground md:h-8 md:p-0\"\n >\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto size-4\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n align=\"end\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"p-0 font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <Sparkles />\n Upgrade to Pro\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <BadgeCheck />\n Account\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CreditCard />\n Billing\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Bell />\n Notifications\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut />\n Log out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar10",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"button",
|
|
"popover",
|
|
"dropdown-menu",
|
|
"collapsible"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar10/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A sidebar in a popover.'\nexport const iframeHeight = '800px'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/new-york/block/Sidebar10/components/AppSidebar.vue'\nimport NavActions from '@/registry/new-york/block/Sidebar10/components/NavActions.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbList,\n BreadcrumbPage,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-14 shrink-0 items-center gap-2\">\n <div class=\"flex flex-1 items-center gap-2 px-3\">\n <SidebarTrigger />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbPage class=\"line-clamp-1\">\n Project Management & Task Tracking\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n <div class=\"ml-auto px-3\">\n <NavActions />\n </div>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 px-4 py-10\">\n <div class=\"mx-auto h-24 w-full max-w-3xl rounded-xl bg-muted/50\" />\n <div class=\"mx-auto h-full w-full max-w-3xl rounded-xl bg-muted/50\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport NavFavorites from '@/registry/new-york/block/Sidebar10/components/NavFavorites.vue'\n\nimport NavMain from '@/registry/new-york/block/Sidebar10/components/NavMain.vue'\nimport NavSecondary from '@/registry/new-york/block/Sidebar10/components/NavSecondary.vue'\nimport NavWorkspaces from '@/registry/new-york/block/Sidebar10/components/NavWorkspaces.vue'\nimport TeamSwitcher from '@/registry/new-york/block/Sidebar10/components/TeamSwitcher.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarHeader,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n AudioWaveform,\n Blocks,\n Calendar,\n Command,\n Home,\n Inbox,\n MessageCircleQuestion,\n Search,\n Settings2,\n Sparkles,\n Trash2,\n} from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n teams: [\n {\n name: 'Acme Inc',\n logo: Command,\n plan: 'Enterprise',\n },\n {\n name: 'Acme Corp.',\n logo: AudioWaveform,\n plan: 'Startup',\n },\n {\n name: 'Evil Corp.',\n logo: Command,\n plan: 'Free',\n },\n ],\n navMain: [\n {\n title: 'Search',\n url: '#',\n icon: Search,\n },\n {\n title: 'Ask AI',\n url: '#',\n icon: Sparkles,\n },\n {\n title: 'Home',\n url: '#',\n icon: Home,\n isActive: true,\n },\n {\n title: 'Inbox',\n url: '#',\n icon: Inbox,\n badge: '10',\n },\n ],\n navSecondary: [\n {\n title: 'Calendar',\n url: '#',\n icon: Calendar,\n },\n {\n title: 'Settings',\n url: '#',\n icon: Settings2,\n },\n {\n title: 'Templates',\n url: '#',\n icon: Blocks,\n },\n {\n title: 'Trash',\n url: '#',\n icon: Trash2,\n },\n {\n title: 'Help',\n url: '#',\n icon: MessageCircleQuestion,\n },\n ],\n favorites: [\n {\n name: 'Project Management & Task Tracking',\n url: '#',\n emoji: '📊',\n },\n {\n name: 'Family Recipe Collection & Meal Planning',\n url: '#',\n emoji: '🍳',\n },\n {\n name: 'Fitness Tracker & Workout Routines',\n url: '#',\n emoji: '💪',\n },\n {\n name: 'Book Notes & Reading List',\n url: '#',\n emoji: '📚',\n },\n {\n name: 'Sustainable Gardening Tips & Plant Care',\n url: '#',\n emoji: '🌱',\n },\n {\n name: 'Language Learning Progress & Resources',\n url: '#',\n emoji: '🗣️',\n },\n {\n name: 'Home Renovation Ideas & Budget Tracker',\n url: '#',\n emoji: '🏠',\n },\n {\n name: 'Personal Finance & Investment Portfolio',\n url: '#',\n emoji: '💰',\n },\n {\n name: 'Movie & TV Show Watchlist with Reviews',\n url: '#',\n emoji: '🎬',\n },\n {\n name: 'Daily Habit Tracker & Goal Setting',\n url: '#',\n emoji: '✅',\n },\n ],\n workspaces: [\n {\n name: 'Personal Life Management',\n emoji: '🏠',\n pages: [\n {\n name: 'Daily Journal & Reflection',\n url: '#',\n emoji: '📔',\n },\n {\n name: 'Health & Wellness Tracker',\n url: '#',\n emoji: '🍏',\n },\n {\n name: 'Personal Growth & Learning Goals',\n url: '#',\n emoji: '🌟',\n },\n ],\n },\n {\n name: 'Professional Development',\n emoji: '💼',\n pages: [\n {\n name: 'Career Objectives & Milestones',\n url: '#',\n emoji: '🎯',\n },\n {\n name: 'Skill Acquisition & Training Log',\n url: '#',\n emoji: '🧠',\n },\n {\n name: 'Networking Contacts & Events',\n url: '#',\n emoji: '🤝',\n },\n ],\n },\n {\n name: 'Creative Projects',\n emoji: '🎨',\n pages: [\n {\n name: 'Writing Ideas & Story Outlines',\n url: '#',\n emoji: '✍️',\n },\n {\n name: 'Art & Design Portfolio',\n url: '#',\n emoji: '🖼️',\n },\n {\n name: 'Music Composition & Practice Log',\n url: '#',\n emoji: '🎵',\n },\n ],\n },\n {\n name: 'Home Management',\n emoji: '🏡',\n pages: [\n {\n name: 'Household Budget & Expense Tracking',\n url: '#',\n emoji: '💰',\n },\n {\n name: 'Home Maintenance Schedule & Tasks',\n url: '#',\n emoji: '🔧',\n },\n {\n name: 'Family Calendar & Event Planning',\n url: '#',\n emoji: '📅',\n },\n ],\n },\n {\n name: 'Travel & Adventure',\n emoji: '🧳',\n pages: [\n {\n name: 'Trip Planning & Itineraries',\n url: '#',\n emoji: '🗺️',\n },\n {\n name: 'Travel Bucket List & Inspiration',\n url: '#',\n emoji: '🌎',\n },\n {\n name: 'Travel Journal & Photo Gallery',\n url: '#',\n emoji: '📸',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar class=\"border-r-0\" v-bind=\"props\">\n <SidebarHeader>\n <TeamSwitcher :teams=\"data.teams\" />\n <NavMain :items=\"data.navMain\" />\n </SidebarHeader>\n <SidebarContent>\n <NavFavorites :favorites=\"data.favorites\" />\n <NavWorkspaces :workspaces=\"data.workspaces\" />\n <NavSecondary :items=\"data.navSecondary\" class=\"mt-auto\" />\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/NavActions.vue",
|
|
"content": "<script setup lang=\"ts\">\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 Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n ArrowDown,\n ArrowUp,\n Bell,\n Copy,\n CornerUpLeft,\n CornerUpRight,\n FileText,\n GalleryVerticalEnd,\n LineChart,\n Link,\n MoreHorizontal,\n Settings2,\n Star,\n Trash,\n Trash2,\n} from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst data = [\n [\n {\n label: 'Customize Page',\n icon: Settings2,\n },\n {\n label: 'Turn into wiki',\n icon: FileText,\n },\n ],\n [\n {\n label: 'Copy Link',\n icon: Link,\n },\n {\n label: 'Duplicate',\n icon: Copy,\n },\n {\n label: 'Move to',\n icon: CornerUpRight,\n },\n {\n label: 'Move to Trash',\n icon: Trash2,\n },\n ],\n [\n {\n label: 'Undo',\n icon: CornerUpLeft,\n },\n {\n label: 'View analytics',\n icon: LineChart,\n },\n {\n label: 'Version History',\n icon: GalleryVerticalEnd,\n },\n {\n label: 'Show delete pages',\n icon: Trash,\n },\n {\n label: 'Notifications',\n icon: Bell,\n },\n ],\n [\n {\n label: 'Import',\n icon: ArrowUp,\n },\n {\n label: 'Export',\n icon: ArrowDown,\n },\n ],\n]\n\nconst isOpen = ref(false)\n</script>\n\n<template>\n <div class=\"flex items-center gap-2 text-sm\">\n <div class=\"hidden font-medium text-muted-foreground md:inline-block\">\n Edit Oct 08\n </div>\n <Button variant=\"ghost\" size=\"icon\" class=\"h-7 w-7\">\n <Star />\n </Button>\n <Popover v-model:open=\"isOpen\">\n <PopoverTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"h-7 w-7 data-[state=open]:bg-accent\"\n >\n <MoreHorizontal />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n class=\"w-56 overflow-hidden rounded-lg p-0\"\n align=\"end\"\n >\n <Sidebar collapsible=\"none\" class=\"bg-transparent\">\n <SidebarContent>\n <SidebarGroup v-for=\"(group, index) in data\" :key=\"index\" class=\"border-b last:border-none\">\n <SidebarGroupContent class=\"gap-0\">\n <SidebarMenu>\n <SidebarMenuItem v-for=\"(item, index) in group\" :key=\"index\">\n <SidebarMenuButton>\n <component :is=\"item.icon\" /> <span>{{ item.label }}</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </PopoverContent>\n </Popover>\n </div>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/NavFavorites.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n ArrowUpRight,\n Link,\n MoreHorizontal,\n StarOff,\n Trash2,\n} from 'lucide-vue-next'\n\ndefineProps<{\n favorites: {\n name: string\n url: string\n emoji: string\n }[]\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarGroup class=\"group-data-[collapsible=icon]:hidden\">\n <SidebarGroupLabel>Favorites</SidebarGroupLabel>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in favorites\" :key=\"item.name\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\" :title=\"item.name\">\n <span>{{ item.emoji }}</span>\n <span>{{ item.name }}</span>\n </a>\n </SidebarMenuButton>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuAction show-on-hover>\n <MoreHorizontal />\n <span class=\"sr-only\">More</span>\n </SidebarMenuAction>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n :align=\"isMobile ? 'end' : 'start'\"\n >\n <DropdownMenuItem>\n <StarOff class=\"text-muted-foreground\" />\n <span>Remove from Favorites</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Link class=\"text-muted-foreground\" />\n <span>Copy Link</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <ArrowUpRight class=\"text-muted-foreground\" />\n <span>Open in New Tab</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Trash2 class=\"text-muted-foreground\" />\n <span>Delete</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n\n <SidebarMenuItem>\n <SidebarMenuButton class=\"text-sidebar-foreground/70\">\n <MoreHorizontal />\n <span>More</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/NavMain.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { LucideIcon } from 'lucide-vue-next'\n\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/new-york/ui/sidebar'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon: LucideIcon\n isActive?: boolean\n }[]\n}>()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuButton as-child :is-active=\"item.isActive\">\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/NavSecondary.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { LucideIcon } from 'lucide-vue-next'\n\nimport type { Component } from 'vue'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/new-york/ui/sidebar'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon: LucideIcon\n badge?: Component\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n <SidebarMenuBadge v-if=\"item.badge\">\n <component :is=\"item.badge\" />\n </SidebarMenuBadge>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/NavWorkspaces.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/new-york/ui/collapsible'\n\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n} from '@/registry/new-york/ui/sidebar'\nimport { ChevronRight, MoreHorizontal, Plus } from 'lucide-vue-next'\n\ndefineProps<{\n workspaces: {\n name: string\n emoji: string\n pages: {\n name: string\n emoji: string\n }[]\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupLabel>Workspaces</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <Collapsible v-for=\"workspace in workspaces\" :key=\"workspace.name\">\n <SidebarMenuItem>\n <SidebarMenuButton as-child>\n <a href=\"#\">\n <span>{{ workspace.emoji }}</span>\n <span>{{ workspace.name }}</span>\n </a>\n </SidebarMenuButton>\n <CollapsibleTrigger as-child>\n <SidebarMenuAction\n class=\"left-2 bg-sidebar-accent text-sidebar-accent-foreground data-[state=open]:rotate-90\"\n show-on-hover\n >\n <ChevronRight />\n </SidebarMenuAction>\n </CollapsibleTrigger>\n <SidebarMenuAction show-on-hover>\n <Plus />\n </SidebarMenuAction>\n <CollapsibleContent>\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"page in workspace.pages\" :key=\"page.name\">\n <SidebarMenuSubButton as-child>\n <a href=\"#\">\n <span>{{ page.emoji }}</span>\n <span>{{ page.name }}</span>\n </a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n\n <SidebarMenuItem>\n <SidebarMenuButton class=\"text-sidebar-foreground/70\">\n <MoreHorizontal />\n <span>More</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/TeamSwitcher.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/new-york/ui/sidebar'\nimport { ChevronDown, Plus } from 'lucide-vue-next'\n\nimport { type Component, ref } from 'vue'\n\nconst props = defineProps<{\n teams: {\n name: string\n logo: Component\n plan: string\n }[]\n}>()\n\nconst activeTeam = ref(props.teams[0])\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton class=\"w-fit px-1.5\">\n <div class=\"flex aspect-square size-5 items-center justify-center rounded-md bg-sidebar-primary text-sidebar-primary-foreground\">\n <component :is=\"activeTeam.logo\" class=\"size-3\" />\n </div>\n <span class=\"truncate font-semibold\">{{ activeTeam.name }}</span>\n <ChevronDown class=\"opacity-50\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-64 rounded-lg\"\n align=\"start\"\n side=\"bottom\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"text-xs text-muted-foreground\">\n Teams\n </DropdownMenuLabel>\n <DropdownMenuItem\n v-for=\"(team, index) in teams\"\n :key=\"team.name\"\n class=\"gap-2 p-2\"\n @click=\"activeTeam = team\"\n >\n <div class=\"flex size-6 items-center justify-center rounded-sm border\">\n <component :is=\"team.logo\" class=\"size-4 shrink-0\" />\n </div>\n {{ team.name }}\n <DropdownMenuShortcut>⌘{{ index + 1 }}</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem class=\"gap-2 p-2\">\n <div class=\"flex size-6 items-center justify-center rounded-md border bg-background\">\n <Plus class=\"size-4\" />\n </div>\n <div class=\"font-medium text-muted-foreground\">\n Add team\n </div>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar11",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar11/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A sidebar with a collapsible file tree.'\nexport const iframeHeight = '800px'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/new-york/block/Sidebar11/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 border-b px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n components\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n ui\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>button.tsx</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar11/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport Tree from '@/registry/new-york/block/Sidebar11/components/Tree.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/new-york/ui/sidebar'\nimport { File } from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n changes: [\n {\n file: 'README.md',\n state: 'M',\n },\n {\n file: 'api/hello/route.ts',\n state: 'U',\n },\n {\n file: 'app/layout.tsx',\n state: 'M',\n },\n ],\n tree: [\n [\n 'app',\n [\n 'api',\n ['hello', ['route.ts']],\n 'page.tsx',\n 'layout.tsx',\n ['blog', ['page.tsx']],\n ],\n ],\n [\n 'components',\n ['ui', 'button.tsx', 'card.tsx'],\n 'header.tsx',\n 'footer.tsx',\n ],\n ['lib', ['util.ts']],\n ['public', 'favicon.ico', 'vercel.svg'],\n '.eslintrc.json',\n '.gitignore',\n 'next.config.js',\n 'tailwind.config.js',\n 'package.json',\n 'README.md',\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Changes</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"(item, index) in data.changes\" :key=\"index\">\n <SidebarMenuButton>\n <File />\n {{ item.file }}\n </SidebarMenuButton>\n <SidebarMenuBadge>{{ item.state }}</SidebarMenuBadge>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n <SidebarGroup>\n <SidebarGroupLabel>Files</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <Tree v-for=\"(item, index) in data.tree\" :key=\"index\" :item=\"item\" />\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar11/components/Tree.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/new-york/ui/collapsible'\n\nimport {\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n} from '@/registry/new-york/ui/sidebar'\nimport { ChevronRight, File, Folder } from 'lucide-vue-next'\n\nconst props = defineProps<{\n item: string | any[]\n}>()\n\nconst [name, ...items] = Array.isArray(props.item) ? props.item : [props.item]\n</script>\n\n<template>\n <SidebarMenuButton\n v-if=\"!items.length\"\n :is-active=\"name === 'button.tsx'\"\n class=\"data-[active=true]:bg-transparent\"\n >\n <File />\n {{ name }}\n </SidebarMenuButton>\n\n <SidebarMenuItem v-else>\n <Collapsible\n class=\"group/collapsible [&[data-state=open]>button>svg:first-child]:rotate-90\"\n :default-open=\"name === 'components' || name === 'ui'\"\n >\n <CollapsibleTrigger as-child>\n <SidebarMenuButton>\n <ChevronRight class=\"transition-transform\" />\n <Folder />\n {{ name }}\n </SidebarMenuButton>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <SidebarMenuSub>\n <Tree v-for=\"(subItem, index) in items\" :key=\"index\" :item=\"subItem\" />\n </SidebarMenuSub>\n </CollapsibleContent>\n </Collapsible>\n </SidebarMenuItem>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar12",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible",
|
|
"calendar",
|
|
"avatar",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar12/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A sidebar with a calendar.'\nexport const iframeHeight = '800px'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/new-york/block/Sidebar12/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbList,\n BreadcrumbPage,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"sticky top-0 flex h-16 shrink-0 items-center gap-2 border-b bg-background px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbPage>October 2024</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-5\">\n <div v-for=\"i in 20\" :key=\"i\" class=\"aspect-square rounded-xl bg-muted/50\" />\n </div>\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar12/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport Calendars from '@/registry/new-york/block/Sidebar12/components/Calendars.vue'\n\nimport DatePicker from '@/registry/new-york/block/Sidebar12/components/DatePicker.vue'\nimport NavUser from '@/registry/new-york/block/Sidebar12/components/NavUser.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n SidebarRail,\n SidebarSeparator,\n} from '@/registry/new-york/ui/sidebar'\nimport { Plus } from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n// This is sample data.\nconst data = {\n user: {\n name: 'shadcn',\n email: 'm@example.com',\n avatar: '/avatars/shadcn.jpg',\n },\n calendars: [\n {\n name: 'My Calendars',\n items: ['Personal', 'Work', 'Family'],\n },\n {\n name: 'Favorites',\n items: ['Holidays', 'Birthdays'],\n },\n {\n name: 'Other',\n items: ['Travel', 'Reminders', 'Deadlines'],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader class=\"h-16 border-b border-sidebar-border\">\n <NavUser :user=\"data.user\" />\n </SidebarHeader>\n <SidebarContent>\n <DatePicker />\n <SidebarSeparator class=\"mx-0\" />\n <Calendars :calendars=\"data.calendars\" />\n </SidebarContent>\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <Plus />\n <span>New Calendar</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar12/components/Calendars.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/new-york/ui/collapsible'\n\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarSeparator,\n} from '@/registry/new-york/ui/sidebar'\nimport { Check, ChevronRight } from 'lucide-vue-next'\n\nconst props = defineProps<{\n calendars: {\n name: string\n items: string[]\n }[]\n}>()\n</script>\n\n<template>\n <template v-for=\"(calendar, index) in calendars\" :key=\"calendar.name\">\n <SidebarGroup class=\"py-0\">\n <Collapsible\n :default-open=\"index === 0\"\n class=\"group/collapsible\"\n >\n <SidebarGroupLabel\n as-child\n class=\"group/label w-full text-sm text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\"\n >\n <CollapsibleTrigger>\n {{ calendar.name }}\n <ChevronRight class=\"ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90\" />\n </CollapsibleTrigger>\n </SidebarGroupLabel>\n <CollapsibleContent>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"(item, index) in calendar.items\" :key=\"item\">\n <SidebarMenuButton>\n <div\n :data-active=\"index < 2\"\n class=\"group/calendar-item flex aspect-square size-4 shrink-0 items-center justify-center rounded-sm border border-sidebar-border text-sidebar-primary-foreground data-[active=true]:border-sidebar-primary data-[active=true]:bg-sidebar-primary\"\n >\n <Check class=\"hidden size-3 group-data-[active=true]/calendar-item:block\" />\n </div>\n {{ item }}\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </CollapsibleContent>\n </Collapsible>\n </SidebarGroup>\n <SidebarSeparator class=\"mx-0\" />\n </template>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar12/components/DatePicker.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Calendar } from '@/registry/new-york/ui/calendar'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarGroup class=\"px-0\">\n <SidebarGroupContent>\n <Calendar class=\"[&_[role=gridcell].bg-accent]:bg-sidebar-primary [&_[role=gridcell].bg-accent]:text-sidebar-primary-foreground [&_[role=gridcell]]:w-[33px]\" />\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar12/components/NavUser.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/registry/new-york/ui/avatar'\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n BadgeCheck,\n Bell,\n ChevronsUpDown,\n CreditCard,\n LogOut,\n Sparkles,\n} from 'lucide-vue-next'\n\nconst props = defineProps<{\n user: {\n name: string\n email: string\n avatar: string\n }\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto size-4\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n align=\"start\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"p-0 font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <Sparkles />\n Upgrade to Pro\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <BadgeCheck />\n Account\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CreditCard />\n Billing\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Bell />\n Notifications\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut />\n Log out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar13",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"button",
|
|
"dialog",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar13/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A sidebar in a dialog.'\nexport const iframeHeight = '800px'\n</script>\n\n<script setup lang=\"ts\">\nimport SettingsDialog from '@/registry/new-york/block/Sidebar13/components/SettingsDialog.vue'\n</script>\n\n<template>\n <div class=\"flex h-svh items-center justify-center\">\n <SettingsDialog />\n </div>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar13/components/SettingsDialog.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\n\nimport { Button } from '@/registry/new-york/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/new-york/ui/dialog'\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n Bell,\n Check,\n Globe,\n Home,\n Keyboard,\n Link,\n Lock,\n Menu,\n MessageCircle,\n Paintbrush,\n Settings,\n Video,\n} from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst data = {\n nav: [\n { name: 'Notifications', icon: Bell },\n { name: 'Navigation', icon: Menu },\n { name: 'Home', icon: Home },\n { name: 'Appearance', icon: Paintbrush },\n { name: 'Messages & media', icon: MessageCircle },\n { name: 'Language & region', icon: Globe },\n { name: 'Accessibility', icon: Keyboard },\n { name: 'Mark as read', icon: Check },\n { name: 'Audio & video', icon: Video },\n { name: 'Connected accounts', icon: Link },\n { name: 'Privacy & visibility', icon: Lock },\n { name: 'Advanced', icon: Settings },\n ],\n}\n\nconst open = ref(true)\n</script>\n\n<template>\n <Dialog v-model:open=\"open\">\n <DialogTrigger as-child>\n <Button size=\"sm\">\n Open Dialog\n </Button>\n </DialogTrigger>\n <DialogContent class=\"overflow-hidden p-0 md:max-h-[500px] md:max-w-[700px] lg:max-w-[800px]\">\n <DialogTitle class=\"sr-only\">\n Settings\n </DialogTitle>\n <DialogDescription class=\"sr-only\">\n Customize your settings here.\n </DialogDescription>\n <SidebarProvider class=\"items-start\">\n <Sidebar collapsible=\"none\" class=\"hidden md:flex\">\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in data.nav\" :key=\"item.name\">\n <SidebarMenuButton\n as-child\n :is-active=\"item.name === 'Messages & media'\"\n >\n <a href=\"#\">\n <component :is=\"item.icon\" />\n <span>{{ item.name }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n <main class=\"flex h-[480px] flex-1 flex-col overflow-hidden\">\n <header class=\"flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12\">\n <div class=\"flex items-center gap-2 px-4\">\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Settings\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Messages & media</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 overflow-y-auto p-4 pt-0\">\n <div\n v-for=\"i in 10\"\n :key=\"i\"\n class=\"aspect-video max-w-3xl rounded-xl bg-muted/50\"\n />\n </div>\n </main>\n </SidebarProvider>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar14",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar14/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A sidebar on the right.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/new-york/block/Sidebar14/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/new-york/ui/breadcrumb'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 border-b px-4\">\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n <SidebarTrigger class=\"-mr-1 ml-auto rotate-180\" />\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n <AppSidebar side=\"right\" />\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar14/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type {\n SidebarProps,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarRail,\n} from '@/registry/new-york/ui/sidebar'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n {\n title: 'Community',\n url: '#',\n items: [\n {\n title: 'Contribution Guide',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Table of Contents</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in data.navMain\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\" class=\"font-medium\">\n {{ item.title }}\n </a>\n </SidebarMenuButton>\n <SidebarMenuSub v-if=\"item.items.length\">\n <SidebarMenuSubItem v-for=\"subItem in item.items\" :key=\"subItem.title\">\n <SidebarMenuSubButton\n as-child\n :is-active=\"subItem.isActive\"\n >\n <a :href=\"subItem.url\">{{ subItem.title }}</a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar15",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible",
|
|
"calendar",
|
|
"dropdown-menu",
|
|
"avatar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar15/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A left and right sidebar.'\n</script>\n\n<script setup lang=\"ts\">\nimport SidebarLeft from '@/registry/new-york/block/Sidebar15/components/SidebarLeft.vue'\nimport SidebarRight from '@/registry/new-york/block/Sidebar15/components/SidebarRight.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbList,\n BreadcrumbPage,\n} from '@/registry/new-york/ui/breadcrumb'\nimport { Separator } from '@/registry/new-york/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <SidebarLeft />\n <SidebarInset>\n <header class=\"sticky top-0 flex h-14 shrink-0 items-center gap-2 bg-background\">\n <div class=\"flex flex-1 items-center gap-2 px-3\">\n <SidebarTrigger />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbPage class=\"line-clamp-1\">\n Project Management & Task Tracking\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"mx-auto h-24 w-full max-w-3xl rounded-xl bg-muted/50\" />\n <div class=\"mx-auto h-[100vh] w-full max-w-3xl rounded-xl bg-muted/50\" />\n </div>\n </SidebarInset>\n <SidebarRight />\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type {\n SidebarProps,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarRail,\n} from '@/registry/new-york/ui/sidebar'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n {\n title: 'Community',\n url: '#',\n items: [\n {\n title: 'Contribution Guide',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Table of Contents</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in data.navMain\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\" class=\"font-medium\">\n {{ item.title }}\n </a>\n </SidebarMenuButton>\n <SidebarMenuSub v-if=\"item.items.length\">\n <SidebarMenuSubItem v-for=\"subItem in item.items\" :key=\"subItem.title\">\n <SidebarMenuSubButton\n as-child\n :is-active=\"subItem.isActive\"\n >\n <a :href=\"subItem.url\">{{ subItem.title }}</a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/Calendars.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/new-york/ui/collapsible'\n\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarSeparator,\n} from '@/registry/new-york/ui/sidebar'\nimport { Check, ChevronRight } from 'lucide-vue-next'\n\nconst props = defineProps<{\n calendars: {\n name: string\n items: string[]\n }[]\n}>()\n</script>\n\n<template>\n <template v-for=\"(calendar, index) in calendars\" :key=\"calendar.name\">\n <SidebarGroup class=\"py-0\">\n <Collapsible\n :default-open=\"index === 0\"\n class=\"group/collapsible\"\n >\n <SidebarGroupLabel\n as-child\n class=\"group/label w-full text-sm text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\"\n >\n <CollapsibleTrigger>\n {{ calendar.name }}\n <ChevronRight class=\"ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90\" />\n </CollapsibleTrigger>\n </SidebarGroupLabel>\n <CollapsibleContent>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"(item, index) in calendar.items\" :key=\"item\">\n <SidebarMenuButton>\n <div\n :data-active=\"index < 2\"\n class=\"group/calendar-item flex aspect-square size-4 shrink-0 items-center justify-center rounded-sm border border-sidebar-border text-sidebar-primary-foreground data-[active=true]:border-sidebar-primary data-[active=true]:bg-sidebar-primary\"\n >\n <Check class=\"hidden size-3 group-data-[active=true]/calendar-item:block\" />\n </div>\n {{ item }}\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </CollapsibleContent>\n </Collapsible>\n </SidebarGroup>\n <SidebarSeparator class=\"mx-0\" />\n </template>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/DatePicker.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Calendar } from '@/registry/new-york/ui/calendar'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n} from '@/registry/new-york/ui/sidebar'\n</script>\n\n<template>\n <SidebarGroup class=\"px-0\">\n <SidebarGroupContent>\n <Calendar class=\"[&_[role=gridcell].bg-accent]:bg-sidebar-primary [&_[role=gridcell].bg-accent]:text-sidebar-primary-foreground [&_[role=gridcell]]:w-[33px]\" />\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/NavFavorites.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n ArrowUpRight,\n Link,\n MoreHorizontal,\n StarOff,\n Trash2,\n} from 'lucide-vue-next'\n\ndefineProps<{\n favorites: {\n name: string\n url: string\n emoji: string\n }[]\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarGroup class=\"group-data-[collapsible=icon]:hidden\">\n <SidebarGroupLabel>Favorites</SidebarGroupLabel>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in favorites\" :key=\"item.name\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\" :title=\"item.name\">\n <span>{{ item.emoji }}</span>\n <span>{{ item.name }}</span>\n </a>\n </SidebarMenuButton>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuAction show-on-hover>\n <MoreHorizontal />\n <span class=\"sr-only\">More</span>\n </SidebarMenuAction>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n :align=\"isMobile ? 'end' : 'start'\"\n >\n <DropdownMenuItem>\n <StarOff class=\"text-muted-foreground\" />\n <span>Remove from Favorites</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Link class=\"text-muted-foreground\" />\n <span>Copy Link</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <ArrowUpRight class=\"text-muted-foreground\" />\n <span>Open in New Tab</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Trash2 class=\"text-muted-foreground\" />\n <span>Delete</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n\n <SidebarMenuItem>\n <SidebarMenuButton class=\"text-sidebar-foreground/70\">\n <MoreHorizontal />\n <span>More</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/NavMain.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { LucideIcon } from 'lucide-vue-next'\n\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/new-york/ui/sidebar'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon: LucideIcon\n isActive?: boolean\n }[]\n}>()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuButton as-child :is-active=\"item.isActive\">\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/NavSecondary.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { LucideIcon } from 'lucide-vue-next'\n\nimport type { Component } from 'vue'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/new-york/ui/sidebar'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon: LucideIcon\n badge?: Component\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n <SidebarMenuBadge v-if=\"item.badge\">\n <component :is=\"item.badge\" />\n </SidebarMenuBadge>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/NavUser.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/registry/new-york/ui/avatar'\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n BadgeCheck,\n Bell,\n ChevronsUpDown,\n CreditCard,\n LogOut,\n Sparkles,\n} from 'lucide-vue-next'\n\nconst props = defineProps<{\n user: {\n name: string\n email: string\n avatar: string\n }\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto size-4\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n align=\"start\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"p-0 font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <Sparkles />\n Upgrade to Pro\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <BadgeCheck />\n Account\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CreditCard />\n Billing\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Bell />\n Notifications\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut />\n Log out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/NavWorkspaces.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/new-york/ui/collapsible'\n\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n} from '@/registry/new-york/ui/sidebar'\nimport { ChevronRight, MoreHorizontal, Plus } from 'lucide-vue-next'\n\ndefineProps<{\n workspaces: {\n name: string\n emoji: string\n pages: {\n name: string\n emoji: string\n }[]\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupLabel>Workspaces</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <Collapsible v-for=\"workspace in workspaces\" :key=\"workspace.name\">\n <SidebarMenuItem>\n <SidebarMenuButton as-child>\n <a href=\"#\">\n <span>{{ workspace.emoji }}</span>\n <span>{{ workspace.name }}</span>\n </a>\n </SidebarMenuButton>\n <CollapsibleTrigger as-child>\n <SidebarMenuAction\n class=\"left-2 bg-sidebar-accent text-sidebar-accent-foreground data-[state=open]:rotate-90\"\n show-on-hover\n >\n <ChevronRight />\n </SidebarMenuAction>\n </CollapsibleTrigger>\n <SidebarMenuAction show-on-hover>\n <Plus />\n </SidebarMenuAction>\n <CollapsibleContent>\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"page in workspace.pages\" :key=\"page.name\">\n <SidebarMenuSubButton as-child>\n <a href=\"#\">\n <span>{{ page.emoji }}</span>\n <span>{{ page.name }}</span>\n </a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n\n <SidebarMenuItem>\n <SidebarMenuButton class=\"text-sidebar-foreground/70\">\n <MoreHorizontal />\n <span>More</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/SidebarLeft.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport NavFavorites from '@/registry/new-york/block/Sidebar15/components/NavFavorites.vue'\n\nimport NavMain from '@/registry/new-york/block/Sidebar15/components/NavMain.vue'\nimport NavSecondary from '@/registry/new-york/block/Sidebar15/components/NavSecondary.vue'\nimport NavWorkspaces from '@/registry/new-york/block/Sidebar15/components/NavWorkspaces.vue'\nimport TeamSwitcher from '@/registry/new-york/block/Sidebar15/components/TeamSwitcher.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarHeader,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/new-york/ui/sidebar'\nimport {\n AudioWaveform,\n Blocks,\n Calendar,\n Command,\n Home,\n Inbox,\n MessageCircleQuestion,\n Search,\n Settings2,\n Sparkles,\n Trash2,\n} from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n teams: [\n {\n name: 'Acme Inc',\n logo: Command,\n plan: 'Enterprise',\n },\n {\n name: 'Acme Corp.',\n logo: AudioWaveform,\n plan: 'Startup',\n },\n {\n name: 'Evil Corp.',\n logo: Command,\n plan: 'Free',\n },\n ],\n navMain: [\n {\n title: 'Search',\n url: '#',\n icon: Search,\n },\n {\n title: 'Ask AI',\n url: '#',\n icon: Sparkles,\n },\n {\n title: 'Home',\n url: '#',\n icon: Home,\n isActive: true,\n },\n {\n title: 'Inbox',\n url: '#',\n icon: Inbox,\n badge: '10',\n },\n ],\n navSecondary: [\n {\n title: 'Calendar',\n url: '#',\n icon: Calendar,\n },\n {\n title: 'Settings',\n url: '#',\n icon: Settings2,\n },\n {\n title: 'Templates',\n url: '#',\n icon: Blocks,\n },\n {\n title: 'Trash',\n url: '#',\n icon: Trash2,\n },\n {\n title: 'Help',\n url: '#',\n icon: MessageCircleQuestion,\n },\n ],\n favorites: [\n {\n name: 'Project Management & Task Tracking',\n url: '#',\n emoji: '📊',\n },\n {\n name: 'Family Recipe Collection & Meal Planning',\n url: '#',\n emoji: '🍳',\n },\n {\n name: 'Fitness Tracker & Workout Routines',\n url: '#',\n emoji: '💪',\n },\n {\n name: 'Book Notes & Reading List',\n url: '#',\n emoji: '📚',\n },\n {\n name: 'Sustainable Gardening Tips & Plant Care',\n url: '#',\n emoji: '🌱',\n },\n {\n name: 'Language Learning Progress & Resources',\n url: '#',\n emoji: '🗣️',\n },\n {\n name: 'Home Renovation Ideas & Budget Tracker',\n url: '#',\n emoji: '🏠',\n },\n {\n name: 'Personal Finance & Investment Portfolio',\n url: '#',\n emoji: '💰',\n },\n {\n name: 'Movie & TV Show Watchlist with Reviews',\n url: '#',\n emoji: '🎬',\n },\n {\n name: 'Daily Habit Tracker & Goal Setting',\n url: '#',\n emoji: '✅',\n },\n ],\n workspaces: [\n {\n name: 'Personal Life Management',\n emoji: '🏠',\n pages: [\n {\n name: 'Daily Journal & Reflection',\n url: '#',\n emoji: '📔',\n },\n {\n name: 'Health & Wellness Tracker',\n url: '#',\n emoji: '🍏',\n },\n {\n name: 'Personal Growth & Learning Goals',\n url: '#',\n emoji: '🌟',\n },\n ],\n },\n {\n name: 'Professional Development',\n emoji: '💼',\n pages: [\n {\n name: 'Career Objectives & Milestones',\n url: '#',\n emoji: '🎯',\n },\n {\n name: 'Skill Acquisition & Training Log',\n url: '#',\n emoji: '🧠',\n },\n {\n name: 'Networking Contacts & Events',\n url: '#',\n emoji: '🤝',\n },\n ],\n },\n {\n name: 'Creative Projects',\n emoji: '🎨',\n pages: [\n {\n name: 'Writing Ideas & Story Outlines',\n url: '#',\n emoji: '✍️',\n },\n {\n name: 'Art & Design Portfolio',\n url: '#',\n emoji: '🖼️',\n },\n {\n name: 'Music Composition & Practice Log',\n url: '#',\n emoji: '🎵',\n },\n ],\n },\n {\n name: 'Home Management',\n emoji: '🏡',\n pages: [\n {\n name: 'Household Budget & Expense Tracking',\n url: '#',\n emoji: '💰',\n },\n {\n name: 'Home Maintenance Schedule & Tasks',\n url: '#',\n emoji: '🔧',\n },\n {\n name: 'Family Calendar & Event Planning',\n url: '#',\n emoji: '📅',\n },\n ],\n },\n {\n name: 'Travel & Adventure',\n emoji: '🧳',\n pages: [\n {\n name: 'Trip Planning & Itineraries',\n url: '#',\n emoji: '🗺️',\n },\n {\n name: 'Travel Bucket List & Inspiration',\n url: '#',\n emoji: '🌎',\n },\n {\n name: 'Travel Journal & Photo Gallery',\n url: '#',\n emoji: '📸',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar class=\"border-r-0\" v-bind=\"props\">\n <SidebarHeader>\n <TeamSwitcher :teams=\"data.teams\" />\n <NavMain :items=\"data.navMain\" />\n </SidebarHeader>\n <SidebarContent>\n <NavFavorites :favorites=\"data.favorites\" />\n <NavWorkspaces :workspaces=\"data.workspaces\" />\n <NavSecondary :items=\"data.navSecondary\" class=\"mt-auto\" />\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/SidebarRight.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport Calendars from '@/registry/new-york/block/Sidebar15/components/Calendars.vue'\n\nimport DatePicker from '@/registry/new-york/block/Sidebar15/components/DatePicker.vue'\nimport NavUser from '@/registry/new-york/block/Sidebar15/components/NavUser.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n SidebarSeparator,\n} from '@/registry/new-york/ui/sidebar'\nimport { Plus } from 'lucide-vue-next'\n\nconst props = withDefaults(defineProps<SidebarProps>(), {\n collapsible: 'none',\n})\n\n// This is sample data.\nconst data = {\n user: {\n name: 'shadcn',\n email: 'm@example.com',\n avatar: '/avatars/shadcn.jpg',\n },\n calendars: [\n {\n name: 'My Calendars',\n items: ['Personal', 'Work', 'Family'],\n },\n {\n name: 'Favorites',\n items: ['Holidays', 'Birthdays'],\n },\n {\n name: 'Other',\n items: ['Travel', 'Reminders', 'Deadlines'],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar\n class=\"sticky hidden lg:flex top-0 h-svh border-l\"\n v-bind=\"props\"\n >\n <SidebarHeader class=\"h-16 border-b border-sidebar-border\">\n <NavUser :user=\"data.user\" />\n </SidebarHeader>\n <SidebarContent>\n <DatePicker />\n <SidebarSeparator class=\"mx-0\" />\n <Calendars :calendars=\"data.calendars\" />\n </SidebarContent>\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <Plus />\n <span>New Calendar</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/TeamSwitcher.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuTrigger,\n} from '@/registry/new-york/ui/dropdown-menu'\n\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/new-york/ui/sidebar'\nimport { ChevronDown, Plus } from 'lucide-vue-next'\n\nimport { type Component, ref } from 'vue'\n\nconst props = defineProps<{\n teams: {\n name: string\n logo: Component\n plan: string\n }[]\n}>()\n\nconst activeTeam = ref(props.teams[0])\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton class=\"w-fit px-1.5\">\n <div class=\"flex aspect-square size-5 items-center justify-center rounded-md bg-sidebar-primary text-sidebar-primary-foreground\">\n <component :is=\"activeTeam.logo\" class=\"size-3\" />\n </div>\n <span class=\"truncate font-semibold\">{{ activeTeam.name }}</span>\n <ChevronDown class=\"opacity-50\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-64 rounded-lg\"\n align=\"start\"\n side=\"bottom\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"text-xs text-muted-foreground\">\n Teams\n </DropdownMenuLabel>\n\n <DropdownMenuItem\n v-for=\"(team, index) in teams\"\n :key=\"team.name\"\n class=\"gap-2 p-2\"\n @click=\"activeTeam = team\"\n >\n <div class=\"flex size-6 items-center justify-center rounded-sm border\">\n <component :is=\"team.logo\" class=\"size-4 shrink-0\" />\n </div>\n {{ team.name }}\n <DropdownMenuShortcut>⌘{{ index + 1 }}</DropdownMenuShortcut>\n </DropdownMenuItem>\n\n <DropdownMenuSeparator />\n <DropdownMenuItem class=\"gap-2 p-2\">\n <div class=\"flex size-6 items-center justify-center rounded-md border bg-background\">\n <Plus class=\"size-4\" />\n </div>\n <div class=\"font-medium text-muted-foreground\">\n Add team\n </div>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "accordion",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/accordion/Accordion.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n AccordionRoot,\n type AccordionRootEmits,\n type AccordionRootProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<AccordionRootProps>()\nconst emits = defineEmits<AccordionRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <AccordionRoot v-bind=\"forwarded\">\n <slot />\n </AccordionRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/accordion/AccordionContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { AccordionContent, type AccordionContentProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AccordionContentProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AccordionContent\n v-bind=\"delegatedProps\"\n class=\"overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\"\n >\n <div :class=\"cn('pb-4 pt-0', props.class)\">\n <slot />\n </div>\n </AccordionContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/accordion/AccordionItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { AccordionItem, type AccordionItemProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AccordionItemProps & { 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 <AccordionItem\n v-bind=\"forwardedProps\"\n :class=\"cn('border-b', props.class)\"\n >\n <slot />\n </AccordionItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/accordion/AccordionTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronDown } from 'lucide-vue-next'\nimport {\n AccordionHeader,\n AccordionTrigger,\n type AccordionTriggerProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AccordionTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AccordionHeader class=\"flex\">\n <AccordionTrigger\n v-bind=\"delegatedProps\"\n :class=\"\n cn(\n 'flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',\n props.class,\n )\n \"\n >\n <slot />\n <slot name=\"icon\">\n <ChevronDown\n class=\"h-4 w-4 shrink-0 transition-transform duration-200\"\n />\n </slot>\n </AccordionTrigger>\n </AccordionHeader>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/accordion/index.ts",
|
|
"content": "export { default as Accordion } from './Accordion.vue'\nexport { default as AccordionContent } from './AccordionContent.vue'\nexport { default as AccordionItem } from './AccordionItem.vue'\nexport { default as AccordionTrigger } from './AccordionTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "alert",
|
|
"type": "registry:ui",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/alert/Alert.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { type AlertVariants, alertVariants } from '.'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n variant?: AlertVariants['variant']\n}>()\n</script>\n\n<template>\n <div :class=\"cn(alertVariants({ variant }), props.class)\" role=\"alert\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert/AlertDescription.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('text-sm [&_p]:leading-relaxed', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert/AlertTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <h5 :class=\"cn('mb-1 font-medium leading-none tracking-tight', props.class)\">\n <slot />\n </h5>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert/index.ts",
|
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Alert } from './Alert.vue'\nexport { default as AlertDescription } from './AlertDescription.vue'\nexport { default as AlertTitle } from './AlertTitle.vue'\n\nexport const alertVariants = cva(\n 'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground',\n {\n variants: {\n variant: {\n default: 'bg-background text-foreground',\n destructive:\n 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n)\n\nexport type AlertVariants = VariantProps<typeof alertVariants>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "alert-dialog",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialog.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { type AlertDialogEmits, type AlertDialogProps, AlertDialogRoot, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<AlertDialogProps>()\nconst emits = defineEmits<AlertDialogEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <AlertDialogRoot v-bind=\"forwarded\">\n <slot />\n </AlertDialogRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogAction.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogCancel.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n AlertDialogContent,\n type AlertDialogContentEmits,\n type AlertDialogContentProps,\n AlertDialogOverlay,\n AlertDialogPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<AlertDialogContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <AlertDialogPortal>\n <AlertDialogOverlay\n class=\"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n />\n <AlertDialogContent\n v-bind=\"forwarded\"\n :class=\"\n cn(\n 'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',\n props.class,\n )\n \"\n >\n <slot />\n </AlertDialogContent>\n </AlertDialogPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogDescription.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n AlertDialogDescription,\n type AlertDialogDescriptionProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogDescriptionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AlertDialogDescription\n v-bind=\"delegatedProps\"\n :class=\"cn('text-sm text-muted-foreground', props.class)\"\n >\n <slot />\n </AlertDialogDescription>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n :class=\"\n cn(\n 'flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-x-2',\n props.class,\n )\n \"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n :class=\"cn('flex flex-col gap-y-2 text-center sm:text-left', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { AlertDialogTitle, type AlertDialogTitleProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<AlertDialogTitleProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <AlertDialogTitle\n v-bind=\"delegatedProps\"\n :class=\"cn('text-lg font-semibold', props.class)\"\n >\n <slot />\n </AlertDialogTitle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/AlertDialogTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AlertDialogTrigger, type AlertDialogTriggerProps } from 'reka-ui'\n\nconst props = defineProps<AlertDialogTriggerProps>()\n</script>\n\n<template>\n <AlertDialogTrigger v-bind=\"props\">\n <slot />\n </AlertDialogTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/alert-dialog/index.ts",
|
|
"content": "export { default as AlertDialog } from './AlertDialog.vue'\nexport { default as AlertDialogAction } from './AlertDialogAction.vue'\nexport { default as AlertDialogCancel } from './AlertDialogCancel.vue'\nexport { default as AlertDialogContent } from './AlertDialogContent.vue'\nexport { default as AlertDialogDescription } from './AlertDialogDescription.vue'\nexport { default as AlertDialogFooter } from './AlertDialogFooter.vue'\nexport { default as AlertDialogHeader } from './AlertDialogHeader.vue'\nexport { default as AlertDialogTitle } from './AlertDialogTitle.vue'\nexport { default as AlertDialogTrigger } from './AlertDialogTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "aspect-ratio",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "ui/aspect-ratio/AspectRatio.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AspectRatio, type AspectRatioProps } from 'reka-ui'\n\nconst props = defineProps<AspectRatioProps>()\n</script>\n\n<template>\n <AspectRatio v-bind=\"props\">\n <slot />\n </AspectRatio>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/aspect-ratio/index.ts",
|
|
"content": "export { default as AspectRatio } from './AspectRatio.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "auto-form",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod",
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"form",
|
|
"accordion",
|
|
"button",
|
|
"separator",
|
|
"checkbox",
|
|
"switch",
|
|
"utils",
|
|
"calendar",
|
|
"popover",
|
|
"label",
|
|
"radio-group",
|
|
"select",
|
|
"input",
|
|
"textarea"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/auto-form/AutoForm.vue",
|
|
"content": "<script setup lang=\"ts\" generic=\"T extends ZodObjectOrWrapped\">\nimport type { FormContext, GenericObject } from 'vee-validate'\nimport type { z, ZodAny } from 'zod'\nimport type { Config, ConfigItem, Dependency, Shape } from './interface'\nimport { Form } from '@/registry/default/ui/form'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { computed, toRefs } from 'vue'\nimport AutoFormField from './AutoFormField.vue'\nimport { provideDependencies } from './dependencies'\nimport { getBaseSchema, getBaseType, getDefaultValueInZodStack, getObjectFormSchema, type ZodObjectOrWrapped } from './utils'\n\nconst props = defineProps<{\n schema: T\n form?: FormContext<GenericObject>\n fieldConfig?: Config<z.infer<T>>\n dependencies?: Dependency<z.infer<T>>[]\n}>()\n\nconst emits = defineEmits<{\n submit: [event: z.infer<T>]\n}>()\n\nconst { dependencies } = toRefs(props)\nprovideDependencies(dependencies)\n\nconst shapes = computed(() => {\n // @ts-expect-error ignore {} not assignable to object\n const val: { [key in keyof T]: Shape } = {}\n const baseSchema = getObjectFormSchema(props.schema)\n const shape = baseSchema.shape\n Object.keys(shape).forEach((name) => {\n const item = shape[name] as ZodAny\n const baseItem = getBaseSchema(item) as ZodAny\n let options = (baseItem && 'values' in baseItem._def) ? baseItem._def.values as string[] : undefined\n if (!Array.isArray(options) && typeof options === 'object')\n options = Object.values(options)\n\n val[name as keyof T] = {\n type: getBaseType(item),\n default: getDefaultValueInZodStack(item),\n options,\n required: !['ZodOptional', 'ZodNullable'].includes(item._def.typeName),\n schema: baseItem,\n }\n })\n return val\n})\n\nconst fields = computed(() => {\n // @ts-expect-error ignore {} not assignable to object\n const val: { [key in keyof z.infer<T>]: { shape: Shape, fieldName: string, config: ConfigItem } } = {}\n for (const key in shapes.value) {\n const shape = shapes.value[key]\n val[key as keyof z.infer<T>] = {\n shape,\n config: props.fieldConfig?.[key] as ConfigItem,\n fieldName: key,\n }\n }\n return val\n})\n\nconst formComponent = computed(() => props.form ? 'form' : Form)\nconst formComponentProps = computed(() => {\n if (props.form) {\n return {\n onSubmit: props.form.handleSubmit(val => emits('submit', val)),\n }\n }\n else {\n const formSchema = toTypedSchema(props.schema)\n return {\n keepValues: true,\n validationSchema: formSchema,\n onSubmit: (val: GenericObject) => emits('submit', val),\n }\n }\n})\n</script>\n\n<template>\n <component\n :is=\"formComponent\"\n v-bind=\"formComponentProps\"\n >\n <slot name=\"customAutoForm\" :fields=\"fields\">\n <template v-for=\"(shape, key) of shapes\" :key=\"key\">\n <slot\n :shape=\"shape\"\n :name=\"key.toString() as keyof z.infer<T>\"\n :field-name=\"key.toString()\"\n :config=\"fieldConfig?.[key as keyof typeof fieldConfig] as ConfigItem\"\n >\n <AutoFormField\n :config=\"fieldConfig?.[key as keyof typeof fieldConfig] as ConfigItem\"\n :field-name=\"key.toString()\"\n :shape=\"shape\"\n />\n </slot>\n </template>\n </slot>\n\n <slot :shapes=\"shapes\" />\n </component>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormField.vue",
|
|
"content": "<script setup lang=\"ts\" generic=\"U extends ZodAny\">\nimport type { ZodAny } from 'zod'\nimport type { Config, ConfigItem, Shape } from './interface'\nimport { computed } from 'vue'\nimport { DEFAULT_ZOD_HANDLERS, INPUT_COMPONENTS } from './constant'\nimport useDependencies from './dependencies'\n\nconst props = defineProps<{\n fieldName: string\n shape: Shape\n config?: ConfigItem | Config<U>\n}>()\n\nfunction isValidConfig(config: any): config is ConfigItem {\n return !!config?.component\n}\n\nconst delegatedProps = computed(() => {\n if (['ZodObject', 'ZodArray'].includes(props.shape?.type))\n return { schema: props.shape?.schema }\n return undefined\n})\n\nconst { isDisabled, isHidden, isRequired, overrideOptions } = useDependencies(props.fieldName)\n</script>\n\n<template>\n <component\n :is=\"isValidConfig(config)\n ? typeof config.component === 'string'\n ? INPUT_COMPONENTS[config.component!]\n : config.component\n : INPUT_COMPONENTS[DEFAULT_ZOD_HANDLERS[shape.type]] \"\n v-if=\"!isHidden\"\n :field-name=\"fieldName\"\n :label=\"shape.schema?.description\"\n :required=\"isRequired || shape.required\"\n :options=\"overrideOptions || shape.options\"\n :disabled=\"isDisabled\"\n :config=\"config\"\n v-bind=\"delegatedProps\"\n >\n <slot />\n </component>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldArray.vue",
|
|
"content": "<script setup lang=\"ts\" generic=\"T extends z.ZodAny\">\nimport type { Config, ConfigItem } from './interface'\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/registry/default/ui/accordion'\nimport { Button } from '@/registry/default/ui/button'\nimport { FormItem, FormMessage } from '@/registry/default/ui/form'\nimport { Separator } from '@/registry/default/ui/separator'\nimport { PlusIcon, TrashIcon } from 'lucide-vue-next'\nimport { FieldArray, FieldContextKey, useField } from 'vee-validate'\nimport { computed, provide } from 'vue'\nimport * as z from 'zod'\nimport AutoFormField from './AutoFormField.vue'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName, getBaseType } from './utils'\n\nconst props = defineProps<{\n fieldName: string\n required?: boolean\n config?: Config<T>\n schema?: z.ZodArray<T>\n disabled?: boolean\n}>()\n\nfunction isZodArray(\n item: z.ZodArray<any> | z.ZodDefault<any>,\n): item is z.ZodArray<any> {\n return item instanceof z.ZodArray\n}\n\nfunction isZodDefault(\n item: z.ZodArray<any> | z.ZodDefault<any>,\n): item is z.ZodDefault<any> {\n return item instanceof z.ZodDefault\n}\n\nconst itemShape = computed(() => {\n if (!props.schema)\n return\n\n const schema: z.ZodAny = isZodArray(props.schema)\n ? props.schema._def.type\n : isZodDefault(props.schema)\n // @ts-expect-error missing schema\n ? props.schema._def.innerType._def.type\n : null\n\n return {\n type: getBaseType(schema),\n schema,\n }\n})\n\nconst fieldContext = useField(props.fieldName)\n// @ts-expect-error ignore missing `id`\nprovide(FieldContextKey, fieldContext)\n</script>\n\n<template>\n <FieldArray v-slot=\"{ fields, remove, push }\" as=\"section\" :name=\"fieldName\">\n <slot v-bind=\"props\">\n <Accordion type=\"multiple\" class=\"w-full\" collapsible :disabled=\"disabled\" as-child>\n <FormItem>\n <AccordionItem :value=\"fieldName\" class=\"border-none\">\n <AccordionTrigger>\n <AutoFormLabel class=\"text-base\" :required=\"required\">\n {{ schema?.description || beautifyObjectName(fieldName) }}\n </AutoFormLabel>\n </AccordionTrigger>\n\n <AccordionContent>\n <template v-for=\"(field, index) of fields\" :key=\"field.key\">\n <div class=\"mb-4 p-1\">\n <AutoFormField\n :field-name=\"`${fieldName}[${index}]`\"\n :label=\"fieldName\"\n :shape=\"itemShape!\"\n :config=\"config as ConfigItem\"\n />\n\n <div class=\"!my-4 flex justify-end\">\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"secondary\"\n @click=\"remove(index)\"\n >\n <TrashIcon :size=\"16\" />\n </Button>\n </div>\n <Separator v-if=\"!field.isLast\" />\n </div>\n </template>\n\n <Button\n type=\"button\"\n variant=\"secondary\"\n class=\"mt-4 flex items-center\"\n @click=\"push(null)\"\n >\n <PlusIcon class=\"mr-2\" :size=\"16\" />\n Add\n </Button>\n </AccordionContent>\n\n <FormMessage />\n </AccordionItem>\n </FormItem>\n </Accordion>\n </slot>\n </FieldArray>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldBoolean.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { Checkbox } from '@/registry/default/ui/checkbox'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/default/ui/form'\nimport { Switch } from '@/registry/default/ui/switch'\nimport { computed } from 'vue'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\nconst props = defineProps<FieldProps>()\n\nconst booleanComponent = computed(() => props.config?.component === 'switch' ? Switch : Checkbox)\n</script>\n\n<template>\n <FormField v-slot=\"slotProps\" :name=\"fieldName\">\n <FormItem>\n <div class=\"space-y-0 mb-3 flex items-center gap-3\">\n <FormControl>\n <slot v-bind=\"slotProps\">\n <component\n :is=\"booleanComponent\"\n v-bind=\"{ ...slotProps.componentField }\"\n :disabled=\"disabled\"\n :model-value=\"slotProps.componentField.modelValue\"\n @update:model-value=\"slotProps.componentField['onUpdate:modelValue']\"\n />\n </slot>\n </FormControl>\n <AutoFormLabel v-if=\"!config?.hideLabel\" :required=\"required\">\n {{ config?.label || beautifyObjectName(label ?? fieldName) }}\n </AutoFormLabel>\n </div>\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": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldDate.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldEnum.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/default/ui/form'\nimport { Label } from '@/registry/default/ui/label'\nimport { RadioGroup, RadioGroupItem } from '@/registry/default/ui/radio-group'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/registry/default/ui/select'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\ndefineProps<FieldProps & {\n options?: string[]\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 <RadioGroup v-if=\"config?.component === 'radio'\" :disabled=\"disabled\" :orientation=\"'vertical'\" v-bind=\"{ ...slotProps.componentField }\">\n <div v-for=\"(option, index) in options\" :key=\"option\" class=\"mb-2 flex items-center gap-3 space-y-0\">\n <RadioGroupItem :id=\"`${option}-${index}`\" :value=\"option\" />\n <Label :for=\"`${option}-${index}`\">{{ beautifyObjectName(option) }}</Label>\n </div>\n </RadioGroup>\n\n <Select v-else :disabled=\"disabled\" v-bind=\"{ ...slotProps.componentField }\">\n <SelectTrigger class=\"w-full\">\n <SelectValue :placeholder=\"config?.inputProps?.placeholder\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem v-for=\"option in options\" :key=\"option\" :value=\"option\">\n {{ beautifyObjectName(option) }}\n </SelectItem>\n </SelectContent>\n </Select>\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": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldFile.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { Button } from '@/registry/default/ui/button'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/default/ui/form'\nimport { Input } from '@/registry/default/ui/input'\nimport { TrashIcon } from 'lucide-vue-next'\nimport { ref } from 'vue'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\ndefineProps<FieldProps>()\n\nconst inputFile = ref<File>()\nasync function parseFileAsString(file: File | undefined): Promise<string> {\n return new Promise((resolve, reject) => {\n if (file) {\n const reader = new FileReader()\n reader.onloadend = () => {\n resolve(reader.result as string)\n }\n reader.onerror = (err) => {\n reject(err)\n }\n reader.readAsDataURL(file)\n }\n })\n}\n</script>\n\n<template>\n <FormField v-slot=\"slotProps\" :name=\"fieldName\">\n <FormItem v-bind=\"$attrs\">\n <AutoFormLabel v-if=\"!config?.hideLabel\" :required=\"required\">\n {{ config?.label || beautifyObjectName(label ?? fieldName) }}\n </AutoFormLabel>\n <FormControl>\n <slot v-bind=\"slotProps\">\n <Input\n v-if=\"!inputFile\"\n type=\"file\"\n v-bind=\"{ ...config?.inputProps }\"\n :disabled=\"disabled\"\n @change=\"async (ev: InputEvent) => {\n const file = (ev.target as HTMLInputElement).files?.[0]\n inputFile = file\n const parsed = await parseFileAsString(file)\n slotProps.componentField.onInput(parsed)\n }\"\n />\n <div v-else class=\"flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent pl-3 pr-1 py-1 text-sm shadow-sm transition-colors\">\n <p>{{ inputFile?.name }}</p>\n <Button\n :size=\"'icon'\"\n :variant=\"'ghost'\"\n class=\"h-[26px] w-[26px]\"\n aria-label=\"Remove file\"\n type=\"button\"\n @click=\"() => {\n inputFile = undefined\n slotProps.componentField.onInput(undefined)\n }\"\n >\n <TrashIcon :size=\"16\" />\n </Button>\n </div>\n </slot>\n </FormControl>\n <FormDescription v-if=\"config?.description\">\n {{ config.description }}\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/default/ui/form'\nimport { Input } from '@/registry/default/ui/input'\nimport { Textarea } from '@/registry/default/ui/textarea'\nimport { computed } from 'vue'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\nconst props = defineProps<FieldProps>()\nconst inputComponent = computed(() => props.config?.component === 'textarea' ? Textarea : Input)\n</script>\n\n<template>\n <FormField v-slot=\"slotProps\" :name=\"fieldName\">\n <FormItem v-bind=\"$attrs\">\n <AutoFormLabel v-if=\"!config?.hideLabel\" :required=\"required\">\n {{ config?.label || beautifyObjectName(label ?? fieldName) }}\n </AutoFormLabel>\n <FormControl>\n <slot v-bind=\"slotProps\">\n <component\n :is=\"inputComponent\"\n type=\"text\"\n v-bind=\"{ ...slotProps.componentField, ...config?.inputProps }\"\n :disabled=\"disabled\"\n />\n </slot>\n </FormControl>\n <FormDescription v-if=\"config?.description\">\n {{ config.description }}\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldNumber.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { FieldProps } from './interface'\nimport { FormControl, FormDescription, FormField, FormItem, FormMessage } from '@/registry/default/ui/form'\nimport { Input } from '@/registry/default/ui/input'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName } from './utils'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\ndefineProps<FieldProps>()\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 <Input type=\"number\" v-bind=\"{ ...slotProps.componentField, ...config?.inputProps }\" :disabled=\"disabled\" />\n </slot>\n </FormControl>\n <FormDescription v-if=\"config?.description\">\n {{ config.description }}\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormFieldObject.vue",
|
|
"content": "<script setup lang=\"ts\" generic=\"T extends ZodRawShape\">\nimport type { ZodAny, ZodObject, ZodRawShape } from 'zod'\nimport type { Config, ConfigItem, Shape } from './interface'\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/registry/default/ui/accordion'\nimport { FormItem } from '@/registry/default/ui/form'\nimport { FieldContextKey, useField } from 'vee-validate'\nimport { computed, provide } from 'vue'\nimport AutoFormField from './AutoFormField.vue'\nimport AutoFormLabel from './AutoFormLabel.vue'\nimport { beautifyObjectName, getBaseSchema, getBaseType, getDefaultValueInZodStack } from './utils'\n\nconst props = defineProps<{\n fieldName: string\n required?: boolean\n config?: Config<T>\n schema?: ZodObject<T>\n disabled?: boolean\n}>()\n\nconst shapes = computed(() => {\n // @ts-expect-error ignore {} not assignable to object\n const val: { [key in keyof T]: Shape } = {}\n\n if (!props.schema)\n return\n const shape = getBaseSchema(props.schema)?.shape\n if (!shape)\n return\n Object.keys(shape).forEach((name) => {\n const item = shape[name] as ZodAny\n const baseItem = getBaseSchema(item) as ZodAny\n let options = (baseItem && 'values' in baseItem._def) ? baseItem._def.values as string[] : undefined\n if (!Array.isArray(options) && typeof options === 'object')\n options = Object.values(options)\n\n val[name as keyof T] = {\n type: getBaseType(item),\n default: getDefaultValueInZodStack(item),\n options,\n required: !['ZodOptional', 'ZodNullable'].includes(item._def.typeName),\n schema: item,\n }\n })\n return val\n})\n\nconst fieldContext = useField(props.fieldName)\n// @ts-expect-error ignore missing `id`\nprovide(FieldContextKey, fieldContext)\n</script>\n\n<template>\n <section>\n <slot v-bind=\"props\">\n <Accordion type=\"single\" as-child class=\"w-full\" collapsible :disabled=\"disabled\">\n <FormItem>\n <AccordionItem :value=\"fieldName\" class=\"border-none\">\n <AccordionTrigger>\n <AutoFormLabel class=\"text-base\" :required=\"required\">\n {{ schema?.description || beautifyObjectName(fieldName) }}\n </AutoFormLabel>\n </AccordionTrigger>\n <AccordionContent class=\"p-1 space-y-5\">\n <template v-for=\"(shape, key) in shapes\" :key=\"key\">\n <AutoFormField\n :config=\"config?.[key as keyof typeof config] as ConfigItem\"\n :field-name=\"`${fieldName}.${key.toString()}`\"\n :label=\"key.toString()\"\n :shape=\"shape\"\n />\n </template>\n </AccordionContent>\n </AccordionItem>\n </FormItem>\n </Accordion>\n </slot>\n </section>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/AutoFormLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { FormLabel } from '@/registry/default/ui/form'\n\ndefineProps<{\n required?: boolean\n}>()\n</script>\n\n<template>\n <FormLabel>\n <slot />\n <span v-if=\"required\" class=\"text-destructive\"> *</span>\n </FormLabel>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/constant.ts",
|
|
"content": "import type { InputComponents } from './interface'\nimport AutoFormFieldArray from './AutoFormFieldArray.vue'\nimport AutoFormFieldBoolean from './AutoFormFieldBoolean.vue'\nimport AutoFormFieldDate from './AutoFormFieldDate.vue'\nimport AutoFormFieldEnum from './AutoFormFieldEnum.vue'\nimport AutoFormFieldFile from './AutoFormFieldFile.vue'\nimport AutoFormFieldInput from './AutoFormFieldInput.vue'\nimport AutoFormFieldNumber from './AutoFormFieldNumber.vue'\nimport AutoFormFieldObject from './AutoFormFieldObject.vue'\n\nexport const INPUT_COMPONENTS: InputComponents = {\n date: AutoFormFieldDate,\n select: AutoFormFieldEnum,\n radio: AutoFormFieldEnum,\n checkbox: AutoFormFieldBoolean,\n switch: AutoFormFieldBoolean,\n textarea: AutoFormFieldInput,\n number: AutoFormFieldNumber,\n string: AutoFormFieldInput,\n file: AutoFormFieldFile,\n array: AutoFormFieldArray,\n object: AutoFormFieldObject,\n}\n\n/**\n * Define handlers for specific Zod types.\n * You can expand this object to support more types.\n */\nexport const DEFAULT_ZOD_HANDLERS: {\n [key: string]: keyof typeof INPUT_COMPONENTS\n} = {\n ZodString: 'string',\n ZodBoolean: 'checkbox',\n ZodDate: 'date',\n ZodEnum: 'select',\n ZodNativeEnum: 'select',\n ZodNumber: 'number',\n ZodArray: 'array',\n ZodObject: 'object',\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/dependencies.ts",
|
|
"content": "import type { Ref } from 'vue'\nimport type * as z from 'zod'\nimport { createContext } from 'reka-ui'\nimport { useFieldValue, useFormValues } from 'vee-validate'\nimport { computed, ref, watch } from 'vue'\nimport { type Dependency, DependencyType, type EnumValues } from './interface'\nimport { getFromPath, getIndexIfArray } from './utils'\n\nexport const [injectDependencies, provideDependencies] = createContext<Ref<Dependency<z.infer<z.ZodObject<any>>>[] | undefined>>('AutoFormDependencies')\n\nexport default function useDependencies(\n fieldName: string,\n) {\n const form = useFormValues()\n // parsed test[0].age => test.age\n const currentFieldName = fieldName.replace(/\\[\\d+\\]/g, '')\n const currentFieldValue = useFieldValue<any>(fieldName)\n\n if (!form)\n throw new Error('useDependencies should be used within <AutoForm>')\n\n const dependencies = injectDependencies()\n const isDisabled = ref(false)\n const isHidden = ref(false)\n const isRequired = ref(false)\n const overrideOptions = ref<EnumValues | undefined>()\n\n const currentFieldDependencies = computed(() => dependencies.value?.filter(\n dependency => dependency.targetField === currentFieldName,\n ))\n\n function getSourceValue(dep: Dependency<any>) {\n const source = dep.sourceField as string\n const index = getIndexIfArray(fieldName) ?? -1\n const [sourceLast, ...sourceInitial] = source.split('.').toReversed()\n const [_targetLast, ...targetInitial] = (dep.targetField as string).split('.').toReversed()\n\n if (index >= 0 && sourceInitial.join(',') === targetInitial.join(',')) {\n const [_currentLast, ...currentInitial] = fieldName.split('.').toReversed()\n return getFromPath(form.value, currentInitial.join('.') + sourceLast)\n }\n\n return getFromPath(form.value, source)\n }\n\n const sourceFieldValues = computed(() => currentFieldDependencies.value?.map(dep => getSourceValue(dep)))\n\n const resetConditionState = () => {\n isDisabled.value = false\n isHidden.value = false\n isRequired.value = false\n overrideOptions.value = undefined\n }\n\n watch([sourceFieldValues, dependencies], () => {\n resetConditionState()\n currentFieldDependencies.value?.forEach((dep) => {\n const sourceValue = getSourceValue(dep)\n const conditionMet = dep.when(sourceValue, currentFieldValue.value)\n\n switch (dep.type) {\n case DependencyType.DISABLES:\n if (conditionMet)\n isDisabled.value = true\n\n break\n case DependencyType.REQUIRES:\n if (conditionMet)\n isRequired.value = true\n\n break\n case DependencyType.HIDES:\n if (conditionMet)\n isHidden.value = true\n\n break\n case DependencyType.SETS_OPTIONS:\n if (conditionMet)\n overrideOptions.value = dep.options\n\n break\n }\n })\n }, { immediate: true, deep: true })\n\n return {\n isDisabled,\n isHidden,\n isRequired,\n overrideOptions,\n }\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/index.ts",
|
|
"content": "export { default as AutoForm } from './AutoForm.vue'\nexport { default as AutoFormField } from './AutoFormField.vue'\n\nexport { default as AutoFormFieldArray } from './AutoFormFieldArray.vue'\nexport { default as AutoFormFieldBoolean } from './AutoFormFieldBoolean.vue'\nexport { default as AutoFormFieldDate } from './AutoFormFieldDate.vue'\n\nexport { default as AutoFormFieldEnum } from './AutoFormFieldEnum.vue'\nexport { default as AutoFormFieldFile } from './AutoFormFieldFile.vue'\nexport { default as AutoFormFieldInput } from './AutoFormFieldInput.vue'\nexport { default as AutoFormFieldNumber } from './AutoFormFieldNumber.vue'\nexport { default as AutoFormFieldObject } from './AutoFormFieldObject.vue'\nexport { default as AutoFormLabel } from './AutoFormLabel.vue'\nexport type { Config, ConfigItem, FieldProps } from './interface'\nexport { getBaseSchema, getBaseType, getObjectFormSchema } from './utils'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/interface.ts",
|
|
"content": "import type { Component, InputHTMLAttributes } from 'vue'\nimport type { z, ZodAny } from 'zod'\nimport type { INPUT_COMPONENTS } from './constant'\n\nexport interface FieldProps {\n fieldName: string\n label?: string\n required?: boolean\n config?: ConfigItem\n disabled?: boolean\n}\n\nexport interface Shape {\n type: string\n default?: any\n required?: boolean\n options?: string[]\n schema?: ZodAny\n}\n\nexport interface InputComponents {\n date: Component\n select: Component\n radio: Component\n checkbox: Component\n switch: Component\n textarea: Component\n number: Component\n string: Component\n file: Component\n array: Component\n object: Component\n};\n\nexport interface ConfigItem {\n /** Value for the `FormLabel` */\n label?: string\n /** Value for the `FormDescription` */\n description?: string\n /** Pick which component to be rendered. */\n component?: keyof typeof INPUT_COMPONENTS | Component\n /** Hide `FormLabel`. */\n hideLabel?: boolean\n inputProps?: InputHTMLAttributes\n}\n\n// Define a type to unwrap an array\ntype UnwrapArray<T> = T extends (infer U)[] ? U : never\n\nexport type Config<SchemaType extends object> = {\n // If SchemaType.key is an object, create a nested Config, otherwise ConfigItem\n [Key in keyof SchemaType]?:\n SchemaType[Key] extends any[]\n ? UnwrapArray<Config<SchemaType[Key]>>\n : SchemaType[Key] extends object\n ? Config<SchemaType[Key]>\n : ConfigItem;\n}\n\nexport enum DependencyType {\n DISABLES,\n REQUIRES,\n HIDES,\n SETS_OPTIONS,\n}\n\ninterface BaseDependency<SchemaType extends z.infer<z.ZodObject<any, any>>> {\n sourceField: keyof SchemaType\n type: DependencyType\n targetField: keyof SchemaType\n when: (sourceFieldValue: any, targetFieldValue: any) => boolean\n}\n\nexport type ValueDependency<SchemaType extends z.infer<z.ZodObject<any, any>>> =\n BaseDependency<SchemaType> & {\n type:\n | DependencyType.DISABLES\n | DependencyType.REQUIRES\n | DependencyType.HIDES\n }\n\nexport type EnumValues = readonly [string, ...string[]]\n\nexport type OptionsDependency<\n SchemaType extends z.infer<z.ZodObject<any, any>>,\n> = BaseDependency<SchemaType> & {\n type: DependencyType.SETS_OPTIONS\n\n // Partial array of values from sourceField that will trigger the dependency\n options: EnumValues\n}\n\nexport type Dependency<SchemaType extends z.infer<z.ZodObject<any, any>>> =\n | ValueDependency<SchemaType>\n | OptionsDependency<SchemaType>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/auto-form/utils.ts",
|
|
"content": "import type { z } from 'zod'\n\n// TODO: This should support recursive ZodEffects but TypeScript doesn't allow circular type definitions.\nexport type ZodObjectOrWrapped =\n | z.ZodObject<any, any>\n | z.ZodEffects<z.ZodObject<any, any>>\n\n/**\n * Beautify a camelCase string.\n * e.g. \"myString\" -> \"My String\"\n */\nexport function beautifyObjectName(string: string) {\n // Remove bracketed indices\n // if numbers only return the string\n let output = string.replace(/\\[\\d+\\]/g, '').replace(/([A-Z])/g, ' $1')\n output = output.charAt(0).toUpperCase() + output.slice(1)\n return output\n}\n\n/**\n * Parse string and extract the index\n * @param string\n * @returns index or undefined\n */\nexport function getIndexIfArray(string: string) {\n const indexRegex = /\\[(\\d+)\\]/\n // Match the index\n const match = string.match(indexRegex)\n // Extract the index (number)\n const index = match ? Number.parseInt(match[1]) : undefined\n return index\n}\n\n/**\n * Get the lowest level Zod type.\n * This will unpack optionals, refinements, etc.\n */\nexport function getBaseSchema<\n ChildType extends z.ZodAny | z.AnyZodObject = z.ZodAny,\n>(schema: ChildType | z.ZodEffects<ChildType>): ChildType | null {\n if (!schema)\n return null\n if ('innerType' in schema._def)\n return getBaseSchema(schema._def.innerType as ChildType)\n\n if ('schema' in schema._def)\n return getBaseSchema(schema._def.schema as ChildType)\n\n return schema as ChildType\n}\n\n/**\n * Get the type name of the lowest level Zod type.\n * This will unpack optionals, refinements, etc.\n */\nexport function getBaseType(schema: z.ZodAny) {\n const baseSchema = getBaseSchema(schema)\n return baseSchema ? baseSchema._def.typeName : ''\n}\n\n/**\n * Search for a \"ZodDefault\" in the Zod stack and return its value.\n */\nexport function getDefaultValueInZodStack(schema: z.ZodAny): any {\n const typedSchema = schema as unknown as z.ZodDefault<\n z.ZodNumber | z.ZodString\n >\n\n if (typedSchema._def.typeName === 'ZodDefault')\n return typedSchema._def.defaultValue()\n\n if ('innerType' in typedSchema._def) {\n return getDefaultValueInZodStack(\n typedSchema._def.innerType as unknown as z.ZodAny,\n )\n }\n if ('schema' in typedSchema._def) {\n return getDefaultValueInZodStack(\n (typedSchema._def as any).schema as z.ZodAny,\n )\n }\n\n return undefined\n}\n\nexport function getObjectFormSchema(\n schema: ZodObjectOrWrapped,\n): z.ZodObject<any, any> {\n if (schema?._def.typeName === 'ZodEffects') {\n const typedSchema = schema as z.ZodEffects<z.ZodObject<any, any>>\n return getObjectFormSchema(typedSchema._def.schema)\n }\n return schema as z.ZodObject<any, any>\n}\n\nfunction isIndex(value: unknown): value is number {\n return Number(value) >= 0\n}\n/**\n * Constructs a path with dot paths for arrays to use brackets to be compatible with vee-validate path syntax\n */\nexport function normalizeFormPath(path: string): string {\n const pathArr = path.split('.')\n if (!pathArr.length)\n return ''\n\n let fullPath = String(pathArr[0])\n for (let i = 1; i < pathArr.length; i++) {\n if (isIndex(pathArr[i])) {\n fullPath += `[${pathArr[i]}]`\n continue\n }\n\n fullPath += `.${pathArr[i]}`\n }\n\n return fullPath\n}\n\ntype NestedRecord = Record<string, unknown> | { [k: string]: NestedRecord }\n/**\n * Checks if the path opted out of nested fields using `[fieldName]` syntax\n */\nexport function isNotNestedPath(path: string) {\n return /^\\[.+\\]$/.test(path)\n}\nfunction isObject(obj: unknown): obj is Record<string, unknown> {\n return obj !== null && !!obj && typeof obj === 'object' && !Array.isArray(obj)\n}\nfunction isContainerValue(value: unknown): value is Record<string, unknown> {\n return isObject(value) || Array.isArray(value)\n}\nfunction cleanupNonNestedPath(path: string) {\n if (isNotNestedPath(path))\n return path.replace(/\\[|\\]/g, '')\n\n return path\n}\n\n/**\n * Gets a nested property value from an object\n */\nexport function getFromPath<TValue = unknown>(object: NestedRecord | undefined, path: string): TValue | undefined\nexport function getFromPath<TValue = unknown, TFallback = TValue>(\n object: NestedRecord | undefined,\n path: string,\n fallback?: TFallback,\n): TValue | TFallback\nexport function getFromPath<TValue = unknown, TFallback = TValue>(\n object: NestedRecord | undefined,\n path: string,\n fallback?: TFallback,\n): TValue | TFallback | undefined {\n if (!object)\n return fallback\n\n if (isNotNestedPath(path))\n return object[cleanupNonNestedPath(path)] as TValue | undefined\n\n const resolvedValue = (path || '')\n .split(/\\.|\\[(\\d+)\\]/)\n .filter(Boolean)\n .reduce((acc, propKey) => {\n if (isContainerValue(acc) && propKey in acc)\n return acc[propKey]\n\n return fallback\n }, object as unknown)\n\n return resolvedValue as TValue | undefined\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "avatar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/avatar/Avatar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { AvatarRoot } from 'reka-ui'\nimport { avatarVariant, type AvatarVariants } from '.'\n\nconst props = withDefaults(defineProps<{\n class?: HTMLAttributes['class']\n size?: AvatarVariants['size']\n shape?: AvatarVariants['shape']\n}>(), {\n size: 'sm',\n shape: 'circle',\n})\n</script>\n\n<template>\n <AvatarRoot :class=\"cn(avatarVariant({ size, shape }), props.class)\">\n <slot />\n </AvatarRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/avatar/AvatarFallback.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AvatarFallback, type AvatarFallbackProps } from 'reka-ui'\n\nconst props = defineProps<AvatarFallbackProps>()\n</script>\n\n<template>\n <AvatarFallback v-bind=\"props\">\n <slot />\n </AvatarFallback>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/avatar/AvatarImage.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AvatarImage, type AvatarImageProps } from 'reka-ui'\n\nconst props = defineProps<AvatarImageProps>()\n</script>\n\n<template>\n <AvatarImage v-bind=\"props\" class=\"h-full w-full object-cover\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/avatar/index.ts",
|
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Avatar } from './Avatar.vue'\nexport { default as AvatarFallback } from './AvatarFallback.vue'\nexport { default as AvatarImage } from './AvatarImage.vue'\n\nexport const avatarVariant = cva(\n 'inline-flex items-center justify-center font-normal text-foreground select-none shrink-0 bg-secondary overflow-hidden',\n {\n variants: {\n size: {\n sm: 'h-10 w-10 text-xs',\n base: 'h-16 w-16 text-2xl',\n lg: 'h-32 w-32 text-5xl',\n },\n shape: {\n circle: 'rounded-full',\n square: 'rounded-md',\n },\n },\n },\n)\n\nexport type AvatarVariants = VariantProps<typeof avatarVariant>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "badge",
|
|
"type": "registry:ui",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/badge/Badge.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { type BadgeVariants, badgeVariants } from '.'\n\nconst props = defineProps<{\n variant?: BadgeVariants['variant']\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn(badgeVariants({ variant }), props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/badge/index.ts",
|
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Badge } from './Badge.vue'\n\nexport const badgeVariants = cva(\n 'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',\n {\n variants: {\n variant: {\n default:\n 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',\n secondary:\n 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',\n destructive:\n 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80',\n outline: 'text-foreground',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n)\n\nexport type BadgeVariants = VariantProps<typeof badgeVariants>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "breadcrumb",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/breadcrumb/Breadcrumb.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <nav aria-label=\"breadcrumb\" :class=\"props.class\">\n <slot />\n </nav>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/BreadcrumbEllipsis.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { MoreHorizontal } from 'lucide-vue-next'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n :class=\"cn('flex h-9 w-9 items-center justify-center', props.class)\"\n >\n <slot>\n <MoreHorizontal class=\"h-4 w-4\" />\n </slot>\n <span class=\"sr-only\">More</span>\n </span>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/BreadcrumbItem.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n :class=\"cn('inline-flex items-center gap-1.5', props.class)\"\n >\n <slot />\n </li>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/BreadcrumbLink.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps } from 'reka-ui'\n\nconst props = withDefaults(defineProps<PrimitiveProps & { class?: HTMLAttributes['class'] }>(), {\n as: 'a',\n})\n</script>\n\n<template>\n <Primitive\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn('transition-colors hover:text-foreground', props.class)\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/BreadcrumbList.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <ol\n :class=\"cn('flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5', props.class)\"\n >\n <slot />\n </ol>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/BreadcrumbPage.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n :class=\"cn('font-normal text-foreground', props.class)\"\n >\n <slot />\n </span>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/BreadcrumbSeparator.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { ChevronRight } from 'lucide-vue-next'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n :class=\"cn('[&>svg]:w-3.5 [&>svg]:h-3.5', props.class)\"\n >\n <slot>\n <ChevronRight />\n </slot>\n </li>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/breadcrumb/index.ts",
|
|
"content": "export { default as Breadcrumb } from './Breadcrumb.vue'\nexport { default as BreadcrumbEllipsis } from './BreadcrumbEllipsis.vue'\nexport { default as BreadcrumbItem } from './BreadcrumbItem.vue'\nexport { default as BreadcrumbLink } from './BreadcrumbLink.vue'\nexport { default as BreadcrumbList } from './BreadcrumbList.vue'\nexport { default as BreadcrumbPage } from './BreadcrumbPage.vue'\nexport { default as BreadcrumbSeparator } from './BreadcrumbSeparator.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "button",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/button/Button.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps } from 'reka-ui'\nimport { type ButtonVariants, buttonVariants } from '.'\n\ninterface Props extends PrimitiveProps {\n variant?: ButtonVariants['variant']\n size?: ButtonVariants['size']\n class?: HTMLAttributes['class']\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n as: 'button',\n})\n</script>\n\n<template>\n <Primitive\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn(buttonVariants({ variant, size }), props.class)\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/button/index.ts",
|
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Button } from './Button.vue'\n\nexport const buttonVariants = cva(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n default:\n 'bg-primary text-primary-foreground shadow hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',\n outline:\n 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-8',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "calendar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/calendar/Calendar.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarRoot, type CalendarRootEmits, type CalendarRootProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, CalendarGridHead, CalendarGridRow, CalendarHeadCell, CalendarHeader, CalendarHeading, CalendarNextButton, CalendarPrevButton } from '.'\n\nconst props = defineProps<CalendarRootProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<CalendarRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <CalendarRoot\n v-slot=\"{ grid, weekDays }\"\n :class=\"cn('p-3', props.class)\"\n v-bind=\"forwarded\"\n >\n <CalendarHeader>\n <CalendarPrevButton />\n <CalendarHeading />\n <CalendarNextButton />\n </CalendarHeader>\n\n <div class=\"flex flex-col gap-y-4 mt-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>\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:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarCell.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarCell, type CalendarCellProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarCellProps & { 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 <CalendarCell\n :class=\"cn('relative h-9 w-9 p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([data-selected])]:rounded-md [&:has([data-selected])]:bg-accent [&:has([data-selected][data-outside-view])]:bg-accent/50', props.class)\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </CalendarCell>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarCellTrigger.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarGrid.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarGrid, type CalendarGridProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarGridProps & { 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 <CalendarGrid\n :class=\"cn('w-full border-collapse space-y-1', props.class)\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </CalendarGrid>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarGridBody.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { CalendarGridBody, type CalendarGridBodyProps } from 'reka-ui'\n\nconst props = defineProps<CalendarGridBodyProps>()\n</script>\n\n<template>\n <CalendarGridBody v-bind=\"props\">\n <slot />\n </CalendarGridBody>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarGridHead.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { CalendarGridHead, type CalendarGridHeadProps } from 'reka-ui'\n\nconst props = defineProps<CalendarGridHeadProps>()\n</script>\n\n<template>\n <CalendarGridHead v-bind=\"props\">\n <slot />\n </CalendarGridHead>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarGridRow.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarGridRow, type CalendarGridRowProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarGridRowProps & { 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 <CalendarGridRow :class=\"cn('flex', props.class)\" v-bind=\"forwardedProps\">\n <slot />\n </CalendarGridRow>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarHeadCell.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarHeadCell, type CalendarHeadCellProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarHeadCellProps & { 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 <CalendarHeadCell :class=\"cn('w-9 rounded-md text-[0.8rem] font-normal text-muted-foreground', props.class)\" v-bind=\"forwardedProps\">\n <slot />\n </CalendarHeadCell>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarHeader.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarHeader, type CalendarHeaderProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarHeaderProps & { 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 <CalendarHeader :class=\"cn('relative flex w-full items-center justify-between pt-1', props.class)\" v-bind=\"forwardedProps\">\n <slot />\n </CalendarHeader>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarHeading.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { CalendarHeading, type CalendarHeadingProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CalendarHeadingProps & { 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 <CalendarHeading\n v-slot=\"{ headingValue }\"\n :class=\"cn('text-sm font-medium', props.class)\"\n v-bind=\"forwardedProps\"\n >\n <slot :heading-value>\n {{ headingValue }}\n </slot>\n </CalendarHeading>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarNextButton.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/CalendarPrevButton.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/calendar/index.ts",
|
|
"content": "export { default as Calendar } from './Calendar.vue'\nexport { default as CalendarCell } from './CalendarCell.vue'\nexport { default as CalendarCellTrigger } from './CalendarCellTrigger.vue'\nexport { default as CalendarGrid } from './CalendarGrid.vue'\nexport { default as CalendarGridBody } from './CalendarGridBody.vue'\nexport { default as CalendarGridHead } from './CalendarGridHead.vue'\nexport { default as CalendarGridRow } from './CalendarGridRow.vue'\nexport { default as CalendarHeadCell } from './CalendarHeadCell.vue'\nexport { default as CalendarHeader } from './CalendarHeader.vue'\nexport { default as CalendarHeading } from './CalendarHeading.vue'\nexport { default as CalendarNextButton } from './CalendarNextButton.vue'\nexport { default as CalendarPrevButton } from './CalendarPrevButton.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "card",
|
|
"type": "registry:ui",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/card/Card.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n :class=\"\n cn(\n 'rounded-lg border bg-card text-card-foreground shadow-sm',\n props.class,\n )\n \"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/card/CardContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('p-6 pt-0', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/card/CardDescription.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <p :class=\"cn('text-sm text-muted-foreground', props.class)\">\n <slot />\n </p>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/card/CardFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('flex items-center p-6 pt-0', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/card/CardHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('flex flex-col gap-y-1.5 p-6', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/card/CardTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <h3\n :class=\"\n cn('text-2xl font-semibold leading-none tracking-tight', props.class)\n \"\n >\n <slot />\n </h3>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/card/index.ts",
|
|
"content": "export { default as Card } from './Card.vue'\nexport { default as CardContent } from './CardContent.vue'\nexport { default as CardDescription } from './CardDescription.vue'\nexport { default as CardFooter } from './CardFooter.vue'\nexport { default as CardHeader } from './CardHeader.vue'\nexport { default as CardTitle } from './CardTitle.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "carousel",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"embla-carousel-vue",
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/carousel/Carousel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { CarouselEmits, CarouselProps, WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\nimport { useProvideCarousel } from './useCarousel'\n\nconst props = withDefaults(defineProps<CarouselProps & WithClassAsProps>(), {\n orientation: 'horizontal',\n})\n\nconst emits = defineEmits<CarouselEmits>()\n\nconst { canScrollNext, canScrollPrev, carouselApi, carouselRef, orientation, scrollNext, scrollPrev } = useProvideCarousel(props, emits)\n\ndefineExpose({\n canScrollNext,\n canScrollPrev,\n carouselApi,\n carouselRef,\n orientation,\n scrollNext,\n scrollPrev,\n})\n\nfunction onKeyDown(event: KeyboardEvent) {\n const prevKey = props.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft'\n const nextKey = props.orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight'\n\n if (event.key === prevKey) {\n event.preventDefault()\n scrollPrev()\n\n return\n }\n\n if (event.key === nextKey) {\n event.preventDefault()\n scrollNext()\n }\n}\n</script>\n\n<template>\n <div\n :class=\"cn('relative', props.class)\"\n role=\"region\"\n aria-roledescription=\"carousel\"\n tabindex=\"0\"\n @keydown=\"onKeyDown\"\n >\n <slot :can-scroll-next :can-scroll-prev :carousel-api :carousel-ref :orientation :scroll-next :scroll-prev />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/CarouselContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\nimport { useCarousel } from './useCarousel'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { carouselRef, orientation } = useCarousel()\n</script>\n\n<template>\n <div ref=\"carouselRef\" class=\"overflow-hidden\">\n <div\n :class=\"\n cn(\n 'flex',\n orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col',\n props.class,\n )\"\n v-bind=\"$attrs\"\n >\n <slot />\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/CarouselItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from './interface'\nimport { cn } from '@/lib/utils'\nimport { useCarousel } from './useCarousel'\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { orientation } = useCarousel()\n</script>\n\n<template>\n <div\n role=\"group\"\n aria-roledescription=\"slide\"\n :class=\"cn(\n 'min-w-0 shrink-0 grow-0 basis-full',\n orientation === 'horizontal' ? 'pl-4' : 'pt-4',\n props.class,\n )\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/CarouselNext.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/CarouselPrevious.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/index.ts",
|
|
"content": "export { default as Carousel } from './Carousel.vue'\nexport { default as CarouselContent } from './CarouselContent.vue'\nexport { default as CarouselItem } from './CarouselItem.vue'\nexport { default as CarouselNext } from './CarouselNext.vue'\nexport { default as CarouselPrevious } from './CarouselPrevious.vue'\nexport type {\n UnwrapRefCarouselApi as CarouselApi,\n} from './interface'\n\nexport { useCarousel } from './useCarousel'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/interface.ts",
|
|
"content": "import type useEmblaCarousel from 'embla-carousel-vue'\nimport type {\n EmblaCarouselVueType,\n} from 'embla-carousel-vue'\nimport type { HTMLAttributes, UnwrapRef } from 'vue'\n\ntype CarouselApi = EmblaCarouselVueType[1]\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>\ntype CarouselOptions = UseCarouselParameters[0]\ntype CarouselPlugin = UseCarouselParameters[1]\n\nexport type UnwrapRefCarouselApi = UnwrapRef<CarouselApi>\n\nexport interface CarouselProps {\n opts?: CarouselOptions\n plugins?: CarouselPlugin\n orientation?: 'horizontal' | 'vertical'\n}\n\nexport interface CarouselEmits {\n (e: 'init-api', payload: UnwrapRefCarouselApi): void\n}\n\nexport interface WithClassAsProps {\n class?: HTMLAttributes['class']\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/carousel/useCarousel.ts",
|
|
"content": "import type { UnwrapRefCarouselApi as CarouselApi, CarouselEmits, CarouselProps } from './interface'\nimport { createInjectionState } from '@vueuse/core'\nimport emblaCarouselVue from 'embla-carousel-vue'\nimport { onMounted, ref } from 'vue'\n\nconst [useProvideCarousel, useInjectCarousel] = createInjectionState(\n ({\n opts,\n orientation,\n plugins,\n }: CarouselProps, emits: CarouselEmits) => {\n const [emblaNode, emblaApi] = emblaCarouselVue({\n ...opts,\n axis: orientation === 'horizontal' ? 'x' : 'y',\n }, plugins)\n\n function scrollPrev() {\n emblaApi.value?.scrollPrev()\n }\n function scrollNext() {\n emblaApi.value?.scrollNext()\n }\n\n const canScrollNext = ref(false)\n const canScrollPrev = ref(false)\n\n function onSelect(api: CarouselApi) {\n canScrollNext.value = api?.canScrollNext() || false\n canScrollPrev.value = api?.canScrollPrev() || false\n }\n\n onMounted(() => {\n if (!emblaApi.value)\n return\n\n emblaApi.value?.on('init', onSelect)\n emblaApi.value?.on('reInit', onSelect)\n emblaApi.value?.on('select', onSelect)\n\n emits('init-api', emblaApi.value)\n })\n\n return { carouselRef: emblaNode, carouselApi: emblaApi, canScrollPrev, canScrollNext, scrollPrev, scrollNext, orientation }\n },\n)\n\nfunction useCarousel() {\n const carouselState = useInjectCarousel()\n\n if (!carouselState)\n throw new Error('useCarousel must be used within a <Carousel />')\n\n return carouselState\n}\n\nexport { useCarousel, useProvideCarousel }\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "chart",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/chart/ChartCrosshair.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { BulletLegendItemInterface } from '@unovis/ts'\nimport { omit } from '@unovis/ts'\nimport { VisCrosshair, VisTooltip } from '@unovis/vue'\nimport { type Component, createApp } from 'vue'\nimport { ChartTooltip } from '.'\n\nconst props = withDefaults(defineProps<{\n colors: string[]\n index: string\n items: BulletLegendItemInterface[]\n customTooltip?: Component\n}>(), {\n colors: () => [],\n})\n\n// Use weakmap to store reference to each datapoint for Tooltip\nconst wm = new WeakMap()\nfunction template(d: any) {\n if (wm.has(d)) {\n return wm.get(d)\n }\n else {\n const componentDiv = document.createElement('div')\n const omittedData = Object.entries(omit(d, [props.index])).map(([key, value]) => {\n const legendReference = props.items.find(i => i.name === key)\n return { ...legendReference, value }\n })\n const TooltipComponent = props.customTooltip ?? ChartTooltip\n createApp(TooltipComponent, { title: d[props.index].toString(), data: omittedData }).mount(componentDiv)\n wm.set(d, componentDiv.innerHTML)\n return componentDiv.innerHTML\n }\n}\n\nfunction color(d: unknown, i: number) {\n return props.colors[i] ?? 'transparent'\n}\n</script>\n\n<template>\n <VisTooltip :horizontal-shift=\"20\" :vertical-shift=\"20\" />\n <VisCrosshair :template=\"template\" :color=\"color\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/chart/ChartLegend.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { BulletLegendItemInterface } from '@unovis/ts'\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { BulletLegend } from '@unovis/ts'\nimport { VisBulletLegend } from '@unovis/vue'\nimport { nextTick, onMounted, ref } from 'vue'\n\nconst props = withDefaults(defineProps<{ items: BulletLegendItemInterface[] }>(), {\n items: () => [],\n})\n\nconst emits = defineEmits<{\n 'legendItemClick': [d: BulletLegendItemInterface, i: number]\n 'update:items': [payload: BulletLegendItemInterface[]]\n}>()\n\nconst elRef = ref<HTMLElement>()\n\nonMounted(() => {\n const selector = `.${BulletLegend.selectors.item}`\n nextTick(() => {\n const elements = elRef.value?.querySelectorAll(selector)\n const classes = buttonVariants({ variant: 'ghost', size: 'xs' }).split(' ')\n elements?.forEach(el => el.classList.add(...classes, '!inline-flex', '!mr-2'))\n })\n})\n\nfunction onLegendItemClick(d: BulletLegendItemInterface, i: number) {\n emits('legendItemClick', d, i)\n const isBulletActive = !props.items[i].inactive\n const isFilterApplied = props.items.some(i => i.inactive)\n if (isFilterApplied && isBulletActive) {\n // reset filter\n emits('update:items', props.items.map(item => ({ ...item, inactive: false })))\n }\n else {\n // apply selection, set other item as inactive\n emits('update:items', props.items.map(item => item.name === d.name ? ({ ...d, inactive: false }) : { ...item, inactive: true }))\n }\n}\n</script>\n\n<template>\n <div ref=\"elRef\" class=\"w-max\">\n <VisBulletLegend\n :items=\"items\"\n :on-legend-item-click=\"onLegendItemClick\"\n />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/chart/ChartSingleTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { BulletLegendItemInterface } from '@unovis/ts'\nimport { omit } from '@unovis/ts'\nimport { VisTooltip } from '@unovis/vue'\nimport { type Component, createApp } from 'vue'\nimport { ChartTooltip } from '.'\n\nconst props = withDefaults(defineProps<{\n selector: string\n index: string\n items?: BulletLegendItemInterface[]\n valueFormatter?: (tick: number, i?: number, ticks?: number[]) => string\n customTooltip?: Component\n}>(), {\n valueFormatter: (tick: number) => `${tick}`,\n})\n\n// Use weakmap to store reference to each datapoint for Tooltip\nconst wm = new WeakMap()\nfunction template(d: any, i: number, elements: (HTMLElement | SVGElement)[]) {\n if (props.index in d) {\n if (wm.has(d)) {\n return wm.get(d)\n }\n else {\n const componentDiv = document.createElement('div')\n const omittedData = Object.entries(omit(d, [props.index])).map(([key, value]) => {\n const legendReference = props.items?.find(i => i.name === key)\n return { ...legendReference, value: props.valueFormatter(value) }\n })\n const TooltipComponent = props.customTooltip ?? ChartTooltip\n createApp(TooltipComponent, { title: d[props.index], data: omittedData }).mount(componentDiv)\n wm.set(d, componentDiv.innerHTML)\n return componentDiv.innerHTML\n }\n }\n\n else {\n const data = d.data\n\n if (wm.has(data)) {\n return wm.get(data)\n }\n else {\n const style = getComputedStyle(elements[i])\n const omittedData = [{ name: data.name, value: props.valueFormatter(data[props.index]), color: style.fill }]\n const componentDiv = document.createElement('div')\n const TooltipComponent = props.customTooltip ?? ChartTooltip\n createApp(TooltipComponent, { title: d[props.index], data: omittedData }).mount(componentDiv)\n wm.set(d, componentDiv.innerHTML)\n return componentDiv.innerHTML\n }\n }\n}\n</script>\n\n<template>\n <VisTooltip\n :horizontal-shift=\"20\" :vertical-shift=\"20\" :triggers=\"{\n [selector]: template,\n }\"\n />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/chart/ChartTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent, CardHeader, CardTitle } from '@/registry/default/ui/card'\n\ndefineProps<{\n title?: string\n data: {\n name: string\n color: string\n value: any\n }[]\n}>()\n</script>\n\n<template>\n <Card class=\"text-sm\">\n <CardHeader v-if=\"title\" class=\"p-3 border-b\">\n <CardTitle>\n {{ title }}\n </CardTitle>\n </CardHeader>\n <CardContent class=\"p-3 min-w-[180px] flex flex-col gap-1\">\n <div v-for=\"(item, key) in data\" :key=\"key\" class=\"flex justify-between\">\n <div class=\"flex items-center\">\n <span class=\"w-2.5 h-2.5 mr-2\">\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 30 30\">\n <path\n d=\" M 15 15 m -14, 0 a 14,14 0 1,1 28,0 a 14,14 0 1,1 -28,0\"\n :stroke=\"item.color\"\n :fill=\"item.color\"\n stroke-width=\"1\"\n />\n </svg>\n </span>\n <span>{{ item.name }}</span>\n </div>\n <span class=\"font-semibold ml-4\">{{ item.value }}</span>\n </div>\n </CardContent>\n </Card>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/chart/index.ts",
|
|
"content": "export { default as ChartCrosshair } from './ChartCrosshair.vue'\nexport { default as ChartLegend } from './ChartLegend.vue'\nexport { default as ChartSingleTooltip } from './ChartSingleTooltip.vue'\nexport { default as ChartTooltip } from './ChartTooltip.vue'\n\nexport function defaultColors(count: number = 3) {\n const quotient = Math.floor(count / 2)\n const remainder = count % 2\n\n const primaryCount = quotient + remainder\n const secondaryCount = quotient\n return [\n ...Array.from(new Array(primaryCount).keys()).map(i => `hsl(var(--vis-primary-color) / ${1 - (1 / primaryCount) * i})`),\n ...Array.from(new Array(secondaryCount).keys()).map(i => `hsl(var(--vis-secondary-color) / ${1 - (1 / secondaryCount) * i})`),\n ]\n}\n\nexport * from './interface'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/chart/interface.ts",
|
|
"content": "import type { Spacing } from '@unovis/ts'\n\ntype KeyOf<T extends Record<string, any>> = Extract<keyof T, string>\n\nexport interface BaseChartProps<T extends Record<string, any>> {\n /**\n * The source data, in which each entry is a dictionary.\n */\n data: T[]\n /**\n * Select the categories from your data. Used to populate the legend and toolip.\n */\n categories: KeyOf<T>[]\n /**\n * Sets the key to map the data to the axis.\n */\n index: KeyOf<T>\n /**\n * Change the default colors.\n */\n colors?: string[]\n /**\n * Margin of each the container\n */\n margin?: Spacing\n /**\n * Change the opacity of the non-selected field\n * @default 0.2\n */\n filterOpacity?: number\n /**\n * Function to format X label\n */\n xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Function to format Y label\n */\n yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Controls the visibility of the X axis.\n * @default true\n */\n showXAxis?: boolean\n /**\n * Controls the visibility of the Y axis.\n * @default true\n */\n showYAxis?: boolean\n /**\n * Controls the visibility of tooltip.\n * @default true\n */\n showTooltip?: boolean\n /**\n * Controls the visibility of legend.\n * @default true\n */\n showLegend?: boolean\n /**\n * Controls the visibility of gridline.\n * @default true\n */\n showGridLine?: boolean\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "chart-area",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts",
|
|
"@vueuse/core",
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"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 { 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": ""
|
|
},
|
|
{
|
|
"path": "ui/chart-area/index.ts",
|
|
"content": "export { default as AreaChart } from './AreaChart.vue'\n\nimport type { Spacing } from '@unovis/ts'\n\ntype KeyOf<T extends Record<string, any>> = Extract<keyof T, string>\n\nexport interface BaseChartProps<T extends Record<string, any>> {\n /**\n * The source data, in which each entry is a dictionary.\n */\n data: T[]\n /**\n * Select the categories from your data. Used to populate the legend and toolip.\n */\n categories: KeyOf<T>[]\n /**\n * Sets the key to map the data to the axis.\n */\n index: KeyOf<T>\n /**\n * Change the default colors.\n */\n colors?: string[]\n /**\n * Margin of each the container\n */\n margin?: Spacing\n /**\n * Change the opacity of the non-selected field\n * @default 0.2\n */\n filterOpacity?: number\n /**\n * Function to format X label\n */\n xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Function to format Y label\n */\n yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Controls the visibility of the X axis.\n * @default true\n */\n showXAxis?: boolean\n /**\n * Controls the visibility of the Y axis.\n * @default true\n */\n showYAxis?: boolean\n /**\n * Controls the visibility of tooltip.\n * @default true\n */\n showTooltip?: boolean\n /**\n * Controls the visibility of legend.\n * @default true\n */\n showLegend?: boolean\n /**\n * Controls the visibility of gridline.\n * @default true\n */\n showGridLine?: boolean\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "chart-bar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts",
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"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 { 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": ""
|
|
},
|
|
{
|
|
"path": "ui/chart-bar/index.ts",
|
|
"content": "export { default as BarChart } from './BarChart.vue'\n\nimport type { Spacing } from '@unovis/ts'\n\ntype KeyOf<T extends Record<string, any>> = Extract<keyof T, string>\n\nexport interface BaseChartProps<T extends Record<string, any>> {\n /**\n * The source data, in which each entry is a dictionary.\n */\n data: T[]\n /**\n * Select the categories from your data. Used to populate the legend and toolip.\n */\n categories: KeyOf<T>[]\n /**\n * Sets the key to map the data to the axis.\n */\n index: KeyOf<T>\n /**\n * Change the default colors.\n */\n colors?: string[]\n /**\n * Margin of each the container\n */\n margin?: Spacing\n /**\n * Change the opacity of the non-selected field\n * @default 0.2\n */\n filterOpacity?: number\n /**\n * Function to format X label\n */\n xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Function to format Y label\n */\n yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Controls the visibility of the X axis.\n * @default true\n */\n showXAxis?: boolean\n /**\n * Controls the visibility of the Y axis.\n * @default true\n */\n showYAxis?: boolean\n /**\n * Controls the visibility of tooltip.\n * @default true\n */\n showTooltip?: boolean\n /**\n * Controls the visibility of legend.\n * @default true\n */\n showLegend?: boolean\n /**\n * Controls the visibility of gridline.\n * @default true\n */\n showGridLine?: boolean\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "chart-donut",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts",
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"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 { 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": ""
|
|
},
|
|
{
|
|
"path": "ui/chart-donut/index.ts",
|
|
"content": "export { default as DonutChart } from './DonutChart.vue'\n\nimport type { Spacing } from '@unovis/ts'\n\ntype KeyOf<T extends Record<string, any>> = Extract<keyof T, string>\n\nexport interface BaseChartProps<T extends Record<string, any>> {\n /**\n * The source data, in which each entry is a dictionary.\n */\n data: T[]\n /**\n * Sets the key to map the data to the axis.\n */\n index: KeyOf<T>\n /**\n * Change the default colors.\n */\n colors?: string[]\n /**\n * Margin of each the container\n */\n margin?: Spacing\n /**\n * Change the opacity of the non-selected field\n * @default 0.2\n */\n filterOpacity?: number\n /**\n * Controls the visibility of tooltip.\n * @default true\n */\n showTooltip?: boolean\n /**\n * Controls the visibility of legend.\n * @default true\n */\n showLegend?: boolean\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "chart-line",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts",
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"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 { 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": ""
|
|
},
|
|
{
|
|
"path": "ui/chart-line/index.ts",
|
|
"content": "export { default as LineChart } from './LineChart.vue'\n\nimport type { Spacing } from '@unovis/ts'\n\ntype KeyOf<T extends Record<string, any>> = Extract<keyof T, string>\n\nexport interface BaseChartProps<T extends Record<string, any>> {\n /**\n * The source data, in which each entry is a dictionary.\n */\n data: T[]\n /**\n * Select the categories from your data. Used to populate the legend and toolip.\n */\n categories: KeyOf<T>[]\n /**\n * Sets the key to map the data to the axis.\n */\n index: KeyOf<T>\n /**\n * Change the default colors.\n */\n colors?: string[]\n /**\n * Margin of each the container\n */\n margin?: Spacing\n /**\n * Change the opacity of the non-selected field\n * @default 0.2\n */\n filterOpacity?: number\n /**\n * Function to format X label\n */\n xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Function to format Y label\n */\n yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string\n /**\n * Controls the visibility of the X axis.\n * @default true\n */\n showXAxis?: boolean\n /**\n * Controls the visibility of the Y axis.\n * @default true\n */\n showYAxis?: boolean\n /**\n * Controls the visibility of tooltip.\n * @default true\n */\n showTooltip?: boolean\n /**\n * Controls the visibility of legend.\n * @default true\n */\n showLegend?: boolean\n /**\n * Controls the visibility of gridline.\n * @default true\n */\n showGridLine?: boolean\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "checkbox",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/checkbox/Checkbox.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { CheckboxRootEmits, CheckboxRootProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { Check } from 'lucide-vue-next'\nimport { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<CheckboxRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<CheckboxRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <CheckboxRoot\n v-bind=\"forwarded\"\n :class=\"\n cn('peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',\n props.class)\"\n >\n <CheckboxIndicator class=\"flex h-full w-full items-center justify-center text-current\">\n <slot>\n <Check class=\"h-4 w-4\" />\n </slot>\n </CheckboxIndicator>\n </CheckboxRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/checkbox/index.ts",
|
|
"content": "export { default as Checkbox } from './Checkbox.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "collapsible",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "ui/collapsible/Collapsible.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { CollapsibleRootEmits, CollapsibleRootProps } from 'reka-ui'\nimport { CollapsibleRoot, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<CollapsibleRootProps>()\nconst emits = defineEmits<CollapsibleRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <CollapsibleRoot v-slot=\"{ open }\" v-bind=\"forwarded\">\n <slot :open=\"open\" />\n </CollapsibleRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/collapsible/CollapsibleContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { CollapsibleContent, type CollapsibleContentProps } from 'reka-ui'\n\nconst props = defineProps<CollapsibleContentProps>()\n</script>\n\n<template>\n <CollapsibleContent v-bind=\"props\" class=\"overflow-hidden transition-all data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down\">\n <slot />\n </CollapsibleContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/collapsible/CollapsibleTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { CollapsibleTrigger, type CollapsibleTriggerProps } from 'reka-ui'\n\nconst props = defineProps<CollapsibleTriggerProps>()\n</script>\n\n<template>\n <CollapsibleTrigger v-bind=\"props\">\n <slot />\n </CollapsibleTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/collapsible/index.ts",
|
|
"content": "export { default as Collapsible } from './Collapsible.vue'\nexport { default as CollapsibleContent } from './CollapsibleContent.vue'\nexport { default as CollapsibleTrigger } from './CollapsibleTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "command",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"dialog"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/command/Command.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ComboboxRootEmits, ComboboxRootProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { ComboboxRoot, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<ComboboxRootProps & { class?: HTMLAttributes['class'] }>(), {\n open: true,\n modelValue: '',\n})\n\nconst emits = defineEmits<ComboboxRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ComboboxRoot\n v-bind=\"forwarded\"\n :class=\"cn('flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground', props.class)\"\n >\n <slot />\n </ComboboxRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandDialog.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { DialogRootEmits, DialogRootProps } from 'reka-ui'\nimport { Dialog, DialogContent } from '@/registry/default/ui/dialog'\nimport { useForwardPropsEmits } from 'reka-ui'\nimport Command from './Command.vue'\n\nconst props = defineProps<DialogRootProps>()\nconst emits = defineEmits<DialogRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <Dialog v-bind=\"forwarded\">\n <DialogContent class=\"overflow-hidden p-0 shadow-lg\">\n <Command class=\"[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n <slot />\n </Command>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandEmpty.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ComboboxEmptyProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { ComboboxEmpty } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ComboboxEmptyProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ComboboxEmpty v-bind=\"delegatedProps\" :class=\"cn('py-6 text-center text-sm', props.class)\">\n <slot />\n </ComboboxEmpty>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ComboboxGroupProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { ComboboxGroup, ComboboxLabel } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ComboboxGroupProps & {\n class?: HTMLAttributes['class']\n heading?: string\n}>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ComboboxGroup\n v-bind=\"delegatedProps\"\n :class=\"cn('overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground', props.class)\"\n >\n <ComboboxLabel v-if=\"heading\" class=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n {{ heading }}\n </ComboboxLabel>\n <slot />\n </ComboboxGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Search } from 'lucide-vue-next'\nimport { ComboboxInput, type ComboboxInputProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = defineProps<ComboboxInputProps & {\n class?: HTMLAttributes['class']\n}>()\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 <div class=\"flex items-center border-b px-3\" cmdk-input-wrapper>\n <Search class=\"mr-2 h-4 w-4 shrink-0 opacity-50\" />\n <ComboboxInput\n v-bind=\"{ ...forwardedProps, ...$attrs }\"\n auto-focus\n :class=\"cn('flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50', props.class)\"\n />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ComboboxItemEmits, ComboboxItemProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { ComboboxItem, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ComboboxItemProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<ComboboxItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ComboboxItem\n v-bind=\"forwarded\"\n :class=\"cn('relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', props.class)\"\n >\n <slot />\n </ComboboxItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandList.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ComboboxContentEmits, ComboboxContentProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { ComboboxContent, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<ComboboxContentProps & { class?: HTMLAttributes['class'] }>(), {\n dismissable: false,\n})\nconst emits = defineEmits<ComboboxContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ComboboxContent v-bind=\"forwarded\" :class=\"cn('max-h-[300px] overflow-y-auto overflow-x-hidden', props.class)\">\n <div role=\"presentation\">\n <slot />\n </div>\n </ComboboxContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ComboboxSeparatorProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { ComboboxSeparator } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ComboboxSeparatorProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ComboboxSeparator\n v-bind=\"delegatedProps\"\n :class=\"cn('-mx-1 h-px bg-border', props.class)\"\n >\n <slot />\n </ComboboxSeparator>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/CommandShortcut.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span :class=\"cn('ml-auto text-xs tracking-widest text-muted-foreground', props.class)\">\n <slot />\n </span>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/command/index.ts",
|
|
"content": "export { default as Command } from './Command.vue'\nexport { default as CommandDialog } from './CommandDialog.vue'\nexport { default as CommandEmpty } from './CommandEmpty.vue'\nexport { default as CommandGroup } from './CommandGroup.vue'\nexport { default as CommandInput } from './CommandInput.vue'\nexport { default as CommandItem } from './CommandItem.vue'\nexport { default as CommandList } from './CommandList.vue'\nexport { default as CommandSeparator } from './CommandSeparator.vue'\nexport { default as CommandShortcut } from './CommandShortcut.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "context-menu",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/context-menu/ContextMenu.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { ContextMenuRootEmits, ContextMenuRootProps } from 'reka-ui'\nimport { ContextMenuRoot, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<ContextMenuRootProps>()\nconst emits = defineEmits<ContextMenuRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <ContextMenuRoot v-bind=\"forwarded\">\n <slot />\n </ContextMenuRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuCheckboxItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Check } from 'lucide-vue-next'\nimport {\n ContextMenuCheckboxItem,\n type ContextMenuCheckboxItemEmits,\n type ContextMenuCheckboxItemProps,\n ContextMenuItemIndicator,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuCheckboxItemProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<ContextMenuCheckboxItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ContextMenuCheckboxItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <ContextMenuItemIndicator>\n <Check class=\"h-4 w-4\" />\n </ContextMenuItemIndicator>\n </span>\n <slot />\n </ContextMenuCheckboxItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n ContextMenuContent,\n type ContextMenuContentEmits,\n type ContextMenuContentProps,\n ContextMenuPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<ContextMenuContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ContextMenuPortal>\n <ContextMenuContent\n v-bind=\"forwarded\"\n :class=\"cn(\n 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\"\n >\n <slot />\n </ContextMenuContent>\n </ContextMenuPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ContextMenuGroup, type ContextMenuGroupProps } from 'reka-ui'\n\nconst props = defineProps<ContextMenuGroupProps>()\n</script>\n\n<template>\n <ContextMenuGroup v-bind=\"props\">\n <slot />\n </ContextMenuGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n ContextMenuItem,\n type ContextMenuItemEmits,\n type ContextMenuItemProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuItemProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\nconst emits = defineEmits<ContextMenuItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ContextMenuItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n </ContextMenuItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ContextMenuLabel, type ContextMenuLabelProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuLabelProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ContextMenuLabel\n v-bind=\"delegatedProps\"\n :class=\"\n cn('px-2 py-1.5 text-sm font-semibold text-foreground',\n inset && 'pl-8', props.class,\n )\"\n >\n <slot />\n </ContextMenuLabel>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuPortal.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ContextMenuPortal, type ContextMenuPortalProps } from 'reka-ui'\n\nconst props = defineProps<ContextMenuPortalProps>()\n</script>\n\n<template>\n <ContextMenuPortal v-bind=\"props\">\n <slot />\n </ContextMenuPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuRadioGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenuRadioGroup,\n type ContextMenuRadioGroupEmits,\n type ContextMenuRadioGroupProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<ContextMenuRadioGroupProps>()\nconst emits = defineEmits<ContextMenuRadioGroupEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <ContextMenuRadioGroup v-bind=\"forwarded\">\n <slot />\n </ContextMenuRadioGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuRadioItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Circle } from 'lucide-vue-next'\nimport {\n ContextMenuItemIndicator,\n ContextMenuRadioItem,\n type ContextMenuRadioItemEmits,\n type ContextMenuRadioItemProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuRadioItemProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<ContextMenuRadioItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ContextMenuRadioItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <ContextMenuItemIndicator>\n <Circle class=\"h-2 w-2 fill-current\" />\n </ContextMenuItemIndicator>\n </span>\n <slot />\n </ContextMenuRadioItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n ContextMenuSeparator,\n type ContextMenuSeparatorProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuSeparatorProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ContextMenuSeparator v-bind=\"delegatedProps\" :class=\"cn('-mx-1 my-1 h-px bg-border', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuShortcut.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span :class=\"cn('ml-auto text-xs tracking-widest text-muted-foreground', props.class)\">\n <slot />\n </span>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuSub.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenuSub,\n type ContextMenuSubEmits,\n type ContextMenuSubProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<ContextMenuSubProps>()\nconst emits = defineEmits<ContextMenuSubEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <ContextMenuSub v-bind=\"forwarded\">\n <slot />\n </ContextMenuSub>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuSubContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n ContextMenuSubContent,\n type DropdownMenuSubContentEmits,\n type DropdownMenuSubContentProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuSubContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<DropdownMenuSubContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ContextMenuSubContent\n v-bind=\"forwarded\"\n :class=\"\n cn(\n 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </ContextMenuSubContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuSubTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronRight } from 'lucide-vue-next'\nimport {\n ContextMenuSubTrigger,\n type ContextMenuSubTriggerProps,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ContextMenuSubTriggerProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\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 <ContextMenuSubTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n <ChevronRight class=\"ml-auto h-4 w-4\" />\n </ContextMenuSubTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/ContextMenuTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ContextMenuTrigger, type ContextMenuTriggerProps, useForwardProps } from 'reka-ui'\n\nconst props = defineProps<ContextMenuTriggerProps>()\n\nconst forwardedProps = useForwardProps(props)\n</script>\n\n<template>\n <ContextMenuTrigger v-bind=\"forwardedProps\">\n <slot />\n </ContextMenuTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/context-menu/index.ts",
|
|
"content": "export { default as ContextMenu } from './ContextMenu.vue'\nexport { default as ContextMenuCheckboxItem } from './ContextMenuCheckboxItem.vue'\nexport { default as ContextMenuContent } from './ContextMenuContent.vue'\nexport { default as ContextMenuGroup } from './ContextMenuGroup.vue'\nexport { default as ContextMenuItem } from './ContextMenuItem.vue'\nexport { default as ContextMenuLabel } from './ContextMenuLabel.vue'\nexport { default as ContextMenuRadioGroup } from './ContextMenuRadioGroup.vue'\nexport { default as ContextMenuRadioItem } from './ContextMenuRadioItem.vue'\nexport { default as ContextMenuSeparator } from './ContextMenuSeparator.vue'\nexport { default as ContextMenuShortcut } from './ContextMenuShortcut.vue'\nexport { default as ContextMenuSub } from './ContextMenuSub.vue'\nexport { default as ContextMenuSubContent } from './ContextMenuSubContent.vue'\nexport { default as ContextMenuSubTrigger } from './ContextMenuSubTrigger.vue'\nexport { default as ContextMenuTrigger } from './ContextMenuTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "dialog",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/dialog/Dialog.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DialogRoot, type DialogRootEmits, type DialogRootProps, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<DialogRootProps>()\nconst emits = defineEmits<DialogRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DialogRoot v-bind=\"forwarded\">\n <slot />\n </DialogRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogClose.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DialogClose, type DialogCloseProps } from 'reka-ui'\n\nconst props = defineProps<DialogCloseProps>()\n</script>\n\n<template>\n <DialogClose v-bind=\"props\">\n <slot />\n </DialogClose>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { X } from 'lucide-vue-next'\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<DialogContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay\n class=\"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n />\n <DialogContent\n v-bind=\"forwarded\"\n :class=\"\n cn(\n 'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',\n props.class,\n )\"\n >\n <slot />\n\n <DialogClose\n class=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground\"\n >\n <X class=\"w-4 h-4\" />\n <span class=\"sr-only\">Close</span>\n </DialogClose>\n </DialogContent>\n </DialogPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogDescription.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DialogDescription, type DialogDescriptionProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogDescriptionProps & { 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 <DialogDescription\n v-bind=\"forwardedProps\"\n :class=\"cn('text-sm text-muted-foreground', props.class)\"\n >\n <slot />\n </DialogDescription>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: HTMLAttributes['class'] }>()\n</script>\n\n<template>\n <div\n :class=\"\n cn(\n 'flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-x-2',\n props.class,\n )\n \"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n :class=\"cn('flex flex-col gap-y-1.5 text-center sm:text-left', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogScrollContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { X } from 'lucide-vue-next'\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<DialogContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay\n class=\"fixed inset-0 z-50 grid place-items-center overflow-y-auto bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n >\n <DialogContent\n :class=\"\n cn(\n 'relative z-50 grid w-full max-w-lg my-8 gap-4 border border-border bg-background p-6 shadow-lg duration-200 sm:rounded-lg md:w-full',\n props.class,\n )\n \"\n v-bind=\"forwarded\"\n @pointer-down-outside=\"(event) => {\n const originalEvent = event.detail.originalEvent;\n const target = originalEvent.target as HTMLElement;\n if (originalEvent.offsetX > target.clientWidth || originalEvent.offsetY > target.clientHeight) {\n event.preventDefault();\n }\n }\"\n >\n <slot />\n\n <DialogClose\n class=\"absolute top-3 right-3 p-0.5 transition-colors rounded-md hover:bg-secondary\"\n >\n <X class=\"w-4 h-4\" />\n <span class=\"sr-only\">Close</span>\n </DialogClose>\n </DialogContent>\n </DialogOverlay>\n </DialogPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DialogTitle, type DialogTitleProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogTitleProps & { 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 <DialogTitle\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'text-lg font-semibold leading-none tracking-tight',\n props.class,\n )\n \"\n >\n <slot />\n </DialogTitle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/DialogTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DialogTrigger, type DialogTriggerProps } from 'reka-ui'\n\nconst props = defineProps<DialogTriggerProps>()\n</script>\n\n<template>\n <DialogTrigger v-bind=\"props\">\n <slot />\n </DialogTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dialog/index.ts",
|
|
"content": "export { default as Dialog } from './Dialog.vue'\nexport { default as DialogClose } from './DialogClose.vue'\nexport { default as DialogContent } from './DialogContent.vue'\nexport { default as DialogDescription } from './DialogDescription.vue'\nexport { default as DialogFooter } from './DialogFooter.vue'\nexport { default as DialogHeader } from './DialogHeader.vue'\nexport { default as DialogScrollContent } from './DialogScrollContent.vue'\nexport { default as DialogTitle } from './DialogTitle.vue'\nexport { default as DialogTrigger } from './DialogTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "drawer",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"vaul-vue",
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/drawer/Drawer.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { DrawerRootEmits, DrawerRootProps } from 'vaul-vue'\nimport { useForwardPropsEmits } from 'reka-ui'\nimport { DrawerRoot } from 'vaul-vue'\n\nconst props = withDefaults(defineProps<DrawerRootProps>(), {\n shouldScaleBackground: true,\n})\n\nconst emits = defineEmits<DrawerRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DrawerRoot v-bind=\"forwarded\">\n <slot />\n </DrawerRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/DrawerContent.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { DialogContentEmits, DialogContentProps } from 'reka-ui'\nimport type { HtmlHTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { useForwardPropsEmits } from 'reka-ui'\nimport { DrawerContent, DrawerPortal } from 'vaul-vue'\nimport DrawerOverlay from './DrawerOverlay.vue'\n\nconst props = defineProps<DialogContentProps & { class?: HtmlHTMLAttributes['class'] }>()\nconst emits = defineEmits<DialogContentEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DrawerPortal>\n <DrawerOverlay />\n <DrawerContent\n v-bind=\"forwarded\" :class=\"cn(\n 'fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background',\n props.class,\n )\"\n >\n <div class=\"mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted\" />\n <slot />\n </DrawerContent>\n </DrawerPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/DrawerDescription.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { DrawerDescriptionProps } from 'vaul-vue'\nimport { cn } from '@/lib/utils'\nimport { DrawerDescription } from 'vaul-vue'\nimport { computed, type HtmlHTMLAttributes } from 'vue'\n\nconst props = defineProps<DrawerDescriptionProps & { class?: HtmlHTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DrawerDescription v-bind=\"delegatedProps\" :class=\"cn('text-sm text-muted-foreground', props.class)\">\n <slot />\n </DrawerDescription>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/DrawerFooter.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HtmlHTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HtmlHTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('mt-auto flex flex-col gap-2 p-4', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/DrawerHeader.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HtmlHTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HtmlHTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('grid gap-1.5 p-4 text-center sm:text-left', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/DrawerOverlay.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { DialogOverlayProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { DrawerOverlay } from 'vaul-vue'\nimport { computed, type HtmlHTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogOverlayProps & { class?: HtmlHTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DrawerOverlay v-bind=\"delegatedProps\" :class=\"cn('fixed inset-0 z-50 bg-black/80', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/DrawerTitle.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { DrawerTitleProps } from 'vaul-vue'\nimport { cn } from '@/lib/utils'\nimport { DrawerTitle } from 'vaul-vue'\nimport { computed, type HtmlHTMLAttributes } from 'vue'\n\nconst props = defineProps<DrawerTitleProps & { class?: HtmlHTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DrawerTitle v-bind=\"delegatedProps\" :class=\"cn('text-lg font-semibold leading-none tracking-tight', props.class)\">\n <slot />\n </DrawerTitle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/drawer/index.ts",
|
|
"content": "export { default as Drawer } from './Drawer.vue'\nexport { default as DrawerContent } from './DrawerContent.vue'\nexport { default as DrawerDescription } from './DrawerDescription.vue'\nexport { default as DrawerFooter } from './DrawerFooter.vue'\nexport { default as DrawerHeader } from './DrawerHeader.vue'\nexport { default as DrawerOverlay } from './DrawerOverlay.vue'\nexport { default as DrawerTitle } from './DrawerTitle.vue'\nexport { DrawerClose, DrawerPortal, DrawerTrigger } from 'vaul-vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "dropdown-menu",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenu.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DropdownMenuRoot, type DropdownMenuRootEmits, type DropdownMenuRootProps, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<DropdownMenuRootProps>()\nconst emits = defineEmits<DropdownMenuRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DropdownMenuRoot v-bind=\"forwarded\">\n <slot />\n </DropdownMenuRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuCheckboxItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Check } from 'lucide-vue-next'\nimport {\n DropdownMenuCheckboxItem,\n type DropdownMenuCheckboxItemEmits,\n type DropdownMenuCheckboxItemProps,\n DropdownMenuItemIndicator,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuCheckboxItemProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<DropdownMenuCheckboxItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DropdownMenuCheckboxItem\n v-bind=\"forwarded\"\n :class=\" cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuItemIndicator>\n <Check class=\"w-4 h-4\" />\n </DropdownMenuItemIndicator>\n </span>\n <slot />\n </DropdownMenuCheckboxItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n DropdownMenuContent,\n type DropdownMenuContentEmits,\n type DropdownMenuContentProps,\n DropdownMenuPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(\n defineProps<DropdownMenuContentProps & { class?: HTMLAttributes['class'] }>(),\n {\n sideOffset: 4,\n },\n)\nconst emits = defineEmits<DropdownMenuContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DropdownMenuPortal>\n <DropdownMenuContent\n v-bind=\"forwarded\"\n :class=\"cn('z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', props.class)\"\n >\n <slot />\n </DropdownMenuContent>\n </DropdownMenuPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DropdownMenuGroup, type DropdownMenuGroupProps } from 'reka-ui'\n\nconst props = defineProps<DropdownMenuGroupProps>()\n</script>\n\n<template>\n <DropdownMenuGroup v-bind=\"props\">\n <slot />\n </DropdownMenuGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DropdownMenuItem, type DropdownMenuItemProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuItemProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\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 <DropdownMenuItem\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm gap-2 px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n </DropdownMenuItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DropdownMenuLabel, type DropdownMenuLabelProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuLabelProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\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 <DropdownMenuLabel\n v-bind=\"forwardedProps\"\n :class=\"cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', props.class)\"\n >\n <slot />\n </DropdownMenuLabel>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuRadioGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenuRadioGroup,\n type DropdownMenuRadioGroupEmits,\n type DropdownMenuRadioGroupProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<DropdownMenuRadioGroupProps>()\nconst emits = defineEmits<DropdownMenuRadioGroupEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DropdownMenuRadioGroup v-bind=\"forwarded\">\n <slot />\n </DropdownMenuRadioGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuRadioItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Circle } from 'lucide-vue-next'\nimport {\n DropdownMenuItemIndicator,\n DropdownMenuRadioItem,\n type DropdownMenuRadioItemEmits,\n type DropdownMenuRadioItemProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuRadioItemProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<DropdownMenuRadioItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DropdownMenuRadioItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuItemIndicator>\n <Circle class=\"h-2 w-2 fill-current\" />\n </DropdownMenuItemIndicator>\n </span>\n <slot />\n </DropdownMenuRadioItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n DropdownMenuSeparator,\n type DropdownMenuSeparatorProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuSeparatorProps & {\n class?: HTMLAttributes['class']\n}>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DropdownMenuSeparator v-bind=\"delegatedProps\" :class=\"cn('-mx-1 my-1 h-px bg-muted', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuShortcut.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span :class=\"cn('ml-auto text-xs tracking-widest opacity-60', props.class)\">\n <slot />\n </span>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuSub.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenuSub,\n type DropdownMenuSubEmits,\n type DropdownMenuSubProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<DropdownMenuSubProps>()\nconst emits = defineEmits<DropdownMenuSubEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DropdownMenuSub v-bind=\"forwarded\">\n <slot />\n </DropdownMenuSub>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuSubContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n DropdownMenuSubContent,\n type DropdownMenuSubContentEmits,\n type DropdownMenuSubContentProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuSubContentProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<DropdownMenuSubContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DropdownMenuSubContent\n v-bind=\"forwarded\"\n :class=\"cn('z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', props.class)\"\n >\n <slot />\n </DropdownMenuSubContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuSubTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronRight } from 'lucide-vue-next'\nimport {\n DropdownMenuSubTrigger,\n type DropdownMenuSubTriggerProps,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DropdownMenuSubTriggerProps & { 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 <DropdownMenuSubTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent',\n props.class,\n )\"\n >\n <slot />\n <ChevronRight class=\"ml-auto h-4 w-4\" />\n </DropdownMenuSubTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/DropdownMenuTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DropdownMenuTrigger, type DropdownMenuTriggerProps, useForwardProps } from 'reka-ui'\n\nconst props = defineProps<DropdownMenuTriggerProps>()\n\nconst forwardedProps = useForwardProps(props)\n</script>\n\n<template>\n <DropdownMenuTrigger class=\"outline-none\" v-bind=\"forwardedProps\">\n <slot />\n </DropdownMenuTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/dropdown-menu/index.ts",
|
|
"content": "export { default as DropdownMenu } from './DropdownMenu.vue'\n\nexport { default as DropdownMenuCheckboxItem } from './DropdownMenuCheckboxItem.vue'\nexport { default as DropdownMenuContent } from './DropdownMenuContent.vue'\nexport { default as DropdownMenuGroup } from './DropdownMenuGroup.vue'\nexport { default as DropdownMenuItem } from './DropdownMenuItem.vue'\nexport { default as DropdownMenuLabel } from './DropdownMenuLabel.vue'\nexport { default as DropdownMenuRadioGroup } from './DropdownMenuRadioGroup.vue'\nexport { default as DropdownMenuRadioItem } from './DropdownMenuRadioItem.vue'\nexport { default as DropdownMenuSeparator } from './DropdownMenuSeparator.vue'\nexport { default as DropdownMenuShortcut } from './DropdownMenuShortcut.vue'\nexport { default as DropdownMenuSub } from './DropdownMenuSub.vue'\nexport { default as DropdownMenuSubContent } from './DropdownMenuSubContent.vue'\nexport { default as DropdownMenuSubTrigger } from './DropdownMenuSubTrigger.vue'\nexport { default as DropdownMenuTrigger } from './DropdownMenuTrigger.vue'\nexport { DropdownMenuPortal } from 'reka-ui'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "form",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui",
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/form/FormControl.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { Slot } from 'reka-ui'\nimport { useFormField } from './useFormField'\n\nconst { error, formItemId, formDescriptionId, formMessageId } = useFormField()\n</script>\n\n<template>\n <Slot\n :id=\"formItemId\"\n :aria-describedby=\"!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`\"\n :aria-invalid=\"!!error\"\n >\n <slot />\n </Slot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/form/FormDescription.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { useFormField } from './useFormField'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst { formDescriptionId } = useFormField()\n</script>\n\n<template>\n <p\n :id=\"formDescriptionId\"\n :class=\"cn('text-sm text-muted-foreground', props.class)\"\n >\n <slot />\n </p>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/form/FormItem.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { useId } from 'reka-ui'\nimport { type HTMLAttributes, provide } from 'vue'\nimport { FORM_ITEM_INJECTION_KEY } from './injectionKeys'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst id = useId()\nprovide(FORM_ITEM_INJECTION_KEY, id)\n</script>\n\n<template>\n <div :class=\"cn('space-y-2', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/form/FormLabel.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/form/FormMessage.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { ErrorMessage } from 'vee-validate'\nimport { toValue } from 'vue'\nimport { useFormField } from './useFormField'\n\nconst { name, formMessageId } = useFormField()\n</script>\n\n<template>\n <ErrorMessage\n :id=\"formMessageId\"\n as=\"p\"\n :name=\"toValue(name)\"\n class=\"text-sm font-medium text-destructive\"\n />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/form/index.ts",
|
|
"content": "export { default as FormControl } from './FormControl.vue'\nexport { default as FormDescription } from './FormDescription.vue'\nexport { default as FormItem } from './FormItem.vue'\nexport { default as FormLabel } from './FormLabel.vue'\nexport { default as FormMessage } from './FormMessage.vue'\nexport { FORM_ITEM_INJECTION_KEY } from './injectionKeys'\nexport { Field as FormField, Form } from 'vee-validate'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/form/injectionKeys.ts",
|
|
"content": "import type { InjectionKey } from 'vue'\n\nexport const FORM_ITEM_INJECTION_KEY\n = Symbol() as InjectionKey<string>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/form/useFormField.ts",
|
|
"content": "import { FieldContextKey, useFieldError, useIsFieldDirty, useIsFieldTouched, useIsFieldValid } from 'vee-validate'\nimport { inject } from 'vue'\nimport { FORM_ITEM_INJECTION_KEY } from './injectionKeys'\n\nexport function useFormField() {\n const fieldContext = inject(FieldContextKey)\n const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY)\n\n if (!fieldContext)\n throw new Error('useFormField should be used within <FormField>')\n\n const { name } = fieldContext\n const id = fieldItemContext\n\n const fieldState = {\n valid: useIsFieldValid(name),\n isDirty: useIsFieldDirty(name),\n isTouched: useIsFieldTouched(name),\n error: useFieldError(name),\n }\n\n return {\n id,\n name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n }\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "hover-card",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/hover-card/HoverCard.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { HoverCardRoot, type HoverCardRootEmits, type HoverCardRootProps, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<HoverCardRootProps>()\nconst emits = defineEmits<HoverCardRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <HoverCardRoot v-bind=\"forwarded\">\n <slot />\n </HoverCardRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/hover-card/HoverCardContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n HoverCardContent,\n type HoverCardContentProps,\n HoverCardPortal,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(\n defineProps<HoverCardContentProps & { class?: HTMLAttributes['class'] }>(),\n {\n sideOffset: 4,\n },\n)\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 <HoverCardPortal>\n <HoverCardContent\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </HoverCardContent>\n </HoverCardPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/hover-card/HoverCardTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { HoverCardTrigger, type HoverCardTriggerProps } from 'reka-ui'\n\nconst props = defineProps<HoverCardTriggerProps>()\n</script>\n\n<template>\n <HoverCardTrigger v-bind=\"props\">\n <slot />\n </HoverCardTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/hover-card/index.ts",
|
|
"content": "export { default as HoverCard } from './HoverCard.vue'\nexport { default as HoverCardContent } from './HoverCardContent.vue'\nexport { default as HoverCardTrigger } from './HoverCardTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "input",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/input/Input.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { useVModel } from '@vueuse/core'\n\nconst props = defineProps<{\n defaultValue?: string | number\n modelValue?: string | number\n class?: HTMLAttributes['class']\n}>()\n\nconst emits = defineEmits<{\n (e: 'update:modelValue', payload: string | number): void\n}>()\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n passive: true,\n defaultValue: props.defaultValue,\n})\n</script>\n\n<template>\n <input v-model=\"modelValue\" :class=\"cn('flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', props.class)\">\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/input/index.ts",
|
|
"content": "export { default as Input } from './Input.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "label",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/label/Label.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Label, type LabelProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<LabelProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <Label\n v-bind=\"delegatedProps\"\n :class=\"\n cn(\n 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',\n props.class,\n )\n \"\n >\n <slot />\n </Label>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/label/index.ts",
|
|
"content": "export { default as Label } from './Label.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "menubar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/menubar/Menubar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n MenubarRoot,\n type MenubarRootEmits,\n type MenubarRootProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<MenubarRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <MenubarRoot\n v-bind=\"forwarded\"\n :class=\"\n cn(\n 'flex h-10 items-center gap-x-1 rounded-md border bg-background p-1',\n props.class,\n )\n \"\n >\n <slot />\n </MenubarRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarCheckboxItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Check } from 'lucide-vue-next'\nimport {\n MenubarCheckboxItem,\n type MenubarCheckboxItemEmits,\n type MenubarCheckboxItemProps,\n MenubarItemIndicator,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarCheckboxItemProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<MenubarCheckboxItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <MenubarCheckboxItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <MenubarItemIndicator>\n <Check class=\"w-4 h-4\" />\n </MenubarItemIndicator>\n </span>\n <slot />\n </MenubarCheckboxItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n MenubarContent,\n type MenubarContentProps,\n MenubarPortal,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(\n defineProps<MenubarContentProps & { class?: HTMLAttributes['class'] }>(),\n {\n align: 'start',\n alignOffset: -4,\n sideOffset: 8,\n },\n)\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 <MenubarPortal>\n <MenubarContent\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'z-50 min-w-48 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </MenubarContent>\n </MenubarPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { MenubarGroup, type MenubarGroupProps } from 'reka-ui'\n\nconst props = defineProps<MenubarGroupProps>()\n</script>\n\n<template>\n <MenubarGroup v-bind=\"props\">\n <slot />\n </MenubarGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n MenubarItem,\n type MenubarItemEmits,\n type MenubarItemProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarItemProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\n\nconst emits = defineEmits<MenubarItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <MenubarItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n </MenubarItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { MenubarLabel, type MenubarLabelProps } from 'reka-ui'\n\nconst props = defineProps<MenubarLabelProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\n</script>\n\n<template>\n <MenubarLabel :class=\"cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', props.class)\">\n <slot />\n </MenubarLabel>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarMenu.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { MenubarMenu, type MenubarMenuProps } from 'reka-ui'\n\nconst props = defineProps<MenubarMenuProps>()\n</script>\n\n<template>\n <MenubarMenu v-bind=\"props\">\n <slot />\n </MenubarMenu>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarRadioGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n MenubarRadioGroup,\n type MenubarRadioGroupEmits,\n type MenubarRadioGroupProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<MenubarRadioGroupProps>()\n\nconst emits = defineEmits<MenubarRadioGroupEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <MenubarRadioGroup v-bind=\"forwarded\">\n <slot />\n </MenubarRadioGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarRadioItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Circle } from 'lucide-vue-next'\nimport {\n MenubarItemIndicator,\n MenubarRadioItem,\n type MenubarRadioItemEmits,\n type MenubarRadioItemProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarRadioItemProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<MenubarRadioItemEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <MenubarRadioItem\n v-bind=\"forwarded\"\n :class=\"cn(\n 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <MenubarItemIndicator>\n <Circle class=\"h-2 w-2 fill-current\" />\n </MenubarItemIndicator>\n </span>\n <slot />\n </MenubarRadioItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { MenubarSeparator, type MenubarSeparatorProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarSeparatorProps & { 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 <MenubarSeparator :class=\" cn('-mx-1 my-1 h-px bg-muted', props.class)\" v-bind=\"forwardedProps\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarShortcut.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span :class=\"cn('ml-auto text-xs tracking-widest text-muted-foreground', props.class)\">\n <slot />\n </span>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarSub.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { MenubarSub, type MenubarSubEmits, useForwardPropsEmits } from 'reka-ui'\n\ninterface MenubarSubRootProps {\n defaultOpen?: boolean\n open?: boolean\n}\n\nconst props = defineProps<MenubarSubRootProps>()\nconst emits = defineEmits<MenubarSubEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <MenubarSub v-bind=\"forwarded\">\n <slot />\n </MenubarSub>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarSubContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n MenubarPortal,\n MenubarSubContent,\n type MenubarSubContentEmits,\n type MenubarSubContentProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarSubContentProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<MenubarSubContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <MenubarPortal>\n <MenubarSubContent\n v-bind=\"forwarded\"\n :class=\"\n cn(\n 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </MenubarSubContent>\n </MenubarPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarSubTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronRight } from 'lucide-vue-next'\nimport { MenubarSubTrigger, type MenubarSubTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarSubTriggerProps & { class?: HTMLAttributes['class'], inset?: boolean }>()\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 <MenubarSubTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',\n inset && 'pl-8',\n props.class,\n )\"\n >\n <slot />\n <ChevronRight class=\"ml-auto h-4 w-4\" />\n </MenubarSubTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/MenubarTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { MenubarTrigger, type MenubarTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<MenubarTriggerProps & { 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 <MenubarTrigger\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',\n props.class,\n )\n \"\n >\n <slot />\n </MenubarTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/menubar/index.ts",
|
|
"content": "export { default as Menubar } from './Menubar.vue'\nexport { default as MenubarCheckboxItem } from './MenubarCheckboxItem.vue'\nexport { default as MenubarContent } from './MenubarContent.vue'\nexport { default as MenubarGroup } from './MenubarGroup.vue'\nexport { default as MenubarItem } from './MenubarItem.vue'\nexport { default as MenubarLabel } from './MenubarLabel.vue'\nexport { default as MenubarMenu } from './MenubarMenu.vue'\nexport { default as MenubarRadioGroup } from './MenubarRadioGroup.vue'\nexport { default as MenubarRadioItem } from './MenubarRadioItem.vue'\nexport { default as MenubarSeparator } from './MenubarSeparator.vue'\nexport { default as MenubarShortcut } from './MenubarShortcut.vue'\nexport { default as MenubarSub } from './MenubarSub.vue'\nexport { default as MenubarSubContent } from './MenubarSubContent.vue'\nexport { default as MenubarSubTrigger } from './MenubarSubTrigger.vue'\nexport { default as MenubarTrigger } from './MenubarTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "navigation-menu",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenu.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n NavigationMenuRoot,\n type NavigationMenuRootEmits,\n type NavigationMenuRootProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport NavigationMenuViewport from './NavigationMenuViewport.vue'\n\nconst props = defineProps<NavigationMenuRootProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<NavigationMenuRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <NavigationMenuRoot\n v-bind=\"forwarded\"\n :class=\"cn('relative z-10 flex max-w-max flex-1 items-center justify-center', props.class)\"\n >\n <slot />\n <NavigationMenuViewport />\n </NavigationMenuRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n NavigationMenuContent,\n type NavigationMenuContentEmits,\n type NavigationMenuContentProps,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NavigationMenuContentProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<NavigationMenuContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <NavigationMenuContent\n v-bind=\"forwarded\"\n :class=\"cn(\n 'left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto',\n props.class,\n )\"\n >\n <slot />\n </NavigationMenuContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuIndicator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { NavigationMenuIndicator, type NavigationMenuIndicatorProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NavigationMenuIndicatorProps & { 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 <NavigationMenuIndicator\n v-bind=\"forwardedProps\"\n :class=\"cn('top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in', props.class)\"\n >\n <div class=\"relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md\" />\n </NavigationMenuIndicator>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { NavigationMenuItem, type NavigationMenuItemProps } from 'reka-ui'\n\nconst props = defineProps<NavigationMenuItemProps>()\n</script>\n\n<template>\n <NavigationMenuItem v-bind=\"props\">\n <slot />\n </NavigationMenuItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuLink.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n NavigationMenuLink,\n type NavigationMenuLinkEmits,\n type NavigationMenuLinkProps,\n useForwardPropsEmits,\n} from 'reka-ui'\n\nconst props = defineProps<NavigationMenuLinkProps>()\nconst emits = defineEmits<NavigationMenuLinkEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <NavigationMenuLink v-bind=\"forwarded\">\n <slot />\n </NavigationMenuLink>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuList.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { NavigationMenuList, type NavigationMenuListProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NavigationMenuListProps & { 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 <NavigationMenuList\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'group flex flex-1 list-none items-center justify-center gap-x-1',\n props.class,\n )\n \"\n >\n <slot />\n </NavigationMenuList>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronDown } from 'lucide-vue-next'\nimport {\n NavigationMenuTrigger,\n type NavigationMenuTriggerProps,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { navigationMenuTriggerStyle } from '.'\n\nconst props = defineProps<NavigationMenuTriggerProps & { 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 <NavigationMenuTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(navigationMenuTriggerStyle(), 'group', props.class)\"\n >\n <slot />\n <ChevronDown\n class=\"relative top-px ml-1 h-3 w-3 transition duration-200 group-data-[state=open]:rotate-180\"\n aria-hidden=\"true\"\n />\n </NavigationMenuTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/NavigationMenuViewport.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n NavigationMenuViewport,\n type NavigationMenuViewportProps,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NavigationMenuViewportProps & { 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 <div class=\"absolute left-0 top-full flex justify-center\">\n <NavigationMenuViewport\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'origin-top-center relative mt-1.5 h-[--reka-navigation-menu-viewport-height] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[--reka-navigation-menu-viewport-width]',\n props.class,\n )\n \"\n />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/navigation-menu/index.ts",
|
|
"content": "import { cva } from 'class-variance-authority'\n\nexport { default as NavigationMenu } from './NavigationMenu.vue'\nexport { default as NavigationMenuContent } from './NavigationMenuContent.vue'\nexport { default as NavigationMenuItem } from './NavigationMenuItem.vue'\nexport { default as NavigationMenuLink } from './NavigationMenuLink.vue'\nexport { default as NavigationMenuList } from './NavigationMenuList.vue'\nexport { default as NavigationMenuTrigger } from './NavigationMenuTrigger.vue'\nexport { default as NavigationMenuViewport } from './NavigationMenuViewport.vue'\n\nexport const navigationMenuTriggerStyle = cva(\n 'group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50',\n)\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "number-field",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/number-field/NumberField.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { NumberFieldRootEmits, NumberFieldRootProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { NumberFieldRoot, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NumberFieldRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<NumberFieldRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <NumberFieldRoot v-bind=\"forwarded\" :class=\"cn('grid gap-1.5', props.class)\">\n <slot />\n </NumberFieldRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/number-field/NumberFieldContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div :class=\"cn('relative [&>[data-slot=input]]:has-[[data-slot=increment]]:pr-5 [&>[data-slot=input]]:has-[[data-slot=decrement]]:pl-5', props.class)\">\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/number-field/NumberFieldDecrement.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { NumberFieldDecrementProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { Minus } from 'lucide-vue-next'\nimport { NumberFieldDecrement, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NumberFieldDecrementProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <NumberFieldDecrement data-slot=\"decrement\" v-bind=\"forwarded\" :class=\"cn('absolute top-1/2 -translate-y-1/2 left-0 p-3 disabled:cursor-not-allowed disabled:opacity-20', props.class)\">\n <slot>\n <Minus class=\"h-4 w-4\" />\n </slot>\n </NumberFieldDecrement>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/number-field/NumberFieldIncrement.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { NumberFieldIncrementProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { Plus } from 'lucide-vue-next'\nimport { NumberFieldIncrement, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<NumberFieldIncrementProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <NumberFieldIncrement data-slot=\"increment\" v-bind=\"forwarded\" :class=\"cn('absolute top-1/2 -translate-y-1/2 right-0 disabled:cursor-not-allowed disabled:opacity-20 p-3', props.class)\">\n <slot>\n <Plus class=\"h-4 w-4\" />\n </slot>\n </NumberFieldIncrement>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/number-field/NumberFieldInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { NumberFieldInput } from 'reka-ui'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <NumberFieldInput\n data-slot=\"input\"\n :class=\"cn('flex h-10 w-full rounded-md border border-input bg-background py-2 text-sm text-center ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', props.class)\"\n />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/number-field/index.ts",
|
|
"content": "export { default as NumberField } from './NumberField.vue'\nexport { default as NumberFieldContent } from './NumberFieldContent.vue'\nexport { default as NumberFieldDecrement } from './NumberFieldDecrement.vue'\nexport { default as NumberFieldIncrement } from './NumberFieldIncrement.vue'\nexport { default as NumberFieldInput } from './NumberFieldInput.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "pagination",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/pagination/PaginationEllipsis.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { MoreHorizontal } from 'lucide-vue-next'\nimport { PaginationEllipsis, type PaginationEllipsisProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<PaginationEllipsisProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <PaginationEllipsis v-bind=\"delegatedProps\" :class=\"cn('w-9 h-9 flex items-center justify-center', props.class)\">\n <slot>\n <MoreHorizontal />\n </slot>\n </PaginationEllipsis>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pagination/PaginationFirst.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/pagination/PaginationLast.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/pagination/PaginationNext.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/pagination/PaginationPrev.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/pagination/index.ts",
|
|
"content": "export { default as PaginationEllipsis } from './PaginationEllipsis.vue'\nexport { default as PaginationFirst } from './PaginationFirst.vue'\nexport { default as PaginationLast } from './PaginationLast.vue'\nexport { default as PaginationNext } from './PaginationNext.vue'\nexport { default as PaginationPrev } from './PaginationPrev.vue'\nexport {\n PaginationList,\n PaginationListItem,\n PaginationRoot as Pagination,\n} from 'reka-ui'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "pin-input",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/pin-input/PinInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { PinInputRoot, type PinInputRootEmits, type PinInputRootProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<PinInputRootProps & { class?: HTMLAttributes['class'] }>(), {\n modelValue: () => [],\n})\nconst emits = defineEmits<PinInputRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <PinInputRoot v-bind=\"forwarded\" :class=\"cn('flex gap-2 items-center', props.class)\">\n <slot />\n </PinInputRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pin-input/PinInputGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<PrimitiveProps & { class?: HTMLAttributes['class'] }>()\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <Primitive v-bind=\"forwardedProps\" :class=\"cn('flex items-center', props.class)\">\n <slot />\n </primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pin-input/PinInputInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { PinInputInput, type PinInputInputProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<PinInputInputProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <PinInputInput v-bind=\"forwardedProps\" :class=\"cn('relative text-center focus:outline-none focus:ring-2 focus:ring-ring focus:relative focus:z-10 flex h-10 w-10 items-center justify-center border-y border-r border-input text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pin-input/PinInputSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Dot } from 'lucide-vue-next'\nimport { Primitive, type PrimitiveProps, useForwardProps } from 'reka-ui'\n\nconst props = defineProps<PrimitiveProps>()\nconst forwardedProps = useForwardProps(props)\n</script>\n\n<template>\n <Primitive v-bind=\"forwardedProps\">\n <slot>\n <Dot />\n </slot>\n </primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/pin-input/index.ts",
|
|
"content": "export { default as PinInput } from './PinInput.vue'\nexport { default as PinInputGroup } from './PinInputGroup.vue'\nexport { default as PinInputInput } from './PinInputInput.vue'\nexport { default as PinInputSeparator } from './PinInputSeparator.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "popover",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/popover/Popover.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { PopoverRootEmits, PopoverRootProps } from 'reka-ui'\nimport { PopoverRoot, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<PopoverRootProps>()\nconst emits = defineEmits<PopoverRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <PopoverRoot v-bind=\"forwarded\">\n <slot />\n </PopoverRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/popover/PopoverContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n PopoverContent,\n type PopoverContentEmits,\n type PopoverContentProps,\n PopoverPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(\n defineProps<PopoverContentProps & { class?: HTMLAttributes['class'] }>(),\n {\n align: 'center',\n sideOffset: 4,\n },\n)\nconst emits = defineEmits<PopoverContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <PopoverPortal>\n <PopoverContent\n v-bind=\"{ ...forwarded, ...$attrs }\"\n :class=\"\n cn(\n 'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n props.class,\n )\n \"\n >\n <slot />\n </PopoverContent>\n </PopoverPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/popover/PopoverTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { PopoverTrigger, type PopoverTriggerProps } from 'reka-ui'\n\nconst props = defineProps<PopoverTriggerProps>()\n</script>\n\n<template>\n <PopoverTrigger v-bind=\"props\">\n <slot />\n </PopoverTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/popover/index.ts",
|
|
"content": "export { default as Popover } from './Popover.vue'\nexport { default as PopoverContent } from './PopoverContent.vue'\nexport { default as PopoverTrigger } from './PopoverTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "progress",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/progress/Progress.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n ProgressIndicator,\n ProgressRoot,\n type ProgressRootProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(\n defineProps<ProgressRootProps & { class?: HTMLAttributes['class'] }>(),\n {\n modelValue: 0,\n },\n)\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ProgressRoot\n v-bind=\"delegatedProps\"\n :class=\"\n cn(\n 'relative h-4 w-full overflow-hidden rounded-full bg-secondary',\n props.class,\n )\n \"\n >\n <ProgressIndicator\n class=\"h-full w-full flex-1 bg-primary transition-all\"\n :style=\"`transform: translateX(-${100 - (props.modelValue ?? 0)}%);`\"\n />\n </ProgressRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/progress/index.ts",
|
|
"content": "export { default as Progress } from './Progress.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "radio-group",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/radio-group/RadioGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { RadioGroupRoot, type RadioGroupRootEmits, type RadioGroupRootProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RadioGroupRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<RadioGroupRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <RadioGroupRoot\n :class=\"cn('grid gap-2', props.class)\"\n v-bind=\"forwarded\"\n >\n <slot />\n </RadioGroupRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/radio-group/RadioGroupItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Circle } from 'lucide-vue-next'\nimport {\n RadioGroupIndicator,\n RadioGroupItem,\n type RadioGroupItemProps,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RadioGroupItemProps & { 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 <RadioGroupItem\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n props.class,\n )\n \"\n >\n <RadioGroupIndicator\n class=\"flex items-center justify-center\"\n >\n <Circle class=\"h-2.5 w-2.5 fill-current text-current\" />\n </RadioGroupIndicator>\n </RadioGroupItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/radio-group/index.ts",
|
|
"content": "export { default as RadioGroup } from './RadioGroup.vue'\nexport { default as RadioGroupItem } from './RadioGroupItem.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "range-calendar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendar.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarRoot, type RangeCalendarRootEmits, type RangeCalendarRootProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { RangeCalendarCell, RangeCalendarCellTrigger, RangeCalendarGrid, RangeCalendarGridBody, RangeCalendarGridHead, RangeCalendarGridRow, RangeCalendarHeadCell, RangeCalendarHeader, RangeCalendarHeading, RangeCalendarNextButton, RangeCalendarPrevButton } from '.'\n\nconst props = defineProps<RangeCalendarRootProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<RangeCalendarRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <RangeCalendarRoot\n v-slot=\"{ grid, weekDays }\"\n :class=\"cn('p-3', props.class)\"\n v-bind=\"forwarded\"\n >\n <RangeCalendarHeader>\n <RangeCalendarPrevButton />\n <RangeCalendarHeading />\n <RangeCalendarNextButton />\n </RangeCalendarHeader>\n\n <div class=\"flex flex-col gap-y-4 mt-4 sm:flex-row sm:gap-x-4 sm:gap-y-0\">\n <RangeCalendarGrid v-for=\"month in grid\" :key=\"month.value.toString()\">\n <RangeCalendarGridHead>\n <RangeCalendarGridRow>\n <RangeCalendarHeadCell\n v-for=\"day in weekDays\" :key=\"day\"\n >\n {{ day }}\n </RangeCalendarHeadCell>\n </RangeCalendarGridRow>\n </RangeCalendarGridHead>\n <RangeCalendarGridBody>\n <RangeCalendarGridRow v-for=\"(weekDates, index) in month.rows\" :key=\"`weekDate-${index}`\" class=\"mt-2 w-full\">\n <RangeCalendarCell\n v-for=\"weekDate in weekDates\"\n :key=\"weekDate.toString()\"\n :date=\"weekDate\"\n >\n <RangeCalendarCellTrigger\n :day=\"weekDate\"\n :month=\"month.value\"\n />\n </RangeCalendarCell>\n </RangeCalendarGridRow>\n </RangeCalendarGridBody>\n </RangeCalendarGrid>\n </div>\n </RangeCalendarRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarCell.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarCell, type RangeCalendarCellProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarCellProps & { 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 <RangeCalendarCell\n :class=\"cn('relative h-9 w-9 p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([data-selected])]:bg-accent first:[&:has([data-selected])]:rounded-l-md last:[&:has([data-selected])]:rounded-r-md [&:has([data-selected][data-outside-view])]:bg-accent/50 [&:has([data-selected][data-selection-end])]:rounded-r-md [&:has([data-selected][data-selection-start])]:rounded-l-md', props.class)\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </RangeCalendarCell>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarCellTrigger.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarGrid.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarGrid, type RangeCalendarGridProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarGridProps & { 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 <RangeCalendarGrid\n :class=\"cn('w-full border-collapse space-y-1', props.class)\"\n v-bind=\"forwardedProps\"\n >\n <slot />\n </RangeCalendarGrid>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarGridBody.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { RangeCalendarGridBody, type RangeCalendarGridBodyProps } from 'reka-ui'\n\nconst props = defineProps<RangeCalendarGridBodyProps>()\n</script>\n\n<template>\n <RangeCalendarGridBody v-bind=\"props\">\n <slot />\n </RangeCalendarGridBody>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarGridHead.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { RangeCalendarGridHead, type RangeCalendarGridHeadProps } from 'reka-ui'\n\nconst props = defineProps<RangeCalendarGridHeadProps>()\n</script>\n\n<template>\n <RangeCalendarGridHead v-bind=\"props\">\n <slot />\n </RangeCalendarGridHead>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarGridRow.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarGridRow, type RangeCalendarGridRowProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarGridRowProps & { 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 <RangeCalendarGridRow :class=\"cn('flex mt-2 w-full', props.class)\" v-bind=\"forwardedProps\">\n <slot />\n </RangeCalendarGridRow>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarHeadCell.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarHeadCell, type RangeCalendarHeadCellProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarHeadCellProps & { 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 <RangeCalendarHeadCell :class=\"cn('w-9 rounded-md text-[0.8rem] font-normal text-muted-foreground', props.class)\" v-bind=\"forwardedProps\">\n <slot />\n </RangeCalendarHeadCell>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarHeader.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarHeader, type RangeCalendarHeaderProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarHeaderProps & { 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 <RangeCalendarHeader :class=\"cn('relative flex w-full items-center justify-between pt-1', props.class)\" v-bind=\"forwardedProps\">\n <slot />\n </RangeCalendarHeader>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarHeading.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { cn } from '@/lib/utils'\nimport { RangeCalendarHeading, type RangeCalendarHeadingProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<RangeCalendarHeadingProps & { 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 <RangeCalendarHeading\n v-slot=\"{ headingValue }\"\n :class=\"cn('text-sm font-medium', props.class)\"\n v-bind=\"forwardedProps\"\n >\n <slot :heading-value>\n {{ headingValue }}\n </slot>\n </RangeCalendarHeading>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarNextButton.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/RangeCalendarPrevButton.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/range-calendar/index.ts",
|
|
"content": "export { default as RangeCalendar } from './RangeCalendar.vue'\nexport { default as RangeCalendarCell } from './RangeCalendarCell.vue'\nexport { default as RangeCalendarCellTrigger } from './RangeCalendarCellTrigger.vue'\nexport { default as RangeCalendarGrid } from './RangeCalendarGrid.vue'\nexport { default as RangeCalendarGridBody } from './RangeCalendarGridBody.vue'\nexport { default as RangeCalendarGridHead } from './RangeCalendarGridHead.vue'\nexport { default as RangeCalendarGridRow } from './RangeCalendarGridRow.vue'\nexport { default as RangeCalendarHeadCell } from './RangeCalendarHeadCell.vue'\nexport { default as RangeCalendarHeader } from './RangeCalendarHeader.vue'\nexport { default as RangeCalendarHeading } from './RangeCalendarHeading.vue'\nexport { default as RangeCalendarNextButton } from './RangeCalendarNextButton.vue'\nexport { default as RangeCalendarPrevButton } from './RangeCalendarPrevButton.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "resizable",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/resizable/ResizableHandle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { GripVertical } from 'lucide-vue-next'\nimport { SplitterResizeHandle, type SplitterResizeHandleEmits, type SplitterResizeHandleProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SplitterResizeHandleProps & { class?: HTMLAttributes['class'], withHandle?: boolean }>()\nconst emits = defineEmits<SplitterResizeHandleEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SplitterResizeHandle v-bind=\"forwarded\" :class=\"cn('relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 [&[data-orientation=vertical]]:h-px [&[data-orientation=vertical]]:w-full [&[data-orientation=vertical]]:after:left-0 [&[data-orientation=vertical]]:after:h-1 [&[data-orientation=vertical]]:after:w-full [&[data-orientation=vertical]]:after:-translate-y-1/2 [&[data-orientation=vertical]]:after:translate-x-0 [&[data-orientation=vertical]>div]:rotate-90', props.class)\">\n <template v-if=\"props.withHandle\">\n <div class=\"z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border\">\n <GripVertical class=\"h-2.5 w-2.5\" />\n </div>\n </template>\n </SplitterResizeHandle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/resizable/ResizablePanelGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { SplitterGroup, type SplitterGroupEmits, type SplitterGroupProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SplitterGroupProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<SplitterGroupEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SplitterGroup v-bind=\"forwarded\" :class=\"cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', props.class)\">\n <slot />\n </SplitterGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/resizable/index.ts",
|
|
"content": "export { default as ResizableHandle } from './ResizableHandle.vue'\nexport { default as ResizablePanelGroup } from './ResizablePanelGroup.vue'\nexport { SplitterPanel as ResizablePanel } from 'reka-ui'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "scroll-area",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/scroll-area/ScrollArea.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n ScrollAreaCorner,\n ScrollAreaRoot,\n type ScrollAreaRootProps,\n ScrollAreaViewport,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport ScrollBar from './ScrollBar.vue'\n\nconst props = defineProps<ScrollAreaRootProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ScrollAreaRoot v-bind=\"delegatedProps\" :class=\"cn('relative overflow-hidden', props.class)\">\n <ScrollAreaViewport class=\"h-full w-full rounded-[inherit]\">\n <slot />\n </ScrollAreaViewport>\n <ScrollBar />\n <ScrollAreaCorner />\n </ScrollAreaRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/scroll-area/ScrollBar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ScrollAreaScrollbar, type ScrollAreaScrollbarProps, ScrollAreaThumb } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = withDefaults(defineProps<ScrollAreaScrollbarProps & { class?: HTMLAttributes['class'] }>(), {\n orientation: 'vertical',\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ScrollAreaScrollbar\n v-bind=\"delegatedProps\"\n :class=\"\n cn('flex touch-none select-none transition-colors',\n orientation === 'vertical'\n && 'h-full w-2.5 border-l border-l-transparent p-px',\n orientation === 'horizontal'\n && 'h-2.5 flex-col border-t border-t-transparent p-px',\n props.class)\"\n >\n <ScrollAreaThumb class=\"relative flex-1 rounded-full bg-border\" />\n </ScrollAreaScrollbar>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/scroll-area/index.ts",
|
|
"content": "export { default as ScrollArea } from './ScrollArea.vue'\nexport { default as ScrollBar } from './ScrollBar.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "select",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/select/Select.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { SelectRootEmits, SelectRootProps } from 'reka-ui'\nimport { SelectRoot, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<SelectRootProps>()\nconst emits = defineEmits<SelectRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <SelectRoot v-bind=\"forwarded\">\n <slot />\n </SelectRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n SelectContent,\n type SelectContentEmits,\n type SelectContentProps,\n SelectPortal,\n SelectViewport,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { SelectScrollDownButton, SelectScrollUpButton } from '.'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(\n defineProps<SelectContentProps & { class?: HTMLAttributes['class'] }>(),\n {\n position: 'popper',\n },\n)\nconst emits = defineEmits<SelectContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SelectPortal>\n <SelectContent\n v-bind=\"{ ...forwarded, ...$attrs }\" :class=\"cn(\n 'relative z-50 max-h-96 min-w-32 overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n position === 'popper'\n && 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',\n props.class,\n )\n \"\n >\n <SelectScrollUpButton />\n <SelectViewport :class=\"cn('p-1', position === 'popper' && 'h-[--reka-select-trigger-height] w-full min-w-[--reka-select-trigger-width]')\">\n <slot />\n </SelectViewport>\n <SelectScrollDownButton />\n </SelectContent>\n </SelectPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { SelectGroup, type SelectGroupProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SelectGroupProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <SelectGroup :class=\"cn('p-1 w-full', props.class)\" v-bind=\"delegatedProps\">\n <slot />\n </SelectGroup>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Check } from 'lucide-vue-next'\nimport {\n SelectItem,\n SelectItemIndicator,\n type SelectItemProps,\n SelectItemText,\n useForwardProps,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SelectItemProps & { 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 <SelectItem\n v-bind=\"forwardedProps\"\n :class=\"\n cn(\n 'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n props.class,\n )\n \"\n >\n <span class=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectItemIndicator>\n <Check class=\"h-4 w-4\" />\n </SelectItemIndicator>\n </span>\n\n <SelectItemText>\n <slot />\n </SelectItemText>\n </SelectItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectItemText.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { SelectItemText, type SelectItemTextProps } from 'reka-ui'\n\nconst props = defineProps<SelectItemTextProps>()\n</script>\n\n<template>\n <SelectItemText v-bind=\"props\">\n <slot />\n </SelectItemText>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { SelectLabel, type SelectLabelProps } from 'reka-ui'\n\nconst props = defineProps<SelectLabelProps & { class?: HTMLAttributes['class'] }>()\n</script>\n\n<template>\n <SelectLabel :class=\"cn('py-1.5 pl-8 pr-2 text-sm font-semibold', props.class)\">\n <slot />\n </SelectLabel>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectScrollDownButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronDown } from 'lucide-vue-next'\nimport { SelectScrollDownButton, type SelectScrollDownButtonProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SelectScrollDownButtonProps & { 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 <SelectScrollDownButton v-bind=\"forwardedProps\" :class=\"cn('flex cursor-default items-center justify-center py-1', props.class)\">\n <slot>\n <ChevronDown class=\"h-4 w-4\" />\n </slot>\n </SelectScrollDownButton>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectScrollUpButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronUp } from 'lucide-vue-next'\nimport { SelectScrollUpButton, type SelectScrollUpButtonProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SelectScrollUpButtonProps & { 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 <SelectScrollUpButton v-bind=\"forwardedProps\" :class=\"cn('flex cursor-default items-center justify-center py-1', props.class)\">\n <slot>\n <ChevronUp class=\"h-4 w-4\" />\n </slot>\n </SelectScrollUpButton>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { SelectSeparator, type SelectSeparatorProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SelectSeparatorProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <SelectSeparator v-bind=\"delegatedProps\" :class=\"cn('-mx-1 my-1 h-px bg-muted', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ChevronDown } from 'lucide-vue-next'\nimport { SelectIcon, SelectTrigger, type SelectTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SelectTriggerProps & { 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 <SelectTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:truncate text-start',\n props.class,\n )\"\n >\n <slot />\n <SelectIcon as-child>\n <ChevronDown class=\"w-4 h-4 opacity-50 shrink-0\" />\n </SelectIcon>\n </SelectTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/SelectValue.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { SelectValue, type SelectValueProps } from 'reka-ui'\n\nconst props = defineProps<SelectValueProps>()\n</script>\n\n<template>\n <SelectValue v-bind=\"props\">\n <slot />\n </SelectValue>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/select/index.ts",
|
|
"content": "export { default as Select } from './Select.vue'\nexport { default as SelectContent } from './SelectContent.vue'\nexport { default as SelectGroup } from './SelectGroup.vue'\nexport { default as SelectItem } from './SelectItem.vue'\nexport { default as SelectItemText } from './SelectItemText.vue'\nexport { default as SelectLabel } from './SelectLabel.vue'\nexport { default as SelectScrollDownButton } from './SelectScrollDownButton.vue'\nexport { default as SelectScrollUpButton } from './SelectScrollUpButton.vue'\nexport { default as SelectSeparator } from './SelectSeparator.vue'\nexport { default as SelectTrigger } from './SelectTrigger.vue'\nexport { default as SelectValue } from './SelectValue.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "separator",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/separator/Separator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Separator, type SeparatorProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<\n SeparatorProps & { class?: HTMLAttributes['class'], label?: string }\n>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <Separator\n v-bind=\"delegatedProps\"\n :class=\"\n cn(\n 'shrink-0 bg-border relative',\n props.orientation === 'vertical' ? 'w-px h-full' : 'h-px w-full',\n props.class,\n )\n \"\n >\n <span\n v-if=\"props.label\"\n :class=\"cn('text-xs text-muted-foreground bg-background absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex justify-center items-center',\n props.orientation === 'vertical' ? 'w-[1px] px-1 py-2' : 'h-[1px] py-1 px-2',\n )\"\n >{{ props.label }}</span>\n </Separator>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/separator/index.ts",
|
|
"content": "export { default as Separator } from './Separator.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "sheet",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/sheet/Sheet.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DialogRoot, type DialogRootEmits, type DialogRootProps, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<DialogRootProps>()\nconst emits = defineEmits<DialogRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <DialogRoot v-bind=\"forwarded\">\n <slot />\n </DialogRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetClose.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DialogClose, type DialogCloseProps } from 'reka-ui'\n\nconst props = defineProps<DialogCloseProps>()\n</script>\n\n<template>\n <DialogClose v-bind=\"props\">\n <slot />\n </DialogClose>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { X } from 'lucide-vue-next'\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { type SheetVariants, sheetVariants } from '.'\n\ninterface SheetContentProps extends DialogContentProps {\n class?: HTMLAttributes['class']\n side?: SheetVariants['side']\n}\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = defineProps<SheetContentProps>()\n\nconst emits = defineEmits<DialogContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, side, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay\n class=\"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n />\n <DialogContent\n :class=\"cn(sheetVariants({ side }), props.class)\"\n v-bind=\"{ ...forwarded, ...$attrs }\"\n >\n <slot />\n\n <DialogClose\n class=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary\"\n >\n <X class=\"w-4 h-4 text-muted-foreground\" />\n </DialogClose>\n </DialogContent>\n </DialogPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetDescription.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DialogDescription, type DialogDescriptionProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DialogDescription\n :class=\"cn('text-sm text-muted-foreground', props.class)\"\n v-bind=\"delegatedProps\"\n >\n <slot />\n </DialogDescription>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: HTMLAttributes['class'] }>()\n</script>\n\n<template>\n <div\n :class=\"\n cn(\n 'flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-x-2',\n props.class,\n )\n \"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{ class?: HTMLAttributes['class'] }>()\n</script>\n\n<template>\n <div\n :class=\"\n cn('flex flex-col gap-y-2 text-center sm:text-left', props.class)\n \"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { DialogTitle, type DialogTitleProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<DialogTitleProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <DialogTitle\n :class=\"cn('text-lg font-semibold text-foreground', props.class)\"\n v-bind=\"delegatedProps\"\n >\n <slot />\n </DialogTitle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/SheetTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DialogTrigger, type DialogTriggerProps } from 'reka-ui'\n\nconst props = defineProps<DialogTriggerProps>()\n</script>\n\n<template>\n <DialogTrigger v-bind=\"props\">\n <slot />\n </DialogTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sheet/index.ts",
|
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Sheet } from './Sheet.vue'\nexport { default as SheetClose } from './SheetClose.vue'\nexport { default as SheetContent } from './SheetContent.vue'\nexport { default as SheetDescription } from './SheetDescription.vue'\nexport { default as SheetFooter } from './SheetFooter.vue'\nexport { default as SheetHeader } from './SheetHeader.vue'\nexport { default as SheetTitle } from './SheetTitle.vue'\nexport { default as SheetTrigger } from './SheetTrigger.vue'\n\nexport const sheetVariants = cva(\n 'fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500',\n {\n variants: {\n side: {\n top: 'inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',\n bottom:\n 'inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',\n left: 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm',\n right:\n 'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm',\n },\n },\n defaultVariants: {\n side: 'right',\n },\n },\n)\n\nexport type SheetVariants = VariantProps<typeof sheetVariants>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "sidebar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui",
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"sheet",
|
|
"input",
|
|
"tooltip",
|
|
"skeleton",
|
|
"separator",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/sidebar/Sidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Sheet, SheetContent } from '@/registry/default/ui/sheet'\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": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"content\"\n :class=\"cn('flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"footer\"\n :class=\"cn('flex flex-col gap-2 p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"group\"\n :class=\"cn('relative flex w-full min-w-0 flex-col p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarGroupAction.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive } from 'reka-ui'\n\nconst props = defineProps<PrimitiveProps & {\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"group-action\"\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn(\n 'absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 after:md:hidden',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarGroupContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"group-content\"\n :class=\"cn('w-full text-sm', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarGroupLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive } from 'reka-ui'\n\nconst props = defineProps<PrimitiveProps & {\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"group-label\"\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn(\n 'duration-200 flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',\n props.class)\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"header\"\n :class=\"cn('flex flex-col gap-2 p-2', props.class)\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Input } from '@/registry/default/ui/input'\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": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarInset.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <main\n :class=\"cn(\n 'relative flex min-h-svh flex-1 flex-col bg-background',\n 'peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow',\n props.class,\n )\"\n >\n <slot />\n </main>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenu.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <ul\n data-sidebar=\"menu\"\n :class=\"cn('flex w-full min-w-0 flex-col gap-1', props.class)\"\n >\n <slot />\n </ul>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuAction.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps } from 'reka-ui'\n\nconst props = withDefaults(defineProps<PrimitiveProps & {\n showOnHover?: boolean\n class?: HTMLAttributes['class']\n}>(), {\n as: 'button',\n})\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"menu-action\"\n :class=\"cn(\n 'absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 after:md:hidden',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n showOnHover\n && 'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0',\n props.class,\n )\"\n :as=\"as\"\n :as-child=\"asChild\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuBadge.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div\n data-sidebar=\"menu-badge\"\n :class=\"cn(\n 'absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground select-none pointer-events-none',\n 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/registry/default/ui/tooltip'\nimport { type Component, computed } from 'vue'\nimport SidebarMenuButtonChild, { type SidebarMenuButtonProps } from './SidebarMenuButtonChild.vue'\nimport { useSidebar } from './utils'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<SidebarMenuButtonProps & {\n tooltip?: string | Component\n}>(), {\n as: 'button',\n variant: 'default',\n size: 'default',\n})\n\nconst { isMobile, state } = useSidebar()\n\nconst delegatedProps = computed(() => {\n const { tooltip, ...delegated } = props\n return delegated\n})\n</script>\n\n<template>\n <SidebarMenuButtonChild v-if=\"!tooltip\" v-bind=\"{ ...delegatedProps, ...$attrs }\">\n <slot />\n </SidebarMenuButtonChild>\n\n <Tooltip v-else>\n <TooltipTrigger as-child>\n <SidebarMenuButtonChild v-bind=\"{ ...delegatedProps, ...$attrs }\">\n <slot />\n </SidebarMenuButtonChild>\n </TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n :hidden=\"state !== 'collapsed' || isMobile\"\n >\n <template v-if=\"typeof tooltip === 'string'\">\n {{ tooltip }}\n </template>\n <component :is=\"tooltip\" v-else />\n </TooltipContent>\n </Tooltip>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuButtonChild.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive, type PrimitiveProps } from 'reka-ui'\nimport { type SidebarMenuButtonVariants, sidebarMenuButtonVariants } from '.'\n\nexport interface SidebarMenuButtonProps extends PrimitiveProps {\n variant?: SidebarMenuButtonVariants['variant']\n size?: SidebarMenuButtonVariants['size']\n isActive?: boolean\n class?: HTMLAttributes['class']\n}\n\nconst props = withDefaults(defineProps<SidebarMenuButtonProps>(), {\n as: 'button',\n variant: 'default',\n size: 'default',\n})\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"menu-button\"\n :data-size=\"size\"\n :data-active=\"isActive\"\n :class=\"cn(sidebarMenuButtonVariants({ variant, size }), props.class)\"\n :as=\"as\"\n :as-child=\"asChild\"\n v-bind=\"$attrs\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n data-sidebar=\"menu-item\"\n :class=\"cn('group/menu-item relative', props.class)\"\n >\n <slot />\n </li>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuSkeleton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Skeleton } from '@/registry/default/ui/skeleton'\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": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuSub.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <ul\n data-sidebar=\"menu-badge\"\n :class=\"cn(\n 'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </ul>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuSubButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { PrimitiveProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Primitive } from 'reka-ui'\n\nconst props = withDefaults(defineProps<PrimitiveProps & {\n size?: 'sm' | 'md'\n isActive?: boolean\n class?: HTMLAttributes['class']\n}>(), {\n as: 'a',\n size: 'md',\n})\n</script>\n\n<template>\n <Primitive\n data-sidebar=\"menu-sub-button\"\n :as=\"as\"\n :as-child=\"asChild\"\n :data-size=\"size\"\n :data-active=\"isActive\"\n :class=\"cn(\n 'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',\n 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n 'group-data-[collapsible=icon]:hidden',\n props.class,\n )\"\n >\n <slot />\n </Primitive>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarMenuSubItem.vue",
|
|
"content": "<script setup lang=\"ts\">\n</script>\n\n<template>\n <li>\n <slot />\n </li>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarProvider.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { useEventListener, useMediaQuery, useVModel } from '@vueuse/core'\nimport { TooltipProvider } from 'reka-ui'\nimport { computed, type HTMLAttributes, type Ref, ref } from 'vue'\nimport { provideSidebarContext, SIDEBAR_COOKIE_MAX_AGE, SIDEBAR_COOKIE_NAME, SIDEBAR_KEYBOARD_SHORTCUT, SIDEBAR_WIDTH, SIDEBAR_WIDTH_ICON } from './utils'\n\nconst props = withDefaults(defineProps<{\n defaultOpen?: boolean\n open?: boolean\n class?: HTMLAttributes['class']\n}>(), {\n defaultOpen: true,\n open: undefined,\n})\n\nconst emits = defineEmits<{\n 'update:open': [open: boolean]\n}>()\n\nconst isMobile = useMediaQuery('(max-width: 768px)')\nconst openMobile = ref(false)\n\nconst open = useVModel(props, 'open', emits, {\n defaultValue: props.defaultOpen ?? false,\n passive: (props.open === undefined) as false,\n}) as Ref<boolean>\n\nfunction setOpen(value: boolean) {\n open.value = value // emits('update:open', value)\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${open.value}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n}\n\nfunction setOpenMobile(value: boolean) {\n openMobile.value = value\n}\n\n// Helper to toggle the sidebar.\nfunction toggleSidebar() {\n return isMobile.value ? setOpenMobile(!openMobile.value) : setOpen(!open.value)\n}\n\nuseEventListener('keydown', (event: KeyboardEvent) => {\n if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n toggleSidebar()\n }\n})\n\n// We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n// This makes it easier to style the sidebar with Tailwind classes.\nconst state = computed(() => open.value ? 'expanded' : 'collapsed')\n\nprovideSidebarContext({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n})\n</script>\n\n<template>\n <TooltipProvider :delay-duration=\"0\">\n <div\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH,\n '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,\n }\"\n :class=\"cn('group/sidebar-wrapper flex min-h-svh w-full text-sidebar-foreground has-[[data-variant=inset]]:bg-sidebar', props.class)\"\n v-bind=\"$attrs\"\n >\n <slot />\n </div>\n </TooltipProvider>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarRail.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\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=\"rail\"\n aria-label=\"Toggle Sidebar\"\n :tabindex=\"-1\"\n title=\"Toggle Sidebar\"\n :class=\"cn(\n 'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex',\n '[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize',\n '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\n 'group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar',\n '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',\n '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',\n props.class,\n )\"\n @click=\"toggleSidebar\"\n >\n <slot />\n </button>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarSeparator.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Separator } from '@/registry/default/ui/separator'\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": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/SidebarTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\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": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/index.ts",
|
|
"content": "import type { HTMLAttributes } from 'vue'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nexport interface SidebarProps {\n side?: 'left' | 'right'\n variant?: 'sidebar' | 'floating' | 'inset'\n collapsible?: 'offcanvas' | 'icon' | 'none'\n class?: HTMLAttributes['class']\n}\n\nexport { default as Sidebar } from './Sidebar.vue'\nexport { default as SidebarContent } from './SidebarContent.vue'\nexport { default as SidebarFooter } from './SidebarFooter.vue'\nexport { default as SidebarGroup } from './SidebarGroup.vue'\nexport { default as SidebarGroupAction } from './SidebarGroupAction.vue'\nexport { default as SidebarGroupContent } from './SidebarGroupContent.vue'\nexport { default as SidebarGroupLabel } from './SidebarGroupLabel.vue'\nexport { default as SidebarHeader } from './SidebarHeader.vue'\nexport { default as SidebarInput } from './SidebarInput.vue'\nexport { default as SidebarInset } from './SidebarInset.vue'\nexport { default as SidebarMenu } from './SidebarMenu.vue'\nexport { default as SidebarMenuAction } from './SidebarMenuAction.vue'\nexport { default as SidebarMenuBadge } from './SidebarMenuBadge.vue'\nexport { default as SidebarMenuButton } from './SidebarMenuButton.vue'\nexport { default as SidebarMenuItem } from './SidebarMenuItem.vue'\nexport { default as SidebarMenuSkeleton } from './SidebarMenuSkeleton.vue'\nexport { default as SidebarMenuSub } from './SidebarMenuSub.vue'\nexport { default as SidebarMenuSubButton } from './SidebarMenuSubButton.vue'\nexport { default as SidebarMenuSubItem } from './SidebarMenuSubItem.vue'\nexport { default as SidebarProvider } from './SidebarProvider.vue'\nexport { default as SidebarRail } from './SidebarRail.vue'\nexport { default as SidebarSeparator } from './SidebarSeparator.vue'\nexport { default as SidebarTrigger } from './SidebarTrigger.vue'\n\nexport { useSidebar } from './utils'\n\nexport const sidebarMenuButtonVariants = cva(\n 'peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',\n {\n variants: {\n variant: {\n default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',\n outline:\n 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',\n },\n size: {\n default: 'h-8 text-sm',\n sm: 'h-7 text-xs',\n lg: 'h-12 text-sm group-data-[collapsible=icon]:!p-0',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type SidebarMenuButtonVariants = VariantProps<typeof sidebarMenuButtonVariants>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sidebar/utils.ts",
|
|
"content": "import type { ComputedRef, Ref } from 'vue'\nimport { createContext } from 'reka-ui'\n\nexport const SIDEBAR_COOKIE_NAME = 'sidebar:state'\nexport const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nexport const SIDEBAR_WIDTH = '16rem'\nexport const SIDEBAR_WIDTH_MOBILE = '18rem'\nexport const SIDEBAR_WIDTH_ICON = '3rem'\nexport const SIDEBAR_KEYBOARD_SHORTCUT = 'b'\n\nexport const [useSidebar, provideSidebarContext] = createContext<{\n state: ComputedRef<'expanded' | 'collapsed'>\n open: Ref<boolean>\n setOpen: (value: boolean) => void\n isMobile: Ref<boolean>\n openMobile: Ref<boolean>\n setOpenMobile: (value: boolean) => void\n toggleSidebar: () => void\n}>('Sidebar')\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "skeleton",
|
|
"type": "registry:ui",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/skeleton/Skeleton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\ninterface SkeletonProps {\n class?: HTMLAttributes['class']\n}\n\nconst props = defineProps<SkeletonProps>()\n</script>\n\n<template>\n <div :class=\"cn('animate-pulse rounded-md bg-muted', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/skeleton/index.ts",
|
|
"content": "export { default as Skeleton } from './Skeleton.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "slider",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/slider/Slider.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { SliderRootEmits, SliderRootProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { SliderRange, SliderRoot, SliderThumb, SliderTrack, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SliderRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<SliderRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SliderRoot\n :class=\"cn(\n 'relative flex w-full touch-none select-none items-center data-[orientation=vertical]:flex-col data-[orientation=vertical]:w-2 data-[orientation=vertical]:h-full',\n props.class,\n )\"\n v-bind=\"forwarded\"\n >\n <SliderTrack class=\"relative h-2 w-full data-[orientation=vertical]:w-2 grow overflow-hidden rounded-full bg-secondary\">\n <SliderRange class=\"absolute h-full data-[orientation=vertical]:w-full bg-primary\" />\n </SliderTrack>\n <SliderThumb\n v-for=\"(_, key) in modelValue\"\n :key=\"key\"\n class=\"block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\"\n />\n </SliderRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/slider/index.ts",
|
|
"content": "export { default as Slider } from './Slider.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "sonner",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"vue-sonner"
|
|
],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "ui/sonner/Sonner.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { Toaster as Sonner, type ToasterProps } from 'vue-sonner'\n\nconst props = defineProps<ToasterProps>()\n</script>\n\n<template>\n <Sonner\n class=\"toaster group\"\n v-bind=\"props\"\n :toast-options=\"{\n classes: {\n toast: 'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg',\n description: 'group-[.toast]:text-muted-foreground',\n actionButton:\n 'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',\n cancelButton:\n 'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',\n },\n }\"\n />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/sonner/index.ts",
|
|
"content": "export { default as Toaster } from './Sonner.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "stepper",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/stepper/Stepper.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperRootEmits, StepperRootProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperRoot, useForwardPropsEmits } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<StepperRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <StepperRoot\n v-slot=\"slotProps\"\n :class=\"cn(\n 'flex gap-2',\n props.class,\n )\"\n v-bind=\"forwarded\"\n >\n <slot v-bind=\"slotProps\" />\n </StepperRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/StepperDescription.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperDescriptionProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperDescription, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperDescriptionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <StepperDescription v-slot=\"slotProps\" v-bind=\"forwarded\" :class=\"cn('text-xs text-muted-foreground', props.class)\">\n <slot v-bind=\"slotProps\" />\n </StepperDescription>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/StepperIndicator.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperIndicatorProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperIndicator, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperIndicatorProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <StepperIndicator\n v-bind=\"forwarded\"\n :class=\"cn(\n 'inline-flex items-center justify-center rounded-full text-muted-foreground/50 w-10 h-10',\n // Disabled\n 'group-data-[disabled]:text-muted-foreground group-data-[disabled]:opacity-50',\n // Active\n 'group-data-[state=active]:bg-primary group-data-[state=active]:text-primary-foreground',\n // Completed\n 'group-data-[state=completed]:bg-accent group-data-[state=completed]:text-accent-foreground',\n props.class,\n )\"\n >\n <slot />\n </StepperIndicator>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/StepperItem.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperItemProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperItem, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperItemProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <StepperItem\n v-slot=\"slotProps\"\n v-bind=\"forwarded\"\n :class=\"cn('flex items-center gap-2 group data-[disabled]:pointer-events-none', props.class)\"\n >\n <slot v-bind=\"slotProps\" />\n </StepperItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/StepperSeparator.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperSeparatorProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperSeparator, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperSeparatorProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <StepperSeparator\n v-bind=\"forwarded\"\n :class=\"cn(\n 'bg-muted',\n // Disabled\n 'group-data-[disabled]:bg-muted group-data-[disabled]:opacity-50',\n // Completed\n 'group-data-[state=completed]:bg-accent-foreground',\n props.class,\n )\"\n />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/StepperTitle.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperTitleProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperTitle, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperTitleProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <StepperTitle v-bind=\"forwarded\" :class=\"cn('text-md font-semibold whitespace-nowrap', props.class)\">\n <slot />\n </StepperTitle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/StepperTrigger.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { StepperTriggerProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { StepperTrigger, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<StepperTriggerProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardProps(delegatedProps)\n</script>\n\n<template>\n <StepperTrigger\n v-bind=\"forwarded\"\n :class=\"cn('p-2 flex flex-col items-center text-center gap-2 rounded-md', props.class)\"\n >\n <slot />\n </StepperTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/stepper/index.ts",
|
|
"content": "export { default as Stepper } from './Stepper.vue'\nexport { default as StepperDescription } from './StepperDescription.vue'\nexport { default as StepperIndicator } from './StepperIndicator.vue'\nexport { default as StepperItem } from './StepperItem.vue'\nexport { default as StepperSeparator } from './StepperSeparator.vue'\nexport { default as StepperTitle } from './StepperTitle.vue'\nexport { default as StepperTrigger } from './StepperTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "switch",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/switch/Switch.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n SwitchRoot,\n type SwitchRootEmits,\n type SwitchRootProps,\n SwitchThumb,\n useForwardPropsEmits,\n} from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SwitchRootProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<SwitchRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SwitchRoot\n v-bind=\"forwarded\"\n :class=\"cn(\n 'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',\n props.class,\n )\"\n >\n <SwitchThumb\n :class=\"cn('pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5')\"\n >\n <slot name=\"thumb\" />\n </SwitchThumb>\n </SwitchRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/switch/index.ts",
|
|
"content": "export { default as Switch } from './Switch.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "table",
|
|
"type": "registry:ui",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/table/Table.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <div class=\"relative w-full overflow-auto\">\n <table :class=\"cn('w-full caption-bottom text-sm', props.class)\">\n <slot />\n </table>\n </div>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableBody.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <tbody :class=\"cn('[&_tr:last-child]:border-0', props.class)\">\n <slot />\n </tbody>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableCaption.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <caption :class=\"cn('mt-4 text-sm text-muted-foreground', props.class)\">\n <slot />\n </caption>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableCell.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <td\n :class=\"\n cn(\n 'p-4 align-middle [&:has([role=checkbox])]:pr-0',\n props.class,\n )\n \"\n >\n <slot />\n </td>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableEmpty.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { computed, type HTMLAttributes } from 'vue'\nimport TableCell from './TableCell.vue'\nimport TableRow from './TableRow.vue'\n\nconst props = withDefaults(defineProps<{\n class?: HTMLAttributes['class']\n colspan?: number\n}>(), {\n colspan: 1,\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <TableRow>\n <TableCell\n :class=\"\n cn(\n 'p-4 whitespace-nowrap align-middle text-sm text-foreground',\n props.class,\n )\n \"\n v-bind=\"delegatedProps\"\n >\n <div class=\"flex items-center justify-center py-10\">\n <slot />\n </div>\n </TableCell>\n </TableRow>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <tfoot :class=\"cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', props.class)\">\n <slot />\n </tfoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableHead.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <th :class=\"cn('h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0', props.class)\">\n <slot />\n </th>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <thead :class=\"cn('[&_tr]:border-b', props.class)\">\n <slot />\n </thead>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/TableRow.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <tr :class=\"cn('border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted', props.class)\">\n <slot />\n </tr>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/table/index.ts",
|
|
"content": "export { default as Table } from './Table.vue'\nexport { default as TableBody } from './TableBody.vue'\nexport { default as TableCaption } from './TableCaption.vue'\nexport { default as TableCell } from './TableCell.vue'\nexport { default as TableEmpty } from './TableEmpty.vue'\nexport { default as TableFooter } from './TableFooter.vue'\nexport { default as TableHead } from './TableHead.vue'\nexport { default as TableHeader } from './TableHeader.vue'\nexport { default as TableRow } from './TableRow.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "tabs",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/tabs/Tabs.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { TabsRootEmits, TabsRootProps } from 'reka-ui'\nimport { TabsRoot, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<TabsRootProps>()\nconst emits = defineEmits<TabsRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <TabsRoot v-bind=\"forwarded\">\n <slot />\n </TabsRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tabs/TabsContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TabsContent, type TabsContentProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TabsContentProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <TabsContent\n :class=\"cn('mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2', props.class)\"\n v-bind=\"delegatedProps\"\n >\n <slot />\n </TabsContent>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tabs/TabsList.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TabsList, type TabsListProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TabsListProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <TabsList\n v-bind=\"delegatedProps\"\n :class=\"cn(\n 'inline-flex items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',\n props.class,\n )\"\n >\n <slot />\n </TabsList>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tabs/TabsTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TabsTrigger, type TabsTriggerProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TabsTriggerProps & { 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 <TabsTrigger\n v-bind=\"forwardedProps\"\n :class=\"cn(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm',\n props.class,\n )\"\n >\n <span class=\"truncate\">\n <slot />\n </span>\n </TabsTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tabs/index.ts",
|
|
"content": "export { default as Tabs } from './Tabs.vue'\nexport { default as TabsContent } from './TabsContent.vue'\nexport { default as TabsList } from './TabsList.vue'\nexport { default as TabsTrigger } from './TabsTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "tags-input",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/tags-input/TagsInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TagsInputRoot, type TagsInputRootEmits, type TagsInputRootProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TagsInputRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<TagsInputRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <TagsInputRoot v-bind=\"forwarded\" :class=\"cn('flex flex-wrap gap-2 items-center rounded-md border border-input bg-background px-3 py-2 text-sm', props.class)\">\n <slot />\n </TagsInputRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tags-input/TagsInputInput.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TagsInputInput, type TagsInputInputProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TagsInputInputProps & { 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 <TagsInputInput v-bind=\"forwardedProps\" :class=\"cn('text-sm min-h-6 focus:outline-none flex-1 bg-transparent px-1', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tags-input/TagsInputItem.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TagsInputItem, type TagsInputItemProps, useForwardProps } from 'reka-ui'\n\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TagsInputItemProps & { 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 <TagsInputItem v-bind=\"forwardedProps\" :class=\"cn('flex h-6 items-center rounded bg-secondary data-[state=active]:ring-ring data-[state=active]:ring-2 data-[state=active]:ring-offset-2 ring-offset-background', props.class)\">\n <slot />\n </TagsInputItem>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tags-input/TagsInputItemDelete.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { X } from 'lucide-vue-next'\nimport { TagsInputItemDelete, type TagsInputItemDeleteProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TagsInputItemDeleteProps & { 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 <TagsInputItemDelete v-bind=\"forwardedProps\" :class=\"cn('flex rounded bg-transparent mr-1', props.class)\">\n <slot>\n <X class=\"w-4 h-4\" />\n </slot>\n </TagsInputItemDelete>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tags-input/TagsInputItemText.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TagsInputItemText, type TagsInputItemTextProps, useForwardProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<TagsInputItemTextProps & { 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 <TagsInputItemText v-bind=\"forwardedProps\" :class=\"cn('py-1 px-2 text-sm rounded bg-transparent', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tags-input/index.ts",
|
|
"content": "export { default as TagsInput } from './TagsInput.vue'\nexport { default as TagsInputInput } from './TagsInputInput.vue'\nexport { default as TagsInputItem } from './TagsInputItem.vue'\nexport { default as TagsInputItemDelete } from './TagsInputItemDelete.vue'\nexport { default as TagsInputItemText } from './TagsInputItemText.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "textarea",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/textarea/Textarea.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { useVModel } from '@vueuse/core'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n defaultValue?: string | number\n modelValue?: string | number\n}>()\n\nconst emits = defineEmits<{\n (e: 'update:modelValue', payload: string | number): void\n}>()\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n passive: true,\n defaultValue: props.defaultValue,\n})\n</script>\n\n<template>\n <textarea v-model=\"modelValue\" :class=\"cn('flex min-h-20 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/textarea/index.ts",
|
|
"content": "export { default as Textarea } from './Textarea.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "toast",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/toast/Toast.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ToastRoot, type ToastRootEmits, useForwardPropsEmits } from 'reka-ui'\nimport { computed } from 'vue'\nimport { type ToastProps, toastVariants } from '.'\n\nconst props = defineProps<ToastProps>()\n\nconst emits = defineEmits<ToastRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ToastRoot\n v-bind=\"forwarded\"\n :class=\"cn(toastVariants({ variant }), props.class)\"\n @update:open=\"onOpenChange\"\n >\n <slot />\n </ToastRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/ToastAction.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ToastAction, type ToastActionProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ToastActionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ToastAction v-bind=\"delegatedProps\" :class=\"cn('inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive', props.class)\">\n <slot />\n </ToastAction>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/ToastClose.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { X } from 'lucide-vue-next'\nimport { ToastClose, type ToastCloseProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ToastCloseProps & {\n class?: HTMLAttributes['class']\n}>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ToastClose v-bind=\"delegatedProps\" :class=\"cn('absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600', props.class)\">\n <X class=\"h-4 w-4\" />\n </ToastClose>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/ToastDescription.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ToastDescription, type ToastDescriptionProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ToastDescriptionProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ToastDescription :class=\"cn('text-sm opacity-90', props.class)\" v-bind=\"delegatedProps\">\n <slot />\n </ToastDescription>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/ToastProvider.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToastProvider, type ToastProviderProps } from 'reka-ui'\n\nconst props = defineProps<ToastProviderProps>()\n</script>\n\n<template>\n <ToastProvider v-bind=\"props\">\n <slot />\n </ToastProvider>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/ToastTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ToastTitle, type ToastTitleProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ToastTitleProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ToastTitle v-bind=\"delegatedProps\" :class=\"cn('text-sm font-semibold', props.class)\">\n <slot />\n </ToastTitle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/ToastViewport.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { ToastViewport, type ToastViewportProps } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<ToastViewportProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n</script>\n\n<template>\n <ToastViewport v-bind=\"delegatedProps\" :class=\"cn('fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]', props.class)\" />\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/Toaster.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { isVNode } from 'vue'\nimport { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from '.'\nimport { useToast } from './use-toast'\n\nconst { toasts } = useToast()\n</script>\n\n<template>\n <ToastProvider>\n <Toast v-for=\"toast in toasts\" :key=\"toast.id\" v-bind=\"toast\">\n <div class=\"grid gap-1\">\n <ToastTitle v-if=\"toast.title\">\n {{ toast.title }}\n </ToastTitle>\n <template v-if=\"toast.description\">\n <ToastDescription v-if=\"isVNode(toast.description)\">\n <component :is=\"toast.description\" />\n </ToastDescription>\n <ToastDescription v-else>\n {{ toast.description }}\n </ToastDescription>\n </template>\n <ToastClose />\n </div>\n <component :is=\"toast.action\" />\n </Toast>\n <ToastViewport />\n </ToastProvider>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/index.ts",
|
|
"content": "import type { ToastRootProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\n\nexport { default as Toast } from './Toast.vue'\nexport { default as ToastAction } from './ToastAction.vue'\nexport { default as ToastClose } from './ToastClose.vue'\nexport { default as ToastDescription } from './ToastDescription.vue'\nexport { default as Toaster } from './Toaster.vue'\nexport { default as ToastProvider } from './ToastProvider.vue'\nexport { default as ToastTitle } from './ToastTitle.vue'\nexport { default as ToastViewport } from './ToastViewport.vue'\nexport { toast, useToast } from './use-toast'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nexport const toastVariants = cva(\n 'group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[--reka-toast-swipe-end-x] data-[swipe=move]:translate-x-[--reka-toast-swipe-move-x] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full',\n {\n variants: {\n variant: {\n default: 'border bg-background text-foreground',\n destructive:\n 'destructive group border-destructive bg-destructive text-destructive-foreground',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n)\n\ntype ToastVariants = VariantProps<typeof toastVariants>\n\nexport interface ToastProps extends ToastRootProps {\n class?: HTMLAttributes['class']\n variant?: ToastVariants['variant']\n onOpenChange?: ((value: boolean) => void) | undefined\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toast/use-toast.ts",
|
|
"content": "import type { Component, VNode } from 'vue'\nimport type { ToastProps } from '.'\nimport { computed, ref } from 'vue'\n\nconst TOAST_LIMIT = 1\nconst TOAST_REMOVE_DELAY = 1000000\n\nexport type StringOrVNode =\n | string\n | VNode\n | (() => VNode)\n\ntype ToasterToast = ToastProps & {\n id: string\n title?: string\n description?: StringOrVNode\n action?: Component\n}\n\nconst actionTypes = {\n ADD_TOAST: 'ADD_TOAST',\n UPDATE_TOAST: 'UPDATE_TOAST',\n DISMISS_TOAST: 'DISMISS_TOAST',\n REMOVE_TOAST: 'REMOVE_TOAST',\n} as const\n\nlet count = 0\n\nfunction genId() {\n count = (count + 1) % Number.MAX_VALUE\n return count.toString()\n}\n\ntype ActionType = typeof actionTypes\n\ntype Action =\n | {\n type: ActionType['ADD_TOAST']\n toast: ToasterToast\n }\n | {\n type: ActionType['UPDATE_TOAST']\n toast: Partial<ToasterToast>\n }\n | {\n type: ActionType['DISMISS_TOAST']\n toastId?: ToasterToast['id']\n }\n | {\n type: ActionType['REMOVE_TOAST']\n toastId?: ToasterToast['id']\n }\n\ninterface State {\n toasts: ToasterToast[]\n}\n\nconst toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()\n\nfunction addToRemoveQueue(toastId: string) {\n if (toastTimeouts.has(toastId))\n return\n\n const timeout = setTimeout(() => {\n toastTimeouts.delete(toastId)\n dispatch({\n type: actionTypes.REMOVE_TOAST,\n toastId,\n })\n }, TOAST_REMOVE_DELAY)\n\n toastTimeouts.set(toastId, timeout)\n}\n\nconst state = ref<State>({\n toasts: [],\n})\n\nfunction dispatch(action: Action) {\n switch (action.type) {\n case actionTypes.ADD_TOAST:\n state.value.toasts = [action.toast, ...state.value.toasts].slice(0, TOAST_LIMIT)\n break\n\n case actionTypes.UPDATE_TOAST:\n state.value.toasts = state.value.toasts.map(t =>\n t.id === action.toast.id ? { ...t, ...action.toast } : t,\n )\n break\n\n case actionTypes.DISMISS_TOAST: {\n const { toastId } = action\n\n if (toastId) {\n addToRemoveQueue(toastId)\n }\n else {\n state.value.toasts.forEach((toast) => {\n addToRemoveQueue(toast.id)\n })\n }\n\n state.value.toasts = state.value.toasts.map(t =>\n t.id === toastId || toastId === undefined\n ? {\n ...t,\n open: false,\n }\n : t,\n )\n break\n }\n\n case actionTypes.REMOVE_TOAST:\n if (action.toastId === undefined)\n state.value.toasts = []\n else\n state.value.toasts = state.value.toasts.filter(t => t.id !== action.toastId)\n\n break\n }\n}\n\nfunction useToast() {\n return {\n toasts: computed(() => state.value.toasts),\n toast,\n dismiss: (toastId?: string) => dispatch({ type: actionTypes.DISMISS_TOAST, toastId }),\n }\n}\n\ntype Toast = Omit<ToasterToast, 'id'>\n\nfunction toast(props: Toast) {\n const id = genId()\n\n const update = (props: ToasterToast) =>\n dispatch({\n type: actionTypes.UPDATE_TOAST,\n toast: { ...props, id },\n })\n\n const dismiss = () => dispatch({ type: actionTypes.DISMISS_TOAST, toastId: id })\n\n dispatch({\n type: actionTypes.ADD_TOAST,\n toast: {\n ...props,\n id,\n open: true,\n onOpenChange: (open: boolean) => {\n if (!open)\n dismiss()\n },\n },\n })\n\n return {\n id,\n dismiss,\n update,\n }\n}\n\nexport { toast, useToast }\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "toggle",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/toggle/Toggle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Toggle, type ToggleEmits, type ToggleProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\nimport { type ToggleVariants, toggleVariants } from '.'\n\nconst props = withDefaults(defineProps<ToggleProps & {\n class?: HTMLAttributes['class']\n variant?: ToggleVariants['variant']\n size?: ToggleVariants['size']\n}>(), {\n variant: 'default',\n size: 'default',\n disabled: false,\n})\n\nconst emits = defineEmits<ToggleEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, size, variant, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <Toggle\n v-bind=\"forwarded\"\n :class=\"cn(toggleVariants({ variant, size }), props.class)\"\n >\n <slot />\n </Toggle>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toggle/index.ts",
|
|
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Toggle } from './Toggle.vue'\n\nexport const toggleVariants = cva(\n 'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 gap-2',\n {\n variants: {\n variant: {\n default: 'bg-transparent',\n outline:\n 'border border-input bg-transparent hover:bg-accent hover:text-accent-foreground',\n },\n size: {\n default: 'h-10 px-3 min-w-10',\n sm: 'h-9 px-2.5 min-w-9',\n lg: 'h-11 px-5 min-w-11',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type ToggleVariants = VariantProps<typeof toggleVariants>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "toggle-group",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"toggle",
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/toggle-group/ToggleGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { toggleVariants } from '@/registry/default/ui/toggle'\nimport type { VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\nimport { ToggleGroupRoot, type ToggleGroupRootEmits, type ToggleGroupRootProps, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes, provide } from 'vue'\n\ntype ToggleGroupVariants = VariantProps<typeof toggleVariants>\n\nconst props = defineProps<ToggleGroupRootProps & {\n class?: HTMLAttributes['class']\n variant?: ToggleGroupVariants['variant']\n size?: ToggleGroupVariants['size']\n}>()\nconst emits = defineEmits<ToggleGroupRootEmits>()\n\nprovide('toggleGroup', {\n variant: props.variant,\n size: props.size,\n})\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <ToggleGroupRoot v-bind=\"forwarded\" :class=\"cn('flex items-center justify-center gap-1', props.class)\">\n <slot />\n </ToggleGroupRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/toggle-group/ToggleGroupItem.vue",
|
|
"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": ""
|
|
},
|
|
{
|
|
"path": "ui/toggle-group/index.ts",
|
|
"content": "export { default as ToggleGroup } from './ToggleGroup.vue'\nexport { default as ToggleGroupItem } from './ToggleGroupItem.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "tooltip",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/tooltip/Tooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { TooltipRoot, type TooltipRootEmits, type TooltipRootProps, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<TooltipRootProps>()\nconst emits = defineEmits<TooltipRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n <TooltipRoot v-bind=\"forwarded\">\n <slot />\n </TooltipRoot>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tooltip/TooltipContent.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { TooltipContent, type TooltipContentEmits, type TooltipContentProps, TooltipPortal, useForwardPropsEmits } from 'reka-ui'\nimport { computed, type HTMLAttributes } from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<TooltipContentProps & { class?: HTMLAttributes['class'] }>(), {\n sideOffset: 4,\n})\n\nconst emits = defineEmits<TooltipContentEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <TooltipPortal>\n <TooltipContent v-bind=\"{ ...forwarded, ...$attrs }\" :class=\"cn('z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', props.class)\">\n <slot />\n </TooltipContent>\n </TooltipPortal>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tooltip/TooltipProvider.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { TooltipProvider, type TooltipProviderProps } from 'reka-ui'\n\nconst props = defineProps<TooltipProviderProps>()\n</script>\n\n<template>\n <TooltipProvider v-bind=\"props\">\n <slot />\n </TooltipProvider>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tooltip/TooltipTrigger.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { TooltipTrigger, type TooltipTriggerProps } from 'reka-ui'\n\nconst props = defineProps<TooltipTriggerProps>()\n</script>\n\n<template>\n <TooltipTrigger v-bind=\"props\">\n <slot />\n </TooltipTrigger>\n</template>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/tooltip/index.ts",
|
|
"content": "export { default as Tooltip } from './Tooltip.vue'\nexport { default as TooltipContent } from './TooltipContent.vue'\nexport { default as TooltipProvider } from './TooltipProvider.vue'\nexport { default as TooltipTrigger } from './TooltipTrigger.vue'\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "v-calendar",
|
|
"type": "registry:ui",
|
|
"dependencies": [
|
|
"v-calendar@next",
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "ui/v-calendar/Calendar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { Calendar } from 'v-calendar'\nimport { cn } from '@/lib/utils'\nimport { buttonVariants } from '@/registry/default/ui/button'\nimport { useVModel } from '@vueuse/core'\nimport { ChevronLeft, ChevronRight } from 'lucide-vue-next'\nimport { DatePicker } from 'v-calendar'\nimport { computed, nextTick, onMounted, ref, useSlots } from 'vue'\nimport { isVCalendarSlot } from '.'\n\n/* Extracted from v-calendar */\ntype DatePickerModel = DatePickerDate | DatePickerRangeObject\ntype DateSource = Date | string | number\ntype DatePickerDate = DateSource | Partial<SimpleDateParts> | null\ninterface DatePickerRangeObject {\n start: Exclude<DatePickerDate, null>\n end: Exclude<DatePickerDate, null>\n}\ninterface SimpleDateParts {\n year: number\n month: number\n day: number\n hours: number\n minutes: number\n seconds: number\n milliseconds: number\n}\n\ndefineOptions({\n inheritAttrs: false,\n})\nconst props = withDefaults(defineProps< {\n modelValue?: string | number | Date | DatePickerModel\n modelModifiers?: object\n columns?: number\n type?: 'single' | 'range'\n}>(), {\n type: 'single',\n columns: 1,\n})\nconst emits = defineEmits<{\n (e: 'update:modelValue', payload: typeof props.modelValue): void\n}>()\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n passive: true,\n})\n\nconst datePicker = ref<InstanceType<typeof DatePicker>>()\n// @ts-expect-error in this current version of v-calendar has the calendaRef instance, which is required to handle arrow nav.\nconst calendarRef = computed<InstanceType<typeof Calendar>>(() => datePicker.value.calendarRef)\n\nfunction handleNav(direction: 'prev' | 'next') {\n if (!calendarRef.value)\n return\n\n if (direction === 'prev')\n calendarRef.value.movePrev()\n else calendarRef.value.moveNext()\n}\n\nonMounted(async () => {\n await nextTick()\n if (modelValue.value instanceof Date && calendarRef.value)\n calendarRef.value.focusDate(modelValue.value)\n})\n\nconst $slots = useSlots()\nconst vCalendarSlots = computed(() => {\n return Object.keys($slots)\n .filter(name => isVCalendarSlot(name))\n .reduce((obj: Record<string, any>, key: string) => {\n obj[key] = $slots[key]\n return obj\n }, {})\n})\n</script>\n\n<template>\n <div class=\"relative\">\n <div v-if=\"$attrs.mode !== 'time'\" class=\"absolute flex justify-between w-full px-4 top-3 z-[1]\">\n <button\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n )\"\n @click=\"handleNav('prev')\"\n >\n <ChevronLeft class=\"w-4 h-4\" />\n </button>\n <button\n :class=\"cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n )\"\n @click=\"handleNav('next')\"\n >\n <ChevronRight class=\"w-4 h-4\" />\n </button>\n </div>\n\n <DatePicker\n ref=\"datePicker\"\n v-bind=\"$attrs\"\n v-model=\"modelValue\"\n :model-modifiers=\"modelModifiers\"\n class=\"calendar\"\n trim-weeks\n :transition=\"'none'\"\n :columns=\"columns\"\n >\n <template v-for=\"(_, slot) of vCalendarSlots\" #[slot]=\"scope\">\n <slot :name=\"slot\" v-bind=\"scope\" />\n </template>\n\n <template #nav-prev-button>\n <ChevronLeft />\n </template>\n\n <template #nav-next-button>\n <ChevronRight />\n </template>\n </DatePicker>\n </div>\n</template>\n\n<style lang=\"css\">\n.calendar {\n @apply p-3 text-center;\n}\n.calendar .vc-pane-layout {\n @apply grid gap-4 max-sm:!grid-cols-1;\n}\n.calendar .vc-title {\n @apply text-sm font-medium relative z-20;\n}\n.vc-popover-content-wrapper .vc-popover-content {\n @apply mt-3 rounded-md max-w-xs border bg-background;\n}\n.vc-popover-content-wrapper .vc-nav-header {\n @apply flex justify-between items-center p-2;\n}\n.vc-popover-content-wrapper .vc-nav-items {\n @apply grid grid-cols-4 gap-2 p-2;\n}\n.vc-popover-content-wrapper .vc-nav-items .vc-nav-item {\n @apply rounded-md px-2 py-1;\n}\n.vc-popover-content-wrapper .vc-nav-items .vc-nav-item:hover {\n @apply text-muted-foreground bg-muted;\n}\n.vc-popover-content-wrapper .vc-nav-items .vc-nav-item.is-active {\n @apply bg-primary text-primary-foreground;\n}\n.calendar .vc-pane-header-wrapper {\n @apply hidden;\n}\n.calendar .vc-weeks {\n @apply mt-4;\n}\n.calendar .vc-weekdays {\n @apply justify-items-center;\n}\n.calendar .vc-weekday {\n @apply text-muted-foreground rounded-md font-normal text-[0.8rem];\n}\n.calendar .vc-weeks {\n @apply w-full space-y-2 flex flex-col [&>_div]:grid [&>_div]:grid-cols-7;\n}\n.calendar .vc-day:has(.vc-highlights) {\n @apply first:rounded-l-md last:rounded-r-md;\n}\n.calendar .vc-day.is-today:not(:has(.vc-day-layer)) .vc-day-content {\n @apply bg-secondary text-primary rounded-md;\n}\n.calendar .vc-day:has(.vc-highlight-base-start) {\n @apply rounded-l-md;\n}\n.calendar .vc-day:has(.vc-highlight-base-end) {\n @apply rounded-r-md;\n}\n.calendar .vc-day:has(.vc-highlight-bg-outline):not(:has(.vc-highlight-base-start)):not(:has(.vc-highlight-base-end)) {\n @apply rounded-md;\n}\n.calendar .vc-day-content {\n @apply text-center text-sm p-0 relative focus-within:relative focus-within:z-20 inline-flex items-center justify-center ring-offset-background hover:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 hover:bg-accent hover:text-accent-foreground h-9 w-9 font-normal aria-selected:opacity-100 select-none;\n}\n.calendar .vc-day-content:not(.vc-highlight-content-light) {\n @apply rounded-md;\n}\n.calendar .is-not-in-month:not(:has(.vc-highlight-content-solid)):not(:has(.vc-highlight-content-light)):not(:has(.vc-highlight-content-outline)),\n.calendar .vc-disabled {\n @apply text-muted-foreground opacity-50;\n}\n.calendar .vc-highlight-content-solid, .calendar .vc-highlight-content-outline {\n @apply bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground;\n}\n.calendar .vc-highlight-content-light {\n @apply bg-accent text-accent-foreground;\n}\n.calendar .vc-pane-container.in-transition {\n @apply overflow-hidden;\n}\n.calendar .vc-pane-container {\n @apply w-full relative;\n}\n:root {\n\t--vc-slide-translate: 22px;\n\t--vc-slide-duration: 0.15s;\n\t--vc-slide-timing: ease;\n}\n\n.calendar .vc-fade-enter-active,\n.calendar .vc-fade-leave-active,\n.calendar .vc-slide-left-enter-active,\n.calendar .vc-slide-left-leave-active,\n.calendar .vc-slide-right-enter-active,\n.calendar .vc-slide-right-leave-active,\n.calendar .vc-slide-up-enter-active,\n.calendar .vc-slide-up-leave-active,\n.calendar .vc-slide-down-enter-active,\n.calendar .vc-slide-down-leave-active,\n.calendar .vc-slide-fade-enter-active,\n.calendar .vc-slide-fade-leave-active {\n\ttransition:\n\t\topacity var(--vc-slide-duration) var(--vc-slide-timing),\n\t\t-webkit-transform var(--vc-slide-duration) var(--vc-slide-timing);\n\ttransition:\n\t\ttransform var(--vc-slide-duration) var(--vc-slide-timing),\n\t\topacity var(--vc-slide-duration) var(--vc-slide-timing);\n\ttransition:\n\t\ttransform var(--vc-slide-duration) var(--vc-slide-timing),\n\t\topacity var(--vc-slide-duration) var(--vc-slide-timing),\n\t\t-webkit-transform var(--vc-slide-duration) var(--vc-slide-timing);\n\t-webkit-backface-visibility: hidden;\n\tbackface-visibility: hidden;\n\tpointer-events: none;\n}\n\n.calendar .vc-none-leave-active,\n.calendar .vc-fade-leave-active,\n.calendar .vc-slide-left-leave-active,\n.calendar .vc-slide-right-leave-active,\n.calendar .vc-slide-up-leave-active,\n.calendar .vc-slide-down-leave-active {\n\tposition: absolute !important;\n\twidth: 100%;\n}\n\n.calendar .vc-none-enter-from,\n.calendar .vc-none-leave-to,\n.calendar .vc-fade-enter-from,\n.calendar .vc-fade-leave-to,\n.calendar .vc-slide-left-enter-from,\n.calendar .vc-slide-left-leave-to,\n.calendar .vc-slide-right-enter-from,\n.calendar .vc-slide-right-leave-to,\n.calendar .vc-slide-up-enter-from,\n.calendar .vc-slide-up-leave-to,\n.calendar .vc-slide-down-enter-from,\n.calendar .vc-slide-down-leave-to,\n.calendar .vc-slide-fade-enter-from,\n.calendar .vc-slide-fade-leave-to {\n\topacity: 0;\n}\n\n.calendar .vc-slide-left-enter-from,\n.calendar .vc-slide-right-leave-to,\n.calendar .vc-slide-fade-enter-from.direction-left,\n.calendar .vc-slide-fade-leave-to.direction-left {\n\t-webkit-transform: translateX(var(--vc-slide-translate));\n\ttransform: translateX(var(--vc-slide-translate));\n}\n\n.calendar .vc-slide-right-enter-from,\n.calendar .vc-slide-left-leave-to,\n.calendar .vc-slide-fade-enter-from.direction-right,\n.calendar .vc-slide-fade-leave-to.direction-right {\n\t-webkit-transform: translateX(calc(-1 * var(--vc-slide-translate)));\n\ttransform: translateX(calc(-1 * var(--vc-slide-translate)));\n}\n\n.calendar .vc-slide-up-enter-from,\n.calendar .vc-slide-down-leave-to,\n.calendar .vc-slide-fade-enter-from.direction-top,\n.calendar .vc-slide-fade-leave-to.direction-top {\n\t-webkit-transform: translateY(var(--vc-slide-translate));\n\ttransform: translateY(var(--vc-slide-translate));\n}\n\n.calendar .vc-slide-down-enter-from,\n.calendar .vc-slide-up-leave-to,\n.calendar .vc-slide-fade-enter-from.direction-bottom,\n.calendar .vc-slide-fade-leave-to.direction-bottom {\n\t-webkit-transform: translateY(calc(-1 * var(--vc-slide-translate)));\n\ttransform: translateY(calc(-1 * var(--vc-slide-translate)));\n}\n/**\n * Timepicker styles\n */\n.vc-time-picker {\n @apply flex flex-col items-center p-2;\n}\n.vc-time-picker.vc-invalid {\n @apply pointer-events-none opacity-50;\n}\n.vc-time-picker.vc-attached {\n @apply border-t border-solid border-secondary mt-2;\n}\n.vc-time-picker > * + * {\n @apply mt-1;\n}\n.vc-time-header {\n @apply flex items-center text-sm font-semibold uppercase mt-1 px-1 leading-6;\n}\n.vc-time-select-group {\n @apply inline-flex items-center px-1 rounded-md bg-primary-foreground border border-solid border-secondary;\n}\n.vc-time-select-group .vc-base-icon {\n @apply mr-1 text-primary stroke-primary;\n}\n.vc-time-select-group select {\n @apply bg-primary-foreground p-1 appearance-none outline-none text-center;\n}\n.vc-time-weekday {\n @apply text-muted-foreground tracking-wide;\n}\n.vc-time-month {\n @apply text-primary ml-2;\n}\n.vc-time-day {\n @apply text-primary ml-1;\n}\n.vc-time-year {\n @apply text-muted-foreground ml-2;\n}\n.vc-time-colon {\n @apply mb-0.5;\n}\n.vc-time-decimal {\n @apply ml-0.5;\n}\n</style>\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "ui/v-calendar/index.ts",
|
|
"content": "export { default as Calendar } from './Calendar.vue'\nimport type { CalendarSlotName } from 'v-calendar/dist/types/src/components/Calendar/CalendarSlot.vue.d.ts'\n\nexport function isVCalendarSlot(slotName: string): slotName is CalendarSlotName {\n const validSlots: CalendarSlotName[] = [\n 'day-content',\n 'day-popover',\n 'dp-footer',\n 'footer',\n 'header-title-wrapper',\n 'header-title',\n 'header-prev-button',\n 'header-next-button',\n 'nav',\n 'nav-prev-button',\n 'nav-next-button',\n 'page',\n 'time-header',\n ]\n\n return validSlots.includes(slotName as CalendarSlotName)\n}\n",
|
|
"type": "registry:ui",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AccordionDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"accordion"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AccordionDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/registry/default/ui/accordion'\n\nconst defaultValue = 'item-1'\n\nconst accordionItems = [\n { value: 'item-1', title: 'Is it accessible?', content: 'Yes. It adheres to the WAI-ARIA design pattern.' },\n { value: 'item-2', title: 'Is it unstyled?', content: 'Yes. It\\'s unstyled by default, giving you freedom over the look and feel.' },\n { value: 'item-3', title: 'Can it be animated?', content: 'Yes! You can use the transition prop to configure the animation.' },\n]\n</script>\n\n<template>\n <Accordion type=\"single\" class=\"w-full\" collapsible :default-value=\"defaultValue\">\n <AccordionItem v-for=\"item in accordionItems\" :key=\"item.value\" :value=\"item.value\">\n <AccordionTrigger>{{ item.title }}</AccordionTrigger>\n <AccordionContent>\n {{ item.content }}\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AlertDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"alert"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AlertDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Alert, AlertDescription, AlertTitle } from '@/registry/default/ui/alert'\nimport { Terminal } from 'lucide-vue-next'\n</script>\n\n<template>\n <Alert>\n <Terminal class=\"h-4 w-4\" />\n <AlertTitle>Heads up!</AlertTitle>\n <AlertDescription>\n You can add components to your app using the cli.\n </AlertDescription>\n </Alert>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AlertDestructiveDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"alert"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AlertDestructiveDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Alert, AlertDescription, AlertTitle } from '@/registry/default/ui/alert'\nimport { AlertCircle } from 'lucide-vue-next'\n</script>\n\n<template>\n <Alert variant=\"destructive\">\n <AlertCircle class=\"w-4 h-4\" />\n <AlertTitle>Error</AlertTitle>\n <AlertDescription>\n Your session has expired. Please log in again.\n </AlertDescription>\n </Alert>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AlertDialogDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"alert-dialog",
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AlertDialogDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from '@/registry/default/ui/alert-dialog'\nimport { Button } from '@/registry/default/ui/button'\n</script>\n\n<template>\n <AlertDialog>\n <AlertDialogTrigger as-child>\n <Button variant=\"outline\">\n Show Dialog\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>\n <AlertDialogDescription>\n This action cannot be undone. This will permanently delete your\n account and remove your data from our servers.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction>Continue</AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AreaChartCustomTooltip",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-area"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AreaChartCustomTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AreaChart } from '@/registry/default/ui/chart-area'\nimport CustomChartTooltip from './CustomChartTooltip.vue'\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 { name: 'Jul', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n]\n</script>\n\n<template>\n <AreaChart\n index=\"name\"\n :data=\"data\"\n :categories=\"['total', 'predicted']\"\n :custom-tooltip=\"CustomChartTooltip\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AreaChartDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-area"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AreaChartDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AreaChart } from '@/registry/default/ui/chart-area'\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 { name: 'Jul', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n]\n</script>\n\n<template>\n <AreaChart :data=\"data\" index=\"name\" :categories=\"['total', 'predicted']\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AreaChartSparkline",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-area"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AreaChartSparkline.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AreaChart } from '@/registry/default/ui/chart-area'\nimport { CurveType } from '@unovis/ts'\n\nconst data = [\n { name: 'Jan', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Feb', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Mar', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Apr', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'May', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Jun', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Jul', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Aug', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Sep', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Oct', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Nov', total: Math.floor(Math.random() * 2000) + 1000 },\n { name: 'Dec', total: Math.floor(Math.random() * 2000) + 1000 },\n]\n</script>\n\n<template>\n <AreaChart\n class=\"h-[100px] w-[400px]\"\n index=\"name\"\n :data=\"data\"\n :categories=\"['total']\"\n :show-grid-line=\"false\"\n :show-legend=\"false\"\n :show-x-axis=\"false\"\n :show-y-axis=\"false\"\n :curve-type=\"CurveType.Linear\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AspectRatioDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"aspect-ratio"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AspectRatioDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AspectRatio } from '@/registry/default/ui/aspect-ratio'\n</script>\n\n<template>\n <AspectRatio :ratio=\"16 / 9\" class=\"bg-muted\">\n <img\n src=\"https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&dpr=2&q=80\"\n alt=\"Photo by Drew Beamer\"\n class=\"rounded-md object-cover w-full h-full\"\n >\n </AspectRatio>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormApi",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormApi.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm } from '@/registry/default/ui/auto-form'\nimport { Button } from '@/registry/default/ui/button'\nimport { toast } from '@/registry/default/ui/toast'\nimport { h, onMounted, shallowRef } from 'vue'\nimport * as z from 'zod'\n\nconst schema = shallowRef<z.ZodObject< any, any, any > | null>(null)\n\nonMounted(() => {\n fetch('https://jsonplaceholder.typicode.com/users')\n .then(response => response.json())\n .then((data) => {\n schema.value = z.object({\n user: z.enum(data.map((user: any) => user.name)),\n })\n })\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <div class=\"flex justify-center w-full\">\n <AutoForm\n v-if=\"schema\"\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n @submit=\"onSubmit\"\n >\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n\n <div v-else>\n Loading...\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormArray",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormArray.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm } from '@/registry/default/ui/auto-form'\nimport { Button } from '@/registry/default/ui/button'\nimport { toast } from '@/registry/default/ui/toast'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst schema = z.object({\n guestListName: z.string(),\n invitedGuests: z\n .array(\n z.object({\n name: z.string(),\n age: z.coerce.number(),\n }),\n )\n .describe('Guests invited to the party'),\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n @submit=\"onSubmit\"\n >\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormBasic",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormBasic.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm, AutoFormField } from '@/registry/default/ui/auto-form'\nimport { Button } from '@/registry/default/ui/button'\nimport { toast } from '@/registry/default/ui/toast'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nenum Sports {\n Football = 'Football/Soccer',\n Basketball = 'Basketball',\n Baseball = 'Baseball',\n Hockey = 'Hockey (Ice)',\n None = 'I don\\'t like sports',\n}\n\nconst schema = z.object({\n username: z\n .string({\n required_error: 'Username is required.',\n })\n .min(2, {\n message: 'Username must be at least 2 characters.',\n }),\n\n password: z\n .string({\n required_error: 'Password is required.',\n })\n .min(8, {\n message: 'Password must be at least 8 characters.',\n }),\n\n favouriteNumber: z.coerce\n .number({\n invalid_type_error: 'Favourite number must be a number.',\n })\n .min(1, {\n message: 'Favourite number must be at least 1.',\n })\n .max(10, {\n message: 'Favourite number must be at most 10.',\n })\n .default(1)\n .optional(),\n\n acceptTerms: z\n .boolean()\n .refine(value => value, {\n message: 'You must accept the terms and conditions.',\n path: ['acceptTerms'],\n }),\n\n sendMeMails: z.boolean().optional(),\n\n birthday: z.coerce.date().optional(),\n\n color: z.enum(['red', 'green', 'blue']).optional(),\n\n // Another enum example\n marshmallows: z\n .enum(['not many', 'a few', 'a lot', 'too many']),\n\n // Native enum example\n sports: z.nativeEnum(Sports).describe('What is your favourite sport?'),\n\n bio: z\n .string()\n .min(10, {\n message: 'Bio must be at least 10 characters.',\n })\n .max(160, {\n message: 'Bio must not be longer than 30 characters.',\n })\n .optional(),\n\n customParent: z.string().optional(),\n\n file: z.string().optional(),\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n :field-config=\"{\n password: {\n label: 'Your secure password',\n inputProps: {\n type: 'password',\n placeholder: '••••••••',\n },\n },\n favouriteNumber: {\n description: 'Your favourite number between 1 and 10.',\n },\n acceptTerms: {\n label: 'Accept terms and conditions.',\n inputProps: {\n required: true,\n },\n },\n\n birthday: {\n description: 'We need your birthday to send you a gift.',\n },\n\n sendMeMails: {\n component: 'switch',\n },\n\n bio: {\n component: 'textarea',\n },\n\n marshmallows: {\n label: 'How many marshmallows fit in your mouth?',\n component: 'radio',\n },\n\n file: {\n label: 'Text file',\n component: 'file',\n },\n }\"\n @submit=\"onSubmit\"\n >\n <template #acceptTerms=\"slotProps\">\n <AutoFormField v-bind=\"slotProps\" />\n <div class=\"!mt-2 text-sm\">\n I agree to the <button class=\"text-primary underline\">\n terms and conditions\n </button>.\n </div>\n </template>\n\n <template #customParent=\"slotProps\">\n <div class=\"flex items-end space-x-2\">\n <AutoFormField v-bind=\"slotProps\" class=\"w-full\" />\n <Button type=\"button\">\n Check\n </Button>\n </div>\n </template>\n\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormConfirmPassword",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormConfirmPassword.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm } from '@/registry/default/ui/auto-form'\nimport { Button } from '@/registry/default/ui/button'\nimport { toast } from '@/registry/default/ui/toast'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst schema = z\n .object({\n password: z.string(),\n confirm: z.string(),\n })\n .refine(data => data.password === data.confirm, {\n message: 'Passwords must match.',\n path: ['confirm'],\n })\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n @submit=\"onSubmit\"\n >\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormControlled",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormControlled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm } from '@/registry/default/ui/auto-form'\nimport { Button } from '@/registry/default/ui/button'\nimport { toast } from '@/registry/default/ui/toast'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst schema = z.object({\n username: z.string(),\n})\n\nconst form = useForm({\n validationSchema: toTypedSchema(schema),\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n :form=\"form\"\n @submit=\"onSubmit\"\n >\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormDependencies",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormDependencies.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm } from '@/registry/default/ui/auto-form'\nimport { Button } from '@/registry/default/ui/button'\nimport { toast } from '@/registry/default/ui/toast'\nimport { h } from 'vue'\nimport * as z from 'zod'\nimport { DependencyType } from '../ui/auto-form/interface'\n\nconst schema = z.object({\n age: z.number(),\n parentsAllowed: z.boolean().optional(),\n vegetarian: z.boolean().optional(),\n mealOptions: z.enum(['Pasta', 'Salad', 'Beef Wellington']).optional(),\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n :field-config=\"{\n age: {\n description:\n 'Setting this below 18 will require parents consent.',\n },\n parentsAllowed: {\n label: 'Did your parents allow you to register?',\n },\n vegetarian: {\n label: 'Are you a vegetarian?',\n description:\n 'Setting this to true will remove non-vegetarian food options.',\n },\n mealOptions: {\n component: 'radio',\n },\n }\"\n :dependencies=\"[\n {\n sourceField: 'age',\n type: DependencyType.HIDES,\n targetField: 'parentsAllowed',\n when: (age) => age >= 18,\n },\n {\n sourceField: 'age',\n type: DependencyType.REQUIRES,\n targetField: 'parentsAllowed',\n when: (age) => age < 18,\n },\n {\n sourceField: 'vegetarian',\n type: DependencyType.SETS_OPTIONS,\n targetField: 'mealOptions',\n when: (vegetarian) => vegetarian,\n options: ['Pasta', 'Salad'],\n },\n ]\"\n @submit=\"onSubmit\"\n >\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormInputWithoutLabel",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormInputWithoutLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm, AutoFormField } from '@/registry/default/ui/auto-form'\nimport { Button } from '@/registry/default/ui/button'\nimport { toast } from '@/registry/default/ui/toast'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst schema = z.object({\n username: z.string(),\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n :field-config=\"{\n username: {\n hideLabel: true,\n },\n }\"\n @submit=\"onSubmit\"\n >\n <template #username=\"slotProps\">\n <div class=\"flex items-start gap-3\">\n <div class=\"flex-1\">\n <AutoFormField v-bind=\"slotProps\" />\n </div>\n <div>\n <Button type=\"submit\">\n Update\n </Button>\n </div>\n </div>\n </template>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AutoFormSubObject",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"auto-form",
|
|
"button",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AutoFormSubObject.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { AutoForm } from '@/registry/default/ui/auto-form'\nimport { Button } from '@/registry/default/ui/button'\nimport { toast } from '@/registry/default/ui/toast'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst schema = z.object({\n subObject: z.object({\n subField: z.string().optional().default('Sub Field'),\n numberField: z.number().optional().default(1),\n\n subSubObject: z\n .object({\n subSubField: z.string().default('Sub Sub Field'),\n })\n .describe('Sub Sub Object Description'),\n }),\n optionalSubObject: z\n .object({\n optionalSubField: z.string(),\n otherOptionalSubField: z.string(),\n })\n .optional(),\n})\n\nfunction onSubmit(values: Record<string, any>) {\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 <AutoForm\n class=\"w-2/3 space-y-6\"\n :schema=\"schema\"\n :field-config=\"{\n subObject: {\n numberField: {\n inputProps: {\n type: 'number',\n },\n },\n },\n }\"\n @submit=\"onSubmit\"\n >\n <Button type=\"submit\">\n Submit\n </Button>\n </AutoForm>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "AvatarDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"avatar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/AvatarDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback, AvatarImage } from '@/registry/default/ui/avatar'\n</script>\n\n<template>\n <Avatar>\n <AvatarImage src=\"https://github.com/unovue.png\" alt=\"@unovue\" />\n <AvatarFallback>CN</AvatarFallback>\n </Avatar>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BadgeDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BadgeDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Badge } from '@/registry/default/ui/badge'\n</script>\n\n<template>\n <Badge>Badge</Badge>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BadgeDestructiveDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BadgeDestructiveDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Badge } from '@/registry/default/ui/badge'\n</script>\n\n<template>\n <Badge variant=\"destructive\">\n Destructive\n </Badge>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BadgeOutlineDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BadgeOutlineDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Badge } from '@/registry/default/ui/badge'\n</script>\n\n<template>\n <Badge variant=\"outline\">\n Outline\n </Badge>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BadgeSecondaryDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BadgeSecondaryDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Badge } from '@/registry/default/ui/badge'\n</script>\n\n<template>\n <Badge variant=\"secondary\">\n Secondary\n </Badge>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BarChartCustomTooltip",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-bar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BarChartCustomTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { BarChart } from '@/registry/default/ui/chart-bar'\nimport CustomChartTooltip from './CustomChartTooltip.vue'\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 { name: 'Jul', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n]\n</script>\n\n<template>\n <BarChart\n :data=\"data\"\n index=\"name\"\n :categories=\"['total', 'predicted']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n :custom-tooltip=\"CustomChartTooltip\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BarChartDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-bar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BarChartDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { BarChart } from '@/registry/default/ui/chart-bar'\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 { name: 'Jul', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n]\n</script>\n\n<template>\n <BarChart\n :data=\"data\"\n index=\"name\"\n :categories=\"['total', 'predicted']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BarChartRounded",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-bar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BarChartRounded.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { BarChart } from '@/registry/default/ui/chart-bar'\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 { name: 'Jul', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n]\n</script>\n\n<template>\n <BarChart\n index=\"name\"\n :data=\"data\"\n :categories=\"['total', 'predicted']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n :rounded-corners=\"4\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BarChartStacked",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-bar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BarChartStacked.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { BarChart } from '@/registry/default/ui/chart-bar'\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 { name: 'Jul', total: Math.floor(Math.random() * 2000) + 500, predicted: Math.floor(Math.random() * 2000) + 500 },\n]\n</script>\n\n<template>\n <BarChart\n index=\"name\"\n :data=\"data\"\n :categories=\"['total', 'predicted']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n :type=\"'stacked'\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BreadcrumbDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BreadcrumbDemo.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\n</script>\n\n<template>\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink href=\"/\">\n Home\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <DropdownMenu>\n <DropdownMenuTrigger class=\"flex items-center gap-1\">\n <BreadcrumbEllipsis class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n <DropdownMenuItem>Documentation</DropdownMenuItem>\n <DropdownMenuItem>Themes</DropdownMenuItem>\n <DropdownMenuItem>GitHub</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink href=\"/docs/components/accordion.html\">\n Components\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BreadcrumbDropdown",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BreadcrumbDropdown.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport { ChevronDown, Slash } from 'lucide-vue-next'\n</script>\n\n<template>\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink href=\"/\">\n Home\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator>\n <Slash />\n </BreadcrumbSeparator>\n <BreadcrumbItem>\n <DropdownMenu>\n <DropdownMenuTrigger class=\"flex items-center gap-1\">\n Components\n <ChevronDown class=\"h-4 w-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n <DropdownMenuItem>Documentation</DropdownMenuItem>\n <DropdownMenuItem>Themes</DropdownMenuItem>\n <DropdownMenuItem>GitHub</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </BreadcrumbItem>\n <BreadcrumbSeparator>\n <Slash />\n </BreadcrumbSeparator>\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BreadcrumbEllipsisDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BreadcrumbEllipsisDemo.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\n</script>\n\n<template>\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"/\">\n Home\n </a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbEllipsis />\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"/docs/components/accordion.html\">\n Components\n </a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BreadcrumbLinkDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BreadcrumbLinkDemo.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\n</script>\n\n<template>\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink>\n <a href=\"/\">\n Home\n </a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink>\n <a href=\"/docs/components/accordion.html\">\n Components\n </a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BreadcrumbResponsive",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"button",
|
|
"drawer",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BreadcrumbResponsive.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from '@/registry/default/ui/drawer'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport { useMediaQuery } from '@vueuse/core'\nimport { computed, ref } from 'vue'\n\nconst isDesktop = useMediaQuery('(min-width: 768px)')\nconst isOpen = ref(false)\nconst items = ref([\n { href: '#', label: 'Home' },\n { href: '#', label: 'Documentation' },\n { href: '#', label: 'Building Your Application' },\n { href: '#', label: 'Data Fetching' },\n { label: 'Caching and Revalidating' },\n])\n\nconst itemsToDisplay = 3\nconst firstLabel = computed(() => items.value[0]?.label)\n\nconst allButLastTwoItems = computed(() => items.value.slice(1, -2))\nconst remainingItems = computed(() => items.value.slice(-itemsToDisplay + 1))\n</script>\n\n<template>\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink href=\"{items[0].href}\">\n {{ firstLabel }}\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <template v-if=\"items.length > itemsToDisplay\">\n <BreadcrumbItem>\n <DropdownMenu v-if=\"isDesktop\" v-model:open=\"isOpen\">\n <DropdownMenuTrigger\n class=\"flex items-center gap-1\"\n aria-label=\"Toggle menu\"\n >\n <BreadcrumbEllipsis class=\"h-4 w-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n <DropdownMenuItem v-for=\"item of allButLastTwoItems\" :key=\"item.label\">\n <a :href=\"item.href || '#'\">\n {{ item.label }}\n </a>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n <Drawer v-else v-model:open=\"isOpen\">\n <DrawerTrigger aria-label=\"Toggle Menu\">\n <BreadcrumbEllipsis class=\"h-4 w-4\" />\n </DrawerTrigger>\n <DrawerContent>\n <DrawerHeader class=\"text-left\">\n <DrawerTitle>Navigate to</DrawerTitle>\n <DrawerDescription>\n Select a page to navigate to.\n </DrawerDescription>\n </DrawerHeader>\n <div class=\"grid gap-1 px-4\">\n <a\n v-for=\"item of allButLastTwoItems\"\n :key=\"item.label\"\n :href=\"item.href\"\n class=\"py-1 text-sm\"\n >\n {{ item.label }}\n </a>\n </div>\n <DrawerFooter class=\"pt-4\">\n <DrawerClose as-child>\n <Button variant=\"outline\">\n Close\n </Button>\n </DrawerClose>\n </DrawerFooter>\n </DrawerContent>\n </Drawer>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n </template>\n <BreadcrumbItem v-for=\" item of remainingItems\" :key=\"item.label\">\n <template v-if=\"item.href\">\n <BreadcrumbLink\n as-child\n class=\"max-w-20 truncate md:max-w-none\"\n >\n <a :href=\"item.href\">\n {{ item.label }}\n </a>\n </BreadcrumbLink>\n <BreadcrumbSeparator />\n </template>\n <BreadcrumbPage v-else class=\"max-w-20 truncate md:max-w-none\">\n {{ item.label }}\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "BreadcrumbSeparatorDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/BreadcrumbSeparatorDemo.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Slash } from 'lucide-vue-next'\n</script>\n\n<template>\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink href=\"/\">\n Home\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator>\n <Slash />\n </BreadcrumbSeparator>\n <BreadcrumbItem>\n <BreadcrumbLink href=\"/docs/components/accordion.html\">\n Components\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator>\n <Slash />\n </BreadcrumbSeparator>\n <BreadcrumbItem>\n <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonAsChildDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonAsChildDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n</script>\n\n<template>\n <Button as-child>\n <a href=\"/login\">\n Login\n </a>\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n</script>\n\n<template>\n <Button>Button</Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonDestructiveDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonDestructiveDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n</script>\n\n<template>\n <Button variant=\"destructive\">\n Destructive\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonGhostDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonGhostDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n</script>\n\n<template>\n <Button variant=\"ghost\">\n Ghost\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonIconDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonIconDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { ChevronRight } from 'lucide-vue-next'\n</script>\n\n<template>\n <Button variant=\"outline\" size=\"icon\">\n <ChevronRight class=\"w-4 h-4\" />\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonLinkDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonLinkDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n</script>\n\n<template>\n <Button variant=\"link\">\n Link\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonLoadingDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonLoadingDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Loader2 } from 'lucide-vue-next'\n</script>\n\n<template>\n <Button disabled>\n <Loader2 class=\"w-4 h-4 mr-2 animate-spin\" />\n Please wait\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonOutlineDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonOutlineDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n</script>\n\n<template>\n <Button variant=\"outline\">\n Outline\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonSecondaryDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonSecondaryDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n</script>\n\n<template>\n <Button variant=\"secondary\">\n Secondary\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ButtonWithIconDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ButtonWithIconDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Mail } from 'lucide-vue-next'\n</script>\n\n<template>\n <Button>\n <Mail class=\"w-4 h-4 mr-2\" /> Login with Email\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CalendarDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CalendarDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Calendar } from '@/registry/default/ui/calendar'\nimport { type DateValue, getLocalTimeZone, today } from '@internationalized/date'\nimport { type Ref, ref } from 'vue'\n\nconst value = ref(today(getLocalTimeZone())) as Ref<DateValue>\n</script>\n\n<template>\n <Calendar v-model=\"value\" :weekday-format=\"'short'\" class=\"rounded-md border\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CalendarForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"calendar",
|
|
"form",
|
|
"popover",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CalendarForm.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CalendarWithSelect",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core",
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"calendar",
|
|
"select"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CalendarWithSelect.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CardChat",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"avatar",
|
|
"button",
|
|
"card",
|
|
"command",
|
|
"dialog",
|
|
"input",
|
|
"tooltip"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CardChat.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { Avatar, AvatarFallback, AvatarImage } from '@/registry/default/ui/avatar'\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Card,\n CardContent,\n CardFooter,\n CardHeader,\n} from '@/registry/default/ui/card'\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/registry/default/ui/command'\n\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/registry/default/ui/dialog'\nimport { Input } from '@/registry/default/ui/input'\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@/registry/default/ui/tooltip'\nimport { Check, Plus, Send } from 'lucide-vue-next'\nimport { computed, ref } from 'vue'\n\nconst input = ref('')\nconst inputLength = computed(() => input.value.trim().length)\nconst users = ref([\n {\n name: 'Olivia Martin',\n email: 'm@example.com',\n avatar: '/avatars/01.png',\n },\n {\n name: 'Isabella Nguyen',\n email: 'isabella.nguyen@email.com',\n avatar: '/avatars/03.png',\n },\n {\n name: 'Emma Wilson',\n email: 'emma@example.com',\n avatar: '/avatars/05.png',\n },\n {\n name: 'Jackson Lee',\n email: 'lee@example.com',\n avatar: '/avatars/02.png',\n },\n {\n name: 'William Kim',\n email: 'will@email.com',\n avatar: '/avatars/04.png',\n },\n])\n\ntype User = (typeof users.value)[number]\n\nconst messages = ref([\n { role: 'agent', content: 'Hi, how can I help you today?' },\n { role: 'user', content: 'Hey, I\\'m having trouble with my account.' },\n { role: 'agent', content: 'What seems to be the problem?' },\n { role: 'user', content: 'I can\\'t log in.' },\n])\n\nconst open = ref(false)\nconst selectedUsers = ref<User[]>([])\n</script>\n\n<template>\n <Card>\n <CardHeader class=\"flex flex-row items-center justify-between\">\n <div class=\"flex items-center space-x-4\">\n <Avatar>\n <AvatarImage src=\"/avatars/01.png\" alt=\"Image\" />\n <AvatarFallback>OM</AvatarFallback>\n </Avatar>\n <div>\n <p class=\"text-sm font-medium leading-none\">\n Sofia Davis\n </p>\n <p class=\"text-sm text-muted-foreground\">\n m@example.com\n </p>\n </div>\n </div>\n <TooltipProvider>\n <Tooltip :delay-duration=\"200\">\n <TooltipTrigger as-child>\n <Button\n variant=\"outline\"\n class=\"rounded-full p-2.5 flex items-center justify-center\"\n @click=\"open = true\"\n >\n <Plus class=\"w-4 h-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent :side-offset=\"10\">\n New message\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </CardHeader>\n <CardContent>\n <div class=\"space-y-4\">\n <div\n v-for=\"(message, index) in messages\"\n :key=\"index\"\n :class=\"cn(\n 'flex w-max max-w-[75%] flex-col gap-2 rounded-lg px-3 py-2 text-sm',\n message.role === 'user' ? 'ml-auto bg-primary text-primary-foreground' : 'bg-muted',\n )\"\n >\n {{ message.content }}\n </div>\n </div>\n </CardContent>\n <CardFooter>\n <form\n class=\"flex w-full items-center space-x-2\"\n @submit.prevent=\"() => {\n if (inputLength === 0) return\n messages.push({\n role: 'user',\n content: input,\n })\n }\"\n >\n <Input v-model=\"input\" placeholder=\"Type a message...\" class=\"flex-1\" />\n <Button class=\"p-2.5 flex items-center justify-center\" :disabled=\"inputLength === 0\">\n <Send class=\"w-4 h-4\" />\n <span class=\"sr-only\">Send</span>\n </Button>\n </form>\n </CardFooter>\n </Card>\n\n <Dialog v-model:open=\"open\">\n <DialogContent class=\"gap-0 p-0 outline-none\">\n <DialogHeader class=\"px-4 pb-4 pt-5\">\n <DialogTitle>New message</DialogTitle>\n <DialogDescription>\n Invite a user to this thread. This will create a new group\n message.\n </DialogDescription>\n </DialogHeader>\n <Command class=\"overflow-hidden rounded-t-none border-t\">\n <CommandInput placeholder=\"Search user...\" />\n <CommandList>\n <CommandEmpty>No users found.</CommandEmpty>\n <CommandGroup class=\"p-2\">\n <CommandItem\n v-for=\"user in users\"\n :key=\"user.email\"\n :value=\"user\"\n class=\"flex items-center px-2\"\n @select=\"() => {\n const index = selectedUsers.findIndex(u => u === user)\n if (index !== -1) {\n selectedUsers.splice(index, 1)\n }\n else {\n selectedUsers.push(user)\n }\n }\"\n >\n <Avatar>\n <AvatarImage :src=\"user.avatar\" alt=\"Image\" />\n <AvatarFallback>{{ user.name[0] }}</AvatarFallback>\n </Avatar>\n <div class=\"ml-2\">\n <p class=\"text-sm font-medium leading-none\">\n {{ user.name }}\n </p>\n <p class=\"text-sm text-muted-foreground\">\n {{ user.email }}\n </p>\n </div>\n <Check v-if=\"selectedUsers.includes(user)\" class=\"ml-auto flex h-5 w-5 text-primary\" />\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n <DialogFooter class=\"flex items-center border-t p-4 sm:justify-between\">\n <div v-if=\"selectedUsers.length > 0\" class=\"flex -space-x-2 overflow-hidden\">\n <Avatar\n v-for=\"user in selectedUsers\"\n :key=\"user.email\"\n class=\"inline-block border-2 border-background\"\n >\n <AvatarImage :src=\"user.avatar\" />\n <AvatarFallback>{{ user.name[0] }}</AvatarFallback>\n </Avatar>\n </div>\n\n <p v-else class=\"text-sm text-muted-foreground\">\n Select users to add to this thread.\n </p>\n\n <Button\n :disabled=\"selectedUsers.length < 2\"\n @click=\"open = false\"\n >\n Continue\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CardDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"card",
|
|
"switch"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CardDemo.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CardFormDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card",
|
|
"input",
|
|
"label",
|
|
"select"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CardFormDemo.vue",
|
|
"content": "<script setup lang='ts'>\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 { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/default/ui/select'\n</script>\n\n<template>\n <Card class=\"w-[350px]\">\n <CardHeader>\n <CardTitle>Create project</CardTitle>\n <CardDescription>Deploy your new project in one-click.</CardDescription>\n </CardHeader>\n <CardContent>\n <form>\n <div class=\"grid items-center w-full gap-4\">\n <div class=\"flex flex-col space-y-1.5\">\n <Label for=\"name\">Name</Label>\n <Input id=\"name\" placeholder=\"Name of your project\" />\n </div>\n <div class=\"flex flex-col space-y-1.5\">\n <Label for=\"framework\">Framework</Label>\n <Select>\n <SelectTrigger id=\"framework\">\n <SelectValue placeholder=\"Select\" />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectItem value=\"nuxt\">\n Nuxt\n </SelectItem>\n <SelectItem value=\"next\">\n Next.js\n </SelectItem>\n <SelectItem value=\"sveltekit\">\n SvelteKit\n </SelectItem>\n <SelectItem value=\"astro\">\n Astro\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n </form>\n </CardContent>\n <CardFooter class=\"flex justify-between px-6 pb-6\">\n <Button variant=\"outline\">\n Cancel\n </Button>\n <Button>Deploy</Button>\n </CardFooter>\n </Card>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CardStats",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts"
|
|
],
|
|
"registryDependencies": [
|
|
"card",
|
|
"registry-themes",
|
|
"config"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CardStats.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent, CardHeader, CardTitle } from '@/registry/default/ui/card'\nimport { themes } from '@/registry/registry-themes'\nimport { useConfigStore } from '@/stores/config'\nimport { VisLine, VisScatter, VisStackedBar, VisXYContainer } from '@unovis/vue'\nimport { useData } from 'vitepress'\nimport { computed } from 'vue'\n\ntype Data = typeof data[number]\nconst data = [\n { revenue: 10400, subscription: 240 },\n { revenue: 14405, subscription: 300 },\n { revenue: 9400, subscription: 200 },\n { revenue: 8200, subscription: 278 },\n { revenue: 7000, subscription: 189 },\n { revenue: 9600, subscription: 239 },\n { revenue: 11244, subscription: 278 },\n { revenue: 26475, subscription: 189 },\n]\n\nconst cfg = useConfigStore()\n\nconst { isDark } = useData()\nconst theme = computed(() => themes.find(theme => theme.name === cfg.config.value.theme))\n\nconst lineX = (d: Data, i: number) => i\nconst lineY = (d: Data) => d.revenue\n</script>\n\n<template>\n <div class=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-2\">\n <Card>\n <CardHeader class=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle class=\"text-sm font-normal\">\n Total Revenue\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div class=\"text-2xl font-bold\">\n $15,231.89\n </div>\n <p class=\"text-xs text-muted-foreground\">\n +20.1% from last month\n </p>\n\n <div class=\"h-20\">\n <VisXYContainer\n height=\"80px\"\n :data=\"data\" :margin=\"{\n top: 5,\n right: 10,\n left: 10,\n bottom: 0,\n }\"\n >\n <VisLine :x=\"lineX\" :y=\"lineY\" color=\"hsl(var(--primary))\" />\n <VisScatter :x=\"lineX\" :y=\"lineY\" :size=\"6\" stroke-color=\"hsl(var(--primary))\" :stroke-width=\"2\" color=\"white\" />\n </VisXYContainer>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader class=\"pb-2\">\n <CardTitle class=\"text-lg\">\n Subscriptions\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div class=\"text-2xl font-bold\">\n +2,350\n </div>\n <p class=\"text-xs text-muted-foreground\">\n +54.8% from last month\n </p>\n\n <div class=\"mt-4 h-20\">\n <VisXYContainer\n height=\"80px\" :data=\"data\" :style=\"{\n '--theme-primary': `hsl(${\n theme?.cssVars?.[isDark ? 'dark' : 'light']?.primary\n })`,\n }\"\n >\n <VisStackedBar\n :x=\"lineX\"\n :y=\"(d: Data) => d.subscription\"\n :bar-padding=\"0.1\"\n :rounded-corners=\"0\" color=\"hsl(var(--primary))\"\n />\n </VisXYContainer>\n </div>\n </CardContent>\n </Card>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CardWithForm",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card",
|
|
"input",
|
|
"label",
|
|
"select"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CardWithForm.vue",
|
|
"content": "<script setup lang=\"ts\">\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 { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/default/ui/select'\n</script>\n\n<template>\n <Card class=\"w-[350px]\">\n <CardHeader>\n <CardTitle>Create project</CardTitle>\n <CardDescription>Deploy your new project in one-click.</CardDescription>\n </CardHeader>\n <CardContent>\n <form>\n <div class=\"grid w-full items-center gap-4\">\n <div class=\"flex flex-col space-y-1.5\">\n <Label for=\"name\">Name</Label>\n <Input id=\"name\" placeholder=\"Name of your project\" />\n </div>\n <div class=\"flex flex-col space-y-1.5\">\n <Label for=\"framework\">Framework</Label>\n <Select>\n <SelectTrigger id=\"framework\">\n <SelectValue placeholder=\"Select\" />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectItem value=\"next\">\n Next.js\n </SelectItem>\n <SelectItem value=\"sveltekit\">\n SvelteKit\n </SelectItem>\n <SelectItem value=\"astro\">\n Astro\n </SelectItem>\n <SelectItem value=\"nuxt\">\n Nuxt\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n </form>\n </CardContent>\n <CardFooter class=\"flex justify-between\">\n <Button variant=\"outline\">\n Cancel\n </Button>\n <Button>Deploy</Button>\n </CardFooter>\n </Card>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselApi",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"carousel",
|
|
"card"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselApi.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { CarouselApi } from '@/registry/default/ui/carousel'\nimport { Card, CardContent } from '@/registry/default/ui/card'\nimport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/default/ui/carousel'\nimport { watchOnce } from '@vueuse/core'\nimport { ref } from 'vue'\n\nconst api = ref<CarouselApi>()\nconst totalCount = ref(0)\nconst current = ref(0)\n\nfunction setApi(val: CarouselApi) {\n api.value = val\n}\n\nwatchOnce(api, (api) => {\n if (!api)\n return\n\n totalCount.value = api.scrollSnapList().length\n current.value = api.selectedScrollSnap() + 1\n\n api.on('select', () => {\n current.value = api.selectedScrollSnap() + 1\n })\n})\n</script>\n\n<template>\n <div class=\"w-full sm:w-auto\">\n <Carousel class=\"relative w-full max-w-xs\" @init-api=\"setApi\">\n <CarouselContent>\n <CarouselItem v-for=\"(_, index) in 5\" :key=\"index\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-4xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n\n <div class=\"py-2 text-center text-sm text-muted-foreground\">\n Slide {{ current }} of {{ totalCount }}\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"card",
|
|
"carousel"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/default/ui/card'\nimport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/default/ui/carousel'\n</script>\n\n<template>\n <Carousel v-slot=\"{ canScrollNext }\" class=\"relative w-full max-w-xs\">\n <CarouselContent>\n <CarouselItem v-for=\"(_, index) in 5\" :key=\"index\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-4xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext v-if=\"canScrollNext\" />\n </Carousel>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselOrientation",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"card",
|
|
"carousel"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselOrientation.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/default/ui/card'\nimport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/default/ui/carousel'\n</script>\n\n<template>\n <Carousel\n orientation=\"vertical\"\n class=\"relative w-full max-w-xsw-full max-w-xs\"\n :opts=\"{\n align: 'start',\n }\"\n >\n <CarouselContent class=\"-mt-1 h-[200px]\">\n <CarouselItem v-for=\"(_, index) in 5\" :key=\"index\" class=\"p-1 md:basis-1/2\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex items-center justify-center p-6\">\n <span class=\"text-3xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselPlugin",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"card",
|
|
"carousel"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselPlugin.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/default/ui/card'\nimport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/default/ui/carousel'\nimport Autoplay from 'embla-carousel-autoplay'\n\nconst plugin = Autoplay({\n delay: 2000,\n stopOnMouseEnter: true,\n stopOnInteraction: false,\n})\n</script>\n\n<template>\n <Carousel\n class=\"relative w-full max-w-xs\"\n :plugins=\"[plugin]\"\n @mouseenter=\"plugin.stop\"\n @mouseleave=\"[plugin.reset(), plugin.play(), console.log('Running')];\"\n >\n <CarouselContent>\n <CarouselItem v-for=\"(_, index) in 5\" :key=\"index\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-4xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselSize",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"card",
|
|
"carousel"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselSize.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/default/ui/card'\nimport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/default/ui/carousel'\n</script>\n\n<template>\n <Carousel\n class=\"relative w-full max-w-sm\"\n :opts=\"{\n align: 'start',\n }\"\n >\n <CarouselContent>\n <CarouselItem v-for=\"(_, index) in 5\" :key=\"index\" class=\"md:basis-1/2 lg:basis-1/3\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-3xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselSpacing",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"card",
|
|
"carousel"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselSpacing.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/default/ui/card'\nimport { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/default/ui/carousel'\n</script>\n\n<template>\n <Carousel\n class=\"relative w-full max-w-sm\"\n :opts=\"{\n align: 'start',\n }\"\n >\n <CarouselContent class=\"-ml-1\">\n <CarouselItem v-for=\"(_, index) in 5\" :key=\"index\" class=\"pl-1 md:basis-1/2 lg:basis-1/3\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-2xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CarouselThumbnails",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"card",
|
|
"carousel"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CarouselThumbnails.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/default/ui/card'\nimport { Carousel, type CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/registry/default/ui/carousel'\nimport { watchOnce } from '@vueuse/core'\nimport { ref } from 'vue'\n\nconst emblaMainApi = ref<CarouselApi>()\nconst emblaThumbnailApi = ref<CarouselApi>()\nconst selectedIndex = ref(0)\n\nfunction onSelect() {\n if (!emblaMainApi.value || !emblaThumbnailApi.value)\n return\n selectedIndex.value = emblaMainApi.value.selectedScrollSnap()\n emblaThumbnailApi.value.scrollTo(emblaMainApi.value.selectedScrollSnap())\n}\n\nfunction onThumbClick(index: number) {\n if (!emblaMainApi.value || !emblaThumbnailApi.value)\n return\n emblaMainApi.value.scrollTo(index)\n}\n\nwatchOnce(emblaMainApi, (emblaMainApi) => {\n if (!emblaMainApi)\n return\n\n onSelect()\n emblaMainApi.on('select', onSelect)\n emblaMainApi.on('reInit', onSelect)\n})\n</script>\n\n<template>\n <div class=\"w-full sm:w-auto\">\n <Carousel\n class=\"relative w-full max-w-xs\"\n @init-api=\"(val) => emblaMainApi = val\"\n >\n <CarouselContent>\n <CarouselItem v-for=\"(_, index) in 10\" :key=\"index\">\n <div class=\"p-1\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-4xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n <CarouselPrevious />\n <CarouselNext />\n </Carousel>\n\n <Carousel\n class=\"relative w-full max-w-xs\"\n @init-api=\"(val) => emblaThumbnailApi = val\"\n >\n <CarouselContent class=\"flex gap-1 ml-0\">\n <CarouselItem v-for=\"(_, index) in 10\" :key=\"index\" class=\"pl-0 basis-1/4 cursor-pointer\" @click=\"onThumbClick(index)\">\n <div class=\"p-1\" :class=\"index === selectedIndex ? '' : 'opacity-50'\">\n <Card>\n <CardContent class=\"flex aspect-square items-center justify-center p-6\">\n <span class=\"text-4xl font-semibold\">{{ index + 1 }}</span>\n </CardContent>\n </Card>\n </div>\n </CarouselItem>\n </CarouselContent>\n </Carousel>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CheckboxDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"checkbox"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CheckboxDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@/registry/default/ui/checkbox'\n</script>\n\n<template>\n <div class=\"flex items-center space-x-2\">\n <Checkbox id=\"terms\" />\n <label\n for=\"terms\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Accept terms and conditions\n </label>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CheckboxDisabled",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"checkbox"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CheckboxDisabled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@/registry/default/ui/checkbox'\n</script>\n\n<template>\n <div class=\"items-top flex space-x-2\">\n <Checkbox id=\"terms1\" disabled />\n <label\n for=\"terms2\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Accept terms and conditions\n </label>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CheckboxFormMultiple",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"checkbox",
|
|
"form",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CheckboxFormMultiple.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Checkbox } from '@/registry/default/ui/checkbox'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/default/ui/form'\nimport { toast } from '@/registry/default/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst items = [\n {\n id: 'recents',\n label: 'Recents',\n },\n {\n id: 'home',\n label: 'Home',\n },\n {\n id: 'applications',\n label: 'Applications',\n },\n {\n id: 'desktop',\n label: 'Desktop',\n },\n {\n id: 'downloads',\n label: 'Downloads',\n },\n {\n id: 'documents',\n label: 'Documents',\n },\n] as const\n\nconst formSchema = toTypedSchema(z.object({\n items: z.array(z.string()).refine(value => value.some(item => item), {\n message: 'You have to select at least one item.',\n }),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n initialValues: {\n items: ['recents', 'home'],\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 @submit=\"onSubmit\">\n <FormField name=\"items\">\n <FormItem>\n <div class=\"mb-4\">\n <FormLabel class=\"text-base\">\n Sidebar\n </FormLabel>\n <FormDescription>\n Select the items you want to display in the sidebar.\n </FormDescription>\n </div>\n\n <FormField v-for=\"item in items\" v-slot=\"{ value, handleChange }\" :key=\"item.id\" type=\"checkbox\" :value=\"item.id\" :unchecked-value=\"false\" name=\"items\">\n <FormItem class=\"flex flex-row items-start space-x-3 space-y-0\">\n <FormControl>\n <Checkbox\n :model-value=\"value.includes(item.id)\"\n @update:model-value=\"handleChange\"\n />\n </FormControl>\n <FormLabel class=\"font-normal\">\n {{ item.label }}\n </FormLabel>\n </FormItem>\n </FormField>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <div class=\"flex justify-start mt-4\">\n <Button type=\"submit\">\n Submit\n </Button>\n </div>\n </form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CheckboxFormSingle",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"checkbox",
|
|
"form",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CheckboxFormSingle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Checkbox } from '@/registry/default/ui/checkbox'\nimport {\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/default/ui/form'\nimport { toast } from '@/registry/default/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n mobile: z.boolean().default(false).optional(),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n initialValues: {\n mobile: true,\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 v-slot=\"{ value, handleChange }\" type=\"checkbox\" name=\"mobile\">\n <FormItem class=\"flex flex-row items-start gap-x-3 space-y-0 rounded-md border p-4\">\n <FormControl>\n <Checkbox :model-value=\"value\" @update:model-value=\"handleChange\" />\n </FormControl>\n <div class=\"space-y-1 leading-none\">\n <FormLabel>Use different settings for my mobile devices</FormLabel>\n <FormDescription>\n You can manage your mobile notifications in the\n <a href=\"/examples/forms\">mobile settings</a> page.\n </FormDescription>\n <FormMessage />\n </div>\n </FormItem>\n </FormField>\n <Button type=\"submit\">\n Submit\n </Button>\n </Form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CheckboxWithText",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"checkbox"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CheckboxWithText.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@/registry/default/ui/checkbox'\n</script>\n\n<template>\n <div class=\"items-top flex gap-x-2\">\n <Checkbox id=\"terms1\" />\n <div class=\"grid gap-1.5 leading-none\">\n <label\n for=\"terms1\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Accept terms and conditions\n </label>\n <p class=\"text-sm text-muted-foreground\">\n You agree to our Terms of Service and Privacy Policy.\n </p>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CollapsibleDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"collapsible"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CollapsibleDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/default/ui/collapsible'\nimport { ChevronsUpDown } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst isOpen = ref(false)\n</script>\n\n<template>\n <Collapsible\n v-model:open=\"isOpen\"\n class=\"w-[350px] space-y-2\"\n >\n <div class=\"flex items-center justify-between space-x-4 px-4\">\n <h4 class=\"text-sm font-semibold\">\n @peduarte starred 3 repositories\n </h4>\n <CollapsibleTrigger as-child>\n <Button variant=\"ghost\" size=\"sm\" class=\"w-9 p-0\">\n <ChevronsUpDown class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle</span>\n </Button>\n </CollapsibleTrigger>\n </div>\n <div class=\"rounded-md border px-4 py-3 font-mono text-sm\">\n @radix-ui/primitives\n </div>\n <CollapsibleContent class=\"space-y-2\">\n <div class=\"rounded-md border px-4 py-3 font-mono text-sm\">\n @radix-ui/colors\n </div>\n <div class=\"rounded-md border px-4 py-3 font-mono text-sm\">\n @stitches/react\n </div>\n </CollapsibleContent>\n </Collapsible>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ComboboxDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"command",
|
|
"popover"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ComboboxDemo.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ComboboxDropdownMenu",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"command",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ComboboxDropdownMenu.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 DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport { Calendar, MoreHorizontal, Tags, Trash, User } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst labels = [\n 'feature',\n 'bug',\n 'enhancement',\n 'documentation',\n 'design',\n 'question',\n 'maintenance',\n]\n\nconst labelRef = ref('feature')\nconst open = ref(false)\n</script>\n\n<template>\n <div class=\"flex w-full flex-col items-start justify-between rounded-md border px-4 py-3 sm:flex-row sm:items-center\">\n <p class=\"text-sm font-medium leading-none\">\n <span class=\"mr-2 rounded-lg bg-primary px-2 py-1 text-xs text-primary-foreground\">\n {{ labelRef }}\n </span>\n <span class=\"text-muted-foreground\">Create a new project</span>\n </p>\n <DropdownMenu v-model:open=\"open\">\n <DropdownMenuTrigger as-child>\n <Button variant=\"ghost\" size=\"sm\">\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" class=\"w-[200px]\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <User class=\"mr-2 h-4 w-4\" />\n Assign to...\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Calendar class=\"mr-2 h-4 w-4\" />\n Set due date...\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuSub>\n <DropdownMenuSubTrigger>\n <Tags class=\"mr-2 h-4 w-4\" />\n Apply label\n </DropdownMenuSubTrigger>\n <DropdownMenuSubContent class=\"p-0\">\n <Command>\n <CommandInput\n placeholder=\"Filter label...\"\n auto-focus\n />\n <CommandList>\n <CommandEmpty>No label found.</CommandEmpty>\n <CommandGroup>\n <CommandItem\n v-for=\"label in labels\"\n :key=\"label\"\n :value=\"label\"\n @select=\"(ev) => {\n labelRef = ev.detail.value as string\n open = false\n }\"\n >\n {{ label }}\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n <DropdownMenuSeparator />\n <DropdownMenuItem class=\"text-red-600\">\n <Trash class=\"mr-2 h-4 w-4\" />\n Delete\n <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ComboboxForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"command",
|
|
"form",
|
|
"popover",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ComboboxForm.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ComboboxPopover",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"command",
|
|
"popover"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ComboboxPopover.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ComboboxResponsive",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"command",
|
|
"drawer",
|
|
"popover"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ComboboxResponsive.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { Button } from '@/registry/default/ui/button'\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/registry/default/ui/command'\nimport { Drawer, DrawerContent, DrawerTrigger } from '@/registry/default/ui/drawer'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/registry/default/ui/popover'\nimport { createReusableTemplate, useMediaQuery } from '@vueuse/core'\nimport { ref } from 'vue'\n\ninterface Status {\n value: string\n label: string\n}\n\nconst statuses: Status[] = [\n {\n value: 'backlog',\n label: 'Backlog',\n },\n {\n value: 'todo',\n label: 'Todo',\n },\n {\n value: 'in progress',\n label: 'In Progress',\n },\n {\n value: 'done',\n label: 'Done',\n },\n {\n value: 'canceled',\n label: 'Canceled',\n },\n]\n\nconst [UseTemplate, StatusList] = createReusableTemplate()\nconst isDesktop = useMediaQuery('(min-width: 768px)')\n\nconst isOpen = ref(false)\nconst selectedStatus = ref<Status | null>(null)\n\nfunction onStatusSelect(status: Status) {\n selectedStatus.value = status\n isOpen.value = false\n}\n</script>\n\n<template>\n <div>\n <UseTemplate>\n <Command>\n <CommandInput placeholder=\"Filter status...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup>\n <CommandItem\n v-for=\"status of statuses\"\n :key=\"status.value\"\n :value=\"status.value\"\n @select=\"onStatusSelect(status)\"\n >\n {{ status.label }}\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </UseTemplate>\n\n <Popover v-if=\"isDesktop\" v-model:open=\"isOpen\">\n <PopoverTrigger as-child>\n <Button variant=\"outline\" class=\"w-[150px] justify-start\">\n {{ selectedStatus ? selectedStatus.label : \"+ Set status\" }}\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-[200px] p-0\" align=\"start\">\n <StatusList />\n </PopoverContent>\n </Popover>\n\n <Drawer v-else :open=\"isOpen\" @update:open=\"(newOpenValue) => isOpen = newOpenValue\">\n <DrawerTrigger as-child>\n <Button variant=\"outline\" class=\"w-[150px] justify-start\">\n {{ selectedStatus ? selectedStatus.label : \"+ Set status\" }}\n </Button>\n </DrawerTrigger>\n <DrawerContent>\n <div class=\"mt-4 border-t\">\n <StatusList />\n </div>\n </DrawerContent>\n </Drawer>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CommandDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"command"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CommandDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n CommandShortcut,\n} from '@/registry/default/ui/command'\n\nimport {\n Calculator,\n Calendar,\n CreditCard,\n Settings,\n Smile,\n User,\n} from 'lucide-vue-next'\n</script>\n\n<template>\n <Command class=\"rounded-lg border shadow-md max-w-[450px]\">\n <CommandInput placeholder=\"Type a command or search...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup heading=\"Suggestions\">\n <CommandItem value=\"Calendar\">\n <Calendar class=\"mr-2 h-4 w-4\" />\n <span>Calendar</span>\n </CommandItem>\n <CommandItem value=\"Search Emoji\">\n <Smile class=\"mr-2 h-4 w-4\" />\n <span>Search Emoji</span>\n </CommandItem>\n <CommandItem value=\"Calculator\">\n <Calculator class=\"mr-2 h-4 w-4\" />\n <span>Calculator</span>\n </CommandItem>\n </CommandGroup>\n <CommandSeparator />\n <CommandGroup heading=\"Settings\">\n <CommandItem value=\"Profile\">\n <User class=\"mr-2 h-4 w-4\" />\n <span>Profile</span>\n <CommandShortcut>⌘P</CommandShortcut>\n </CommandItem>\n <CommandItem value=\"Billing\">\n <CreditCard class=\"mr-2 h-4 w-4\" />\n <span>Billing</span>\n <CommandShortcut>⌘B</CommandShortcut>\n </CommandItem>\n <CommandItem value=\"Settings\">\n <Settings class=\"mr-2 h-4 w-4\" />\n <span>Settings</span>\n <CommandShortcut>⌘S</CommandShortcut>\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CommandDialogDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"command"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CommandDialogDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n} from '@/registry/default/ui/command'\n\nimport { useMagicKeys } from '@vueuse/core'\nimport { ref, watch } from 'vue'\n\nconst open = ref(false)\n\nconst { Meta_J, Ctrl_J } = useMagicKeys({\n passive: false,\n onEventFired(e) {\n if (e.key === 'j' && (e.metaKey || e.ctrlKey))\n e.preventDefault()\n },\n})\n\nwatch([Meta_J, Ctrl_J], (v) => {\n if (v[0] || v[1])\n handleOpenChange()\n})\n\nfunction handleOpenChange() {\n open.value = !open.value\n}\n</script>\n\n<template>\n <div>\n <p class=\"text-sm text-muted-foreground\">\n Press\n <kbd\n class=\"pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100\"\n >\n <span class=\"text-xs\">⌘</span>J\n </kbd>\n </p>\n <CommandDialog v-model:open=\"open\">\n <CommandInput placeholder=\"Type a command or search...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup heading=\"Suggestions\">\n <CommandItem value=\"calendar\">\n Calendar\n </CommandItem>\n <CommandItem value=\"search-emoji\">\n Search Emoji\n </CommandItem>\n <CommandItem value=\"calculator\">\n Calculator\n </CommandItem>\n </CommandGroup>\n <CommandSeparator />\n <CommandGroup heading=\"Settings\">\n <CommandItem value=\"profile\">\n Profile\n </CommandItem>\n <CommandItem value=\"billing\">\n Billing\n </CommandItem>\n <CommandItem value=\"settings\">\n Settings\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </CommandDialog>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ContextMenuDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"context-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ContextMenuDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n ContextMenu,\n ContextMenuCheckboxItem,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuLabel,\n ContextMenuRadioGroup,\n ContextMenuRadioItem,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuTrigger,\n} from '@/registry/default/ui/context-menu'\n</script>\n\n<template>\n <ContextMenu>\n <ContextMenuTrigger class=\"flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm\">\n Right click here\n </ContextMenuTrigger>\n <ContextMenuContent class=\"w-64\">\n <ContextMenuItem inset>\n Back\n <ContextMenuShortcut>⌘[</ContextMenuShortcut>\n </ContextMenuItem>\n <ContextMenuItem inset disabled>\n Forward\n <ContextMenuShortcut>⌘]</ContextMenuShortcut>\n </ContextMenuItem>\n <ContextMenuItem inset>\n Reload\n <ContextMenuShortcut>⌘R</ContextMenuShortcut>\n </ContextMenuItem>\n <ContextMenuSub>\n <ContextMenuSubTrigger inset>\n More Tools\n </ContextMenuSubTrigger>\n <ContextMenuSubContent class=\"w-48\">\n <ContextMenuItem>\n Save Page As...\n <ContextMenuShortcut>⇧⌘S</ContextMenuShortcut>\n </ContextMenuItem>\n <ContextMenuItem>Create Shortcut...</ContextMenuItem>\n <ContextMenuItem>Name Window...</ContextMenuItem>\n <ContextMenuSeparator />\n <ContextMenuItem>Developer Tools</ContextMenuItem>\n </ContextMenuSubContent>\n </ContextMenuSub>\n <ContextMenuSeparator />\n <ContextMenuCheckboxItem checked>\n Show Bookmarks Bar\n <ContextMenuShortcut>⌘⇧B</ContextMenuShortcut>\n </ContextMenuCheckboxItem>\n <ContextMenuCheckboxItem>Show Full URLs</ContextMenuCheckboxItem>\n <ContextMenuSeparator />\n <ContextMenuRadioGroup model-value=\"pedro\">\n <ContextMenuLabel inset>\n People\n </ContextMenuLabel>\n <ContextMenuSeparator />\n <ContextMenuRadioItem value=\"pedro\">\n Pedro Duarte\n </ContextMenuRadioItem>\n <ContextMenuRadioItem value=\"colm\">\n Colm Tuite\n </ContextMenuRadioItem>\n </ContextMenuRadioGroup>\n </ContextMenuContent>\n </ContextMenu>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "CustomChartTooltip",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"card"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/CustomChartTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Card, CardContent } from '@/registry/default/ui/card'\n\ndefineProps<{\n title?: string\n data: {\n name: string\n color: string\n value: any\n }[]\n}>()\n</script>\n\n<template>\n <Card class=\"text-sm\">\n <CardContent class=\"p-3 min-w-[180px] flex flex-col gap-2\">\n <div v-for=\"(item, key) in data\" :key=\"key\" class=\"flex justify-between items-center\">\n <div class=\"flex items-center\">\n <span class=\"w-1 h-7 mr-4 rounded-full\" :style=\"{ background: item.color }\" />\n <span>{{ item.name }}</span>\n </div>\n <span class=\"font-semibold ml-4\">{{ item.value }}</span>\n </div>\n </CardContent>\n </Card>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DataTableColumnPinningDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@tanstack/vue-table"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"checkbox",
|
|
"dropdown-menu",
|
|
"input",
|
|
"table"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DataTableColumnPinningDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type {\n ColumnFiltersState,\n ExpandedState,\n SortingState,\n VisibilityState,\n} from '@tanstack/vue-table'\nimport { cn, valueUpdater } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\n\nimport { Checkbox } from '@/registry/default/ui/checkbox'\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport { Input } from '@/registry/default/ui/input'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/default/ui/table'\nimport {\n createColumnHelper,\n FlexRender,\n getCoreRowModel,\n getExpandedRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useVueTable,\n} from '@tanstack/vue-table'\nimport { ArrowUpDown, ChevronDown } from 'lucide-vue-next'\nimport { h, ref } from 'vue'\nimport DropdownAction from './DataTableDemoColumn.vue'\n\nexport interface Payment {\n id: string\n amount: number\n status: 'pending' | 'processing' | 'success' | 'failed'\n email: string\n}\n\nconst data: Payment[] = [\n {\n id: 'm5gr84i9',\n amount: 316,\n status: 'success',\n email: 'ken99@yahoo.com',\n },\n {\n id: '3u1reuv4',\n amount: 242,\n status: 'success',\n email: 'Abe45@gmail.com',\n },\n {\n id: 'derv1ws0',\n amount: 837,\n status: 'processing',\n email: 'Monserrat44@gmail.com',\n },\n {\n id: '5kma53ae',\n amount: 874,\n status: 'success',\n email: 'Silas22@gmail.com',\n },\n {\n id: 'bhqecj4p',\n amount: 721,\n status: 'failed',\n email: 'carmella@hotmail.com',\n },\n]\n\nconst columnHelper = createColumnHelper<Payment>()\n\nconst columns = [\n columnHelper.display({\n id: 'select',\n header: ({ table }) => h(Checkbox, {\n 'modelValue': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),\n 'onUpdate:modelValue': value => table.toggleAllPageRowsSelected(!!value),\n 'ariaLabel': 'Select all',\n }),\n cell: ({ row }) => {\n return h(Checkbox, {\n 'modelValue': row.getIsSelected(),\n 'onUpdate:modelValue': value => row.toggleSelected(!!value),\n 'ariaLabel': 'Select row',\n })\n },\n enableSorting: false,\n enableHiding: false,\n }),\n columnHelper.accessor('status', {\n enablePinning: true,\n header: 'Status',\n cell: ({ row }) => h('div', { class: 'capitalize' }, row.getValue('status')),\n }),\n columnHelper.accessor('email', {\n header: ({ column }) => {\n return h(Button, {\n variant: 'ghost',\n onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'),\n }, () => ['Email', h(ArrowUpDown, { class: 'ml-2 h-4 w-4' })])\n },\n cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),\n }),\n columnHelper.accessor('amount', {\n header: () => h('div', { class: 'text-right' }, 'Amount'),\n cell: ({ row }) => {\n const amount = Number.parseFloat(row.getValue('amount'))\n\n // Format the amount as a dollar amount\n const formatted = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n }).format(amount)\n\n return h('div', { class: 'text-right font-medium' }, formatted)\n },\n }),\n columnHelper.display({\n id: 'actions',\n enableHiding: false,\n cell: ({ row }) => {\n const payment = row.original\n\n return h('div', { class: 'relative' }, h(DropdownAction, {\n payment,\n onExpand: row.toggleExpanded,\n }))\n },\n }),\n]\n\nconst sorting = ref<SortingState>([])\nconst columnFilters = ref<ColumnFiltersState>([])\nconst columnVisibility = ref<VisibilityState>({})\nconst rowSelection = ref({})\nconst expanded = ref<ExpandedState>({})\n\nconst table = useVueTable({\n data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getExpandedRowModel: getExpandedRowModel(),\n onSortingChange: updaterOrValue => valueUpdater(updaterOrValue, sorting),\n onColumnFiltersChange: updaterOrValue => valueUpdater(updaterOrValue, columnFilters),\n onColumnVisibilityChange: updaterOrValue => valueUpdater(updaterOrValue, columnVisibility),\n onRowSelectionChange: updaterOrValue => valueUpdater(updaterOrValue, rowSelection),\n onExpandedChange: updaterOrValue => valueUpdater(updaterOrValue, expanded),\n state: {\n get sorting() { return sorting.value },\n get columnFilters() { return columnFilters.value },\n get columnVisibility() { return columnVisibility.value },\n get rowSelection() { return rowSelection.value },\n get expanded() { return expanded.value },\n columnPinning: {\n left: ['status'],\n },\n },\n})\n</script>\n\n<template>\n <div class=\"w-full\">\n <div class=\"flex gap-2 items-center py-4\">\n <Input\n class=\"max-w-sm\"\n placeholder=\"Filter emails...\"\n :model-value=\"table.getColumn('email')?.getFilterValue() as string\"\n @update:model-value=\" table.getColumn('email')?.setFilterValue($event)\"\n />\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\" class=\"ml-auto\">\n Columns <ChevronDown class=\"ml-2 h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuCheckboxItem\n v-for=\"column in table.getAllColumns().filter((column) => column.getCanHide())\"\n :key=\"column.id\"\n class=\"capitalize\"\n :model-value=\"column.getIsVisible()\"\n @update:model-value=\"(value) => {\n column.toggleVisibility(!!value)\n }\"\n >\n {{ column.id }}\n </DropdownMenuCheckboxItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n <div class=\"rounded-md border\">\n <Table>\n <TableHeader>\n <TableRow v-for=\"headerGroup in table.getHeaderGroups()\" :key=\"headerGroup.id\">\n <TableHead\n v-for=\"header in headerGroup.headers\" :key=\"header.id\" :data-pinned=\"header.column.getIsPinned()\"\n :class=\"cn(\n { 'sticky bg-background/95': header.column.getIsPinned() },\n header.column.getIsPinned() === 'left' ? 'left-0' : 'right-0',\n )\"\n >\n <FlexRender v-if=\"!header.isPlaceholder\" :render=\"header.column.columnDef.header\" :props=\"header.getContext()\" />\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <template v-if=\"table.getRowModel().rows?.length\">\n <template v-for=\"row in table.getRowModel().rows\" :key=\"row.id\">\n <TableRow :data-state=\"row.getIsSelected() && 'selected'\">\n <TableCell\n v-for=\"cell in row.getVisibleCells()\" :key=\"cell.id\" :data-pinned=\"cell.column.getIsPinned()\"\n :class=\"cn(\n { 'sticky bg-background/95': cell.column.getIsPinned() },\n cell.column.getIsPinned() === 'left' ? 'left-0' : 'right-0',\n )\"\n >\n <FlexRender :render=\"cell.column.columnDef.cell\" :props=\"cell.getContext()\" />\n </TableCell>\n </TableRow>\n <TableRow v-if=\"row.getIsExpanded()\">\n <TableCell :colspan=\"row.getAllCells().length\">\n {{ row.original }}\n </TableCell>\n </TableRow>\n </template>\n </template>\n\n <TableRow v-else>\n <TableCell\n :colspan=\"columns.length\"\n class=\"h-24 text-center\"\n >\n No results.\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </div>\n\n <div class=\"flex items-center justify-end space-x-2 py-4\">\n <div class=\"flex-1 text-sm text-muted-foreground\">\n {{ table.getFilteredSelectedRowModel().rows.length }} of\n {{ table.getFilteredRowModel().rows.length }} row(s) selected.\n </div>\n <div class=\"space-x-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"!table.getCanPreviousPage()\"\n @click=\"table.previousPage()\"\n >\n Previous\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"!table.getCanNextPage()\"\n @click=\"table.nextPage()\"\n >\n Next\n </Button>\n </div>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DataTableDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@tanstack/vue-table"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"checkbox",
|
|
"dropdown-menu",
|
|
"input",
|
|
"table"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DataTableDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type {\n ColumnDef,\n ColumnFiltersState,\n ExpandedState,\n SortingState,\n VisibilityState,\n} from '@tanstack/vue-table'\nimport { valueUpdater } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\n\nimport { Checkbox } from '@/registry/default/ui/checkbox'\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport { Input } from '@/registry/default/ui/input'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/default/ui/table'\nimport {\n FlexRender,\n getCoreRowModel,\n getExpandedRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useVueTable,\n} from '@tanstack/vue-table'\nimport { ArrowUpDown, ChevronDown } from 'lucide-vue-next'\nimport { h, ref } from 'vue'\nimport DropdownAction from './DataTableDemoColumn.vue'\n\nexport interface Payment {\n id: string\n amount: number\n status: 'pending' | 'processing' | 'success' | 'failed'\n email: string\n}\n\nconst data: Payment[] = [\n {\n id: 'm5gr84i9',\n amount: 316,\n status: 'success',\n email: 'ken99@yahoo.com',\n },\n {\n id: '3u1reuv4',\n amount: 242,\n status: 'success',\n email: 'Abe45@gmail.com',\n },\n {\n id: 'derv1ws0',\n amount: 837,\n status: 'processing',\n email: 'Monserrat44@gmail.com',\n },\n {\n id: '5kma53ae',\n amount: 874,\n status: 'success',\n email: 'Silas22@gmail.com',\n },\n {\n id: 'bhqecj4p',\n amount: 721,\n status: 'failed',\n email: 'carmella@hotmail.com',\n },\n]\n\nconst columns: ColumnDef<Payment>[] = [\n {\n id: 'select',\n header: ({ table }) => h(Checkbox, {\n 'modelValue': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),\n 'onUpdate:modelValue': value => table.toggleAllPageRowsSelected(!!value),\n 'ariaLabel': 'Select all',\n }),\n cell: ({ row }) => h(Checkbox, {\n 'modelValue': row.getIsSelected(),\n 'onUpdate:modelValue': value => row.toggleSelected(!!value),\n 'ariaLabel': 'Select row',\n }),\n enableSorting: false,\n enableHiding: false,\n },\n {\n accessorKey: 'status',\n header: 'Status',\n cell: ({ row }) => h('div', { class: 'capitalize' }, row.getValue('status')),\n },\n {\n accessorKey: 'email',\n header: ({ column }) => {\n return h(Button, {\n variant: 'ghost',\n onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'),\n }, () => ['Email', h(ArrowUpDown, { class: 'ml-2 h-4 w-4' })])\n },\n cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),\n },\n {\n accessorKey: 'amount',\n header: () => h('div', { class: 'text-right' }, 'Amount'),\n cell: ({ row }) => {\n const amount = Number.parseFloat(row.getValue('amount'))\n\n // Format the amount as a dollar amount\n const formatted = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n }).format(amount)\n\n return h('div', { class: 'text-right font-medium' }, formatted)\n },\n },\n {\n id: 'actions',\n enableHiding: false,\n cell: ({ row }) => {\n const payment = row.original\n\n return h('div', { class: 'relative' }, h(DropdownAction, {\n payment,\n onExpand: row.toggleExpanded,\n }))\n },\n },\n]\n\nconst sorting = ref<SortingState>([])\nconst columnFilters = ref<ColumnFiltersState>([])\nconst columnVisibility = ref<VisibilityState>({})\nconst rowSelection = ref({})\nconst expanded = ref<ExpandedState>({})\n\nconst table = useVueTable({\n data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getExpandedRowModel: getExpandedRowModel(),\n onSortingChange: updaterOrValue => valueUpdater(updaterOrValue, sorting),\n onColumnFiltersChange: updaterOrValue => valueUpdater(updaterOrValue, columnFilters),\n onColumnVisibilityChange: updaterOrValue => valueUpdater(updaterOrValue, columnVisibility),\n onRowSelectionChange: updaterOrValue => valueUpdater(updaterOrValue, rowSelection),\n onExpandedChange: updaterOrValue => valueUpdater(updaterOrValue, expanded),\n state: {\n get sorting() { return sorting.value },\n get columnFilters() { return columnFilters.value },\n get columnVisibility() { return columnVisibility.value },\n get rowSelection() { return rowSelection.value },\n get expanded() { return expanded.value },\n },\n})\n</script>\n\n<template>\n <div class=\"w-full\">\n <div class=\"flex gap-2 items-center py-4\">\n <Input\n class=\"max-w-sm\"\n placeholder=\"Filter emails...\"\n :model-value=\"table.getColumn('email')?.getFilterValue() as string\"\n @update:model-value=\" table.getColumn('email')?.setFilterValue($event)\"\n />\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\" class=\"ml-auto\">\n Columns <ChevronDown class=\"ml-2 h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuCheckboxItem\n v-for=\"column in table.getAllColumns().filter((column) => column.getCanHide())\"\n :key=\"column.id\"\n class=\"capitalize\"\n :model-value=\"column.getIsVisible()\"\n @update:model-value=\"(value) => {\n column.toggleVisibility(!!value)\n }\"\n >\n {{ column.id }}\n </DropdownMenuCheckboxItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n <div class=\"rounded-md border\">\n <Table>\n <TableHeader>\n <TableRow v-for=\"headerGroup in table.getHeaderGroups()\" :key=\"headerGroup.id\">\n <TableHead v-for=\"header in headerGroup.headers\" :key=\"header.id\">\n <FlexRender v-if=\"!header.isPlaceholder\" :render=\"header.column.columnDef.header\" :props=\"header.getContext()\" />\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <template v-if=\"table.getRowModel().rows?.length\">\n <template v-for=\"row in table.getRowModel().rows\" :key=\"row.id\">\n <TableRow :data-state=\"row.getIsSelected() && 'selected'\">\n <TableCell v-for=\"cell in row.getVisibleCells()\" :key=\"cell.id\">\n <FlexRender :render=\"cell.column.columnDef.cell\" :props=\"cell.getContext()\" />\n </TableCell>\n </TableRow>\n <TableRow v-if=\"row.getIsExpanded()\">\n <TableCell :colspan=\"row.getAllCells().length\">\n {{ JSON.stringify(row.original) }}\n </TableCell>\n </TableRow>\n </template>\n </template>\n\n <TableRow v-else>\n <TableCell\n :colspan=\"columns.length\"\n class=\"h-24 text-center\"\n >\n No results.\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </div>\n\n <div class=\"flex items-center justify-end space-x-2 py-4\">\n <div class=\"flex-1 text-sm text-muted-foreground\">\n {{ table.getFilteredSelectedRowModel().rows.length }} of\n {{ table.getFilteredRowModel().rows.length }} row(s) selected.\n </div>\n <div class=\"space-x-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"!table.getCanPreviousPage()\"\n @click=\"table.previousPage()\"\n >\n Previous\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"!table.getCanNextPage()\"\n @click=\"table.nextPage()\"\n >\n Next\n </Button>\n </div>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DataTableDemoColumn",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DataTableDemoColumn.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/default/ui/dropdown-menu'\nimport { MoreHorizontal } from 'lucide-vue-next'\n\ndefineProps<{\n payment: {\n id: string\n }\n}>()\n\ndefineEmits<{\n (e: 'expand'): void\n}>()\n\nfunction copy(id: string) {\n navigator.clipboard.writeText(id)\n}\n</script>\n\n<template>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"ghost\" class=\"h-8 w-8 p-0\">\n <span class=\"sr-only\">Open menu</span>\n <MoreHorizontal class=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem @click=\"copy(payment.id)\">\n Copy payment ID\n </DropdownMenuItem>\n <DropdownMenuItem @click=\"$emit('expand')\">\n Expand\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>View customer</DropdownMenuItem>\n <DropdownMenuItem>View payment details</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DataTableReactiveDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@tanstack/vue-table"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"checkbox",
|
|
"dropdown-menu",
|
|
"input",
|
|
"table"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DataTableReactiveDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type {\n ColumnDef,\n ColumnFiltersState,\n ExpandedState,\n SortingState,\n VisibilityState,\n} from '@tanstack/vue-table'\nimport { valueUpdater } from '@/lib/utils'\nimport { Button } from '@/registry/default/ui/button'\n\nimport { Checkbox } from '@/registry/default/ui/checkbox'\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport { Input } from '@/registry/default/ui/input'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/default/ui/table'\nimport {\n FlexRender,\n getCoreRowModel,\n getExpandedRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n useVueTable,\n} from '@tanstack/vue-table'\nimport { ArrowUpDown, ChevronDown } from 'lucide-vue-next'\nimport { h, ref, shallowRef } from 'vue'\nimport DropdownAction from './DataTableDemoColumn.vue'\n\nexport interface Payment {\n id: string\n amount: number\n status: 'pending' | 'processing' | 'success' | 'failed'\n email: string\n}\n\nconst data = shallowRef<Payment[]>([\n {\n id: 'm5gr84i9',\n amount: 316,\n status: 'success',\n email: 'ken99@yahoo.com',\n },\n {\n id: '3u1reuv4',\n amount: 242,\n status: 'success',\n email: 'Abe45@gmail.com',\n },\n {\n id: 'derv1ws0',\n amount: 837,\n status: 'processing',\n email: 'Monserrat44@gmail.com',\n },\n {\n id: '5kma53ae',\n amount: 874,\n status: 'success',\n email: 'Silas22@gmail.com',\n },\n {\n id: 'bhqecj4p',\n amount: 721,\n status: 'failed',\n email: 'carmella@hotmail.com',\n },\n])\n\nconst columns: ColumnDef<Payment>[] = [\n {\n id: 'select',\n header: ({ table }) => h(Checkbox, {\n 'modelValue': table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),\n 'onUpdate:modelValue': value => table.toggleAllPageRowsSelected(!!value),\n 'ariaLabel': 'Select all',\n }),\n cell: ({ row }) => h(Checkbox, {\n 'modelValue': row.getIsSelected(),\n 'onUpdate:modelValue': value => row.toggleSelected(!!value),\n 'ariaLabel': 'Select row',\n }),\n enableSorting: false,\n enableHiding: false,\n },\n {\n accessorKey: 'status',\n header: 'Status',\n cell: ({ row }) => h('div', { class: 'capitalize' }, row.getValue('status')),\n },\n {\n accessorKey: 'email',\n header: ({ column }) => {\n return h(Button, {\n variant: 'ghost',\n onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'),\n }, () => ['Email', h(ArrowUpDown, { class: 'ml-2 h-4 w-4' })])\n },\n cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),\n },\n {\n accessorKey: 'amount',\n header: () => h('div', { class: 'text-right' }, 'Amount'),\n cell: ({ row }) => {\n const amount = Number.parseFloat(row.getValue('amount'))\n\n // Format the amount as a dollar amount\n const formatted = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n }).format(amount)\n\n return h('div', { class: 'text-right font-medium' }, formatted)\n },\n },\n {\n id: 'actions',\n enableHiding: false,\n cell: ({ row }) => {\n const payment = row.original\n\n return h('div', { class: 'relative' }, h(DropdownAction, {\n payment,\n onExpand: row.toggleExpanded,\n }))\n },\n },\n]\n\nconst sorting = ref<SortingState>([])\nconst columnFilters = ref<ColumnFiltersState>([])\nconst columnVisibility = ref<VisibilityState>({})\nconst rowSelection = ref({})\nconst expanded = ref<ExpandedState>({})\n\nconst table = useVueTable({\n data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getExpandedRowModel: getExpandedRowModel(),\n onSortingChange: updaterOrValue => valueUpdater(updaterOrValue, sorting),\n onColumnFiltersChange: updaterOrValue => valueUpdater(updaterOrValue, columnFilters),\n onColumnVisibilityChange: updaterOrValue => valueUpdater(updaterOrValue, columnVisibility),\n onRowSelectionChange: updaterOrValue => valueUpdater(updaterOrValue, rowSelection),\n onExpandedChange: updaterOrValue => valueUpdater(updaterOrValue, expanded),\n state: {\n get sorting() { return sorting.value },\n get columnFilters() { return columnFilters.value },\n get columnVisibility() { return columnVisibility.value },\n get rowSelection() { return rowSelection.value },\n get expanded() { return expanded.value },\n },\n})\n\nconst statuses: Payment['status'][] = ['pending', 'processing', 'success', 'failed']\nfunction randomize() {\n data.value = data.value.map(item => ({\n ...item,\n status: statuses[Math.floor(Math.random() * statuses.length)],\n }))\n}\n</script>\n\n<template>\n <div class=\"w-full\">\n <div class=\"flex gap-2 items-center py-4\">\n <Input\n class=\"max-w-52\"\n placeholder=\"Filter emails...\"\n :model-value=\"table.getColumn('email')?.getFilterValue() as string\"\n @update:model-value=\" table.getColumn('email')?.setFilterValue($event)\"\n />\n <Button @click=\"randomize\">\n Randomize\n </Button>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\" class=\"ml-auto\">\n Columns <ChevronDown class=\"ml-2 h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuCheckboxItem\n v-for=\"column in table.getAllColumns().filter((column) => column.getCanHide())\"\n :key=\"column.id\"\n class=\"capitalize\"\n :model-value=\"column.getIsVisible()\"\n @update:model-value=\"(value) => {\n column.toggleVisibility(!!value)\n }\"\n >\n {{ column.id }}\n </DropdownMenuCheckboxItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n <div class=\"rounded-md border\">\n <Table>\n <TableHeader>\n <TableRow v-for=\"headerGroup in table.getHeaderGroups()\" :key=\"headerGroup.id\">\n <TableHead v-for=\"header in headerGroup.headers\" :key=\"header.id\">\n <FlexRender v-if=\"!header.isPlaceholder\" :render=\"header.column.columnDef.header\" :props=\"header.getContext()\" />\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <template v-if=\"table.getRowModel().rows?.length\">\n <template v-for=\"row in table.getRowModel().rows\" :key=\"row.id\">\n <TableRow :data-state=\"row.getIsSelected() && 'selected'\">\n <TableCell v-for=\"cell in row.getVisibleCells()\" :key=\"cell.id\">\n <FlexRender :render=\"cell.column.columnDef.cell\" :props=\"cell.getContext()\" />\n </TableCell>\n </TableRow>\n <TableRow v-if=\"row.getIsExpanded()\">\n <TableCell :colspan=\"row.getAllCells().length\">\n {{ JSON.stringify(row.original) }}\n </TableCell>\n </TableRow>\n </template>\n </template>\n\n <TableRow v-else>\n <TableCell\n :colspan=\"columns.length\"\n class=\"h-24 text-center\"\n >\n No results.\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </div>\n\n <div class=\"flex items-center justify-end space-x-2 py-4\">\n <div class=\"flex-1 text-sm text-muted-foreground\">\n {{ table.getFilteredSelectedRowModel().rows.length }} of\n {{ table.getFilteredRowModel().rows.length }} row(s) selected.\n </div>\n <div class=\"space-x-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"!table.getCanPreviousPage()\"\n @click=\"table.previousPage()\"\n >\n Previous\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"!table.getCanNextPage()\"\n @click=\"table.nextPage()\"\n >\n Next\n </Button>\n </div>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DatePickerDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"calendar",
|
|
"popover"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DatePickerDemo.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DatePickerForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"calendar",
|
|
"form",
|
|
"popover",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DatePickerForm.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DatePickerWithIndependentMonths",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"range-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DatePickerWithIndependentMonths.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\n\nimport { Button, buttonVariants } from '@/registry/default/ui/button'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\n\nimport {\n RangeCalendarCell,\n RangeCalendarCellTrigger,\n RangeCalendarGrid,\n RangeCalendarGridBody,\n RangeCalendarGridHead,\n RangeCalendarGridRow,\n RangeCalendarHeadCell,\n} from '@/registry/default/ui/range-calendar'\nimport {\n CalendarDate,\n type DateValue,\n isEqualMonth,\n} from '@internationalized/date'\nimport {\n Calendar as CalendarIcon,\n ChevronLeft,\n ChevronRight,\n} from 'lucide-vue-next'\nimport { type DateRange, RangeCalendarRoot, useDateFormatter } from 'reka-ui'\nimport { createMonth, type Grid, toDate } from 'reka-ui/date'\nimport { type Ref, ref, watch } from 'vue'\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\nconst locale = ref('en-US')\nconst formatter = useDateFormatter(locale.value)\n\nconst placeholder = ref(value.value.start) as Ref<DateValue>\nconst secondMonthPlaceholder = ref(value.value.end) as Ref<DateValue>\n\nconst firstMonth = ref(\n createMonth({\n dateObj: placeholder.value,\n locale: locale.value,\n fixedWeeks: true,\n weekStartsOn: 0,\n }),\n) as Ref<Grid<DateValue>>\nconst secondMonth = ref(\n createMonth({\n dateObj: secondMonthPlaceholder.value,\n locale: locale.value,\n fixedWeeks: true,\n weekStartsOn: 0,\n }),\n) as Ref<Grid<DateValue>>\n\nfunction updateMonth(reference: 'first' | 'second', months: number) {\n if (reference === 'first') {\n placeholder.value = placeholder.value.add({ months })\n }\n else {\n secondMonthPlaceholder.value = secondMonthPlaceholder.value.add({\n months,\n })\n }\n}\n\nwatch(placeholder, (_placeholder) => {\n firstMonth.value = createMonth({\n dateObj: _placeholder,\n weekStartsOn: 0,\n fixedWeeks: false,\n locale: locale.value,\n })\n if (isEqualMonth(secondMonthPlaceholder.value, _placeholder)) {\n secondMonthPlaceholder.value = secondMonthPlaceholder.value.add({\n months: 1,\n })\n }\n})\n\nwatch(secondMonthPlaceholder, (_secondMonthPlaceholder) => {\n secondMonth.value = createMonth({\n dateObj: _secondMonthPlaceholder,\n weekStartsOn: 0,\n fixedWeeks: false,\n locale: locale.value,\n })\n if (isEqualMonth(_secondMonthPlaceholder, placeholder.value))\n placeholder.value = placeholder.value.subtract({ months: 1 })\n})\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n :class=\"\n cn(\n 'w-[280px] justify-start text-left font-normal',\n !value && 'text-muted-foreground',\n )\n \"\n >\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\n <template v-if=\"value.start\">\n <template v-if=\"value.end\">\n {{\n formatter.custom(toDate(value.start), {\n dateStyle: \"medium\",\n })\n }}\n -\n {{\n formatter.custom(toDate(value.end), {\n dateStyle: \"medium\",\n })\n }}\n </template>\n\n <template v-else>\n {{\n formatter.custom(toDate(value.start), {\n dateStyle: \"medium\",\n })\n }}\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 <RangeCalendarRoot v-slot=\"{ weekDays }\" v-model=\"value\" v-model:placeholder=\"placeholder\" class=\"p-3\">\n <div\n class=\"flex flex-col gap-y-4 mt-4 sm:flex-row sm:gap-x-4 sm:gap-y-0\"\n >\n <div class=\"flex flex-col gap-4\">\n <div class=\"flex items-center justify-between\">\n <button\n :class=\"\n cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n )\n \"\n @click=\"updateMonth('first', -1)\"\n >\n <ChevronLeft class=\"h-4 w-4\" />\n </button>\n <div\n :class=\"cn('text-sm font-medium')\"\n >\n {{\n formatter.fullMonthAndYear(\n toDate(firstMonth.value),\n )\n }}\n </div>\n <button\n :class=\"\n cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n )\n \"\n @click=\"updateMonth('first', 1)\"\n >\n <ChevronRight class=\"h-4 w-4\" />\n </button>\n </div>\n <RangeCalendarGrid>\n <RangeCalendarGridHead>\n <RangeCalendarGridRow>\n <RangeCalendarHeadCell\n v-for=\"day in weekDays\"\n :key=\"day\"\n class=\"w-full\"\n >\n {{ day }}\n </RangeCalendarHeadCell>\n </RangeCalendarGridRow>\n </RangeCalendarGridHead>\n <RangeCalendarGridBody>\n <RangeCalendarGridRow\n v-for=\"(\n weekDates, index\n ) in firstMonth.rows\"\n :key=\"`weekDate-${index}`\"\n class=\"mt-2 w-full\"\n >\n <RangeCalendarCell\n v-for=\"weekDate in weekDates\"\n :key=\"weekDate.toString()\"\n :date=\"weekDate\"\n >\n <RangeCalendarCellTrigger\n :day=\"weekDate\"\n :month=\"firstMonth.value\"\n />\n </RangeCalendarCell>\n </RangeCalendarGridRow>\n </RangeCalendarGridBody>\n </RangeCalendarGrid>\n </div>\n <div class=\"flex flex-col gap-4\">\n <div class=\"flex items-center justify-between\">\n <button\n :class=\"\n cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n )\n \"\n @click=\"updateMonth('second', -1)\"\n >\n <ChevronLeft class=\"h-4 w-4\" />\n </button>\n <div\n :class=\"cn('text-sm font-medium')\"\n >\n {{\n formatter.fullMonthAndYear(\n toDate(secondMonth.value),\n )\n }}\n </div>\n\n <button\n :class=\"\n cn(\n buttonVariants({ variant: 'outline' }),\n 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',\n )\n \"\n @click=\"updateMonth('second', 1)\"\n >\n <ChevronRight class=\"h-4 w-4\" />\n </button>\n </div>\n <RangeCalendarGrid>\n <RangeCalendarGridHead>\n <RangeCalendarGridRow>\n <RangeCalendarHeadCell\n v-for=\"day in weekDays\"\n :key=\"day\"\n class=\"w-full\"\n >\n {{ day }}\n </RangeCalendarHeadCell>\n </RangeCalendarGridRow>\n </RangeCalendarGridHead>\n <RangeCalendarGridBody>\n <RangeCalendarGridRow\n v-for=\"(\n weekDates, index\n ) in secondMonth.rows\"\n :key=\"`weekDate-${index}`\"\n class=\"mt-2 w-full\"\n >\n <RangeCalendarCell\n v-for=\"weekDate in weekDates\"\n :key=\"weekDate.toString()\"\n :date=\"weekDate\"\n >\n <RangeCalendarCellTrigger\n :day=\"weekDate\"\n :month=\"secondMonth.value\"\n />\n </RangeCalendarCell>\n </RangeCalendarGridRow>\n </RangeCalendarGridBody>\n </RangeCalendarGrid>\n </div>\n </div>\n </RangeCalendarRoot>\n </PopoverContent>\n </Popover>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DatePickerWithPresets",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"calendar",
|
|
"popover",
|
|
"select"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DatePickerWithPresets.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DatePickerWithRange",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"range-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DatePickerWithRange.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DialogCustomCloseButton",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog",
|
|
"input",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DialogCustomCloseButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/default/ui/dialog'\nimport { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\nimport { Copy } from 'lucide-vue-next'\n</script>\n\n<template>\n <Dialog>\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Share\n </Button>\n </DialogTrigger>\n <DialogContent class=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>Share link</DialogTitle>\n <DialogDescription>\n Anyone who has this link will be able to view this.\n </DialogDescription>\n </DialogHeader>\n <div class=\"flex items-center space-x-2\">\n <div class=\"grid flex-1 gap-2\">\n <Label for=\"link\" class=\"sr-only\">\n Link\n </Label>\n <Input\n id=\"link\"\n default-value=\"https://shadcn-vue.com/docs/installation\"\n read-only\n />\n </div>\n <Button type=\"submit\" size=\"sm\" class=\"px-3\">\n <span class=\"sr-only\">Copy</span>\n <Copy class=\"w-4 h-4\" />\n </Button>\n </div>\n <DialogFooter class=\"sm:justify-start\">\n <DialogClose as-child>\n <Button type=\"button\" variant=\"secondary\">\n Close\n </Button>\n </DialogClose>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DialogDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog",
|
|
"input",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DialogDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/default/ui/dialog'\nimport { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\n</script>\n\n<template>\n <Dialog>\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Edit Profile\n </Button>\n </DialogTrigger>\n <DialogContent class=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Edit profile</DialogTitle>\n <DialogDescription>\n Make changes to your profile here. Click save when you're done.\n </DialogDescription>\n </DialogHeader>\n <div class=\"grid gap-4 py-4\">\n <div class=\"grid grid-cols-4 items-center gap-4\">\n <Label for=\"name\" class=\"text-right\">\n Name\n </Label>\n <Input id=\"name\" default-value=\"Pedro Duarte\" class=\"col-span-3\" />\n </div>\n <div class=\"grid grid-cols-4 items-center gap-4\">\n <Label for=\"username\" class=\"text-right\">\n Username\n </Label>\n <Input id=\"username\" default-value=\"@peduarte\" class=\"col-span-3\" />\n </div>\n </div>\n <DialogFooter>\n <Button type=\"submit\">\n Save changes\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DialogForm",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog",
|
|
"form",
|
|
"input",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DialogForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/default/ui/dialog'\nimport {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/default/ui/form'\n\nimport { Input } from '@/registry/default/ui/input'\nimport { toast } from '@/registry/default/ui/toast'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n username: z.string().min(2).max(50),\n}))\n\nfunction onSubmit(values: any) {\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 v-slot=\"{ handleSubmit }\" as=\"\" keep-values :validation-schema=\"formSchema\">\n <Dialog>\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Edit Profile\n </Button>\n </DialogTrigger>\n <DialogContent class=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Edit profile</DialogTitle>\n <DialogDescription>\n Make changes to your profile here. Click save when you're done.\n </DialogDescription>\n </DialogHeader>\n\n <form id=\"dialogForm\" @submit=\"handleSubmit($event, onSubmit)\">\n <FormField v-slot=\"{ componentField }\" name=\"username\">\n <FormItem>\n <FormLabel>Username</FormLabel>\n <FormControl>\n <Input type=\"text\" placeholder=\"shadcn\" v-bind=\"componentField\" />\n </FormControl>\n <FormDescription>\n This is your public display name.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n </form>\n\n <DialogFooter>\n <Button type=\"submit\" form=\"dialogForm\">\n Save changes\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </Form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DialogScrollBodyDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DialogScrollBodyDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/default/ui/dialog'\n</script>\n\n<template>\n <Dialog>\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Edit Profile\n </Button>\n </DialogTrigger>\n <DialogContent class=\"sm:max-w-[425px] grid-rows-[auto_minmax(0,1fr)_auto] p-0 max-h-[90dvh]\">\n <DialogHeader class=\"p-6 pb-0\">\n <DialogTitle>Edit profile</DialogTitle>\n <DialogDescription>\n Make changes to your profile here. Click save when you're done.\n </DialogDescription>\n </DialogHeader>\n <div class=\"grid gap-4 py-4 overflow-y-auto px-6\">\n <div class=\"flex flex-col justify-between h-[300dvh]\">\n <p>\n This is some placeholder content to show the scrolling behavior for modals. We use repeated line breaks to demonstrate how content can exceed minimum inner height, thereby showing inner scrolling. When content becomes longer than the predefined max-height of modal, content will be cropped and scrollable within the modal.\n </p>\n\n <p>This content should appear at the bottom after you scroll.</p>\n </div>\n </div>\n <DialogFooter class=\"p-6 pt-0\">\n <Button type=\"submit\">\n Save changes\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DialogScrollOverlayDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DialogScrollOverlayDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Dialog,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogScrollContent,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/default/ui/dialog'\n</script>\n\n<template>\n <Dialog>\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Edit Profile\n </Button>\n </DialogTrigger>\n <DialogScrollContent class=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Modal title</DialogTitle>\n <DialogDescription>\n Here is modal with overlay scroll\n </DialogDescription>\n </DialogHeader>\n <div class=\"grid gap-4 py-4 h-[300dvh]\">\n <p>\n This is some placeholder content to show the scrolling behavior for modals. Instead of repeating the text in the modal, we use an inline style to set a minimum height, thereby extending the length of the overall modal and demonstrating the overflow scrolling. When content becomes longer than the height of the viewport, scrolling will move the modal as needed.\n </p>\n </div>\n <DialogFooter>\n <Button type=\"submit\">\n Save changes\n </Button>\n </DialogFooter>\n </DialogScrollContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DonutChartColor",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-donut"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DonutChartColor.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DonutChart } from '@/registry/default/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 :colors=\"['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'purple']\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DonutChartCustomTooltip",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-donut"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DonutChartCustomTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DonutChart } from '@/registry/default/ui/chart-donut'\nimport CustomChartTooltip from './CustomChartTooltip.vue'\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</script>\n\n<template>\n <DonutChart\n index=\"name\"\n :category=\"'total'\"\n :data=\"data\"\n :custom-tooltip=\"CustomChartTooltip\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DonutChartDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-donut"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DonutChartDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DonutChart } from '@/registry/default/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</script>\n\n<template>\n <DonutChart\n index=\"name\"\n :category=\"'total'\"\n :data=\"data\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DonutChartPie",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-donut"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DonutChartPie.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { DonutChart } from '@/registry/default/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</script>\n\n<template>\n <DonutChart\n index=\"name\"\n :category=\"'total'\"\n :data=\"data\"\n :type=\"'pie'\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DrawerDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@unovis/vue",
|
|
"@unovis/ts"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"drawer"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DrawerDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from '@/registry/default/ui/drawer'\nimport { VisStackedBar, VisXYContainer } from '@unovis/vue'\nimport { Minus, Plus } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst goal = ref(350)\n\ntype Data = typeof data[number]\nconst data = [\n { goal: 400 },\n { goal: 300 },\n { goal: 200 },\n { goal: 300 },\n { goal: 200 },\n { goal: 278 },\n { goal: 189 },\n { goal: 239 },\n { goal: 300 },\n { goal: 200 },\n { goal: 278 },\n { goal: 189 },\n { goal: 349 },\n]\n</script>\n\n<template>\n <Drawer>\n <DrawerTrigger as-child>\n <Button variant=\"outline\">\n Open Drawer\n </Button>\n </DrawerTrigger>\n <DrawerContent>\n <div class=\"mx-auto w-full max-w-sm\">\n <DrawerHeader>\n <DrawerTitle>Move Goal</DrawerTitle>\n <DrawerDescription>Set your daily activity goal.</DrawerDescription>\n </DrawerHeader>\n <div class=\"p-4 pb-0\">\n <div class=\"flex items-center justify-center space-x-2\">\n <Button\n variant=\"outline\"\n size=\"icon\"\n class=\"h-8 w-8 shrink-0 rounded-full\"\n :disabled=\"goal <= 200\"\n @click=\"goal -= 10\"\n >\n <Minus class=\"h-4 w-4\" />\n <span class=\"sr-only\">Decrease</span>\n </Button>\n <div class=\"flex-1 text-center\">\n <div class=\"text-7xl font-bold tracking-tighter\">\n {{ goal }}\n </div>\n <div class=\"text-[0.70rem] uppercase text-muted-foreground\">\n Calories/day\n </div>\n </div>\n <Button\n variant=\"outline\"\n size=\"icon\"\n class=\"h-8 w-8 shrink-0 rounded-full\"\n :disabled=\"goal >= 400\"\n @click=\"goal += 10\"\n >\n <Plus class=\"h-4 w-4\" />\n <span class=\"sr-only\">Increase</span>\n </Button>\n </div>\n <div class=\"my-3 px-3 h-[120px]\">\n <VisXYContainer\n :data=\"data\"\n class=\"h-[120px]\"\n :style=\"{\n 'opacity': 0.9,\n '--theme-primary': `hsl(var(--foreground))`,\n }\"\n >\n <VisStackedBar\n :x=\"(d: Data, i :number) => i\"\n :y=\"(d: Data) => d.goal\"\n color=\"var(--theme-primary)\"\n :bar-padding=\"0.1\"\n :rounded-corners=\"0\"\n />\n </VisXYContainer>\n </div>\n </div>\n <DrawerFooter>\n <Button>Submit</Button>\n <DrawerClose as-child>\n <Button variant=\"outline\">\n Cancel\n </Button>\n </DrawerClose>\n </DrawerFooter>\n </div>\n </DrawerContent>\n </Drawer>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DrawerDialog",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog",
|
|
"drawer",
|
|
"input",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DrawerDialog.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/default/ui/dialog'\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerFooter,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from '@/registry/default/ui/drawer'\nimport { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\nimport { createReusableTemplate, useMediaQuery } from '@vueuse/core'\nimport { ref } from 'vue'\n\n// Reuse `form` section\nconst [UseTemplate, GridForm] = createReusableTemplate()\nconst isDesktop = useMediaQuery('(min-width: 768px)')\n\nconst isOpen = ref(false)\n</script>\n\n<template>\n <UseTemplate>\n <form class=\"grid items-start gap-4 px-4\">\n <div class=\"grid gap-2\">\n <Label html-for=\"email\">Email</Label>\n <Input id=\"email\" type=\"email\" default-value=\"shadcn@example.com\" />\n </div>\n <div class=\"grid gap-2\">\n <Label html-for=\"username\">Username</Label>\n <Input id=\"username\" default-value=\"@shadcn\" />\n </div>\n <Button type=\"submit\">\n Save changes\n </Button>\n </form>\n </UseTemplate>\n\n <Dialog v-if=\"isDesktop\" v-model:open=\"isOpen\">\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Edit Profile\n </Button>\n </DialogTrigger>\n <DialogContent class=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Edit profile</DialogTitle>\n <DialogDescription>\n Make changes to your profile here. Click save when you're done.\n </DialogDescription>\n </DialogHeader>\n <GridForm />\n </DialogContent>\n </Dialog>\n\n <Drawer v-else v-model:open=\"isOpen\">\n <DrawerTrigger as-child>\n <Button variant=\"outline\">\n Edit Profile\n </Button>\n </DrawerTrigger>\n <DrawerContent>\n <DrawerHeader class=\"text-left\">\n <DrawerTitle>Edit profile</DrawerTitle>\n <DrawerDescription>\n Make changes to your profile here. Click save when you're done.\n </DrawerDescription>\n </DrawerHeader>\n <GridForm />\n <DrawerFooter class=\"pt-2\">\n <DrawerClose as-child>\n <Button variant=\"outline\">\n Cancel\n </Button>\n </DrawerClose>\n </DrawerFooter>\n </DrawerContent>\n </Drawer>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DropdownMenuCheckboxes",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DropdownMenuCheckboxes.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport type { DropdownMenuCheckboxItemProps } from 'reka-ui'\nimport { Button } from '@/registry/default/ui/button'\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport { ref } from 'vue'\n\ntype Checked = DropdownMenuCheckboxItemProps['modelValue']\n\nconst showStatusBar = ref<Checked>(true)\nconst showActivityBar = ref<Checked>(false)\nconst showPanel = ref<Checked>(false)\n</script>\n\n<template>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\">\n Open\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent class=\"w-56\">\n <DropdownMenuLabel>Appearance</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuCheckboxItem\n v-model:model-value=\"showStatusBar\"\n >\n Status Bar\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n v-model:model-value=\"showActivityBar\"\n disabled\n >\n Activity Bar\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n v-model:model-value=\"showPanel\"\n >\n Panel\n </DropdownMenuCheckboxItem>\n </DropdownMenuContent>\n </DropdownMenu>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DropdownMenuDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DropdownMenuDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuPortal,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport {\n Cloud,\n CreditCard,\n Github,\n Keyboard,\n LifeBuoy,\n LogOut,\n Mail,\n MessageSquare,\n Plus,\n PlusCircle,\n Settings,\n User,\n UserPlus,\n Users,\n} from 'lucide-vue-next'\n</script>\n\n<template>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\">\n Open\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent class=\"w-56\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <User class=\"mr-2 h-4 w-4\" />\n <span>Profile</span>\n <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CreditCard class=\"mr-2 h-4 w-4\" />\n <span>Billing</span>\n <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Settings class=\"mr-2 h-4 w-4\" />\n <span>Settings</span>\n <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Keyboard class=\"mr-2 h-4 w-4\" />\n <span>Keyboard shortcuts</span>\n <DropdownMenuShortcut>⌘K</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <Users class=\"mr-2 h-4 w-4\" />\n <span>Team</span>\n </DropdownMenuItem>\n <DropdownMenuSub>\n <DropdownMenuSubTrigger>\n <UserPlus class=\"mr-2 h-4 w-4\" />\n <span>Invite users</span>\n </DropdownMenuSubTrigger>\n <DropdownMenuPortal>\n <DropdownMenuSubContent>\n <DropdownMenuItem>\n <Mail class=\"mr-2 h-4 w-4\" />\n <span>Email</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <MessageSquare class=\"mr-2 h-4 w-4\" />\n <span>Message</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <PlusCircle class=\"mr-2 h-4 w-4\" />\n <span>More...</span>\n </DropdownMenuItem>\n </DropdownMenuSubContent>\n </DropdownMenuPortal>\n </DropdownMenuSub>\n <DropdownMenuItem>\n <Plus class=\"mr-2 h-4 w-4\" />\n <span>New Team</span>\n <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Github class=\"mr-2 h-4 w-4\" />\n <span>GitHub</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <LifeBuoy class=\"mr-2 h-4 w-4\" />\n <span>Support</span>\n </DropdownMenuItem>\n <DropdownMenuItem disabled>\n <Cloud class=\"mr-2 h-4 w-4\" />\n <span>API</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut class=\"mr-2 h-4 w-4\" />\n <span>Log out</span>\n <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DropdownMenuRadioGroup",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/DropdownMenuRadioGroup.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { Button } from '@/registry/default/ui/button'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport { ref } from 'vue'\n\nconst position = ref('bottom')\n</script>\n\n<template>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\">\n Open\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent class=\"w-56\">\n <DropdownMenuLabel>Panel Position</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuRadioGroup v-model=\"position\">\n <DropdownMenuRadioItem value=\"top\">\n Top\n </DropdownMenuRadioItem>\n <DropdownMenuRadioItem value=\"bottom\">\n Bottom\n </DropdownMenuRadioItem>\n <DropdownMenuRadioItem value=\"right\">\n Right\n </DropdownMenuRadioItem>\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "HoverCardDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"avatar",
|
|
"button",
|
|
"hover-card"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/HoverCardDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/registry/default/ui/avatar'\n\nimport { Button } from '@/registry/default/ui/button'\nimport {\n HoverCard,\n HoverCardContent,\n HoverCardTrigger,\n} from '@/registry/default/ui/hover-card'\nimport { CalendarDays } from 'lucide-vue-next'\n</script>\n\n<template>\n <HoverCard>\n <HoverCardTrigger as-child>\n <Button variant=\"link\">\n @vuejs\n </Button>\n </HoverCardTrigger>\n <HoverCardContent class=\"w-80\">\n <div class=\"flex justify-between space-x-4\">\n <Avatar>\n <AvatarImage src=\"https://github.com/vuejs.png\" />\n <AvatarFallback>VC</AvatarFallback>\n </Avatar>\n <div class=\"space-y-1\">\n <h4 class=\"text-sm font-semibold\">\n @vuejs\n </h4>\n <p class=\"text-sm\">\n Progressive JavaScript framework for building modern web interfaces.\n </p>\n <div class=\"flex items-center pt-2\">\n <CalendarDays class=\"mr-2 h-4 w-4 opacity-70\" />\n <span class=\"text-xs text-muted-foreground\">\n Joined January 2014\n </span>\n </div>\n </div>\n </div>\n </HoverCardContent>\n </HoverCard>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Input } from '@/registry/default/ui/input'\n</script>\n\n<template>\n <Input type=\"email\" placeholder=\"Email\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputDisabled",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputDisabled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Input } from '@/registry/default/ui/input'\n</script>\n\n<template>\n <Input disabled type=\"email\" placeholder=\"Email\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputFile",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"input",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputFile.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\n</script>\n\n<template>\n <div class=\"grid w-full max-w-sm items-center gap-1.5\">\n <Label for=\"picture\">Picture</Label>\n <Input id=\"picture\" type=\"file\" />\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"input",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputForm.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 { Input } from '@/registry/default/ui/input'\nimport { toast } from '@/registry/default/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n username: z.string().min(2).max(50),\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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField }\" name=\"username\">\n <FormItem>\n <FormLabel>Username</FormLabel>\n <FormControl>\n <Input type=\"text\" placeholder=\"shadcn\" v-bind=\"componentField\" />\n </FormControl>\n <FormDescription>\n This is your public display name.\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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputFormAutoAnimate",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"input",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputFormAutoAnimate.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 { Input } from '@/registry/default/ui/input'\nimport { toast } from '@/registry/default/ui/toast'\nimport { vAutoAnimate } from '@formkit/auto-animate/vue'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n username: z.string().min(2).max(50),\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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField }\" name=\"username\">\n <FormItem v-auto-animate>\n <FormLabel>Username</FormLabel>\n <FormControl>\n <Input type=\"text\" placeholder=\"shadcn\" v-bind=\"componentField\" />\n </FormControl>\n <FormDescription>\n This is your public display name.\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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputWithButton",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputWithButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Input } from '@/registry/default/ui/input'\n</script>\n\n<template>\n <div class=\"flex w-full max-w-sm items-center gap-1.5\">\n <Input id=\"email\" type=\"email\" placeholder=\"Email\" />\n <Button type=\"submit\">\n Subscribe\n </Button>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputWithIcon",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputWithIcon.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Input } from '@/registry/default/ui/input'\nimport { Search } from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"relative w-full max-w-sm items-center\">\n <Input id=\"search\" type=\"text\" placeholder=\"Search...\" class=\"pl-10\" />\n <span class=\"absolute start-0 inset-y-0 flex items-center justify-center px-2\">\n <Search class=\"size-6 text-muted-foreground\" />\n </span>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "InputWithLabel",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"input",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/InputWithLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\n</script>\n\n<template>\n <div class=\"grid w-full max-w-sm items-center gap-1.5\">\n <Label for=\"email\">Email</Label>\n <Input id=\"email\" type=\"email\" placeholder=\"Email\" />\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "LabelDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"checkbox",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/LabelDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Checkbox } from '@/registry/default/ui/checkbox'\nimport { Label } from '@/registry/default/ui/label'\n</script>\n\n<template>\n <div>\n <div class=\"flex items-center space-x-2\">\n <Checkbox id=\"terms\" />\n <Label for=\"terms\">Accept terms and conditions</Label>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "LineChartCustomTooltip",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-line"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/LineChartCustomTooltip.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { LineChart } from '@/registry/default/ui/chart-line'\nimport CustomChartTooltip from './CustomChartTooltip.vue'\n\nconst data = [\n {\n 'year': 1970,\n 'Export Growth Rate': 2.04,\n 'Import Growth Rate': 1.53,\n },\n {\n 'year': 1971,\n 'Export Growth Rate': 1.96,\n 'Import Growth Rate': 1.58,\n },\n {\n 'year': 1972,\n 'Export Growth Rate': 1.96,\n 'Import Growth Rate': 1.61,\n },\n {\n 'year': 1973,\n 'Export Growth Rate': 1.93,\n 'Import Growth Rate': 1.61,\n },\n {\n 'year': 1974,\n 'Export Growth Rate': 1.88,\n 'Import Growth Rate': 1.67,\n },\n {\n 'year': 1975,\n 'Export Growth Rate': 1.79,\n 'Import Growth Rate': 1.64,\n },\n {\n 'year': 1976,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.62,\n },\n {\n 'year': 1977,\n 'Export Growth Rate': 1.74,\n 'Import Growth Rate': 1.69,\n },\n {\n 'year': 1978,\n 'Export Growth Rate': 1.74,\n 'Import Growth Rate': 1.7,\n },\n {\n 'year': 1979,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.67,\n },\n {\n 'year': 1980,\n 'Export Growth Rate': 1.79,\n 'Import Growth Rate': 1.7,\n },\n {\n 'year': 1981,\n 'Export Growth Rate': 1.81,\n 'Import Growth Rate': 1.72,\n },\n {\n 'year': 1982,\n 'Export Growth Rate': 1.84,\n 'Import Growth Rate': 1.73,\n },\n {\n 'year': 1983,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.73,\n },\n {\n 'year': 1984,\n 'Export Growth Rate': 1.78,\n 'Import Growth Rate': 1.78,\n },\n {\n 'year': 1985,\n 'Export Growth Rate': 1.78,\n 'Import Growth Rate': 1.81,\n },\n {\n 'year': 1986,\n 'Export Growth Rate': 1.82,\n 'Import Growth Rate': 1.89,\n },\n {\n 'year': 1987,\n 'Export Growth Rate': 1.82,\n 'Import Growth Rate': 1.91,\n },\n {\n 'year': 1988,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.94,\n },\n {\n 'year': 1989,\n 'Export Growth Rate': 1.76,\n 'Import Growth Rate': 1.94,\n },\n {\n 'year': 1990,\n 'Export Growth Rate': 1.75,\n 'Import Growth Rate': 1.97,\n },\n {\n 'year': 1991,\n 'Export Growth Rate': 1.62,\n 'Import Growth Rate': 1.99,\n },\n {\n 'year': 1992,\n 'Export Growth Rate': 1.56,\n 'Import Growth Rate': 2.12,\n },\n {\n 'year': 1993,\n 'Export Growth Rate': 1.5,\n 'Import Growth Rate': 2.13,\n },\n {\n 'year': 1994,\n 'Export Growth Rate': 1.46,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 1995,\n 'Export Growth Rate': 1.43,\n 'Import Growth Rate': 2.17,\n },\n {\n 'year': 1996,\n 'Export Growth Rate': 1.4,\n 'Import Growth Rate': 2.2,\n },\n {\n 'year': 1997,\n 'Export Growth Rate': 1.37,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 1998,\n 'Export Growth Rate': 1.34,\n 'Import Growth Rate': 2.07,\n },\n {\n 'year': 1999,\n 'Export Growth Rate': 1.32,\n 'Import Growth Rate': 2.05,\n },\n {\n 'year': 2000,\n 'Export Growth Rate': 1.33,\n 'Import Growth Rate': 2.07,\n },\n {\n 'year': 2001,\n 'Export Growth Rate': 1.31,\n 'Import Growth Rate': 2.08,\n },\n {\n 'year': 2002,\n 'Export Growth Rate': 1.29,\n 'Import Growth Rate': 2.1,\n },\n {\n 'year': 2003,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 2004,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.21,\n },\n {\n 'year': 2005,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.23,\n },\n {\n 'year': 2006,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.29,\n },\n {\n 'year': 2007,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.34,\n },\n {\n 'year': 2008,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.36,\n },\n {\n 'year': 2009,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.36,\n },\n {\n 'year': 2010,\n 'Export Growth Rate': 1.25,\n 'Import Growth Rate': 2.35,\n },\n {\n 'year': 2011,\n 'Export Growth Rate': 1.24,\n 'Import Growth Rate': 2.34,\n },\n {\n 'year': 2012,\n 'Export Growth Rate': 1.25,\n 'Import Growth Rate': 2.39,\n },\n {\n 'year': 2013,\n 'Export Growth Rate': 1.22,\n 'Import Growth Rate': 2.3,\n },\n {\n 'year': 2014,\n 'Export Growth Rate': 1.2,\n 'Import Growth Rate': 2.35,\n },\n {\n 'year': 2015,\n 'Export Growth Rate': 1.17,\n 'Import Growth Rate': 2.39,\n },\n {\n 'year': 2016,\n 'Export Growth Rate': 1.16,\n 'Import Growth Rate': 2.41,\n },\n {\n 'year': 2017,\n 'Export Growth Rate': 1.13,\n 'Import Growth Rate': 2.44,\n },\n {\n 'year': 2018,\n 'Export Growth Rate': 1.07,\n 'Import Growth Rate': 2.45,\n },\n {\n 'year': 2019,\n 'Export Growth Rate': 1.03,\n 'Import Growth Rate': 2.47,\n },\n {\n 'year': 2020,\n 'Export Growth Rate': 0.92,\n 'Import Growth Rate': 2.48,\n },\n {\n 'year': 2021,\n 'Export Growth Rate': 0.82,\n 'Import Growth Rate': 2.51,\n },\n]\n</script>\n\n<template>\n <LineChart\n :data=\"data\"\n index=\"year\"\n :categories=\"['Export Growth Rate', 'Import Growth Rate']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n :custom-tooltip=\"CustomChartTooltip\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "LineChartDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-line"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/LineChartDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { LineChart } from '@/registry/default/ui/chart-line'\n\nconst data = [\n {\n 'year': 1970,\n 'Export Growth Rate': 2.04,\n 'Import Growth Rate': 1.53,\n },\n {\n 'year': 1971,\n 'Export Growth Rate': 1.96,\n 'Import Growth Rate': 1.58,\n },\n {\n 'year': 1972,\n 'Export Growth Rate': 1.96,\n 'Import Growth Rate': 1.61,\n },\n {\n 'year': 1973,\n 'Export Growth Rate': 1.93,\n 'Import Growth Rate': 1.61,\n },\n {\n 'year': 1974,\n 'Export Growth Rate': 1.88,\n 'Import Growth Rate': 1.67,\n },\n {\n 'year': 1975,\n 'Export Growth Rate': 1.79,\n 'Import Growth Rate': 1.64,\n },\n {\n 'year': 1976,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.62,\n },\n {\n 'year': 1977,\n 'Export Growth Rate': 1.74,\n 'Import Growth Rate': 1.69,\n },\n {\n 'year': 1978,\n 'Export Growth Rate': 1.74,\n 'Import Growth Rate': 1.7,\n },\n {\n 'year': 1979,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.67,\n },\n {\n 'year': 1980,\n 'Export Growth Rate': 1.79,\n 'Import Growth Rate': 1.7,\n },\n {\n 'year': 1981,\n 'Export Growth Rate': 1.81,\n 'Import Growth Rate': 1.72,\n },\n {\n 'year': 1982,\n 'Export Growth Rate': 1.84,\n 'Import Growth Rate': 1.73,\n },\n {\n 'year': 1983,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.73,\n },\n {\n 'year': 1984,\n 'Export Growth Rate': 1.78,\n 'Import Growth Rate': 1.78,\n },\n {\n 'year': 1985,\n 'Export Growth Rate': 1.78,\n 'Import Growth Rate': 1.81,\n },\n {\n 'year': 1986,\n 'Export Growth Rate': 1.82,\n 'Import Growth Rate': 1.89,\n },\n {\n 'year': 1987,\n 'Export Growth Rate': 1.82,\n 'Import Growth Rate': 1.91,\n },\n {\n 'year': 1988,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.94,\n },\n {\n 'year': 1989,\n 'Export Growth Rate': 1.76,\n 'Import Growth Rate': 1.94,\n },\n {\n 'year': 1990,\n 'Export Growth Rate': 1.75,\n 'Import Growth Rate': 1.97,\n },\n {\n 'year': 1991,\n 'Export Growth Rate': 1.62,\n 'Import Growth Rate': 1.99,\n },\n {\n 'year': 1992,\n 'Export Growth Rate': 1.56,\n 'Import Growth Rate': 2.12,\n },\n {\n 'year': 1993,\n 'Export Growth Rate': 1.5,\n 'Import Growth Rate': 2.13,\n },\n {\n 'year': 1994,\n 'Export Growth Rate': 1.46,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 1995,\n 'Export Growth Rate': 1.43,\n 'Import Growth Rate': 2.17,\n },\n {\n 'year': 1996,\n 'Export Growth Rate': 1.4,\n 'Import Growth Rate': 2.2,\n },\n {\n 'year': 1997,\n 'Export Growth Rate': 1.37,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 1998,\n 'Export Growth Rate': 1.34,\n 'Import Growth Rate': 2.07,\n },\n {\n 'year': 1999,\n 'Export Growth Rate': 1.32,\n 'Import Growth Rate': 2.05,\n },\n {\n 'year': 2000,\n 'Export Growth Rate': 1.33,\n 'Import Growth Rate': 2.07,\n },\n {\n 'year': 2001,\n 'Export Growth Rate': 1.31,\n 'Import Growth Rate': 2.08,\n },\n {\n 'year': 2002,\n 'Export Growth Rate': 1.29,\n 'Import Growth Rate': 2.1,\n },\n {\n 'year': 2003,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 2004,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.21,\n },\n {\n 'year': 2005,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.23,\n },\n {\n 'year': 2006,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.29,\n },\n {\n 'year': 2007,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.34,\n },\n {\n 'year': 2008,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.36,\n },\n {\n 'year': 2009,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.36,\n },\n {\n 'year': 2010,\n 'Export Growth Rate': 1.25,\n 'Import Growth Rate': 2.35,\n },\n {\n 'year': 2011,\n 'Export Growth Rate': 1.24,\n 'Import Growth Rate': 2.34,\n },\n {\n 'year': 2012,\n 'Export Growth Rate': 1.25,\n 'Import Growth Rate': 2.39,\n },\n {\n 'year': 2013,\n 'Export Growth Rate': 1.22,\n 'Import Growth Rate': 2.3,\n },\n {\n 'year': 2014,\n 'Export Growth Rate': 1.2,\n 'Import Growth Rate': 2.35,\n },\n {\n 'year': 2015,\n 'Export Growth Rate': 1.17,\n 'Import Growth Rate': 2.39,\n },\n {\n 'year': 2016,\n 'Export Growth Rate': 1.16,\n 'Import Growth Rate': 2.41,\n },\n {\n 'year': 2017,\n 'Export Growth Rate': 1.13,\n 'Import Growth Rate': 2.44,\n },\n {\n 'year': 2018,\n 'Export Growth Rate': 1.07,\n 'Import Growth Rate': 2.45,\n },\n {\n 'year': 2019,\n 'Export Growth Rate': 1.03,\n 'Import Growth Rate': 2.47,\n },\n {\n 'year': 2020,\n 'Export Growth Rate': 0.92,\n 'Import Growth Rate': 2.48,\n },\n {\n 'year': 2021,\n 'Export Growth Rate': 0.82,\n 'Import Growth Rate': 2.51,\n },\n]\n</script>\n\n<template>\n <LineChart\n :data=\"data\"\n index=\"year\"\n :categories=\"['Export Growth Rate', 'Import Growth Rate']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "LineChartSparkline",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"chart-line"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/LineChartSparkline.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { LineChart } from '@/registry/default/ui/chart-line'\n\nconst data = [\n {\n 'year': 1970,\n 'Export Growth Rate': 2.04,\n 'Import Growth Rate': 1.53,\n },\n {\n 'year': 1971,\n 'Export Growth Rate': 1.96,\n 'Import Growth Rate': 1.58,\n },\n {\n 'year': 1972,\n 'Export Growth Rate': 1.96,\n 'Import Growth Rate': 1.61,\n },\n {\n 'year': 1973,\n 'Export Growth Rate': 1.93,\n 'Import Growth Rate': 1.61,\n },\n {\n 'year': 1974,\n 'Export Growth Rate': 1.88,\n 'Import Growth Rate': 1.67,\n },\n {\n 'year': 1975,\n 'Export Growth Rate': 1.79,\n 'Import Growth Rate': 1.64,\n },\n {\n 'year': 1976,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.62,\n },\n {\n 'year': 1977,\n 'Export Growth Rate': 1.74,\n 'Import Growth Rate': 1.69,\n },\n {\n 'year': 1978,\n 'Export Growth Rate': 1.74,\n 'Import Growth Rate': 1.7,\n },\n {\n 'year': 1979,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.67,\n },\n {\n 'year': 1980,\n 'Export Growth Rate': 1.79,\n 'Import Growth Rate': 1.7,\n },\n {\n 'year': 1981,\n 'Export Growth Rate': 1.81,\n 'Import Growth Rate': 1.72,\n },\n {\n 'year': 1982,\n 'Export Growth Rate': 1.84,\n 'Import Growth Rate': 1.73,\n },\n {\n 'year': 1983,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.73,\n },\n {\n 'year': 1984,\n 'Export Growth Rate': 1.78,\n 'Import Growth Rate': 1.78,\n },\n {\n 'year': 1985,\n 'Export Growth Rate': 1.78,\n 'Import Growth Rate': 1.81,\n },\n {\n 'year': 1986,\n 'Export Growth Rate': 1.82,\n 'Import Growth Rate': 1.89,\n },\n {\n 'year': 1987,\n 'Export Growth Rate': 1.82,\n 'Import Growth Rate': 1.91,\n },\n {\n 'year': 1988,\n 'Export Growth Rate': 1.77,\n 'Import Growth Rate': 1.94,\n },\n {\n 'year': 1989,\n 'Export Growth Rate': 1.76,\n 'Import Growth Rate': 1.94,\n },\n {\n 'year': 1990,\n 'Export Growth Rate': 1.75,\n 'Import Growth Rate': 1.97,\n },\n {\n 'year': 1991,\n 'Export Growth Rate': 1.62,\n 'Import Growth Rate': 1.99,\n },\n {\n 'year': 1992,\n 'Export Growth Rate': 1.56,\n 'Import Growth Rate': 2.12,\n },\n {\n 'year': 1993,\n 'Export Growth Rate': 1.5,\n 'Import Growth Rate': 2.13,\n },\n {\n 'year': 1994,\n 'Export Growth Rate': 1.46,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 1995,\n 'Export Growth Rate': 1.43,\n 'Import Growth Rate': 2.17,\n },\n {\n 'year': 1996,\n 'Export Growth Rate': 1.4,\n 'Import Growth Rate': 2.2,\n },\n {\n 'year': 1997,\n 'Export Growth Rate': 1.37,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 1998,\n 'Export Growth Rate': 1.34,\n 'Import Growth Rate': 2.07,\n },\n {\n 'year': 1999,\n 'Export Growth Rate': 1.32,\n 'Import Growth Rate': 2.05,\n },\n {\n 'year': 2000,\n 'Export Growth Rate': 1.33,\n 'Import Growth Rate': 2.07,\n },\n {\n 'year': 2001,\n 'Export Growth Rate': 1.31,\n 'Import Growth Rate': 2.08,\n },\n {\n 'year': 2002,\n 'Export Growth Rate': 1.29,\n 'Import Growth Rate': 2.1,\n },\n {\n 'year': 2003,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.15,\n },\n {\n 'year': 2004,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.21,\n },\n {\n 'year': 2005,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.23,\n },\n {\n 'year': 2006,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.29,\n },\n {\n 'year': 2007,\n 'Export Growth Rate': 1.27,\n 'Import Growth Rate': 2.34,\n },\n {\n 'year': 2008,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.36,\n },\n {\n 'year': 2009,\n 'Export Growth Rate': 1.26,\n 'Import Growth Rate': 2.36,\n },\n {\n 'year': 2010,\n 'Export Growth Rate': 1.25,\n 'Import Growth Rate': 2.35,\n },\n {\n 'year': 2011,\n 'Export Growth Rate': 1.24,\n 'Import Growth Rate': 2.34,\n },\n {\n 'year': 2012,\n 'Export Growth Rate': 1.25,\n 'Import Growth Rate': 2.39,\n },\n {\n 'year': 2013,\n 'Export Growth Rate': 1.22,\n 'Import Growth Rate': 2.3,\n },\n {\n 'year': 2014,\n 'Export Growth Rate': 1.2,\n 'Import Growth Rate': 2.35,\n },\n {\n 'year': 2015,\n 'Export Growth Rate': 1.17,\n 'Import Growth Rate': 2.39,\n },\n {\n 'year': 2016,\n 'Export Growth Rate': 1.16,\n 'Import Growth Rate': 2.41,\n },\n {\n 'year': 2017,\n 'Export Growth Rate': 1.13,\n 'Import Growth Rate': 2.44,\n },\n {\n 'year': 2018,\n 'Export Growth Rate': 1.07,\n 'Import Growth Rate': 2.45,\n },\n {\n 'year': 2019,\n 'Export Growth Rate': 1.03,\n 'Import Growth Rate': 2.47,\n },\n {\n 'year': 2020,\n 'Export Growth Rate': 0.92,\n 'Import Growth Rate': 2.48,\n },\n {\n 'year': 2021,\n 'Export Growth Rate': 0.82,\n 'Import Growth Rate': 2.51,\n },\n]\n</script>\n\n<template>\n <LineChart\n index=\"year\"\n class=\"h-[100px] w-[400px]\"\n :data=\"data\"\n :categories=\"['Export Growth Rate']\"\n :y-formatter=\"(tick, i) => {\n return typeof tick === 'number'\n ? `$ ${new Intl.NumberFormat('us').format(tick).toString()}`\n : ''\n }\"\n :show-tooltip=\"false\"\n :show-grid-line=\"false\"\n :show-legend=\"false\"\n :show-x-axis=\"false\"\n :show-y-axis=\"false\"\n />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "MenubarDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"menubar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/MenubarDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Menubar,\n MenubarCheckboxItem,\n MenubarContent,\n MenubarItem,\n MenubarMenu,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarSeparator,\n MenubarShortcut,\n MenubarSub,\n MenubarSubContent,\n MenubarSubTrigger,\n MenubarTrigger,\n} from '@/registry/default/ui/menubar'\n</script>\n\n<template>\n <Menubar>\n <MenubarMenu>\n <MenubarTrigger>File</MenubarTrigger>\n <MenubarContent>\n <MenubarItem>\n New Tab <MenubarShortcut>⌘T</MenubarShortcut>\n </MenubarItem>\n <MenubarItem>\n New Window <MenubarShortcut>⌘N</MenubarShortcut>\n </MenubarItem>\n <MenubarItem disabled>\n New Incognito Window\n </MenubarItem>\n <MenubarSeparator />\n <MenubarSub>\n <MenubarSubTrigger>Share</MenubarSubTrigger>\n <MenubarSubContent>\n <MenubarItem>Email link</MenubarItem>\n <MenubarItem>Messages</MenubarItem>\n <MenubarItem>Notes</MenubarItem>\n </MenubarSubContent>\n </MenubarSub>\n <MenubarSeparator />\n <MenubarItem>\n Print... <MenubarShortcut>⌘P</MenubarShortcut>\n </MenubarItem>\n </MenubarContent>\n </MenubarMenu>\n <MenubarMenu>\n <MenubarTrigger>Edit</MenubarTrigger>\n <MenubarContent>\n <MenubarItem>\n Undo <MenubarShortcut>⌘Z</MenubarShortcut>\n </MenubarItem>\n <MenubarItem>\n Redo <MenubarShortcut>⇧⌘Z</MenubarShortcut>\n </MenubarItem>\n <MenubarSeparator />\n <MenubarSub>\n <MenubarSubTrigger>Find</MenubarSubTrigger>\n <MenubarSubContent>\n <MenubarItem>Search the web</MenubarItem>\n <MenubarSeparator />\n <MenubarItem>Find...</MenubarItem>\n <MenubarItem>Find Next</MenubarItem>\n <MenubarItem>Find Previous</MenubarItem>\n </MenubarSubContent>\n </MenubarSub>\n <MenubarSeparator />\n <MenubarItem>Cut</MenubarItem>\n <MenubarItem>Copy</MenubarItem>\n <MenubarItem>Paste</MenubarItem>\n </MenubarContent>\n </MenubarMenu>\n <MenubarMenu>\n <MenubarTrigger>View</MenubarTrigger>\n <MenubarContent>\n <MenubarCheckboxItem>Always Show Bookmarks Bar</MenubarCheckboxItem>\n <MenubarCheckboxItem checked>\n Always Show Full URLs\n </MenubarCheckboxItem>\n <MenubarSeparator />\n <MenubarItem inset>\n Reload <MenubarShortcut>⌘R</MenubarShortcut>\n </MenubarItem>\n <MenubarItem disabled inset>\n Force Reload <MenubarShortcut>⇧⌘R</MenubarShortcut>\n </MenubarItem>\n <MenubarSeparator />\n <MenubarItem inset>\n Toggle Fullscreen\n </MenubarItem>\n <MenubarSeparator />\n <MenubarItem inset>\n Hide Sidebar\n </MenubarItem>\n </MenubarContent>\n </MenubarMenu>\n <MenubarMenu>\n <MenubarTrigger>Profiles</MenubarTrigger>\n <MenubarContent>\n <MenubarRadioGroup value=\"benoit\">\n <MenubarRadioItem value=\"andy\">\n Andy\n </MenubarRadioItem>\n <MenubarRadioItem value=\"benoit\">\n Benoit\n </MenubarRadioItem>\n <MenubarRadioItem value=\"Luis\">\n Luis\n </MenubarRadioItem>\n </MenubarRadioGroup>\n <MenubarSeparator />\n <MenubarItem inset>\n Edit...\n </MenubarItem>\n <MenubarSeparator />\n <MenubarItem inset>\n Add Profile...\n </MenubarItem>\n </MenubarContent>\n </MenubarMenu>\n </Menubar>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NavigationMenuDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"navigation-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NavigationMenuDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n navigationMenuTriggerStyle,\n} from '@/registry/default/ui/navigation-menu'\n\nconst components: { title: string, href: string, description: string }[] = [\n {\n title: 'Alert Dialog',\n href: '/docs/components/alert-dialog',\n description:\n 'A modal dialog that interrupts the user with important content and expects a response.',\n },\n {\n title: 'Hover Card',\n href: '/docs/components/hover-card',\n description:\n 'For sighted users to preview content available behind a link.',\n },\n {\n title: 'Progress',\n href: '/docs/components/progress',\n description:\n 'Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.',\n },\n {\n title: 'Scroll-area',\n href: '/docs/components/scroll-area',\n description: 'Visually or semantically separates content.',\n },\n {\n title: 'Tabs',\n href: '/docs/components/tabs',\n description:\n 'A set of layered sections of content—known as tab panels—that are displayed one at a time.',\n },\n {\n title: 'Tooltip',\n href: '/docs/components/tooltip',\n description:\n 'A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.',\n },\n]\n</script>\n\n<template>\n <NavigationMenu>\n <NavigationMenuList>\n <NavigationMenuItem>\n <NavigationMenuTrigger>Getting started</NavigationMenuTrigger>\n <NavigationMenuContent>\n <ul class=\"grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[minmax(0,.75fr)_minmax(0,1fr)]\">\n <li class=\"row-span-3\">\n <NavigationMenuLink as-child>\n <a\n class=\"flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md\"\n href=\"/\"\n >\n <img src=\"https://www.reka-ui.com/logo.svg\" class=\"h-6 w-6\">\n <div class=\"mb-2 mt-4 text-lg font-medium\">\n shadcn/ui\n </div>\n <p class=\"text-sm leading-tight text-muted-foreground\">\n Beautifully designed components built with Radix UI and\n Tailwind CSS.\n </p>\n </a>\n </NavigationMenuLink>\n </li>\n\n <li>\n <NavigationMenuLink as-child>\n <a\n href=\"/docs/introduction\"\n class=\"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\"\n >\n <div class=\"text-sm font-medium leading-none\">Introduction</div>\n <p class=\"line-clamp-2 text-sm leading-snug text-muted-foreground\">\n Re-usable components built using Radix UI and Tailwind CSS.\n </p>\n </a>\n </NavigationMenuLink>\n </li>\n <li>\n <NavigationMenuLink as-child>\n <a\n href=\"/docs/installation\"\n class=\"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\"\n >\n <div class=\"text-sm font-medium leading-none\">Installation</div>\n <p class=\"line-clamp-2 text-sm leading-snug text-muted-foreground\">\n How to install dependencies and structure your app.\n </p>\n </a>\n </NavigationMenuLink>\n </li>\n <li>\n <NavigationMenuLink as-child>\n <a\n href=\"/docs/typography\"\n class=\"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\"\n >\n <div class=\"text-sm font-medium leading-none\">Typography</div>\n <p class=\"line-clamp-2 text-sm leading-snug text-muted-foreground\">\n Styles for headings, paragraphs, lists...etc\n </p>\n </a>\n </NavigationMenuLink>\n </li>\n </ul>\n </NavigationMenuContent>\n </NavigationMenuItem>\n <NavigationMenuItem>\n <NavigationMenuTrigger>Components</NavigationMenuTrigger>\n <NavigationMenuContent>\n <ul class=\"grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] \">\n <li v-for=\"component in components\" :key=\"component.title\">\n <NavigationMenuLink as-child>\n <a\n :href=\"component.href\"\n class=\"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\"\n >\n <div class=\"text-sm font-medium leading-none\">{{ component.title }}</div>\n <p class=\"line-clamp-2 text-sm leading-snug text-muted-foreground\">\n {{ component.description }}\n </p>\n </a>\n </NavigationMenuLink>\n </li>\n </ul>\n </NavigationMenuContent>\n </NavigationMenuItem>\n <NavigationMenuItem>\n <NavigationMenuLink href=\"/docs/introduction\" :class=\"navigationMenuTriggerStyle()\">\n Documentation\n </NavigationMenuLink>\n </NavigationMenuItem>\n </NavigationMenuList>\n </NavigationMenu>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NumberFieldCurrency",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"number-field"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NumberFieldCurrency.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/default/ui/label'\nimport {\n NumberField,\n NumberFieldContent,\n NumberFieldDecrement,\n NumberFieldIncrement,\n NumberFieldInput,\n} from '@/registry/default/ui/number-field'\n</script>\n\n<template>\n <NumberField\n id=\"balance\"\n :default-value=\"1500\"\n :format-options=\"{\n style: 'currency',\n currency: 'EUR',\n currencyDisplay: 'code',\n currencySign: 'accounting',\n }\"\n >\n <Label for=\"balance\">Balance</Label>\n <NumberFieldContent>\n <NumberFieldDecrement />\n <NumberFieldInput />\n <NumberFieldIncrement />\n </NumberFieldContent>\n </NumberField>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NumberFieldDecimal",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"number-field"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NumberFieldDecimal.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/default/ui/label'\nimport {\n NumberField,\n NumberFieldContent,\n NumberFieldDecrement,\n NumberFieldIncrement,\n NumberFieldInput,\n} from '@/registry/default/ui/number-field'\n</script>\n\n<template>\n <NumberField\n id=\"number\"\n :default-value=\"5\"\n :format-options=\"{\n signDisplay: 'exceptZero',\n minimumFractionDigits: 1,\n }\"\n >\n <Label for=\"number\">Number</Label>\n <NumberFieldContent>\n <NumberFieldDecrement />\n <NumberFieldInput />\n <NumberFieldIncrement />\n </NumberFieldContent>\n </NumberField>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NumberFieldDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"number-field"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NumberFieldDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/default/ui/label'\nimport {\n NumberField,\n NumberFieldContent,\n NumberFieldDecrement,\n NumberFieldIncrement,\n NumberFieldInput,\n} from '@/registry/default/ui/number-field'\n</script>\n\n<template>\n <NumberField id=\"age\" :default-value=\"18\" :min=\"0\">\n <Label for=\"age\">Age</Label>\n <NumberFieldContent>\n <NumberFieldDecrement />\n <NumberFieldInput />\n <NumberFieldIncrement />\n </NumberFieldContent>\n </NumberField>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NumberFieldDisabled",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"number-field"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NumberFieldDisabled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/default/ui/label'\nimport {\n NumberField,\n NumberFieldContent,\n NumberFieldDecrement,\n NumberFieldIncrement,\n NumberFieldInput,\n} from '@/registry/default/ui/number-field'\n</script>\n\n<template>\n <NumberField id=\"age-disabled\" :default-value=\"18\" disabled>\n <Label for=\"age-disabled\">Age</Label>\n <NumberFieldContent>\n <NumberFieldDecrement />\n <NumberFieldInput />\n <NumberFieldIncrement />\n </NumberFieldContent>\n </NumberField>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NumberFieldForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"number-field",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NumberFieldForm.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 NumberField,\n NumberFieldContent,\n NumberFieldDecrement,\n NumberFieldIncrement,\n NumberFieldInput,\n} from '@/registry/default/ui/number-field'\nimport { toast } from '@/registry/default/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n payment: z.number().min(10, 'Min 10 euros to send payment').max(5000, 'Max 5000 euros to send payment'),\n}))\n\nconst { handleSubmit, setFieldValue } = useForm({\n validationSchema: formSchema,\n initialValues: {\n payment: 10,\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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ value }\" name=\"payment\">\n <FormItem>\n <FormLabel>Payment</FormLabel>\n <NumberField\n class=\"gap-2\"\n :min=\"0\"\n :format-options=\"{\n style: 'currency',\n currency: 'EUR',\n currencyDisplay: 'code',\n currencySign: 'accounting',\n }\"\n :model-value=\"value\"\n @update:model-value=\"(v) => {\n if (v) {\n setFieldValue('payment', v)\n }\n else {\n setFieldValue('payment', undefined)\n }\n }\"\n >\n <NumberFieldContent>\n <NumberFieldDecrement />\n <FormControl>\n <NumberFieldInput />\n </FormControl>\n <NumberFieldIncrement />\n </NumberFieldContent>\n </NumberField>\n <FormDescription>\n Enter value between 10 and 5000.\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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "NumberFieldPercentage",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"number-field"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/NumberFieldPercentage.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/default/ui/label'\nimport {\n NumberField,\n NumberFieldContent,\n NumberFieldDecrement,\n NumberFieldIncrement,\n NumberFieldInput,\n} from '@/registry/default/ui/number-field'\n</script>\n\n<template>\n <NumberField\n id=\"percent\"\n :default-value=\"0.05\"\n :step=\"0.01\"\n :format-options=\"{\n style: 'percent',\n }\"\n >\n <Label for=\"percent\">Percent</Label>\n <NumberFieldContent>\n <NumberFieldDecrement />\n <NumberFieldInput />\n <NumberFieldIncrement />\n </NumberFieldContent>\n </NumberField>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PaginationDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"pagination"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PaginationDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Button,\n} from '@/registry/default/ui/button'\n\nimport {\n Pagination,\n PaginationEllipsis,\n PaginationFirst,\n PaginationLast,\n PaginationList,\n PaginationListItem,\n PaginationNext,\n PaginationPrev,\n} from '@/registry/default/ui/pagination'\n</script>\n\n<template>\n <Pagination v-slot=\"{ page }\" :items-per-page=\"10\" :total=\"100\" :sibling-count=\"1\" show-edges :default-page=\"2\">\n <PaginationList v-slot=\"{ items }\" class=\"flex items-center gap-1\">\n <PaginationFirst />\n <PaginationPrev />\n\n <template v-for=\"(item, index) in items\">\n <PaginationListItem v-if=\"item.type === 'page'\" :key=\"index\" :value=\"item.value\" as-child>\n <Button class=\"w-10 h-10 p-0\" :variant=\"item.value === page ? 'default' : 'outline'\">\n {{ item.value }}\n </Button>\n </PaginationListItem>\n <PaginationEllipsis v-else :key=\"item.type\" :index=\"index\" />\n </template>\n\n <PaginationNext />\n <PaginationLast />\n </PaginationList>\n </Pagination>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PinInputControlled",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"pin-input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PinInputControlled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n PinInput,\n PinInputGroup,\n PinInputInput,\n} from '@/registry/default/ui/pin-input'\nimport { ref } from 'vue'\n\nconst value = ref<string[]>(['1', '2', '3'])\nconst handleComplete = (e: string[]) => alert(e.join(''))\n</script>\n\n<template>\n <div>\n <PinInput\n id=\"pin-input\"\n v-model=\"value\"\n placeholder=\"○\"\n @complete=\"handleComplete\"\n >\n <PinInputGroup>\n <PinInputInput\n v-for=\"(id, index) in 5\"\n :key=\"id\"\n :index=\"index\"\n />\n </PinInputGroup>\n </PinInput>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PinInputDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"pin-input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PinInputDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n PinInput,\n PinInputGroup,\n PinInputInput,\n} from '@/registry/default/ui/pin-input'\nimport { ref } from 'vue'\n\nconst value = ref<string[]>([])\nconst handleComplete = (e: string[]) => alert(e.join(''))\n</script>\n\n<template>\n <div>\n <PinInput\n id=\"pin-input\"\n v-model=\"value\"\n placeholder=\"○\"\n @complete=\"handleComplete\"\n >\n <PinInputGroup>\n <PinInputInput\n v-for=\"(id, index) in 5\"\n :key=\"id\"\n :index=\"index\"\n />\n </PinInputGroup>\n </PinInput>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PinInputDisabled",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"pin-input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PinInputDisabled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n PinInput,\n PinInputGroup,\n PinInputInput,\n} from '@/registry/default/ui/pin-input'\nimport { ref } from 'vue'\n\nconst value = ref<string[]>([])\n</script>\n\n<template>\n <div>\n <PinInput\n id=\"pin-input\"\n v-model=\"value\"\n placeholder=\"○\"\n disabled\n >\n <PinInputGroup>\n <PinInputInput\n v-for=\"(id, index) in 5\"\n :key=\"id\"\n :index=\"index\"\n />\n </PinInputGroup>\n </PinInput>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PinInputFormDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"pin-input",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PinInputFormDemo.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 PinInput,\n PinInputGroup,\n PinInputInput,\n} from '@/registry/default/ui/pin-input'\nimport { toast } from '@/registry/default/ui/toast'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n pin: z.array(z.coerce.string()).length(5, { message: 'Invalid input' }),\n}))\n\nconst { handleSubmit, setFieldValue } = useForm({\n validationSchema: formSchema,\n initialValues: {\n pin: ['1', '2', '3'],\n },\n})\n\nconst onSubmit = handleSubmit(({ pin }) => {\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(pin.join(''), null, 2))),\n })\n})\n\nconst handleComplete = (e: string[]) => console.log(e.join(''))\n</script>\n\n<template>\n <form class=\"w-2/3 space-y-6 mx-auto\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField, value }\" name=\"pin\">\n <FormItem>\n <FormLabel>OTP</FormLabel>\n <FormControl>\n <PinInput\n id=\"pin-input\"\n :model-value=\"value\"\n placeholder=\"○\"\n class=\"flex gap-2 items-center mt-1\"\n otp\n type=\"number\"\n :name=\"componentField.name\"\n @complete=\"handleComplete\"\n @update:model-value=\"(arrStr) => {\n setFieldValue('pin', arrStr.filter(Boolean))\n }\"\n >\n <PinInputGroup>\n <PinInputInput\n v-for=\"(id, index) in 5\"\n :key=\"id\"\n :index=\"index\"\n />\n </PinInputGroup>\n </PinInput>\n </FormControl>\n <FormDescription>\n Allows users to input a sequence of one-character alphanumeric inputs.\n </FormDescription>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <Button>Submit</Button>\n </form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PinInputSeparatorDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"pin-input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PinInputSeparatorDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n PinInput,\n PinInputGroup,\n PinInputInput,\n PinInputSeparator,\n} from '@/registry/default/ui/pin-input'\nimport { ref } from 'vue'\n\nconst value = ref<string[]>([])\nconst handleComplete = (e: string[]) => alert(e.join(''))\n</script>\n\n<template>\n <div>\n <PinInput\n id=\"pin-input\"\n v-model=\"value\"\n placeholder=\"○\"\n @complete=\"handleComplete\"\n >\n <PinInputGroup class=\"gap-1\">\n <template v-for=\"(id, index) in 5\" :key=\"id\">\n <PinInputInput\n class=\"rounded-md border\"\n :index=\"index\"\n />\n <template v-if=\"index !== 4\">\n <PinInputSeparator />\n </template>\n </template>\n </PinInputGroup>\n </PinInput>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "PopoverDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"input",
|
|
"label",
|
|
"popover"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/PopoverDemo.vue",
|
|
"content": "<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'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button variant=\"outline\">\n Open popover\n </Button>\n </PopoverTrigger>\n <PopoverContent class=\"w-80\">\n <div class=\"grid gap-4\">\n <div class=\"space-y-2\">\n <h4 class=\"font-medium leading-none\">\n Dimensions\n </h4>\n <p class=\"text-sm text-muted-foreground\">\n Set the dimensions for the layer.\n </p>\n </div>\n <div class=\"grid gap-2\">\n <div class=\"grid grid-cols-3 items-center gap-4\">\n <Label for=\"width\">Width</Label>\n <Input\n id=\"width\"\n type=\"text\"\n default-value=\"100%\"\n class=\"col-span-2 h-8\"\n />\n </div>\n <div class=\"grid grid-cols-3 items-center gap-4\">\n <Label for=\"maxWidth\">Max. width</Label>\n <Input\n id=\"maxWidth\"\n type=\"text\"\n default-value=\"300px\"\n class=\"col-span-2 h-8\"\n />\n </div>\n <div class=\"grid grid-cols-3 items-center gap-4\">\n <Label for=\"height\">Height</Label>\n <Input\n id=\"height\"\n type=\"text\"\n default-value=\"25px\"\n class=\"col-span-2 h-8\"\n />\n </div>\n <div class=\"grid grid-cols-3 items-center gap-4\">\n <Label for=\"maxHeight\">Max. height</Label>\n <Input\n id=\"maxHeight\"\n type=\"text\"\n default-value=\"none\"\n class=\"col-span-2 h-8\"\n />\n </div>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ProgressDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"progress"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ProgressDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Progress } from '@/registry/default/ui/progress'\nimport { ref, watchEffect } from 'vue'\n\nconst progress = ref(13)\n\nwatchEffect((cleanupFn) => {\n const timer = setTimeout(() => progress.value = 66, 500)\n cleanupFn(() => clearTimeout(timer))\n})\n</script>\n\n<template>\n <Progress v-model=\"progress\" class=\"w-3/5\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "RadioGroupDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"radio-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/RadioGroupDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/default/ui/label'\nimport { RadioGroup, RadioGroupItem } from '@/registry/default/ui/radio-group'\n</script>\n\n<template>\n <RadioGroup default-value=\"comfortable\">\n <div class=\"flex items-center space-x-2\">\n <RadioGroupItem id=\"r1\" value=\"default\" />\n <Label for=\"r1\">Default</Label>\n </div>\n <div class=\"flex items-center space-x-2\">\n <RadioGroupItem id=\"r2\" value=\"comfortable\" />\n <Label for=\"r2\">Comfortable</Label>\n </div>\n <div class=\"flex items-center space-x-2\">\n <RadioGroupItem id=\"r3\" value=\"compact\" />\n <Label for=\"r3\">Compact</Label>\n </div>\n </RadioGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "RadioGroupForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"radio-group",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/RadioGroupForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/registry/default/ui/form'\nimport { RadioGroup, RadioGroupItem } from '@/registry/default/ui/radio-group'\nimport { toast } from '@/registry/default/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n type: z.enum(['all', 'mentions', 'none'], {\n required_error: 'You need to select a notification type.',\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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField }\" type=\"radio\" name=\"type\">\n <FormItem class=\"space-y-3\">\n <FormLabel>Notify me about...</FormLabel>\n\n <FormControl>\n <RadioGroup\n class=\"flex flex-col space-y-1\"\n v-bind=\"componentField\"\n >\n <FormItem class=\"flex items-center space-y-0 gap-x-3\">\n <FormControl>\n <RadioGroupItem value=\"all\" />\n </FormControl>\n <FormLabel class=\"font-normal\">\n All new messages\n </FormLabel>\n </FormItem>\n <FormItem class=\"flex items-center space-y-0 gap-x-3\">\n <FormControl>\n <RadioGroupItem value=\"mentions\" />\n </FormControl>\n <FormLabel class=\"font-normal\">\n Direct messages and mentions\n </FormLabel>\n </FormItem>\n <FormItem class=\"flex items-center space-y-0 gap-x-3\">\n <FormControl>\n <RadioGroupItem value=\"none\" />\n </FormControl>\n <FormLabel class=\"font-normal\">\n Nothing\n </FormLabel>\n </FormItem>\n </RadioGroup>\n </FormControl>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <Button type=\"submit\">\n Submit\n </Button>\n </form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "RangeCalendarDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"range-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/RangeCalendarDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { DateRange } from 'reka-ui'\nimport { RangeCalendar } from '@/registry/default/ui/range-calendar'\nimport { getLocalTimeZone, today } from '@internationalized/date'\nimport { type Ref, ref } from 'vue'\n\nconst start = today(getLocalTimeZone())\nconst end = start.add({ days: 7 })\n\nconst value = ref({\n start,\n end,\n}) as Ref<DateRange>\n</script>\n\n<template>\n <RangeCalendar v-model=\"value\" class=\"rounded-md border\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ResizableDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"resizable"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ResizableDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from '@/registry/default/ui/resizable'\n</script>\n\n<template>\n <ResizablePanelGroup\n id=\"demo-group-1\"\n direction=\"horizontal\"\n class=\"max-w-md rounded-lg border\"\n >\n <ResizablePanel id=\"demo-panel-1\" :default-size=\"50\">\n <div class=\"flex h-[200px] items-center justify-center p-6\">\n <span class=\"font-semibold\">One</span>\n </div>\n </ResizablePanel>\n <ResizableHandle id=\"demo-handle-1\" />\n <ResizablePanel id=\"demo-panel-2\" :default-size=\"50\">\n <ResizablePanelGroup id=\"demo-group-2\" direction=\"vertical\">\n <ResizablePanel id=\"demo-panel-3\" :default-size=\"25\">\n <div class=\"flex h-full items-center justify-center p-6\">\n <span class=\"font-semibold\">Two</span>\n </div>\n </ResizablePanel>\n <ResizableHandle id=\"demo-handle-2\" />\n <ResizablePanel id=\"demo-panel-4\" :default-size=\"75\">\n <div class=\"flex h-full items-center justify-center p-6\">\n <span class=\"font-semibold\">Three</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n </ResizablePanelGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ResizableHandleDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"resizable"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ResizableHandleDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from '@/registry/default/ui/resizable'\n</script>\n\n<template>\n <ResizablePanelGroup\n id=\"handle-demo-group-1\"\n direction=\"horizontal\"\n class=\"min-h-[200px] max-w-md rounded-lg border\"\n >\n <ResizablePanel id=\"handle-demo-panel-1\" :default-size=\"25\">\n <div class=\"flex h-full items-center justify-center p-6\">\n <span class=\"font-semibold\">Sidebar</span>\n </div>\n </ResizablePanel>\n <ResizableHandle id=\"handle-demo-handle-1\" with-handle />\n <ResizablePanel id=\"handle-demo-panel-2\" :default-size=\"75\">\n <div class=\"flex h-full items-center justify-center p-6\">\n <span class=\"font-semibold\">Content</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ResizableVerticalDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"resizable"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ResizableVerticalDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from '@/registry/default/ui/resizable'\n</script>\n\n<template>\n <ResizablePanelGroup\n id=\"vertical-demo-group-1\"\n direction=\"vertical\"\n class=\"min-h-[200px] max-w-md rounded-lg border\"\n >\n <ResizablePanel id=\"vertical-demo-panel-1\" :default-size=\"25\">\n <div class=\"flex h-full items-center justify-center p-6\">\n <span class=\"font-semibold\">Header</span>\n </div>\n </ResizablePanel>\n <ResizableHandle id=\"vertical-demo-handle-1\" />\n <ResizablePanel id=\"vertical-demo-panel-2\" :default-size=\"75\">\n <div class=\"flex h-full items-center justify-center p-6\">\n <span class=\"font-semibold\">Content</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ScrollAreaDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"scroll-area",
|
|
"separator"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ScrollAreaDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ScrollArea } from '@/registry/default/ui/scroll-area'\nimport { Separator } from '@/registry/default/ui/separator'\n\nconst tags = Array.from({ length: 50 }).map(\n (_, i, a) => `v1.2.0-beta.${a.length - i}`,\n)\n</script>\n\n<template>\n <ScrollArea class=\"h-72 w-48 rounded-md border\">\n <div class=\"p-4\">\n <h4 class=\"mb-4 text-sm font-medium leading-none\">\n Tags\n </h4>\n\n <div v-for=\"tag in tags\" :key=\"tag\">\n <div class=\"text-sm\">\n {{ tag }}\n </div>\n <Separator class=\"my-2\" />\n </div>\n </div>\n </ScrollArea>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ScrollAreaHorizontalDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"scroll-area"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ScrollAreaHorizontalDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ScrollArea, ScrollBar } from '@/registry/default/ui/scroll-area'\n\ninterface Artwork {\n id: string\n artist: string\n art: string\n}\n\nconst works: Artwork[] = [\n {\n id: '1',\n artist: 'Ornella Binni',\n art: 'https://images.unsplash.com/photo-1465869185982-5a1a7522cbcb?auto=format&fit=crop&w=300&q=80',\n },\n {\n id: '2',\n artist: 'Tom Byrom',\n art: 'https://images.unsplash.com/photo-1548516173-3cabfa4607e9?auto=format&fit=crop&w=300&q=80',\n },\n {\n id: '3',\n artist: 'Vladimir Malyavko',\n art: 'https://images.unsplash.com/photo-1494337480532-3725c85fd2ab?auto=format&fit=crop&w=300&q=80',\n },\n]\n</script>\n\n<template>\n <ScrollArea class=\"border rounded-md w-96 whitespace-nowrap\">\n <div class=\"flex p-4 space-x-4 w-max\">\n <div v-for=\"artwork in works\" :key=\"artwork.id\">\n <figure class=\"shrink-0\">\n <div class=\"overflow-hidden rounded-md\">\n <img\n :src=\"artwork.art\"\n :alt=\"`Photo by ${artwork.artist}`\"\n class=\"aspect-[3/4] w-36 h-56 object-cover\"\n >\n </div>\n <figcaption class=\"pt-2 text-xs text-muted-foreground\">\n Photo by\n <span class=\"font-semibold text-foreground\">\n {{ artwork.artist }}\n </span>\n </figcaption>\n </figure>\n </div>\n </div>\n <ScrollBar orientation=\"horizontal\" />\n </ScrollArea>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SelectDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"select"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SelectDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n} from '@/registry/default/ui/select'\n</script>\n\n<template>\n <Select>\n <SelectTrigger class=\"w-[180px]\">\n <SelectValue placeholder=\"Select a fruit\" />\n </SelectTrigger>\n <SelectContent>\n <SelectGroup>\n <SelectLabel>Fruits</SelectLabel>\n <SelectItem value=\"apple\">\n Apple\n </SelectItem>\n <SelectItem value=\"banana\">\n Banana\n </SelectItem>\n <SelectItem value=\"blueberry\">\n Blueberry\n </SelectItem>\n <SelectItem value=\"grapes\">\n Grapes\n </SelectItem>\n <SelectItem value=\"pineapple\">\n Pineapple\n </SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SelectForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"select",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SelectForm.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 Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/default/ui/select'\nimport { toast } from '@/registry/default/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n email: z\n .string({\n required_error: 'Please select an email to display.',\n })\n .email(),\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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField }\" name=\"email\">\n <FormItem>\n <FormLabel>Email</FormLabel>\n\n <Select v-bind=\"componentField\">\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select a verified email to display\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n <SelectGroup>\n <SelectItem value=\"m@example.com\">\n m@example.com\n </SelectItem>\n <SelectItem value=\"m@google.com\">\n m@google.com\n </SelectItem>\n <SelectItem value=\"m@support.com\">\n m@support.com\n </SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n <FormDescription>\n You can manage email addresses in your\n <a href=\"/examples/forms\">email settings</a>.\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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SelectScrollable",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"select"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SelectScrollable.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n} from '@/registry/default/ui/select'\n</script>\n\n<template>\n <Select>\n <SelectTrigger class=\"w-[280px]\">\n <SelectValue placeholder=\"Select a timezone\" />\n </SelectTrigger>\n <SelectContent>\n <SelectGroup>\n <SelectLabel>North America</SelectLabel>\n <SelectItem value=\"est\">\n Eastern Standard Time (EST)\n </SelectItem>\n <SelectItem value=\"cst\">\n Central Standard Time (CST)\n </SelectItem>\n <SelectItem value=\"mst\">\n Mountain Standard Time (MST)\n </SelectItem>\n <SelectItem value=\"pst\">\n Pacific Standard Time (PST)\n </SelectItem>\n <SelectItem value=\"akst\">\n Alaska Standard Time (AKST)\n </SelectItem>\n <SelectItem value=\"hst\">\n Hawaii Standard Time (HST)\n </SelectItem>\n </SelectGroup>\n <SelectGroup>\n <SelectLabel>Europe & Africa</SelectLabel>\n <SelectItem value=\"gmt\">\n Greenwich Mean Time (GMT)\n </SelectItem>\n <SelectItem value=\"cet\">\n Central European Time (CET)\n </SelectItem>\n <SelectItem value=\"eet\">\n Eastern European Time (EET)\n </SelectItem>\n <SelectItem value=\"west\">\n Western European Summer Time (WEST)\n </SelectItem>\n <SelectItem value=\"cat\">\n Central Africa Time (CAT)\n </SelectItem>\n <SelectItem value=\"eat\">\n East Africa Time (EAT)\n </SelectItem>\n </SelectGroup>\n <SelectGroup>\n <SelectLabel>Asia</SelectLabel>\n <SelectItem value=\"msk\">\n Moscow Time (MSK)\n </SelectItem>\n <SelectItem value=\"ist\">\n India Standard Time (IST)\n </SelectItem>\n <SelectItem value=\"cst_china\">\n China Standard Time (CST)\n </SelectItem>\n <SelectItem value=\"jst\">\n Japan Standard Time (JST)\n </SelectItem>\n <SelectItem value=\"kst\">\n Korea Standard Time (KST)\n </SelectItem>\n <SelectItem value=\"ist_indonesia\">\n Indonesia Central Standard Time (WITA)\n </SelectItem>\n </SelectGroup>\n <SelectGroup>\n <SelectLabel>Australia & Pacific</SelectLabel>\n <SelectItem value=\"awst\">\n Australian Western Standard Time (AWST)\n </SelectItem>\n <SelectItem value=\"acst\">\n Australian Central Standard Time (ACST)\n </SelectItem>\n <SelectItem value=\"aest\">\n Australian Eastern Standard Time (AEST)\n </SelectItem>\n <SelectItem value=\"nzst\">\n New Zealand Standard Time (NZST)\n </SelectItem>\n <SelectItem value=\"fjt\">\n Fiji Time (FJT)\n </SelectItem>\n </SelectGroup>\n <SelectGroup>\n <SelectLabel>South America</SelectLabel>\n <SelectItem value=\"art\">\n Argentina Time (ART)\n </SelectItem>\n <SelectItem value=\"bot\">\n Bolivia Time (BOT)\n </SelectItem>\n <SelectItem value=\"brt\">\n Brasilia Time (BRT)\n </SelectItem>\n <SelectItem value=\"clt\">\n Chile Standard Time (CLT)\n </SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SeparatorDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"separator"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SeparatorDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Separator } from '@/registry/default/ui/separator'\n</script>\n\n<template>\n <div>\n <div class=\"space-y-1\">\n <h4 class=\"text-sm font-medium leading-none\">\n Radix Primitives\n </h4>\n <p class=\"text-sm text-muted-foreground\">\n An open-source UI component library.\n </p>\n </div>\n <Separator class=\"my-4\" label=\"Or\" />\n <div class=\"flex h-5 items-center space-x-4 text-sm\">\n <div>Blog</div>\n <Separator orientation=\"vertical\" />\n <div>Docs</div>\n <Separator orientation=\"vertical\" />\n <div>Source</div>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SheetDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"input",
|
|
"label",
|
|
"sheet"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SheetDemo.vue",
|
|
"content": "<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'\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from '@/registry/default/ui/sheet'\n</script>\n\n<template>\n <Sheet>\n <SheetTrigger as-child>\n <Button variant=\"outline\">\n Open\n </Button>\n </SheetTrigger>\n <SheetContent>\n <SheetHeader>\n <SheetTitle>Edit profile</SheetTitle>\n <SheetDescription>\n Make changes to your profile here. Click save when you're done.\n </SheetDescription>\n </SheetHeader>\n <div class=\"grid gap-4 py-4\">\n <div class=\"grid grid-cols-4 items-center gap-4\">\n <Label for=\"name\" class=\"text-right\">\n Name\n </Label>\n <Input id=\"name\" default-value=\"Pedro Duarte\" class=\"col-span-3\" />\n </div>\n <div class=\"grid grid-cols-4 items-center gap-4\">\n <Label for=\"username\" class=\"text-right\">\n Username\n </Label>\n <Input id=\"username\" default-value=\"@peduarte\" class=\"col-span-3\" />\n </div>\n </div>\n <SheetFooter>\n <SheetClose as-child>\n <Button type=\"submit\">\n Save changes\n </Button>\n </SheetClose>\n </SheetFooter>\n </SheetContent>\n </Sheet>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SheetSideDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"input",
|
|
"label",
|
|
"sheet"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SheetSideDemo.vue",
|
|
"content": "<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'\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from '@/registry/default/ui/sheet'\nimport { ref } from 'vue'\n\nconst SHEET_SIDES = ['top', 'right', 'bottom', 'left'] as const\n\nconst username = ref('')\n</script>\n\n<template>\n <div class=\"grid grid-cols-2 gap-2\">\n <Sheet v-for=\"side in SHEET_SIDES\" :key=\"side\">\n <SheetTrigger as-child>\n <Button variant=\"outline\">\n {{ side }}\n </Button>\n </SheetTrigger>\n <SheetContent :side=\"side\">\n <SheetHeader>\n <SheetTitle>Edit profile</SheetTitle>\n <SheetDescription>\n Make changes to your profile here. Click save when you're done.\n </SheetDescription>\n </SheetHeader>\n <div class=\"grid gap-4 py-4\">\n <div class=\"grid items-center grid-cols-4 gap-4\">\n <Label for=\"name\" class=\"text-right\">Name</Label>\n <Input id=\"name\" v-model=\"username\" class=\"col-span-3\" />\n </div>\n <div class=\"grid items-center grid-cols-4 gap-4\">\n <Label for=\"username\" class=\"text-right\">Username</Label>\n <Input id=\"username\" v-model=\"username\" class=\"col-span-3\" />\n </div>\n </div>\n <SheetFooter>\n <SheetClose as-child>\n <Button type=\"submit\">\n Save changes\n </Button>\n </SheetClose>\n </SheetFooter>\n </SheetContent>\n </Sheet>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SkeletonCard",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"skeleton"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SkeletonCard.vue",
|
|
"content": "<script lang=\"ts\" setup>\nimport { Skeleton } from '@/registry/default/ui/skeleton'\n</script>\n\n<template>\n <div class=\"flex flex-col space-y-3\">\n <Skeleton class=\"h-[125px] w-[250px] rounded-xl\" />\n <div class=\"space-y-2\">\n <Skeleton class=\"h-4 w-[250px]\" />\n <Skeleton class=\"h-4 w-[200px]\" />\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SkeletonDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"skeleton"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SkeletonDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Skeleton } from '@/registry/default/ui/skeleton'\n</script>\n\n<template>\n <div class=\"flex items-center space-x-4\">\n <Skeleton class=\"h-12 w-12 rounded-full\" />\n <div class=\"space-y-2\">\n <Skeleton class=\"h-4 w-[250px]\" />\n <Skeleton class=\"h-4 w-[200px]\" />\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SliderDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"slider"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SliderDemo.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SliderForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"slider",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SliderForm.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 { Slider } from '@/registry/default/ui/slider'\nimport { toast } from '@/registry/default/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n duration: z.array(\n z.number().min(0).max(60),\n ),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n initialValues: {\n duration: [30],\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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField, value }\" name=\"duration\">\n <FormItem>\n <FormLabel>Duration</FormLabel>\n <FormControl>\n <Slider\n v-bind=\"componentField\"\n :default-value=\"[30]\"\n :max=\"100\"\n :min=\"0\"\n :step=\"5\"\n />\n <FormDescription class=\"flex justify-between\">\n <span>How many minutes are you available?</span>\n <span>{{ value?.[0] }} min</span>\n </FormDescription>\n </FormControl>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <Button type=\"submit\">\n Submit\n </Button>\n </form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SonnerDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vue-sonner"
|
|
],
|
|
"registryDependencies": [
|
|
"button"
|
|
],
|
|
"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\"\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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SonnerWithDialog",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vue-sonner"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"dialog"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SonnerWithDialog.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/default/ui/dialog'\nimport { toast } from 'vue-sonner'\n</script>\n\n<template>\n <Dialog>\n <DialogTrigger as-child>\n <Button variant=\"outline\">\n Dialog with toast\n </Button>\n </DialogTrigger>\n <DialogContent\n class=\"sm:max-w-md\"\n @interact-outside=\"event => {\n const target = event.target as HTMLElement;\n if (target?.closest('[data-sonner-toaster]')) return event.preventDefault()\n }\"\n >\n <DialogHeader>\n <DialogTitle>Vue Sonner Toast</DialogTitle>\n <DialogDescription> Dialog with toast </DialogDescription>\n </DialogHeader>\n <div class=\"grid gap-4\">\n <Button\n size=\"sm\"\n class=\"px-3\"\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 Toast\n </Button>\n </div>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "StepperDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"stepper"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/StepperDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Stepper, StepperDescription, StepperIndicator, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/registry/default/ui/stepper'\n\nimport { BookUser, Check, CreditCard, Truck } from 'lucide-vue-next'\n\nconst steps = [{\n step: 1,\n title: 'Address',\n description: 'Add your address here',\n icon: BookUser,\n}, {\n step: 2,\n title: 'Shipping',\n description: 'Set your preferred shipping method',\n icon: Truck,\n}, {\n step: 3,\n title: 'Payment',\n description: 'Add any payment information you have',\n icon: CreditCard,\n}, {\n step: 4,\n title: 'Checkout',\n description: 'Confirm your order',\n icon: Check,\n}]\n</script>\n\n<template>\n <Stepper>\n <StepperItem\n v-for=\"item in steps\"\n :key=\"item.step\"\n class=\"basis-1/4\"\n :step=\"item.step\"\n >\n <StepperTrigger>\n <StepperIndicator>\n <component :is=\"item.icon\" class=\"w-4 h-4\" />\n </StepperIndicator>\n <div class=\"flex flex-col\">\n <StepperTitle>\n {{ item.title }}\n </StepperTitle>\n <StepperDescription>\n {{ item.description }}\n </StepperDescription>\n </div>\n </StepperTrigger>\n <StepperSeparator\n v-if=\"item.step !== steps[steps.length - 1].step\"\n class=\"w-full h-px\"\n />\n </StepperItem>\n </Stepper>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "StepperForm",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"input",
|
|
"select",
|
|
"stepper",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/StepperForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/registry/default/ui/form'\nimport { Input } from '@/registry/default/ui/input'\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/default/ui/select'\nimport { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/registry/default/ui/stepper'\nimport { toast } from '@/registry/default/ui/toast'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { Check, Circle, Dot } from 'lucide-vue-next'\nimport { h, ref } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = [\n z.object({\n fullName: z.string(),\n email: z.string().email(),\n }),\n z.object({\n password: z.string().min(2).max(50),\n confirmPassword: z.string(),\n }).refine(\n (values) => {\n return values.password === values.confirmPassword\n },\n {\n message: 'Passwords must match!',\n path: ['confirmPassword'],\n },\n ),\n z.object({\n favoriteDrink: z.union([z.literal('coffee'), z.literal('tea'), z.literal('soda')]),\n }),\n]\n\nconst stepIndex = ref(1)\nconst steps = [\n {\n step: 1,\n title: 'Your details',\n description: 'Provide your name and email',\n },\n {\n step: 2,\n title: 'Your password',\n description: 'Choose a password',\n },\n {\n step: 3,\n title: 'Your Favorite Drink',\n description: 'Choose a drink',\n },\n]\n\nfunction onSubmit(values: any) {\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\n v-slot=\"{ meta, values, validate }\"\n as=\"\" keep-values :validation-schema=\"toTypedSchema(formSchema[stepIndex - 1])\"\n >\n <Stepper v-slot=\"{ isNextDisabled, isPrevDisabled, nextStep, prevStep }\" v-model=\"stepIndex\" class=\"block w-full\">\n <form\n @submit=\"(e) => {\n e.preventDefault()\n validate()\n\n if (stepIndex === steps.length && meta.valid) {\n onSubmit(values)\n }\n }\"\n >\n <div class=\"flex w-full flex-start gap-2\">\n <StepperItem\n v-for=\"step in steps\"\n :key=\"step.step\"\n v-slot=\"{ state }\"\n class=\"relative flex w-full flex-col items-center justify-center\"\n :step=\"step.step\"\n >\n <StepperSeparator\n v-if=\"step.step !== steps[steps.length - 1].step\"\n class=\"absolute left-[calc(50%+20px)] right-[calc(-50%+10px)] top-5 block h-0.5 shrink-0 rounded-full bg-muted group-data-[state=completed]:bg-primary\"\n />\n\n <StepperTrigger as-child>\n <Button\n :variant=\"state === 'completed' || state === 'active' ? 'default' : 'outline'\"\n size=\"icon\"\n class=\"z-10 rounded-full shrink-0\"\n :class=\"[state === 'active' && 'ring-2 ring-ring ring-offset-2 ring-offset-background']\"\n :disabled=\"state !== 'completed' && !meta.valid\"\n >\n <Check v-if=\"state === 'completed'\" class=\"size-5\" />\n <Circle v-if=\"state === 'active'\" />\n <Dot v-if=\"state === 'inactive'\" />\n </Button>\n </StepperTrigger>\n\n <div class=\"mt-5 flex flex-col items-center text-center\">\n <StepperTitle\n :class=\"[state === 'active' && 'text-primary']\"\n class=\"text-sm font-semibold transition lg:text-base\"\n >\n {{ step.title }}\n </StepperTitle>\n <StepperDescription\n :class=\"[state === 'active' && 'text-primary']\"\n class=\"sr-only text-xs text-muted-foreground transition md:not-sr-only lg:text-sm\"\n >\n {{ step.description }}\n </StepperDescription>\n </div>\n </StepperItem>\n </div>\n\n <div class=\"flex flex-col gap-4 mt-4\">\n <template v-if=\"stepIndex === 1\">\n <FormField v-slot=\"{ componentField }\" name=\"fullName\">\n <FormItem>\n <FormLabel>Full Name</FormLabel>\n <FormControl>\n <Input type=\"text\" v-bind=\"componentField\" />\n </FormControl>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <FormField v-slot=\"{ componentField }\" name=\"email\">\n <FormItem>\n <FormLabel>Email</FormLabel>\n <FormControl>\n <Input type=\"email \" v-bind=\"componentField\" />\n </FormControl>\n <FormMessage />\n </FormItem>\n </FormField>\n </template>\n\n <template v-if=\"stepIndex === 2\">\n <FormField v-slot=\"{ componentField }\" name=\"password\">\n <FormItem>\n <FormLabel>Password</FormLabel>\n <FormControl>\n <Input type=\"password\" v-bind=\"componentField\" />\n </FormControl>\n <FormMessage />\n </FormItem>\n </FormField>\n\n <FormField v-slot=\"{ componentField }\" name=\"confirmPassword\">\n <FormItem>\n <FormLabel>Confirm Password</FormLabel>\n <FormControl>\n <Input type=\"password\" v-bind=\"componentField\" />\n </FormControl>\n <FormMessage />\n </FormItem>\n </FormField>\n </template>\n\n <template v-if=\"stepIndex === 3\">\n <FormField v-slot=\"{ componentField }\" name=\"favoriteDrink\">\n <FormItem>\n <FormLabel>Drink</FormLabel>\n\n <Select v-bind=\"componentField\">\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select a drink\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n <SelectGroup>\n <SelectItem value=\"coffee\">\n Coffe\n </SelectItem>\n <SelectItem value=\"tea\">\n Tea\n </SelectItem>\n <SelectItem value=\"soda\">\n Soda\n </SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n <FormMessage />\n </FormItem>\n </FormField>\n </template>\n </div>\n\n <div class=\"flex items-center justify-between mt-4\">\n <Button :disabled=\"isPrevDisabled\" variant=\"outline\" size=\"sm\" @click=\"prevStep()\">\n Back\n </Button>\n <div class=\"flex items-center gap-3\">\n <Button v-if=\"stepIndex !== 3\" :type=\"meta.valid ? 'button' : 'submit'\" :disabled=\"isNextDisabled\" size=\"sm\" @click=\"meta.valid && nextStep()\">\n Next\n </Button>\n <Button\n v-if=\"stepIndex === 3\" size=\"sm\" type=\"submit\"\n >\n Submit\n </Button>\n </div>\n </div>\n </form>\n </Stepper>\n </Form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "StepperHorizental",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"stepper"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/StepperHorizental.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n\nimport { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/registry/default/ui/stepper'\nimport { Check, Circle, Dot } from 'lucide-vue-next'\n\nconst steps = [\n {\n step: 1,\n title: 'Your details',\n description: 'Provide your name and email',\n },\n {\n step: 2,\n title: 'Company details',\n description: 'A few details about your company',\n },\n {\n step: 3,\n title: 'Invite your team',\n description: 'Start collaborating with your team',\n },\n]\n</script>\n\n<template>\n <Stepper class=\"flex w-full items-start gap-2\">\n <StepperItem\n v-for=\"step in steps\"\n :key=\"step.step\"\n v-slot=\"{ state }\"\n class=\"relative flex w-full flex-col items-center justify-center\"\n :step=\"step.step\"\n >\n <StepperSeparator\n v-if=\"step.step !== steps[steps.length - 1].step\"\n class=\"absolute left-[calc(50%+20px)] right-[calc(-50%+10px)] top-5 block h-0.5 shrink-0 rounded-full bg-muted group-data-[state=completed]:bg-primary\"\n />\n\n <StepperTrigger as-child>\n <Button\n :variant=\"state === 'completed' || state === 'active' ? 'default' : 'outline'\"\n size=\"icon\"\n class=\"z-10 rounded-full shrink-0\"\n :class=\"[state === 'active' && 'ring-2 ring-ring ring-offset-2 ring-offset-background']\"\n >\n <Check v-if=\"state === 'completed'\" class=\"size-5\" />\n <Circle v-if=\"state === 'active'\" />\n <Dot v-if=\"state === 'inactive'\" />\n </Button>\n </StepperTrigger>\n\n <div class=\"mt-5 flex flex-col items-center text-center\">\n <StepperTitle\n :class=\"[state === 'active' && 'text-primary']\"\n class=\"text-sm font-semibold transition lg:text-base\"\n >\n {{ step.title }}\n </StepperTitle>\n <StepperDescription\n :class=\"[state === 'active' && 'text-primary']\"\n class=\"sr-only text-xs text-muted-foreground transition md:not-sr-only lg:text-sm\"\n >\n {{ step.description }}\n </StepperDescription>\n </div>\n </StepperItem>\n </Stepper>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "StepperVertical",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"stepper"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/StepperVertical.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n\nimport { Stepper, StepperDescription, StepperItem, StepperSeparator, StepperTitle, StepperTrigger } from '@/registry/default/ui/stepper'\nimport { Check, Circle, Dot } from 'lucide-vue-next'\n\nconst steps = [\n {\n step: 1,\n title: 'Your details',\n description:\n 'Provide your name and email address. We will use this information to create your account',\n },\n {\n step: 2,\n title: 'Company details',\n description: 'A few details about your company will help us personalize your experience',\n },\n {\n step: 3,\n title: 'Invite your team',\n description:\n 'Start collaborating with your team by inviting them to join your account. You can skip this step and invite them later',\n },\n]\n</script>\n\n<template>\n <Stepper orientation=\"vertical\" class=\"mx-auto flex w-full max-w-md flex-col justify-start gap-10\">\n <StepperItem\n v-for=\"step in steps\"\n :key=\"step.step\"\n v-slot=\"{ state }\"\n class=\"relative flex w-full items-start gap-6\"\n :step=\"step.step\"\n >\n <StepperSeparator\n v-if=\"step.step !== steps[steps.length - 1].step\"\n class=\"absolute left-[18px] top-[38px] block h-[105%] w-0.5 shrink-0 rounded-full bg-muted group-data-[state=completed]:bg-primary\"\n />\n\n <StepperTrigger as-child>\n <Button\n :variant=\"state === 'completed' || state === 'active' ? 'default' : 'outline'\"\n size=\"icon\"\n class=\"z-10 rounded-full shrink-0\"\n :class=\"[state === 'active' && 'ring-2 ring-ring ring-offset-2 ring-offset-background']\"\n >\n <Check v-if=\"state === 'completed'\" class=\"size-5\" />\n <Circle v-if=\"state === 'active'\" />\n <Dot v-if=\"state === 'inactive'\" />\n </Button>\n </StepperTrigger>\n\n <div class=\"flex flex-col gap-1\">\n <StepperTitle\n :class=\"[state === 'active' && 'text-primary']\"\n class=\"text-sm font-semibold transition lg:text-base\"\n >\n {{ step.title }}\n </StepperTitle>\n <StepperDescription\n :class=\"[state === 'active' && 'text-primary']\"\n class=\"sr-only text-xs text-muted-foreground transition md:not-sr-only lg:text-sm\"\n >\n {{ step.description }}\n </StepperDescription>\n </div>\n </StepperItem>\n </Stepper>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SwitchDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"switch"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SwitchDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/default/ui/label'\nimport { Switch } from '@/registry/default/ui/switch'\n</script>\n\n<template>\n <div class=\"flex items-center space-x-2\">\n <Switch id=\"airplane-mode\" />\n <Label for=\"airplane-mode\">Airplane Mode</Label>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "SwitchForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"switch",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/SwitchForm.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} from '@/registry/default/ui/form'\nimport { Switch } from '@/registry/default/ui/switch'\nimport { toast } from '@/registry/default/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n marketing_emails: z.boolean().default(false).optional(),\n security_emails: z.boolean(),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n initialValues: {\n security_emails: true,\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=\"w-full space-y-6\" @submit=\"onSubmit\">\n <div>\n <h3 class=\"mb-4 text-lg font-medium\">\n Email Notifications\n </h3>\n\n <div class=\"space-y-4\">\n <FormField v-slot=\"{ value, handleChange }\" name=\"marketing_emails\">\n <FormItem class=\"flex flex-row items-center justify-between rounded-lg border p-4\">\n <div class=\"space-y-0.5\">\n <FormLabel class=\"text-base\">\n Marketing emails\n </FormLabel>\n <FormDescription>\n Receive emails about new products, features, and more.\n </FormDescription>\n </div>\n <FormControl>\n <Switch\n :model-value=\"value\"\n @update:model-value=\"handleChange\"\n />\n </FormControl>\n </FormItem>\n </FormField>\n <FormField v-slot=\"{ value, handleChange }\" name=\"security_emails\">\n <FormItem class=\"flex flex-row items-center justify-between rounded-lg border p-4\">\n <div class=\"space-y-0.5\">\n <FormLabel class=\"text-base\">\n Security emails\n </FormLabel>\n <FormDescription>\n Receive emails about your account security.\n </FormDescription>\n </div>\n <FormControl>\n <Switch\n :model-value=\"value\"\n disabled\n aria-readonly\n @update:model-value=\"handleChange\"\n />\n </FormControl>\n </FormItem>\n </FormField>\n </div>\n </div>\n <Button type=\"submit\">\n Submit\n </Button>\n </form>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TableDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"table"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TableDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Table,\n TableBody,\n TableCaption,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/default/ui/table'\n\nconst invoices = [\n {\n invoice: 'INV001',\n paymentStatus: 'Paid',\n totalAmount: '$250.00',\n paymentMethod: 'Credit Card',\n },\n {\n invoice: 'INV002',\n paymentStatus: 'Pending',\n totalAmount: '$150.00',\n paymentMethod: 'PayPal',\n },\n {\n invoice: 'INV003',\n paymentStatus: 'Unpaid',\n totalAmount: '$350.00',\n paymentMethod: 'Bank Transfer',\n },\n {\n invoice: 'INV004',\n paymentStatus: 'Paid',\n totalAmount: '$450.00',\n paymentMethod: 'Credit Card',\n },\n {\n invoice: 'INV005',\n paymentStatus: 'Paid',\n totalAmount: '$550.00',\n paymentMethod: 'PayPal',\n },\n {\n invoice: 'INV006',\n paymentStatus: 'Pending',\n totalAmount: '$200.00',\n paymentMethod: 'Bank Transfer',\n },\n {\n invoice: 'INV007',\n paymentStatus: 'Unpaid',\n totalAmount: '$300.00',\n paymentMethod: 'Credit Card',\n },\n]\n</script>\n\n<template>\n <Table>\n <TableCaption>A list of your recent invoices.</TableCaption>\n <TableHeader>\n <TableRow>\n <TableHead class=\"w-[100px]\">\n Invoice\n </TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Method</TableHead>\n <TableHead class=\"text-right\">\n Amount\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <TableRow v-for=\"invoice in invoices\" :key=\"invoice.invoice\">\n <TableCell class=\"font-medium\">\n {{ invoice.invoice }}\n </TableCell>\n <TableCell>{{ invoice.paymentStatus }}</TableCell>\n <TableCell>{{ invoice.paymentMethod }}</TableCell>\n <TableCell class=\"text-right\">\n {{ invoice.totalAmount }}\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TabsDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card",
|
|
"input",
|
|
"label",
|
|
"tabs"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TabsDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\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 { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@/registry/default/ui/tabs'\n</script>\n\n<template>\n <Tabs default-value=\"account\" class=\"w-[400px]\">\n <TabsList class=\"grid w-full grid-cols-2\">\n <TabsTrigger value=\"account\">\n Account\n </TabsTrigger>\n <TabsTrigger value=\"password\">\n Password\n </TabsTrigger>\n </TabsList>\n <TabsContent value=\"account\">\n <Card>\n <CardHeader>\n <CardTitle>Account</CardTitle>\n <CardDescription>\n Make changes to your account here. Click save when you're done.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"space-y-2\">\n <div class=\"space-y-1\">\n <Label for=\"name\">Name</Label>\n <Input id=\"name\" default-value=\"Pedro Duarte\" />\n </div>\n <div class=\"space-y-1\">\n <Label for=\"username\">Username</Label>\n <Input id=\"username\" default-value=\"@peduarte\" />\n </div>\n </CardContent>\n <CardFooter>\n <Button>Save changes</Button>\n </CardFooter>\n </Card>\n </TabsContent>\n <TabsContent value=\"password\">\n <Card>\n <CardHeader>\n <CardTitle>Password</CardTitle>\n <CardDescription>\n Change your password here. After saving, you'll be logged out.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"space-y-2\">\n <div class=\"space-y-1\">\n <Label for=\"current\">Current password</Label>\n <Input id=\"current\" type=\"password\" />\n </div>\n <div class=\"space-y-1\">\n <Label for=\"new\">New password</Label>\n <Input id=\"new\" type=\"password\" />\n </div>\n </CardContent>\n <CardFooter>\n <Button>Save password</Button>\n </CardFooter>\n </Card>\n </TabsContent>\n </Tabs>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TabsVerticalDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card",
|
|
"input",
|
|
"label",
|
|
"tabs"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TabsVerticalDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\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 { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@/registry/default/ui/tabs'\n</script>\n\n<template>\n <Tabs default-value=\"account\" class=\"w-[400px]\" orientation=\"vertical\">\n <TabsList class=\"grid w-full grid-cols-1\">\n <TabsTrigger value=\"account\">\n Accounts\n </TabsTrigger>\n <TabsTrigger value=\"password\">\n Password\n </TabsTrigger>\n </TabsList>\n <TabsContent value=\"account\">\n <Card>\n <CardHeader>\n <CardTitle>Account</CardTitle>\n <CardDescription>\n Make changes to your account here. Click save when you're done.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"space-y-2\">\n <div class=\"space-y-1\">\n <Label for=\"name\">Name</Label>\n <Input id=\"name\" default-value=\"Pedro Duarte\" />\n </div>\n <div class=\"space-y-1\">\n <Label for=\"username\">Username</Label>\n <Input id=\"username\" default-value=\"@peduarte\" />\n </div>\n </CardContent>\n <CardFooter>\n <Button>Save changes</Button>\n </CardFooter>\n </Card>\n </TabsContent>\n <TabsContent value=\"password\">\n <Card>\n <CardHeader>\n <CardTitle>Password</CardTitle>\n <CardDescription>\n Change your password here. After saving, you'll be logged out.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"space-y-2\">\n <div class=\"space-y-1\">\n <Label for=\"current\">Current password</Label>\n <Input id=\"current\" type=\"password\" />\n </div>\n <div class=\"space-y-1\">\n <Label for=\"new\">New password</Label>\n <Input id=\"new\" type=\"password\" />\n </div>\n </CardContent>\n <CardFooter>\n <Button>Save password</Button>\n </CardFooter>\n </Card>\n </TabsContent>\n </Tabs>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TagsInputComboboxDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"reka-ui"
|
|
],
|
|
"registryDependencies": [
|
|
"command",
|
|
"tags-input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TagsInputComboboxDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { CommandEmpty, CommandGroup, CommandItem, CommandList } from '@/registry/default/ui/command'\nimport { TagsInput, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText } from '@/registry/default/ui/tags-input'\nimport { ComboboxAnchor, ComboboxContent, ComboboxInput, ComboboxPortal, ComboboxRoot } from 'reka-ui'\nimport { computed, 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 modelValue = ref<string[]>([])\nconst open = ref(false)\nconst searchTerm = ref('')\n\nconst filteredFrameworks = computed(() => frameworks.filter(i => !modelValue.value.includes(i.label)))\n</script>\n\n<template>\n <TagsInput class=\"px-0 gap-0 w-80\" :model-value=\"modelValue\">\n <div class=\"flex gap-2 flex-wrap items-center px-3\">\n <TagsInputItem v-for=\"item in modelValue\" :key=\"item\" :value=\"item\">\n <TagsInputItemText />\n <TagsInputItemDelete />\n </TagsInputItem>\n </div>\n\n <ComboboxRoot v-model=\"modelValue\" v-model:open=\"open\" v-model:search-term=\"searchTerm\" class=\"w-full\">\n <ComboboxAnchor as-child>\n <ComboboxInput placeholder=\"Framework...\" as-child>\n <TagsInputInput class=\"w-full px-3\" :class=\"modelValue.length > 0 ? 'mt-2' : ''\" @keydown.enter.prevent />\n </ComboboxInput>\n </ComboboxAnchor>\n\n <ComboboxPortal>\n <ComboboxContent>\n <CommandList\n position=\"popper\"\n class=\"w-[--reka-popper-anchor-width] rounded-md mt-2 border bg-popover text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\"\n >\n <CommandEmpty />\n <CommandGroup>\n <CommandItem\n v-for=\"framework in filteredFrameworks\" :key=\"framework.value\" :value=\"framework.label\"\n @select.prevent=\"(ev) => {\n if (typeof ev.detail.value === 'string') {\n searchTerm = ''\n modelValue.push(ev.detail.value)\n }\n\n if (filteredFrameworks.length === 0) {\n open = false\n }\n }\"\n >\n {{ framework.label }}\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n </TagsInput>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TagsInputDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"tags-input"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TagsInputDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { TagsInput, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText } from '@/registry/default/ui/tags-input'\nimport { ref } from 'vue'\n\nconst modelValue = ref(['Apple', 'Banana'])\n</script>\n\n<template>\n <TagsInput v-model=\"modelValue\">\n <TagsInputItem v-for=\"item in modelValue\" :key=\"item\" :value=\"item\">\n <TagsInputItemText />\n <TagsInputItemDelete />\n </TagsInputItem>\n\n <TagsInputInput placeholder=\"Fruits...\" />\n </TagsInput>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TagsInputFormDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"tags-input",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TagsInputFormDemo.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 { TagsInput, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText } from '@/registry/default/ui/tags-input'\nimport { toast } from '@/registry/default/ui/toast'\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport { z } from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n fruits: z.array(z.string()).min(1).max(3),\n}))\n\nconst { handleSubmit } = useForm({\n validationSchema: formSchema,\n initialValues: {\n fruits: ['Apple', 'Banana'],\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=\"w-2/3 space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ value }\" name=\"fruits\">\n <FormItem>\n <FormLabel>Fruits</FormLabel>\n <FormControl>\n <TagsInput :model-value=\"value\">\n <TagsInputItem v-for=\"item in value\" :key=\"item\" :value=\"item\">\n <TagsInputItemText />\n <TagsInputItemDelete />\n </TagsInputItem>\n\n <TagsInputInput placeholder=\"Fruits...\" />\n </TagsInput>\n </FormControl>\n <FormDescription>\n Select your favorite fruits.\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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TextareaDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"textarea"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TextareaDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Textarea } from '@/registry/default/ui/textarea'\n</script>\n\n<template>\n <Textarea placeholder=\"Type your message here.\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TextareaDisabled",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"textarea"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TextareaDisabled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Textarea } from '@/registry/default/ui/textarea'\n</script>\n\n<template>\n <Textarea placeholder=\"Type your message here.\" disabled />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TextareaForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"button",
|
|
"form",
|
|
"textarea",
|
|
"toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TextareaForm.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 { Textarea } from '@/registry/default/ui/textarea'\nimport { toast } from '@/registry/default/ui/toast'\n\nimport { toTypedSchema } from '@vee-validate/zod'\nimport { useForm } from 'vee-validate'\nimport { h } from 'vue'\nimport * as z from 'zod'\n\nconst formSchema = toTypedSchema(z.object({\n bio: z\n .string()\n .min(10, {\n message: 'Bio must be at least 10 characters.',\n })\n .max(160, {\n message: 'Bio must not be longer than 30 characters.',\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=\"w-full space-y-6\" @submit=\"onSubmit\">\n <FormField v-slot=\"{ componentField }\" name=\"bio\">\n <FormItem>\n <FormLabel>Bio</FormLabel>\n <FormControl>\n <Textarea\n placeholder=\"Tell us a little bit about yourself\"\n class=\"resize-none\"\n v-bind=\"componentField\"\n />\n </FormControl>\n <FormDescription>\n You can <span>@mention</span> other users and organizations.\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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TextareaWithButton",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"textarea"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TextareaWithButton.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { Textarea } from '@/registry/default/ui/textarea'\n</script>\n\n<template>\n <div class=\"grid w-full gap-2\">\n <Textarea placeholder=\"Type your message here.\" />\n <Button>Send message</Button>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TextareaWithLabel",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"textarea"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TextareaWithLabel.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/default/ui/label'\nimport { Textarea } from '@/registry/default/ui/textarea'\n</script>\n\n<template>\n <div class=\"grid w-full gap-1.5\">\n <Label for=\"message\">Your message</Label>\n <Textarea id=\"message\" placeholder=\"Type your message here.\" />\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TextareaWithText",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"label",
|
|
"textarea"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TextareaWithText.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/default/ui/label'\nimport { Textarea } from '@/registry/default/ui/textarea'\n</script>\n\n<template>\n <div class=\"grid w-full gap-1.5\">\n <Label for=\"message-2\">Your message</Label>\n <Textarea id=\"message-2\" placeholder=\"Type your message here.\" />\n <p class=\"text-sm text-muted-foreground\">\n Your message will be copied to the support team.\n </p>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToastDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"use-toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToastDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { useToast } from '@/registry/default/ui/toast/use-toast'\n\nconst { toast } = useToast()\n</script>\n\n<template>\n <Button\n variant=\"outline\" @click=\"() => {\n toast({\n title: 'Scheduled: Catch up',\n description: 'Friday, February 10, 2023 at 5:57 PM',\n });\n }\"\n >\n Add to calendar\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToastDestructive",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"toast",
|
|
"use-toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToastDestructive.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { ToastAction } from '@/registry/default/ui/toast'\nimport { useToast } from '@/registry/default/ui/toast/use-toast'\nimport { h } from 'vue'\n\nconst { toast } = useToast()\n</script>\n\n<template>\n <Button\n variant=\"outline\" @click=\"() => {\n toast({\n title: 'Uh oh! Something went wrong.',\n description: 'There was a problem with your request.',\n variant: 'destructive',\n action: h(ToastAction, {\n altText: 'Try again',\n }, {\n default: () => 'Try again',\n }),\n });\n }\"\n >\n Show Toast\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToastSimple",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"use-toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToastSimple.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { useToast } from '@/registry/default/ui/toast/use-toast'\n\nconst { toast } = useToast()\n</script>\n\n<template>\n <Button\n variant=\"outline\" @click=\"() => {\n toast({\n description: 'Your message has been sent.',\n });\n }\"\n >\n Show Toast\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToastWithAction",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"toast",
|
|
"use-toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToastWithAction.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { ToastAction } from '@/registry/default/ui/toast'\nimport { useToast } from '@/registry/default/ui/toast/use-toast'\nimport { h } from 'vue'\n\nconst { toast } = useToast()\n</script>\n\n<template>\n <Button\n variant=\"outline\" @click=\"() => {\n toast({\n title: 'Uh oh! Something went wrong.',\n description: 'There was a problem with your request.',\n action: h(ToastAction, {\n altText: 'Try again',\n }, {\n default: () => 'Try again',\n }),\n });\n }\"\n >\n Show Toast\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToastWithTitle",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"use-toast"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToastWithTitle.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport { useToast } from '@/registry/default/ui/toast/use-toast'\n\nconst { toast } = useToast()\n</script>\n\n<template>\n <Button\n variant=\"outline\" @click=\"() => {\n toast({\n title: 'Uh oh! Something went wrong.',\n description: 'There was a problem with your request.',\n });\n }\"\n >\n Show Toast\n </Button>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Toggle } from '@/registry/default/ui/toggle'\n\nimport { Bold } from 'lucide-vue-next'\n</script>\n\n<template>\n <Toggle aria-label=\"Toggle bold\">\n <Bold class=\"h-4 w-4\" />\n </Toggle>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleDisabledDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleDisabledDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Toggle } from '@/registry/default/ui/toggle'\n\nimport { Underline } from 'lucide-vue-next'\n</script>\n\n<template>\n <Toggle aria-label=\"Toggle underline\" disabled>\n <Underline class=\"w-4 h-4\" />\n </Toggle>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleGroupDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleGroupDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/default/ui/toggle-group'\n\nimport { Bold, Italic, Underline } from 'lucide-vue-next'\n</script>\n\n<template>\n <ToggleGroup type=\"multiple\">\n <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n <Bold class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n <Italic class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n <Underline class=\"h-4 w-4\" />\n </ToggleGroupItem>\n </ToggleGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleGroupDisabledDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleGroupDisabledDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/default/ui/toggle-group'\n\nimport { Bold, Italic, Underline } from 'lucide-vue-next'\n</script>\n\n<template>\n <ToggleGroup type=\"multiple\" disabled>\n <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n <Bold class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n <Italic class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n <Underline class=\"h-4 w-4\" />\n </ToggleGroupItem>\n </ToggleGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleGroupLargeDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleGroupLargeDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/default/ui/toggle-group'\n\nimport { Bold, Italic, Underline } from 'lucide-vue-next'\n</script>\n\n<template>\n <ToggleGroup type=\"multiple\" size=\"lg\">\n <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n <Bold class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n <Italic class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n <Underline class=\"h-4 w-4\" />\n </ToggleGroupItem>\n </ToggleGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleGroupOutlineDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleGroupOutlineDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/default/ui/toggle-group'\n\nimport { Bold, Italic, Underline } from 'lucide-vue-next'\n</script>\n\n<template>\n <ToggleGroup type=\"multiple\" variant=\"outline\">\n <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n <Bold class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n <Italic class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n <Underline class=\"h-4 w-4\" />\n </ToggleGroupItem>\n </ToggleGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleGroupSingleDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleGroupSingleDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/default/ui/toggle-group'\n\nimport { Bold, Italic, Underline } from 'lucide-vue-next'\n</script>\n\n<template>\n <ToggleGroup type=\"single\">\n <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n <Bold class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n <Italic class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n <Underline class=\"h-4 w-4\" />\n </ToggleGroupItem>\n </ToggleGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleGroupSmallDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle-group"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleGroupSmallDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/default/ui/toggle-group'\n\nimport { Bold, Italic, Underline } from 'lucide-vue-next'\n</script>\n\n<template>\n <ToggleGroup type=\"multiple\" size=\"sm\">\n <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n <Bold class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n <Italic class=\"h-4 w-4\" />\n </ToggleGroupItem>\n <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n <Underline class=\"h-4 w-4\" />\n </ToggleGroupItem>\n </ToggleGroup>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleItalicDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleItalicDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Toggle } from '@/registry/default/ui/toggle'\n\nimport { Italic } from 'lucide-vue-next'\n</script>\n\n<template>\n <Toggle variant=\"outline\" aria-label=\"Toggle italic\">\n <Italic class=\"w-4 h-4\" />\n </Toggle>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleItalicWithTextDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleItalicWithTextDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Toggle } from '@/registry/default/ui/toggle'\n\nimport { Italic } from 'lucide-vue-next'\n</script>\n\n<template>\n <Toggle aria-label=\"Toggle italic\">\n <Italic class=\"w-4 h-4 mr-2\" />\n Italic\n </Toggle>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleLargeDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleLargeDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Toggle } from '@/registry/default/ui/toggle'\n\nimport { Italic } from 'lucide-vue-next'\n</script>\n\n<template>\n <Toggle size=\"lg\" aria-label=\"Toggle italic\">\n <Italic class=\"w-4 h-4\" />\n </Toggle>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "ToggleSmallDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"toggle"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/ToggleSmallDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Toggle } from '@/registry/default/ui/toggle'\n\nimport { Italic } from 'lucide-vue-next'\n</script>\n\n<template>\n <Toggle size=\"sm\" aria-label=\"Toggle italic\">\n <Italic class=\"w-4 h-4\" />\n </Toggle>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TooltipDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"tooltip"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/TooltipDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@/registry/default/ui/tooltip'\n</script>\n\n<template>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button variant=\"outline\">\n Hover\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n <p>Add to library</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyBlockquote",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyBlockquote.vue",
|
|
"content": "<template>\n <blockquote class=\"mt-6 border-l-2 pl-6 italic\">\n \"After all,\" he said, \"everyone enjoys a good joke, so it's only fair that\n they should pay for the privilege.\"\n </blockquote>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyDemo.vue",
|
|
"content": "<template>\n <div>\n <h1 class=\"scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl\">\n The Joke Tax Chronicles\n </h1>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n Once upon a time, in a far-off land, there was a very lazy king who\n spent all day lounging on his throne. One day, his advisors came to him\n with a problem: the kingdom was running out of money.\n </p>\n <h2\n class=\"mt-10 scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight transition-colors first:mt-0\"\n >\n The King's Plan\n </h2>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n The king thought long and hard, and finally came up with\n <a\n href=\"#\"\n class=\"font-medium text-primary underline underline-offset-4\"\n >\n a brilliant plan\n </a>\n : he would tax the jokes in the kingdom.\n </p>\n <blockquote class=\"mt-6 border-l-2 pl-6 italic\">\n \"After all,\" he said, \"everyone enjoys a good joke, so it's only fair\n that they should pay for the privilege.\"\n </blockquote>\n <h3 class=\"mt-8 scroll-m-20 text-2xl font-semibold tracking-tight\">\n The Joke Tax\n </h3>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n The king's subjects were not amused. They grumbled and complained, but\n the king was firm:\n </p>\n <ul class=\"my-6 ml-6 list-disc [&>li]:mt-2\">\n <li>1st level of puns: 5 gold coins</li>\n <li>2nd level of jokes: 10 gold coins</li>\n <li>3rd level of one-liners : 20 gold coins</li>\n </ul>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n As a result, people stopped telling jokes, and the kingdom fell into a\n gloom. But there was one person who refused to let the king's\n foolishness get him down: a court jester named Jokester.\n </p>\n <h3 class=\"mt-8 scroll-m-20 text-2xl font-semibold tracking-tight\">\n Jokester's Revolt\n </h3>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n Jokester began sneaking into the castle in the middle of the night and\n leaving jokes all over the place: under the king's pillow, in his soup,\n even in the royal toilet. The king was furious, but he couldn't seem to\n stop Jokester.\n </p>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n And then, one day, the people of the kingdom discovered that the jokes\n left by Jokester were so funny that they couldn't help but laugh. And\n once they started laughing, they couldn't stop.\n </p>\n <h3 class=\"mt-8 scroll-m-20 text-2xl font-semibold tracking-tight\">\n The People's Rebellion\n </h3>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n The people of the kingdom, feeling uplifted by the laughter, started to\n tell jokes and puns again, and soon the entire kingdom was in on the\n joke.\n </p>\n <div class=\"my-6 w-full overflow-y-auto\">\n <table class=\"w-full\">\n <thead>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <th\n class=\"border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n King's Treasury\n </th>\n <th\n class=\"border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n People's happiness\n </th>\n </tr>\n </thead>\n <tbody>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Empty\n </td>\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Overflowing\n </td>\n </tr>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Modest\n </td>\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Satisfied\n </td>\n </tr>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Full\n </td>\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Ecstatic\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n The king, seeing how much happier his subjects were, realized the error\n of his ways and repealed the joke tax. Jokester was declared a hero, and\n the kingdom lived happily ever after.\n </p>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n The moral of the story is: never underestimate the power of a good laugh\n and always be careful of bad ideas.\n </p>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyH1",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyH1.vue",
|
|
"content": "<template>\n <h1 class=\"scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl\">\n Taxing Laughter: The Joke Tax Chronicles\n </h1>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyH2",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyH2.vue",
|
|
"content": "<template>\n <h2\n class=\"scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight transition-colors first:mt-0\"\n >\n The People of the Kingdom\n </h2>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyH3",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyH3.vue",
|
|
"content": "<template>\n <h3 class=\"scroll-m-20 text-2xl font-semibold tracking-tight\">\n The Joke Tax\n </h3>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyH4",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyH4.vue",
|
|
"content": "<template>\n <h4 class=\"scroll-m-20 text-xl font-semibold tracking-tight\">\n People stopped telling jokes\n </h4>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyInlineCode",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyInlineCode.vue",
|
|
"content": "<template>\n <code\n class=\"relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold\"\n >\n reka-ui\n </code>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyLarge",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyLarge.vue",
|
|
"content": "<template>\n <div class=\"text-lg font-semibold\">\n Are you absolutely sure?\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyLead",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyLead.vue",
|
|
"content": "<template>\n <p class=\"text-xl text-muted-foreground\">\n A modal dialog that interrupts the user with important content and expects a\n response.\n </p>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyList",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyList.vue",
|
|
"content": "<template>\n <ul class=\"my-6 ml-6 list-disc [&>li]:mt-2\">\n <li>1st level of puns: 5 gold coins</li>\n <li>2nd level of jokes: 10 gold coins</li>\n <li>3rd level of one-liners : 20 gold coins</li>\n </ul>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyMuted",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyMuted.vue",
|
|
"content": "<template>\n <p class=\"text-sm text-muted-foreground\">\n Enter your email address.\n </p>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyP",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyP.vue",
|
|
"content": "<template>\n <p class=\"leading-7 [&:not(:first-child)]:mt-6\">\n The king, seeing how much happier his subjects were, realized the error of\n his ways and repealed the joke tax.\n </p>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographySmall",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographySmall.vue",
|
|
"content": "<template>\n <small class=\"text-sm font-medium leading-none\">\n Email address\n </small>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "TypographyTable",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [],
|
|
"files": [
|
|
{
|
|
"path": "example/TypographyTable.vue",
|
|
"content": "<template>\n <div class=\"my-6 w-full overflow-y-auto\">\n <table class=\"w-full\">\n <thead>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <th\n class=\"border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n King's Treasury\n </th>\n <th\n class=\"border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n People's happiness\n </th>\n </tr>\n </thead>\n <tbody>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Empty\n </td>\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Overflowing\n </td>\n </tr>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Modest\n </td>\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Satisfied\n </td>\n </tr>\n <tr class=\"m-0 border-t p-0 even:bg-muted\">\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Full\n </td>\n <td\n class=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n >\n Ecstatic\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VCalendarDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VCalendarDemo.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Calendar } from '@/registry/default/ui/v-calendar'\nimport { ref } from 'vue'\n\nconst date = ref(new Date())\n</script>\n\n<template>\n <Calendar v-model=\"date\" class=\"rounded-md border\" />\n</template>\n",
|
|
"type": "registry:example",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VDatePickerDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VDatePickerDemo.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VDatePickerForm",
|
|
"type": "registry:example",
|
|
"dependencies": [
|
|
"vee-validate",
|
|
"@vee-validate/zod",
|
|
"zod"
|
|
],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"form",
|
|
"popover",
|
|
"toast",
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VDatePickerForm.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VDatePickerWithPresets",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"select",
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VDatePickerWithPresets.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VDatePickerWithRange",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VDatePickerWithRange.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VDateTimePickerDemo",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VDateTimePickerDemo.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "VRangePickerWithSlot",
|
|
"type": "registry:example",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"utils",
|
|
"button",
|
|
"popover",
|
|
"v-calendar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "example/VRangePickerWithSlot.vue",
|
|
"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": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Authentication01",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"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": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Authentication02",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"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": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Authentication03",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"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": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Authentication04",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"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": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard01",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"avatar",
|
|
"badge",
|
|
"button",
|
|
"card",
|
|
"dropdown-menu",
|
|
"input",
|
|
"sheet",
|
|
"table"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard01.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'An application shell with a header and main content area. The header has a navbar, a search input and and a user nav dropdown. The user nav is toggled by a button with an avatar image. The main content area is divided into two rows. The first row has a grid of cards with statistics. The second row has a grid of cards with a table of recent transactions and a list of recent sales.'\nexport const iframeHeight = '825px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Avatar, AvatarFallback, AvatarImage } from '@/registry/default/ui/avatar'\nimport { Badge } from '@/registry/default/ui/badge'\nimport { Button } from '@/registry/default/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/registry/default/ui/card'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/default/ui/dropdown-menu'\nimport { Input } from '@/registry/default/ui/input'\nimport { Sheet, SheetContent, SheetTrigger } from '@/registry/default/ui/sheet'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/registry/default/ui/table'\nimport { Activity, ArrowUpRight, CircleUser, CreditCard, DollarSign, Menu, Package2, Search, Users } from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"flex min-h-screen w-full flex-col\">\n <header class=\"sticky top-0 flex h-16 items-center gap-4 border-b bg-background px-4 md:px-6\">\n <nav class=\"hidden flex-col gap-6 text-lg font-medium md:flex md:flex-row md:items-center md:gap-5 md:text-sm lg:gap-6\">\n <a\n href=\"#\"\n class=\"flex items-center gap-2 text-lg font-semibold md:text-base\"\n >\n <Package2 class=\"h-6 w-6\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"text-foreground transition-colors hover:text-foreground\"\n >\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Orders\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Products\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Customers\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Analytics\n </a>\n </nav>\n <Sheet>\n <SheetTrigger as-child>\n <Button\n variant=\"outline\"\n size=\"icon\"\n class=\"shrink-0 md:hidden\"\n >\n <Menu class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle navigation menu</span>\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\">\n <nav class=\"grid gap-6 text-lg font-medium\">\n <a\n href=\"#\"\n class=\"flex items-center gap-2 text-lg font-semibold\"\n >\n <Package2 class=\"h-6 w-6\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a href=\"#\" class=\"hover:text-foreground\">\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Orders\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Products\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Customers\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Analytics\n </a>\n </nav>\n </SheetContent>\n </Sheet>\n <div class=\"flex w-full items-center gap-4 md:ml-auto md:gap-2 lg:gap-4\">\n <form class=\"ml-auto flex-1 sm:flex-initial\">\n <div class=\"relative\">\n <Search class=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n type=\"search\"\n placeholder=\"Search products...\"\n class=\"pl-8 sm:w-[300px] md:w-[200px] lg:w-[300px]\"\n />\n </div>\n </form>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"secondary\" size=\"icon\" class=\"rounded-full\">\n <CircleUser class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle user menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Settings</DropdownMenuItem>\n <DropdownMenuItem>Support</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Logout</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </header>\n <main class=\"flex flex-1 flex-col gap-4 p-4 md:gap-8 md:p-8\">\n <div class=\"grid gap-4 md:grid-cols-2 md:gap-8 lg:grid-cols-4\">\n <Card>\n <CardHeader class=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle class=\"text-sm font-medium\">\n Total Revenue\n </CardTitle>\n <DollarSign class=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div class=\"text-2xl font-bold\">\n $45,231.89\n </div>\n <p class=\"text-xs text-muted-foreground\">\n +20.1% from last month\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader class=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle class=\"text-sm font-medium\">\n Subscriptions\n </CardTitle>\n <Users class=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div class=\"text-2xl font-bold\">\n +2350\n </div>\n <p class=\"text-xs text-muted-foreground\">\n +180.1% from last month\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader class=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle class=\"text-sm font-medium\">\n Sales\n </CardTitle>\n <CreditCard class=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div class=\"text-2xl font-bold\">\n +12,234\n </div>\n <p class=\"text-xs text-muted-foreground\">\n +19% from last month\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardHeader class=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle class=\"text-sm font-medium\">\n Active Now\n </CardTitle>\n <Activity class=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div class=\"text-2xl font-bold\">\n +573\n </div>\n <p class=\"text-xs text-muted-foreground\">\n +201 since last hour\n </p>\n </CardContent>\n </Card>\n </div>\n <div class=\"grid gap-4 md:gap-8 lg:grid-cols-2 xl:grid-cols-3\">\n <Card class=\"xl:col-span-2\">\n <CardHeader class=\"flex flex-row items-center\">\n <div class=\"grid gap-2\">\n <CardTitle>Transactions</CardTitle>\n <CardDescription>\n Recent transactions from your store.\n </CardDescription>\n </div>\n <Button as-child size=\"sm\" class=\"ml-auto gap-1\">\n <a href=\"#\">\n View All\n <ArrowUpRight class=\"h-4 w-4\" />\n </a>\n </Button>\n </CardHeader>\n <CardContent>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Customer</TableHead>\n <TableHead class=\"hidden xl:table-column\">\n Type\n </TableHead>\n <TableHead class=\"hidden xl:table-column\">\n Status\n </TableHead>\n <TableHead class=\"hidden xl:table-column\">\n Date\n </TableHead>\n <TableHead class=\"text-right\">\n Amount\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Liam Johnson\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n liam@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n Sale\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Approved\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell lg:hidden xl:table-column\">\n 2023-06-23\n </TableCell>\n <TableCell class=\"text-right\">\n $250.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Olivia Smith\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n olivia@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n Refund\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Declined\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell lg:hidden xl:table-column\">\n 2023-06-24\n </TableCell>\n <TableCell class=\"text-right\">\n $150.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Noah Williams\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n noah@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n Subscription\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Approved\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell lg:hidden xl:table-column\">\n 2023-06-25\n </TableCell>\n <TableCell class=\"text-right\">\n $350.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Emma Brown\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n emma@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n Sale\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Approved\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell lg:hidden xl:table-column\">\n 2023-06-26\n </TableCell>\n <TableCell class=\"text-right\">\n $450.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Liam Johnson\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n liam@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n Sale\n </TableCell>\n <TableCell class=\"hidden xl:table-column\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Approved\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell lg:hidden xl:table-column\">\n 2023-06-27\n </TableCell>\n <TableCell class=\"text-right\">\n $550.00\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Recent Sales</CardTitle>\n </CardHeader>\n <CardContent class=\"grid gap-8\">\n <div class=\"flex items-center gap-4\">\n <Avatar class=\"hidden h-9 w-9 sm:flex\">\n <AvatarImage src=\"/avatars/01.png\" alt=\"Avatar\" />\n <AvatarFallback>OM</AvatarFallback>\n </Avatar>\n <div class=\"grid gap-1\">\n <p class=\"text-sm font-medium leading-none\">\n Olivia Martin\n </p>\n <p class=\"text-sm text-muted-foreground\">\n olivia.martin@email.com\n </p>\n </div>\n <div class=\"ml-auto font-medium\">\n +$1,999.00\n </div>\n </div>\n <div class=\"flex items-center gap-4\">\n <Avatar class=\"hidden h-9 w-9 sm:flex\">\n <AvatarImage src=\"/avatars/02.png\" alt=\"Avatar\" />\n <AvatarFallback>JL</AvatarFallback>\n </Avatar>\n <div class=\"grid gap-1\">\n <p class=\"text-sm font-medium leading-none\">\n Jackson Lee\n </p>\n <p class=\"text-sm text-muted-foreground\">\n jackson.lee@email.com\n </p>\n </div>\n <div class=\"ml-auto font-medium\">\n +$39.00\n </div>\n </div>\n <div class=\"flex items-center gap-4\">\n <Avatar class=\"hidden h-9 w-9 sm:flex\">\n <AvatarImage src=\"/avatars/03.png\" alt=\"Avatar\" />\n <AvatarFallback>IN</AvatarFallback>\n </Avatar>\n <div class=\"grid gap-1\">\n <p class=\"text-sm font-medium leading-none\">\n Isabella Nguyen\n </p>\n <p class=\"text-sm text-muted-foreground\">\n isabella.nguyen@email.com\n </p>\n </div>\n <div class=\"ml-auto font-medium\">\n +$299.00\n </div>\n </div>\n <div class=\"flex items-center gap-4\">\n <Avatar class=\"hidden h-9 w-9 sm:flex\">\n <AvatarImage src=\"/avatars/04.png\" alt=\"Avatar\" />\n <AvatarFallback>WK</AvatarFallback>\n </Avatar>\n <div class=\"grid gap-1\">\n <p class=\"text-sm font-medium leading-none\">\n William Kim\n </p>\n <p class=\"text-sm text-muted-foreground\">\n will@email.com\n </p>\n </div>\n <div class=\"ml-auto font-medium\">\n +$99.00\n </div>\n </div>\n <div class=\"flex items-center gap-4\">\n <Avatar class=\"hidden h-9 w-9 sm:flex\">\n <AvatarImage src=\"/avatars/05.png\" alt=\"Avatar\" />\n <AvatarFallback>SD</AvatarFallback>\n </Avatar>\n <div class=\"grid gap-1\">\n <p class=\"text-sm font-medium leading-none\">\n Sofia Davis\n </p>\n <p class=\"text-sm text-muted-foreground\">\n sofia.davis@email.com\n </p>\n </div>\n <div class=\"ml-auto font-medium\">\n +$39.00\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n </main>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard02",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge",
|
|
"button",
|
|
"card",
|
|
"dropdown-menu",
|
|
"input",
|
|
"sheet"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard02.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A products dashboard with a sidebar navigation and a main content area. The dashboard has a header with a search input and a user menu. The sidebar has a logo, navigation links, and a card with a call to action. The main content area shows an empty state with a call to action.'\nexport const iframeHeight = '800px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Badge } from '@/registry/default/ui/badge'\n\nimport { Button } from '@/registry/default/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/registry/default/ui/card'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/default/ui/dropdown-menu'\nimport { Input } from '@/registry/default/ui/input'\nimport { Sheet, SheetContent, SheetTrigger } from '@/registry/default/ui/sheet'\nimport { Bell, CircleUser, Home, LineChart, Menu, Package, Package2, Search, ShoppingCart, Users } from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"grid min-h-screen w-full md:grid-cols-[220px_1fr] lg:grid-cols-[280px_1fr]\">\n <div class=\"hidden border-r bg-muted/40 md:block\">\n <div class=\"flex h-full max-h-screen flex-col gap-2\">\n <div class=\"flex h-14 items-center border-b px-4 lg:h-[60px] lg:px-6\">\n <a href=\"/\" class=\"flex items-center gap-2 font-semibold\">\n <Package2 class=\"h-6 w-6\" />\n <span class=\"\">Acme Inc</span>\n </a>\n <Button variant=\"outline\" size=\"icon\" class=\"ml-auto h-8 w-8\">\n <Bell class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle notifications</span>\n </Button>\n </div>\n <div class=\"flex-1\">\n <nav class=\"grid items-start px-2 text-sm font-medium lg:px-4\">\n <a\n href=\"/\"\n class=\"flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary\"\n >\n <Home class=\"h-4 w-4\" />\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary\"\n >\n <ShoppingCart class=\"h-4 w-4\" />\n Orders\n <Badge class=\"ml-auto flex h-6 w-6 shrink-0 items-center justify-center rounded-full\">\n 6\n </Badge>\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-3 rounded-lg bg-muted px-3 py-2 text-primary transition-all hover:text-primary\"\n >\n <Package class=\"h-4 w-4\" />\n Products\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary\"\n >\n <Users class=\"h-4 w-4\" />\n Customers\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-3 rounded-lg px-3 py-2 text-muted-foreground transition-all hover:text-primary\"\n >\n <LineChart class=\"h-4 w-4\" />\n Analytics\n </a>\n </nav>\n </div>\n <div class=\"mt-auto p-4\">\n <Card>\n <CardHeader class=\"p-2 pt-0 md:p-4\">\n <CardTitle>Upgrade to Pro</CardTitle>\n <CardDescription>\n Unlock all features and get unlimited access to our support\n team.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"p-2 pt-0 md:p-4 md:pt-0\">\n <Button size=\"sm\" class=\"w-full\">\n Upgrade\n </Button>\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n <div class=\"flex flex-col\">\n <header class=\"flex h-14 items-center gap-4 border-b bg-muted/40 px-4 lg:h-[60px] lg:px-6\">\n <Sheet>\n <SheetTrigger as-child>\n <Button\n variant=\"outline\"\n size=\"icon\"\n class=\"shrink-0 md:hidden\"\n >\n <Menu class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle navigation menu</span>\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\" class=\"flex flex-col\">\n <nav class=\"grid gap-2 text-lg font-medium\">\n <a\n href=\"#\"\n class=\"flex items-center gap-2 text-lg font-semibold\"\n >\n <Package2 class=\"h-6 w-6\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 text-muted-foreground hover:text-foreground\"\n >\n <Home class=\"h-5 w-5\" />\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"mx-[-0.65rem] flex items-center gap-4 rounded-xl bg-muted px-3 py-2 text-foreground hover:text-foreground\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n Orders\n <Badge class=\"ml-auto flex h-6 w-6 shrink-0 items-center justify-center rounded-full\">\n 6\n </Badge>\n </a>\n <a\n href=\"#\"\n class=\"mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 text-muted-foreground hover:text-foreground\"\n >\n <Package class=\"h-5 w-5\" />\n Products\n </a>\n <a\n href=\"#\"\n class=\"mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 text-muted-foreground hover:text-foreground\"\n >\n <Users class=\"h-5 w-5\" />\n Customers\n </a>\n <a\n href=\"#\"\n class=\"mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 text-muted-foreground hover:text-foreground\"\n >\n <LineChart class=\"h-5 w-5\" />\n Analytics\n </a>\n </nav>\n <div class=\"mt-auto\">\n <Card>\n <CardHeader>\n <CardTitle>Upgrade to Pro</CardTitle>\n <CardDescription>\n Unlock all features and get unlimited access to our\n support team.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Button size=\"sm\" class=\"w-full\">\n Upgrade\n </Button>\n </CardContent>\n </Card>\n </div>\n </SheetContent>\n </Sheet>\n <div class=\"w-full flex-1\">\n <form>\n <div class=\"relative\">\n <Search class=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n type=\"search\"\n placeholder=\"Search products...\"\n class=\"w-full appearance-none bg-background pl-8 shadow-none md:w-2/3 lg:w-1/3\"\n />\n </div>\n </form>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"secondary\" size=\"icon\" class=\"rounded-full\">\n <CircleUser class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle user menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Settings</DropdownMenuItem>\n <DropdownMenuItem>Support</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Logout</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </header>\n <main class=\"flex flex-1 flex-col gap-4 p-4 lg:gap-6 lg:p-6\">\n <div class=\"flex items-center\">\n <h1 class=\"text-lg font-semibold md:text-2xl\">\n Inventory\n </h1>\n </div>\n <div class=\"flex flex-1 items-center justify-center rounded-lg border border-dashed shadow-sm\">\n <div class=\"flex flex-col items-center gap-1 text-center\">\n <h3 class=\"text-2xl font-bold tracking-tight\">\n You have no products\n </h3>\n <p class=\"text-sm text-muted-foreground\">\n You can start selling as soon as you add a product.\n </p>\n <Button class=\"mt-4\">\n Add Product\n </Button>\n </div>\n </div>\n </main>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard03",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge",
|
|
"button",
|
|
"drawer",
|
|
"input",
|
|
"label",
|
|
"select",
|
|
"textarea",
|
|
"tooltip"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard03.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'An AI playground with a sidebar navigation and a main content area. The playground has a header with a settings drawer and a share button. The sidebar has navigation links and a user menu. The main content area shows a form to configure the model and messages.'\nexport const iframeHeight = '740px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Badge } from '@/registry/default/ui/badge'\n\nimport { Button } from '@/registry/default/ui/button'\nimport { Drawer, DrawerContent, DrawerDescription, DrawerHeader, DrawerTitle, DrawerTrigger } from '@/registry/default/ui/drawer'\nimport { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/registry/default/ui/select'\nimport { Textarea } from '@/registry/default/ui/textarea'\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/registry/default/ui/tooltip'\nimport { Bird, Book, Bot, Code2, CornerDownLeft, LifeBuoy, Mic, Paperclip, Rabbit, Settings, Settings2, Share, SquareTerminal, SquareUser, Triangle, Turtle } from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"grid h-screen w-full pl-[56px]\">\n <aside class=\"inset-y fixed left-0 z-20 flex h-full flex-col border-r\">\n <div class=\"border-b p-2\">\n <Button variant=\"outline\" size=\"icon\" aria-label=\"Home\">\n <Triangle class=\"size-5 fill-foreground\" />\n </Button>\n </div>\n <nav class=\"grid gap-1 p-2\">\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"rounded-lg bg-muted\"\n aria-label=\"Playground\"\n >\n <SquareTerminal class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n Playground\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"rounded-lg\"\n aria-label=\"Models\"\n >\n <Bot class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n Models\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"rounded-lg\"\n aria-label=\"API\"\n >\n <Code2 class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n API\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"rounded-lg\"\n aria-label=\"Documentation\"\n >\n <Book class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n Documentation\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"rounded-lg\"\n aria-label=\"Settings\"\n >\n <Settings2 class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n Settings\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </nav>\n <nav class=\"mt-auto grid gap-1 p-2\">\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mt-auto rounded-lg\"\n aria-label=\"Help\"\n >\n <LifeBuoy class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n Help\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mt-auto rounded-lg\"\n aria-label=\"Account\"\n >\n <SquareUser class=\"size-5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" :side-offset=\"5\">\n Account\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </nav>\n </aside>\n <div class=\"flex flex-col\">\n <header class=\"sticky top-0 z-10 flex h-[57px] items-center gap-1 border-b bg-background px-4\">\n <h1 class=\"text-xl font-semibold\">\n Playground\n </h1>\n <Drawer>\n <DrawerTrigger as-child>\n <Button variant=\"ghost\" size=\"icon\" class=\"md:hidden\">\n <Settings class=\"size-4\" />\n <span class=\"sr-only\">Settings</span>\n </Button>\n </DrawerTrigger>\n <DrawerContent class=\"max-h-[80vh]\">\n <DrawerHeader>\n <DrawerTitle>Configuration</DrawerTitle>\n <DrawerDescription>\n Configure the settings for the model and messages.\n </DrawerDescription>\n </DrawerHeader>\n <form class=\"grid w-full items-start gap-6 overflow-auto p-4 pt-0\">\n <fieldset class=\"grid gap-6 rounded-lg border p-4\">\n <legend class=\"-ml-1 px-1 text-sm font-medium\">\n Settings\n </legend>\n <div class=\"grid gap-3\">\n <Label for=\"model\">Model</Label>\n <Select>\n <SelectTrigger\n id=\"model\"\n class=\"items-start [&_[data-description]]:hidden\"\n >\n <SelectValue placeholder=\"Select a model\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"genesis\">\n <div class=\"flex items-start gap-3 text-muted-foreground\">\n <Rabbit class=\"size-5\" />\n <div class=\"grid gap-0.5\">\n <p>\n Neural\n <span class=\"font-medium text-foreground\">\n Genesis\n </span>\n </p>\n <p class=\"text-xs\" data-description>\n Our fastest model for general use cases.\n </p>\n </div>\n </div>\n </SelectItem>\n <SelectItem value=\"explorer\">\n <div class=\"flex items-start gap-3 text-muted-foreground\">\n <Bird class=\"size-5\" />\n <div class=\"grid gap-0.5\">\n <p>\n Neural\n <span class=\"font-medium text-foreground\">\n Explorer\n </span>\n </p>\n <p class=\"text-xs\" data-description>\n Performance and speed for efficiency.\n </p>\n </div>\n </div>\n </SelectItem>\n <SelectItem value=\"quantum\">\n <div class=\"flex items-start gap-3 text-muted-foreground\">\n <Turtle class=\"size-5\" />\n <div class=\"grid gap-0.5\">\n <p>\n Neural\n <span class=\"font-medium text-foreground\">\n Quantum\n </span>\n </p>\n <p class=\"text-xs\" data-description>\n The most powerful model for complex\n computations.\n </p>\n </div>\n </div>\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"temperature\">Temperature</Label>\n <Input id=\"temperature\" type=\"number\" placeholder=\"0.4\" />\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"top-p\">Top P</Label>\n <Input id=\"top-p\" type=\"number\" placeholder=\"0.7\" />\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"top-k\">Top K</Label>\n <Input id=\"top-k\" type=\"number\" placeholder=\"0.0\" />\n </div>\n </fieldset>\n <fieldset class=\"grid gap-6 rounded-lg border p-4\">\n <legend class=\"-ml-1 px-1 text-sm font-medium\">\n Messages\n </legend>\n <div class=\"grid gap-3\">\n <Label for=\"role\">Role</Label>\n <Select default-value=\"system\">\n <SelectTrigger>\n <SelectValue placeholder=\"Select a role\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"system\">\n System\n </SelectItem>\n <SelectItem value=\"user\">\n User\n </SelectItem>\n <SelectItem value=\"assistant\">\n Assistant\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"content\">Content</Label>\n <Textarea id=\"content\" placeholder=\"You are a...\" />\n </div>\n </fieldset>\n </form>\n </DrawerContent>\n </Drawer>\n <Button\n variant=\"outline\"\n size=\"sm\"\n class=\"ml-auto gap-1.5 text-sm\"\n >\n <Share class=\"size-3.5\" />\n Share\n </Button>\n </header>\n <main class=\"grid flex-1 gap-4 overflow-auto p-4 md:grid-cols-2 lg:grid-cols-3\">\n <div class=\"relative hidden flex-col items-start gap-8 md:flex\">\n <form class=\"grid w-full items-start gap-6\">\n <fieldset class=\"grid gap-6 rounded-lg border p-4\">\n <legend class=\"-ml-1 px-1 text-sm font-medium\">\n Settings\n </legend>\n <div class=\"grid gap-3\">\n <Label for=\"model\">Model</Label>\n <Select>\n <SelectTrigger\n id=\"model\"\n class=\"items-start [&_[data-description]]:hidden\"\n >\n <SelectValue placeholder=\"Select a model\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"genesis\">\n <div class=\"flex items-start gap-3 text-muted-foreground\">\n <Rabbit class=\"size-5\" />\n <div class=\"grid gap-0.5\">\n <p>\n Neural\n <span class=\"font-medium text-foreground\">\n Genesis\n </span>\n </p>\n <p class=\"text-xs\" data-description>\n Our fastest model for general use cases.\n </p>\n </div>\n </div>\n </SelectItem>\n <SelectItem value=\"explorer\">\n <div class=\"flex items-start gap-3 text-muted-foreground\">\n <Bird class=\"size-5\" />\n <div class=\"grid gap-0.5\">\n <p>\n Neural\n <span class=\"font-medium text-foreground\">\n Explorer\n </span>\n </p>\n <p class=\"text-xs\" data-description>\n Performance and speed for efficiency.\n </p>\n </div>\n </div>\n </SelectItem>\n <SelectItem value=\"quantum\">\n <div class=\"flex items-start gap-3 text-muted-foreground\">\n <Turtle class=\"size-5\" />\n <div class=\"grid gap-0.5\">\n <p>\n Neural\n <span class=\"font-medium text-foreground\">\n Quantum\n </span>\n </p>\n <p class=\"text-xs\" data-description>\n The most powerful model for complex computations.\n </p>\n </div>\n </div>\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"temperature\">Temperature</Label>\n <Input id=\"temperature\" type=\"number\" placeholder=\"0.4\" />\n </div>\n <div class=\"grid grid-cols-2 gap-4\">\n <div class=\"grid gap-3\">\n <Label for=\"top-p\">Top P</Label>\n <Input id=\"top-p\" type=\"number\" placeholder=\"0.7\" />\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"top-k\">Top K</Label>\n <Input id=\"top-k\" type=\"number\" placeholder=\"0.0\" />\n </div>\n </div>\n </fieldset>\n <fieldset class=\"grid gap-6 rounded-lg border p-4\">\n <legend class=\"-ml-1 px-1 text-sm font-medium\">\n Messages\n </legend>\n <div class=\"grid gap-3\">\n <Label for=\"role\">Role</Label>\n <Select default-value=\"system\">\n <SelectTrigger>\n <SelectValue placeholder=\"Select a role\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"system\">\n System\n </SelectItem>\n <SelectItem value=\"user\">\n User\n </SelectItem>\n <SelectItem value=\"assistant\">\n Assistant\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"content\">Content</Label>\n <Textarea\n id=\"content\"\n placeholder=\"You are a...\"\n class=\"min-h-[9.5rem]\"\n />\n </div>\n </fieldset>\n </form>\n </div>\n <div class=\"relative flex h-full min-h-[50vh] flex-col rounded-xl bg-muted/50 p-4 lg:col-span-2\">\n <Badge variant=\"outline\" class=\"absolute right-3 top-3\">\n Output\n </Badge>\n <div class=\"flex-1\" />\n <form class=\"relative overflow-hidden rounded-lg border bg-background focus-within:ring-1 focus-within:ring-ring\">\n <Label for=\"message\" class=\"sr-only\">\n Message\n </Label>\n <Textarea\n id=\"message\"\n placeholder=\"Type your message here...\"\n class=\"min-h-12 resize-none border-0 p-3 shadow-none focus-visible:ring-0\"\n />\n <div class=\"flex items-center p-3 pt-0\">\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button variant=\"ghost\" size=\"icon\">\n <Paperclip class=\"size-4\" />\n <span class=\"sr-only\">Attach file</span>\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"top\">\n Attach File\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <Button variant=\"ghost\" size=\"icon\">\n <Mic class=\"size-4\" />\n <span class=\"sr-only\">Use Microphone</span>\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"top\">\n Use Microphone\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <Button type=\"submit\" size=\"sm\" class=\"ml-auto gap-1.5\">\n Send Message\n <CornerDownLeft class=\"size-3.5\" />\n </Button>\n </div>\n </form>\n </div>\n </main>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard04",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card",
|
|
"checkbox",
|
|
"dropdown-menu",
|
|
"input",
|
|
"sheet"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard04.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A settings page. The settings page has a sidebar navigation and a main content area. The main content area has a form to update the store name and a form to update the plugins directory. The sidebar navigation has links to general, security, integrations, support, organizations, and advanced settings.'\nexport const iframeHeight = '780px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/registry/default/ui/card'\nimport { Checkbox } from '@/registry/default/ui/checkbox'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/default/ui/dropdown-menu'\nimport { Input } from '@/registry/default/ui/input'\nimport { Sheet, SheetContent, SheetTrigger } from '@/registry/default/ui/sheet'\nimport { CircleUser, Menu, Package2, Search } from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"flex min-h-screen w-full flex-col\">\n <header class=\"sticky top-0 flex h-16 items-center gap-4 border-b bg-background px-4 md:px-6\">\n <nav class=\"hidden flex-col gap-6 text-lg font-medium md:flex md:flex-row md:items-center md:gap-5 md:text-sm lg:gap-6\">\n <a\n href=\"#\"\n class=\"flex items-center gap-2 text-lg font-semibold md:text-base\"\n >\n <Package2 class=\"h-6 w-6\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Orders\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Products\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n Customers\n </a>\n <a\n href=\"#\"\n class=\"text-foreground transition-colors hover:text-foreground\"\n >\n Settings\n </a>\n </nav>\n <Sheet>\n <SheetTrigger as-child>\n <Button\n variant=\"outline\"\n size=\"icon\"\n class=\"shrink-0 md:hidden\"\n >\n <Menu class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle navigation menu</span>\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\">\n <nav class=\"grid gap-6 text-lg font-medium\">\n <a\n href=\"#\"\n class=\"flex items-center gap-2 text-lg font-semibold\"\n >\n <Package2 class=\"h-6 w-6\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Orders\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Products\n </a>\n <a\n href=\"#\"\n class=\"text-muted-foreground hover:text-foreground\"\n >\n Customers\n </a>\n <a href=\"#\" class=\"hover:text-foreground\">\n Settings\n </a>\n </nav>\n </SheetContent>\n </Sheet>\n <div class=\"flex w-full items-center gap-4 md:ml-auto md:gap-2 lg:gap-4\">\n <form class=\"ml-auto flex-1 sm:flex-initial\">\n <div class=\"relative\">\n <Search class=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n type=\"search\"\n placeholder=\"Search products...\"\n class=\"pl-8 sm:w-[300px] md:w-[200px] lg:w-[300px]\"\n />\n </div>\n </form>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"secondary\" size=\"icon\" class=\"rounded-full\">\n <CircleUser class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle user menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Settings</DropdownMenuItem>\n <DropdownMenuItem>Support</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Logout</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </header>\n <main class=\"flex min-h-[calc(100vh_-_theme(spacing.16))] flex-1 flex-col gap-4 bg-muted/40 p-4 md:gap-8 md:p-10\">\n <div class=\"mx-auto grid w-full max-w-6xl gap-2\">\n <h1 class=\"text-3xl font-semibold\">\n Settings\n </h1>\n </div>\n <div class=\"mx-auto grid w-full max-w-6xl items-start gap-6 md:grid-cols-[180px_1fr] lg:grid-cols-[250px_1fr]\">\n <nav class=\"grid gap-4 text-sm text-muted-foreground\">\n <a href=\"#\" class=\"font-semibold text-primary\">\n General\n </a>\n <a href=\"#\">\n Security\n </a>\n <a href=\"#\">\n Integrations\n </a>\n <a href=\"#\">\n Support\n </a>\n <a href=\"#\">\n Organizations\n </a>\n <a href=\"#\">\n Advanced\n </a>\n </nav>\n <div class=\"grid gap-6\">\n <Card>\n <CardHeader>\n <CardTitle>Store Name</CardTitle>\n <CardDescription>\n Used to identify your store in the marketplace.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <form>\n <Input placeholder=\"Store Name\" />\n </form>\n </CardContent>\n <CardFooter class=\"border-t px-6 py-4\">\n <Button>Save</Button>\n </CardFooter>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Plugins Directory</CardTitle>\n <CardDescription>\n The directory within your project, in which your plugins are\n located.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <form class=\"flex flex-col gap-4\">\n <Input\n placeholder=\"Project Name\"\n default-value=\"/content/plugins\"\n />\n <div class=\"flex items-center space-x-2\">\n <Checkbox id=\"include\" default-checked />\n <label\n for=\"include\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Allow administrators to change the directory.\n </label>\n </div>\n </form>\n </CardContent>\n <CardFooter class=\"border-t px-6 py-4\">\n <Button>Save</Button>\n </CardFooter>\n </Card>\n </div>\n </div>\n </main>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard05",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge",
|
|
"breadcrumb",
|
|
"button",
|
|
"card",
|
|
"checkbox",
|
|
"dropdown-menu",
|
|
"input",
|
|
"pagination",
|
|
"progress",
|
|
"separator",
|
|
"sheet",
|
|
"table",
|
|
"tabs",
|
|
"tooltip"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard05.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'An orders dashboard with a sidebar navigation. The sidebar has icon navigation. The content area has a breadcrumb and search in the header. The main area has a list of recent orders with a filter and export button. The main area also has a detailed view of a single order with order details, shipping information, billing information, customer information, and payment information.'\nexport const iframeHeight = '1112px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Badge } from '@/registry/default/ui/badge'\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Button } from '@/registry/default/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/registry/default/ui/card'\nimport { Checkbox } from '@/registry/default/ui/checkbox'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/default/ui/dropdown-menu'\nimport { Input } from '@/registry/default/ui/input'\nimport {\n Pagination,\n PaginationList,\n PaginationNext,\n PaginationPrev,\n} from '@/registry/default/ui/pagination'\nimport { Progress } from '@/registry/default/ui/progress'\nimport { Separator } from '@/registry/default/ui/separator'\nimport { Sheet, SheetContent, SheetTrigger } from '@/registry/default/ui/sheet'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/default/ui/table'\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@/registry/default/ui/tabs'\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@/registry/default/ui/tooltip'\nimport {\n CircleUser,\n Copy,\n CreditCard,\n File,\n Home,\n LineChart,\n ListFilter,\n MoreVertical,\n Package,\n Package2,\n PanelLeft,\n Search,\n Settings,\n ShoppingCart,\n Truck,\n Users2,\n} from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"flex min-h-screen w-full flex-col bg-muted/40\">\n <aside class=\"fixed inset-y-0 left-0 z-10 hidden w-14 flex-col border-r bg-background sm:flex\">\n <nav class=\"flex flex-col items-center gap-4 px-2 sm:py-5\">\n <a\n href=\"#\"\n class=\"group flex h-9 w-9 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:h-8 md:w-8 md:text-base\"\n >\n <Package2 class=\"h-4 w-4 transition-all group-hover:scale-110\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Home class=\"h-5 w-5\" />\n <span class=\"sr-only\">Dashboard</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Dashboard\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg bg-accent text-accent-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n <span class=\"sr-only\">Orders</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Orders\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Package class=\"h-5 w-5\" />\n <span class=\"sr-only\">Products</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Products\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Users2 class=\"h-5 w-5\" />\n <span class=\"sr-only\">Customers</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Customers\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <LineChart class=\"h-5 w-5\" />\n <span class=\"sr-only\">Analytics</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Analytics\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </nav>\n <nav class=\"mt-auto flex flex-col items-center gap-4 px-2 sm:py-5\">\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Settings class=\"h-5 w-5\" />\n <span class=\"sr-only\">Settings</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Settings\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </nav>\n </aside>\n <div class=\"flex flex-col sm:gap-4 sm:py-4 sm:pl-14\">\n <header class=\"sticky top-0 z-30 flex h-14 items-center gap-4 border-b bg-background px-4 sm:static sm:h-auto sm:border-0 sm:bg-transparent sm:px-6\">\n <Sheet>\n <SheetTrigger as-child>\n <Button size=\"icon\" variant=\"outline\" class=\"sm:hidden\">\n <PanelLeft class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle Menu</span>\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\" class=\"sm:max-w-xs\">\n <nav class=\"grid gap-6 text-lg font-medium\">\n <a\n href=\"#\"\n class=\"group flex h-10 w-10 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:text-base\"\n >\n <Package2 class=\"h-5 w-5 transition-all group-hover:scale-110\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Home class=\"h-5 w-5\" />\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-foreground\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n Orders\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Package class=\"h-5 w-5\" />\n Products\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Users2 class=\"h-5 w-5\" />\n Customers\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <LineChart class=\"h-5 w-5\" />\n Settings\n </a>\n </nav>\n </SheetContent>\n </Sheet>\n <Breadcrumb class=\"hidden md:flex\">\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"#\">Dashboard</a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"#\">Orders</a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Recent Orders</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n <div class=\"relative ml-auto flex-1 md:grow-0\">\n <Search class=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n type=\"search\"\n placeholder=\"Search...\"\n class=\"w-full rounded-lg bg-background pl-8 md:w-[200px] lg:w-[336px]\"\n />\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"secondary\" size=\"icon\" class=\"rounded-full\">\n <CircleUser class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle user menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Settings</DropdownMenuItem>\n <DropdownMenuItem>Support</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Logout</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </header>\n <main class=\"grid flex-1 items-start gap-4 p-4 sm:px-6 sm:py-0 md:gap-8 lg:grid-cols-3 xl:grid-cols-3\">\n <div class=\"grid auto-rows-max items-start gap-4 md:gap-8 lg:col-span-2\">\n <div class=\"grid gap-4 sm:grid-cols-2 md:grid-cols-4 lg:grid-cols-2 xl:grid-cols-4\">\n <Card class=\"sm:col-span-2\">\n <CardHeader class=\"pb-3\">\n <CardTitle>Your Orders</CardTitle>\n <CardDescription class=\"max-w-lg text-balance leading-relaxed\">\n Introducing Our Dynamic Orders Dashboard for Seamless\n Management and Insightful Analysis.\n </CardDescription>\n </CardHeader>\n <CardFooter>\n <Button>Create New Order</Button>\n </CardFooter>\n </Card>\n <Card>\n <CardHeader class=\"pb-2\">\n <CardDescription>This Week</CardDescription>\n <CardTitle class=\"text-4xl\">\n $1329\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div class=\"text-xs text-muted-foreground\">\n +25% from last week\n </div>\n </CardContent>\n <CardFooter>\n <Progress :model-value=\"25\" aria-label=\"25% increase\" />\n </CardFooter>\n </Card>\n <Card>\n <CardHeader class=\"pb-2\">\n <CardDescription>This Month</CardDescription>\n <CardTitle class=\"text-3xl\">\n $5,329\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div class=\"text-xs text-muted-foreground\">\n +10% from last month\n </div>\n </CardContent>\n <CardFooter>\n <Progress :model-value=\"12\" aria-label=\"12% increase\" />\n </CardFooter>\n </Card>\n </div>\n <Tabs default-value=\"week\">\n <div class=\"flex items-center\">\n <TabsList>\n <TabsTrigger value=\"week\">\n Week\n </TabsTrigger>\n <TabsTrigger value=\"month\">\n Month\n </TabsTrigger>\n <TabsTrigger value=\"year\">\n Year\n </TabsTrigger>\n </TabsList>\n <div class=\"ml-auto flex items-center gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\" size=\"sm\" class=\"h-7 gap-1 rounded-md px-3\">\n <ListFilter class=\"h-3.5 w-3.5\" />\n <span class=\"sr-only sm:not-sr-only\">Filter</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Filter by</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <div class=\"items-top flex space-x-2\">\n <Checkbox id=\"terms1\" />\n <label\n for=\"terms2\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Fulfilled\n </label>\n </div>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <div class=\"items-top flex space-x-2\">\n <Checkbox id=\"terms1\" />\n <label\n for=\"terms2\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Declined\n </label>\n </div>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <div class=\"items-top flex space-x-2\">\n <Checkbox id=\"terms1\" />\n <label\n for=\"terms2\"\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n Refunded\n </label>\n </div>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n <Button variant=\"outline\" size=\"sm\" class=\"h-7 gap-1 rounded-md px-3\">\n <File class=\"h-3.5 w-3.5\" />\n <span class=\"sr-only sm:not-sr-only\">Export</span>\n </Button>\n </div>\n </div>\n <TabsContent value=\"week\">\n <Card>\n <CardHeader class=\"px-7\">\n <CardTitle>Orders</CardTitle>\n <CardDescription>\n Recent orders from your store.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Customer</TableHead>\n <TableHead class=\"hidden sm:table-cell\">\n Type\n </TableHead>\n <TableHead class=\"hidden sm:table-cell\">\n Status\n </TableHead>\n <TableHead class=\"hidden md:table-cell\">\n Date\n </TableHead>\n <TableHead class=\"text-right\">\n Amount\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <TableRow class=\"bg-accent\">\n <TableCell>\n <div class=\"font-medium\">\n Liam Johnson\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n liam@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Sale\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"secondary\">\n Fulfilled\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-23\n </TableCell>\n <TableCell class=\"text-right\">\n $250.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Olivia Smith\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n olivia@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Refund\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Declined\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-24\n </TableCell>\n <TableCell class=\"text-right\">\n $150.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Noah Williams\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n noah@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Subscription\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"secondary\">\n Fulfilled\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-25\n </TableCell>\n <TableCell class=\"text-right\">\n $350.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Emma Brown\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n emma@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Sale\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"secondary\">\n Fulfilled\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-26\n </TableCell>\n <TableCell class=\"text-right\">\n $450.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Liam Johnson\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n liam@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Sale\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"secondary\">\n Fulfilled\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-23\n </TableCell>\n <TableCell class=\"text-right\">\n $250.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Liam Johnson\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n liam@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Sale\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"secondary\">\n Fulfilled\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-23\n </TableCell>\n <TableCell class=\"text-right\">\n $250.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Olivia Smith\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n olivia@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Refund\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"outline\">\n Declined\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-24\n </TableCell>\n <TableCell class=\"text-right\">\n $150.00\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell>\n <div class=\"font-medium\">\n Emma Brown\n </div>\n <div class=\"hidden text-sm text-muted-foreground md:inline\">\n emma@example.com\n </div>\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n Sale\n </TableCell>\n <TableCell class=\"hidden sm:table-cell\">\n <Badge class=\"text-xs\" variant=\"secondary\">\n Fulfilled\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-06-26\n </TableCell>\n <TableCell class=\"text-right\">\n $450.00\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </div>\n <div>\n <Card class=\"overflow-hidden\">\n <CardHeader class=\"flex flex-row items-start bg-muted/50\">\n <div class=\"grid gap-0.5\">\n <CardTitle class=\"group flex items-center gap-2 text-lg\">\n Order ID: Oe31b70H\n <Button\n size=\"icon\"\n variant=\"outline\"\n class=\"h-6 w-6 opacity-0 transition-opacity group-hover:opacity-100\"\n >\n <Copy class=\"h-3 w-3\" />\n <span class=\"sr-only\">Copy Order ID</span>\n </Button>\n </CardTitle>\n <CardDescription>Date: November 23, 2023</CardDescription>\n </div>\n <div class=\"ml-auto flex items-center gap-1\">\n <Button size=\"sm\" variant=\"outline\" class=\"h-8 gap-1\">\n <Truck class=\"h-3.5 w-3.5\" />\n <span class=\"lg:sr-only xl:not-sr-only xl:whitespace-nowrap\">\n Track Order\n </span>\n </Button>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button size=\"icon\" variant=\"outline\" class=\"h-8 w-8\">\n <MoreVertical class=\"h-3.5 w-3.5\" />\n <span class=\"sr-only\">More</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Export</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Trash</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </CardHeader>\n <CardContent class=\"p-6 text-sm\">\n <div class=\"grid gap-3\">\n <div class=\"font-semibold\">\n Order Details\n </div>\n <ul class=\"grid gap-3\">\n <li class=\"flex items-center justify-between\">\n <span class=\"text-muted-foreground\">\n Glimmer Lamps x <span>2</span>\n </span>\n <span>$250.00</span>\n </li>\n <li class=\"flex items-center justify-between\">\n <span class=\"text-muted-foreground\">\n Aqua Filters x <span>1</span>\n </span>\n <span>$49.00</span>\n </li>\n </ul>\n <Separator class=\"my-2\" />\n <ul class=\"grid gap-3\">\n <li class=\"flex items-center justify-between\">\n <span class=\"text-muted-foreground\">Subtotal</span>\n <span>$299.00</span>\n </li>\n <li class=\"flex items-center justify-between\">\n <span class=\"text-muted-foreground\">Shipping</span>\n <span>$5.00</span>\n </li>\n <li class=\"flex items-center justify-between\">\n <span class=\"text-muted-foreground\">Tax</span>\n <span>$25.00</span>\n </li>\n <li class=\"flex items-center justify-between font-semibold\">\n <span class=\"text-muted-foreground\">Total</span>\n <span>$329.00</span>\n </li>\n </ul>\n </div>\n <Separator class=\"my-4\" />\n <div class=\"grid grid-cols-2 gap-4\">\n <div class=\"grid gap-3\">\n <div class=\"font-semibold\">\n Shipping Information\n </div>\n <address class=\"grid gap-0.5 not-italic text-muted-foreground\">\n <span>Liam Johnson</span>\n <span>1234 Main St.</span>\n <span>Anytown, CA 12345</span>\n </address>\n </div>\n <div class=\"grid auto-rows-max gap-3\">\n <div class=\"font-semibold\">\n Billing Information\n </div>\n <div class=\"text-muted-foreground\">\n Same as shipping address\n </div>\n </div>\n </div>\n <Separator class=\"my-4\" />\n <div class=\"grid gap-3\">\n <div class=\"font-semibold\">\n Customer Information\n </div>\n <dl class=\"grid gap-3\">\n <div class=\"flex items-center justify-between\">\n <dt class=\"text-muted-foreground\">\n Customer\n </dt>\n <dd>Liam Johnson</dd>\n </div>\n <div class=\"flex items-center justify-between\">\n <dt class=\"text-muted-foreground\">\n Email\n </dt>\n <dd>\n <a href=\"mailto:\">liam@acme.com</a>\n </dd>\n </div>\n <div class=\"flex items-center justify-between\">\n <dt class=\"text-muted-foreground\">\n Phone\n </dt>\n <dd>\n <a href=\"tel:\">+1 234 567 890</a>\n </dd>\n </div>\n </dl>\n </div>\n <Separator class=\"my-4\" />\n <div class=\"grid gap-3\">\n <div class=\"font-semibold\">\n Payment Information\n </div>\n <dl class=\"grid gap-3\">\n <div class=\"flex items-center justify-between\">\n <dt class=\"flex items-center gap-1 text-muted-foreground\">\n <CreditCard class=\"h-4 w-4\" />\n Visa\n </dt>\n <dd>**** **** **** 4532</dd>\n </div>\n </dl>\n </div>\n </CardContent>\n <CardFooter class=\"flex flex-row items-center border-t bg-muted/50 px-6 py-3\">\n <div class=\"text-xs text-muted-foreground\">\n Updated <time dateTime=\"2023-11-23\">November 23, 2023</time>\n </div>\n <Pagination class=\"ml-auto mr-0 w-auto\" :items-per-page=\"10\">\n <PaginationList class=\"gap-1\">\n <PaginationPrev variant=\"outline\" class=\"h-6 w-6\" />\n <PaginationNext variant=\"outline\" class=\"h-6 w-6\" />\n </PaginationList>\n </Pagination>\n </CardFooter>\n </Card>\n </div>\n </main>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard06",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge",
|
|
"breadcrumb",
|
|
"button",
|
|
"card",
|
|
"dropdown-menu",
|
|
"input",
|
|
"sheet",
|
|
"table",
|
|
"tabs",
|
|
"tooltip"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard06.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'An products dashboard with a sidebar navigation. The sidebar has icon navigation. The content area has a breadcrumb and search in the header. It displays a list of products in a table with actions.'\nexport const iframeHeight = '938px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Badge } from '@/registry/default/ui/badge'\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Button } from '@/registry/default/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/registry/default/ui/card'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/default/ui/dropdown-menu'\nimport { Input } from '@/registry/default/ui/input'\nimport { Sheet, SheetContent, SheetTrigger } from '@/registry/default/ui/sheet'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/default/ui/table'\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@/registry/default/ui/tabs'\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@/registry/default/ui/tooltip'\nimport {\n CircleUser,\n File,\n Home,\n LineChart,\n ListFilter,\n MoreHorizontal,\n Package,\n Package2,\n PanelLeft,\n PlusCircle,\n Search,\n Settings,\n ShoppingCart,\n Users2,\n} from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"flex min-h-screen w-full flex-col bg-muted/40\">\n <aside class=\"fixed inset-y-0 left-0 z-10 hidden w-14 flex-col border-r bg-background sm:flex\">\n <nav class=\"flex flex-col items-center gap-4 px-2 py-4\">\n <a\n href=\"#\"\n class=\"group flex h-9 w-9 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:h-8 md:w-8 md:text-base\"\n >\n <Package2 class=\"h-4 w-4 transition-all group-hover:scale-110\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Home class=\"h-5 w-5\" />\n <span class=\"sr-only\">Dashboard</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Dashboard\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n <span class=\"sr-only\">Orders</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Orders\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg bg-accent text-accent-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Package class=\"h-5 w-5\" />\n <span class=\"sr-only\">Products</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Products\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Users2 class=\"h-5 w-5\" />\n <span class=\"sr-only\">Customers</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Customers\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <LineChart class=\"h-5 w-5\" />\n <span class=\"sr-only\">Analytics</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Analytics\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </nav>\n <nav class=\"mt-auto flex flex-col items-center gap-4 px-2 py-4\">\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Settings class=\"h-5 w-5\" />\n <span class=\"sr-only\">Settings</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Settings\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </nav>\n </aside>\n <div class=\"flex flex-col sm:gap-4 sm:py-4 sm:pl-14\">\n <header class=\"sticky top-0 z-30 flex h-14 items-center gap-4 border-b bg-background px-4 sm:static sm:h-auto sm:border-0 sm:bg-transparent sm:px-6\">\n <Sheet>\n <SheetTrigger as-child>\n <Button size=\"icon\" variant=\"outline\" class=\"sm:hidden\">\n <PanelLeft class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle Menu</span>\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\" class=\"sm:max-w-xs\">\n <nav class=\"grid gap-6 text-lg font-medium\">\n <a\n href=\"#\"\n class=\"group flex h-10 w-10 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:text-base\"\n >\n <Package2 class=\"h-5 w-5 transition-all group-hover:scale-110\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Home class=\"h-5 w-5\" />\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n Orders\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-foreground\"\n >\n <Package class=\"h-5 w-5\" />\n Products\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Users2 class=\"h-5 w-5\" />\n Customers\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <LineChart class=\"h-5 w-5\" />\n Settings\n </a>\n </nav>\n </SheetContent>\n </Sheet>\n <Breadcrumb class=\"hidden md:flex\">\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"#\">Dashboard</a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"#\">Products</a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>All Products</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n <div class=\"relative ml-auto flex-1 md:grow-0\">\n <Search class=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n type=\"search\"\n placeholder=\"Search...\"\n class=\"w-full rounded-lg bg-background pl-8 md:w-[200px] lg:w-[320px]\"\n />\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"secondary\" size=\"icon\" class=\"rounded-full\">\n <CircleUser class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle user menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Settings</DropdownMenuItem>\n <DropdownMenuItem>Support</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Logout</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </header>\n <main class=\"grid flex-1 items-start gap-4 p-4 sm:px-6 sm:py-0 md:gap-8\">\n <Tabs default-value=\"all\">\n <div class=\"flex items-center\">\n <TabsList>\n <TabsTrigger value=\"all\">\n All\n </TabsTrigger>\n <TabsTrigger value=\"active\">\n Active\n </TabsTrigger>\n <TabsTrigger value=\"draft\">\n Draft\n </TabsTrigger>\n <TabsTrigger value=\"archived\" class=\"hidden sm:flex\">\n Archived\n </TabsTrigger>\n </TabsList>\n <div class=\"ml-auto flex items-center gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"outline\" size=\"sm\" class=\"h-7 gap-1\">\n <ListFilter class=\"h-3.5 w-3.5\" />\n <span class=\"sr-only sm:not-sr-only sm:whitespace-nowrap\">\n Filter\n </span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Filter by</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem checked>\n Active\n </DropdownMenuItem>\n <DropdownMenuItem>Draft</DropdownMenuItem>\n <DropdownMenuItem>\n Archived\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n <Button size=\"sm\" variant=\"outline\" class=\"h-7 gap-1\">\n <File class=\"h-3.5 w-3.5\" />\n <span class=\"sr-only sm:not-sr-only sm:whitespace-nowrap\">\n Export\n </span>\n </Button>\n <Button size=\"sm\" class=\"h-7 gap-1\">\n <PlusCircle class=\"h-3.5 w-3.5\" />\n <span class=\"sr-only sm:not-sr-only sm:whitespace-nowrap\">\n Add Product\n </span>\n </Button>\n </div>\n </div>\n <TabsContent value=\"all\">\n <Card>\n <CardHeader>\n <CardTitle>Products</CardTitle>\n <CardDescription>\n Manage your products and view their sales performance.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead class=\"hidden w-[100px] sm:table-cell\">\n <span class=\"sr-only\">img</span>\n </TableHead>\n <TableHead>Name</TableHead>\n <TableHead>Status</TableHead>\n <TableHead class=\"hidden md:table-cell\">\n Price\n </TableHead>\n <TableHead class=\"hidden md:table-cell\">\n Total Sales\n </TableHead>\n <TableHead class=\"hidden md:table-cell\">\n Created at\n </TableHead>\n <TableHead>\n <span class=\"sr-only\">Actions</span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <TableRow>\n <TableCell class=\"hidden sm:table-cell\">\n <img\n alt=\"Product image\"\n class=\"aspect-square rounded-md object-cover\"\n height=\"64\"\n src=\"/placeholder.svg\"\n width=\"64\"\n >\n </TableCell>\n <TableCell class=\"font-medium\">\n Laser Lemonade Machine\n </TableCell>\n <TableCell>\n <Badge variant=\"outline\">\n Draft\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n $499.99\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 25\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-07-12 10:42 AM\n </TableCell>\n <TableCell>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button\n aria-haspopup=\"true\"\n size=\"icon\"\n variant=\"ghost\"\n >\n <MoreHorizontal class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Delete</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"hidden sm:table-cell\">\n <img\n alt=\"Product image\"\n class=\"aspect-square rounded-md object-cover\"\n height=\"64\"\n src=\"/placeholder.svg\"\n width=\"64\"\n >\n </TableCell>\n <TableCell class=\"font-medium\">\n Hypernova Headphones\n </TableCell>\n <TableCell>\n <Badge variant=\"outline\">\n Active\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n $129.99\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 100\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-10-18 03:21 PM\n </TableCell>\n <TableCell>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button\n aria-haspopup=\"true\"\n size=\"icon\"\n variant=\"ghost\"\n >\n <MoreHorizontal class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Delete</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"hidden sm:table-cell\">\n <img\n alt=\"Product image\"\n class=\"aspect-square rounded-md object-cover\"\n height=\"64\"\n src=\"/placeholder.svg\"\n width=\"64\"\n >\n </TableCell>\n <TableCell class=\"font-medium\">\n AeroGlow Desk Lamp\n </TableCell>\n <TableCell>\n <Badge variant=\"outline\">\n Active\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n $39.99\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 50\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-11-29 08:15 AM\n </TableCell>\n <TableCell>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button\n aria-haspopup=\"true\"\n size=\"icon\"\n variant=\"ghost\"\n >\n <MoreHorizontal class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Delete</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"hidden sm:table-cell\">\n <img\n alt=\"Product image\"\n class=\"aspect-square rounded-md object-cover\"\n height=\"64\"\n src=\"/placeholder.svg\"\n width=\"64\"\n >\n </TableCell>\n <TableCell class=\"font-medium\">\n TechTonic Energy Drink\n </TableCell>\n <TableCell>\n <Badge variant=\"secondary\">\n Draft\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n $2.99\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 0\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2023-12-25 11:59 PM\n </TableCell>\n <TableCell>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button\n aria-haspopup=\"true\"\n size=\"icon\"\n variant=\"ghost\"\n >\n <MoreHorizontal class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Delete</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"hidden sm:table-cell\">\n <img\n alt=\"Product image\"\n class=\"aspect-square rounded-md object-cover\"\n height=\"64\"\n src=\"/placeholder.svg\"\n width=\"64\"\n >\n </TableCell>\n <TableCell class=\"font-medium\">\n Gamer Gear Pro Controller\n </TableCell>\n <TableCell>\n <Badge variant=\"outline\">\n Active\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n $59.99\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 75\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2024-01-01 12:00 AM\n </TableCell>\n <TableCell>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button\n aria-haspopup=\"true\"\n size=\"icon\"\n variant=\"ghost\"\n >\n <MoreHorizontal class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Delete</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"hidden sm:table-cell\">\n <img\n alt=\"Product image\"\n class=\"aspect-square rounded-md object-cover\"\n height=\"64\"\n src=\"/placeholder.svg\"\n width=\"64\"\n >\n </TableCell>\n <TableCell class=\"font-medium\">\n Luminous VR Headset\n </TableCell>\n <TableCell>\n <Badge variant=\"outline\">\n Active\n </Badge>\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n $199.99\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 30\n </TableCell>\n <TableCell class=\"hidden md:table-cell\">\n 2024-02-14 02:14 PM\n </TableCell>\n <TableCell>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button\n aria-haspopup=\"true\"\n size=\"icon\"\n variant=\"ghost\"\n >\n <MoreHorizontal class=\"h-4 w-4\" />\n <span class=\"sr-only\">Toggle menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuItem>Edit</DropdownMenuItem>\n <DropdownMenuItem>Delete</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </CardContent>\n <CardFooter>\n <div class=\"text-xs text-muted-foreground\">\n Showing <strong>1-10</strong> of <strong>32</strong>\n products\n </div>\n </CardFooter>\n </Card>\n </TabsContent>\n </Tabs>\n </main>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Dashboard07",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"badge",
|
|
"breadcrumb",
|
|
"button",
|
|
"card",
|
|
"dropdown-menu",
|
|
"input",
|
|
"label",
|
|
"select",
|
|
"sheet",
|
|
"table",
|
|
"textarea",
|
|
"toggle-group",
|
|
"tooltip"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Dashboard07.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A product edit page. The product edit page has a form to edit the product details, stock, product category, product status, and product images. The product edit page has a sidebar navigation and a main content area. The main content area has a form to edit the product details, stock, product category, product status, and product images. The sidebar navigation has links to product details, stock, product category, product status, and product images.'\nexport const iframeHeight = '1200px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport { Badge } from '@/registry/default/ui/badge'\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Button } from '@/registry/default/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/registry/default/ui/card'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/registry/default/ui/dropdown-menu'\nimport { Input } from '@/registry/default/ui/input'\nimport { Label } from '@/registry/default/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/registry/default/ui/select'\nimport { Sheet, SheetContent, SheetTrigger } from '@/registry/default/ui/sheet'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/registry/default/ui/table'\nimport { Textarea } from '@/registry/default/ui/textarea'\nimport { ToggleGroup, ToggleGroupItem } from '@/registry/default/ui/toggle-group'\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@/registry/default/ui/tooltip'\nimport {\n ChevronLeft,\n CircleUser,\n Home,\n LineChart,\n Package,\n Package2,\n PanelLeft,\n PlusCircle,\n Search,\n Settings,\n ShoppingCart,\n Upload,\n Users2,\n} from 'lucide-vue-next'\n</script>\n\n<template>\n <div class=\"flex min-h-screen w-full flex-col bg-muted/40\">\n <aside class=\"fixed inset-y-0 left-0 z-10 hidden w-14 flex-col border-r bg-background sm:flex\">\n <nav class=\"flex flex-col items-center gap-4 px-2 sm:py-5\">\n <a\n href=\"#\"\n class=\"group flex h-9 w-9 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:h-8 md:w-8 md:text-base\"\n >\n <Package2 class=\"h-4 w-4 transition-all group-hover:scale-110\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Home class=\"h-5 w-5\" />\n <span class=\"sr-only\">Dashboard</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Dashboard\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg bg-accent text-accent-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n <span class=\"sr-only\">Orders</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Orders\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Package class=\"h-5 w-5\" />\n <span class=\"sr-only\">Products</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Products\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Users2 class=\"h-5 w-5\" />\n <span class=\"sr-only\">Customers</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Customers\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <LineChart class=\"h-5 w-5\" />\n <span class=\"sr-only\">Analytics</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Analytics\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </nav>\n <nav class=\"mt-auto flex flex-col items-center gap-4 px-2 sm:py-5\">\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger as-child>\n <a\n href=\"#\"\n class=\"flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8\"\n >\n <Settings class=\"h-5 w-5\" />\n <span class=\"sr-only\">Settings</span>\n </a>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n Settings\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n </nav>\n </aside>\n <div class=\"flex flex-col sm:gap-4 sm:py-4 sm:pl-14\">\n <header class=\"sticky top-0 z-30 flex h-14 items-center gap-4 border-b bg-background px-4 sm:static sm:h-auto sm:border-0 sm:bg-transparent sm:px-6\">\n <Sheet>\n <SheetTrigger as-child>\n <Button size=\"icon\" variant=\"outline\" class=\"sm:hidden\">\n <PanelLeft class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle Menu</span>\n </Button>\n </SheetTrigger>\n <SheetContent side=\"left\" class=\"sm:max-w-xs\">\n <nav class=\"grid gap-6 text-lg font-medium\">\n <a\n href=\"#\"\n class=\"group flex h-10 w-10 shrink-0 items-center justify-center gap-2 rounded-full bg-primary text-lg font-semibold text-primary-foreground md:text-base\"\n >\n <Package2 class=\"h-5 w-5 transition-all group-hover:scale-110\" />\n <span class=\"sr-only\">Acme Inc</span>\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Home class=\"h-5 w-5\" />\n Dashboard\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <ShoppingCart class=\"h-5 w-5\" />\n Orders\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-foreground\"\n >\n <Package class=\"h-5 w-5\" />\n Products\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <Users2 class=\"h-5 w-5\" />\n Customers\n </a>\n <a\n href=\"#\"\n class=\"flex items-center gap-4 px-2.5 text-muted-foreground hover:text-foreground\"\n >\n <LineChart class=\"h-5 w-5\" />\n Settings\n </a>\n </nav>\n </SheetContent>\n </Sheet>\n <Breadcrumb class=\"hidden md:flex\">\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"#\">Dashboard</a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink as-child>\n <a href=\"#\">Products</a>\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Edit Product</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n <div class=\"relative ml-auto flex-1 md:grow-0\">\n <Search class=\"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground\" />\n <Input\n type=\"search\"\n placeholder=\"Search...\"\n class=\"w-full rounded-lg bg-background pl-8 md:w-[200px] lg:w-[336px]\"\n />\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <Button variant=\"secondary\" size=\"icon\" class=\"rounded-full\">\n <CircleUser class=\"h-5 w-5\" />\n <span class=\"sr-only\">Toggle user menu</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Settings</DropdownMenuItem>\n <DropdownMenuItem>Support</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>Logout</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </header>\n <main class=\"grid flex-1 items-start gap-4 p-4 sm:px-6 sm:py-0 md:gap-8\">\n <div class=\"mx-auto grid max-w-[59rem] flex-1 auto-rows-max gap-4\">\n <div class=\"flex items-center gap-4\">\n <Button variant=\"outline\" size=\"icon\" class=\"h-7 w-7\">\n <ChevronLeft class=\"h-4 w-4\" />\n <span class=\"sr-only\">Back</span>\n </Button>\n <h1 class=\"flex-1 shrink-0 whitespace-nowrap text-xl font-semibold tracking-tight sm:grow-0\">\n Pro Controller\n </h1>\n <Badge variant=\"outline\" class=\"ml-auto sm:ml-0\">\n In stock\n </Badge>\n <div class=\"hidden items-center gap-2 md:ml-auto md:flex\">\n <Button variant=\"outline\" size=\"sm\">\n Discard\n </Button>\n <Button size=\"sm\">\n Save Product\n </Button>\n </div>\n </div>\n <div class=\"grid gap-4 md:grid-cols-[1fr_250px] lg:grid-cols-3 lg:gap-8\">\n <div class=\"grid auto-rows-max items-start gap-4 lg:col-span-2 lg:gap-8\">\n <Card>\n <CardHeader>\n <CardTitle>Product Details</CardTitle>\n <CardDescription>\n Lipsum dolor sit amet, consectetur adipiscing elit\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div class=\"grid gap-6\">\n <div class=\"grid gap-3\">\n <Label for=\"name\">Name</Label>\n <Input\n id=\"name\"\n type=\"text\"\n class=\"w-full\"\n default-value=\"Gamer Gear Pro Controller\"\n />\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"description\">Description</Label>\n <Textarea\n id=\"description\"\n default-value=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam auctor, nisl nec ultricies ultricies, nunc nisl ultricies nunc, nec ultricies nunc nisl nec nunc.\"\n class=\"min-h-32\"\n />\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Stock</CardTitle>\n <CardDescription>\n Lipsum dolor sit amet, consectetur adipiscing elit\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead class=\"w-[100px]\">\n SKU\n </TableHead>\n <TableHead>Stock</TableHead>\n <TableHead>Price</TableHead>\n <TableHead class=\"w-[100px]\">\n Size\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <TableRow>\n <TableCell class=\"font-semibold\">\n GGPC-001\n </TableCell>\n <TableCell>\n <Label for=\"stock-1\" class=\"sr-only\">\n Stock\n </Label>\n <Input\n id=\"stock-1\"\n type=\"number\"\n default-value=\"100\"\n />\n </TableCell>\n <TableCell>\n <Label for=\"price-1\" class=\"sr-only\">\n Price\n </Label>\n <Input\n id=\"price-1\"\n type=\"number\"\n default-value=\"99.99\"\n />\n </TableCell>\n <TableCell>\n <ToggleGroup\n type=\"single\"\n default-value=\"s\"\n variant=\"outline\"\n >\n <ToggleGroupItem value=\"s\">\n S\n </ToggleGroupItem>\n <ToggleGroupItem value=\"m\">\n M\n </ToggleGroupItem>\n <ToggleGroupItem value=\"l\">\n L\n </ToggleGroupItem>\n </ToggleGroup>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"font-semibold\">\n GGPC-002\n </TableCell>\n <TableCell>\n <Label for=\"stock-2\" class=\"sr-only\">\n Stock\n </Label>\n <Input\n id=\"stock-2\"\n type=\"number\"\n default-value=\"143\"\n />\n </TableCell>\n <TableCell>\n <Label for=\"price-2\" class=\"sr-only\">\n Price\n </Label>\n <Input\n id=\"price-2\"\n type=\"number\"\n default-value=\"99.99\"\n />\n </TableCell>\n <TableCell>\n <ToggleGroup\n type=\"single\"\n default-value=\"m\"\n variant=\"outline\"\n >\n <ToggleGroupItem value=\"s\">\n S\n </ToggleGroupItem>\n <ToggleGroupItem value=\"m\">\n M\n </ToggleGroupItem>\n <ToggleGroupItem value=\"l\">\n L\n </ToggleGroupItem>\n </ToggleGroup>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell class=\"font-semibold\">\n GGPC-003\n </TableCell>\n <TableCell>\n <Label for=\"stock-3\" class=\"sr-only\">\n Stock\n </Label>\n <Input\n id=\"stock-3\"\n type=\"number\"\n default-value=\"32\"\n />\n </TableCell>\n <TableCell>\n <Label for=\"price-3\" class=\"sr-only\">\n Stock\n </Label>\n <Input\n id=\"price-3\"\n type=\"number\"\n default-value=\"99.99\"\n />\n </TableCell>\n <TableCell>\n <ToggleGroup\n type=\"single\"\n default-value=\"s\"\n variant=\"outline\"\n >\n <ToggleGroupItem value=\"s\">\n S\n </ToggleGroupItem>\n <ToggleGroupItem value=\"m\">\n M\n </ToggleGroupItem>\n <ToggleGroupItem value=\"l\">\n L\n </ToggleGroupItem>\n </ToggleGroup>\n </TableCell>\n </TableRow>\n </TableBody>\n </Table>\n </CardContent>\n <CardFooter class=\"justify-center border-t p-4\">\n <Button size=\"sm\" variant=\"ghost\" class=\"gap-1\">\n <PlusCircle class=\"h-3.5 w-3.5\" />\n Add Variant\n </Button>\n </CardFooter>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Product Category</CardTitle>\n </CardHeader>\n <CardContent>\n <div class=\"grid gap-6 sm:grid-cols-3\">\n <div class=\"grid gap-3\">\n <Label for=\"category\">Category</Label>\n <Select>\n <SelectTrigger\n id=\"category\"\n aria-label=\"Select category\"\n >\n <SelectValue placeholder=\"Select category\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"clothing\">\n Clothing\n </SelectItem>\n <SelectItem value=\"electronics\">\n Electronics\n </SelectItem>\n <SelectItem value=\"accessories\">\n Accessories\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div class=\"grid gap-3\">\n <Label for=\"subcategory\">\n Subcategory (optional)\n </Label>\n <Select>\n <SelectTrigger\n id=\"subcategory\"\n aria-label=\"Select subcategory\"\n >\n <SelectValue placeholder=\"Select subcategory\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"t-shirts\">\n T-Shirts\n </SelectItem>\n <SelectItem value=\"hoodies\">\n Hoodies\n </SelectItem>\n <SelectItem value=\"sweatshirts\">\n Sweatshirts\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n <div class=\"grid auto-rows-max items-start gap-4 lg:gap-8\">\n <Card>\n <CardHeader>\n <CardTitle>Product Status</CardTitle>\n </CardHeader>\n <CardContent>\n <div class=\"grid gap-6\">\n <div class=\"grid gap-3\">\n <Label for=\"status\">Status</Label>\n <Select>\n <SelectTrigger id=\"status\" aria-label=\"Select status\">\n <SelectValue placeholder=\"Select status\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"draft\">\n Draft\n </SelectItem>\n <SelectItem value=\"published\">\n Active\n </SelectItem>\n <SelectItem value=\"archived\">\n Archived\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card class=\"overflow-hidden\">\n <CardHeader>\n <CardTitle>Product imgs</CardTitle>\n <CardDescription>\n Lipsum dolor sit amet, consectetur adipiscing elit\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div class=\"grid gap-2\">\n <img\n alt=\"Product image\"\n class=\"aspect-square w-full rounded-md object-cover\"\n height=\"300\"\n src=\"/placeholder.svg\"\n width=\"300\"\n >\n <div class=\"grid grid-cols-3 gap-2\">\n <button>\n <img\n alt=\"Product image\"\n class=\"aspect-square w-full rounded-md object-cover\"\n height=\"84\"\n src=\"/placeholder.svg\"\n width=\"84\"\n >\n </button>\n <button>\n <img\n alt=\"Product image\"\n class=\"aspect-square w-full rounded-md object-cover\"\n height=\"84\"\n src=\"/placeholder.svg\"\n width=\"84\"\n >\n </button>\n <button class=\"flex aspect-square w-full items-center justify-center rounded-md border border-dashed\">\n <Upload class=\"h-4 w-4 text-muted-foreground\" />\n <span class=\"sr-only\">Upload</span>\n </button>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Archive Product</CardTitle>\n <CardDescription>\n Lipsum dolor sit amet, consectetur adipiscing elit.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div />\n <Button size=\"sm\" variant=\"secondary\">\n Archive Product\n </Button>\n </CardContent>\n </Card>\n </div>\n </div>\n <div class=\"flex items-center justify-center gap-2 md:hidden\">\n <Button variant=\"outline\" size=\"sm\">\n Discard\n </Button>\n <Button size=\"sm\">\n Save Product\n </Button>\n </div>\n </div>\n </main>\n </div>\n </div>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebar",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarInset,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n\nimport { Calendar, Home, Inbox, Search, Settings } from 'lucide-vue-next'\n\n// Menu items.\nconst items = [\n {\n title: 'Home',\n url: '#',\n icon: Home,\n },\n {\n title: 'Inbox',\n url: '#',\n icon: Inbox,\n },\n {\n title: 'Calendar',\n url: '#',\n icon: Calendar,\n },\n {\n title: 'Search',\n url: '#',\n icon: Search,\n },\n {\n title: 'Settings',\n url: '#',\n icon: Settings,\n },\n]\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Application</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n <SidebarInset>\n <header class=\"flex items-center justify-between px-4 h-12\">\n <SidebarTrigger />\n </header>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarControlled",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarControlled.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarInset,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/default/ui/sidebar'\nimport {\n Frame,\n LifeBuoy,\n Map,\n PanelLeftClose,\n PanelLeftOpen,\n PieChart,\n Send,\n} from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst projects = [\n {\n name: 'Design Engineering',\n url: '#',\n icon: Frame,\n },\n {\n name: 'Sales & Marketing',\n url: '#',\n icon: PieChart,\n },\n {\n name: 'Travel',\n url: '#',\n icon: Map,\n },\n {\n name: 'Support',\n url: '#',\n icon: LifeBuoy,\n },\n {\n name: 'Feedback',\n url: '#',\n icon: Send,\n },\n]\n\nconst open = ref(true)\n</script>\n\n<template>\n <SidebarProvider v-model:open=\"open\">\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"project in projects\" :key=\"project.name\">\n <SidebarMenuButton as-child>\n <a :href=\"project.url\">\n <component :is=\"project.icon\" />\n <span>{{ project.name }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n <SidebarInset>\n <header className=\"flex items-center h-12 px-4 justify-between\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n @click=\"open = !open\"\n >\n <PanelLeftClose v-if=\"open\" />\n <PanelLeftOpen v-else />\n <span>{{ open ? 'Close' : 'Open' }} Sidebar</span>\n </Button>\n </header>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarFooter",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"dropdown-menu",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarFooter.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarInset,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\nimport { ChevronUp } from 'lucide-vue-next'\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarHeader />\n <SidebarContent />\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\">\n Username\n <ChevronUp class=\"ml-auto\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n side=\"top\"\n class=\"w-[--reka-popper-anchor-width]\"\n >\n <DropdownMenuItem>\n <span>Account</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <span>Billing</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <span>Sign out</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n </Sidebar>\n <SidebarInset>\n <header class=\"flex items-center justify-between px-4 h-12\">\n <SidebarTrigger />\n </header>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarGroup",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarGroup.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/default/ui/sidebar'\n\nimport { LifeBuoy, Send } from 'lucide-vue-next'\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Help</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <LifeBuoy />\n Support\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <Send />\n Feedback\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarGroupAction",
|
|
"type": "registry:block",
|
|
"dependencies": [
|
|
"vue-sonner"
|
|
],
|
|
"registryDependencies": [
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarGroupAction.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/default/ui/sidebar'\nimport {\n Frame,\n Map,\n PieChart,\n Plus,\n} from 'lucide-vue-next'\n\nimport { toast, Toaster } from 'vue-sonner'\n</script>\n\n<template>\n <SidebarProvider>\n <Toaster\n position=\"bottom-left\"\n :toast-options=\"{\n class: 'ml-[160px]',\n }\"\n />\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarGroupAction\n title=\"Add Project\"\n @click=\"() => toast('You clicked the group action!')\"\n >\n <Plus /> <span class=\"sr-only\">Add Project</span>\n </SidebarGroupAction>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton as-child>\n <a href=\"#\">\n <Frame />\n <span>Design Engineering</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton as-child>\n <a href=\"#\">\n <PieChart />\n <span>Sales & Marketing</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton as-child>\n <a href=\"#\">\n <Map />\n <span>Travel</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarGroupCollapsible",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"collapsible",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarGroupCollapsible.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/default/ui/collapsible'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/default/ui/sidebar'\nimport { ChevronDown, LifeBuoy, Send } from 'lucide-vue-next'\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <Collapsible :default-open=\"true\" class=\"group/collapsible\">\n <SidebarGroup>\n <SidebarGroupLabel\n as-child\n class=\"text-sm hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\"\n >\n <CollapsibleTrigger>\n Help\n <ChevronDown class=\"ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180\" />\n </CollapsibleTrigger>\n </SidebarGroupLabel>\n <CollapsibleContent>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <LifeBuoy />\n Support\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <Send />\n Feedback\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </CollapsibleContent>\n </SidebarGroup>\n </Collapsible>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarHeader",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"dropdown-menu",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarHeader.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\n\nimport {\n Sidebar,\n SidebarHeader,\n SidebarInset,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\nimport { ChevronDown } from 'lucide-vue-next'\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\">\n Select Workspace\n <ChevronDown class=\"ml-auto\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent class=\"w-[--reka-popper-anchor-width]\">\n <DropdownMenuItem>\n <span>Acme Inc</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <span>Acme Corp.</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarHeader>\n </Sidebar>\n <SidebarInset>\n <header class=\"flex items-center justify-between px-4 h-12\">\n <SidebarTrigger />\n </header>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarMenu",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarMenu.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/default/ui/sidebar'\n\nimport { Frame, LifeBuoy, Map, PieChart, Send } from 'lucide-vue-next'\n\nconst projects = [\n {\n name: 'Design Engineering',\n url: '#',\n icon: Frame,\n },\n {\n name: 'Sales & Marketing',\n url: '#',\n icon: PieChart,\n },\n {\n name: 'Travel',\n url: '#',\n icon: Map,\n },\n {\n name: 'Support',\n url: '#',\n icon: LifeBuoy,\n },\n {\n name: 'Feedback',\n url: '#',\n icon: Send,\n },\n]\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"project in projects\" :key=\"project.name\">\n <SidebarMenuButton as-child>\n <a :href=\"project.url\">\n <component :is=\"project.icon\" />\n <span>{{ project.name }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarMenuAction",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"dropdown-menu",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarMenuAction.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/default/ui/sidebar'\nimport {\n Frame,\n LifeBuoy,\n Map,\n MoreHorizontal,\n PieChart,\n Send,\n} from 'lucide-vue-next'\n\nconst projects = [\n {\n name: 'Design Engineering',\n url: '#',\n icon: Frame,\n },\n {\n name: 'Sales & Marketing',\n url: '#',\n icon: PieChart,\n },\n {\n name: 'Travel',\n url: '#',\n icon: Map,\n },\n {\n name: 'Support',\n url: '#',\n icon: LifeBuoy,\n },\n {\n name: 'Feedback',\n url: '#',\n icon: Send,\n },\n]\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"project in projects\" :key=\"project.name\">\n <SidebarMenuButton\n as-child\n class=\"group-has-[[data-state=open]]/menu-item:bg-sidebar-accent\"\n >\n <a :href=\"project.url\">\n <component :is=\"project.icon\" />\n <span>{{ project.name }}</span>\n </a>\n </SidebarMenuButton>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuAction>\n <MoreHorizontal />\n <span class=\"sr-only\">More</span>\n </SidebarMenuAction>\n </DropdownMenuTrigger>\n <DropdownMenuContent side=\"right\" align=\"start\">\n <DropdownMenuItem>\n <span>Edit Project</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <span>Delete Project</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarMenuBadge",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarMenuBadge.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/default/ui/sidebar'\n\nimport { Frame, LifeBuoy, Map, PieChart, Send } from 'lucide-vue-next'\n\nconst projects = [\n {\n name: 'Design Engineering',\n url: '#',\n icon: Frame,\n badge: '24',\n },\n {\n name: 'Sales & Marketing',\n url: '#',\n icon: PieChart,\n badge: '12',\n },\n {\n name: 'Travel',\n url: '#',\n icon: Map,\n badge: '3',\n },\n {\n name: 'Support',\n url: '#',\n icon: LifeBuoy,\n badge: '21',\n },\n {\n name: 'Feedback',\n url: '#',\n icon: Send,\n badge: '8',\n },\n]\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"project in projects\" :key=\"project.name\">\n <SidebarMenuButton\n as-child\n class=\"group-has-[[data-state=open]]/menu-item:bg-sidebar-accent\"\n >\n <a :href=\"project.url\">\n <component :is=\"project.icon\" />\n <span>{{ project.name }}</span>\n </a>\n </SidebarMenuButton>\n <SidebarMenuBadge>{{ project.badge }}</SidebarMenuBadge>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarMenuCollapsible",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"collapsible",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarMenuCollapsible.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/default/ui/collapsible'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n} from '@/registry/default/ui/sidebar'\nimport { ChevronRight } from 'lucide-vue-next'\n\nconst items = [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n]\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupContent>\n <SidebarMenu>\n <Collapsible\n v-for=\"(item, index) in items\"\n :key=\"index\"\n class=\"group/collapsible\"\n :default-open=\"index === 0\"\n >\n <SidebarMenuItem>\n <CollapsibleTrigger as-child>\n <SidebarMenuButton>\n <span>{{ item.title }}</span>\n <ChevronRight class=\"transition-transform ml-auto group-data-[state=open]/collapsible:rotate-90\" />\n </SidebarMenuButton>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"(subItem, subIndex) in item.items\" :key=\"subIndex\">\n <SidebarMenuSubButton as-child>\n <a :href=\"subItem.url\">\n <span>{{ subItem.title }}</span>\n </a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "DemoSidebarMenuSub",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/DemoSidebarMenuSub.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n} from '@/registry/default/ui/sidebar'\n\nconst items = [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n]\n</script>\n\n<template>\n <SidebarProvider>\n <Sidebar>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"(item, index) in items\" :key=\"index\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\">\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"(subItem, subIndex) in item.items\" :key=\"subIndex\">\n <SidebarMenuSubButton as-child>\n <a :href=\"subItem.url\">\n <span>{{ subItem.title }}</span>\n </a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:block",
|
|
"target": "pages/dashboard/index.vue"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Login01",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"button",
|
|
"card",
|
|
"input",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Login01/page.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 = '870px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport LoginForm from '@/registry/default/block/Login01/components/LoginForm.vue'\n</script>\n\n<template>\n <div className=\"flex h-screen w-full items-center justify-center px-4\">\n <LoginForm />\n </div>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Login01/components/LoginForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} 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:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar01",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"label",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar01/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description\n = 'A simple sidebar with navigation grouped by section.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/default/block/Sidebar01/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Separator } from '@/registry/default/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 border-b px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar01/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport SearchForm from '@/registry/default/block/Sidebar01/components/SearchForm.vue'\nimport VersionSwitcher from '@/registry/default/block/Sidebar01/components/VersionSwitcher.vue'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/default/ui/sidebar'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n versions: ['1.0.1', '1.1.0-alpha', '2.0.0-beta1'],\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <VersionSwitcher\n :versions=\"data.versions\"\n :default-version=\"data.versions[0]\"\n />\n <SearchForm />\n </SidebarHeader>\n <SidebarContent>\n <SidebarGroup v-for=\"item in data.navMain\" :key=\"item.title\">\n <SidebarGroupLabel>{{ item.title }}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"childItem in item.items\" :key=\"childItem.title\">\n <SidebarMenuButton as-child :is-active=\"childItem.isActive\">\n <a :href=\"childItem.url\">{{ childItem.title }}</a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar01/components/SearchForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/default/ui/label'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarInput,\n} from '@/registry/default/ui/sidebar'\nimport { Search } from 'lucide-vue-next'\n</script>\n\n<template>\n <form>\n <SidebarGroup class=\"py-0\">\n <SidebarGroupContent class=\"relative\">\n <Label for=\"search\" class=\"sr-only\">\n Search\n </Label>\n <SidebarInput\n id=\"search\"\n placeholder=\"Search the docs...\"\n class=\"pl-8\"\n />\n <Search class=\"pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 select-none opacity-50\" />\n </SidebarGroupContent>\n </SidebarGroup>\n </form>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar01/components/VersionSwitcher.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\n\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/default/ui/sidebar'\nimport { Check, ChevronsUpDown, GalleryVerticalEnd } from 'lucide-vue-next'\n\nimport { ref } from 'vue'\n\nconst props = defineProps<{\n versions: string[]\n defaultVersion: string\n}>()\n\nconst selectedVersion = ref(props.defaultVersion)\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <GalleryVerticalEnd class=\"size-4\" />\n </div>\n <div class=\"flex flex-col gap-0.5 leading-none\">\n <span class=\"font-semibold\">Documentation</span>\n <span class=\"\">v{{ selectedVersion }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width]\"\n align=\"start\"\n >\n <DropdownMenuItem\n v-for=\"version in versions\"\n :key=\"version\"\n @select=\"selectedVersion = version\"\n >\n v{{ version }}\n <Check v-if=\"version === selectedVersion\" class=\"ml-auto\" />\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar02",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible",
|
|
"label",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar02/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A sidebar with collapsible sections.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/default/block/Sidebar02/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Separator } from '@/registry/default/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex sticky top-0 bg-background h-16 shrink-0 items-center gap-2 border-b px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div\n v-for=\"i in 24\"\n :key=\"i\"\n class=\"aspect-video h-12 w-full rounded-lg bg-muted/50\"\n />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar02/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport SearchForm from '@/registry/default/block/Sidebar02/components/SearchForm.vue'\nimport VersionSwitcher from '@/registry/default/block/Sidebar02/components/VersionSwitcher.vue'\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/default/ui/collapsible'\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/default/ui/sidebar'\nimport { ChevronRight } from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n versions: ['1.0.1', '1.1.0-alpha', '2.0.0-beta1'],\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n {\n title: 'Community',\n url: '#',\n items: [\n {\n title: 'Contribution Guide',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <VersionSwitcher\n :versions=\"data.versions\"\n :default-version=\"data.versions[0]\"\n />\n <SearchForm />\n </SidebarHeader>\n <SidebarContent class=\"gap-0\">\n <Collapsible\n v-for=\"item in data.navMain\"\n :key=\"item.title\"\n :title=\"item.title\"\n default-open\n class=\"group/collapsible\"\n >\n <SidebarGroup>\n <SidebarGroupLabel\n as-child\n class=\"group/label text-sm text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\"\n >\n <CollapsibleTrigger>\n {{ item.title }}\n <ChevronRight class=\"ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90\" />\n </CollapsibleTrigger>\n </SidebarGroupLabel>\n <CollapsibleContent>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"childItem in item.items\" :key=\"childItem.title\">\n <SidebarMenuButton as-child :is-active=\"childItem.isActive\">\n <a :href=\"item.url\">{{ childItem.title }}</a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </CollapsibleContent>\n </SidebarGroup>\n </Collapsible>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar02/components/SearchForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/default/ui/label'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarInput,\n} from '@/registry/default/ui/sidebar'\nimport { Search } from 'lucide-vue-next'\n</script>\n\n<template>\n <form>\n <SidebarGroup class=\"py-0\">\n <SidebarGroupContent class=\"relative\">\n <Label for=\"search\" class=\"sr-only\">\n Search\n </Label>\n <SidebarInput\n id=\"search\"\n placeholder=\"Search the docs...\"\n class=\"pl-8\"\n />\n <Search class=\"pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 select-none opacity-50\" />\n </SidebarGroupContent>\n </SidebarGroup>\n </form>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar02/components/VersionSwitcher.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\n\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/default/ui/sidebar'\nimport { Check, ChevronsUpDown, GalleryVerticalEnd } from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst props = defineProps<{\n versions: string[]\n defaultVersion: string\n}>()\n\nconst selectedVersion = ref(props.defaultVersion)\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <GalleryVerticalEnd class=\"size-4\" />\n </div>\n <div class=\"flex flex-col gap-0.5 leading-none\">\n <span class=\"font-semibold\">Documentation</span>\n <span class=\"\">v{{ selectedVersion }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width]\"\n align=\"start\"\n >\n <DropdownMenuItem\n v-for=\"version in versions\"\n :key=\"version\"\n @select=\"selectedVersion = version\"\n >\n v{{ version }}\n <Check v-if=\"selectedVersion === version\" class=\"ml-auto\" />\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar03",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar03/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A sidebar with submenus.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/default/block/Sidebar03/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Separator } from '@/registry/default/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 border-b\">\n <div class=\"flex items-center gap-2 px-3\">\n <SidebarTrigger />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar03/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/default/ui/sidebar'\n\nimport { GalleryVerticalEnd } from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n {\n title: 'Community',\n url: '#',\n items: [\n {\n title: 'Contribution Guide',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton size=\"lg\" as-child>\n <a href=\"#\">\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <GalleryVerticalEnd class=\"size-4\" />\n </div>\n <div class=\"flex flex-col gap-0.5 leading-none\">\n <span class=\"font-semibold\">Documentation</span>\n <span class=\"\">v1.0.0</span>\n </div>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarHeader>\n <SidebarContent>\n <SidebarGroup>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in data.navMain\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\" class=\"font-medium\">\n {{ item.title }}\n </a>\n </SidebarMenuButton>\n <SidebarMenuSub v-if=\"item.items.length\">\n <SidebarMenuSubItem v-for=\"childItem in item.items\" :key=\"childItem.title\">\n <SidebarMenuSubButton as-child :is-active=\"childItem.isActive\">\n <a :href=\"childItem.url\">{{ childItem.title }}</a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar04",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar04/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A floating sidebar with submenus.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/default/block/Sidebar04/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Separator } from '@/registry/default/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider :style=\"{ '--sidebar-width': '19rem' }\">\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4 pt-0\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar04/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n type SidebarProps,\n} from '@/registry/default/ui/sidebar'\n\nimport { GalleryVerticalEnd } from 'lucide-vue-next'\n\nconst props = withDefaults(defineProps<SidebarProps>(), {\n variant: 'floating',\n})\n\n// This is sample data.\nconst data = {\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n {\n title: 'Community',\n url: '#',\n items: [\n {\n title: 'Contribution Guide',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton size=\"lg\" as-child>\n <a href=\"#\">\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <GalleryVerticalEnd class=\"size-4\" />\n </div>\n <div class=\"flex flex-col gap-0.5 leading-none\">\n <span class=\"font-semibold\">Documentation</span>\n <span class=\"\">v1.0.0</span>\n </div>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarHeader>\n <SidebarContent>\n <SidebarGroup>\n <SidebarMenu class=\"gap-2\">\n <SidebarMenuItem v-for=\"item in data.navMain\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\" class=\"font-medium\">\n {{ item.title }}\n </a>\n </SidebarMenuButton>\n <SidebarMenuSub v-if=\"item.items.length\">\n <SidebarMenuSubItem v-for=\"childItem in item.items\" :key=\"childItem.title\">\n <SidebarMenuSubButton as-child :is-active=\"childItem.isActive\">\n <a :href=\"childItem.url\">{{ childItem.title }}</a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar05",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible",
|
|
"label"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar05/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A sidebar with collapsible submenus.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/default/block/Sidebar01/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Separator } from '@/registry/default/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 border-b px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar05/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport SearchForm from '@/registry/default/block/Sidebar05/components/SearchForm.vue'\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/default/ui/collapsible'\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/default/ui/sidebar'\nimport { GalleryVerticalEnd, Minus, Plus } from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n {\n title: 'Community',\n url: '#',\n items: [\n {\n title: 'Contribution Guide',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton size=\"lg\" as-child>\n <a href=\"#\">\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <GalleryVerticalEnd class=\"size-4\" />\n </div>\n <div class=\"flex flex-col gap-0.5 leading-none\">\n <span class=\"font-semibold\">Documentation</span>\n <span class=\"\">v1.0.0</span>\n </div>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n <SearchForm />\n </SidebarHeader>\n <SidebarContent>\n <SidebarGroup>\n <SidebarMenu>\n <Collapsible\n v-for=\"(item, index) in data.navMain\"\n :key=\"item.title\"\n :default-open=\"index === 1\"\n class=\"group/collapsible\"\n >\n <SidebarMenuItem>\n <CollapsibleTrigger as-child>\n <SidebarMenuButton>\n {{ item.title }}\n <Plus class=\"ml-auto group-data-[state=open]/collapsible:hidden\" />\n <Minus class=\"ml-auto group-data-[state=closed]/collapsible:hidden\" />\n </SidebarMenuButton>\n </CollapsibleTrigger>\n <CollapsibleContent v-if=\"item.items.length\">\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"childItem in item.items\" :key=\"childItem.title\">\n <SidebarMenuSubButton\n as-child\n :is-active=\"childItem.isActive\"\n >\n <a :href=\"childItem.url\">{{ childItem.title }}</a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n </SidebarMenu>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar05/components/SearchForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Label } from '@/registry/default/ui/label'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarInput,\n} from '@/registry/default/ui/sidebar'\nimport { Search } from 'lucide-vue-next'\n</script>\n\n<template>\n <form>\n <SidebarGroup class=\"py-0\">\n <SidebarGroupContent class=\"relative\">\n <Label for=\"search\" class=\"sr-only\">\n Search\n </Label>\n <SidebarInput\n id=\"search\"\n placeholder=\"Search the docs...\"\n class=\"pl-8\"\n />\n <Search class=\"pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 select-none opacity-50\" />\n </SidebarGroupContent>\n </SidebarGroup>\n </form>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar06",
|
|
"type": "registry:block",
|
|
"dependencies": [
|
|
"@vueuse/core"
|
|
],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"dropdown-menu",
|
|
"button",
|
|
"card"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar06/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A sidebar with submenus as dropdowns.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/default/block/Sidebar06/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Separator } from '@/registry/default/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 border-b px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar06/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport NavMain from '@/registry/default/block/Sidebar06/components/NavMain.vue'\nimport SidebarOptInForm from '@/registry/default/block/Sidebar06/components/SidebarOptInForm.vue'\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/default/ui/sidebar'\nimport { GalleryVerticalEnd } from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton size=\"lg\" as-child>\n <a href=\"#\">\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <GalleryVerticalEnd class=\"size-4\" />\n </div>\n <div class=\"flex flex-col gap-0.5 leading-none\">\n <span class=\"font-semibold\">Documentation</span>\n <span class=\"\">v1.0.0</span>\n </div>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarHeader>\n <SidebarContent>\n <NavMain :items=\"data.navMain\" />\n </SidebarContent>\n <SidebarFooter>\n <div class=\"p-1\">\n <SidebarOptInForm />\n </div>\n </SidebarFooter>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar06/components/NavMain.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\n\nimport {\n SidebarGroup,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/default/ui/sidebar'\nimport { useMediaQuery } from '@vueuse/core'\nimport { type LucideIcon, MoreHorizontal } from 'lucide-vue-next'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon?: LucideIcon\n isActive?: boolean\n items?: {\n title: string\n url: string\n }[]\n }[]\n}>()\n\nconst isMobile = useMediaQuery('(max-width: 768px)')\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarMenu>\n <DropdownMenu v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuItem>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\">\n {{ item.title }} <MoreHorizontal class=\"ml-auto\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n v-if=\"item.items?.length\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n :align=\"isMobile ? 'end' : 'start'\"\n class=\"min-w-56 rounded-lg\"\n >\n <DropdownMenuItem v-for=\"childItem in item.items\" :key=\"childItem.title\" as-child>\n <a :href=\"childItem.url\">{{ childItem.title }}</a>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </SidebarMenuItem>\n </DropdownMenu>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar06/components/SidebarOptInForm.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from '@/registry/default/ui/card'\nimport { SidebarInput } from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <Card class=\"shadow-none\">\n <form>\n <CardHeader class=\"p-4 pb-0\">\n <CardTitle class=\"text-sm\">\n Subscribe to our newsletter\n </CardTitle>\n <CardDescription>\n Opt-in to receive updates and news about the sidebar.\n </CardDescription>\n </CardHeader>\n <CardContent class=\"grid gap-2.5 p-4\">\n <SidebarInput type=\"email\" placeholder=\"Email\" />\n <Button\n class=\"w-full bg-sidebar-primary text-sidebar-primary-foreground shadow-none\"\n size=\"sm\"\n >\n Subscribe\n </Button>\n </CardContent>\n </form>\n </Card>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar07",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible",
|
|
"dropdown-menu",
|
|
"avatar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar07/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description\n = 'A sidebar that collapses to icons.'\nexport const iframeHeight = '800px'\nexport const containerClass = 'w-full h-full'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/default/block/Sidebar07/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Separator } from '@/registry/default/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12\">\n <div class=\"flex items-center gap-2 px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4 pt-0\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar07/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { SidebarProps } from '@/registry/default/ui/sidebar'\n\nimport NavMain from '@/registry/default/block/Sidebar07/components/NavMain.vue'\nimport NavProjects from '@/registry/default/block/Sidebar07/components/NavProjects.vue'\nimport NavUser from '@/registry/default/block/Sidebar07/components/NavUser.vue'\nimport TeamSwitcher from '@/registry/default/block/Sidebar07/components/TeamSwitcher.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarRail,\n} from '@/registry/default/ui/sidebar'\n\nimport {\n AudioWaveform,\n BookOpen,\n Bot,\n Command,\n Frame,\n GalleryVerticalEnd,\n Map,\n PieChart,\n Settings2,\n SquareTerminal,\n} from 'lucide-vue-next'\n\nconst props = withDefaults(defineProps<SidebarProps>(), {\n collapsible: 'icon',\n})\n\n// This is sample data.\nconst data = {\n user: {\n name: 'shadcn',\n email: 'm@example.com',\n avatar: '/avatars/shadcn.jpg',\n },\n teams: [\n {\n name: 'Acme Inc',\n logo: GalleryVerticalEnd,\n plan: 'Enterprise',\n },\n {\n name: 'Acme Corp.',\n logo: AudioWaveform,\n plan: 'Startup',\n },\n {\n name: 'Evil Corp.',\n logo: Command,\n plan: 'Free',\n },\n ],\n navMain: [\n {\n title: 'Playground',\n url: '#',\n icon: SquareTerminal,\n isActive: true,\n items: [\n {\n title: 'History',\n url: '#',\n },\n {\n title: 'Starred',\n url: '#',\n },\n {\n title: 'Settings',\n url: '#',\n },\n ],\n },\n {\n title: 'Models',\n url: '#',\n icon: Bot,\n items: [\n {\n title: 'Genesis',\n url: '#',\n },\n {\n title: 'Explorer',\n url: '#',\n },\n {\n title: 'Quantum',\n url: '#',\n },\n ],\n },\n {\n title: 'Documentation',\n url: '#',\n icon: BookOpen,\n items: [\n {\n title: 'Introduction',\n url: '#',\n },\n {\n title: 'Get Started',\n url: '#',\n },\n {\n title: 'Tutorials',\n url: '#',\n },\n {\n title: 'Changelog',\n url: '#',\n },\n ],\n },\n {\n title: 'Settings',\n url: '#',\n icon: Settings2,\n items: [\n {\n title: 'General',\n url: '#',\n },\n {\n title: 'Team',\n url: '#',\n },\n {\n title: 'Billing',\n url: '#',\n },\n {\n title: 'Limits',\n url: '#',\n },\n ],\n },\n ],\n projects: [\n {\n name: 'Design Engineering',\n url: '#',\n icon: Frame,\n },\n {\n name: 'Sales & Marketing',\n url: '#',\n icon: PieChart,\n },\n {\n name: 'Travel',\n url: '#',\n icon: Map,\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <TeamSwitcher :teams=\"data.teams\" />\n </SidebarHeader>\n <SidebarContent>\n <NavMain :items=\"data.navMain\" />\n <NavProjects :projects=\"data.projects\" />\n </SidebarContent>\n <SidebarFooter>\n <NavUser :user=\"data.user\" />\n </SidebarFooter>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar07/components/NavMain.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/default/ui/collapsible'\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n} from '@/registry/default/ui/sidebar'\nimport { ChevronRight, type LucideIcon } from 'lucide-vue-next'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon?: LucideIcon\n isActive?: boolean\n items?: {\n title: string\n url: string\n }[]\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupLabel>Platform</SidebarGroupLabel>\n <SidebarMenu>\n <Collapsible\n v-for=\"item in items\"\n :key=\"item.title\"\n as-child\n :default-open=\"item.isActive\"\n class=\"group/collapsible\"\n >\n <SidebarMenuItem>\n <CollapsibleTrigger as-child>\n <SidebarMenuButton :tooltip=\"item.title\">\n <component :is=\"item.icon\" v-if=\"item.icon\" />\n <span>{{ item.title }}</span>\n <ChevronRight class=\"ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90\" />\n </SidebarMenuButton>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"subItem in item.items\" :key=\"subItem.title\">\n <SidebarMenuSubButton as-child>\n <a :href=\"subItem.url\">\n <span>{{ subItem.title }}</span>\n </a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar07/components/NavProjects.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\n\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/default/ui/sidebar'\nimport {\n Folder,\n Forward,\n type LucideIcon,\n MoreHorizontal,\n Trash2,\n} from 'lucide-vue-next'\n\ndefineProps<{\n projects: {\n name: string\n url: string\n icon: LucideIcon\n }[]\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarGroup class=\"group-data-[collapsible=icon]:hidden\">\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in projects\" :key=\"item.name\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.name }}</span>\n </a>\n </SidebarMenuButton>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuAction show-on-hover>\n <MoreHorizontal />\n <span class=\"sr-only\">More</span>\n </SidebarMenuAction>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-48 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n :align=\"isMobile ? 'end' : 'start'\"\n >\n <DropdownMenuItem>\n <Folder class=\"text-muted-foreground\" />\n <span>View Project</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Forward class=\"text-muted-foreground\" />\n <span>Share Project</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Trash2 class=\"text-muted-foreground\" />\n <span>Delete Project</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton class=\"text-sidebar-foreground/70\">\n <MoreHorizontal class=\"text-sidebar-foreground/70\" />\n <span>More</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar07/components/NavUser.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/registry/default/ui/avatar'\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/default/ui/sidebar'\nimport {\n BadgeCheck,\n Bell,\n ChevronsUpDown,\n CreditCard,\n LogOut,\n Sparkles,\n} from 'lucide-vue-next'\n\nconst props = defineProps<{\n user: {\n name: string\n email: string\n avatar: string\n }\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto size-4\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n align=\"end\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"p-0 font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <Sparkles />\n Upgrade to Pro\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <BadgeCheck />\n Account\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CreditCard />\n Billing\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Bell />\n Notifications\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut />\n Log out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar07/components/TeamSwitcher.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\n\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/default/ui/sidebar'\nimport { ChevronsUpDown, Plus } from 'lucide-vue-next'\n\nimport { type Component, ref } from 'vue'\n\nconst props = defineProps<{\n teams: {\n name: string\n logo: Component\n plan: string\n }[]\n}>()\n\nconst { isMobile } = useSidebar()\nconst activeTeam = ref(props.teams[0])\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <component :is=\"activeTeam.logo\" class=\"size-4\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">\n {{ activeTeam.name }}\n </span>\n <span class=\"truncate text-xs\">{{ activeTeam.plan }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n align=\"start\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"text-xs text-muted-foreground\">\n Teams\n </DropdownMenuLabel>\n <DropdownMenuItem\n v-for=\"(team, index) in teams\"\n :key=\"team.name\"\n class=\"gap-2 p-2\"\n @click=\"activeTeam = team\"\n >\n <div class=\"flex size-6 items-center justify-center rounded-sm border\">\n <component :is=\"team.logo\" class=\"size-4 shrink-0\" />\n </div>\n {{ team.name }}\n <DropdownMenuShortcut>⌘{{ index + 1 }}</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem class=\"gap-2 p-2\">\n <div class=\"flex size-6 items-center justify-center rounded-md border bg-background\">\n <Plus class=\"size-4\" />\n </div>\n <div class=\"font-medium text-muted-foreground\">\n Add team\n </div>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar08",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible",
|
|
"dropdown-menu",
|
|
"avatar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar08/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'An inset sidebar with secondary navigation.'\nexport const iframeHeight = '800px'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/default/block/Sidebar08/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Separator } from '@/registry/default/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2\">\n <div class=\"flex items-center gap-2 px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4 pt-0\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar08/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport NavMain from '@/registry/default/block/Sidebar08/components/NavMain.vue'\n\nimport NavProjects from '@/registry/default/block/Sidebar08/components/NavProjects.vue'\nimport NavSecondary from '@/registry/default/block/Sidebar08/components/NavSecondary.vue'\nimport NavUser from '@/registry/default/block/Sidebar08/components/NavUser.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n} from '@/registry/default/ui/sidebar'\nimport {\n BookOpen,\n Bot,\n Command,\n Frame,\n LifeBuoy,\n Map,\n PieChart,\n Send,\n Settings2,\n SquareTerminal,\n} from 'lucide-vue-next'\n\nconst props = withDefaults(defineProps<SidebarProps>(), {\n variant: 'inset',\n})\n\nconst data = {\n user: {\n name: 'shadcn',\n email: 'm@example.com',\n avatar: '/avatars/shadcn.jpg',\n },\n navMain: [\n {\n title: 'Playground',\n url: '#',\n icon: SquareTerminal,\n isActive: true,\n items: [\n {\n title: 'History',\n url: '#',\n },\n {\n title: 'Starred',\n url: '#',\n },\n {\n title: 'Settings',\n url: '#',\n },\n ],\n },\n {\n title: 'Models',\n url: '#',\n icon: Bot,\n items: [\n {\n title: 'Genesis',\n url: '#',\n },\n {\n title: 'Explorer',\n url: '#',\n },\n {\n title: 'Quantum',\n url: '#',\n },\n ],\n },\n {\n title: 'Documentation',\n url: '#',\n icon: BookOpen,\n items: [\n {\n title: 'Introduction',\n url: '#',\n },\n {\n title: 'Get Started',\n url: '#',\n },\n {\n title: 'Tutorials',\n url: '#',\n },\n {\n title: 'Changelog',\n url: '#',\n },\n ],\n },\n {\n title: 'Settings',\n url: '#',\n icon: Settings2,\n items: [\n {\n title: 'General',\n url: '#',\n },\n {\n title: 'Team',\n url: '#',\n },\n {\n title: 'Billing',\n url: '#',\n },\n {\n title: 'Limits',\n url: '#',\n },\n ],\n },\n ],\n navSecondary: [\n {\n title: 'Support',\n url: '#',\n icon: LifeBuoy,\n },\n {\n title: 'Feedback',\n url: '#',\n icon: Send,\n },\n ],\n projects: [\n {\n name: 'Design Engineering',\n url: '#',\n icon: Frame,\n },\n {\n name: 'Sales & Marketing',\n url: '#',\n icon: PieChart,\n },\n {\n name: 'Travel',\n url: '#',\n icon: Map,\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton size=\"lg\" as-child>\n <a href=\"#\">\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <Command class=\"size-4\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">Acme Inc</span>\n <span class=\"truncate text-xs\">Enterprise</span>\n </div>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarHeader>\n <SidebarContent>\n <NavMain :items=\"data.navMain\" />\n <NavProjects :projects=\"data.projects\" />\n <NavSecondary :items=\"data.navSecondary\" class=\"mt-auto\" />\n </SidebarContent>\n <SidebarFooter>\n <NavUser :user=\"data.user\" />\n </SidebarFooter>\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar08/components/NavMain.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/default/ui/collapsible'\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n} from '@/registry/default/ui/sidebar'\nimport { ChevronRight, type LucideIcon } from 'lucide-vue-next'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon: LucideIcon\n isActive?: boolean\n items?: {\n title: string\n url: string\n }[]\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupLabel>Platform</SidebarGroupLabel>\n <SidebarMenu>\n <Collapsible v-for=\"item in items\" :key=\"item.title\" as-child :default-open=\"item.isActive\">\n <SidebarMenuItem>\n <SidebarMenuButton as-child :tooltip=\"item.title\">\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n <template v-if=\"item.items?.length\">\n <CollapsibleTrigger as-child>\n <SidebarMenuAction class=\"data-[state=open]:rotate-90\">\n <ChevronRight />\n <span class=\"sr-only\">Toggle</span>\n </SidebarMenuAction>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"subItem in item.items\" :key=\"subItem.title\">\n <SidebarMenuSubButton as-child>\n <a :href=\"subItem.url\">\n <span>{{ subItem.title }}</span>\n </a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </CollapsibleContent>\n </template>\n </SidebarMenuItem>\n </Collapsible>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar08/components/NavProjects.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\n\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/default/ui/sidebar'\nimport {\n Folder,\n Forward,\n type LucideIcon,\n MoreHorizontal,\n Trash2,\n} from 'lucide-vue-next'\n\ndefineProps<{\n projects: {\n name: string\n url: string\n icon: LucideIcon\n }[]\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarGroup class=\"group-data-[collapsible=icon]:hidden\">\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in projects\" :key=\"item.name\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.name }}</span>\n </a>\n </SidebarMenuButton>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuAction show-on-hover>\n <MoreHorizontal />\n <span class=\"sr-only\">More</span>\n </SidebarMenuAction>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-48 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n :align=\"isMobile ? 'end' : 'start'\"\n >\n <DropdownMenuItem>\n <Folder class=\"text-muted-foreground\" />\n <span>View Project</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Forward class=\"text-muted-foreground\" />\n <span>Share Project</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Trash2 class=\"text-muted-foreground\" />\n <span>Delete Project</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton class=\"text-sidebar-foreground/70\">\n <MoreHorizontal class=\"text-sidebar-foreground/70\" />\n <span>More</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar08/components/NavSecondary.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { LucideIcon } from 'lucide-vue-next'\n\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/default/ui/sidebar'\n\nconst props = defineProps<{\n items: {\n title: string\n url: string\n icon: LucideIcon\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuButton as-child size=\"sm\">\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar08/components/NavUser.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/registry/default/ui/avatar'\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/default/ui/sidebar'\nimport {\n BadgeCheck,\n Bell,\n ChevronsUpDown,\n CreditCard,\n LogOut,\n Sparkles,\n} from 'lucide-vue-next'\n\nconst props = defineProps<{\n user: {\n name: string\n email: string\n avatar: string\n }\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto size-4\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n align=\"end\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"p-0 font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <Sparkles />\n Upgrade to Pro\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <BadgeCheck />\n Account\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CreditCard />\n Billing\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Bell />\n Notifications\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut />\n Log out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar09",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"label",
|
|
"switch",
|
|
"avatar",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar09/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'Collapsible nested sidebars.'\nexport const iframeHeight = '800px'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/default/block/Sidebar09/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Separator } from '@/registry/default/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider\n :style=\"{\n '--sidebar-width': '350px',\n }\"\n >\n <AppSidebar />\n <SidebarInset>\n <header class=\"sticky top-0 flex shrink-0 items-center gap-2 border-b bg-background p-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n All Inboxes\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Inbox</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div\n v-for=\"index in 24\"\n :key=\"index\"\n class=\"aspect-video h-12 w-full rounded-lg bg-muted/50\"\n />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar09/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport NavUser from '@/registry/default/block/Sidebar09/components/NavUser.vue'\n\nimport { Label } from '@/registry/default/ui/label'\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupContent,\n SidebarHeader,\n SidebarInput,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n useSidebar,\n} from '@/registry/default/ui/sidebar'\nimport { Switch } from '@/registry/default/ui/switch'\nimport { ArchiveX, Command, File, Inbox, Send, Trash2 } from 'lucide-vue-next'\nimport { h, ref } from 'vue'\n\nconst props = withDefaults(defineProps<SidebarProps>(), {\n collapsible: 'icon',\n})\n\n// This is sample data\nconst data = {\n user: {\n name: 'shadcn',\n email: 'm@example.com',\n avatar: '/avatars/shadcn.jpg',\n },\n navMain: [\n {\n title: 'Inbox',\n url: '#',\n icon: Inbox,\n isActive: true,\n },\n {\n title: 'Drafts',\n url: '#',\n icon: File,\n isActive: false,\n },\n {\n title: 'Sent',\n url: '#',\n icon: Send,\n isActive: false,\n },\n {\n title: 'Junk',\n url: '#',\n icon: ArchiveX,\n isActive: false,\n },\n {\n title: 'Trash',\n url: '#',\n icon: Trash2,\n isActive: false,\n },\n ],\n mails: [\n {\n name: 'William Smith',\n email: 'williamsmith@example.com',\n subject: 'Meeting Tomorrow',\n date: '09:34 AM',\n teaser:\n 'Hi team, just a reminder about our meeting tomorrow at 10 AM.\\nPlease come prepared with your project updates.',\n },\n {\n name: 'Alice Smith',\n email: 'alicesmith@example.com',\n subject: 'Re: Project Update',\n date: 'Yesterday',\n teaser:\n 'Thanks for the update. The progress looks great so far.\\nLet\\'s schedule a call to discuss the next steps.',\n },\n {\n name: 'Bob Johnson',\n email: 'bobjohnson@example.com',\n subject: 'Weekend Plans',\n date: '2 days ago',\n teaser:\n 'Hey everyone! I\\'m thinking of organizing a team outing this weekend.\\nWould you be interested in a hiking trip or a beach day?',\n },\n {\n name: 'Emily Davis',\n email: 'emilydavis@example.com',\n subject: 'Re: Question about Budget',\n date: '2 days ago',\n teaser:\n 'I\\'ve reviewed the budget numbers you sent over.\\nCan we set up a quick call to discuss some potential adjustments?',\n },\n {\n name: 'Michael Wilson',\n email: 'michaelwilson@example.com',\n subject: 'Important Announcement',\n date: '1 week ago',\n teaser:\n 'Please join us for an all-hands meeting this Friday at 3 PM.\\nWe have some exciting news to share about the company\\'s future.',\n },\n {\n name: 'Sarah Brown',\n email: 'sarahbrown@example.com',\n subject: 'Re: Feedback on Proposal',\n date: '1 week ago',\n teaser:\n 'Thank you for sending over the proposal. I\\'ve reviewed it and have some thoughts.\\nCould we schedule a meeting to discuss my feedback in detail?',\n },\n {\n name: 'David Lee',\n email: 'davidlee@example.com',\n subject: 'New Project Idea',\n date: '1 week ago',\n teaser:\n 'I\\'ve been brainstorming and came up with an interesting project concept.\\nDo you have time this week to discuss its potential impact and feasibility?',\n },\n {\n name: 'Olivia Wilson',\n email: 'oliviawilson@example.com',\n subject: 'Vacation Plans',\n date: '1 week ago',\n teaser:\n 'Just a heads up that I\\'ll be taking a two-week vacation next month.\\nI\\'ll make sure all my projects are up to date before I leave.',\n },\n {\n name: 'James Martin',\n email: 'jamesmartin@example.com',\n subject: 'Re: Conference Registration',\n date: '1 week ago',\n teaser:\n 'I\\'ve completed the registration for the upcoming tech conference.\\nLet me know if you need any additional information from my end.',\n },\n {\n name: 'Sophia White',\n email: 'sophiawhite@example.com',\n subject: 'Team Dinner',\n date: '1 week ago',\n teaser:\n 'To celebrate our recent project success, I\\'d like to organize a team dinner.\\nAre you available next Friday evening? Please let me know your preferences.',\n },\n ],\n}\n\nconst activeItem = ref(data.navMain[0])\nconst mails = ref(data.mails)\nconst { setOpen } = useSidebar()\n</script>\n\n<template>\n <Sidebar\n class=\"overflow-hidden [&>[data-sidebar=sidebar]]:flex-row\"\n v-bind=\"props\"\n >\n <!-- This is the first sidebar -->\n <!-- We disable collapsible and adjust width to icon. -->\n <!-- This will make the sidebar appear as icons. -->\n <Sidebar\n collapsible=\"none\"\n class=\"!w-[calc(var(--sidebar-width-icon)_+_1px)] border-r\"\n >\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton size=\"lg\" as-child class=\"md:h-8 md:p-0\">\n <a href=\"#\">\n <div class=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <Command class=\"size-4\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">Acme Inc</span>\n <span class=\"truncate text-xs\">Enterprise</span>\n </div>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarHeader>\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupContent class=\"px-1.5 md:px-0\">\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in data.navMain\" :key=\"item.title\">\n <SidebarMenuButton\n :tooltip=\"h('div', { hidden: false }, item.title)\"\n :is-active=\"activeItem.title === item.title\"\n class=\"px-2.5 md:px-2\"\n @click=\"() => {\n activeItem = item\n const mail = data.mails.sort(() => Math.random() - 0.5)\n mails = mail.slice(0, Math.max(5, Math.floor(Math.random() * 10) + 1))\n setOpen(true)\n }\"\n >\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n <SidebarFooter>\n <NavUser :user=\"data.user\" />\n </SidebarFooter>\n </Sidebar>\n\n <!-- This is the second sidebar -->\n <!-- We disable collapsible and let it fill remaining space -->\n <Sidebar collapsible=\"none\" class=\"hidden flex-1 md:flex\">\n <SidebarHeader class=\"gap-3.5 border-b p-4\">\n <div class=\"flex w-full items-center justify-between\">\n <div class=\"text-base font-medium text-foreground\">\n {{ activeItem.title }}\n </div>\n <Label class=\"flex items-center gap-2 text-sm\">\n <span>Unreads</span>\n <Switch class=\"shadow-none\" />\n </Label>\n </div>\n <SidebarInput placeholder=\"Type to search...\" />\n </SidebarHeader>\n <SidebarContent>\n <SidebarGroup class=\"px-0\">\n <SidebarGroupContent>\n <a\n v-for=\"mail in mails\"\n :key=\"mail.email\"\n href=\"#\"\n class=\"flex flex-col items-start gap-2 whitespace-nowrap border-b p-4 text-sm leading-tight last:border-b-0 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\"\n >\n <div class=\"flex w-full items-center gap-2\">\n <span>{{ mail.name }}</span>\n <span class=\"ml-auto text-xs\">{{ mail.date }}</span>\n </div>\n <span class=\"font-medium\">{{ mail.subject }}</span>\n <span class=\"line-clamp-2 w-[260px] whitespace-break-spaces text-xs\">\n {{ mail.teaser }}\n </span>\n </a>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar09/components/NavUser.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/registry/default/ui/avatar'\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/default/ui/sidebar'\nimport {\n BadgeCheck,\n Bell,\n ChevronsUpDown,\n CreditCard,\n LogOut,\n Sparkles,\n} from 'lucide-vue-next'\n\nconst props = defineProps<{\n user: {\n name: string\n email: string\n avatar: string\n }\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground md:h-8 md:p-0\"\n >\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto size-4\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n align=\"end\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"p-0 font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <Sparkles />\n Upgrade to Pro\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <BadgeCheck />\n Account\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CreditCard />\n Billing\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Bell />\n Notifications\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut />\n Log out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar10",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"button",
|
|
"popover",
|
|
"dropdown-menu",
|
|
"collapsible"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar10/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A sidebar in a popover.'\nexport const iframeHeight = '800px'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/default/block/Sidebar10/components/AppSidebar.vue'\nimport NavActions from '@/registry/default/block/Sidebar10/components/NavActions.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbList,\n BreadcrumbPage,\n} from '@/registry/default/ui/breadcrumb'\nimport { Separator } from '@/registry/default/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-14 shrink-0 items-center gap-2\">\n <div class=\"flex flex-1 items-center gap-2 px-3\">\n <SidebarTrigger />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbPage class=\"line-clamp-1\">\n Project Management & Task Tracking\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n <div class=\"ml-auto px-3\">\n <NavActions />\n </div>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 px-4 py-10\">\n <div class=\"mx-auto h-24 w-full max-w-3xl rounded-xl bg-muted/50\" />\n <div class=\"mx-auto h-full w-full max-w-3xl rounded-xl bg-muted/50\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport NavFavorites from '@/registry/default/block/Sidebar10/components/NavFavorites.vue'\n\nimport NavMain from '@/registry/default/block/Sidebar10/components/NavMain.vue'\nimport NavSecondary from '@/registry/default/block/Sidebar10/components/NavSecondary.vue'\nimport NavWorkspaces from '@/registry/default/block/Sidebar10/components/NavWorkspaces.vue'\nimport TeamSwitcher from '@/registry/default/block/Sidebar10/components/TeamSwitcher.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarHeader,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/default/ui/sidebar'\nimport {\n AudioWaveform,\n Blocks,\n Calendar,\n Command,\n Home,\n Inbox,\n MessageCircleQuestion,\n Search,\n Settings2,\n Sparkles,\n Trash2,\n} from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n teams: [\n {\n name: 'Acme Inc',\n logo: Command,\n plan: 'Enterprise',\n },\n {\n name: 'Acme Corp.',\n logo: AudioWaveform,\n plan: 'Startup',\n },\n {\n name: 'Evil Corp.',\n logo: Command,\n plan: 'Free',\n },\n ],\n navMain: [\n {\n title: 'Search',\n url: '#',\n icon: Search,\n },\n {\n title: 'Ask AI',\n url: '#',\n icon: Sparkles,\n },\n {\n title: 'Home',\n url: '#',\n icon: Home,\n isActive: true,\n },\n {\n title: 'Inbox',\n url: '#',\n icon: Inbox,\n badge: '10',\n },\n ],\n navSecondary: [\n {\n title: 'Calendar',\n url: '#',\n icon: Calendar,\n },\n {\n title: 'Settings',\n url: '#',\n icon: Settings2,\n },\n {\n title: 'Templates',\n url: '#',\n icon: Blocks,\n },\n {\n title: 'Trash',\n url: '#',\n icon: Trash2,\n },\n {\n title: 'Help',\n url: '#',\n icon: MessageCircleQuestion,\n },\n ],\n favorites: [\n {\n name: 'Project Management & Task Tracking',\n url: '#',\n emoji: '📊',\n },\n {\n name: 'Family Recipe Collection & Meal Planning',\n url: '#',\n emoji: '🍳',\n },\n {\n name: 'Fitness Tracker & Workout Routines',\n url: '#',\n emoji: '💪',\n },\n {\n name: 'Book Notes & Reading List',\n url: '#',\n emoji: '📚',\n },\n {\n name: 'Sustainable Gardening Tips & Plant Care',\n url: '#',\n emoji: '🌱',\n },\n {\n name: 'Language Learning Progress & Resources',\n url: '#',\n emoji: '🗣️',\n },\n {\n name: 'Home Renovation Ideas & Budget Tracker',\n url: '#',\n emoji: '🏠',\n },\n {\n name: 'Personal Finance & Investment Portfolio',\n url: '#',\n emoji: '💰',\n },\n {\n name: 'Movie & TV Show Watchlist with Reviews',\n url: '#',\n emoji: '🎬',\n },\n {\n name: 'Daily Habit Tracker & Goal Setting',\n url: '#',\n emoji: '✅',\n },\n ],\n workspaces: [\n {\n name: 'Personal Life Management',\n emoji: '🏠',\n pages: [\n {\n name: 'Daily Journal & Reflection',\n url: '#',\n emoji: '📔',\n },\n {\n name: 'Health & Wellness Tracker',\n url: '#',\n emoji: '🍏',\n },\n {\n name: 'Personal Growth & Learning Goals',\n url: '#',\n emoji: '🌟',\n },\n ],\n },\n {\n name: 'Professional Development',\n emoji: '💼',\n pages: [\n {\n name: 'Career Objectives & Milestones',\n url: '#',\n emoji: '🎯',\n },\n {\n name: 'Skill Acquisition & Training Log',\n url: '#',\n emoji: '🧠',\n },\n {\n name: 'Networking Contacts & Events',\n url: '#',\n emoji: '🤝',\n },\n ],\n },\n {\n name: 'Creative Projects',\n emoji: '🎨',\n pages: [\n {\n name: 'Writing Ideas & Story Outlines',\n url: '#',\n emoji: '✍️',\n },\n {\n name: 'Art & Design Portfolio',\n url: '#',\n emoji: '🖼️',\n },\n {\n name: 'Music Composition & Practice Log',\n url: '#',\n emoji: '🎵',\n },\n ],\n },\n {\n name: 'Home Management',\n emoji: '🏡',\n pages: [\n {\n name: 'Household Budget & Expense Tracking',\n url: '#',\n emoji: '💰',\n },\n {\n name: 'Home Maintenance Schedule & Tasks',\n url: '#',\n emoji: '🔧',\n },\n {\n name: 'Family Calendar & Event Planning',\n url: '#',\n emoji: '📅',\n },\n ],\n },\n {\n name: 'Travel & Adventure',\n emoji: '🧳',\n pages: [\n {\n name: 'Trip Planning & Itineraries',\n url: '#',\n emoji: '🗺️',\n },\n {\n name: 'Travel Bucket List & Inspiration',\n url: '#',\n emoji: '🌎',\n },\n {\n name: 'Travel Journal & Photo Gallery',\n url: '#',\n emoji: '📸',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar class=\"border-r-0\" v-bind=\"props\">\n <SidebarHeader>\n <TeamSwitcher :teams=\"data.teams\" />\n <NavMain :items=\"data.navMain\" />\n </SidebarHeader>\n <SidebarContent>\n <NavFavorites :favorites=\"data.favorites\" />\n <NavWorkspaces :workspaces=\"data.workspaces\" />\n <NavSecondary :items=\"data.navSecondary\" class=\"mt-auto\" />\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/NavActions.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Button } from '@/registry/default/ui/button'\n\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/registry/default/ui/popover'\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/default/ui/sidebar'\nimport {\n ArrowDown,\n ArrowUp,\n Bell,\n Copy,\n CornerUpLeft,\n CornerUpRight,\n FileText,\n GalleryVerticalEnd,\n LineChart,\n Link,\n MoreHorizontal,\n Settings2,\n Star,\n Trash,\n Trash2,\n} from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst data = [\n [\n {\n label: 'Customize Page',\n icon: Settings2,\n },\n {\n label: 'Turn into wiki',\n icon: FileText,\n },\n ],\n [\n {\n label: 'Copy Link',\n icon: Link,\n },\n {\n label: 'Duplicate',\n icon: Copy,\n },\n {\n label: 'Move to',\n icon: CornerUpRight,\n },\n {\n label: 'Move to Trash',\n icon: Trash2,\n },\n ],\n [\n {\n label: 'Undo',\n icon: CornerUpLeft,\n },\n {\n label: 'View analytics',\n icon: LineChart,\n },\n {\n label: 'Version History',\n icon: GalleryVerticalEnd,\n },\n {\n label: 'Show delete pages',\n icon: Trash,\n },\n {\n label: 'Notifications',\n icon: Bell,\n },\n ],\n [\n {\n label: 'Import',\n icon: ArrowUp,\n },\n {\n label: 'Export',\n icon: ArrowDown,\n },\n ],\n]\n\nconst isOpen = ref(false)\n</script>\n\n<template>\n <div class=\"flex items-center gap-2 text-sm\">\n <div class=\"hidden font-medium text-muted-foreground md:inline-block\">\n Edit Oct 08\n </div>\n <Button variant=\"ghost\" size=\"icon\" class=\"h-7 w-7\">\n <Star />\n </Button>\n <Popover v-model:open=\"isOpen\">\n <PopoverTrigger as-child>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n class=\"h-7 w-7 data-[state=open]:bg-accent\"\n >\n <MoreHorizontal />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n class=\"w-56 overflow-hidden rounded-lg p-0\"\n align=\"end\"\n >\n <Sidebar collapsible=\"none\" class=\"bg-transparent\">\n <SidebarContent>\n <SidebarGroup v-for=\"(group, index) in data\" :key=\"index\" class=\"border-b last:border-none\">\n <SidebarGroupContent class=\"gap-0\">\n <SidebarMenu>\n <SidebarMenuItem v-for=\"(item, index) in group\" :key=\"index\">\n <SidebarMenuButton>\n <component :is=\"item.icon\" /> <span>{{ item.label }}</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n </PopoverContent>\n </Popover>\n </div>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/NavFavorites.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\n\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/default/ui/sidebar'\nimport {\n ArrowUpRight,\n Link,\n MoreHorizontal,\n StarOff,\n Trash2,\n} from 'lucide-vue-next'\n\ndefineProps<{\n favorites: {\n name: string\n url: string\n emoji: string\n }[]\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarGroup class=\"group-data-[collapsible=icon]:hidden\">\n <SidebarGroupLabel>Favorites</SidebarGroupLabel>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in favorites\" :key=\"item.name\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\" :title=\"item.name\">\n <span>{{ item.emoji }}</span>\n <span>{{ item.name }}</span>\n </a>\n </SidebarMenuButton>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuAction show-on-hover>\n <MoreHorizontal />\n <span class=\"sr-only\">More</span>\n </SidebarMenuAction>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n :align=\"isMobile ? 'end' : 'start'\"\n >\n <DropdownMenuItem>\n <StarOff class=\"text-muted-foreground\" />\n <span>Remove from Favorites</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Link class=\"text-muted-foreground\" />\n <span>Copy Link</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <ArrowUpRight class=\"text-muted-foreground\" />\n <span>Open in New Tab</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Trash2 class=\"text-muted-foreground\" />\n <span>Delete</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n\n <SidebarMenuItem>\n <SidebarMenuButton class=\"text-sidebar-foreground/70\">\n <MoreHorizontal />\n <span>More</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/NavMain.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { LucideIcon } from 'lucide-vue-next'\n\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/default/ui/sidebar'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon: LucideIcon\n isActive?: boolean\n }[]\n}>()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuButton as-child :is-active=\"item.isActive\">\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/NavSecondary.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { LucideIcon } from 'lucide-vue-next'\n\nimport type { Component } from 'vue'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/default/ui/sidebar'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon: LucideIcon\n badge?: Component\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n <SidebarMenuBadge v-if=\"item.badge\">\n <component :is=\"item.badge\" />\n </SidebarMenuBadge>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/NavWorkspaces.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/default/ui/collapsible'\n\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n} from '@/registry/default/ui/sidebar'\nimport { ChevronRight, MoreHorizontal, Plus } from 'lucide-vue-next'\n\ndefineProps<{\n workspaces: {\n name: string\n emoji: string\n pages: {\n name: string\n emoji: string\n }[]\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupLabel>Workspaces</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <Collapsible v-for=\"workspace in workspaces\" :key=\"workspace.name\">\n <SidebarMenuItem>\n <SidebarMenuButton as-child>\n <a href=\"#\">\n <span>{{ workspace.emoji }}</span>\n <span>{{ workspace.name }}</span>\n </a>\n </SidebarMenuButton>\n <CollapsibleTrigger as-child>\n <SidebarMenuAction\n class=\"left-2 bg-sidebar-accent text-sidebar-accent-foreground data-[state=open]:rotate-90\"\n show-on-hover\n >\n <ChevronRight />\n </SidebarMenuAction>\n </CollapsibleTrigger>\n <SidebarMenuAction show-on-hover>\n <Plus />\n </SidebarMenuAction>\n <CollapsibleContent>\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"page in workspace.pages\" :key=\"page.name\">\n <SidebarMenuSubButton as-child>\n <a href=\"#\">\n <span>{{ page.emoji }}</span>\n <span>{{ page.name }}</span>\n </a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n\n <SidebarMenuItem>\n <SidebarMenuButton class=\"text-sidebar-foreground/70\">\n <MoreHorizontal />\n <span>More</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar10/components/TeamSwitcher.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/default/ui/sidebar'\nimport { ChevronDown, Plus } from 'lucide-vue-next'\n\nimport { type Component, ref } from 'vue'\n\nconst props = defineProps<{\n teams: {\n name: string\n logo: Component\n plan: string\n }[]\n}>()\n\nconst activeTeam = ref(props.teams[0])\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton class=\"w-fit px-1.5\">\n <div class=\"flex aspect-square size-5 items-center justify-center rounded-md bg-sidebar-primary text-sidebar-primary-foreground\">\n <component :is=\"activeTeam.logo\" class=\"size-3\" />\n </div>\n <span class=\"truncate font-semibold\">{{ activeTeam.name }}</span>\n <ChevronDown class=\"opacity-50\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-64 rounded-lg\"\n align=\"start\"\n side=\"bottom\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"text-xs text-muted-foreground\">\n Teams\n </DropdownMenuLabel>\n <DropdownMenuItem\n v-for=\"(team, index) in teams\"\n :key=\"team.name\"\n class=\"gap-2 p-2\"\n @click=\"activeTeam = team\"\n >\n <div class=\"flex size-6 items-center justify-center rounded-sm border\">\n <component :is=\"team.logo\" class=\"size-4 shrink-0\" />\n </div>\n {{ team.name }}\n <DropdownMenuShortcut>⌘{{ index + 1 }}</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem class=\"gap-2 p-2\">\n <div class=\"flex size-6 items-center justify-center rounded-md border bg-background\">\n <Plus class=\"size-4\" />\n </div>\n <div class=\"font-medium text-muted-foreground\">\n Add team\n </div>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar11",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar11/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A sidebar with a collapsible file tree.'\nexport const iframeHeight = '800px'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/default/block/Sidebar11/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport { Separator } from '@/registry/default/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 border-b px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n components\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n ui\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>button.tsx</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar11/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport Tree from '@/registry/default/block/Sidebar11/components/Tree.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/default/ui/sidebar'\nimport { File } from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n changes: [\n {\n file: 'README.md',\n state: 'M',\n },\n {\n file: 'api/hello/route.ts',\n state: 'U',\n },\n {\n file: 'app/layout.tsx',\n state: 'M',\n },\n ],\n tree: [\n [\n 'app',\n [\n 'api',\n ['hello', ['route.ts']],\n 'page.tsx',\n 'layout.tsx',\n ['blog', ['page.tsx']],\n ],\n ],\n [\n 'components',\n ['ui', 'button.tsx', 'card.tsx'],\n 'header.tsx',\n 'footer.tsx',\n ],\n ['lib', ['util.ts']],\n ['public', 'favicon.ico', 'vercel.svg'],\n '.eslintrc.json',\n '.gitignore',\n 'next.config.js',\n 'tailwind.config.js',\n 'package.json',\n 'README.md',\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Changes</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"(item, index) in data.changes\" :key=\"index\">\n <SidebarMenuButton>\n <File />\n {{ item.file }}\n </SidebarMenuButton>\n <SidebarMenuBadge>{{ item.state }}</SidebarMenuBadge>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n <SidebarGroup>\n <SidebarGroupLabel>Files</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <Tree v-for=\"(item, index) in data.tree\" :key=\"index\" :item=\"item\" />\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar11/components/Tree.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/default/ui/collapsible'\n\nimport {\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n} from '@/registry/default/ui/sidebar'\nimport { ChevronRight, File, Folder } from 'lucide-vue-next'\n\nconst props = defineProps<{\n item: string | any[]\n}>()\n\nconst [name, ...items] = Array.isArray(props.item) ? props.item : [props.item]\n</script>\n\n<template>\n <SidebarMenuButton\n v-if=\"!items.length\"\n :is-active=\"name === 'button.tsx'\"\n class=\"data-[active=true]:bg-transparent\"\n >\n <File />\n {{ name }}\n </SidebarMenuButton>\n\n <SidebarMenuItem v-else>\n <Collapsible\n class=\"group/collapsible [&[data-state=open]>button>svg:first-child]:rotate-90\"\n :default-open=\"name === 'components' || name === 'ui'\"\n >\n <CollapsibleTrigger as-child>\n <SidebarMenuButton>\n <ChevronRight class=\"transition-transform\" />\n <Folder />\n {{ name }}\n </SidebarMenuButton>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <SidebarMenuSub>\n <Tree v-for=\"(subItem, index) in items\" :key=\"index\" :item=\"subItem\" />\n </SidebarMenuSub>\n </CollapsibleContent>\n </Collapsible>\n </SidebarMenuItem>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar12",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible",
|
|
"calendar",
|
|
"avatar",
|
|
"dropdown-menu"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar12/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A sidebar with a calendar.'\nexport const iframeHeight = '800px'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/default/block/Sidebar12/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbList,\n BreadcrumbPage,\n} from '@/registry/default/ui/breadcrumb'\nimport { Separator } from '@/registry/default/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <AppSidebar />\n <SidebarInset>\n <header class=\"sticky top-0 flex h-16 shrink-0 items-center gap-2 border-b bg-background px-4\">\n <SidebarTrigger class=\"-ml-1\" />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbPage>October 2024</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-5\">\n <div v-for=\"i in 20\" :key=\"i\" class=\"aspect-square rounded-xl bg-muted/50\" />\n </div>\n </div>\n </SidebarInset>\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar12/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport Calendars from '@/registry/default/block/Sidebar12/components/Calendars.vue'\n\nimport DatePicker from '@/registry/default/block/Sidebar12/components/DatePicker.vue'\nimport NavUser from '@/registry/default/block/Sidebar12/components/NavUser.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n SidebarRail,\n SidebarSeparator,\n} from '@/registry/default/ui/sidebar'\nimport { Plus } from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n// This is sample data.\nconst data = {\n user: {\n name: 'shadcn',\n email: 'm@example.com',\n avatar: '/avatars/shadcn.jpg',\n },\n calendars: [\n {\n name: 'My Calendars',\n items: ['Personal', 'Work', 'Family'],\n },\n {\n name: 'Favorites',\n items: ['Holidays', 'Birthdays'],\n },\n {\n name: 'Other',\n items: ['Travel', 'Reminders', 'Deadlines'],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarHeader class=\"h-16 border-b border-sidebar-border\">\n <NavUser :user=\"data.user\" />\n </SidebarHeader>\n <SidebarContent>\n <DatePicker />\n <SidebarSeparator class=\"mx-0\" />\n <Calendars :calendars=\"data.calendars\" />\n </SidebarContent>\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <Plus />\n <span>New Calendar</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar12/components/Calendars.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/default/ui/collapsible'\n\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarSeparator,\n} from '@/registry/default/ui/sidebar'\nimport { Check, ChevronRight } from 'lucide-vue-next'\n\nconst props = defineProps<{\n calendars: {\n name: string\n items: string[]\n }[]\n}>()\n</script>\n\n<template>\n <template v-for=\"(calendar, index) in calendars\" :key=\"calendar.name\">\n <SidebarGroup class=\"py-0\">\n <Collapsible\n :default-open=\"index === 0\"\n class=\"group/collapsible\"\n >\n <SidebarGroupLabel\n as-child\n class=\"group/label w-full text-sm text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\"\n >\n <CollapsibleTrigger>\n {{ calendar.name }}\n <ChevronRight class=\"ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90\" />\n </CollapsibleTrigger>\n </SidebarGroupLabel>\n <CollapsibleContent>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"(item, index) in calendar.items\" :key=\"item\">\n <SidebarMenuButton>\n <div\n :data-active=\"index < 2\"\n class=\"group/calendar-item flex aspect-square size-4 shrink-0 items-center justify-center rounded-sm border border-sidebar-border text-sidebar-primary-foreground data-[active=true]:border-sidebar-primary data-[active=true]:bg-sidebar-primary\"\n >\n <Check class=\"hidden size-3 group-data-[active=true]/calendar-item:block\" />\n </div>\n {{ item }}\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </CollapsibleContent>\n </Collapsible>\n </SidebarGroup>\n <SidebarSeparator class=\"mx-0\" />\n </template>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar12/components/DatePicker.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Calendar } from '@/registry/default/ui/calendar'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarGroup class=\"px-0\">\n <SidebarGroupContent>\n <Calendar class=\"[&_[role=gridcell].bg-accent]:bg-sidebar-primary [&_[role=gridcell].bg-accent]:text-sidebar-primary-foreground [&_[role=gridcell]]:w-[33px]\" />\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar12/components/NavUser.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/registry/default/ui/avatar'\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/default/ui/sidebar'\nimport {\n BadgeCheck,\n Bell,\n ChevronsUpDown,\n CreditCard,\n LogOut,\n Sparkles,\n} from 'lucide-vue-next'\n\nconst props = defineProps<{\n user: {\n name: string\n email: string\n avatar: string\n }\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto size-4\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n align=\"start\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"p-0 font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <Sparkles />\n Upgrade to Pro\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <BadgeCheck />\n Account\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CreditCard />\n Billing\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Bell />\n Notifications\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut />\n Log out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar13",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"button",
|
|
"dialog",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar13/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const description = 'A sidebar in a dialog.'\nexport const iframeHeight = '800px'\n</script>\n\n<script setup lang=\"ts\">\nimport SettingsDialog from '@/registry/default/block/Sidebar13/components/SettingsDialog.vue'\n</script>\n\n<template>\n <div class=\"flex h-svh items-center justify-center\">\n <SettingsDialog />\n </div>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar13/components/SettingsDialog.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\n\nimport { Button } from '@/registry/default/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogTitle,\n DialogTrigger,\n} from '@/registry/default/ui/dialog'\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/registry/default/ui/sidebar'\nimport {\n Bell,\n Check,\n Globe,\n Home,\n Keyboard,\n Link,\n Lock,\n Menu,\n MessageCircle,\n Paintbrush,\n Settings,\n Video,\n} from 'lucide-vue-next'\nimport { ref } from 'vue'\n\nconst data = {\n nav: [\n { name: 'Notifications', icon: Bell },\n { name: 'Navigation', icon: Menu },\n { name: 'Home', icon: Home },\n { name: 'Appearance', icon: Paintbrush },\n { name: 'Messages & media', icon: MessageCircle },\n { name: 'Language & region', icon: Globe },\n { name: 'Accessibility', icon: Keyboard },\n { name: 'Mark as read', icon: Check },\n { name: 'Audio & video', icon: Video },\n { name: 'Connected accounts', icon: Link },\n { name: 'Privacy & visibility', icon: Lock },\n { name: 'Advanced', icon: Settings },\n ],\n}\n\nconst open = ref(true)\n</script>\n\n<template>\n <Dialog v-model:open=\"open\">\n <DialogTrigger as-child>\n <Button size=\"sm\">\n Open Dialog\n </Button>\n </DialogTrigger>\n <DialogContent class=\"overflow-hidden p-0 md:max-h-[500px] md:max-w-[700px] lg:max-w-[800px]\">\n <DialogTitle class=\"sr-only\">\n Settings\n </DialogTitle>\n <DialogDescription class=\"sr-only\">\n Customize your settings here.\n </DialogDescription>\n <SidebarProvider class=\"items-start\">\n <Sidebar collapsible=\"none\" class=\"hidden md:flex\">\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in data.nav\" :key=\"item.name\">\n <SidebarMenuButton\n as-child\n :is-active=\"item.name === 'Messages & media'\"\n >\n <a href=\"#\">\n <component :is=\"item.icon\" />\n <span>{{ item.name }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n <main class=\"flex h-[480px] flex-1 flex-col overflow-hidden\">\n <header class=\"flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12\">\n <div class=\"flex items-center gap-2 px-4\">\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Settings\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Messages & media</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 overflow-y-auto p-4 pt-0\">\n <div\n v-for=\"i in 10\"\n :key=\"i\"\n class=\"aspect-video max-w-3xl rounded-xl bg-muted/50\"\n />\n </div>\n </main>\n </SidebarProvider>\n </DialogContent>\n </Dialog>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar14",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"sidebar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar14/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A sidebar on the right.'\n</script>\n\n<script setup lang=\"ts\">\nimport AppSidebar from '@/registry/default/block/Sidebar14/components/AppSidebar.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/registry/default/ui/breadcrumb'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <SidebarInset>\n <header class=\"flex h-16 shrink-0 items-center gap-2 border-b px-4\">\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem class=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator class=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n <SidebarTrigger class=\"-mr-1 ml-auto rotate-180\" />\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n <div class=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div class=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n <AppSidebar side=\"right\" />\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar14/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type {\n SidebarProps,\n} from '@/registry/default/ui/sidebar'\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarRail,\n} from '@/registry/default/ui/sidebar'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n {\n title: 'Community',\n url: '#',\n items: [\n {\n title: 'Contribution Guide',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Table of Contents</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in data.navMain\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\" class=\"font-medium\">\n {{ item.title }}\n </a>\n </SidebarMenuButton>\n <SidebarMenuSub v-if=\"item.items.length\">\n <SidebarMenuSubItem v-for=\"subItem in item.items\" :key=\"subItem.title\">\n <SidebarMenuSubButton\n as-child\n :is-active=\"subItem.isActive\"\n >\n <a :href=\"subItem.url\">{{ subItem.title }}</a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Sidebar15",
|
|
"type": "registry:block",
|
|
"dependencies": [],
|
|
"registryDependencies": [
|
|
"breadcrumb",
|
|
"separator",
|
|
"sidebar",
|
|
"collapsible",
|
|
"calendar",
|
|
"dropdown-menu",
|
|
"avatar"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "block/Sidebar15/page.vue",
|
|
"content": "<script lang=\"ts\">\nexport const iframeHeight = '800px'\nexport const description = 'A left and right sidebar.'\n</script>\n\n<script setup lang=\"ts\">\nimport SidebarLeft from '@/registry/default/block/Sidebar15/components/SidebarLeft.vue'\nimport SidebarRight from '@/registry/default/block/Sidebar15/components/SidebarRight.vue'\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbList,\n BreadcrumbPage,\n} from '@/registry/default/ui/breadcrumb'\nimport { Separator } from '@/registry/default/ui/separator'\nimport {\n SidebarInset,\n SidebarProvider,\n SidebarTrigger,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarProvider>\n <SidebarLeft />\n <SidebarInset>\n <header class=\"sticky top-0 flex h-14 shrink-0 items-center gap-2 bg-background\">\n <div class=\"flex flex-1 items-center gap-2 px-3\">\n <SidebarTrigger />\n <Separator orientation=\"vertical\" class=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbPage class=\"line-clamp-1\">\n Project Management & Task Tracking\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n </header>\n <div class=\"flex flex-1 flex-col gap-4 p-4\">\n <div class=\"mx-auto h-24 w-full max-w-3xl rounded-xl bg-muted/50\" />\n <div class=\"mx-auto h-[100vh] w-full max-w-3xl rounded-xl bg-muted/50\" />\n </div>\n </SidebarInset>\n <SidebarRight />\n </SidebarProvider>\n</template>\n",
|
|
"type": "registry:page",
|
|
"target": "pages/dashboard/index.vue"
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/AppSidebar.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type {\n SidebarProps,\n} from '@/registry/default/ui/sidebar'\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarRail,\n} from '@/registry/default/ui/sidebar'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n navMain: [\n {\n title: 'Getting Started',\n url: '#',\n items: [\n {\n title: 'Installation',\n url: '#',\n },\n {\n title: 'Project Structure',\n url: '#',\n },\n ],\n },\n {\n title: 'Building Your Application',\n url: '#',\n items: [\n {\n title: 'Routing',\n url: '#',\n },\n {\n title: 'Data Fetching',\n url: '#',\n isActive: true,\n },\n {\n title: 'Rendering',\n url: '#',\n },\n {\n title: 'Caching',\n url: '#',\n },\n {\n title: 'Styling',\n url: '#',\n },\n {\n title: 'Optimizing',\n url: '#',\n },\n {\n title: 'Configuring',\n url: '#',\n },\n {\n title: 'Testing',\n url: '#',\n },\n {\n title: 'Authentication',\n url: '#',\n },\n {\n title: 'Deploying',\n url: '#',\n },\n {\n title: 'Upgrading',\n url: '#',\n },\n {\n title: 'Examples',\n url: '#',\n },\n ],\n },\n {\n title: 'API Reference',\n url: '#',\n items: [\n {\n title: 'Components',\n url: '#',\n },\n {\n title: 'File Conventions',\n url: '#',\n },\n {\n title: 'Functions',\n url: '#',\n },\n {\n title: 'next.config.js Options',\n url: '#',\n },\n {\n title: 'CLI',\n url: '#',\n },\n {\n title: 'Edge Runtime',\n url: '#',\n },\n ],\n },\n {\n title: 'Architecture',\n url: '#',\n items: [\n {\n title: 'Accessibility',\n url: '#',\n },\n {\n title: 'Fast Refresh',\n url: '#',\n },\n {\n title: 'Next.js Compiler',\n url: '#',\n },\n {\n title: 'Supported Browsers',\n url: '#',\n },\n {\n title: 'Turbopack',\n url: '#',\n },\n ],\n },\n {\n title: 'Community',\n url: '#',\n items: [\n {\n title: 'Contribution Guide',\n url: '#',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar v-bind=\"props\">\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Table of Contents</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in data.navMain\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\" class=\"font-medium\">\n {{ item.title }}\n </a>\n </SidebarMenuButton>\n <SidebarMenuSub v-if=\"item.items.length\">\n <SidebarMenuSubItem v-for=\"subItem in item.items\" :key=\"subItem.title\">\n <SidebarMenuSubButton\n as-child\n :is-active=\"subItem.isActive\"\n >\n <a :href=\"subItem.url\">{{ subItem.title }}</a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/Calendars.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/default/ui/collapsible'\n\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarSeparator,\n} from '@/registry/default/ui/sidebar'\nimport { Check, ChevronRight } from 'lucide-vue-next'\n\nconst props = defineProps<{\n calendars: {\n name: string\n items: string[]\n }[]\n}>()\n</script>\n\n<template>\n <template v-for=\"(calendar, index) in calendars\" :key=\"calendar.name\">\n <SidebarGroup class=\"py-0\">\n <Collapsible\n :default-open=\"index === 0\"\n class=\"group/collapsible\"\n >\n <SidebarGroupLabel\n as-child\n class=\"group/label w-full text-sm text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\"\n >\n <CollapsibleTrigger>\n {{ calendar.name }}\n <ChevronRight class=\"ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90\" />\n </CollapsibleTrigger>\n </SidebarGroupLabel>\n <CollapsibleContent>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"(item, index) in calendar.items\" :key=\"item\">\n <SidebarMenuButton>\n <div\n :data-active=\"index < 2\"\n class=\"group/calendar-item flex aspect-square size-4 shrink-0 items-center justify-center rounded-sm border border-sidebar-border text-sidebar-primary-foreground data-[active=true]:border-sidebar-primary data-[active=true]:bg-sidebar-primary\"\n >\n <Check class=\"hidden size-3 group-data-[active=true]/calendar-item:block\" />\n </div>\n {{ item }}\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </CollapsibleContent>\n </Collapsible>\n </SidebarGroup>\n <SidebarSeparator class=\"mx-0\" />\n </template>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/DatePicker.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport { Calendar } from '@/registry/default/ui/calendar'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n} from '@/registry/default/ui/sidebar'\n</script>\n\n<template>\n <SidebarGroup class=\"px-0\">\n <SidebarGroupContent>\n <Calendar class=\"[&_[role=gridcell].bg-accent]:bg-sidebar-primary [&_[role=gridcell].bg-accent]:text-sidebar-primary-foreground [&_[role=gridcell]]:w-[33px]\" />\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/NavFavorites.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\n\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/default/ui/sidebar'\nimport {\n ArrowUpRight,\n Link,\n MoreHorizontal,\n StarOff,\n Trash2,\n} from 'lucide-vue-next'\n\ndefineProps<{\n favorites: {\n name: string\n url: string\n emoji: string\n }[]\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarGroup class=\"group-data-[collapsible=icon]:hidden\">\n <SidebarGroupLabel>Favorites</SidebarGroupLabel>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in favorites\" :key=\"item.name\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\" :title=\"item.name\">\n <span>{{ item.emoji }}</span>\n <span>{{ item.name }}</span>\n </a>\n </SidebarMenuButton>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuAction show-on-hover>\n <MoreHorizontal />\n <span class=\"sr-only\">More</span>\n </SidebarMenuAction>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n :align=\"isMobile ? 'end' : 'start'\"\n >\n <DropdownMenuItem>\n <StarOff class=\"text-muted-foreground\" />\n <span>Remove from Favorites</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Link class=\"text-muted-foreground\" />\n <span>Copy Link</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <ArrowUpRight class=\"text-muted-foreground\" />\n <span>Open in New Tab</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Trash2 class=\"text-muted-foreground\" />\n <span>Delete</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n\n <SidebarMenuItem>\n <SidebarMenuButton class=\"text-sidebar-foreground/70\">\n <MoreHorizontal />\n <span>More</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/NavMain.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { LucideIcon } from 'lucide-vue-next'\n\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/default/ui/sidebar'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon: LucideIcon\n isActive?: boolean\n }[]\n}>()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuButton as-child :is-active=\"item.isActive\">\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/NavSecondary.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport type { LucideIcon } from 'lucide-vue-next'\n\nimport type { Component } from 'vue'\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/default/ui/sidebar'\n\ndefineProps<{\n items: {\n title: string\n url: string\n icon: LucideIcon\n badge?: Component\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem v-for=\"item in items\" :key=\"item.title\">\n <SidebarMenuButton as-child>\n <a :href=\"item.url\">\n <component :is=\"item.icon\" />\n <span>{{ item.title }}</span>\n </a>\n </SidebarMenuButton>\n <SidebarMenuBadge v-if=\"item.badge\">\n <component :is=\"item.badge\" />\n </SidebarMenuBadge>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/NavUser.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/registry/default/ui/avatar'\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/registry/default/ui/sidebar'\nimport {\n BadgeCheck,\n Bell,\n ChevronsUpDown,\n CreditCard,\n LogOut,\n Sparkles,\n} from 'lucide-vue-next'\n\nconst props = defineProps<{\n user: {\n name: string\n email: string\n avatar: string\n }\n}>()\n\nconst { isMobile } = useSidebar()\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton\n size=\"lg\"\n class=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n <ChevronsUpDown class=\"ml-auto size-4\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-[--reka-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n :side=\"isMobile ? 'bottom' : 'right'\"\n align=\"start\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"p-0 font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar class=\"h-8 w-8 rounded-lg\">\n <AvatarImage :src=\"user.avatar\" :alt=\"user.name\" />\n <AvatarFallback class=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-semibold\">{{ user.name }}</span>\n <span class=\"truncate text-xs\">{{ user.email }}</span>\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <Sparkles />\n Upgrade to Pro\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <BadgeCheck />\n Account\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CreditCard />\n Billing\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Bell />\n Notifications\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut />\n Log out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/NavWorkspaces.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/registry/default/ui/collapsible'\n\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n} from '@/registry/default/ui/sidebar'\nimport { ChevronRight, MoreHorizontal, Plus } from 'lucide-vue-next'\n\ndefineProps<{\n workspaces: {\n name: string\n emoji: string\n pages: {\n name: string\n emoji: string\n }[]\n }[]\n}>()\n</script>\n\n<template>\n <SidebarGroup>\n <SidebarGroupLabel>Workspaces</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n <Collapsible v-for=\"workspace in workspaces\" :key=\"workspace.name\">\n <SidebarMenuItem>\n <SidebarMenuButton as-child>\n <a href=\"#\">\n <span>{{ workspace.emoji }}</span>\n <span>{{ workspace.name }}</span>\n </a>\n </SidebarMenuButton>\n <CollapsibleTrigger as-child>\n <SidebarMenuAction\n class=\"left-2 bg-sidebar-accent text-sidebar-accent-foreground data-[state=open]:rotate-90\"\n show-on-hover\n >\n <ChevronRight />\n </SidebarMenuAction>\n </CollapsibleTrigger>\n <SidebarMenuAction show-on-hover>\n <Plus />\n </SidebarMenuAction>\n <CollapsibleContent>\n <SidebarMenuSub>\n <SidebarMenuSubItem v-for=\"page in workspace.pages\" :key=\"page.name\">\n <SidebarMenuSubButton as-child>\n <a href=\"#\">\n <span>{{ page.emoji }}</span>\n <span>{{ page.name }}</span>\n </a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n\n <SidebarMenuItem>\n <SidebarMenuButton class=\"text-sidebar-foreground/70\">\n <MoreHorizontal />\n <span>More</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/SidebarLeft.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport NavFavorites from '@/registry/default/block/Sidebar15/components/NavFavorites.vue'\n\nimport NavMain from '@/registry/default/block/Sidebar15/components/NavMain.vue'\nimport NavSecondary from '@/registry/default/block/Sidebar15/components/NavSecondary.vue'\nimport NavWorkspaces from '@/registry/default/block/Sidebar15/components/NavWorkspaces.vue'\nimport TeamSwitcher from '@/registry/default/block/Sidebar15/components/TeamSwitcher.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarHeader,\n type SidebarProps,\n SidebarRail,\n} from '@/registry/default/ui/sidebar'\nimport {\n AudioWaveform,\n Blocks,\n Calendar,\n Command,\n Home,\n Inbox,\n MessageCircleQuestion,\n Search,\n Settings2,\n Sparkles,\n Trash2,\n} from 'lucide-vue-next'\n\nconst props = defineProps<SidebarProps>()\n\n// This is sample data.\nconst data = {\n teams: [\n {\n name: 'Acme Inc',\n logo: Command,\n plan: 'Enterprise',\n },\n {\n name: 'Acme Corp.',\n logo: AudioWaveform,\n plan: 'Startup',\n },\n {\n name: 'Evil Corp.',\n logo: Command,\n plan: 'Free',\n },\n ],\n navMain: [\n {\n title: 'Search',\n url: '#',\n icon: Search,\n },\n {\n title: 'Ask AI',\n url: '#',\n icon: Sparkles,\n },\n {\n title: 'Home',\n url: '#',\n icon: Home,\n isActive: true,\n },\n {\n title: 'Inbox',\n url: '#',\n icon: Inbox,\n badge: '10',\n },\n ],\n navSecondary: [\n {\n title: 'Calendar',\n url: '#',\n icon: Calendar,\n },\n {\n title: 'Settings',\n url: '#',\n icon: Settings2,\n },\n {\n title: 'Templates',\n url: '#',\n icon: Blocks,\n },\n {\n title: 'Trash',\n url: '#',\n icon: Trash2,\n },\n {\n title: 'Help',\n url: '#',\n icon: MessageCircleQuestion,\n },\n ],\n favorites: [\n {\n name: 'Project Management & Task Tracking',\n url: '#',\n emoji: '📊',\n },\n {\n name: 'Family Recipe Collection & Meal Planning',\n url: '#',\n emoji: '🍳',\n },\n {\n name: 'Fitness Tracker & Workout Routines',\n url: '#',\n emoji: '💪',\n },\n {\n name: 'Book Notes & Reading List',\n url: '#',\n emoji: '📚',\n },\n {\n name: 'Sustainable Gardening Tips & Plant Care',\n url: '#',\n emoji: '🌱',\n },\n {\n name: 'Language Learning Progress & Resources',\n url: '#',\n emoji: '🗣️',\n },\n {\n name: 'Home Renovation Ideas & Budget Tracker',\n url: '#',\n emoji: '🏠',\n },\n {\n name: 'Personal Finance & Investment Portfolio',\n url: '#',\n emoji: '💰',\n },\n {\n name: 'Movie & TV Show Watchlist with Reviews',\n url: '#',\n emoji: '🎬',\n },\n {\n name: 'Daily Habit Tracker & Goal Setting',\n url: '#',\n emoji: '✅',\n },\n ],\n workspaces: [\n {\n name: 'Personal Life Management',\n emoji: '🏠',\n pages: [\n {\n name: 'Daily Journal & Reflection',\n url: '#',\n emoji: '📔',\n },\n {\n name: 'Health & Wellness Tracker',\n url: '#',\n emoji: '🍏',\n },\n {\n name: 'Personal Growth & Learning Goals',\n url: '#',\n emoji: '🌟',\n },\n ],\n },\n {\n name: 'Professional Development',\n emoji: '💼',\n pages: [\n {\n name: 'Career Objectives & Milestones',\n url: '#',\n emoji: '🎯',\n },\n {\n name: 'Skill Acquisition & Training Log',\n url: '#',\n emoji: '🧠',\n },\n {\n name: 'Networking Contacts & Events',\n url: '#',\n emoji: '🤝',\n },\n ],\n },\n {\n name: 'Creative Projects',\n emoji: '🎨',\n pages: [\n {\n name: 'Writing Ideas & Story Outlines',\n url: '#',\n emoji: '✍️',\n },\n {\n name: 'Art & Design Portfolio',\n url: '#',\n emoji: '🖼️',\n },\n {\n name: 'Music Composition & Practice Log',\n url: '#',\n emoji: '🎵',\n },\n ],\n },\n {\n name: 'Home Management',\n emoji: '🏡',\n pages: [\n {\n name: 'Household Budget & Expense Tracking',\n url: '#',\n emoji: '💰',\n },\n {\n name: 'Home Maintenance Schedule & Tasks',\n url: '#',\n emoji: '🔧',\n },\n {\n name: 'Family Calendar & Event Planning',\n url: '#',\n emoji: '📅',\n },\n ],\n },\n {\n name: 'Travel & Adventure',\n emoji: '🧳',\n pages: [\n {\n name: 'Trip Planning & Itineraries',\n url: '#',\n emoji: '🗺️',\n },\n {\n name: 'Travel Bucket List & Inspiration',\n url: '#',\n emoji: '🌎',\n },\n {\n name: 'Travel Journal & Photo Gallery',\n url: '#',\n emoji: '📸',\n },\n ],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar class=\"border-r-0\" v-bind=\"props\">\n <SidebarHeader>\n <TeamSwitcher :teams=\"data.teams\" />\n <NavMain :items=\"data.navMain\" />\n </SidebarHeader>\n <SidebarContent>\n <NavFavorites :favorites=\"data.favorites\" />\n <NavWorkspaces :workspaces=\"data.workspaces\" />\n <NavSecondary :items=\"data.navSecondary\" class=\"mt-auto\" />\n </SidebarContent>\n <SidebarRail />\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/SidebarRight.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport Calendars from '@/registry/default/block/Sidebar15/components/Calendars.vue'\n\nimport DatePicker from '@/registry/default/block/Sidebar15/components/DatePicker.vue'\nimport NavUser from '@/registry/default/block/Sidebar15/components/NavUser.vue'\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n type SidebarProps,\n SidebarSeparator,\n} from '@/registry/default/ui/sidebar'\nimport { Plus } from 'lucide-vue-next'\n\nconst props = withDefaults(defineProps<SidebarProps>(), {\n collapsible: 'none',\n})\n\n// This is sample data.\nconst data = {\n user: {\n name: 'shadcn',\n email: 'm@example.com',\n avatar: '/avatars/shadcn.jpg',\n },\n calendars: [\n {\n name: 'My Calendars',\n items: ['Personal', 'Work', 'Family'],\n },\n {\n name: 'Favorites',\n items: ['Holidays', 'Birthdays'],\n },\n {\n name: 'Other',\n items: ['Travel', 'Reminders', 'Deadlines'],\n },\n ],\n}\n</script>\n\n<template>\n <Sidebar\n class=\"sticky hidden lg:flex top-0 h-svh border-l\"\n v-bind=\"props\"\n >\n <SidebarHeader class=\"h-16 border-b border-sidebar-border\">\n <NavUser :user=\"data.user\" />\n </SidebarHeader>\n <SidebarContent>\n <DatePicker />\n <SidebarSeparator class=\"mx-0\" />\n <Calendars :calendars=\"data.calendars\" />\n </SidebarContent>\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton>\n <Plus />\n <span>New Calendar</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n </Sidebar>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
},
|
|
{
|
|
"path": "block/Sidebar15/components/TeamSwitcher.vue",
|
|
"content": "<script setup lang=\"ts\">\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuTrigger,\n} from '@/registry/default/ui/dropdown-menu'\n\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/registry/default/ui/sidebar'\nimport { ChevronDown, Plus } from 'lucide-vue-next'\n\nimport { type Component, ref } from 'vue'\n\nconst props = defineProps<{\n teams: {\n name: string\n logo: Component\n plan: string\n }[]\n}>()\n\nconst activeTeam = ref(props.teams[0])\n</script>\n\n<template>\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger as-child>\n <SidebarMenuButton class=\"w-fit px-1.5\">\n <div class=\"flex aspect-square size-5 items-center justify-center rounded-md bg-sidebar-primary text-sidebar-primary-foreground\">\n <component :is=\"activeTeam.logo\" class=\"size-3\" />\n </div>\n <span class=\"truncate font-semibold\">{{ activeTeam.name }}</span>\n <ChevronDown class=\"opacity-50\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n class=\"w-64 rounded-lg\"\n align=\"start\"\n side=\"bottom\"\n :side-offset=\"4\"\n >\n <DropdownMenuLabel class=\"text-xs text-muted-foreground\">\n Teams\n </DropdownMenuLabel>\n\n <DropdownMenuItem\n v-for=\"(team, index) in teams\"\n :key=\"team.name\"\n class=\"gap-2 p-2\"\n @click=\"activeTeam = team\"\n >\n <div class=\"flex size-6 items-center justify-center rounded-sm border\">\n <component :is=\"team.logo\" class=\"size-4 shrink-0\" />\n </div>\n {{ team.name }}\n <DropdownMenuShortcut>⌘{{ index + 1 }}</DropdownMenuShortcut>\n </DropdownMenuItem>\n\n <DropdownMenuSeparator />\n <DropdownMenuItem class=\"gap-2 p-2\">\n <div class=\"flex size-6 items-center justify-center rounded-md border bg-background\">\n <Plus class=\"size-4\" />\n </div>\n <div class=\"font-medium text-muted-foreground\">\n Add team\n </div>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n</template>\n",
|
|
"type": "registry:component",
|
|
"target": ""
|
|
}
|
|
]
|
|
}
|
|
]
|