refactor: update

This commit is contained in:
Sadegh Barati 2024-01-06 21:17:15 +03:30
parent 66254fade7
commit a10731b8a0
34 changed files with 348 additions and 135 deletions

View File

@ -11,7 +11,7 @@ interface Props extends PrimitiveProps {
class?: HTMLAttributes['class'] class?: HTMLAttributes['class']
} }
withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
as: 'button', as: 'button',
}) })
</script> </script>
@ -20,7 +20,7 @@ withDefaults(defineProps<Props>(), {
<Primitive <Primitive
:as="as" :as="as"
:as-child="asChild" :as-child="asChild"
:class="cn(buttonVariants({ variant, size }), $attrs.class ?? '')" :class="cn(buttonVariants({ variant, size }), props.class)"
> >
<slot /> <slot />
</Primitive> </Primitive>

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
MenubarContent, MenubarContent,
type MenubarContentProps, type MenubarContentProps,
@ -7,24 +8,25 @@ import {
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = withDefaults( const props = withDefaults(
defineProps<MenubarContentProps & { class?: string }>(), defineProps<MenubarContentProps & { class?: HTMLAttributes['class'] }>(),
{ {
align: 'start', align: 'start',
alignOffset: -4, alignOffset: -4,
sideOffset: 8, sideOffset: 8,
}, },
) )
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<MenubarPortal> <MenubarPortal>
<MenubarContent <MenubarContent
:loop="props.loop" v-bind="delegatedProps"
:as-child="props.asChild"
:side-offset="props.sideOffset"
:side="props.side"
:align="props.align"
:align-offset="props.alignOffset"
:class=" :class="
cn( cn(
'z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', 'z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',

View File

@ -1,19 +1,32 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
MenubarItem, MenubarItem,
type MenubarItemEmits, type MenubarItemEmits,
type MenubarItemProps, type MenubarItemProps,
useEmitAsProps,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<MenubarItemProps & { inset?: boolean; class?: string }>() const props = defineProps<MenubarItemProps & { class?: HTMLAttributes['class']; inset?: boolean }>()
const emits = defineEmits<MenubarItemEmits>() const emits = defineEmits<MenubarItemEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const emitsAsProps = useEmitAsProps(emits)
</script> </script>
<template> <template>
<MenubarItem <MenubarItem
v-bind="props" v-bind="{
...delegatedProps,
...emitsAsProps,
}"
:class="[ :class="[
cn( cn(
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
@ -21,7 +34,6 @@ const emits = defineEmits<MenubarItemEmits>()
props.class, props.class,
), ),
]" ]"
@select="emits('select', $event)"
> >
<slot /> <slot />
</MenubarItem> </MenubarItem>

View File

@ -1,8 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { MenubarLabel, type MenubarLabelProps } from 'radix-vue' import { MenubarLabel, type MenubarLabelProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<MenubarLabelProps & { inset?: boolean; class?: string }>() const props = defineProps<MenubarLabelProps & { class?: HTMLAttributes['class']; inset?: boolean }>()
</script> </script>
<template> <template>

View File

@ -3,18 +3,18 @@ import {
MenubarRadioGroup, MenubarRadioGroup,
type MenubarRadioGroupEmits, type MenubarRadioGroupEmits,
type MenubarRadioGroupProps, type MenubarRadioGroupProps,
useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
const props = defineProps<MenubarRadioGroupProps>() const props = defineProps<MenubarRadioGroupProps>()
const emits = defineEmits<MenubarRadioGroupEmits>() const emits = defineEmits<MenubarRadioGroupEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script> </script>
<template> <template>
<MenubarRadioGroup <MenubarRadioGroup v-bind="forwarded">
v-bind="props"
@update:model-value="emits('update:modelValue', $event)"
>
<slot /> <slot />
</MenubarRadioGroup> </MenubarRadioGroup>
</template> </template>

View File

@ -1,28 +1,40 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
MenubarItemIndicator, MenubarItemIndicator,
MenubarRadioItem, MenubarRadioItem,
type MenubarRadioItemEmits, type MenubarRadioItemEmits,
type MenubarRadioItemProps, type MenubarRadioItemProps,
useEmitAsProps,
} from 'radix-vue' } from 'radix-vue'
import { Circle } from 'lucide-vue-next' import { Circle } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<MenubarRadioItemProps & { class?: string }>() const props = defineProps<MenubarRadioItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<MenubarRadioItemEmits>() const emits = defineEmits<MenubarRadioItemEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const emitsAsProps = useEmitAsProps(emits)
</script> </script>
<template> <template>
<MenubarRadioItem <MenubarRadioItem
v-bind="props" v-bind="{
...delegatedProps,
...emitsAsProps,
}"
:class="[ :class="[
cn( cn(
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
props.class, props.class,
), ),
]" ]"
@select="emits('select', $event)"
> >
<MenubarItemIndicator <MenubarItemIndicator
class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center" class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"

View File

@ -1,10 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { MenubarSeparator, type MenubarSeparatorProps } from 'radix-vue' import { MenubarSeparator, type MenubarSeparatorProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<MenubarSeparatorProps>() const props = defineProps<MenubarSeparatorProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<MenubarSeparator :class=" cn('-mx-1 my-1 h-px bg-secondary', $attrs.class ?? '')" v-bind="props" /> <MenubarSeparator :class=" cn('-mx-1 my-1 h-px bg-secondary', props.class)" v-bind="delegatedProps" />
</template> </template>

View File

@ -1,9 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script> </script>
<template> <template>
<span :class="cn('text-xxs ml-auto tracking-widest opacity-50', $attrs.class ?? '')"> <span :class="cn('text-xxs ml-auto tracking-widest opacity-50', props.class)">
<slot /> <slot />
</span> </span>
</template> </template>

View File

@ -1,14 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
MenubarPortal, MenubarPortal,
MenubarSubContent, MenubarSubContent,
type MenubarSubContentEmits, type MenubarSubContentEmits,
type MenubarSubContentProps, type MenubarSubContentProps,
useEmitAsProps,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = withDefaults( const props = withDefaults(
defineProps<MenubarSubContentProps & { class?: string }>(), defineProps<MenubarSubContentProps & { class?: HTMLAttributes['class'] }>(),
{ {
sideOffset: 2, sideOffset: 2,
alignOffset: 0, alignOffset: 0,
@ -16,17 +18,23 @@ const props = withDefaults(
) )
const emits = defineEmits<MenubarSubContentEmits>() const emits = defineEmits<MenubarSubContentEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const emitsAsProps = useEmitAsProps(emits)
</script> </script>
<template> <template>
<MenubarPortal> <MenubarPortal>
<MenubarSubContent <MenubarSubContent
:loop="props.loop" v-bind="{
:as-child="props.asChild" ...delegatedProps,
:side-offset="props.sideOffset" ...emitsAsProps,
:side="props.side" }"
:align="props.align"
:align-offset="props.alignOffset"
:class=" :class="
cn( cn(
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',

View File

@ -1,14 +1,21 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { MenubarSubTrigger, type MenubarSubTriggerProps } from 'radix-vue' import { MenubarSubTrigger, type MenubarSubTriggerProps } from 'radix-vue'
import { ChevronRight } from 'lucide-vue-next' import { ChevronRight } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<MenubarSubTriggerProps & { inset?: boolean; class?: string }>() const props = defineProps<MenubarSubTriggerProps & { class?: HTMLAttributes['class']; inset?: boolean }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<MenubarSubTrigger <MenubarSubTrigger
v-bind="props" v-bind="delegatedProps"
:class="[ :class="[
cn( cn(
'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground', 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',

View File

@ -1,13 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { MenubarTrigger, type MenubarTriggerProps } from 'radix-vue' import { MenubarTrigger, type MenubarTriggerProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<MenubarTriggerProps & { class?: string }>() const props = defineProps<MenubarTriggerProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<MenubarTrigger <MenubarTrigger
v-bind="props" v-bind="delegatedProps"
:class=" :class="
cn( cn(
'flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground', 'flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',

View File

@ -1,22 +1,34 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
NavigationMenuRoot, NavigationMenuRoot,
type NavigationMenuRootEmits, type NavigationMenuRootEmits,
type NavigationMenuRootProps, type NavigationMenuRootProps,
useEmitAsProps,
} from 'radix-vue' } from 'radix-vue'
import NavigationMenuViewport from './NavigationMenuViewport.vue' import NavigationMenuViewport from './NavigationMenuViewport.vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<NavigationMenuRootProps & { class?: string }>() const props = defineProps<NavigationMenuRootProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<NavigationMenuRootEmits>() const emits = defineEmits<NavigationMenuRootEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const emitsAsProps = useEmitAsProps(emits)
</script> </script>
<template> <template>
<NavigationMenuRoot <NavigationMenuRoot
v-bind="props" v-bind="{
...delegatedProps,
...emitsAsProps,
}"
:class="cn('relative z-10 flex max-w-max flex-1 items-center justify-center', props.class)" :class="cn('relative z-10 flex max-w-max flex-1 items-center justify-center', props.class)"
@update:model-value="emits('update:modelValue', $event)"
> >
<slot /> <slot />
<NavigationMenuViewport /> <NavigationMenuViewport />

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
NavigationMenuContent, NavigationMenuContent,
type NavigationMenuContentEmits, type NavigationMenuContentEmits,
@ -7,14 +8,20 @@ import {
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<NavigationMenuContentProps & { class?: string }>() const props = defineProps<NavigationMenuContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<NavigationMenuContentEmits>() const emits = defineEmits<NavigationMenuContentEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<NavigationMenuContent <NavigationMenuContent
v-bind="{ ...props, ...useEmitAsProps(emits) }" v-bind="{ ...delegatedProps, ...useEmitAsProps(emits) }"
:class=" :class="
cn( cn(
'left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto ', 'left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto ',

View File

@ -1,14 +1,21 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { NavigationMenuIndicator, type NavigationMenuIndicatorProps } from 'radix-vue' import { NavigationMenuIndicator, type NavigationMenuIndicatorProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<NavigationMenuIndicatorProps>() const props = defineProps<NavigationMenuIndicatorProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<NavigationMenuIndicator <NavigationMenuIndicator
v-bind="props" v-bind="delegatedProps"
:class="cn('top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in', $attrs.class ?? '')" :class="cn('top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in', props.class)"
> >
<div class="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" /> <div class="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
</NavigationMenuIndicator> </NavigationMenuIndicator>

View File

@ -3,15 +3,17 @@ import {
NavigationMenuLink, NavigationMenuLink,
type NavigationMenuLinkEmits, type NavigationMenuLinkEmits,
type NavigationMenuLinkProps, type NavigationMenuLinkProps,
useEmitAsProps, useForwardPropsEmits,
} from 'radix-vue' } from 'radix-vue'
const props = defineProps<NavigationMenuLinkProps>() const props = defineProps<NavigationMenuLinkProps>()
const emits = defineEmits<NavigationMenuLinkEmits>() const emits = defineEmits<NavigationMenuLinkEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script> </script>
<template> <template>
<NavigationMenuLink v-bind="{ ...props, ...useEmitAsProps(emits) }"> <NavigationMenuLink v-bind="forwarded">
<slot /> <slot />
</NavigationMenuLink> </NavigationMenuLink>
</template> </template>

View File

@ -1,13 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { NavigationMenuList, type NavigationMenuListProps } from 'radix-vue' import { NavigationMenuList, type NavigationMenuListProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<NavigationMenuListProps & { class?: string }>() const props = defineProps<NavigationMenuListProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<NavigationMenuList <NavigationMenuList
v-bind="props" v-bind="delegatedProps"
:class=" :class="
cn( cn(
'group flex flex-1 list-none items-center justify-center space-x-1', 'group flex flex-1 list-none items-center justify-center space-x-1',

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
NavigationMenuTrigger, NavigationMenuTrigger,
type NavigationMenuTriggerProps, type NavigationMenuTriggerProps,
@ -7,13 +8,19 @@ import { ChevronDown } from 'lucide-vue-next'
import { navigationMenuTriggerStyle } from '.' import { navigationMenuTriggerStyle } from '.'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<NavigationMenuTriggerProps & { class?: string }>() const props = defineProps<NavigationMenuTriggerProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<NavigationMenuTrigger <NavigationMenuTrigger
v-bind="delegatedProps"
:class="cn(navigationMenuTriggerStyle(), 'group', props.class)" :class="cn(navigationMenuTriggerStyle(), 'group', props.class)"
v-bind="props"
> >
<slot /> <slot />
<ChevronDown <ChevronDown

View File

@ -1,21 +1,28 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
NavigationMenuViewport, NavigationMenuViewport,
type NavigationMenuViewportProps, type NavigationMenuViewportProps,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<NavigationMenuViewportProps>() const props = defineProps<NavigationMenuViewportProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<div class="absolute left-0 top-full flex justify-center"> <div class="absolute left-0 top-full flex justify-center">
<NavigationMenuViewport <NavigationMenuViewport
v-bind="props" v-bind="delegatedProps"
:class=" :class="
cn( cn(
'origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]', 'origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]',
$attrs.class ?? '', props.class,
) )
" "
/> />

View File

@ -1,20 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { useAttrs } from 'vue' import { type HTMLAttributes, computed } from 'vue'
import { PaginationEllipsis, type PaginationEllipsisProps, useForwardProps } from 'radix-vue' import { PaginationEllipsis, type PaginationEllipsisProps } from 'radix-vue'
import { MoreHorizontal } from 'lucide-vue-next' import { MoreHorizontal } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
defineOptions({ const props = defineProps<PaginationEllipsisProps & { class?: HTMLAttributes['class'] }>()
inheritAttrs: false,
})
const props = defineProps<PaginationEllipsisProps>() const delegatedProps = computed(() => {
const forwarded = useForwardProps(props) const { class: _, ...delegated } = props
const { class: className, ...rest } = useAttrs()
return delegated
})
</script> </script>
<template> <template>
<PaginationEllipsis :class="cn('w-9 h-9 flex items-center justify-center', className ?? '')" v-bind="{ ...forwarded, ...rest }"> <PaginationEllipsis v-bind="delegatedProps" :class="cn('w-9 h-9 flex items-center justify-center', props.class)">
<slot> <slot>
<MoreHorizontal /> <MoreHorizontal />
</slot> </slot>

View File

@ -1,19 +1,26 @@
<script setup lang="ts"> <script setup lang="ts">
import { PaginationFirst, type PaginationFirstProps, useForwardProps } from 'radix-vue' import { type HTMLAttributes, computed } from 'vue'
import { PaginationFirst, type PaginationFirstProps } from 'radix-vue'
import { ChevronsLeft } from 'lucide-vue-next' import { ChevronsLeft } from 'lucide-vue-next'
import { import {
Button, Button,
} from '@/lib/registry/default/ui/button' } from '@/lib/registry/default/ui/button'
import { cn } from '@/lib/utils'
const props = withDefaults(defineProps<PaginationFirstProps>(), { const props = withDefaults(defineProps<PaginationFirstProps & { class?: HTMLAttributes['class'] }>(), {
asChild: true, asChild: true,
}) })
const forwarded = useForwardProps(props)
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<PaginationFirst v-bind="forwarded"> <PaginationFirst v-bind="delegatedProps">
<Button class="w-10 h-10 p-0" variant="outline"> <Button :class="cn('w-10 h-10 p-0', props.class)" variant="outline">
<slot> <slot>
<ChevronsLeft class="h-4 w-4" /> <ChevronsLeft class="h-4 w-4" />
</slot> </slot>

View File

@ -1,19 +1,26 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { PaginationLast, type PaginationLastProps, useForwardProps } from 'radix-vue' import { PaginationLast, type PaginationLastProps, useForwardProps } from 'radix-vue'
import { ChevronsRight } from 'lucide-vue-next' import { ChevronsRight } from 'lucide-vue-next'
import { import {
Button, Button,
} from '@/lib/registry/default/ui/button' } from '@/lib/registry/default/ui/button'
import { cn } from '@/lib/utils'
const props = withDefaults(defineProps<PaginationLastProps>(), { const props = withDefaults(defineProps<PaginationLastProps & { class?: HTMLAttributes['class'] }>(), {
asChild: true, asChild: true,
}) })
const forwarded = useForwardProps(props)
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<PaginationLast v-bind="forwarded"> <PaginationLast v-bind="delegatedProps">
<Button class="w-10 h-10 p-0" variant="outline"> <Button :class="cn('w-10 h-10 p-0', props.class)" variant="outline">
<slot> <slot>
<ChevronsRight class="h-4 w-4" /> <ChevronsRight class="h-4 w-4" />
</slot> </slot>

View File

@ -1,19 +1,26 @@
<script setup lang="ts"> <script setup lang="ts">
import { PaginationNext, type PaginationNextProps, useForwardProps } from 'radix-vue' import { type HTMLAttributes, computed } from 'vue'
import { PaginationNext, type PaginationNextProps } from 'radix-vue'
import { ChevronRight } from 'lucide-vue-next' import { ChevronRight } from 'lucide-vue-next'
import { import {
Button, Button,
} from '@/lib/registry/default/ui/button' } from '@/lib/registry/default/ui/button'
import { cn } from '@/lib/utils'
const props = withDefaults(defineProps<PaginationNextProps>(), { const props = withDefaults(defineProps<PaginationNextProps & { class?: HTMLAttributes['class'] }>(), {
asChild: true, asChild: true,
}) })
const forwarded = useForwardProps(props)
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<PaginationNext v-bind="forwarded"> <PaginationNext v-bind="delegatedProps">
<Button class="w-10 h-10 p-0" variant="outline"> <Button :class="cn('w-10 h-10 p-0', props.class)" variant="outline">
<slot> <slot>
<ChevronRight class="h-4 w-4" /> <ChevronRight class="h-4 w-4" />
</slot> </slot>

View File

@ -1,19 +1,26 @@
<script setup lang="ts"> <script setup lang="ts">
import { PaginationPrev, type PaginationPrevProps, useForwardProps } from 'radix-vue' import { type HTMLAttributes, computed } from 'vue'
import { PaginationPrev, type PaginationPrevProps } from 'radix-vue'
import { ChevronLeft } from 'lucide-vue-next' import { ChevronLeft } from 'lucide-vue-next'
import { import {
Button, Button,
} from '@/lib/registry/default/ui/button' } from '@/lib/registry/default/ui/button'
import { cn } from '@/lib/utils'
const props = withDefaults(defineProps<PaginationPrevProps>(), { const props = withDefaults(defineProps<PaginationPrevProps & { class?: HTMLAttributes['class'] }>(), {
asChild: true, asChild: true,
}) })
const forwarded = useForwardProps(props)
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<PaginationPrev v-bind="forwarded"> <PaginationPrev v-bind="delegatedProps">
<Button class="w-10 h-10 p-0" variant="outline"> <Button :class="cn('w-10 h-10 p-0', props.class)" variant="outline">
<slot> <slot>
<ChevronLeft class="h-4 w-4" /> <ChevronLeft class="h-4 w-4" />
</slot> </slot>

View File

@ -1,28 +1,39 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
PopoverContent, PopoverContent,
type PopoverContentEmits, type PopoverContentEmits,
type PopoverContentProps, type PopoverContentProps,
PopoverPortal, PopoverPortal,
useForwardPropsEmits, useEmitAsProps,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
defineOptions({
inheritAttrs: false,
})
const props = withDefaults( const props = withDefaults(
defineProps<PopoverContentProps & { class?: string }>(), defineProps<PopoverContentProps & { class?: HTMLAttributes['class'] }>(),
{ {
sideOffset: 4, sideOffset: 4,
}, },
) )
const emits = defineEmits<PopoverContentEmits>() const emits = defineEmits<PopoverContentEmits>()
const forwarded = useForwardPropsEmits(props, emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const emitsAsProps = useEmitAsProps(emits)
</script> </script>
<template> <template>
<PopoverPortal> <PopoverPortal>
<PopoverContent <PopoverContent
v-bind="{ ...forwarded, ...$attrs }" v-bind="{ ...delegatedProps, ...emitsAsProps, ...$attrs }"
:class=" :class="
cn( cn(
'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', 'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
ProgressIndicator, ProgressIndicator,
ProgressRoot, ProgressRoot,
@ -7,31 +8,32 @@ import {
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = withDefaults( const props = withDefaults(
defineProps<ProgressRootProps & { class?: string }>(), defineProps<ProgressRootProps & { class?: HTMLAttributes['class'] }>(),
{ {
class: '', class: '',
modelValue: 0, modelValue: 0,
}, },
) )
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<ProgressRoot <ProgressRoot
v-bind="delegatedProps"
:class=" :class="
cn( cn(
'relative h-4 w-full overflow-hidden rounded-full bg-secondary', 'relative h-4 w-full overflow-hidden rounded-full bg-secondary',
props.class, props.class,
) )
" "
v-bind="props"
> >
<ProgressIndicator <ProgressIndicator
:class=" class="h-full w-full flex-1 duration-300 bg-foreground transition-all"
cn(
'h-full w-full flex-1 duration-300 bg-foreground transition-all',
props.class,
)
"
:style="`transform: translateX(-${100 - (props.modelValue ?? 0)}%);`" :style="`transform: translateX(-${100 - (props.modelValue ?? 0)}%);`"
/> />
</ProgressRoot> </ProgressRoot>

View File

@ -1,15 +1,28 @@
<script setup lang="ts"> <script setup lang="ts">
import { RadioGroupRoot, type RadioGroupRootEmits, type RadioGroupRootProps, useForwardPropsEmits } from 'radix-vue' import { type HTMLAttributes, computed } from 'vue'
import { RadioGroupRoot, type RadioGroupRootEmits, type RadioGroupRootProps, useEmitAsProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<RadioGroupRootProps & { class?: string }>() const props = defineProps<RadioGroupRootProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<RadioGroupRootEmits>() const emits = defineEmits<RadioGroupRootEmits>()
const forwarded = useForwardPropsEmits(props, emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const emitsAsProps = useEmitAsProps(emits)
</script> </script>
<template> <template>
<RadioGroupRoot :class="cn('grid gap-2', props.class)" v-bind="forwarded"> <RadioGroupRoot
:class="cn('grid gap-2', props.class)"
v-bind="{
...delegatedProps,
...emitsAsProps,
}"
>
<slot /> <slot />
</RadioGroupRoot> </RadioGroupRoot>
</template> </template>

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
RadioGroupIndicator, RadioGroupIndicator,
RadioGroupItem, RadioGroupItem,
@ -7,12 +8,18 @@ import {
import { Circle } from 'lucide-vue-next' import { Circle } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<RadioGroupItemProps & { class?: string }>() const props = defineProps<RadioGroupItemProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<RadioGroupItem <RadioGroupItem
v-bind="props" v-bind="delegatedProps"
:class=" :class="
cn( cn(
'aspect-square h-4 w-4 rounded-full cursor-pointer flex justify-center items-center border border-primary disabled:cursor-not-allowed disabled:opacity-50', 'aspect-square h-4 w-4 rounded-full cursor-pointer flex justify-center items-center border border-primary disabled:cursor-not-allowed disabled:opacity-50',
@ -21,7 +28,7 @@ const props = defineProps<RadioGroupItemProps & { class?: string }>()
" "
> >
<RadioGroupIndicator <RadioGroupIndicator
:class="cn('flex items-center justify-center', props.class)" class="flex items-center justify-center"
> >
<Circle class="w-2.5 h-2.5 text-foreground" /> <Circle class="w-2.5 h-2.5 text-foreground" />
</RadioGroupIndicator> </RadioGroupIndicator>

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
ScrollAreaCorner, ScrollAreaCorner,
ScrollAreaRoot, ScrollAreaRoot,
@ -8,20 +9,18 @@ import {
import ScrollBar from './ScrollBar.vue' import ScrollBar from './ScrollBar.vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = withDefaults( const props = defineProps<ScrollAreaRootProps & { class?: HTMLAttributes['class'] }>()
defineProps<
ScrollAreaRootProps & { class?: string } const delegatedProps = computed(() => {
>(), const { class: _, ...delegated } = props
{
class: '', return delegated
orientation: 'vertical', })
},
)
</script> </script>
<template> <template>
<ScrollAreaRoot :type="type" :class="cn('relative overflow-hidden', props.class)"> <ScrollAreaRoot v-bind="delegatedProps" :class="cn('relative overflow-hidden', props.class)">
<ScrollAreaViewport class="h-full w-full rounded-[inherit]"> <ScrollAreaViewport class="h-full w-full rounded-[inherit]">
<slot /> <slot />
</ScrollAreaViewport> </ScrollAreaViewport>
<ScrollBar /> <ScrollBar />

View File

@ -1,22 +1,29 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { ScrollAreaScrollbar, type ScrollAreaScrollbarProps, ScrollAreaThumb } from 'radix-vue' import { ScrollAreaScrollbar, type ScrollAreaScrollbarProps, ScrollAreaThumb } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = withDefaults(defineProps<ScrollAreaScrollbarProps>(), { const props = withDefaults(defineProps<ScrollAreaScrollbarProps & { class?: HTMLAttributes['class'] }>(), {
orientation: 'vertical', orientation: 'vertical',
}) })
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<ScrollAreaScrollbar <ScrollAreaScrollbar
v-bind="props" v-bind="delegatedProps"
:class=" :class="
cn('flex touch-none select-none transition-colors', cn('flex touch-none select-none transition-colors',
orientation === 'vertical' orientation === 'vertical'
&& 'h-full w-2.5 border-l border-l-transparent p-[1px]', && 'h-full w-2.5 border-l border-l-transparent p-[1px]',
orientation === 'horizontal' orientation === 'horizontal'
&& 'h-2.5 border-t border-t-transparent p-[1px]', && 'h-2.5 border-t border-t-transparent p-[1px]',
$attrs.class ?? '')" props.class)"
> >
<ScrollAreaThumb class="relative flex-1 rounded-full bg-border" /> <ScrollAreaThumb class="relative flex-1 rounded-full bg-border" />
</ScrollAreaScrollbar> </ScrollAreaScrollbar>

View File

@ -1,43 +1,51 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
SelectContent, SelectContent,
type SelectContentEmits, type SelectContentEmits,
type SelectContentProps, type SelectContentProps,
SelectPortal, SelectPortal,
SelectViewport, SelectViewport,
useForwardPropsEmits, useEmitAsProps,
} from 'radix-vue' } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
defineOptions({
inheritAttrs: false,
})
const props = withDefaults( const props = withDefaults(
defineProps<SelectContentProps & { class?: string }>(), { defineProps<SelectContentProps & { class?: HTMLAttributes['class'] }>(), {
position: 'popper', position: 'popper',
sideOffset: 4, sideOffset: 4,
}, },
) )
const emits = defineEmits<SelectContentEmits>() const emits = defineEmits<SelectContentEmits>()
const forwarded = useForwardPropsEmits(props, emits) const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const emitsAsProps = useEmitAsProps(emits)
</script> </script>
<template> <template>
<SelectPortal> <SelectPortal>
<SelectContent <SelectContent
v-bind="{ ...forwarded, ...$attrs }" v-bind="{ ...delegatedProps, ...emitsAsProps, ...$attrs }" :class="cn(
:class=" 'relative z-50 min-w-[10rem] overflow-hidden rounded-md bg-background border border-border text-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
cn( position === 'popper'
'relative z-50 min-w-[10rem] overflow-hidden rounded-md bg-background border border-border text-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', && 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
position === 'popper' props.class,
&& '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,
)
" "
> >
<SelectViewport <SelectViewport
:class=" :class="cn('p-1',
cn('p-1', position === 'popper'
position === 'popper' && 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]')"
&& 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]')"
> >
<slot /> <slot />
</SelectViewport> </SelectViewport>

View File

@ -1,12 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { SelectGroup, type SelectGroupProps } from 'radix-vue' import { SelectGroup, type SelectGroupProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<SelectGroupProps & { class?: string }>() const props = defineProps<SelectGroupProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<SelectGroup :class="cn('p-1 w-full', props.class)" v-bind="props"> <SelectGroup :class="cn('p-1 w-full', props.class)" v-bind="delegatedProps">
<slot /> <slot />
</SelectGroup> </SelectGroup>
</template> </template>

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { import {
SelectItem, SelectItem,
SelectItemIndicator, SelectItemIndicator,
@ -8,12 +9,18 @@ import {
import { Check } from 'lucide-vue-next' import { Check } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<SelectItemProps & { class?: string }>() const props = defineProps<SelectItemProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<SelectItem <SelectItem
v-bind="props" v-bind="delegatedProps"
:class=" :class="
cn( cn(
'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', 'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',

View File

@ -1,10 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { SelectSeparator, type SelectSeparatorProps } from 'radix-vue' import { SelectSeparator, type SelectSeparatorProps } from 'radix-vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = defineProps<SelectSeparatorProps & { class?: string }>() const props = defineProps<SelectSeparatorProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<SelectSeparator :class="cn('-mx-1 my-1 h-px bg-muted', props.class)" /> <SelectSeparator v-bind="delegatedProps" :class="cn('-mx-1 my-1 h-px bg-muted', props.class)" />
</template> </template>

View File

@ -1,20 +1,27 @@
<script setup lang="ts"> <script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { SelectIcon, SelectTrigger, type SelectTriggerProps } from 'radix-vue' import { SelectIcon, SelectTrigger, type SelectTriggerProps } from 'radix-vue'
import { ChevronDown } from 'lucide-vue-next' import { ChevronDown } from 'lucide-vue-next'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
const props = withDefaults( const props = withDefaults(
defineProps<SelectTriggerProps & { class?: string; invalid?: boolean }>(), defineProps<SelectTriggerProps & { class?: HTMLAttributes['class']; invalid?: boolean }>(),
{ {
class: '', class: '',
invalid: false, invalid: false,
}, },
) )
const delegatedProps = computed(() => {
const { class: _, invalid, ...delegated } = props
return delegated
})
</script> </script>
<template> <template>
<SelectTrigger <SelectTrigger
v-bind="props" v-bind="delegatedProps"
:class="[ :class="[
cn( cn(
'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', 'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',