Merge branch 'unovue:dev' into dev
This commit is contained in:
commit
097c07c232
|
|
@ -43,7 +43,7 @@ const { isDark } = useData()
|
|||
@click="setTheme(color)"
|
||||
>
|
||||
<span
|
||||
class="h-5 w-5 rounded-full flex items-center justify-center"
|
||||
class="h-5 w-5 rounded-full flex items-center justify-center shrink-0"
|
||||
:style="{ backgroundColor: colors[color][7].rgb }"
|
||||
>
|
||||
<RadixIconsCheck
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@
|
|||
|
||||
* {
|
||||
@apply border-border;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: hsl(var(--border)) transparent;
|
||||
}
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@
|
|||
padding: 0 24px; */
|
||||
width: calc(100% + 2 * 24px);
|
||||
display: inline-block;
|
||||
@apply bg-[hsl(var(--foreground))] dark:bg-[hsl(var(--background)_/_50%)]
|
||||
@apply bg-[hsl(var(--muted))] dark:bg-[hsl(var(--muted))]
|
||||
}
|
||||
|
||||
.vp-doc [class*='language-'] code .highlighted.error {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "www",
|
||||
"type": "module",
|
||||
"version": "0.11.2",
|
||||
"version": "0.11.3",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ npx shadcn-vue@latest init
|
|||
|
||||
You will be asked a few questions to configure `components.json`:
|
||||
|
||||
```txt:line-numbers
|
||||
```ansi:line-numbers
|
||||
Would you like to use TypeScript (recommended)? no / yes
|
||||
Which framework are you using? Vite / Nuxt / Laravel
|
||||
Which style would you like to use? › Default
|
||||
|
|
@ -29,7 +29,7 @@ Configure the import alias for utils: › @/lib/utils
|
|||
|
||||
### Options
|
||||
|
||||
```txt
|
||||
```ansi
|
||||
Usage: shadcn-vue init [options]
|
||||
|
||||
initialize your project and install dependencies
|
||||
|
|
@ -50,7 +50,7 @@ npx shadcn-vue@latest add [component]
|
|||
|
||||
You will be presented with a list of components to choose from:
|
||||
|
||||
```txt
|
||||
```ansi
|
||||
Which components would you like to add? › Space to select. Return to submit.
|
||||
|
||||
◯ accordion
|
||||
|
|
@ -67,7 +67,7 @@ Which components would you like to add? › Space to select. Return to submit.
|
|||
|
||||
### Options
|
||||
|
||||
```txt
|
||||
```ansi
|
||||
Usage: shadcn-vue add [options] [components...]
|
||||
|
||||
add components to your project
|
||||
|
|
@ -90,7 +90,7 @@ Use the `update` command to update components in your project. This will overwri
|
|||
|
||||
We plan on improving this command in the future to improve the update experience.
|
||||
|
||||
```txt
|
||||
```ansi
|
||||
Usage: shadcn-vue update [options] [components...]
|
||||
|
||||
update components in your project
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Data Table
|
||||
description: Powerful table and datagrids built using TanStack Table.
|
||||
primitive: https://tanstack.com/table/v8/docs/guide/introduction
|
||||
primitive: https://tanstack.com/table/v8/docs/introduction
|
||||
---
|
||||
|
||||
<ComponentPreview name="DataTableDemo" />
|
||||
|
|
@ -102,7 +102,7 @@ export const payments: Payment[] = [
|
|||
|
||||
Start by creating the following file structure:
|
||||
|
||||
```txt
|
||||
```ansi
|
||||
components
|
||||
└── payments
|
||||
├── columns.ts
|
||||
|
|
|
|||
|
|
@ -101,13 +101,13 @@ You can use the `pnpm --filter=[WORKSPACE]` command to start the development pro
|
|||
|
||||
1. To run the `shadcn-vue.com` website:
|
||||
|
||||
```
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
2. To run the `shadcn-vue` cli package:
|
||||
|
||||
```
|
||||
```bash
|
||||
pnpm dev:cli
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ npm create astro@latest
|
|||
|
||||
You will be asked a few questions to configure your project:
|
||||
|
||||
```txt:line-numbers
|
||||
```ansi:line-numbers
|
||||
- Where should we create your new project?
|
||||
./your-app-name
|
||||
- How would you like to start your new project?
|
||||
|
|
@ -99,7 +99,7 @@ npx shadcn-vue@latest init
|
|||
|
||||
You will be asked a few questions to configure `components.json`:
|
||||
|
||||
```txt:line-numbers
|
||||
```ansi:line-numbers
|
||||
Would you like to use TypeScript (recommended)? no / yes
|
||||
Which framework are you using? Astro
|
||||
Which style would you like to use? › Default
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ npx shadcn-vue@latest init
|
|||
|
||||
You will be asked a few questions to configure `components.json`:
|
||||
|
||||
```txt:line-numbers
|
||||
```ansi:line-numbers
|
||||
Would you like to use TypeScript (recommended)? no / yes
|
||||
Which framework are you using? Vite / Nuxt / Laravel
|
||||
Which style would you like to use? › Default
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ npx shadcn-vue@latest init
|
|||
|
||||
You will be asked a few questions to configure `components.json`:
|
||||
|
||||
```txt:line-numbers
|
||||
```ansi:line-numbers
|
||||
Would you like to use TypeScript (recommended)? no / yes
|
||||
Which framework are you using? Vite / Nuxt / Laravel
|
||||
Which style would you like to use? › Default
|
||||
|
|
@ -231,7 +231,7 @@ Write configuration to components.json. Proceed? > Y/n
|
|||
|
||||
Here's the default structure of Nuxt app. You can use this as a reference:
|
||||
|
||||
```txt {6-16,20-21}
|
||||
```ansi {6-16,20-21}
|
||||
.
|
||||
├── pages
|
||||
│ ├── index.vue
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ npx shadcn-vue@latest init
|
|||
|
||||
You will be asked a few questions to configure `components.json`:
|
||||
|
||||
```txt:line-numbers
|
||||
```ansi:line-numbers
|
||||
Would you like to use TypeScript (recommended)? no / yes
|
||||
Which framework are you using? Vite / Nuxt / Laravel
|
||||
Which style would you like to use? › Default
|
||||
|
|
|
|||
|
|
@ -32,13 +32,13 @@ import { Label } from '@/lib/registry/default/ui/label'
|
|||
<Label for="name" class="text-right">
|
||||
Name
|
||||
</Label>
|
||||
<Input id="name" value="Pedro Duarte" class="col-span-3" />
|
||||
<Input id="name" default-value="Pedro Duarte" class="col-span-3" />
|
||||
</div>
|
||||
<div class="grid grid-cols-4 items-center gap-4">
|
||||
<Label for="username" class="text-right">
|
||||
Username
|
||||
</Label>
|
||||
<Input id="username" value="@peduarte" class="col-span-3" />
|
||||
<Input id="username" default-value="@peduarte" class="col-span-3" />
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ function onSubmit(values: any) {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<Form v-slot="{ submitForm }" as="" :validation-schema="formSchema" @submit="onSubmit">
|
||||
<Form v-slot="{ handleSubmit }" as="" keep-values :validation-schema="formSchema">
|
||||
<Dialog>
|
||||
<DialogTrigger as-child>
|
||||
<Button variant="outline">
|
||||
|
|
@ -53,7 +53,7 @@ function onSubmit(values: any) {
|
|||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<form @submit="submitForm">
|
||||
<form id="dialogForm" @submit="handleSubmit($event, onSubmit)">
|
||||
<FormField v-slot="{ componentField }" name="username">
|
||||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
|
|
|
|||
|
|
@ -33,13 +33,13 @@ import {
|
|||
<Label for="name" class="text-right">
|
||||
Name
|
||||
</Label>
|
||||
<Input id="name" value="Pedro Duarte" class="col-span-3" />
|
||||
<Input id="name" default-value="Pedro Duarte" class="col-span-3" />
|
||||
</div>
|
||||
<div class="grid grid-cols-4 items-center gap-4">
|
||||
<Label for="username" class="text-right">
|
||||
Username
|
||||
</Label>
|
||||
<Input id="username" value="@peduarte" class="col-span-3" />
|
||||
<Input id="username" default-value="@peduarte" class="col-span-3" />
|
||||
</div>
|
||||
</div>
|
||||
<SheetFooter>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import type { InputComponents } from './interface'
|
||||
import AutoFormFieldArray from './AutoFormFieldArray.vue'
|
||||
import AutoFormFieldBoolean from './AutoFormFieldBoolean.vue'
|
||||
import AutoFormFieldDate from './AutoFormFieldDate.vue'
|
||||
|
|
@ -7,7 +8,7 @@ import AutoFormFieldInput from './AutoFormFieldInput.vue'
|
|||
import AutoFormFieldNumber from './AutoFormFieldNumber.vue'
|
||||
import AutoFormFieldObject from './AutoFormFieldObject.vue'
|
||||
|
||||
export const INPUT_COMPONENTS = {
|
||||
export const INPUT_COMPONENTS: InputComponents = {
|
||||
date: AutoFormFieldDate,
|
||||
select: AutoFormFieldEnum,
|
||||
radio: AutoFormFieldEnum,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,20 @@ export interface Shape {
|
|||
schema?: ZodAny
|
||||
}
|
||||
|
||||
export interface InputComponents {
|
||||
date: Component;
|
||||
select: Component;
|
||||
radio: Component;
|
||||
checkbox: Component;
|
||||
switch: Component;
|
||||
textarea: Component;
|
||||
number: Component;
|
||||
string: Component;
|
||||
file: Component;
|
||||
array: Component;
|
||||
object: Component;
|
||||
};
|
||||
|
||||
export interface ConfigItem {
|
||||
/** Value for the `FormLabel` */
|
||||
label?: string
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { cva, type VariantProps } from 'class-variance-authority'
|
|||
export { default as Button } from './Button.vue'
|
||||
|
||||
export const buttonVariants = cva(
|
||||
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
|
|||
<SheetContent
|
||||
data-sidebar="sidebar"
|
||||
data-mobile="true"
|
||||
:side="side"
|
||||
class="w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
|
||||
:style="{
|
||||
'--sidebar-width': SIDEBAR_WIDTH_MOBILE,
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
@ -18,7 +18,7 @@ const emits = defineEmits<{
|
|||
'update:open': [open: boolean]
|
||||
}>()
|
||||
|
||||
const isMobile = ref(false) // useIsMobile()
|
||||
const isMobile = useMediaQuery('(max-width: 768px)')
|
||||
const openMobile = ref(false)
|
||||
|
||||
const open = useVModel(props, 'open', emits, {
|
||||
|
|
@ -39,7 +39,7 @@ function setOpenMobile(value: boolean) {
|
|||
|
||||
// Helper to toggle the sidebar.
|
||||
function toggleSidebar() {
|
||||
return isMobile.value ? setOpenMobile(!open.value) : setOpen(!open.value)
|
||||
return isMobile.value ? setOpenMobile(!openMobile.value) : setOpen(!open.value)
|
||||
}
|
||||
|
||||
useEventListener('keydown', (event: KeyboardEvent) => {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ function onSubmit(values: any) {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<Form v-slot="{ submitForm }" as="" keep-values :validation-schema="formSchema" @submit="onSubmit">
|
||||
<Form v-slot="{ handleSubmit }" as="" keep-values :validation-schema="formSchema">
|
||||
<Dialog>
|
||||
<DialogTrigger as-child>
|
||||
<Button variant="outline">
|
||||
|
|
@ -53,7 +53,7 @@ function onSubmit(values: any) {
|
|||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<form @submit="submitForm">
|
||||
<form id="dialogForm" @submit="handleSubmit($event, onSubmit)">
|
||||
<FormField v-slot="{ componentField }" name="username">
|
||||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import type { InputComponents } from './interface'
|
||||
import AutoFormFieldArray from './AutoFormFieldArray.vue'
|
||||
import AutoFormFieldBoolean from './AutoFormFieldBoolean.vue'
|
||||
import AutoFormFieldDate from './AutoFormFieldDate.vue'
|
||||
|
|
@ -7,7 +8,7 @@ import AutoFormFieldInput from './AutoFormFieldInput.vue'
|
|||
import AutoFormFieldNumber from './AutoFormFieldNumber.vue'
|
||||
import AutoFormFieldObject from './AutoFormFieldObject.vue'
|
||||
|
||||
export const INPUT_COMPONENTS = {
|
||||
export const INPUT_COMPONENTS: InputComponents = {
|
||||
date: AutoFormFieldDate,
|
||||
select: AutoFormFieldEnum,
|
||||
radio: AutoFormFieldEnum,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,20 @@ export interface Shape {
|
|||
schema?: ZodAny
|
||||
}
|
||||
|
||||
export interface InputComponents {
|
||||
date: Component;
|
||||
select: Component;
|
||||
radio: Component;
|
||||
checkbox: Component;
|
||||
switch: Component;
|
||||
textarea: Component;
|
||||
number: Component;
|
||||
string: Component;
|
||||
file: Component;
|
||||
array: Component;
|
||||
object: Component;
|
||||
};
|
||||
|
||||
export interface ConfigItem {
|
||||
/** Value for the `FormLabel` */
|
||||
label?: string
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { cva, type VariantProps } from 'class-variance-authority'
|
|||
export { default as Button } from './Button.vue'
|
||||
|
||||
export const buttonVariants = cva(
|
||||
'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',
|
||||
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
|
|||
<SheetContent
|
||||
data-sidebar="sidebar"
|
||||
data-mobile="true"
|
||||
:side="side"
|
||||
class="w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
|
||||
:style="{
|
||||
'--sidebar-width': SIDEBAR_WIDTH_MOBILE,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ const emits = defineEmits<{
|
|||
'update:open': [open: boolean]
|
||||
}>()
|
||||
|
||||
const isMobile = ref(false) // useIsMobile()
|
||||
const isMobile = useMediaQuery('(max-width: 768px)')
|
||||
const openMobile = ref(false)
|
||||
|
||||
const open = useVModel(props, 'open', emits, {
|
||||
|
|
@ -39,7 +39,7 @@ function setOpenMobile(value: boolean) {
|
|||
|
||||
// Helper to toggle the sidebar.
|
||||
function toggleSidebar() {
|
||||
return isMobile.value ? setOpenMobile(!open.value) : setOpen(!open.value)
|
||||
return isMobile.value ? setOpenMobile(!openMobile.value) : setOpen(!open.value)
|
||||
}
|
||||
|
||||
useEventListener('keydown', (event: KeyboardEvent) => {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
},
|
||||
{
|
||||
"name": "index.ts",
|
||||
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Button } from './Button.vue'\n\nexport const buttonVariants = cva(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n default:\n 'bg-primary text-primary-foreground shadow hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',\n outline:\n 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-8',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>\n"
|
||||
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Button } from './Button.vue'\n\nexport const buttonVariants = cva(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n default:\n 'bg-primary text-primary-foreground shadow hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',\n outline:\n 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-8',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
"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 class=\"w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH_MOBILE,\n }\"\n >\n <div class=\"flex h-full w-full flex-col\">\n <slot />\n </div>\n </SheetContent>\n </Sheet>\n\n <div\n v-else class=\"group peer hidden md:block\"\n :data-state=\"state\"\n :data-collapsible=\"state === 'collapsed' ? collapsible : ''\"\n :data-variant=\"variant\"\n :data-side=\"side\"\n >\n <!-- This is what handles the sidebar gap on desktop -->\n <div\n :class=\"cn(\n 'duration-200 relative h-svh w-[--sidebar-width] bg-transparent transition-[width] ease-linear',\n 'group-data-[collapsible=offcanvas]:w-0',\n 'group-data-[side=right]:rotate-180',\n variant === 'floating' || variant === 'inset'\n ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]',\n )\"\n />\n <div\n :class=\"cn(\n 'duration-200 fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] ease-linear md:flex',\n side === 'left'\n ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'\n : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',\n // Adjust the padding for floating and inset variants.\n variant === 'floating' || variant === 'inset'\n ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l',\n props.class,\n )\"\n v-bind=\"$attrs\"\n >\n <div\n data-sidebar=\"sidebar\"\n class=\"flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow\"\n >\n <slot />\n </div>\n </div>\n </div>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport 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"
|
||||
},
|
||||
{
|
||||
"name": "SidebarContent.vue",
|
||||
|
|
@ -98,7 +98,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 = ref(false) // useIsMobile()\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(!open.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 >\n <slot />\n </div>\n </TooltipProvider>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "SidebarRail.vue",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
},
|
||||
{
|
||||
"name": "index.ts",
|
||||
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Button } from './Button.vue'\n\nexport const buttonVariants = cva(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground shadow hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',\n outline:\n 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2',\n xs: 'h-7 rounded px-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-8',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>\n"
|
||||
"content": "import { cva, type VariantProps } from 'class-variance-authority'\n\nexport { default as Button } from './Button.vue'\n\nexport const buttonVariants = cva(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground shadow hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',\n outline:\n 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2',\n xs: 'h-7 rounded px-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-8',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
"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 class=\"w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n :style=\"{\n '--sidebar-width': SIDEBAR_WIDTH_MOBILE,\n }\"\n >\n <div class=\"flex h-full w-full flex-col\">\n <slot />\n </div>\n </SheetContent>\n </Sheet>\n\n <div\n v-else class=\"group peer hidden md:block\"\n :data-state=\"state\"\n :data-collapsible=\"state === 'collapsed' ? collapsible : ''\"\n :data-variant=\"variant\"\n :data-side=\"side\"\n >\n <!-- This is what handles the sidebar gap on desktop -->\n <div\n :class=\"cn(\n 'duration-200 relative h-svh w-[--sidebar-width] bg-transparent transition-[width] ease-linear',\n 'group-data-[collapsible=offcanvas]:w-0',\n 'group-data-[side=right]:rotate-180',\n variant === 'floating' || variant === 'inset'\n ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]',\n )\"\n />\n <div\n :class=\"cn(\n 'duration-200 fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] ease-linear md:flex',\n side === 'left'\n ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'\n : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',\n // Adjust the padding for floating and inset variants.\n variant === 'floating' || variant === 'inset'\n ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'\n : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l',\n props.class,\n )\"\n v-bind=\"$attrs\"\n >\n <div\n data-sidebar=\"sidebar\"\n class=\"flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow\"\n >\n <slot />\n </div>\n </div>\n </div>\n</template>\n"
|
||||
"content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport 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"
|
||||
},
|
||||
{
|
||||
"name": "SidebarContent.vue",
|
||||
|
|
@ -98,7 +98,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 = ref(false) // useIsMobile()\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(!open.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, 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"
|
||||
},
|
||||
{
|
||||
"name": "SidebarRail.vue",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "shadcn-vue",
|
||||
"type": "module",
|
||||
"version": "0.11.2",
|
||||
"version": "0.11.3",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@9.10.0",
|
||||
"license": "MIT",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "shadcn-vue",
|
||||
"type": "module",
|
||||
"version": "0.11.2",
|
||||
"version": "0.11.3",
|
||||
"description": "Add components to your apps.",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
|
@ -69,7 +69,7 @@
|
|||
"radix-vue": "catalog:",
|
||||
"semver": "^7.6.3",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"vue-metamorph": "^3.2.0",
|
||||
"vue-metamorph": "3.2.0",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "shadcn-nuxt",
|
||||
"type": "module",
|
||||
"version": "0.11.2",
|
||||
"version": "0.11.3",
|
||||
"description": "Add shadcn-vue module to Nuxt",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ importers:
|
|||
specifier: '*'
|
||||
version: 2.1.3(@types/node@22.7.7)(@vitest/ui@2.1.3)(stylus@0.57.0)(terser@5.36.0)
|
||||
vue-metamorph:
|
||||
specifier: ^3.2.0
|
||||
specifier: 3.2.0
|
||||
version: 3.2.0(eslint@9.13.0(jiti@2.3.3))
|
||||
zod:
|
||||
specifier: ^3.23.8
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user