mirror of
https://github.com/versia-pub/frontend.git
synced 2026-03-13 03:29:16 +01:00
chore: ⬆️ Upgrade to the latest Shadcn-Vue version
Some checks failed
Some checks failed
This commit is contained in:
parent
7649ecfb80
commit
092bce0f24
169 changed files with 1860 additions and 1088 deletions
|
|
@ -4,7 +4,7 @@ import {
|
|||
type AlertDialogProps,
|
||||
AlertDialogRoot,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
|
||||
const props = defineProps<AlertDialogProps>();
|
||||
const emits = defineEmits<AlertDialogEmits>();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import { buttonVariants } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { AlertDialogAction, type AlertDialogActionProps } from "radix-vue";
|
||||
import { AlertDialogAction, type AlertDialogActionProps } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
import { buttonVariants } from "~/components/ui/button";
|
||||
|
||||
const props = defineProps<
|
||||
AlertDialogActionProps & { class?: HTMLAttributes["class"] }
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import { buttonVariants } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { AlertDialogCancel, type AlertDialogCancelProps } from "radix-vue";
|
||||
import { AlertDialogCancel, type AlertDialogCancelProps } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
import { buttonVariants } from "~/components/ui/button";
|
||||
|
||||
const props = defineProps<
|
||||
AlertDialogCancelProps & { class?: HTMLAttributes["class"] }
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
AlertDialogOverlay,
|
||||
AlertDialogPortal,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
@ -27,13 +27,13 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|||
<template>
|
||||
<AlertDialogPortal>
|
||||
<AlertDialogOverlay
|
||||
class="fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
|
||||
class="fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
|
||||
/>
|
||||
<AlertDialogContent
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded',
|
||||
'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { cn } from "@/lib/utils";
|
|||
import {
|
||||
AlertDialogDescription,
|
||||
type AlertDialogDescriptionProps,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { AlertDialogTitle, type AlertDialogTitleProps } from "radix-vue";
|
||||
import { AlertDialogTitle, type AlertDialogTitleProps } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { AlertDialogTrigger, type AlertDialogTriggerProps } from "radix-vue";
|
||||
import { AlertDialogTrigger, type AlertDialogTriggerProps } from "reka-ui";
|
||||
|
||||
const props = defineProps<AlertDialogTriggerProps>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export { default as AlertDescription } from "./AlertDescription.vue";
|
|||
export { default as AlertTitle } from "./AlertTitle.vue";
|
||||
|
||||
export const alertVariants = cva(
|
||||
"relative w-full rounded border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
|
||||
"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg]:size-4",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { AvatarRoot } from "radix-vue";
|
||||
import { AvatarRoot } from "reka-ui";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { type AvatarVariants, avatarVariant } from ".";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { AvatarFallback, type AvatarFallbackProps } from "radix-vue";
|
||||
import { AvatarFallback, type AvatarFallbackProps } from "reka-ui";
|
||||
|
||||
const props = defineProps<AvatarFallbackProps>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
import { AvatarImage, type AvatarImageProps } from "radix-vue";
|
||||
import type { AvatarImageProps } from "reka-ui";
|
||||
import { AvatarImage } from "reka-ui";
|
||||
|
||||
const props = defineProps<AvatarImageProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AvatarImage v-bind="props" class="h-full w-full object-cover" />
|
||||
<AvatarImage v-bind="props" class="h-full w-full object-cover">
|
||||
<slot />
|
||||
</AvatarImage>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export const avatarVariant = cva(
|
|||
},
|
||||
shape: {
|
||||
circle: "rounded-full",
|
||||
square: "rounded",
|
||||
square: "rounded-md",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Primitive, type PrimitiveProps } from "radix-vue";
|
||||
import { Primitive, type PrimitiveProps } from "reka-ui";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { type ButtonVariants, buttonVariants } from ".";
|
||||
|
||||
|
|
@ -20,7 +20,6 @@ const props = withDefaults(defineProps<Props>(), {
|
|||
:as="as"
|
||||
:as-child="asChild"
|
||||
:class="cn(buttonVariants({ variant, size }), props.class)"
|
||||
data-component="button"
|
||||
>
|
||||
<slot />
|
||||
</Primitive>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import { type VariantProps, cva } from "class-variance-authority";
|
||||
import type { VariantProps } from "class-variance-authority";
|
||||
import { cva } from "class-variance-authority";
|
||||
|
||||
export { default as Button } from "./Button.vue";
|
||||
|
||||
export const buttonVariants = cva(
|
||||
|
|
@ -7,21 +9,21 @@ export const buttonVariants = cva(
|
|||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
||||
"bg-primary text-primary-foreground hover:bg-primary/90",
|
||||
destructive:
|
||||
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
||||
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
||||
outline:
|
||||
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
||||
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
||||
secondary:
|
||||
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
||||
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
},
|
||||
size: {
|
||||
default: "h-9 px-4 py-2",
|
||||
sm: "h-8 px-3 text-xs",
|
||||
lg: "h-10 px-8",
|
||||
icon: "size-9",
|
||||
default: "h-10 px-4 py-2",
|
||||
sm: "h-9 rounded-md px-3",
|
||||
lg: "h-11 rounded-md px-8",
|
||||
icon: "h-10 w-10",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
|
|
|
|||
|
|
@ -1,22 +1,21 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Primitive, type PrimitiveProps } from "radix-vue";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<PrimitiveProps & { class?: HTMLAttributes["class"] }>(),
|
||||
{
|
||||
as: "div",
|
||||
},
|
||||
);
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes["class"];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Primitive :as="props.as" :as-child="props.asChild" :class="cn(
|
||||
'rounded-lg border bg-card/90 backdrop-blur-xl text-card-foreground shadow-sm',
|
||||
props.class,
|
||||
)
|
||||
" data-component="card">
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'rounded-lg border bg-card text-card-foreground shadow-sm flex flex-col gap-6 p-4 items-center justify-center',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</Primitive>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const props = defineProps<{
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="cn('p-6 pt-0', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
<div :class="cn('flex flex-col gap-2', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const props = defineProps<{
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="cn('flex items-center p-6 pt-0', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
<div :class="cn('flex items-center', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,14 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Primitive, type PrimitiveProps } from "radix-vue";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<PrimitiveProps & { class?: HTMLAttributes["class"] }>(),
|
||||
{
|
||||
as: "div",
|
||||
},
|
||||
);
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes["class"];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Primitive :as="props.as" :as-child="props.asChild" :class="cn('flex flex-col gap-y-1.5 p-6', props.class)">
|
||||
<div :class="cn('flex flex-col gap-y-1.5', props.class)">
|
||||
<slot />
|
||||
</Primitive>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Check } from "lucide-vue-next";
|
||||
import type { CheckboxRootEmits, CheckboxRootProps } from "radix-vue";
|
||||
import {
|
||||
CheckboxIndicator,
|
||||
CheckboxRoot,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
import type { CheckboxRootEmits, CheckboxRootProps } from "reka-ui";
|
||||
import { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
@ -24,12 +20,16 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<CheckboxRoot v-bind="forwarded" :class="cn('peer size-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',
|
||||
props.class)">
|
||||
<CheckboxIndicator class="flex h-full w-full items-center justify-center text-current">
|
||||
<slot>
|
||||
<Check class="size-4" />
|
||||
</slot>
|
||||
</CheckboxIndicator>
|
||||
</CheckboxRoot>
|
||||
<CheckboxRoot
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn('peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',
|
||||
props.class)"
|
||||
>
|
||||
<CheckboxIndicator class="flex h-full w-full items-center justify-center text-current">
|
||||
<slot>
|
||||
<Check class="h-4 w-4" />
|
||||
</slot>
|
||||
</CheckboxIndicator>
|
||||
</CheckboxRoot>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { CollapsibleRootEmits, CollapsibleRootProps } from "radix-vue";
|
||||
import { CollapsibleRoot, useForwardPropsEmits } from "radix-vue";
|
||||
import type { CollapsibleRootEmits, CollapsibleRootProps } from "reka-ui";
|
||||
import { CollapsibleRoot, useForwardPropsEmits } from "reka-ui";
|
||||
|
||||
const props = defineProps<CollapsibleRootProps>();
|
||||
const emits = defineEmits<CollapsibleRootEmits>();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { CollapsibleContent, type CollapsibleContentProps } from "radix-vue";
|
||||
import { CollapsibleContent, type CollapsibleContentProps } from "reka-ui";
|
||||
|
||||
const props = defineProps<CollapsibleContentProps>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { CollapsibleTrigger, type CollapsibleTriggerProps } from "radix-vue";
|
||||
import { CollapsibleTrigger, type CollapsibleTriggerProps } from "reka-ui";
|
||||
|
||||
const props = defineProps<CollapsibleTriggerProps>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComboboxRootEmits, ComboboxRootProps } from "radix-vue";
|
||||
import { ComboboxRoot, useForwardPropsEmits } from "radix-vue";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
import type { ListboxRootEmits, ListboxRootProps } from "reka-ui";
|
||||
import { ListboxRoot, useFilter, useForwardPropsEmits } from "reka-ui";
|
||||
import { type HTMLAttributes, computed, reactive, ref, watch } from "vue";
|
||||
import { provideCommandContext } from ".";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<ComboboxRootProps & { class?: HTMLAttributes["class"] }>(),
|
||||
defineProps<ListboxRootProps & { class?: HTMLAttributes["class"] }>(),
|
||||
{
|
||||
open: true,
|
||||
modelValue: "",
|
||||
},
|
||||
);
|
||||
|
||||
const emits = defineEmits<ComboboxRootEmits>();
|
||||
const emits = defineEmits<ListboxRootEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
|
@ -21,11 +21,84 @@ const delegatedProps = computed(() => {
|
|||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
|
||||
const allItems = ref<Map<string, string>>(new Map());
|
||||
const allGroups = ref<Map<string, Set<string>>>(new Map());
|
||||
|
||||
const { contains } = useFilter({ sensitivity: "base" });
|
||||
const filterState = reactive({
|
||||
search: "",
|
||||
filtered: {
|
||||
/** The count of all visible items. */
|
||||
count: 0,
|
||||
/** Map from visible item id to its search score. */
|
||||
items: new Map() as Map<string, number>,
|
||||
/** Set of groups with at least one visible item. */
|
||||
groups: new Set() as Set<string>,
|
||||
},
|
||||
});
|
||||
|
||||
function filterItems() {
|
||||
if (!filterState.search) {
|
||||
filterState.filtered.count = allItems.value.size;
|
||||
// Do nothing, each item will know to show itself because search is empty
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset the groups
|
||||
filterState.filtered.groups = new Set();
|
||||
let itemCount = 0;
|
||||
|
||||
// Check which items should be included
|
||||
for (const [id, value] of allItems.value) {
|
||||
const score = contains(value, filterState.search);
|
||||
filterState.filtered.items.set(id, score ? 1 : 0);
|
||||
if (score) {
|
||||
itemCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Check which groups have at least 1 item shown
|
||||
for (const [groupId, group] of allGroups.value) {
|
||||
for (const itemId of group) {
|
||||
if (filterState.filtered.items.get(itemId)) {
|
||||
filterState.filtered.groups.add(groupId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filterState.filtered.count = itemCount;
|
||||
}
|
||||
|
||||
function handleSelect() {
|
||||
filterState.search = "";
|
||||
}
|
||||
|
||||
watch(
|
||||
() => filterState.search,
|
||||
() => {
|
||||
filterItems();
|
||||
},
|
||||
);
|
||||
|
||||
provideCommandContext({
|
||||
allItems,
|
||||
allGroups,
|
||||
filterState,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ComboboxRoot v-bind="forwarded"
|
||||
:class="cn('flex h-full w-full flex-col overflow-hidden rounded bg-popover text-popover-foreground', props.class)">
|
||||
<ListboxRoot
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</ComboboxRoot>
|
||||
</ListboxRoot>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import type { DialogRootEmits, DialogRootProps } from "radix-vue";
|
||||
import { useForwardPropsEmits } from "radix-vue";
|
||||
import { Dialog, DialogContent } from "~/components/ui/dialog";
|
||||
import { Dialog, DialogContent } from "@/components/ui/dialog";
|
||||
import type { DialogRootEmits, DialogRootProps } from "reka-ui";
|
||||
import { useForwardPropsEmits } from "reka-ui";
|
||||
import Command from "./Command.vue";
|
||||
|
||||
const props = defineProps<DialogRootProps>();
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComboboxEmptyProps } from "radix-vue";
|
||||
import { ComboboxEmpty } from "radix-vue";
|
||||
import type { PrimitiveProps } from "reka-ui";
|
||||
import { Primitive } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
import { useCommand } from ".";
|
||||
|
||||
const props = defineProps<
|
||||
ComboboxEmptyProps & { class?: HTMLAttributes["class"] }
|
||||
PrimitiveProps & { class?: HTMLAttributes["class"] }
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
|
|
@ -13,10 +14,15 @@ const delegatedProps = computed(() => {
|
|||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const { filterState } = useCommand();
|
||||
const isRender = computed(
|
||||
() => !!filterState.search && filterState.filtered.count === 0,
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ComboboxEmpty v-bind="delegatedProps" :class="cn('py-6 text-center text-sm', props.class)">
|
||||
<Primitive v-if="isRender" v-bind="delegatedProps" :class="cn('py-6 text-center text-sm', props.class)">
|
||||
<slot />
|
||||
</ComboboxEmpty>
|
||||
</Primitive>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComboboxGroupProps } from "radix-vue";
|
||||
import { ComboboxGroup, ComboboxLabel } from "radix-vue";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
import type { ListboxGroupProps } from "reka-ui";
|
||||
import { ListboxGroup, ListboxGroupLabel, useId } from "reka-ui";
|
||||
import { type HTMLAttributes, computed, onMounted, onUnmounted } from "vue";
|
||||
import { provideCommandGroupContext, useCommand } from ".";
|
||||
|
||||
const props = defineProps<
|
||||
ComboboxGroupProps & {
|
||||
ListboxGroupProps & {
|
||||
class?: HTMLAttributes["class"];
|
||||
heading?: string;
|
||||
}
|
||||
|
|
@ -16,16 +17,43 @@ const delegatedProps = computed(() => {
|
|||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const { allGroups, filterState } = useCommand();
|
||||
const id = useId();
|
||||
|
||||
const isRender = computed(() =>
|
||||
filterState.search ? filterState.filtered.groups.has(id) : true,
|
||||
);
|
||||
|
||||
provideCommandGroupContext({ id });
|
||||
onMounted(() => {
|
||||
if (!allGroups.value.has(id)) {
|
||||
allGroups.value.set(id, new Set());
|
||||
}
|
||||
});
|
||||
onUnmounted(() => {
|
||||
allGroups.value.delete(id);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ComboboxGroup
|
||||
v-bind="delegatedProps"
|
||||
:class="cn('overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground', props.class)"
|
||||
>
|
||||
<ComboboxLabel v-if="heading" class="px-2 py-1.5 text-xs font-medium text-muted-foreground">
|
||||
{{ heading }}
|
||||
</ComboboxLabel>
|
||||
<slot />
|
||||
</ComboboxGroup>
|
||||
<ListboxGroup
|
||||
v-bind="delegatedProps"
|
||||
:id="id"
|
||||
:class="
|
||||
cn(
|
||||
'overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
:hidden="isRender ? undefined : true"
|
||||
>
|
||||
<ListboxGroupLabel
|
||||
v-if="heading"
|
||||
class="px-2 py-1.5 text-xs font-medium text-muted-foreground"
|
||||
>
|
||||
{{ heading }}
|
||||
</ListboxGroupLabel>
|
||||
<slot />
|
||||
</ListboxGroup>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -2,18 +2,19 @@
|
|||
import { cn } from "@/lib/utils";
|
||||
import { Search } from "lucide-vue-next";
|
||||
import {
|
||||
ComboboxInput,
|
||||
type ComboboxInputProps,
|
||||
ListboxFilter,
|
||||
type ListboxFilterProps,
|
||||
useForwardProps,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
import { useCommand } from ".";
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
const props = defineProps<
|
||||
ComboboxInputProps & {
|
||||
ListboxFilterProps & {
|
||||
class?: HTMLAttributes["class"];
|
||||
}
|
||||
>();
|
||||
|
|
@ -25,12 +26,18 @@ const delegatedProps = computed(() => {
|
|||
});
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
|
||||
const { filterState } = useCommand();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex items-center border-b px-3" cmdk-input-wrapper>
|
||||
<Search class="mr-2 size-4 shrink-0 opacity-50" />
|
||||
<ComboboxInput v-bind="{ ...forwardedProps, ...$attrs }" auto-focus
|
||||
:class="cn('flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50', props.class)" />
|
||||
</div>
|
||||
<div class="flex items-center border-b px-3" cmdk-input-wrapper>
|
||||
<Search class="mr-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
<ListboxFilter
|
||||
v-bind="{ ...forwardedProps, ...$attrs }"
|
||||
v-model="filterState.search"
|
||||
auto-focus
|
||||
:class="cn('flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50', props.class)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,21 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComboboxItemEmits, ComboboxItemProps } from "radix-vue";
|
||||
import { ComboboxItem, useForwardPropsEmits } from "radix-vue";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
import { useCurrentElement } from "@vueuse/core";
|
||||
import type { ListboxItemEmits, ListboxItemProps } from "reka-ui";
|
||||
import { ListboxItem, useForwardPropsEmits, useId } from "reka-ui";
|
||||
import {
|
||||
type HTMLAttributes,
|
||||
computed,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
ref,
|
||||
} from "vue";
|
||||
import { useCommand, useCommandGroup } from ".";
|
||||
|
||||
const props = defineProps<
|
||||
ComboboxItemProps & { class?: HTMLAttributes["class"] }
|
||||
ListboxItemProps & { class?: HTMLAttributes["class"] }
|
||||
>();
|
||||
const emits = defineEmits<ComboboxItemEmits>();
|
||||
const emits = defineEmits<ListboxItemEmits>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
|
@ -16,13 +24,72 @@ const delegatedProps = computed(() => {
|
|||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
|
||||
const id = useId();
|
||||
const { filterState, allItems, allGroups } = useCommand();
|
||||
const groupContext = useCommandGroup();
|
||||
|
||||
const isRender = computed(() => {
|
||||
if (filterState.search) {
|
||||
const filteredCurrentItem = filterState.filtered.items.get(id);
|
||||
// If the filtered items is undefined means not in the all times map yet
|
||||
// Do the first render to add into the map
|
||||
if (filteredCurrentItem === undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check with filter
|
||||
return filteredCurrentItem > 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
const itemRef = ref();
|
||||
const currentElement = useCurrentElement(itemRef);
|
||||
onMounted(() => {
|
||||
if (!(currentElement.value instanceof HTMLElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// textValue to perform filter
|
||||
allItems.value.set(
|
||||
id,
|
||||
currentElement.value.textContent ?? props.value?.toString() ?? "",
|
||||
);
|
||||
|
||||
const groupId = groupContext?.id;
|
||||
if (groupId) {
|
||||
if (allGroups.value.has(groupId)) {
|
||||
allGroups.value.get(groupId)?.add(id);
|
||||
} else {
|
||||
allGroups.value.set(groupId, new Set([id]));
|
||||
}
|
||||
}
|
||||
});
|
||||
onUnmounted(() => {
|
||||
allItems.value.delete(id);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ComboboxItem
|
||||
v-bind="forwarded"
|
||||
:class="cn('relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</ComboboxItem>
|
||||
<ListboxItem
|
||||
v-if="isRender"
|
||||
v-bind="forwarded"
|
||||
:id="id"
|
||||
ref="itemRef"
|
||||
:class="
|
||||
cn(
|
||||
'relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
@select="
|
||||
() => {
|
||||
filterState.search = '';
|
||||
}
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</ListboxItem>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComboboxContentEmits, ComboboxContentProps } from "radix-vue";
|
||||
import { ComboboxContent, useForwardPropsEmits } from "radix-vue";
|
||||
import type { ListboxContentProps } from "reka-ui";
|
||||
import { ListboxContent, useForwardProps } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<ComboboxContentProps & { class?: HTMLAttributes["class"] }>(),
|
||||
{
|
||||
dismissable: false,
|
||||
},
|
||||
);
|
||||
const emits = defineEmits<ComboboxContentEmits>();
|
||||
const props = defineProps<
|
||||
ListboxContentProps & { class?: HTMLAttributes["class"] }
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
|
@ -18,13 +14,13 @@ const delegatedProps = computed(() => {
|
|||
return delegated;
|
||||
});
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||
const forwarded = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ComboboxContent v-bind="forwarded" :class="cn('max-h-[300px] overflow-y-auto overflow-x-hidden', props.class)">
|
||||
<ListboxContent v-bind="forwarded" :class="cn('max-h-[300px] overflow-y-auto overflow-x-hidden', props.class)">
|
||||
<div role="presentation">
|
||||
<slot />
|
||||
</div>
|
||||
</ComboboxContent>
|
||||
</ListboxContent>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComboboxSeparatorProps } from "radix-vue";
|
||||
import { ComboboxSeparator } from "radix-vue";
|
||||
import type { SeparatorProps } from "reka-ui";
|
||||
import { Separator } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
ComboboxSeparatorProps & { class?: HTMLAttributes["class"] }
|
||||
SeparatorProps & { class?: HTMLAttributes["class"] }
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
|
|
@ -16,10 +16,10 @@ const delegatedProps = computed(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<ComboboxSeparator
|
||||
<Separator
|
||||
v-bind="delegatedProps"
|
||||
:class="cn('-mx-1 h-px bg-border', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</ComboboxSeparator>
|
||||
</Separator>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
import { createContext } from "reka-ui";
|
||||
import type { Ref } from "vue";
|
||||
|
||||
export { default as Command } from "./Command.vue";
|
||||
export { default as CommandDialog } from "./CommandDialog.vue";
|
||||
export { default as CommandEmpty } from "./CommandEmpty.vue";
|
||||
|
|
@ -7,3 +10,20 @@ export { default as CommandItem } from "./CommandItem.vue";
|
|||
export { default as CommandList } from "./CommandList.vue";
|
||||
export { default as CommandSeparator } from "./CommandSeparator.vue";
|
||||
export { default as CommandShortcut } from "./CommandShortcut.vue";
|
||||
|
||||
export const [useCommand, provideCommandContext] = createContext<{
|
||||
allItems: Ref<Map<string, string>>;
|
||||
allGroups: Ref<Map<string, Set<string>>>;
|
||||
filterState: {
|
||||
search: string;
|
||||
filtered: {
|
||||
count: number;
|
||||
items: Map<string, number>;
|
||||
groups: Set<string>;
|
||||
};
|
||||
};
|
||||
}>("Command");
|
||||
|
||||
export const [useCommandGroup, provideCommandGroupContext] = createContext<{
|
||||
id?: string;
|
||||
}>("CommandGroup");
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
type DialogRootEmits,
|
||||
type DialogRootProps,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
|
||||
const props = defineProps<DialogRootProps>();
|
||||
const emits = defineEmits<DialogRootEmits>();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { DialogClose, type DialogCloseProps } from "radix-vue";
|
||||
import { DialogClose, type DialogCloseProps } from "reka-ui";
|
||||
|
||||
const props = defineProps<DialogCloseProps>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
DialogOverlay,
|
||||
DialogPortal,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
@ -32,16 +32,24 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|||
<template>
|
||||
<DialogPortal>
|
||||
<DialogOverlay
|
||||
class="fixed inset-0 z-50 bg-black/80 backdrop-blur data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" />
|
||||
<DialogContent v-bind="forwarded" :class="cn(
|
||||
'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
|
||||
props.class,
|
||||
)">
|
||||
class="fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
|
||||
/>
|
||||
<DialogContent
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
|
||||
<DialogClose v-if="!props.hideClose"
|
||||
class="absolute right-4 top-4 rounded opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
||||
<X class="size-4" />
|
||||
<DialogClose
|
||||
v-if="!hideClose"
|
||||
class="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground"
|
||||
>
|
||||
<X class="w-4 h-4" />
|
||||
<span class="sr-only">Close</span>
|
||||
</DialogClose>
|
||||
</DialogContent>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
DialogDescription,
|
||||
type DialogDescriptionProps,
|
||||
useForwardProps,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const props = defineProps<{ class?: HTMLAttributes["class"] }>();
|
|||
<div
|
||||
:class="
|
||||
cn(
|
||||
'flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-x-2 gap-y-2',
|
||||
'flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-x-2',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
DialogOverlay,
|
||||
DialogPortal,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
@ -29,7 +29,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|||
<template>
|
||||
<DialogPortal>
|
||||
<DialogOverlay
|
||||
class="fixed inset-0 z-50 grid place-items-center overflow-y-auto bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
|
||||
class="fixed inset-0 z-50 grid place-items-center overflow-y-auto bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
|
||||
>
|
||||
<DialogContent
|
||||
:class="
|
||||
|
|
@ -52,7 +52,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|||
<DialogClose
|
||||
class="absolute top-3 right-3 p-0.5 transition-colors rounded-md hover:bg-secondary"
|
||||
>
|
||||
<X class="size-4" />
|
||||
<X class="w-4 h-4" />
|
||||
<span class="sr-only">Close</span>
|
||||
</DialogClose>
|
||||
</DialogContent>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { DialogTitle, type DialogTitleProps, useForwardProps } from "radix-vue";
|
||||
import { DialogTitle, type DialogTitleProps, useForwardProps } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { DialogTrigger, type DialogTriggerProps } from "radix-vue";
|
||||
import { DialogTrigger, type DialogTriggerProps } from "reka-ui";
|
||||
|
||||
const props = defineProps<DialogTriggerProps>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts" setup>
|
||||
import { useForwardPropsEmits } from "radix-vue";
|
||||
import { useForwardPropsEmits } from "reka-ui";
|
||||
import type { DrawerRootEmits, DrawerRootProps } from "vaul-vue";
|
||||
import { DrawerRoot } from "vaul-vue";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts" setup>
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { DialogContentEmits, DialogContentProps } from "radix-vue";
|
||||
import { useForwardPropsEmits } from "radix-vue";
|
||||
import type { DialogContentEmits, DialogContentProps } from "reka-ui";
|
||||
import { useForwardPropsEmits } from "reka-ui";
|
||||
import { DrawerContent, DrawerPortal } from "vaul-vue";
|
||||
import type { HtmlHTMLAttributes } from "vue";
|
||||
import DrawerOverlay from "./DrawerOverlay.vue";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts" setup>
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { DialogOverlayProps } from "radix-vue";
|
||||
import type { DialogOverlayProps } from "reka-ui";
|
||||
import { DrawerOverlay } from "vaul-vue";
|
||||
import { type HtmlHTMLAttributes, computed } from "vue";
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
type DropdownMenuRootEmits,
|
||||
type DropdownMenuRootProps,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
|
||||
const props = defineProps<DropdownMenuRootProps>();
|
||||
const emits = defineEmits<DropdownMenuRootEmits>();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
type DropdownMenuCheckboxItemProps,
|
||||
DropdownMenuItemIndicator,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
@ -25,15 +25,18 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuCheckboxItem v-bind="forwarded" :class="cn(
|
||||
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
props.class,
|
||||
)">
|
||||
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<DropdownMenuItemIndicator>
|
||||
<Check class="!mr-0" />
|
||||
</DropdownMenuItemIndicator>
|
||||
</span>
|
||||
<slot />
|
||||
</DropdownMenuCheckboxItem>
|
||||
<DropdownMenuCheckboxItem
|
||||
v-bind="forwarded"
|
||||
:class=" cn(
|
||||
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
props.class,
|
||||
)"
|
||||
>
|
||||
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<DropdownMenuItemIndicator>
|
||||
<Check class="w-4 h-4" />
|
||||
</DropdownMenuItemIndicator>
|
||||
</span>
|
||||
<slot />
|
||||
</DropdownMenuCheckboxItem>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
type DropdownMenuContentProps,
|
||||
DropdownMenuPortal,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = withDefaults(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { DropdownMenuGroup, type DropdownMenuGroupProps } from "radix-vue";
|
||||
import { DropdownMenuGroup, type DropdownMenuGroupProps } from "reka-ui";
|
||||
|
||||
const props = defineProps<DropdownMenuGroupProps>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
DropdownMenuItem,
|
||||
type DropdownMenuItemProps,
|
||||
useForwardProps,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
@ -21,11 +21,16 @@ const forwardedProps = useForwardProps(delegatedProps);
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuItem v-bind="forwardedProps" :class="cn(
|
||||
'relative flex cursor-default select-none items-center rounded-sm gap-2 px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:mr-0.5 w-full',
|
||||
inset && 'pl-8',
|
||||
props.class,
|
||||
)">
|
||||
<DropdownMenuItem
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn(
|
||||
'relative flex w-full cursor-default select-none items-center rounded-sm gap-2 px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0',
|
||||
inset && 'pl-8',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</DropdownMenuItem>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
DropdownMenuLabel,
|
||||
type DropdownMenuLabelProps,
|
||||
useForwardProps,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
@ -24,8 +24,10 @@ const forwardedProps = useForwardProps(delegatedProps);
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuLabel v-bind="forwardedProps"
|
||||
:class="cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', props.class)">
|
||||
<slot />
|
||||
</DropdownMenuLabel>
|
||||
<DropdownMenuLabel
|
||||
v-bind="forwardedProps"
|
||||
:class="cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</DropdownMenuLabel>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
type DropdownMenuRadioGroupEmits,
|
||||
type DropdownMenuRadioGroupProps,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
|
||||
const props = defineProps<DropdownMenuRadioGroupProps>();
|
||||
const emits = defineEmits<DropdownMenuRadioGroupEmits>();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
type DropdownMenuRadioItemEmits,
|
||||
type DropdownMenuRadioItemProps,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
@ -26,15 +26,18 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<DropdownMenuRadioItem v-bind="forwarded" :class="cn(
|
||||
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
props.class,
|
||||
)">
|
||||
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<DropdownMenuItemIndicator>
|
||||
<Circle class="size-2 fill-current" />
|
||||
</DropdownMenuItemIndicator>
|
||||
</span>
|
||||
<slot />
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem
|
||||
v-bind="forwarded"
|
||||
:class="cn(
|
||||
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
props.class,
|
||||
)"
|
||||
>
|
||||
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<DropdownMenuItemIndicator>
|
||||
<Circle class="h-2 w-2 fill-current" />
|
||||
</DropdownMenuItemIndicator>
|
||||
</span>
|
||||
<slot />
|
||||
</DropdownMenuRadioItem>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { cn } from "@/lib/utils";
|
|||
import {
|
||||
DropdownMenuSeparator,
|
||||
type DropdownMenuSeparatorProps,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
type DropdownMenuSubEmits,
|
||||
type DropdownMenuSubProps,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
|
||||
const props = defineProps<DropdownMenuSubProps>();
|
||||
const emits = defineEmits<DropdownMenuSubEmits>();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
type DropdownMenuSubContentEmits,
|
||||
type DropdownMenuSubContentProps,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
DropdownMenuSubTrigger,
|
||||
type DropdownMenuSubTriggerProps,
|
||||
useForwardProps,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
@ -30,6 +30,6 @@ const forwardedProps = useForwardProps(delegatedProps);
|
|||
)"
|
||||
>
|
||||
<slot />
|
||||
<ChevronRight class="ml-auto size-4" />
|
||||
<ChevronRight class="ml-auto h-4 w-4" />
|
||||
</DropdownMenuSubTrigger>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import {
|
|||
DropdownMenuTrigger,
|
||||
type DropdownMenuTriggerProps,
|
||||
useForwardProps,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
|
||||
const props = defineProps<DropdownMenuTriggerProps>();
|
||||
|
||||
|
|
|
|||
|
|
@ -13,4 +13,4 @@ export { default as DropdownMenuSub } from "./DropdownMenuSub.vue";
|
|||
export { default as DropdownMenuSubContent } from "./DropdownMenuSubContent.vue";
|
||||
export { default as DropdownMenuSubTrigger } from "./DropdownMenuSubTrigger.vue";
|
||||
export { default as DropdownMenuTrigger } from "./DropdownMenuTrigger.vue";
|
||||
export { DropdownMenuPortal } from "radix-vue";
|
||||
export { DropdownMenuPortal } from "reka-ui";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts" setup>
|
||||
import { Slot } from "radix-vue";
|
||||
import { Slot } from "reka-ui";
|
||||
import { useFormField } from "./useFormField";
|
||||
|
||||
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
|
||||
|
|
|
|||
|
|
@ -1,26 +1,19 @@
|
|||
<script lang="ts" setup>
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Primitive, type PrimitiveProps, useId } from "radix-vue";
|
||||
import { useId } from "reka-ui";
|
||||
import { type HTMLAttributes, provide } from "vue";
|
||||
import { FORM_ITEM_INJECTION_KEY } from "./injectionKeys";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<
|
||||
PrimitiveProps & {
|
||||
class?: HTMLAttributes["class"];
|
||||
}
|
||||
>(),
|
||||
{
|
||||
as: "div",
|
||||
},
|
||||
);
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes["class"];
|
||||
}>();
|
||||
|
||||
const id = useId();
|
||||
provide(FORM_ITEM_INJECTION_KEY, id);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Primitive :as="props.as" :as-child="props.asChild" :class="cn('space-y-2', props.class)">
|
||||
<slot />
|
||||
</Primitive>
|
||||
<div :class="cn('space-y-2', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<script lang="ts" setup>
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { LabelProps } from "radix-vue";
|
||||
import type { LabelProps } from "reka-ui";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { Label } from "~/components/ui/label";
|
||||
import { useFormField } from "./useFormField";
|
||||
|
||||
const props = defineProps<LabelProps & { class?: HTMLAttributes["class"] }>();
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ export { default as FormItem } from "./FormItem.vue";
|
|||
export { default as FormLabel } from "./FormLabel.vue";
|
||||
export { default as FormMessage } from "./FormMessage.vue";
|
||||
export { FORM_ITEM_INJECTION_KEY } from "./injectionKeys";
|
||||
export { Field as FormField, Form } from "vee-validate";
|
||||
export { Form, Field as FormField } from "vee-validate";
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
type HoverCardRootEmits,
|
||||
type HoverCardRootProps,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
|
||||
const props = defineProps<HoverCardRootProps>();
|
||||
const emits = defineEmits<HoverCardRootEmits>();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
type HoverCardContentProps,
|
||||
HoverCardPortal,
|
||||
useForwardProps,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = withDefaults(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { HoverCardTrigger, type HoverCardTriggerProps } from "radix-vue";
|
||||
import { HoverCardTrigger, type HoverCardTriggerProps } from "reka-ui";
|
||||
|
||||
const props = defineProps<HoverCardTriggerProps>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,5 @@ const modelValue = useVModel(props, "modelValue", emits, {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<input v-model="modelValue"
|
||||
:class="cn('flex h-10 w-full rounded border !border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus:ring-0 focus:ring-offset-0 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-50', props.class)">
|
||||
<input v-model="modelValue" :class="cn('flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', props.class)">
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Label, type LabelProps } from "radix-vue";
|
||||
import { Label, type LabelProps } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<LabelProps & { class?: HTMLAttributes["class"] }>();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { PopoverRootEmits, PopoverRootProps } from "radix-vue";
|
||||
import { PopoverRoot, useForwardPropsEmits } from "radix-vue";
|
||||
import type { PopoverRootEmits, PopoverRootProps } from "reka-ui";
|
||||
import { PopoverRoot, useForwardPropsEmits } from "reka-ui";
|
||||
|
||||
const props = defineProps<PopoverRootProps>();
|
||||
const emits = defineEmits<PopoverRootEmits>();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
type PopoverContentProps,
|
||||
PopoverPortal,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
defineOptions({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { PopoverTrigger, type PopoverTriggerProps } from "radix-vue";
|
||||
import { PopoverTrigger, type PopoverTriggerProps } from "reka-ui";
|
||||
|
||||
const props = defineProps<PopoverTriggerProps>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { SelectRootEmits, SelectRootProps } from "radix-vue";
|
||||
import { SelectRoot, useForwardPropsEmits } from "radix-vue";
|
||||
import type { SelectRootEmits, SelectRootProps } from "reka-ui";
|
||||
import { SelectRoot, useForwardPropsEmits } from "reka-ui";
|
||||
|
||||
const props = defineProps<SelectRootProps>();
|
||||
const emits = defineEmits<SelectRootEmits>();
|
||||
|
|
@ -9,7 +9,7 @@ const forwarded = useForwardPropsEmits(props, emits);
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<SelectRoot v-bind="forwarded">
|
||||
<slot />
|
||||
</SelectRoot>
|
||||
<SelectRoot v-bind="forwarded">
|
||||
<slot />
|
||||
</SelectRoot>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
SelectPortal,
|
||||
SelectViewport,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
import { SelectScrollDownButton, SelectScrollUpButton } from ".";
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|||
"
|
||||
>
|
||||
<SelectScrollUpButton />
|
||||
<SelectViewport :class="cn('p-1', position === 'popper' && 'h-[--radix-select-trigger-height] w-full min-w-[--radix-select-trigger-width]')">
|
||||
<SelectViewport :class="cn('p-1', position === 'popper' && 'h-[--reka-select-trigger-height] w-full min-w-[--reka-select-trigger-width]')">
|
||||
<slot />
|
||||
</SelectViewport>
|
||||
<SelectScrollDownButton />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { SelectGroup, type SelectGroupProps } from "radix-vue";
|
||||
import { SelectGroup, type SelectGroupProps } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
type SelectItemProps,
|
||||
SelectItemText,
|
||||
useForwardProps,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
@ -24,23 +24,25 @@ const forwardedProps = useForwardProps(delegatedProps);
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<SelectItem
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn(
|
||||
'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-10 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<span class="absolute left-3 flex size-3.5 items-center justify-center">
|
||||
<SelectItemIndicator>
|
||||
<Check class="size-4" />
|
||||
</SelectItemIndicator>
|
||||
</span>
|
||||
<SelectItem
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
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',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<span
|
||||
class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"
|
||||
>
|
||||
<SelectItemIndicator>
|
||||
<Check class="h-4 w-4" />
|
||||
</SelectItemIndicator>
|
||||
</span>
|
||||
|
||||
<SelectItemText class="w-full">
|
||||
<slot />
|
||||
</SelectItemText>
|
||||
</SelectItem>
|
||||
<SelectItemText class="w-full">
|
||||
<slot />
|
||||
</SelectItemText>
|
||||
</SelectItem>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { SelectItemText, type SelectItemTextProps } from "radix-vue";
|
||||
import { SelectItemText, type SelectItemTextProps } from "reka-ui";
|
||||
|
||||
const props = defineProps<SelectItemTextProps>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { SelectLabel, type SelectLabelProps } from "radix-vue";
|
||||
import { SelectLabel, type SelectLabelProps } from "reka-ui";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
SelectScrollDownButton,
|
||||
type SelectScrollDownButtonProps,
|
||||
useForwardProps,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
@ -24,7 +24,7 @@ const forwardedProps = useForwardProps(delegatedProps);
|
|||
<template>
|
||||
<SelectScrollDownButton v-bind="forwardedProps" :class="cn('flex cursor-default items-center justify-center py-1', props.class)">
|
||||
<slot>
|
||||
<ChevronDown class="size-4" />
|
||||
<ChevronDown class="h-4 w-4" />
|
||||
</slot>
|
||||
</SelectScrollDownButton>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
SelectScrollUpButton,
|
||||
type SelectScrollUpButtonProps,
|
||||
useForwardProps,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
@ -24,7 +24,7 @@ const forwardedProps = useForwardProps(delegatedProps);
|
|||
<template>
|
||||
<SelectScrollUpButton v-bind="forwardedProps" :class="cn('flex cursor-default items-center justify-center py-1', props.class)">
|
||||
<slot>
|
||||
<ChevronUp class="size-4" />
|
||||
<ChevronUp class="h-4 w-4" />
|
||||
</slot>
|
||||
</SelectScrollUpButton>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { SelectSeparator, type SelectSeparatorProps } from "radix-vue";
|
||||
import { SelectSeparator, type SelectSeparatorProps } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
|
|||
|
|
@ -6,11 +6,15 @@ import {
|
|||
SelectTrigger,
|
||||
type SelectTriggerProps,
|
||||
useForwardProps,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
SelectTriggerProps & { class?: HTMLAttributes["class"] }
|
||||
SelectTriggerProps & {
|
||||
class?: HTMLAttributes["class"];
|
||||
disableDefaultClasses?: boolean;
|
||||
disableSelectIcon?: boolean;
|
||||
}
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
|
|
@ -23,16 +27,19 @@ const forwardedProps = useForwardProps(delegatedProps);
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<SelectTrigger
|
||||
v-bind="forwardedProps"
|
||||
:class="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 data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:truncate text-start',
|
||||
props.class,
|
||||
)"
|
||||
>
|
||||
<slot />
|
||||
<SelectIcon as-child>
|
||||
<ChevronDown class="size-4 opacity-50 shrink-0" />
|
||||
</SelectIcon>
|
||||
</SelectTrigger>
|
||||
<SelectTrigger
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn(
|
||||
!$props.disableDefaultClasses &&
|
||||
'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:truncate text-start',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
<SelectIcon as-child v-if="!$props.disableSelectIcon">
|
||||
<ChevronDown class="w-4 h-4 opacity-50 shrink-0" />
|
||||
</SelectIcon>
|
||||
</SelectTrigger>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { SelectValue, type SelectValueProps } from "radix-vue";
|
||||
import { SelectValue, type SelectValueProps } from "reka-ui";
|
||||
|
||||
const props = defineProps<SelectValueProps>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Separator, type SeparatorProps } from "radix-vue";
|
||||
import { Separator, type SeparatorProps } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
type DialogRootEmits,
|
||||
type DialogRootProps,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
|
||||
const props = defineProps<DialogRootProps>();
|
||||
const emits = defineEmits<DialogRootEmits>();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { DialogClose, type DialogCloseProps } from "radix-vue";
|
||||
import { DialogClose, type DialogCloseProps } from "reka-ui";
|
||||
|
||||
const props = defineProps<DialogCloseProps>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
DialogOverlay,
|
||||
DialogPortal,
|
||||
useForwardPropsEmits,
|
||||
} from "radix-vue";
|
||||
} from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
import { type SheetVariants, sheetVariants } from ".";
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|||
<template>
|
||||
<DialogPortal>
|
||||
<DialogOverlay
|
||||
class="fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
|
||||
class="fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
|
||||
/>
|
||||
<DialogContent
|
||||
:class="cn(sheetVariants({ side }), props.class)"
|
||||
|
|
@ -49,7 +49,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|||
<DialogClose
|
||||
class="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary"
|
||||
>
|
||||
<X class="size-4 text-muted-foreground" />
|
||||
<X class="w-4 h-4 text-muted-foreground" />
|
||||
</DialogClose>
|
||||
</DialogContent>
|
||||
</DialogPortal>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { DialogDescription, type DialogDescriptionProps } from "radix-vue";
|
||||
import { DialogDescription, type DialogDescriptionProps } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { DialogTitle, type DialogTitleProps } from "radix-vue";
|
||||
import { DialogTitle, type DialogTitleProps } from "reka-ui";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { DialogTrigger, type DialogTriggerProps } from "radix-vue";
|
||||
import { DialogTrigger, type DialogTriggerProps } from "reka-ui";
|
||||
|
||||
const props = defineProps<DialogTriggerProps>();
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,30 +1,100 @@
|
|||
<script setup lang="ts">
|
||||
import { Sheet, SheetContent } from "@/components/ui/sheet";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import type { SidebarProps } from ".";
|
||||
import { SIDEBAR_WIDTH_MOBILE, useSidebar } from "./utils";
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
side?: "left" | "right";
|
||||
variant?: "sidebar" | "floating" | "inset";
|
||||
collapsible?: "offcanvas" | "icon" | "none";
|
||||
class?: HTMLAttributes["class"];
|
||||
}>(),
|
||||
{
|
||||
side: "left",
|
||||
variant: "sidebar",
|
||||
collapsible: "offcanvas",
|
||||
},
|
||||
);
|
||||
const props = withDefaults(defineProps<SidebarProps>(), {
|
||||
side: "left",
|
||||
variant: "sidebar",
|
||||
collapsible: "offcanvas",
|
||||
});
|
||||
|
||||
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<aside
|
||||
:class="cn('flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground p-1', props.class)"
|
||||
v-bind="$attrs" data-component="sidebar">
|
||||
<div
|
||||
v-if="collapsible === 'none'"
|
||||
:class="
|
||||
cn(
|
||||
'flex h-dvh w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<slot />
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<Sheet
|
||||
v-else-if="isMobile"
|
||||
:open="openMobile"
|
||||
v-bind="$attrs"
|
||||
@update:open="setOpenMobile"
|
||||
>
|
||||
<SheetContent
|
||||
data-sidebar="sidebar"
|
||||
data-mobile="true"
|
||||
:side="side"
|
||||
class="w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
|
||||
:style="{
|
||||
'--sidebar-width': SIDEBAR_WIDTH_MOBILE,
|
||||
}"
|
||||
>
|
||||
<div class="flex h-full w-full flex-col">
|
||||
<slot />
|
||||
</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
|
||||
<div
|
||||
v-else
|
||||
class="group peer hidden md:block"
|
||||
:data-state="state"
|
||||
:data-collapsible="state === 'collapsed' ? collapsible : ''"
|
||||
:data-variant="variant"
|
||||
:data-side="side"
|
||||
>
|
||||
<!-- This is what handles the sidebar gap on desktop -->
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'duration-200 relative h-svh w-[--sidebar-width] bg-transparent transition-[width] ease-linear',
|
||||
'group-data-[collapsible=offcanvas]:w-0',
|
||||
'group-data-[side=right]:rotate-180',
|
||||
variant === 'floating' || variant === 'inset'
|
||||
? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'
|
||||
: 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]'
|
||||
)
|
||||
"
|
||||
/>
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'duration-200 fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] ease-linear md:flex',
|
||||
side === 'left'
|
||||
? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'
|
||||
: 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',
|
||||
// Adjust the padding for floating and inset variants.
|
||||
variant === 'floating' || variant === 'inset'
|
||||
? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'
|
||||
: 'group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<div
|
||||
data-sidebar="sidebar"
|
||||
class="flex h-full w-full flex-col text-sidebar-foreground bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { PrimitiveProps } from "radix-vue";
|
||||
import { Primitive } from "radix-vue";
|
||||
import type { PrimitiveProps } from "reka-ui";
|
||||
import { Primitive } from "reka-ui";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
@ -18,7 +18,6 @@ const props = defineProps<
|
|||
:as-child="asChild"
|
||||
:class="cn(
|
||||
'absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
|
||||
// Increases the hit area of the button on mobile.
|
||||
'after:absolute after:-inset-2 after:md:hidden',
|
||||
'group-data-[collapsible=icon]:hidden',
|
||||
props.class,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { PrimitiveProps } from "radix-vue";
|
||||
import { Primitive } from "radix-vue";
|
||||
import type { PrimitiveProps } from "reka-ui";
|
||||
import { Primitive } from "reka-ui";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import Input from "~/components/ui/input/Input.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes["class"];
|
||||
|
|
|
|||
|
|
@ -1,30 +1,22 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { SettingIds } from "~/settings";
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes["class"];
|
||||
}>();
|
||||
|
||||
const bgSetting = useSetting(SettingIds.BackgroundURL);
|
||||
const bgImage = computed(() =>
|
||||
bgSetting.value.value && URL.canParse(bgSetting.value.value as string)
|
||||
? bgSetting.value.value
|
||||
: "/images/banner.webp",
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main :class="cn(
|
||||
'relative flex min-h-svh max-w-full flex-1 flex-col bg-background',
|
||||
'peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:overflow-hidden md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow bg-cover bg-center bg-no-repeat',
|
||||
props.class,
|
||||
)" :style="{
|
||||
backgroundImage: `url('${bgImage}')`,
|
||||
}">
|
||||
<!-- Overlay for the background image -->
|
||||
<div class="absolute -z-10 inset-0 bg-black/20" />
|
||||
<main
|
||||
:class="
|
||||
cn(
|
||||
'relative flex min-h-svh flex-1 flex-col bg-background',
|
||||
'peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</main>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Primitive, type PrimitiveProps } from "radix-vue";
|
||||
import { Primitive, type PrimitiveProps } from "reka-ui";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
|
||||
const props = withDefaults(
|
||||
|
|
@ -21,7 +21,6 @@ const props = withDefaults(
|
|||
data-sidebar="menu-action"
|
||||
:class="cn(
|
||||
'absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',
|
||||
// Increases the hit area of the button on mobile.
|
||||
'after:absolute after:-inset-2 after:md:hidden',
|
||||
'peer-data-[size=sm]/menu-button:top-1',
|
||||
'peer-data-[size=default]/menu-button:top-1.5',
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
<script setup lang="ts">
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { type Component, computed } from "vue";
|
||||
import Tooltip from "~/components/ui/tooltip/Tooltip.vue";
|
||||
import TooltipContent from "~/components/ui/tooltip/TooltipContent.vue";
|
||||
import TooltipTrigger from "~/components/ui/tooltip/TooltipTrigger.vue";
|
||||
import SidebarMenuButtonChild, {
|
||||
type SidebarMenuButtonProps,
|
||||
} from "./SidebarMenuButtonChild.vue";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Primitive, type PrimitiveProps } from "radix-vue";
|
||||
import { Primitive, type PrimitiveProps } from "reka-ui";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { type SidebarMenuButtonVariants, sidebarMenuButtonVariants } from ".";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { type HTMLAttributes, computed } from "vue";
|
||||
import Skeleton from "~/components/ui/skeleton/Skeleton.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
showIcon?: boolean;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { PrimitiveProps } from "radix-vue";
|
||||
import { Primitive } from "radix-vue";
|
||||
import type { PrimitiveProps } from "reka-ui";
|
||||
import { Primitive } from "reka-ui";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
|
||||
const props = withDefaults(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useEventListener, useMediaQuery, useVModel } from "@vueuse/core";
|
||||
import { TooltipProvider } from "radix-vue";
|
||||
import { TooltipProvider } from "reka-ui";
|
||||
import { type HTMLAttributes, type Ref, computed, ref } from "vue";
|
||||
import {
|
||||
SIDEBAR_COOKIE_MAX_AGE,
|
||||
|
|
@ -86,7 +86,8 @@ provideSidebarContext({
|
|||
'--sidebar-width': SIDEBAR_WIDTH,
|
||||
'--sidebar-width-icon': SIDEBAR_WIDTH_ICON,
|
||||
}"
|
||||
:class="cn('group/sidebar-wrapper flex h-svh overflow-hidden w-full text-sidebar-foreground has-[[data-variant=inset]]:bg-sidebar', props.class)"
|
||||
:class="cn('group/sidebar-wrapper flex min-h-svh w-full has-[[data-variant=inset]]:bg-sidebar', props.class)"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import Separator from "~/components/ui/separator/Separator.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes["class"];
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { PanelLeft } from "lucide-vue-next";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import Button from "~/components/ui/button/Button.vue";
|
||||
import { useSidebar } from "./utils";
|
||||
|
||||
const props = defineProps<{
|
||||
|
|
@ -17,7 +17,7 @@ const { toggleSidebar } = useSidebar();
|
|||
data-sidebar="trigger"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
:class="cn('size-7', props.class)"
|
||||
:class="cn('h-7 w-7', props.class)"
|
||||
@click="toggleSidebar"
|
||||
>
|
||||
<PanelLeft />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,12 @@
|
|||
import { type VariantProps, cva } from "class-variance-authority";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
|
||||
export interface SidebarProps {
|
||||
side?: "left" | "right";
|
||||
variant?: "sidebar" | "floating" | "inset";
|
||||
collapsible?: "offcanvas" | "icon" | "none";
|
||||
class?: HTMLAttributes["class"];
|
||||
}
|
||||
|
||||
export { default as Sidebar } from "./Sidebar.vue";
|
||||
export { default as SidebarContent } from "./SidebarContent.vue";
|
||||
|
|
@ -37,9 +45,9 @@ export const sidebarMenuButtonVariants = cva(
|
|||
"bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
|
||||
},
|
||||
size: {
|
||||
default: "h-8 text-sm",
|
||||
sm: "h-7 text-xs",
|
||||
lg: "h-12 text-sm group-data-[collapsible=icon]:!p-0",
|
||||
default: "text-sm",
|
||||
sm: "text-xs",
|
||||
lg: "text-sm group-data-[collapsible=icon]:!p-0",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue