Fix: style 'new-york' + CSS exacto del manual shadcn-vue

- components.json: reka-nova → new-york
- style.css: reescrito según manual (orden @theme inline después de :root/.dark)
- color-destructive-foreground agregado a @theme inline
- Colores chart correctos (no grayscale), sidebar-border sólido, destructive tonos
- @layer base sin duplicados, font-sans vía CSS variable
- 130 componentes reinstalados con new-york variants
This commit is contained in:
2026-05-22 22:56:56 -05:00
parent c08f73400c
commit 28856e2149
132 changed files with 941 additions and 986 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"$schema": "https://shadcn-vue.com/schema.json", "$schema": "https://shadcn-vue.com/schema.json",
"style": "reka-nova", "style": "new-york",
"font": "geist-sans", "font": "geist-sans",
"typescript": true, "typescript": true,
"tailwind": { "tailwind": {
+5 -9
View File
@@ -1,21 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import type { AvatarVariants } from '.' import { AvatarRoot } from "reka-ui"
import { AvatarRoot } from 'reka-ui' import { cn } from "@/lib/utils"
import { cn } from '@/lib/utils'
import { avatarVariants } from '.'
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
size?: AvatarVariants['size']
}>() }>()
</script> </script>
<template> <template>
<AvatarRoot <AvatarRoot
data-slot="avatar" data-slot="avatar"
:data-size="size ?? 'default'" :class="cn('relative flex size-8 shrink-0 overflow-hidden rounded-full', props.class)"
:class="cn(avatarVariants({ size }), props.class)"
> >
<slot /> <slot />
</AvatarRoot> </AvatarRoot>
+8 -8
View File
@@ -1,20 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import type { AvatarFallbackProps } from 'reka-ui' import type { AvatarFallbackProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { AvatarFallback } from 'reka-ui' import { AvatarFallback } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<AvatarFallbackProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<AvatarFallbackProps & { class?: HTMLAttributes["class"] }>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
</script> </script>
<template> <template>
<AvatarFallback <AvatarFallback
data-slot="avatar-fallback" data-slot="avatar-fallback"
v-bind="delegatedProps" v-bind="delegatedProps"
:class="cn('bg-muted text-muted-foreground rounded-full flex size-full items-center justify-center text-sm group-data-[size=sm]/avatar:text-xs', props.class)" :class="cn('bg-muted flex size-full items-center justify-center rounded-full', props.class)"
> >
<slot /> <slot />
</AvatarFallback> </AvatarFallback>
+3 -3
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { AvatarImageProps } from 'reka-ui' import type { AvatarImageProps } from "reka-ui"
import { AvatarImage } from 'reka-ui' import { AvatarImage } from "reka-ui"
const props = defineProps<AvatarImageProps>() const props = defineProps<AvatarImageProps>()
</script> </script>
@@ -9,7 +9,7 @@ const props = defineProps<AvatarImageProps>()
<AvatarImage <AvatarImage
data-slot="avatar-image" data-slot="avatar-image"
v-bind="props" v-bind="props"
class="rounded-full aspect-square size-full object-cover" class="aspect-square size-full"
> >
<slot /> <slot />
</AvatarImage> </AvatarImage>
+3 -27
View File
@@ -1,27 +1,3 @@
import type { VariantProps } from 'class-variance-authority' export { default as Avatar } from "./Avatar.vue"
import { cva } from 'class-variance-authority' export { default as AvatarFallback } from "./AvatarFallback.vue"
export { default as AvatarImage } from "./AvatarImage.vue"
export { default as Avatar } from './Avatar.vue'
export { default as AvatarBadge } from './AvatarBadge.vue'
export { default as AvatarFallback } from './AvatarFallback.vue'
export { default as AvatarGroup } from './AvatarGroup.vue'
export { default as AvatarGroupCount } from './AvatarGroupCount.vue'
export { default as AvatarImage } from './AvatarImage.vue'
export const avatarVariants = cva(
'size-8 rounded-full after:rounded-full data-[size=lg]:size-10 data-[size=sm]:size-6 group/avatar relative flex shrink-0 select-none after:absolute after:inset-0 after:border after:border-border after:mix-blend-darken dark:after:mix-blend-lighten',
{
variants: {
size: {
sm: '',
default: '',
lg: '',
},
},
defaultVariants: {
size: 'default',
},
},
)
export type AvatarVariants = VariantProps<typeof avatarVariants>
+10 -11
View File
@@ -1,24 +1,23 @@
<script setup lang="ts"> <script setup lang="ts">
import type { PrimitiveProps } from 'reka-ui' import type { PrimitiveProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import type { BadgeVariants } from '.' import type { BadgeVariants } from "."
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { Primitive } from 'reka-ui' import { Primitive } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
import { badgeVariants } from '.' import { badgeVariants } from "."
const props = defineProps<PrimitiveProps & { const props = defineProps<PrimitiveProps & {
variant?: BadgeVariants['variant'] variant?: BadgeVariants["variant"]
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
</script> </script>
<template> <template>
<Primitive <Primitive
data-slot="badge" data-slot="badge"
:data-variant="variant"
:class="cn(badgeVariants({ variant }), props.class)" :class="cn(badgeVariants({ variant }), props.class)"
v-bind="delegatedProps" v-bind="delegatedProps"
> >
+13 -11
View File
@@ -1,23 +1,25 @@
import type { VariantProps } from 'class-variance-authority' import type { VariantProps } from "class-variance-authority"
import { cva } from 'class-variance-authority' import { cva } from "class-variance-authority"
export { default as Badge } from './Badge.vue' export { default as Badge } from "./Badge.vue"
export const badgeVariants = cva( export const badgeVariants = cva(
'h-5 gap-1 rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! group/badge inline-flex w-fit shrink-0 items-center justify-center overflow-hidden whitespace-nowrap focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none', "inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
{ {
variants: { variants: {
variant: { variant: {
default: 'bg-primary text-primary-foreground [a]:hover:bg-primary/80', default:
secondary: 'bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80', "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
destructive: 'bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20', secondary:
outline: 'border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground', "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
ghost: 'hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50', destructive:
link: 'text-primary underline-offset-4 hover:underline', "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
outline:
"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
}, },
}, },
defaultVariants: { defaultVariants: {
variant: 'default', variant: "default",
}, },
}, },
) )
+3 -4
View File
@@ -1,9 +1,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils'
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -11,7 +10,7 @@ const props = defineProps<{
<nav <nav
aria-label="breadcrumb" aria-label="breadcrumb"
data-slot="breadcrumb" data-slot="breadcrumb"
:class="cn('', props.class)" :class="props.class"
> >
<slot /> <slot />
</nav> </nav>
@@ -1,11 +1,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { MoreHorizontal } from "@lucide/vue"
import { MoreHorizontalIcon } from '@lucide/vue' import { cn } from "@/lib/utils"
import { cn } from '@/lib/utils'
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -14,10 +13,10 @@ const props = defineProps<{
data-slot="breadcrumb-ellipsis" data-slot="breadcrumb-ellipsis"
role="presentation" role="presentation"
aria-hidden="true" aria-hidden="true"
:class="cn('size-5 [&>svg]:size-4 flex items-center justify-center', props.class)" :class="cn('flex size-9 items-center justify-center', props.class)"
> >
<slot> <slot>
<MoreHorizontalIcon /> <MoreHorizontal class="size-4" />
</slot> </slot>
<span class="sr-only">More</span> <span class="sr-only">More</span>
</span> </span>
@@ -1,16 +1,16 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
<template> <template>
<li <li
data-slot="breadcrumb-item" data-slot="breadcrumb-item"
:class="cn('gap-1 inline-flex items-center', props.class)" :class="cn('inline-flex items-center gap-1.5', props.class)"
> >
<slot /> <slot />
</li> </li>
@@ -1,11 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { PrimitiveProps } from 'reka-ui' import type { PrimitiveProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { Primitive } from 'reka-ui' import { Primitive } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = withDefaults(defineProps<PrimitiveProps & { class?: HTMLAttributes['class'] }>(), { const props = withDefaults(defineProps<PrimitiveProps & { class?: HTMLAttributes["class"] }>(), {
as: 'a', as: "a",
}) })
</script> </script>
@@ -1,16 +1,16 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
<template> <template>
<ol <ol
data-slot="breadcrumb-list" data-slot="breadcrumb-list"
:class="cn('text-muted-foreground gap-1.5 text-sm flex flex-wrap items-center wrap-break-word', props.class)" :class="cn('text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5', props.class)"
> >
<slot /> <slot />
</ol> </ol>
@@ -1,9 +1,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -1,11 +1,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { ChevronRight } from "@lucide/vue"
import { ChevronRightIcon } from '@lucide/vue' import { cn } from "@/lib/utils"
import { cn } from '@/lib/utils'
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -17,7 +16,7 @@ const props = defineProps<{
:class="cn('[&>svg]:size-3.5', props.class)" :class="cn('[&>svg]:size-3.5', props.class)"
> >
<slot> <slot>
<ChevronRightIcon class="cn-rtl-flip" /> <ChevronRight />
</slot> </slot>
</li> </li>
</template> </template>
+7 -7
View File
@@ -1,7 +1,7 @@
export { default as Breadcrumb } from './Breadcrumb.vue' export { default as Breadcrumb } from "./Breadcrumb.vue"
export { default as BreadcrumbEllipsis } from './BreadcrumbEllipsis.vue' export { default as BreadcrumbEllipsis } from "./BreadcrumbEllipsis.vue"
export { default as BreadcrumbItem } from './BreadcrumbItem.vue' export { default as BreadcrumbItem } from "./BreadcrumbItem.vue"
export { default as BreadcrumbLink } from './BreadcrumbLink.vue' export { default as BreadcrumbLink } from "./BreadcrumbLink.vue"
export { default as BreadcrumbList } from './BreadcrumbList.vue' export { default as BreadcrumbList } from "./BreadcrumbList.vue"
export { default as BreadcrumbPage } from './BreadcrumbPage.vue' export { default as BreadcrumbPage } from "./BreadcrumbPage.vue"
export { default as BreadcrumbSeparator } from './BreadcrumbSeparator.vue' export { default as BreadcrumbSeparator } from "./BreadcrumbSeparator.vue"
+10 -10
View File
@@ -1,19 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import type { PrimitiveProps } from 'reka-ui' import type { PrimitiveProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import type { ButtonVariants } from '.' import type { ButtonVariants } from "."
import { Primitive } from 'reka-ui' import { Primitive } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
import { buttonVariants } from '.' import { buttonVariants } from "."
interface Props extends PrimitiveProps { interface Props extends PrimitiveProps {
variant?: ButtonVariants['variant'] variant?: ButtonVariants["variant"]
size?: ButtonVariants['size'] size?: ButtonVariants["size"]
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
as: 'button', as: "button",
}) })
</script> </script>
+23 -20
View File
@@ -1,34 +1,37 @@
import type { VariantProps } from 'class-variance-authority' import type { VariantProps } from "class-variance-authority"
import { cva } from 'class-variance-authority' import { cva } from "class-variance-authority"
export { default as Button } from './Button.vue' export { default as Button } from "./Button.vue"
export const buttonVariants = cva( export const buttonVariants = cva(
'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 active:not-aria-[haspopup]:translate-y-px [&_svg:not([class*=size-])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-all outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0', "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
{ {
variants: { variants: {
variant: { variant: {
default: 'bg-primary text-primary-foreground [a]:hover:bg-primary/80', default:
outline: 'border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground', "bg-primary text-primary-foreground hover:bg-primary/90",
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground', destructive:
ghost: 'hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground', "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
destructive: 'bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30', outline:
link: 'text-primary underline-offset-4 hover:underline', "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost:
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
link: "text-primary underline-offset-4 hover:underline",
}, },
size: { size: {
'default': 'h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2', "default": "h-9 px-4 py-2 has-[>svg]:px-3",
'xs': 'h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*=size-])]:size-3', "sm": "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
'sm': 'h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*=size-])]:size-3.5', "lg": "h-10 rounded-md px-6 has-[>svg]:px-4",
'lg': 'h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2', "icon": "size-9",
'icon': 'size-8', "icon-sm": "size-8",
'icon-xs': 'size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*=size-])]:size-3', "icon-lg": "size-10",
'icon-sm': 'size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg',
'icon-lg': 'size-9',
}, },
}, },
defaultVariants: { defaultVariants: {
variant: 'default', variant: "default",
size: 'default', size: "default",
}, },
}, },
) )
+11 -10
View File
@@ -1,20 +1,21 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = withDefaults(defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
size?: 'default' | 'sm' }>()
}>(), {
size: 'default',
})
</script> </script>
<template> <template>
<div <div
data-slot="card" data-slot="card"
:data-size="size" :class="
:class="cn('ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-xl py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col', props.class)" cn(
'bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm',
props.class,
)
"
> >
<slot /> <slot />
</div> </div>
+3 -3
View File
@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
+4 -4
View File
@@ -1,16 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
<template> <template>
<div <div
data-slot="card-content" data-slot="card-content"
:class="cn('px-4 group-data-[size=sm]/card:px-3', props.class)" :class="cn('px-6', props.class)"
> >
<slot /> <slot />
</div> </div>
+5 -5
View File
@@ -1,17 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
<template> <template>
<div <p
data-slot="card-description" data-slot="card-description"
:class="cn('text-muted-foreground text-sm', props.class)" :class="cn('text-muted-foreground text-sm', props.class)"
> >
<slot /> <slot />
</div> </p>
</template> </template>
+4 -4
View File
@@ -1,16 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
<template> <template>
<div <div
data-slot="card-footer" data-slot="card-footer"
:class="cn('bg-muted/50 rounded-b-xl border-t p-4 group-data-[size=sm]/card:p-3 flex items-center', props.class)" :class="cn('flex items-center px-6 [.border-t]:pt-6', props.class)"
> >
<slot /> <slot />
</div> </div>
+4 -4
View File
@@ -1,16 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
<template> <template>
<div <div
data-slot="card-header" data-slot="card-header"
:class="cn('gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]', props.class)" :class="cn('@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6', props.class)"
> >
<slot /> <slot />
</div> </div>
+6 -6
View File
@@ -1,17 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
<template> <template>
<div <h3
data-slot="card-title" data-slot="card-title"
:class="cn('text-base leading-snug font-medium group-data-[size=sm]/card:text-sm cn-font-heading', props.class)" :class="cn('leading-none font-semibold', props.class)"
> >
<slot /> <slot />
</div> </h3>
</template> </template>
+7 -7
View File
@@ -1,7 +1,7 @@
export { default as Card } from './Card.vue' export { default as Card } from "./Card.vue"
export { default as CardAction } from './CardAction.vue' export { default as CardAction } from "./CardAction.vue"
export { default as CardContent } from './CardContent.vue' export { default as CardContent } from "./CardContent.vue"
export { default as CardDescription } from './CardDescription.vue' export { default as CardDescription } from "./CardDescription.vue"
export { default as CardFooter } from './CardFooter.vue' export { default as CardFooter } from "./CardFooter.vue"
export { default as CardHeader } from './CardHeader.vue' export { default as CardHeader } from "./CardHeader.vue"
export { default as CardTitle } from './CardTitle.vue' export { default as CardTitle } from "./CardTitle.vue"
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { CollapsibleRootEmits, CollapsibleRootProps } from 'reka-ui' import type { CollapsibleRootEmits, CollapsibleRootProps } from "reka-ui"
import { CollapsibleRoot, useForwardPropsEmits } from 'reka-ui' import { CollapsibleRoot, useForwardPropsEmits } from "reka-ui"
const props = defineProps<CollapsibleRootProps>() const props = defineProps<CollapsibleRootProps>()
const emits = defineEmits<CollapsibleRootEmits>() const emits = defineEmits<CollapsibleRootEmits>()
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { CollapsibleContentProps } from 'reka-ui' import type { CollapsibleContentProps } from "reka-ui"
import { CollapsibleContent } from 'reka-ui' import { CollapsibleContent } from "reka-ui"
const props = defineProps<CollapsibleContentProps>() const props = defineProps<CollapsibleContentProps>()
</script> </script>
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { CollapsibleTriggerProps } from 'reka-ui' import type { CollapsibleTriggerProps } from "reka-ui"
import { CollapsibleTrigger } from 'reka-ui' import { CollapsibleTrigger } from "reka-ui"
const props = defineProps<CollapsibleTriggerProps>() const props = defineProps<CollapsibleTriggerProps>()
</script> </script>
+3 -3
View File
@@ -1,3 +1,3 @@
export { default as Collapsible } from './Collapsible.vue' export { default as Collapsible } from "./Collapsible.vue"
export { default as CollapsibleContent } from './CollapsibleContent.vue' export { default as CollapsibleContent } from "./CollapsibleContent.vue"
export { default as CollapsibleTrigger } from './CollapsibleTrigger.vue' export { default as CollapsibleTrigger } from "./CollapsibleTrigger.vue"
+2 -2
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogRootEmits, DialogRootProps } from 'reka-ui' import type { DialogRootEmits, DialogRootProps } from "reka-ui"
import { DialogRoot, useForwardPropsEmits } from 'reka-ui' import { DialogRoot, useForwardPropsEmits } from "reka-ui"
const props = defineProps<DialogRootProps>() const props = defineProps<DialogRootProps>()
const emits = defineEmits<DialogRootEmits>() const emits = defineEmits<DialogRootEmits>()
+2 -2
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogCloseProps } from 'reka-ui' import type { DialogCloseProps } from "reka-ui"
import { DialogClose } from 'reka-ui' import { DialogClose } from "reka-ui"
const props = defineProps<DialogCloseProps>() const props = defineProps<DialogCloseProps>()
</script> </script>
+17 -17
View File
@@ -1,29 +1,27 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogContentEmits, DialogContentProps } from 'reka-ui' import type { DialogContentEmits, DialogContentProps } from "reka-ui"
import type { HTMLAttributes } from "vue"
import type { HTMLAttributes } from 'vue' import { X } from "@lucide/vue"
import { XIcon } from '@lucide/vue' import { reactiveOmit } from "@vueuse/core"
import { reactiveOmit } from '@vueuse/core'
import { import {
DialogClose, DialogClose,
DialogContent, DialogContent,
DialogPortal, DialogPortal,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
import { Button } from '@/components/ui/button' import DialogOverlay from "./DialogOverlay.vue"
import DialogOverlay from './DialogOverlay.vue'
defineOptions({ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}) })
const props = withDefaults(defineProps<DialogContentProps & { class?: HTMLAttributes['class'], showCloseButton?: boolean }>(), { const props = withDefaults(defineProps<DialogContentProps & { class?: HTMLAttributes["class"], showCloseButton?: boolean }>(), {
showCloseButton: true, showCloseButton: true,
}) })
const emits = defineEmits<DialogContentEmits>() const emits = defineEmits<DialogContentEmits>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
const forwarded = useForwardPropsEmits(delegatedProps, emits) const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
@@ -34,19 +32,21 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
<DialogContent <DialogContent
data-slot="dialog-content" data-slot="dialog-content"
v-bind="{ ...$attrs, ...forwarded }" v-bind="{ ...$attrs, ...forwarded }"
:class="cn('bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-foreground/10 grid max-w-[calc(100%-2rem)] gap-4 rounded-xl p-4 text-sm ring-1 duration-100 sm:max-w-sm fixed top-1/2 left-1/2 z-50 w-full -translate-x-1/2 -translate-y-1/2 outline-none', props.class)" :class="
cn(
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
props.class,
)"
> >
<slot /> <slot />
<DialogClose <DialogClose
v-if="showCloseButton" v-if="showCloseButton"
data-slot="dialog-close" data-slot="dialog-close"
as-child class="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
> >
<Button variant="ghost" class="absolute top-2 right-2" size="icon-sm"> <X />
<XIcon /> <span class="sr-only">Close</span>
<span class="sr-only">Close</span>
</Button>
</DialogClose> </DialogClose>
</DialogContent> </DialogContent>
</DialogPortal> </DialogPortal>
@@ -1,13 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogDescriptionProps } from 'reka-ui' import type { DialogDescriptionProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { DialogDescription, useForwardProps } from 'reka-ui' import { DialogDescription, useForwardProps } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes["class"] }>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
const forwardedProps = useForwardProps(delegatedProps) const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
@@ -16,7 +16,7 @@ const forwardedProps = useForwardProps(delegatedProps)
<DialogDescription <DialogDescription
data-slot="dialog-description" data-slot="dialog-description"
v-bind="forwardedProps" v-bind="forwardedProps"
:class="cn('text-muted-foreground *:[a]:hover:text-foreground text-sm *:[a]:underline *:[a]:underline-offset-3', props.class)" :class="cn('text-muted-foreground text-sm', props.class)"
> >
<slot /> <slot />
</DialogDescription> </DialogDescription>
+5 -5
View File
@@ -1,11 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { DialogClose } from 'reka-ui' import { DialogClose } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
showCloseButton?: boolean showCloseButton?: boolean
}>(), { }>(), {
showCloseButton: false, showCloseButton: false,
@@ -15,7 +15,7 @@ const props = withDefaults(defineProps<{
<template> <template>
<div <div
data-slot="dialog-footer" data-slot="dialog-footer"
:class="cn('bg-muted/50 -mx-4 -mb-4 rounded-b-xl border-t p-4 flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', props.class)" :class="cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', props.class)"
> >
<slot /> <slot />
<DialogClose v-if="showCloseButton" as-child> <DialogClose v-if="showCloseButton" as-child>
+4 -4
View File
@@ -1,16 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
<template> <template>
<div <div
data-slot="dialog-header" data-slot="dialog-header"
:class="cn('gap-2 flex flex-col', props.class)" :class="cn('flex flex-col gap-2 text-center sm:text-left', props.class)"
> >
<slot /> <slot />
</div> </div>
+8 -8
View File
@@ -1,20 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogOverlayProps } from 'reka-ui' import type { DialogOverlayProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { DialogOverlay } from 'reka-ui' import { DialogOverlay } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<DialogOverlayProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogOverlayProps & { class?: HTMLAttributes["class"] }>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
</script> </script>
<template> <template>
<DialogOverlay <DialogOverlay
data-slot="dialog-overlay" data-slot="dialog-overlay"
v-bind="delegatedProps" v-bind="delegatedProps"
:class="cn('data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 isolate z-50', props.class)" :class="cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80', props.class)"
> >
<slot /> <slot />
</DialogOverlay> </DialogOverlay>
@@ -1,26 +1,25 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogContentEmits, DialogContentProps } from 'reka-ui' import type { DialogContentEmits, DialogContentProps } from "reka-ui"
import type { HTMLAttributes } from "vue"
import type { HTMLAttributes } from 'vue' import { X } from "@lucide/vue"
import { XIcon } from '@lucide/vue' import { reactiveOmit } from "@vueuse/core"
import { reactiveOmit } from '@vueuse/core'
import { import {
DialogClose, DialogClose,
DialogContent, DialogContent,
DialogOverlay, DialogOverlay,
DialogPortal, DialogPortal,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
defineOptions({ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}) })
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogContentProps & { class?: HTMLAttributes["class"] }>()
const emits = defineEmits<DialogContentEmits>() const emits = defineEmits<DialogContentEmits>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
const forwarded = useForwardPropsEmits(delegatedProps, emits) const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
@@ -51,7 +50,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
<DialogClose <DialogClose
class="absolute top-4 right-4 p-0.5 transition-colors rounded-md hover:bg-secondary" class="absolute top-4 right-4 p-0.5 transition-colors rounded-md hover:bg-secondary"
> >
<XIcon class="w-4 h-4" /> <X class="w-4 h-4" />
<span class="sr-only">Close</span> <span class="sr-only">Close</span>
</DialogClose> </DialogClose>
</DialogContent> </DialogContent>
+8 -8
View File
@@ -1,13 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogTitleProps } from 'reka-ui' import type { DialogTitleProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { DialogTitle, useForwardProps } from 'reka-ui' import { DialogTitle, useForwardProps } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<DialogTitleProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogTitleProps & { class?: HTMLAttributes["class"] }>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
const forwardedProps = useForwardProps(delegatedProps) const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
@@ -16,7 +16,7 @@ const forwardedProps = useForwardProps(delegatedProps)
<DialogTitle <DialogTitle
data-slot="dialog-title" data-slot="dialog-title"
v-bind="forwardedProps" v-bind="forwardedProps"
:class="cn('text-base leading-none font-medium cn-font-heading', props.class)" :class="cn('text-lg leading-none font-semibold', props.class)"
> >
<slot /> <slot />
</DialogTitle> </DialogTitle>
+2 -2
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogTriggerProps } from 'reka-ui' import type { DialogTriggerProps } from "reka-ui"
import { DialogTrigger } from 'reka-ui' import { DialogTrigger } from "reka-ui"
const props = defineProps<DialogTriggerProps>() const props = defineProps<DialogTriggerProps>()
</script> </script>
+10 -10
View File
@@ -1,10 +1,10 @@
export { default as Dialog } from './Dialog.vue' export { default as Dialog } from "./Dialog.vue"
export { default as DialogClose } from './DialogClose.vue' export { default as DialogClose } from "./DialogClose.vue"
export { default as DialogContent } from './DialogContent.vue' export { default as DialogContent } from "./DialogContent.vue"
export { default as DialogDescription } from './DialogDescription.vue' export { default as DialogDescription } from "./DialogDescription.vue"
export { default as DialogFooter } from './DialogFooter.vue' export { default as DialogFooter } from "./DialogFooter.vue"
export { default as DialogHeader } from './DialogHeader.vue' export { default as DialogHeader } from "./DialogHeader.vue"
export { default as DialogOverlay } from './DialogOverlay.vue' export { default as DialogOverlay } from "./DialogOverlay.vue"
export { default as DialogScrollContent } from './DialogScrollContent.vue' export { default as DialogScrollContent } from "./DialogScrollContent.vue"
export { default as DialogTitle } from './DialogTitle.vue' export { default as DialogTitle } from "./DialogTitle.vue"
export { default as DialogTrigger } from './DialogTrigger.vue' export { default as DialogTrigger } from "./DialogTrigger.vue"
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DropdownMenuRootEmits, DropdownMenuRootProps } from 'reka-ui' import type { DropdownMenuRootEmits, DropdownMenuRootProps } from "reka-ui"
import { DropdownMenuRoot, useForwardPropsEmits } from 'reka-ui' import { DropdownMenuRoot, useForwardPropsEmits } from "reka-ui"
const props = defineProps<DropdownMenuRootProps>() const props = defineProps<DropdownMenuRootProps>()
const emits = defineEmits<DropdownMenuRootEmits>() const emits = defineEmits<DropdownMenuRootEmits>()
@@ -1,20 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DropdownMenuCheckboxItemEmits, DropdownMenuCheckboxItemProps } from 'reka-ui' import type { DropdownMenuCheckboxItemEmits, DropdownMenuCheckboxItemProps } from "reka-ui"
import type { HTMLAttributes } from "vue"
import type { HTMLAttributes } from 'vue' import { Check } from "@lucide/vue"
import { CheckIcon } from '@lucide/vue' import { reactiveOmit } from "@vueuse/core"
import { reactiveOmit } from '@vueuse/core'
import { import {
DropdownMenuCheckboxItem, DropdownMenuCheckboxItem,
DropdownMenuItemIndicator, DropdownMenuItemIndicator,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<DropdownMenuCheckboxItemProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DropdownMenuCheckboxItemProps & { class?: HTMLAttributes["class"] }>()
const emits = defineEmits<DropdownMenuCheckboxItemEmits>() const emits = defineEmits<DropdownMenuCheckboxItemEmits>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
const forwarded = useForwardPropsEmits(delegatedProps, emits) const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
@@ -23,18 +22,15 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
<DropdownMenuCheckboxItem <DropdownMenuCheckboxItem
data-slot="dropdown-menu-checkbox-item" data-slot="dropdown-menu-checkbox-item"
v-bind="forwarded" v-bind="forwarded"
:class="cn( :class=" cn(
'focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm data-inset:pl-7 [&_svg:not([class*=size-])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0', 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
props.class, props.class,
)" )"
> >
<span <span class="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
class="absolute right-2 flex items-center justify-center pointer-events-none"
data-slot="dropdown-menu-checkbox-item-indicator"
>
<DropdownMenuItemIndicator> <DropdownMenuItemIndicator>
<slot name="indicator-icon"> <slot name="indicator-icon">
<CheckIcon /> <Check class="size-4" />
</slot> </slot>
</DropdownMenuItemIndicator> </DropdownMenuItemIndicator>
</span> </span>
@@ -1,28 +1,27 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DropdownMenuContentEmits, DropdownMenuContentProps } from 'reka-ui' import type { DropdownMenuContentEmits, DropdownMenuContentProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { import {
DropdownMenuContent, DropdownMenuContent,
DropdownMenuPortal, DropdownMenuPortal,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
defineOptions({ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}) })
const props = withDefaults( const props = withDefaults(
defineProps<DropdownMenuContentProps & { class?: HTMLAttributes['class'] }>(), defineProps<DropdownMenuContentProps & { class?: HTMLAttributes["class"] }>(),
{ {
align: 'start',
sideOffset: 4, sideOffset: 4,
}, },
) )
const emits = defineEmits<DropdownMenuContentEmits>() const emits = defineEmits<DropdownMenuContentEmits>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
const forwarded = useForwardPropsEmits(delegatedProps, emits) const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
@@ -32,7 +31,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
<DropdownMenuContent <DropdownMenuContent
data-slot="dropdown-menu-content" data-slot="dropdown-menu-content"
v-bind="{ ...$attrs, ...forwarded }" v-bind="{ ...$attrs, ...forwarded }"
:class="cn('data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground min-w-32 rounded-lg p-1 shadow-md ring-1 duration-100 cn-menu-translucent z-50 max-h-(--reka-dropdown-menu-content-available-height) w-(--reka-dropdown-menu-trigger-width) origin-(--reka-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto data-[state=closed]:overflow-hidden', props.class)" :class="cn('bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--reka-dropdown-menu-content-available-height) min-w-[8rem] origin-(--reka-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md', props.class)"
> >
<slot /> <slot />
</DropdownMenuContent> </DropdownMenuContent>
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DropdownMenuGroupProps } from 'reka-ui' import type { DropdownMenuGroupProps } from "reka-ui"
import { DropdownMenuGroup } from 'reka-ui' import { DropdownMenuGroup } from "reka-ui"
const props = defineProps<DropdownMenuGroupProps>() const props = defineProps<DropdownMenuGroupProps>()
</script> </script>
@@ -1,19 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DropdownMenuItemProps } from 'reka-ui' import type { DropdownMenuItemProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { DropdownMenuItem, useForwardProps } from 'reka-ui' import { DropdownMenuItem, useForwardProps } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = withDefaults(defineProps<DropdownMenuItemProps & { const props = withDefaults(defineProps<DropdownMenuItemProps & {
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
inset?: boolean inset?: boolean
variant?: 'default' | 'destructive' variant?: "default" | "destructive"
}>(), { }>(), {
variant: 'default', variant: "default",
}) })
const delegatedProps = reactiveOmit(props, 'inset', 'variant', 'class') const delegatedProps = reactiveOmit(props, "inset", "variant", "class")
const forwardedProps = useForwardProps(delegatedProps) const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
@@ -24,7 +24,7 @@ const forwardedProps = useForwardProps(delegatedProps)
:data-inset="inset ? '' : undefined" :data-inset="inset ? '' : undefined"
:data-variant="variant" :data-variant="variant"
v-bind="forwardedProps" v-bind="forwardedProps"
:class="cn('focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md px-1.5 py-1 text-sm data-inset:pl-7 [&_svg:not([class*=size-])]:size-4 group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0', props.class)" :class="cn('focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*=\'text-\'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4', props.class)"
> >
<slot /> <slot />
</DropdownMenuItem> </DropdownMenuItem>
@@ -1,13 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DropdownMenuLabelProps } from 'reka-ui' import type { DropdownMenuLabelProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { DropdownMenuLabel, useForwardProps } from 'reka-ui' import { DropdownMenuLabel, useForwardProps } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<DropdownMenuLabelProps & { class?: HTMLAttributes['class'], inset?: boolean }>() const props = defineProps<DropdownMenuLabelProps & { class?: HTMLAttributes["class"], inset?: boolean }>()
const delegatedProps = reactiveOmit(props, 'class', 'inset') const delegatedProps = reactiveOmit(props, "class", "inset")
const forwardedProps = useForwardProps(delegatedProps) const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
@@ -16,7 +16,7 @@ const forwardedProps = useForwardProps(delegatedProps)
data-slot="dropdown-menu-label" data-slot="dropdown-menu-label"
:data-inset="inset ? '' : undefined" :data-inset="inset ? '' : undefined"
v-bind="forwardedProps" v-bind="forwardedProps"
:class="cn('text-muted-foreground px-1.5 py-1 text-xs font-medium data-inset:pl-7', props.class)" :class="cn('px-2 py-1.5 text-sm font-medium data-[inset]:pl-8', props.class)"
> >
<slot /> <slot />
</DropdownMenuLabel> </DropdownMenuLabel>
@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DropdownMenuRadioGroupEmits, DropdownMenuRadioGroupProps } from 'reka-ui' import type { DropdownMenuRadioGroupEmits, DropdownMenuRadioGroupProps } from "reka-ui"
import { import {
DropdownMenuRadioGroup, DropdownMenuRadioGroup,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from "reka-ui"
const props = defineProps<DropdownMenuRadioGroupProps>() const props = defineProps<DropdownMenuRadioGroupProps>()
const emits = defineEmits<DropdownMenuRadioGroupEmits>() const emits = defineEmits<DropdownMenuRadioGroupEmits>()
@@ -1,21 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DropdownMenuRadioItemEmits, DropdownMenuRadioItemProps } from 'reka-ui' import type { DropdownMenuRadioItemEmits, DropdownMenuRadioItemProps } from "reka-ui"
import type { HTMLAttributes } from "vue"
import type { HTMLAttributes } from 'vue' import { Circle } from "@lucide/vue"
import { CheckIcon } from '@lucide/vue' import { reactiveOmit } from "@vueuse/core"
import { reactiveOmit } from '@vueuse/core'
import { import {
DropdownMenuItemIndicator, DropdownMenuItemIndicator,
DropdownMenuRadioItem, DropdownMenuRadioItem,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<DropdownMenuRadioItemProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DropdownMenuRadioItemProps & { class?: HTMLAttributes["class"] }>()
const emits = defineEmits<DropdownMenuRadioItemEmits>() const emits = defineEmits<DropdownMenuRadioItemEmits>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
const forwarded = useForwardPropsEmits(delegatedProps, emits) const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
@@ -25,17 +24,14 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
data-slot="dropdown-menu-radio-item" data-slot="dropdown-menu-radio-item"
v-bind="forwarded" v-bind="forwarded"
:class="cn( :class="cn(
'focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm data-inset:pl-7 [&_svg:not([class*=size-])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0', 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
props.class, props.class,
)" )"
> >
<span <span class="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
class="absolute right-2 flex items-center justify-center pointer-events-none"
data-slot="dropdown-menu-radio-item-indicator"
>
<DropdownMenuItemIndicator> <DropdownMenuItemIndicator>
<slot name="indicator-icon"> <slot name="indicator-icon">
<CheckIcon /> <Circle class="size-2 fill-current" />
</slot> </slot>
</DropdownMenuItemIndicator> </DropdownMenuItemIndicator>
</span> </span>
@@ -1,17 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DropdownMenuSeparatorProps } from 'reka-ui' import type { DropdownMenuSeparatorProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { import {
DropdownMenuSeparator, DropdownMenuSeparator,
} from 'reka-ui' } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<DropdownMenuSeparatorProps & { const props = defineProps<DropdownMenuSeparatorProps & {
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
</script> </script>
<template> <template>
@@ -1,16 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
<template> <template>
<span <span
data-slot="dropdown-menu-shortcut" data-slot="dropdown-menu-shortcut"
:class="cn('text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground ml-auto text-xs tracking-widest', props.class)" :class="cn('text-muted-foreground ml-auto text-xs tracking-widest', props.class)"
> >
<slot /> <slot />
</span> </span>
@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DropdownMenuSubEmits, DropdownMenuSubProps } from 'reka-ui' import type { DropdownMenuSubEmits, DropdownMenuSubProps } from "reka-ui"
import { import {
DropdownMenuSub, DropdownMenuSub,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from "reka-ui"
const props = defineProps<DropdownMenuSubProps>() const props = defineProps<DropdownMenuSubProps>()
const emits = defineEmits<DropdownMenuSubEmits>() const emits = defineEmits<DropdownMenuSubEmits>()
@@ -1,17 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DropdownMenuSubContentEmits, DropdownMenuSubContentProps } from 'reka-ui' import type { DropdownMenuSubContentEmits, DropdownMenuSubContentProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { import {
DropdownMenuSubContent, DropdownMenuSubContent,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<DropdownMenuSubContentProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DropdownMenuSubContentProps & { class?: HTMLAttributes["class"] }>()
const emits = defineEmits<DropdownMenuSubContentEmits>() const emits = defineEmits<DropdownMenuSubContentEmits>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
const forwarded = useForwardPropsEmits(delegatedProps, emits) const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
@@ -20,7 +20,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
<DropdownMenuSubContent <DropdownMenuSubContent
data-slot="dropdown-menu-sub-content" data-slot="dropdown-menu-sub-content"
v-bind="forwarded" v-bind="forwarded"
:class="cn('data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground min-w-[96px] rounded-lg p-1 shadow-lg ring-1 duration-100 cn-menu-translucent z-50 origin-(--reka-dropdown-menu-content-transform-origin) overflow-hidden', props.class)" :class="cn('bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--reka-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg', props.class)"
> >
<slot /> <slot />
</DropdownMenuSubContent> </DropdownMenuSubContent>
@@ -1,32 +1,31 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DropdownMenuSubTriggerProps } from 'reka-ui' import type { DropdownMenuSubTriggerProps } from "reka-ui"
import type { HTMLAttributes } from "vue"
import type { HTMLAttributes } from 'vue' import { ChevronRight } from "@lucide/vue"
import { ChevronRightIcon } from '@lucide/vue' import { reactiveOmit } from "@vueuse/core"
import { reactiveOmit } from '@vueuse/core'
import { import {
DropdownMenuSubTrigger, DropdownMenuSubTrigger,
useForwardProps, useForwardProps,
} from 'reka-ui' } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<DropdownMenuSubTriggerProps & { class?: HTMLAttributes['class'], inset?: boolean }>() const props = defineProps<DropdownMenuSubTriggerProps & { class?: HTMLAttributes["class"], inset?: boolean }>()
const delegatedProps = reactiveOmit(props, 'class', 'inset') const delegatedProps = reactiveOmit(props, "class", "inset")
const forwardedProps = useForwardProps(delegatedProps) const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
<template> <template>
<DropdownMenuSubTrigger <DropdownMenuSubTrigger
data-slot="dropdown-menu-sub-trigger" data-slot="dropdown-menu-sub-trigger"
:data-inset="inset ? '' : undefined"
v-bind="forwardedProps" v-bind="forwardedProps"
:data-inset="inset ? '' : undefined"
:class="cn( :class="cn(
'focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md px-1.5 py-1 text-sm data-inset:pl-7 [&_svg:not([class*=size-])]:size-4 flex cursor-default items-center outline-hidden select-none [&_svg]:pointer-events-none [&_svg]:shrink-0', 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4 data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*=\'text-\'])]:text-muted-foreground',
props.class, props.class,
)" )"
> >
<slot /> <slot />
<ChevronRightIcon class="cn-rtl-flip ml-auto" /> <ChevronRight class="ml-auto size-4" />
</DropdownMenuSubTrigger> </DropdownMenuSubTrigger>
</template> </template>
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DropdownMenuTriggerProps } from 'reka-ui' import type { DropdownMenuTriggerProps } from "reka-ui"
import { DropdownMenuTrigger, useForwardProps } from 'reka-ui' import { DropdownMenuTrigger, useForwardProps } from "reka-ui"
const props = defineProps<DropdownMenuTriggerProps>() const props = defineProps<DropdownMenuTriggerProps>()
+15 -15
View File
@@ -1,16 +1,16 @@
export { default as DropdownMenu } from './DropdownMenu.vue' export { default as DropdownMenu } from "./DropdownMenu.vue"
export { default as DropdownMenuCheckboxItem } from './DropdownMenuCheckboxItem.vue' export { default as DropdownMenuCheckboxItem } from "./DropdownMenuCheckboxItem.vue"
export { default as DropdownMenuContent } from './DropdownMenuContent.vue' export { default as DropdownMenuContent } from "./DropdownMenuContent.vue"
export { default as DropdownMenuGroup } from './DropdownMenuGroup.vue' export { default as DropdownMenuGroup } from "./DropdownMenuGroup.vue"
export { default as DropdownMenuItem } from './DropdownMenuItem.vue' export { default as DropdownMenuItem } from "./DropdownMenuItem.vue"
export { default as DropdownMenuLabel } from './DropdownMenuLabel.vue' export { default as DropdownMenuLabel } from "./DropdownMenuLabel.vue"
export { default as DropdownMenuRadioGroup } from './DropdownMenuRadioGroup.vue' export { default as DropdownMenuRadioGroup } from "./DropdownMenuRadioGroup.vue"
export { default as DropdownMenuRadioItem } from './DropdownMenuRadioItem.vue' export { default as DropdownMenuRadioItem } from "./DropdownMenuRadioItem.vue"
export { default as DropdownMenuSeparator } from './DropdownMenuSeparator.vue' export { default as DropdownMenuSeparator } from "./DropdownMenuSeparator.vue"
export { default as DropdownMenuShortcut } from './DropdownMenuShortcut.vue' export { default as DropdownMenuShortcut } from "./DropdownMenuShortcut.vue"
export { default as DropdownMenuSub } from './DropdownMenuSub.vue' export { default as DropdownMenuSub } from "./DropdownMenuSub.vue"
export { default as DropdownMenuSubContent } from './DropdownMenuSubContent.vue' export { default as DropdownMenuSubContent } from "./DropdownMenuSubContent.vue"
export { default as DropdownMenuSubTrigger } from './DropdownMenuSubTrigger.vue' export { default as DropdownMenuSubTrigger } from "./DropdownMenuSubTrigger.vue"
export { default as DropdownMenuTrigger } from './DropdownMenuTrigger.vue' export { default as DropdownMenuTrigger } from "./DropdownMenuTrigger.vue"
export { DropdownMenuPortal } from 'reka-ui' export { DropdownMenuPortal } from "reka-ui"
+9 -7
View File
@@ -1,19 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { useVModel } from '@vueuse/core' import { useVModel } from "@vueuse/core"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
defaultValue?: string | number defaultValue?: string | number
modelValue?: string | number modelValue?: string | number
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
const emits = defineEmits<{ const emits = defineEmits<{
(e: 'update:modelValue', payload: string | number): void (e: "update:modelValue", payload: string | number): void
}>() }>()
const modelValue = useVModel(props, 'modelValue', emits, { const modelValue = useVModel(props, "modelValue", emits, {
passive: true, passive: true,
defaultValue: props.defaultValue, defaultValue: props.defaultValue,
}) })
@@ -24,7 +24,9 @@ const modelValue = useVModel(props, 'modelValue', emits, {
v-model="modelValue" v-model="modelValue"
data-slot="input" data-slot="input"
:class="cn( :class="cn(
'dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 rounded-lg border bg-transparent px-2.5 py-1 text-base transition-colors file:h-6 file:text-sm file:font-medium focus-visible:ring-3 aria-invalid:ring-3 md:text-sm w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50', 'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
props.class, props.class,
)" )"
> >
+1 -1
View File
@@ -1 +1 @@
export { default as Input } from './Input.vue' export { default as Input } from "./Input.vue"
+2 -2
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectRootEmits, SelectRootProps } from 'reka-ui' import type { SelectRootEmits, SelectRootProps } from "reka-ui"
import { SelectRoot, useForwardPropsEmits } from 'reka-ui' import { SelectRoot, useForwardPropsEmits } from "reka-ui"
const props = defineProps<SelectRootProps>() const props = defineProps<SelectRootProps>()
const emits = defineEmits<SelectRootEmits>() const emits = defineEmits<SelectRootEmits>()
+11 -18
View File
@@ -1,30 +1,29 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectContentEmits, SelectContentProps } from 'reka-ui' import type { SelectContentEmits, SelectContentProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { import {
SelectContent, SelectContent,
SelectPortal, SelectPortal,
SelectViewport, SelectViewport,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
import { SelectScrollDownButton, SelectScrollUpButton } from '.' import { SelectScrollDownButton, SelectScrollUpButton } from "."
defineOptions({ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}) })
const props = withDefaults( const props = withDefaults(
defineProps<SelectContentProps & { class?: HTMLAttributes['class'] }>(), defineProps<SelectContentProps & { class?: HTMLAttributes["class"] }>(),
{ {
position: 'item-aligned', position: "popper",
align: 'center',
}, },
) )
const emits = defineEmits<SelectContentEmits>() const emits = defineEmits<SelectContentEmits>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
const forwarded = useForwardPropsEmits(delegatedProps, emits) const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
@@ -33,10 +32,9 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
<SelectPortal> <SelectPortal>
<SelectContent <SelectContent
data-slot="select-content" data-slot="select-content"
:data-align-trigger="position === 'item-aligned'"
v-bind="{ ...$attrs, ...forwarded }" v-bind="{ ...$attrs, ...forwarded }"
:class="cn( :class="cn(
'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 min-w-36 rounded-lg shadow-md ring-1 duration-100 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 cn-menu-translucent relative z-50 max-h-(--reka-select-content-available-height) origin-(--reka-select-content-transform-origin) overflow-x-hidden overflow-y-auto data-[align-trigger=true]:animate-none', 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--reka-select-content-available-height) min-w-[8rem] overflow-x-hidden overflow-y-auto rounded-md border shadow-md',
position === 'popper' position === 'popper'
&& 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1', && 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
props.class, props.class,
@@ -44,12 +42,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
" "
> >
<SelectScrollUpButton /> <SelectScrollUpButton />
<SelectViewport <SelectViewport :class="cn('p-1', position === 'popper' && 'h-[var(--reka-select-trigger-height)] w-full min-w-[var(--reka-select-trigger-width)] scroll-my-1')">
:data-position="position"
:class="cn(
'data-[position=popper]:h-[var(--reka-select-trigger-height)] data-[position=popper]:w-full data-[position=popper]:min-w-[var(--reka-select-trigger-width)]',
)"
>
<slot /> <slot />
</SelectViewport> </SelectViewport>
<SelectScrollDownButton /> <SelectScrollDownButton />
+4 -10
View File
@@ -1,20 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectGroupProps } from 'reka-ui' import type { SelectGroupProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import { SelectGroup } from "reka-ui"
import { reactiveOmit } from '@vueuse/core'
import { SelectGroup } from 'reka-ui'
import { cn } from '@/lib/utils'
const props = defineProps<SelectGroupProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<SelectGroupProps>()
const delegatedProps = reactiveOmit(props, 'class')
</script> </script>
<template> <template>
<SelectGroup <SelectGroup
data-slot="select-group" data-slot="select-group"
v-bind="delegatedProps" v-bind="props"
:class="cn('scroll-my-1 p-1', props.class)"
> >
<slot /> <slot />
</SelectGroup> </SelectGroup>
+11 -12
View File
@@ -1,20 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectItemProps } from 'reka-ui' import type { SelectItemProps } from "reka-ui"
import type { HTMLAttributes } from "vue"
import type { HTMLAttributes } from 'vue' import { Check } from "@lucide/vue"
import { CheckIcon } from '@lucide/vue' import { reactiveOmit } from "@vueuse/core"
import { reactiveOmit } from '@vueuse/core'
import { import {
SelectItem, SelectItem,
SelectItemIndicator, SelectItemIndicator,
SelectItemText, SelectItemText,
useForwardProps, useForwardProps,
} from 'reka-ui' } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<SelectItemProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<SelectItemProps & { class?: HTMLAttributes["class"] }>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
const forwardedProps = useForwardProps(delegatedProps) const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
@@ -25,15 +24,15 @@ const forwardedProps = useForwardProps(delegatedProps)
v-bind="forwardedProps" v-bind="forwardedProps"
:class=" :class="
cn( cn(
'focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm [&_svg:not([class*=size-])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-default items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0', 'focus:bg-accent focus:text-accent-foreground [&_svg:not([class*=\'text-\'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2',
props.class, props.class,
) )
" "
> >
<span class="pointer-events-none absolute right-2 flex size-4 items-center justify-center"> <span class="absolute right-2 flex size-3.5 items-center justify-center">
<SelectItemIndicator> <SelectItemIndicator>
<slot name="indicator-icon"> <slot name="indicator-icon">
<CheckIcon class="pointer-events-none" /> <Check class="size-4" />
</slot> </slot>
</SelectItemIndicator> </SelectItemIndicator>
</span> </span>
+2 -2
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectItemTextProps } from 'reka-ui' import type { SelectItemTextProps } from "reka-ui"
import { SelectItemText } from 'reka-ui' import { SelectItemText } from "reka-ui"
const props = defineProps<SelectItemTextProps>() const props = defineProps<SelectItemTextProps>()
</script> </script>
+6 -6
View File
@@ -1,16 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectLabelProps } from 'reka-ui' import type { SelectLabelProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { SelectLabel } from 'reka-ui' import { SelectLabel } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<SelectLabelProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<SelectLabelProps & { class?: HTMLAttributes["class"] }>()
</script> </script>
<template> <template>
<SelectLabel <SelectLabel
data-slot="select-label" data-slot="select-label"
:class="cn('text-muted-foreground px-1.5 py-1 text-xs', props.class)" :class="cn('text-muted-foreground px-2 py-1.5 text-xs', props.class)"
> >
<slot /> <slot />
</SelectLabel> </SelectLabel>
@@ -1,15 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectScrollDownButtonProps } from 'reka-ui' import type { SelectScrollDownButtonProps } from "reka-ui"
import type { HTMLAttributes } from "vue"
import { ChevronDown } from "@lucide/vue"
import { reactiveOmit } from "@vueuse/core"
import { SelectScrollDownButton, useForwardProps } from "reka-ui"
import { cn } from "@/lib/utils"
import type { HTMLAttributes } from 'vue' const props = defineProps<SelectScrollDownButtonProps & { class?: HTMLAttributes["class"] }>()
import { ChevronDownIcon } from '@lucide/vue'
import { reactiveOmit } from '@vueuse/core'
import { SelectScrollDownButton, useForwardProps } from 'reka-ui'
import { cn } from '@/lib/utils'
const props = defineProps<SelectScrollDownButtonProps & { class?: HTMLAttributes['class'] }>() const delegatedProps = reactiveOmit(props, "class")
const delegatedProps = reactiveOmit(props, 'class')
const forwardedProps = useForwardProps(delegatedProps) const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
@@ -18,10 +17,10 @@ const forwardedProps = useForwardProps(delegatedProps)
<SelectScrollDownButton <SelectScrollDownButton
data-slot="select-scroll-down-button" data-slot="select-scroll-down-button"
v-bind="forwardedProps" v-bind="forwardedProps"
:class="cn('bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*=size-])]:size-4', props.class)" :class="cn('flex cursor-default items-center justify-center py-1', props.class)"
> >
<slot> <slot>
<ChevronDownIcon /> <ChevronDown class="size-4" />
</slot> </slot>
</SelectScrollDownButton> </SelectScrollDownButton>
</template> </template>
@@ -1,15 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectScrollUpButtonProps } from 'reka-ui' import type { SelectScrollUpButtonProps } from "reka-ui"
import type { HTMLAttributes } from "vue"
import { ChevronUp } from "@lucide/vue"
import { reactiveOmit } from "@vueuse/core"
import { SelectScrollUpButton, useForwardProps } from "reka-ui"
import { cn } from "@/lib/utils"
import type { HTMLAttributes } from 'vue' const props = defineProps<SelectScrollUpButtonProps & { class?: HTMLAttributes["class"] }>()
import { ChevronUpIcon } from '@lucide/vue'
import { reactiveOmit } from '@vueuse/core'
import { SelectScrollUpButton, useForwardProps } from 'reka-ui'
import { cn } from '@/lib/utils'
const props = defineProps<SelectScrollUpButtonProps & { class?: HTMLAttributes['class'] }>() const delegatedProps = reactiveOmit(props, "class")
const delegatedProps = reactiveOmit(props, 'class')
const forwardedProps = useForwardProps(delegatedProps) const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
@@ -18,10 +17,10 @@ const forwardedProps = useForwardProps(delegatedProps)
<SelectScrollUpButton <SelectScrollUpButton
data-slot="select-scroll-up-button" data-slot="select-scroll-up-button"
v-bind="forwardedProps" v-bind="forwardedProps"
:class="cn('bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*=size-])]:size-4', props.class)" :class="cn('flex cursor-default items-center justify-center py-1', props.class)"
> >
<slot> <slot>
<ChevronUpIcon /> <ChevronUp class="size-4" />
</slot> </slot>
</SelectScrollUpButton> </SelectScrollUpButton>
</template> </template>
+8 -8
View File
@@ -1,19 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectSeparatorProps } from 'reka-ui' import type { SelectSeparatorProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { SelectSeparator } from 'reka-ui' import { SelectSeparator } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<SelectSeparatorProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<SelectSeparatorProps & { class?: HTMLAttributes["class"] }>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
</script> </script>
<template> <template>
<SelectSeparator <SelectSeparator
data-slot="select-separator" data-slot="select-separator"
v-bind="delegatedProps" v-bind="delegatedProps"
:class="cn('bg-border -mx-1 my-1 h-px pointer-events-none', props.class)" :class="cn('bg-border pointer-events-none -mx-1 my-1 h-px', props.class)"
/> />
</template> </template>
+11 -12
View File
@@ -1,18 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectTriggerProps } from 'reka-ui' import type { SelectTriggerProps } from "reka-ui"
import type { HTMLAttributes } from "vue"
import type { HTMLAttributes } from 'vue' import { ChevronDown } from "@lucide/vue"
import { ChevronDownIcon } from '@lucide/vue' import { reactiveOmit } from "@vueuse/core"
import { reactiveOmit } from '@vueuse/core' import { SelectIcon, SelectTrigger, useForwardProps } from "reka-ui"
import { SelectIcon, SelectTrigger, useForwardProps } from 'reka-ui' import { cn } from "@/lib/utils"
import { cn } from '@/lib/utils'
const props = withDefaults( const props = withDefaults(
defineProps<SelectTriggerProps & { class?: HTMLAttributes['class'], size?: 'sm' | 'default' }>(), defineProps<SelectTriggerProps & { class?: HTMLAttributes["class"], size?: "sm" | "default" }>(),
{ size: 'default' }, { size: "default" },
) )
const delegatedProps = reactiveOmit(props, 'class', 'size') const delegatedProps = reactiveOmit(props, "class", "size")
const forwardedProps = useForwardProps(delegatedProps) const forwardedProps = useForwardProps(delegatedProps)
</script> </script>
@@ -22,13 +21,13 @@ const forwardedProps = useForwardProps(delegatedProps)
:data-size="size" :data-size="size"
v-bind="forwardedProps" v-bind="forwardedProps"
:class="cn( :class="cn(
'border-input data-placeholder:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 gap-1.5 rounded-lg border bg-transparent py-2 pr-2 pl-2.5 text-sm transition-colors select-none focus-visible:ring-3 aria-invalid:ring-3 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:gap-1.5 [&_svg:not([class*=size-])]:size-4 flex w-fit items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center [&_svg]:pointer-events-none [&_svg]:shrink-0', 'border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*=\'text-\'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
props.class, props.class,
)" )"
> >
<slot /> <slot />
<SelectIcon as-child> <SelectIcon as-child>
<ChevronDownIcon class="text-muted-foreground size-4 pointer-events-none" /> <ChevronDown class="size-4 opacity-50" />
</SelectIcon> </SelectIcon>
</SelectTrigger> </SelectTrigger>
</template> </template>
+2 -2
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectValueProps } from 'reka-ui' import type { SelectValueProps } from "reka-ui"
import { SelectValue } from 'reka-ui' import { SelectValue } from "reka-ui"
const props = defineProps<SelectValueProps>() const props = defineProps<SelectValueProps>()
</script> </script>
+11 -11
View File
@@ -1,11 +1,11 @@
export { default as Select } from './Select.vue' export { default as Select } from "./Select.vue"
export { default as SelectContent } from './SelectContent.vue' export { default as SelectContent } from "./SelectContent.vue"
export { default as SelectGroup } from './SelectGroup.vue' export { default as SelectGroup } from "./SelectGroup.vue"
export { default as SelectItem } from './SelectItem.vue' export { default as SelectItem } from "./SelectItem.vue"
export { default as SelectItemText } from './SelectItemText.vue' export { default as SelectItemText } from "./SelectItemText.vue"
export { default as SelectLabel } from './SelectLabel.vue' export { default as SelectLabel } from "./SelectLabel.vue"
export { default as SelectScrollDownButton } from './SelectScrollDownButton.vue' export { default as SelectScrollDownButton } from "./SelectScrollDownButton.vue"
export { default as SelectScrollUpButton } from './SelectScrollUpButton.vue' export { default as SelectScrollUpButton } from "./SelectScrollUpButton.vue"
export { default as SelectSeparator } from './SelectSeparator.vue' export { default as SelectSeparator } from "./SelectSeparator.vue"
export { default as SelectTrigger } from './SelectTrigger.vue' export { default as SelectTrigger } from "./SelectTrigger.vue"
export { default as SelectValue } from './SelectValue.vue' export { default as SelectValue } from "./SelectValue.vue"
+9 -9
View File
@@ -1,18 +1,18 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SeparatorProps } from 'reka-ui' import type { SeparatorProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { Separator } from 'reka-ui' import { Separator } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = withDefaults(defineProps< const props = withDefaults(defineProps<
SeparatorProps & { class?: HTMLAttributes['class'] } SeparatorProps & { class?: HTMLAttributes["class"] }
>(), { >(), {
orientation: 'horizontal', orientation: "horizontal",
decorative: true, decorative: true,
}) })
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
</script> </script>
<template> <template>
@@ -21,7 +21,7 @@ const delegatedProps = reactiveOmit(props, 'class')
v-bind="delegatedProps" v-bind="delegatedProps"
:class=" :class="
cn( cn(
'shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:self-stretch', 'bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px',
props.class, props.class,
) )
" "
+1 -1
View File
@@ -1 +1 @@
export { default as Separator } from './Separator.vue' export { default as Separator } from "./Separator.vue"
+2 -2
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogRootEmits, DialogRootProps } from 'reka-ui' import type { DialogRootEmits, DialogRootProps } from "reka-ui"
import { DialogRoot, useForwardPropsEmits } from 'reka-ui' import { DialogRoot, useForwardPropsEmits } from "reka-ui"
const props = defineProps<DialogRootProps>() const props = defineProps<DialogRootProps>()
const emits = defineEmits<DialogRootEmits>() const emits = defineEmits<DialogRootEmits>()
+2 -2
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogCloseProps } from 'reka-ui' import type { DialogCloseProps } from "reka-ui"
import { DialogClose } from 'reka-ui' import { DialogClose } from "reka-ui"
const props = defineProps<DialogCloseProps>() const props = defineProps<DialogCloseProps>()
</script> </script>
+25 -24
View File
@@ -1,23 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogContentEmits, DialogContentProps } from 'reka-ui' import type { DialogContentEmits, DialogContentProps } from "reka-ui"
import type { HTMLAttributes } from "vue"
import type { HTMLAttributes } from 'vue' import { X } from "@lucide/vue"
import { XIcon } from '@lucide/vue' import { reactiveOmit } from "@vueuse/core"
import { reactiveOmit } from '@vueuse/core'
import { import {
DialogClose, DialogClose,
DialogContent, DialogContent,
DialogPortal, DialogPortal,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
import { Button } from '@/components/ui/button' import SheetOverlay from "./SheetOverlay.vue"
import SheetOverlay from './SheetOverlay.vue'
interface SheetContentProps extends DialogContentProps { interface SheetContentProps extends DialogContentProps {
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
side?: 'top' | 'right' | 'bottom' | 'left' side?: "top" | "right" | "bottom" | "left"
showCloseButton?: boolean
} }
defineOptions({ defineOptions({
@@ -25,12 +22,11 @@ defineOptions({
}) })
const props = withDefaults(defineProps<SheetContentProps>(), { const props = withDefaults(defineProps<SheetContentProps>(), {
side: 'right', side: "right",
showCloseButton: true,
}) })
const emits = defineEmits<DialogContentEmits>() const emits = defineEmits<DialogContentEmits>()
const delegatedProps = reactiveOmit(props, 'class', 'side', 'showCloseButton') const delegatedProps = reactiveOmit(props, "class", "side")
const forwarded = useForwardPropsEmits(delegatedProps, emits) const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script> </script>
@@ -40,21 +36,26 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
<SheetOverlay /> <SheetOverlay />
<DialogContent <DialogContent
data-slot="sheet-content" data-slot="sheet-content"
:data-side="side" :class="cn(
:class="cn('bg-popover text-popover-foreground fixed z-50 flex flex-col gap-4 bg-clip-padding text-sm shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10', props.class)" 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
side === 'right'
&& 'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
side === 'left'
&& 'data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',
side === 'top'
&& 'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b',
side === 'bottom'
&& 'data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t',
props.class)"
v-bind="{ ...$attrs, ...forwarded }" v-bind="{ ...$attrs, ...forwarded }"
> >
<slot /> <slot />
<DialogClose <DialogClose
v-if="showCloseButton" class="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none"
data-slot="sheet-close"
as-child
> >
<Button variant="ghost" class="absolute top-3 right-3" size="icon-sm"> <X class="size-4" />
<XIcon /> <span class="sr-only">Close</span>
<span class="sr-only">Close</span>
</Button>
</DialogClose> </DialogClose>
</DialogContent> </DialogContent>
</DialogPortal> </DialogPortal>
+7 -7
View File
@@ -1,13 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogDescriptionProps } from 'reka-ui' import type { DialogDescriptionProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { DialogDescription } from 'reka-ui' import { DialogDescription } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes["class"] }>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
</script> </script>
<template> <template>
+5 -4
View File
@@ -1,14 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ class?: HTMLAttributes['class'] }>() const props = defineProps<{ class?: HTMLAttributes["class"] }>()
</script> </script>
<template> <template>
<div <div
data-slot="sheet-footer" data-slot="sheet-footer"
:class="cn('gap-2 p-4 mt-auto flex flex-col', props.class)" :class="cn('mt-auto flex flex-col gap-2 p-4', props.class)
"
> >
<slot /> <slot />
</div> </div>
+4 -4
View File
@@ -1,14 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ class?: HTMLAttributes['class'] }>() const props = defineProps<{ class?: HTMLAttributes["class"] }>()
</script> </script>
<template> <template>
<div <div
data-slot="sheet-header" data-slot="sheet-header"
:class="cn('gap-0.5 p-4 flex flex-col', props.class)" :class="cn('flex flex-col gap-1.5 p-4', props.class)"
> >
<slot /> <slot />
</div> </div>
+8 -8
View File
@@ -1,19 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogOverlayProps } from 'reka-ui' import type { DialogOverlayProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { DialogOverlay } from 'reka-ui' import { DialogOverlay } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<DialogOverlayProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogOverlayProps & { class?: HTMLAttributes["class"] }>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
</script> </script>
<template> <template>
<DialogOverlay <DialogOverlay
data-slot="sheet-overlay" data-slot="sheet-overlay"
:class="cn('bg-black/10 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 z-50 duration-100 data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0', props.class)" :class="cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80', props.class)"
v-bind="delegatedProps" v-bind="delegatedProps"
> >
<slot /> <slot />
+8 -8
View File
@@ -1,19 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogTitleProps } from 'reka-ui' import type { DialogTitleProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { DialogTitle } from 'reka-ui' import { DialogTitle } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<DialogTitleProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogTitleProps & { class?: HTMLAttributes["class"] }>()
const delegatedProps = reactiveOmit(props, 'class') const delegatedProps = reactiveOmit(props, "class")
</script> </script>
<template> <template>
<DialogTitle <DialogTitle
data-slot="sheet-title" data-slot="sheet-title"
:class="cn('text-foreground text-base font-medium cn-font-heading', props.class)" :class="cn('text-foreground font-semibold', props.class)"
v-bind="delegatedProps" v-bind="delegatedProps"
> >
<slot /> <slot />
+2 -2
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DialogTriggerProps } from 'reka-ui' import type { DialogTriggerProps } from "reka-ui"
import { DialogTrigger } from 'reka-ui' import { DialogTrigger } from "reka-ui"
const props = defineProps<DialogTriggerProps>() const props = defineProps<DialogTriggerProps>()
</script> </script>
+8 -8
View File
@@ -1,8 +1,8 @@
export { default as Sheet } from './Sheet.vue' export { default as Sheet } from "./Sheet.vue"
export { default as SheetClose } from './SheetClose.vue' export { default as SheetClose } from "./SheetClose.vue"
export { default as SheetContent } from './SheetContent.vue' export { default as SheetContent } from "./SheetContent.vue"
export { default as SheetDescription } from './SheetDescription.vue' export { default as SheetDescription } from "./SheetDescription.vue"
export { default as SheetFooter } from './SheetFooter.vue' export { default as SheetFooter } from "./SheetFooter.vue"
export { default as SheetHeader } from './SheetHeader.vue' export { default as SheetHeader } from "./SheetHeader.vue"
export { default as SheetTitle } from './SheetTitle.vue' export { default as SheetTitle } from "./SheetTitle.vue"
export { default as SheetTrigger } from './SheetTrigger.vue' export { default as SheetTrigger } from "./SheetTrigger.vue"
+8 -12
View File
@@ -1,20 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SidebarProps } from '.' import type { SidebarProps } from "."
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
import { Sheet, SheetContent } from '@/components/ui/sheet' import { Sheet, SheetContent } from '@/components/ui/sheet'
import SheetDescription from '@/components/ui/sheet/SheetDescription.vue' import SheetDescription from '@/components/ui/sheet/SheetDescription.vue'
import SheetHeader from '@/components/ui/sheet/SheetHeader.vue' import SheetHeader from '@/components/ui/sheet/SheetHeader.vue'
import SheetTitle from '@/components/ui/sheet/SheetTitle.vue' import SheetTitle from '@/components/ui/sheet/SheetTitle.vue'
import { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils' import { SIDEBAR_WIDTH_MOBILE, useSidebar } from "./utils"
defineOptions({ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}) })
const props = withDefaults(defineProps<SidebarProps>(), { const props = withDefaults(defineProps<SidebarProps>(), {
side: 'left', side: "left",
variant: 'sidebar', variant: "sidebar",
collapsible: 'offcanvas', collapsible: "offcanvas",
}) })
const { isMobile, state, openMobile, setOpenMobile } = useSidebar() const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
@@ -62,9 +62,8 @@ const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
> >
<!-- This is what handles the sidebar gap on desktop --> <!-- This is what handles the sidebar gap on desktop -->
<div <div
data-slot="sidebar-gap"
:class="cn( :class="cn(
'transition-[width] duration-200 ease-linear relative w-(--sidebar-width) bg-transparent', 'relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear',
'group-data-[collapsible=offcanvas]:w-0', 'group-data-[collapsible=offcanvas]:w-0',
'group-data-[side=right]:rotate-180', 'group-data-[side=right]:rotate-180',
variant === 'floating' || variant === 'inset' variant === 'floating' || variant === 'inset'
@@ -73,8 +72,6 @@ const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
)" )"
/> />
<div <div
data-slot="sidebar-container"
:data-side="side"
:class="cn( :class="cn(
'fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex', 'fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex',
side === 'left' side === 'left'
@@ -90,8 +87,7 @@ const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
> >
<div <div
data-sidebar="sidebar" data-sidebar="sidebar"
data-slot="sidebar-inner" class="bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"
class="bg-sidebar group-data-[variant=floating]:ring-sidebar-border group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 flex size-full flex-col"
> >
<slot /> <slot />
</div> </div>
+4 -4
View File
@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -11,7 +11,7 @@ const props = defineProps<{
<div <div
data-slot="sidebar-content" data-slot="sidebar-content"
data-sidebar="content" data-sidebar="content"
:class="cn('no-scrollbar gap-0 flex min-h-0 flex-1 flex-col overflow-auto group-data-[collapsible=icon]:overflow-hidden', props.class)" :class="cn('flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', props.class)"
> >
<slot /> <slot />
</div> </div>
+4 -4
View File
@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -11,7 +11,7 @@ const props = defineProps<{
<div <div
data-slot="sidebar-footer" data-slot="sidebar-footer"
data-sidebar="footer" data-sidebar="footer"
:class="cn('gap-2 p-2 flex flex-col', props.class)" :class="cn('flex flex-col gap-2 p-2', props.class)"
> >
<slot /> <slot />
</div> </div>
+4 -4
View File
@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -11,7 +11,7 @@ const props = defineProps<{
<div <div
data-slot="sidebar-group" data-slot="sidebar-group"
data-sidebar="group" data-sidebar="group"
:class="cn('p-2 relative flex w-full min-w-0 flex-col', props.class)" :class="cn('relative flex w-full min-w-0 flex-col p-2', props.class)"
> >
<slot /> <slot />
</div> </div>
@@ -1,11 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import type { PrimitiveProps } from 'reka-ui' import type { PrimitiveProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { Primitive } from 'reka-ui' import { Primitive } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<PrimitiveProps & { const props = defineProps<PrimitiveProps & {
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -16,7 +16,9 @@ const props = defineProps<PrimitiveProps & {
:as="as" :as="as"
:as-child="asChild" :as-child="asChild"
:class="cn( :class="cn(
'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 w-5 rounded-md p-0 focus-visible:ring-2 [&>svg]:size-4 flex aspect-square items-center justify-center outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden [&>svg]:shrink-0', 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
'after:absolute after:-inset-2 md:after:hidden',
'group-data-[collapsible=icon]:hidden',
props.class, props.class,
)" )"
> >
@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -11,7 +11,7 @@ const props = defineProps<{
<div <div
data-slot="sidebar-group-content" data-slot="sidebar-group-content"
data-sidebar="group-content" data-sidebar="group-content"
:class="cn('text-sm w-full', props.class)" :class="cn('w-full text-sm', props.class)"
> >
<slot /> <slot />
</div> </div>
@@ -1,11 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import type { PrimitiveProps } from 'reka-ui' import type { PrimitiveProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { Primitive } from 'reka-ui' import { Primitive } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<PrimitiveProps & { const props = defineProps<PrimitiveProps & {
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -16,7 +16,8 @@ const props = defineProps<PrimitiveProps & {
:as="as" :as="as"
:as-child="asChild" :as-child="asChild"
:class="cn( :class="cn(
'text-sidebar-foreground/70 ring-sidebar-ring h-8 rounded-md px-2 text-xs font-medium transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 flex shrink-0 items-center outline-hidden [&>svg]:shrink-0', 'text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',
props.class)" props.class)"
> >
<slot /> <slot />
+4 -4
View File
@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -11,7 +11,7 @@ const props = defineProps<{
<div <div
data-slot="sidebar-header" data-slot="sidebar-header"
data-sidebar="header" data-sidebar="header"
:class="cn('gap-2 p-2 flex flex-col', props.class)" :class="cn('flex flex-col gap-2 p-2', props.class)"
> >
<slot /> <slot />
</div> </div>
+7 -4
View File
@@ -1,10 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
import { Input } from '@/components/ui/input' import { Input } from '@/components/ui/input'
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -12,7 +12,10 @@ const props = defineProps<{
<Input <Input
data-slot="sidebar-input" data-slot="sidebar-input"
data-sidebar="input" data-sidebar="input"
:class="cn('bg-background h-8 w-full shadow-none', props.class)" :class="cn(
'bg-background h-8 w-full shadow-none',
props.class,
)"
> >
<slot /> <slot />
</Input> </Input>
+5 -4
View File
@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -11,7 +11,8 @@ const props = defineProps<{
<main <main
data-slot="sidebar-inset" data-slot="sidebar-inset"
:class="cn( :class="cn(
'bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2 relative flex w-full flex-1 flex-col', 'bg-background relative flex w-full flex-1 flex-col',
'md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2',
props.class, props.class,
)" )"
> >
+4 -4
View File
@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -11,7 +11,7 @@ const props = defineProps<{
<ul <ul
data-slot="sidebar-menu" data-slot="sidebar-menu"
data-sidebar="menu" data-sidebar="menu"
:class="cn('gap-0 flex w-full min-w-0 flex-col', props.class)" :class="cn('flex w-full min-w-0 flex-col gap-1', props.class)"
> >
<slot /> <slot />
</ul> </ul>
@@ -1,14 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { PrimitiveProps } from 'reka-ui' import type { PrimitiveProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { Primitive } from 'reka-ui' import { Primitive } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = withDefaults(defineProps<PrimitiveProps & { const props = withDefaults(defineProps<PrimitiveProps & {
showOnHover?: boolean showOnHover?: boolean
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>(), { }>(), {
as: 'button', as: "button",
}) })
</script> </script>
@@ -17,9 +17,14 @@ const props = withDefaults(defineProps<PrimitiveProps & {
data-slot="sidebar-menu-action" data-slot="sidebar-menu-action"
data-sidebar="menu-action" data-sidebar="menu-action"
:class="cn( :class="cn(
'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 aspect-square w-5 rounded-md p-0 peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 focus-visible:ring-2 [&>svg]:size-4 flex items-center justify-center outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden [&>svg]:shrink-0', 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
'after:absolute after:-inset-2 md:after:hidden',
'peer-data-[size=sm]/menu-button:top-1',
'peer-data-[size=default]/menu-button:top-1.5',
'peer-data-[size=lg]/menu-button:top-2.5',
'group-data-[collapsible=icon]:hidden',
showOnHover showOnHover
&& 'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-active/menu-button:text-sidebar-accent-foreground aria-expanded:opacity-100 md:opacity-0', && 'peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0',
props.class, props.class,
)" )"
:as="as" :as="as"
@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -12,7 +12,12 @@ const props = defineProps<{
data-slot="sidebar-menu-badge" data-slot="sidebar-menu-badge"
data-sidebar="menu-badge" data-sidebar="menu-badge"
:class="cn( :class="cn(
'text-sidebar-foreground peer-hover/menu-button:text-sidebar-accent-foreground peer-data-active/menu-button:text-sidebar-accent-foreground pointer-events-none absolute right-1 h-5 min-w-5 rounded-md px-1 text-xs font-medium peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 flex items-center justify-center tabular-nums select-none group-data-[collapsible=icon]:hidden', 'text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none',
'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',
'peer-data-[size=sm]/menu-button:top-1',
'peer-data-[size=default]/menu-button:top-1.5',
'peer-data-[size=lg]/menu-button:top-2.5',
'group-data-[collapsible=icon]:hidden',
props.class, props.class,
)" )"
> >
@@ -1,10 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import type { Component } from 'vue' import type { Component } from "vue"
import type { SidebarMenuButtonProps } from './SidebarMenuButtonChild.vue' import type { SidebarMenuButtonProps } from "./SidebarMenuButtonChild.vue"
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from "@vueuse/core"
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import SidebarMenuButtonChild from './SidebarMenuButtonChild.vue' import SidebarMenuButtonChild from "./SidebarMenuButtonChild.vue"
import { useSidebar } from './utils' import { useSidebar } from "./utils"
defineOptions({ defineOptions({
inheritAttrs: false, inheritAttrs: false,
@@ -13,14 +13,14 @@ defineOptions({
const props = withDefaults(defineProps<SidebarMenuButtonProps & { const props = withDefaults(defineProps<SidebarMenuButtonProps & {
tooltip?: string | Component tooltip?: string | Component
}>(), { }>(), {
as: 'button', as: "button",
variant: 'default', variant: "default",
size: 'default', size: "default",
}) })
const { isMobile, state } = useSidebar() const { isMobile, state } = useSidebar()
const delegatedProps = reactiveOmit(props, 'tooltip') const delegatedProps = reactiveOmit(props, "tooltip")
</script> </script>
<template> <template>
@@ -1,22 +1,22 @@
<script setup lang="ts"> <script setup lang="ts">
import type { PrimitiveProps } from 'reka-ui' import type { PrimitiveProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import type { SidebarMenuButtonVariants } from '.' import type { SidebarMenuButtonVariants } from "."
import { Primitive } from 'reka-ui' import { Primitive } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
import { sidebarMenuButtonVariants } from '.' import { sidebarMenuButtonVariants } from "."
export interface SidebarMenuButtonProps extends PrimitiveProps { export interface SidebarMenuButtonProps extends PrimitiveProps {
variant?: SidebarMenuButtonVariants['variant'] variant?: SidebarMenuButtonVariants["variant"]
size?: SidebarMenuButtonVariants['size'] size?: SidebarMenuButtonVariants["size"]
isActive?: boolean isActive?: boolean
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
} }
const props = withDefaults(defineProps<SidebarMenuButtonProps>(), { const props = withDefaults(defineProps<SidebarMenuButtonProps>(), {
as: 'button', as: "button",
variant: 'default', variant: "default",
size: 'default', size: "default",
}) })
</script> </script>
@@ -25,7 +25,7 @@ const props = withDefaults(defineProps<SidebarMenuButtonProps>(), {
data-slot="sidebar-menu-button" data-slot="sidebar-menu-button"
data-sidebar="menu-button" data-sidebar="menu-button"
:data-size="size" :data-size="size"
:data-active="isActive || undefined" :data-active="isActive"
:class="cn(sidebarMenuButtonVariants({ variant, size }), props.class)" :class="cn(sidebarMenuButtonVariants({ variant, size }), props.class)"
:as="as" :as="as"
:as-child="asChild" :as-child="asChild"
@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
@@ -1,12 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { computed } from 'vue' import { computed } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
import { Skeleton } from '@/components/ui/skeleton' import { Skeleton } from '@/components/ui/skeleton'
const props = defineProps<{ const props = defineProps<{
showIcon?: boolean showIcon?: boolean
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
const width = computed(() => { const width = computed(() => {
@@ -18,7 +18,7 @@ const width = computed(() => {
<div <div
data-slot="sidebar-menu-skeleton" data-slot="sidebar-menu-skeleton"
data-sidebar="menu-skeleton" data-sidebar="menu-skeleton"
:class="cn('h-8 gap-2 rounded-md px-2 flex items-center', props.class)" :class="cn('flex h-8 items-center gap-2 rounded-md px-2', props.class)"
> >
<Skeleton <Skeleton
v-if="showIcon" v-if="showIcon"
+6 -5
View File
@@ -1,18 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>() }>()
</script> </script>
<template> <template>
<ul <ul
data-slot="sidebar-menu-sub" data-slot="sidebar-menu-sub"
data-sidebar="menu-sub" data-sidebar="menu-badge"
:class="cn( :class="cn(
'border-sidebar-border mx-3.5 translate-x-px gap-1 border-l px-2.5 py-0.5 group-data-[collapsible=icon]:hidden flex min-w-0 flex-col', 'border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5',
'group-data-[collapsible=icon]:hidden',
props.class, props.class,
)" )"
> >
@@ -1,16 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import type { PrimitiveProps } from 'reka-ui' import type { PrimitiveProps } from "reka-ui"
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from "vue"
import { Primitive } from 'reka-ui' import { Primitive } from "reka-ui"
import { cn } from '@/lib/utils' import { cn } from "@/lib/utils"
const props = withDefaults(defineProps<PrimitiveProps & { const props = withDefaults(defineProps<PrimitiveProps & {
size?: 'sm' | 'md' size?: "sm" | "md"
isActive?: boolean isActive?: boolean
class?: HTMLAttributes['class'] class?: HTMLAttributes["class"]
}>(), { }>(), {
as: 'a', as: "a",
size: 'md', size: "md",
}) })
</script> </script>
@@ -21,9 +21,13 @@ const props = withDefaults(defineProps<PrimitiveProps & {
:as="as" :as="as"
:as-child="asChild" :as-child="asChild"
:data-size="size" :data-size="size"
:data-active="isActive || undefined" :data-active="isActive"
:class="cn( :class="cn(
'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground h-7 gap-2 rounded-md px-2 focus-visible:ring-2 data-[size=md]:text-sm data-[size=sm]:text-xs [&>svg]:size-4 flex min-w-0 -translate-x-px items-center overflow-hidden outline-hidden group-data-[collapsible=icon]:hidden disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:shrink-0', 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',
size === 'sm' && 'text-xs',
size === 'md' && 'text-sm',
'group-data-[collapsible=icon]:hidden',
props.class, props.class,
)" )"
> >

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