Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47f53cb985 | ||
| 1e1f335853 | |||
| 32d6b8b397 | |||
|
|
3eaef4a748 | ||
|
|
5b1f952e0a | ||
|
|
693b0d2a08 | ||
|
|
8a24d11a65 | ||
|
|
e4fea78b33 | ||
|
|
5869165a84 | ||
|
|
857f10de51 | ||
|
|
5ada562803 |
|
|
@ -1,7 +1,7 @@
|
|||
<p align="center">
|
||||
<img align="center" src="https://raw.githubusercontent.com/radix-vue/shadcn-vue/dev/apps/www/src/public/android-chrome-192x192.png" height="96" />
|
||||
<h1 align="center">
|
||||
shadcn-vue
|
||||
shadcn-vue by Niklas Hermanns
|
||||
</h1>
|
||||
</p>
|
||||
|
||||
|
|
@ -31,3 +31,7 @@ All credits go to these open-source works and resources
|
|||
## License
|
||||
|
||||
Licensed under the [MIT license](https://github.com/shadcn/ui/blob/main/LICENSE.md).
|
||||
|
||||
## Actions
|
||||
|
||||
- Test
|
||||
|
|
@ -209,7 +209,7 @@ watch(() => $route.path, (n) => {
|
|||
<span class="inline-block ml-2">
|
||||
Ported to Vue by
|
||||
<a
|
||||
href="https://github.com/radix-vue"
|
||||
href="https://github.com/unovue"
|
||||
target="_blank"
|
||||
class="underline underline-offset-4 font-bold decoration-foreground"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -403,6 +403,7 @@ By passing the `form` as props, you can control and use the method provided by `
|
|||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { AutoForm } from '@/components/ui/auto-form'
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
import { useForm } from 'vee-validate'
|
||||
import * as z from 'zod'
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ const value = ref('')
|
|||
<CommandItem
|
||||
v-for="framework in frameworks"
|
||||
:key="framework.value"
|
||||
:value="framework"
|
||||
:value="framework.value"
|
||||
@select="open = false"
|
||||
>
|
||||
<Check
|
||||
|
|
|
|||
|
|
@ -44,12 +44,9 @@ Install `tailwindcss` and its peer dependencies, then generate your `tailwind.co
|
|||
|
||||
#### `vite.config`
|
||||
|
||||
```typescript {3,4,11-15}
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
|
||||
```typescript {2,3,8-12}
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import autoprefixer from 'autoprefixer'
|
||||
|
||||
import tailwind from 'tailwindcss'
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
|
|
@ -60,14 +57,7 @@ export default defineConfig({
|
|||
plugins: [tailwind(), autoprefixer()],
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
vue(),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
}
|
||||
}
|
||||
plugins: [vue()],
|
||||
})
|
||||
```
|
||||
|
||||
|
|
@ -125,12 +115,10 @@ Add the code below to the vite.config.ts so your app can resolve paths without e
|
|||
npm i -D @types/node
|
||||
```
|
||||
|
||||
```typescript {20-22}
|
||||
```typescript {1,15-19}
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import autoprefixer from 'autoprefixer'
|
||||
|
||||
import tailwind from 'tailwindcss'
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
|
|
@ -141,9 +129,7 @@ export default defineConfig({
|
|||
plugins: [tailwind(), autoprefixer()],
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
vue(),
|
||||
],
|
||||
plugins: [vue()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ const itemsToDisplay = 3
|
|||
const firstLabel = computed(() => items.value[0]?.label)
|
||||
|
||||
const allButLastTwoItems = computed(() => items.value.slice(1, -2))
|
||||
const remainingItems = computed(() => items.value.slice(-itemsToDisplay + 1))
|
||||
const remainingItems = computed(() => items.value.slice(-Math.min(itemsToDisplay, items.value.length) + 1))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import Sheet from '@/lib/registry/default/ui/sheet/Sheet.vue'
|
||||
import SheetContent from '@/lib/registry/default/ui/sheet/SheetContent.vue'
|
||||
import type { SidebarProps } from '.'
|
||||
import { Sheet, SheetContent } from '@/lib/registry/default/ui/sheet'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils'
|
||||
|
||||
|
|
@ -9,12 +8,7 @@ defineOptions({
|
|||
inheritAttrs: false,
|
||||
})
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
side?: 'left' | 'right'
|
||||
variant?: 'sidebar' | 'floating' | 'inset'
|
||||
collapsible?: 'offcanvas' | 'icon' | 'none'
|
||||
class?: HTMLAttributes['class']
|
||||
}>(), {
|
||||
const props = withDefaults(defineProps<SidebarProps>(), {
|
||||
side: 'left',
|
||||
variant: 'sidebar',
|
||||
collapsible: 'offcanvas',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import Input from '@/lib/registry/default/ui/input/Input.vue'
|
||||
import { Input } from '@/lib/registry/default/ui/input'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import Tooltip from '@/lib/registry/default/ui/tooltip/Tooltip.vue'
|
||||
import TooltipContent from '@/lib/registry/default/ui/tooltip/TooltipContent.vue'
|
||||
import TooltipTrigger from '@/lib/registry/default/ui/tooltip/TooltipTrigger.vue'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/default/ui/tooltip'
|
||||
import { type Component, computed } from 'vue'
|
||||
import SidebarMenuButtonChild, { type SidebarMenuButtonProps } from './SidebarMenuButtonChild.vue'
|
||||
import { useSidebar } from './utils'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import Skeleton from '@/lib/registry/default/ui/skeleton/Skeleton.vue'
|
||||
import { Skeleton } from '@/lib/registry/default/ui/skeleton'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { computed, type HTMLAttributes } from 'vue'
|
||||
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ provideSidebarContext({
|
|||
'--sidebar-width-icon': SIDEBAR_WIDTH_ICON,
|
||||
}"
|
||||
:class="cn('group/sidebar-wrapper flex min-h-svh w-full text-sidebar-foreground has-[[data-variant=inset]]:bg-sidebar', props.class)"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import Separator from '@/lib/registry/default/ui/separator/Separator.vue'
|
||||
import { Separator } from '@/lib/registry/default/ui/separator'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import Button from '@/lib/registry/default/ui/button/Button.vue'
|
||||
import { Button } from '@/lib/registry/default/ui/button'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { PanelLeft } from 'lucide-vue-next'
|
||||
import { useSidebar } from './utils'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,13 @@
|
|||
import type { HTMLAttributes } from 'vue'
|
||||
import { cva, type VariantProps } from 'class-variance-authority'
|
||||
|
||||
export interface SidebarProps {
|
||||
side?: 'left' | 'right'
|
||||
variant?: 'sidebar' | 'floating' | 'inset'
|
||||
collapsible?: 'offcanvas' | 'icon' | 'none'
|
||||
class?: HTMLAttributes['class']
|
||||
}
|
||||
|
||||
export { default as Sidebar } from './Sidebar.vue'
|
||||
export { default as SidebarContent } from './SidebarContent.vue'
|
||||
export { default as SidebarFooter } from './SidebarFooter.vue'
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ const itemsToDisplay = 3
|
|||
const firstLabel = computed(() => items.value[0]?.label)
|
||||
|
||||
const allButLastTwoItems = computed(() => items.value.slice(1, -2))
|
||||
const remainingItems = computed(() => items.value.slice(-itemsToDisplay + 1))
|
||||
const remainingItems = computed(() => items.value.slice(-Math.min(itemsToDisplay, items.value.length) + 1))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import Sheet from '@/lib/registry/new-york/ui/sheet/Sheet.vue'
|
||||
import SheetContent from '@/lib/registry/new-york/ui/sheet/SheetContent.vue'
|
||||
import type { SidebarProps } from '.'
|
||||
import { Sheet, SheetContent } from '@/lib/registry/new-york/ui/sheet'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils'
|
||||
|
||||
|
|
@ -9,12 +8,7 @@ defineOptions({
|
|||
inheritAttrs: false,
|
||||
})
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
side?: 'left' | 'right'
|
||||
variant?: 'sidebar' | 'floating' | 'inset'
|
||||
collapsible?: 'offcanvas' | 'icon' | 'none'
|
||||
class?: HTMLAttributes['class']
|
||||
}>(), {
|
||||
const props = withDefaults(defineProps<SidebarProps>(), {
|
||||
side: 'left',
|
||||
variant: 'sidebar',
|
||||
collapsible: 'offcanvas',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import Input from '@/lib/registry/new-york/ui/input/Input.vue'
|
||||
import { Input } from '@/lib/registry/new-york/ui/input'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import Tooltip from '@/lib/registry/new-york/ui/tooltip/Tooltip.vue'
|
||||
import TooltipContent from '@/lib/registry/new-york/ui/tooltip/TooltipContent.vue'
|
||||
import TooltipTrigger from '@/lib/registry/new-york/ui/tooltip/TooltipTrigger.vue'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/registry/new-york/ui/tooltip'
|
||||
import { type Component, computed } from 'vue'
|
||||
import SidebarMenuButtonChild, { type SidebarMenuButtonProps } from './SidebarMenuButtonChild.vue'
|
||||
import { useSidebar } from './utils'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import Skeleton from '@/lib/registry/new-york/ui/skeleton/Skeleton.vue'
|
||||
import { Skeleton } from '@/lib/registry/new-york/ui/skeleton'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { computed, type HTMLAttributes } from 'vue'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useEventListener, useVModel } from '@vueuse/core'
|
||||
import { useEventListener, useMediaQuery, useVModel } from '@vueuse/core'
|
||||
import { TooltipProvider } from 'radix-vue'
|
||||
import { computed, type HTMLAttributes, type Ref, ref } from 'vue'
|
||||
import { provideSidebarContext, SIDEBAR_COOKIE_MAX_AGE, SIDEBAR_COOKIE_NAME, SIDEBAR_KEYBOARD_SHORTCUT, SIDEBAR_WIDTH, SIDEBAR_WIDTH_ICON } from './utils'
|
||||
|
|
@ -72,6 +72,7 @@ provideSidebarContext({
|
|||
'--sidebar-width-icon': SIDEBAR_WIDTH_ICON,
|
||||
}"
|
||||
:class="cn('group/sidebar-wrapper flex min-h-svh w-full text-sidebar-foreground has-[[data-variant=inset]]:bg-sidebar', props.class)"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import Separator from '@/lib/registry/new-york/ui/separator/Separator.vue'
|
||||
import { Separator } from '@/lib/registry/new-york/ui/separator'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import Button from '@/lib/registry/new-york/ui/button/Button.vue'
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { PanelLeft } from 'lucide-vue-next'
|
||||
import { useSidebar } from './utils'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,13 @@
|
|||
import type { HTMLAttributes } from 'vue'
|
||||
import { cva, type VariantProps } from 'class-variance-authority'
|
||||
|
||||
export interface SidebarProps {
|
||||
side?: 'left' | 'right'
|
||||
variant?: 'sidebar' | 'floating' | 'inset'
|
||||
collapsible?: 'offcanvas' | 'icon' | 'none'
|
||||
class?: HTMLAttributes['class']
|
||||
}
|
||||
|
||||
export { default as Sidebar } from './Sidebar.vue'
|
||||
export { default as SidebarContent } from './SidebarContent.vue'
|
||||
export { default as SidebarFooter } from './SidebarFooter.vue'
|
||||
|
|
|
|||
|
|
@ -749,16 +749,13 @@
|
|||
"@vueuse/core"
|
||||
],
|
||||
"registryDependencies": [
|
||||
"Sheet.vue",
|
||||
"SheetContent.vue",
|
||||
"sheet",
|
||||
"utils",
|
||||
"Input.vue",
|
||||
"Tooltip.vue",
|
||||
"TooltipContent.vue",
|
||||
"TooltipTrigger.vue",
|
||||
"Skeleton.vue",
|
||||
"Separator.vue",
|
||||
"Button.vue"
|
||||
"input",
|
||||
"tooltip",
|
||||
"skeleton",
|
||||
"separator",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
"ui/sidebar/Sidebar.vue",
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
},
|
||||
{
|
||||
"name": "constant.ts",
|
||||
"content": "import 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 = {\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"
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"name": "dependencies.ts",
|
||||
|
|
@ -80,7 +80,7 @@
|
|||
},
|
||||
{
|
||||
"name": "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 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"
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"name": "utils.ts",
|
||||
|
|
|
|||
|
|
@ -4,21 +4,18 @@
|
|||
"@vueuse/core"
|
||||
],
|
||||
"registryDependencies": [
|
||||
"Sheet.vue",
|
||||
"SheetContent.vue",
|
||||
"sheet",
|
||||
"utils",
|
||||
"Input.vue",
|
||||
"Tooltip.vue",
|
||||
"TooltipContent.vue",
|
||||
"TooltipTrigger.vue",
|
||||
"Skeleton.vue",
|
||||
"Separator.vue",
|
||||
"Button.vue"
|
||||
"input",
|
||||
"tooltip",
|
||||
"skeleton",
|
||||
"separator",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"name": "Sidebar.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Sheet from '@/lib/registry/default/ui/sheet/Sheet.vue'\nimport SheetContent from '@/lib/registry/default/ui/sheet/SheetContent.vue'\nimport { cn } from '@/lib/utils'\nimport { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n side?: 'left' | 'right'\n variant?: 'sidebar' | 'floating' | 'inset'\n collapsible?: 'offcanvas' | 'icon' | 'none'\n class?: HTMLAttributes['class']\n}>(), {\n side: 'left',\n variant: 'sidebar',\n collapsible: 'offcanvas',\n})\n\nconst { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n</script>\n\n<template>\n <div\n v-if=\"collapsible === 'none'\"\n :class=\"cn('flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground', props.class)\"\n v-bind=\"$attrs\"\n >\n <slot />\n </div>\n\n <Sheet v-else-if=\"isMobile\" :open=\"openMobile\" v-bind=\"$attrs\" @update:open=\"setOpenMobile\">\n <SheetContent\n data-sidebar=\"sidebar\"\n data-mobile=\"true\"\n :side=\"side\"\n class=\"w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH_MOBILE,\n }\"\n >\n <div class=\"flex h-full w-full flex-col\">\n <slot />\n </div>\n </SheetContent>\n </Sheet>\n\n <div\n v-else class=\"group peer hidden md:block\"\n :data-state=\"state\"\n :data-collapsible=\"state === 'collapsed' ? collapsible : ''\"\n :data-variant=\"variant\"\n :data-side=\"side\"\n >\n <!-- This is what handles the sidebar gap on desktop -->\n <div\n :class=\"cn(\n 'duration-200 relative h-svh w-[--sidebar-width] bg-transparent transition-[width] ease-linear',\n 'group-data-[collapsible=offcanvas]:w-0',\n 'group-data-[side=right]:rotate-180',\n variant === 'floating' || variant === 'inset'\n ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]',\n )\"\n />\n <div\n :class=\"cn(\n 'duration-200 fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] ease-linear md:flex',\n side === 'left'\n ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'\n : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',\n // Adjust the padding for floating and inset variants.\n variant === 'floating' || variant === 'inset'\n ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l',\n props.class,\n )\"\n v-bind=\"$attrs\"\n >\n <div\n data-sidebar=\"sidebar\"\n class=\"flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow\"\n >\n <slot />\n </div>\n </div>\n </div>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport type { SidebarProps } from '.'\nimport { Sheet, SheetContent } from '@/lib/registry/default/ui/sheet'\nimport { cn } from '@/lib/utils'\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"
|
||||
},
|
||||
{
|
||||
"name": "SidebarContent.vue",
|
||||
|
|
@ -50,7 +47,7 @@
|
|||
},
|
||||
{
|
||||
"name": "SidebarInput.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Input from '@/lib/registry/default/ui/input/Input.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Input\n data-sidebar=\"input\"\n :class=\"cn(\n 'h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring',\n props.class,\n )\"\n >\n <slot />\n </Input>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { Input } from '@/lib/registry/default/ui/input'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Input\n data-sidebar=\"input\"\n :class=\"cn(\n 'h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring',\n props.class,\n )\"\n >\n <slot />\n </Input>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "SidebarInset.vue",
|
||||
|
|
@ -70,7 +67,7 @@
|
|||
},
|
||||
{
|
||||
"name": "SidebarMenuButton.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport Tooltip from '@/lib/registry/default/ui/tooltip/Tooltip.vue'\nimport TooltipContent from '@/lib/registry/default/ui/tooltip/TooltipContent.vue'\nimport TooltipTrigger from '@/lib/registry/default/ui/tooltip/TooltipTrigger.vue'\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"
|
||||
"content": "<script setup lang=\"ts\">\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/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"
|
||||
},
|
||||
{
|
||||
"name": "SidebarMenuButtonChild.vue",
|
||||
|
|
@ -82,7 +79,7 @@
|
|||
},
|
||||
{
|
||||
"name": "SidebarMenuSkeleton.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport Skeleton from '@/lib/registry/default/ui/skeleton/Skeleton.vue'\nimport { cn } from '@/lib/utils'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n showIcon?: boolean\n class?: HTMLAttributes['class']\n}>()\n\nconst width = computed(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n})\n</script>\n\n<template>\n <div\n data-sidebar=\"menu-skeleton\"\n :class=\"cn('rounded-md h-8 flex gap-2 px-2 items-center', props.class)\"\n >\n <Skeleton\n v-if=\"showIcon\"\n class=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n\n <Skeleton\n class=\"h-4 flex-1 max-w-[--skeleton-width]\"\n data-sidebar=\"menu-skeleton-text\"\n :style=\"{ '--skeleton-width': width }\"\n />\n </div>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport { Skeleton } from '@/lib/registry/default/ui/skeleton'\nimport { cn } from '@/lib/utils'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n showIcon?: boolean\n class?: HTMLAttributes['class']\n}>()\n\nconst width = computed(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n})\n</script>\n\n<template>\n <div\n data-sidebar=\"menu-skeleton\"\n :class=\"cn('rounded-md h-8 flex gap-2 px-2 items-center', props.class)\"\n >\n <Skeleton\n v-if=\"showIcon\"\n class=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n\n <Skeleton\n class=\"h-4 flex-1 max-w-[--skeleton-width]\"\n data-sidebar=\"menu-skeleton-text\"\n :style=\"{ '--skeleton-width': width }\"\n />\n </div>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "SidebarMenuSub.vue",
|
||||
|
|
@ -98,7 +95,7 @@
|
|||
},
|
||||
{
|
||||
"name": "SidebarProvider.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { useEventListener, useMediaQuery, useVModel } from '@vueuse/core'\nimport { TooltipProvider } from 'radix-vue'\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 >\n <slot />\n </div>\n </TooltipProvider>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { useEventListener, useMediaQuery, useVModel } from '@vueuse/core'\nimport { TooltipProvider } from 'radix-vue'\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"
|
||||
},
|
||||
{
|
||||
"name": "SidebarRail.vue",
|
||||
|
|
@ -106,15 +103,15 @@
|
|||
},
|
||||
{
|
||||
"name": "SidebarSeparator.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Separator from '@/lib/registry/default/ui/separator/Separator.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Separator\n data-sidebar=\"separator\"\n :class=\"cn('mx-2 w-auto bg-sidebar-border', props.class)\"\n >\n <slot />\n </Separator>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { Separator } from '@/lib/registry/default/ui/separator'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Separator\n data-sidebar=\"separator\"\n :class=\"cn('mx-2 w-auto bg-sidebar-border', props.class)\"\n >\n <slot />\n </Separator>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "SidebarTrigger.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Button from '@/lib/registry/default/ui/button/Button.vue'\nimport { cn } from '@/lib/utils'\nimport { PanelLeft } from 'lucide-vue-next'\nimport { useSidebar } from './utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst { toggleSidebar } = useSidebar()\n</script>\n\n<template>\n <Button\n data-sidebar=\"trigger\"\n variant=\"ghost\"\n size=\"icon\"\n :class=\"cn('h-7 w-7', props.class)\"\n @click=\"toggleSidebar\"\n >\n <PanelLeft />\n <span class=\"sr-only\">Toggle Sidebar</span>\n </Button>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { Button } from '@/lib/registry/default/ui/button'\nimport { cn } from '@/lib/utils'\nimport { PanelLeft } from 'lucide-vue-next'\nimport { useSidebar } from './utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst { toggleSidebar } = useSidebar()\n</script>\n\n<template>\n <Button\n data-sidebar=\"trigger\"\n variant=\"ghost\"\n size=\"icon\"\n :class=\"cn('h-7 w-7', props.class)\"\n @click=\"toggleSidebar\"\n >\n <PanelLeft />\n <span class=\"sr-only\">Toggle Sidebar</span>\n </Button>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "index.ts",
|
||||
"content": "import { cva, type VariantProps } from 'class-variance-authority'\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"
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"name": "utils.ts",
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
},
|
||||
{
|
||||
"name": "constant.ts",
|
||||
"content": "import 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 = {\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"
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"name": "dependencies.ts",
|
||||
|
|
@ -80,7 +80,7 @@
|
|||
},
|
||||
{
|
||||
"name": "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 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"
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"name": "utils.ts",
|
||||
|
|
|
|||
|
|
@ -4,21 +4,18 @@
|
|||
"@vueuse/core"
|
||||
],
|
||||
"registryDependencies": [
|
||||
"Sheet.vue",
|
||||
"SheetContent.vue",
|
||||
"sheet",
|
||||
"utils",
|
||||
"Input.vue",
|
||||
"Tooltip.vue",
|
||||
"TooltipContent.vue",
|
||||
"TooltipTrigger.vue",
|
||||
"Skeleton.vue",
|
||||
"Separator.vue",
|
||||
"Button.vue"
|
||||
"input",
|
||||
"tooltip",
|
||||
"skeleton",
|
||||
"separator",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"name": "Sidebar.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Sheet from '@/lib/registry/new-york/ui/sheet/Sheet.vue'\nimport SheetContent from '@/lib/registry/new-york/ui/sheet/SheetContent.vue'\nimport { cn } from '@/lib/utils'\nimport { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n side?: 'left' | 'right'\n variant?: 'sidebar' | 'floating' | 'inset'\n collapsible?: 'offcanvas' | 'icon' | 'none'\n class?: HTMLAttributes['class']\n}>(), {\n side: 'left',\n variant: 'sidebar',\n collapsible: 'offcanvas',\n})\n\nconst { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n</script>\n\n<template>\n <div\n v-if=\"collapsible === 'none'\"\n :class=\"cn('flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground', props.class)\"\n v-bind=\"$attrs\"\n >\n <slot />\n </div>\n\n <Sheet v-else-if=\"isMobile\" :open=\"openMobile\" v-bind=\"$attrs\" @update:open=\"setOpenMobile\">\n <SheetContent\n data-sidebar=\"sidebar\"\n data-mobile=\"true\"\n :side=\"side\"\n class=\"w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH_MOBILE,\n }\"\n >\n <div class=\"flex h-full w-full flex-col\">\n <slot />\n </div>\n </SheetContent>\n </Sheet>\n\n <div\n v-else class=\"group peer hidden md:block\"\n :data-state=\"state\"\n :data-collapsible=\"state === 'collapsed' ? collapsible : ''\"\n :data-variant=\"variant\"\n :data-side=\"side\"\n >\n <!-- This is what handles the sidebar gap on desktop -->\n <div\n :class=\"cn(\n 'duration-200 relative h-svh w-[--sidebar-width] bg-transparent transition-[width] ease-linear',\n 'group-data-[collapsible=offcanvas]:w-0',\n 'group-data-[side=right]:rotate-180',\n variant === 'floating' || variant === 'inset'\n ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]',\n )\"\n />\n <div\n :class=\"cn(\n 'duration-200 fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] ease-linear md:flex',\n side === 'left'\n ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'\n : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',\n // Adjust the padding for floating and inset variants.\n variant === 'floating' || variant === 'inset'\n ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l',\n props.class,\n )\"\n v-bind=\"$attrs\"\n >\n <div\n data-sidebar=\"sidebar\"\n class=\"flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow\"\n >\n <slot />\n </div>\n </div>\n </div>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport type { SidebarProps } from '.'\nimport { Sheet, SheetContent } from '@/lib/registry/new-york/ui/sheet'\nimport { cn } from '@/lib/utils'\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"
|
||||
},
|
||||
{
|
||||
"name": "SidebarContent.vue",
|
||||
|
|
@ -50,7 +47,7 @@
|
|||
},
|
||||
{
|
||||
"name": "SidebarInput.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Input from '@/lib/registry/new-york/ui/input/Input.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Input\n data-sidebar=\"input\"\n :class=\"cn(\n 'h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring',\n props.class,\n )\"\n >\n <slot />\n </Input>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { Input } from '@/lib/registry/new-york/ui/input'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Input\n data-sidebar=\"input\"\n :class=\"cn(\n 'h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring',\n props.class,\n )\"\n >\n <slot />\n </Input>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "SidebarInset.vue",
|
||||
|
|
@ -70,7 +67,7 @@
|
|||
},
|
||||
{
|
||||
"name": "SidebarMenuButton.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport Tooltip from '@/lib/registry/new-york/ui/tooltip/Tooltip.vue'\nimport TooltipContent from '@/lib/registry/new-york/ui/tooltip/TooltipContent.vue'\nimport TooltipTrigger from '@/lib/registry/new-york/ui/tooltip/TooltipTrigger.vue'\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"
|
||||
"content": "<script setup lang=\"ts\">\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/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"
|
||||
},
|
||||
{
|
||||
"name": "SidebarMenuButtonChild.vue",
|
||||
|
|
@ -82,7 +79,7 @@
|
|||
},
|
||||
{
|
||||
"name": "SidebarMenuSkeleton.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport Skeleton from '@/lib/registry/new-york/ui/skeleton/Skeleton.vue'\nimport { cn } from '@/lib/utils'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n showIcon?: boolean\n class?: HTMLAttributes['class']\n}>()\n\nconst width = computed(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n})\n</script>\n\n<template>\n <div\n data-sidebar=\"menu-skeleton\"\n :class=\"cn('rounded-md h-8 flex gap-2 px-2 items-center', props.class)\"\n >\n <Skeleton\n v-if=\"showIcon\"\n class=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n\n <Skeleton\n class=\"h-4 flex-1 max-w-[--skeleton-width]\"\n data-sidebar=\"menu-skeleton-text\"\n :style=\"{ '--skeleton-width': width }\"\n />\n </div>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport { Skeleton } from '@/lib/registry/new-york/ui/skeleton'\nimport { cn } from '@/lib/utils'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n showIcon?: boolean\n class?: HTMLAttributes['class']\n}>()\n\nconst width = computed(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n})\n</script>\n\n<template>\n <div\n data-sidebar=\"menu-skeleton\"\n :class=\"cn('rounded-md h-8 flex gap-2 px-2 items-center', props.class)\"\n >\n <Skeleton\n v-if=\"showIcon\"\n class=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n\n <Skeleton\n class=\"h-4 flex-1 max-w-[--skeleton-width]\"\n data-sidebar=\"menu-skeleton-text\"\n :style=\"{ '--skeleton-width': width }\"\n />\n </div>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "SidebarMenuSub.vue",
|
||||
|
|
@ -98,7 +95,7 @@
|
|||
},
|
||||
{
|
||||
"name": "SidebarProvider.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { useEventListener, useVModel } from '@vueuse/core'\nimport { TooltipProvider } from 'radix-vue'\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 >\n <slot />\n </div>\n </TooltipProvider>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport { useEventListener, useMediaQuery, useVModel } from '@vueuse/core'\nimport { TooltipProvider } from 'radix-vue'\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"
|
||||
},
|
||||
{
|
||||
"name": "SidebarRail.vue",
|
||||
|
|
@ -106,15 +103,15 @@
|
|||
},
|
||||
{
|
||||
"name": "SidebarSeparator.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Separator from '@/lib/registry/new-york/ui/separator/Separator.vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Separator\n data-sidebar=\"separator\"\n :class=\"cn('mx-2 w-auto bg-sidebar-border', props.class)\"\n >\n <slot />\n </Separator>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { Separator } from '@/lib/registry/new-york/ui/separator'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <Separator\n data-sidebar=\"separator\"\n :class=\"cn('mx-2 w-auto bg-sidebar-border', props.class)\"\n >\n <slot />\n </Separator>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "SidebarTrigger.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport Button from '@/lib/registry/new-york/ui/button/Button.vue'\nimport { cn } from '@/lib/utils'\nimport { PanelLeft } from 'lucide-vue-next'\nimport { useSidebar } from './utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst { toggleSidebar } = useSidebar()\n</script>\n\n<template>\n <Button\n data-sidebar=\"trigger\"\n variant=\"ghost\"\n size=\"icon\"\n :class=\"cn('h-7 w-7', props.class)\"\n @click=\"toggleSidebar\"\n >\n <PanelLeft />\n <span class=\"sr-only\">Toggle Sidebar</span>\n </Button>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { Button } from '@/lib/registry/new-york/ui/button'\nimport { cn } from '@/lib/utils'\nimport { PanelLeft } from 'lucide-vue-next'\nimport { useSidebar } from './utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n\nconst { toggleSidebar } = useSidebar()\n</script>\n\n<template>\n <Button\n data-sidebar=\"trigger\"\n variant=\"ghost\"\n size=\"icon\"\n :class=\"cn('h-7 w-7', props.class)\"\n @click=\"toggleSidebar\"\n >\n <PanelLeft />\n <span class=\"sr-only\">Toggle Sidebar</span>\n </Button>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "index.ts",
|
||||
"content": "import { cva, type VariantProps } from 'class-variance-authority'\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"
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"name": "utils.ts",
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@
|
|||
"consola": "^3.2.3",
|
||||
"diff": "^7.0.0",
|
||||
"fs-extra": "^11.2.0",
|
||||
"https-proxy-agent": "^7.0.5",
|
||||
"lodash-es": "^4.17.21",
|
||||
"magic-string": "^0.30.12",
|
||||
"nypm": "^0.3.12",
|
||||
|
|
@ -69,6 +68,7 @@
|
|||
"radix-vue": "catalog:",
|
||||
"semver": "^7.6.3",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"undici": "^7.0.0",
|
||||
"vue-metamorph": "3.2.0",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ import {
|
|||
stylesSchema,
|
||||
} from '@/src/utils/registry/schema'
|
||||
import consola from 'consola'
|
||||
import { HttpsProxyAgent } from 'https-proxy-agent'
|
||||
import { ofetch } from 'ofetch'
|
||||
import path from 'pathe'
|
||||
import { ProxyAgent } from 'undici'
|
||||
|
||||
const baseUrl = process.env.COMPONENTS_REGISTRY_URL ?? 'https://www.shadcn-vue.com'
|
||||
const agent = process.env.https_proxy
|
||||
? new HttpsProxyAgent(process.env.https_proxy)
|
||||
? new ProxyAgent(process.env.https_proxy)
|
||||
: undefined
|
||||
|
||||
export async function getRegistryIndex() {
|
||||
|
|
@ -144,8 +144,7 @@ async function fetchRegistry(paths: string[]) {
|
|||
const results = await Promise.all(
|
||||
paths.map(async (path) => {
|
||||
const response = await ofetch(`${baseUrl}/registry/${path}`, {
|
||||
// @ts-expect-error agent type
|
||||
agent,
|
||||
dispatcher: agent,
|
||||
})
|
||||
|
||||
return response
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ importers:
|
|||
devDependencies:
|
||||
'@antfu/eslint-config':
|
||||
specifier: ^3.6.2
|
||||
version: 3.8.0(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3))(@vue/compiler-sfc@3.5.12)(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3)(vitest@2.1.3(@types/node@22.7.7)(@vitest/ui@2.1.3)(stylus@0.57.0)(terser@5.36.0))
|
||||
version: 3.8.0(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3))(@vue/compiler-sfc@3.5.12)(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3)(vitest@2.1.3)
|
||||
'@commitlint/cli':
|
||||
specifier: ^19.5.0
|
||||
version: 19.5.0(@types/node@22.7.7)(typescript@5.6.3)
|
||||
|
|
@ -270,9 +270,6 @@ importers:
|
|||
fs-extra:
|
||||
specifier: ^11.2.0
|
||||
version: 11.2.0
|
||||
https-proxy-agent:
|
||||
specifier: ^7.0.5
|
||||
version: 7.0.5
|
||||
lodash-es:
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.21
|
||||
|
|
@ -306,6 +303,9 @@ importers:
|
|||
tsconfig-paths:
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0
|
||||
undici:
|
||||
specifier: ^7.0.0
|
||||
version: 7.0.0
|
||||
vitest:
|
||||
specifier: '*'
|
||||
version: 2.1.3(@types/node@22.7.7)(@vitest/ui@2.1.3)(stylus@0.57.0)(terser@5.36.0)
|
||||
|
|
@ -367,7 +367,7 @@ importers:
|
|||
version: 3.13.2(rollup@4.24.0)
|
||||
'@nuxt/test-utils':
|
||||
specifier: ^3.14.0
|
||||
version: 3.14.4(@vitest/ui@2.1.3(vitest@2.1.3))(h3@1.13.0)(magicast@0.3.5)(nitropack@2.9.7(encoding@0.1.13)(magicast@0.3.5))(rollup@4.24.0)(vite@5.4.9(@types/node@20.16.13)(stylus@0.57.0)(terser@5.36.0))(vitest@2.1.3(@types/node@20.16.13)(@vitest/ui@2.1.3)(stylus@0.57.0)(terser@5.36.0))(vue-router@4.4.5(vue@3.5.12(typescript@5.6.3)))(vue@3.5.12(typescript@5.6.3))
|
||||
version: 3.14.4(@vitest/ui@2.1.3)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.9.7(encoding@0.1.13)(magicast@0.3.5))(rollup@4.24.0)(vite@5.4.9(@types/node@20.16.13)(stylus@0.57.0)(terser@5.36.0))(vitest@2.1.3)(vue-router@4.4.5(vue@3.5.12(typescript@5.6.3)))(vue@3.5.12(typescript@5.6.3))
|
||||
'@nuxtjs/color-mode':
|
||||
specifier: ^3.5.1
|
||||
version: 3.5.1(magicast@0.3.5)(rollup@4.24.0)
|
||||
|
|
@ -2800,10 +2800,6 @@ packages:
|
|||
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
||||
engines: {node: '>= 6.0.0'}
|
||||
|
||||
agent-base@7.1.1:
|
||||
resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
agentkeepalive@3.5.3:
|
||||
resolution: {integrity: sha512-yqXL+k5rr8+ZRpOAntkaaRgWgE5o8ESAj5DyRmVTCSoZxXmqemb9Dd7T4i5UzwuERdLAJUy6XzR9zFVuf0kzkw==}
|
||||
engines: {node: '>= 4.0.0'}
|
||||
|
|
@ -3323,7 +3319,7 @@ packages:
|
|||
resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==}
|
||||
|
||||
concat-map@0.0.1:
|
||||
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
|
||||
concat-stream@1.6.2:
|
||||
resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
|
||||
|
|
@ -3903,7 +3899,7 @@ packages:
|
|||
engines: {node: '>=0.8'}
|
||||
|
||||
ee-first@1.1.1:
|
||||
resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=}
|
||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||
|
||||
electron-to-chromium@1.5.41:
|
||||
resolution: {integrity: sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==}
|
||||
|
|
@ -4700,10 +4696,6 @@ packages:
|
|||
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
https-proxy-agent@7.0.5:
|
||||
resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
httpxy@0.1.5:
|
||||
resolution: {integrity: sha512-hqLDO+rfststuyEUTWObQK6zHEEmZ/kaIP2/zclGGZn6X8h/ESTWg+WKecQ/e5k4nPswjzZD+q2VqZIbr15CoQ==}
|
||||
|
||||
|
|
@ -5368,7 +5360,7 @@ packages:
|
|||
resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
|
||||
|
||||
media-typer@0.3.0:
|
||||
resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=}
|
||||
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
meow@12.1.1:
|
||||
|
|
@ -7304,6 +7296,10 @@ packages:
|
|||
resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==}
|
||||
engines: {node: '>=14.0'}
|
||||
|
||||
undici@7.0.0:
|
||||
resolution: {integrity: sha512-c4xi3kWnQJrb7h2q8aJYKvUzmz7boCgz1cUCC6OwdeM5Tr2P0hDuthr2iut4ggqsz+Cnh20U/LoTzbKIdDS/Nw==}
|
||||
engines: {node: '>=20.18.1'}
|
||||
|
||||
unenv@1.10.0:
|
||||
resolution: {integrity: sha512-wY5bskBQFL9n3Eca5XnhH6KbUo/tfvkwm9OpcdCvLaeA7piBNbavbOKJySEwQ1V0RH6HvNlSAFRTpvTqgKRQXQ==}
|
||||
|
||||
|
|
@ -8015,7 +8011,7 @@ snapshots:
|
|||
'@jridgewell/gen-mapping': 0.3.5
|
||||
'@jridgewell/trace-mapping': 0.3.25
|
||||
|
||||
'@antfu/eslint-config@3.8.0(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3))(@vue/compiler-sfc@3.5.12)(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3)(vitest@2.1.3(@types/node@22.7.7)(@vitest/ui@2.1.3)(stylus@0.57.0)(terser@5.36.0))':
|
||||
'@antfu/eslint-config@3.8.0(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3))(@vue/compiler-sfc@3.5.12)(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3)(vitest@2.1.3)':
|
||||
dependencies:
|
||||
'@antfu/install-pkg': 0.4.1
|
||||
'@clack/prompts': 0.7.0
|
||||
|
|
@ -8024,7 +8020,7 @@ snapshots:
|
|||
'@stylistic/eslint-plugin': 2.9.0(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3)
|
||||
'@typescript-eslint/eslint-plugin': 8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3)
|
||||
'@typescript-eslint/parser': 8.10.0(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3)
|
||||
'@vitest/eslint-plugin': 1.1.7(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3)(vitest@2.1.3(@types/node@22.7.7)(@vitest/ui@2.1.3)(stylus@0.57.0)(terser@5.36.0))
|
||||
'@vitest/eslint-plugin': 1.1.7(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3)(vitest@2.1.3)
|
||||
eslint: 9.13.0(jiti@2.3.3)
|
||||
eslint-config-flat-gitignore: 0.3.0(eslint@9.13.0(jiti@2.3.3))
|
||||
eslint-flat-config-utils: 0.4.0
|
||||
|
|
@ -9348,7 +9344,7 @@ snapshots:
|
|||
- supports-color
|
||||
- webpack-sources
|
||||
|
||||
'@nuxt/test-utils@3.14.4(@vitest/ui@2.1.3(vitest@2.1.3))(h3@1.13.0)(magicast@0.3.5)(nitropack@2.9.7(encoding@0.1.13)(magicast@0.3.5))(rollup@4.24.0)(vite@5.4.9(@types/node@20.16.13)(stylus@0.57.0)(terser@5.36.0))(vitest@2.1.3(@types/node@20.16.13)(@vitest/ui@2.1.3)(stylus@0.57.0)(terser@5.36.0))(vue-router@4.4.5(vue@3.5.12(typescript@5.6.3)))(vue@3.5.12(typescript@5.6.3))':
|
||||
'@nuxt/test-utils@3.14.4(@vitest/ui@2.1.3)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.9.7(encoding@0.1.13)(magicast@0.3.5))(rollup@4.24.0)(vite@5.4.9(@types/node@20.16.13)(stylus@0.57.0)(terser@5.36.0))(vitest@2.1.3)(vue-router@4.4.5(vue@3.5.12(typescript@5.6.3)))(vue@3.5.12(typescript@5.6.3))':
|
||||
dependencies:
|
||||
'@nuxt/kit': 3.13.2(magicast@0.3.5)(rollup@4.24.0)
|
||||
'@nuxt/schema': 3.13.2(rollup@4.24.0)
|
||||
|
|
@ -9375,7 +9371,7 @@ snapshots:
|
|||
unenv: 1.10.0
|
||||
unplugin: 1.14.1
|
||||
vite: 5.4.9(@types/node@20.16.13)(stylus@0.57.0)(terser@5.36.0)
|
||||
vitest-environment-nuxt: 1.0.1(@vitest/ui@2.1.3(vitest@2.1.3))(h3@1.13.0)(magicast@0.3.5)(nitropack@2.9.7(encoding@0.1.13)(magicast@0.3.5))(rollup@4.24.0)(vite@5.4.9(@types/node@20.16.13)(stylus@0.57.0)(terser@5.36.0))(vitest@2.1.3(@types/node@20.16.13)(@vitest/ui@2.1.3)(stylus@0.57.0)(terser@5.36.0))(vue-router@4.4.5(vue@3.5.12(typescript@5.6.3)))(vue@3.5.12(typescript@5.6.3))
|
||||
vitest-environment-nuxt: 1.0.1(@vitest/ui@2.1.3)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.9.7(encoding@0.1.13)(magicast@0.3.5))(rollup@4.24.0)(vite@5.4.9(@types/node@20.16.13)(stylus@0.57.0)(terser@5.36.0))(vitest@2.1.3)(vue-router@4.4.5(vue@3.5.12(typescript@5.6.3)))(vue@3.5.12(typescript@5.6.3))
|
||||
vue: 3.5.12(typescript@5.6.3)
|
||||
vue-router: 4.4.5(vue@3.5.12(typescript@5.6.3))
|
||||
optionalDependencies:
|
||||
|
|
@ -10308,7 +10304,7 @@ snapshots:
|
|||
vite: 5.4.9(@types/node@22.7.7)(stylus@0.57.0)(terser@5.36.0)
|
||||
vue: 3.5.12(typescript@5.6.3)
|
||||
|
||||
'@vitest/eslint-plugin@1.1.7(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3)(vitest@2.1.3(@types/node@22.7.7)(@vitest/ui@2.1.3)(stylus@0.57.0)(terser@5.36.0))':
|
||||
'@vitest/eslint-plugin@1.1.7(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3)(vitest@2.1.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@2.3.3))(typescript@5.6.3)
|
||||
eslint: 9.13.0(jiti@2.3.3)
|
||||
|
|
@ -10638,12 +10634,6 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
agent-base@7.1.1:
|
||||
dependencies:
|
||||
debug: 4.3.7
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
agentkeepalive@3.5.3:
|
||||
dependencies:
|
||||
humanize-ms: 1.2.1
|
||||
|
|
@ -12871,13 +12861,6 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
https-proxy-agent@7.0.5:
|
||||
dependencies:
|
||||
agent-base: 7.1.1
|
||||
debug: 4.3.7
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
httpxy@0.1.5: {}
|
||||
|
||||
human-signals@2.1.0: {}
|
||||
|
|
@ -15916,6 +15899,8 @@ snapshots:
|
|||
dependencies:
|
||||
'@fastify/busboy': 2.1.1
|
||||
|
||||
undici@7.0.0: {}
|
||||
|
||||
unenv@1.10.0:
|
||||
dependencies:
|
||||
consola: 3.2.3
|
||||
|
|
@ -16341,9 +16326,9 @@ snapshots:
|
|||
- typescript
|
||||
- universal-cookie
|
||||
|
||||
vitest-environment-nuxt@1.0.1(@vitest/ui@2.1.3(vitest@2.1.3))(h3@1.13.0)(magicast@0.3.5)(nitropack@2.9.7(encoding@0.1.13)(magicast@0.3.5))(rollup@4.24.0)(vite@5.4.9(@types/node@20.16.13)(stylus@0.57.0)(terser@5.36.0))(vitest@2.1.3(@types/node@20.16.13)(@vitest/ui@2.1.3)(stylus@0.57.0)(terser@5.36.0))(vue-router@4.4.5(vue@3.5.12(typescript@5.6.3)))(vue@3.5.12(typescript@5.6.3)):
|
||||
vitest-environment-nuxt@1.0.1(@vitest/ui@2.1.3)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.9.7(encoding@0.1.13)(magicast@0.3.5))(rollup@4.24.0)(vite@5.4.9(@types/node@20.16.13)(stylus@0.57.0)(terser@5.36.0))(vitest@2.1.3)(vue-router@4.4.5(vue@3.5.12(typescript@5.6.3)))(vue@3.5.12(typescript@5.6.3)):
|
||||
dependencies:
|
||||
'@nuxt/test-utils': 3.14.4(@vitest/ui@2.1.3(vitest@2.1.3))(h3@1.13.0)(magicast@0.3.5)(nitropack@2.9.7(encoding@0.1.13)(magicast@0.3.5))(rollup@4.24.0)(vite@5.4.9(@types/node@20.16.13)(stylus@0.57.0)(terser@5.36.0))(vitest@2.1.3(@types/node@20.16.13)(@vitest/ui@2.1.3)(stylus@0.57.0)(terser@5.36.0))(vue-router@4.4.5(vue@3.5.12(typescript@5.6.3)))(vue@3.5.12(typescript@5.6.3))
|
||||
'@nuxt/test-utils': 3.14.4(@vitest/ui@2.1.3)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.9.7(encoding@0.1.13)(magicast@0.3.5))(rollup@4.24.0)(vite@5.4.9(@types/node@20.16.13)(stylus@0.57.0)(terser@5.36.0))(vitest@2.1.3)(vue-router@4.4.5(vue@3.5.12(typescript@5.6.3)))(vue@3.5.12(typescript@5.6.3))
|
||||
transitivePeerDependencies:
|
||||
- '@cucumber/cucumber'
|
||||
- '@jest/globals'
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user