feature/project-redesign #28

Merged
ilia merged 88 commits from feature/project-redesign into main 2026-03-02 19:46:39 +00:00
112 changed files with 0 additions and 3020 deletions
Showing only changes of commit e7225a6009 - Show all commits

View File

@@ -1,55 +0,0 @@
<script lang="ts" module>
import {
type VariantProps,
tv,
} from 'tailwind-variants';
export const badgeVariants = tv({
base:
'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] [&>svg]:pointer-events-none [&>svg]:size-3',
variants: {
variant: {
default: 'bg-primary text-primary-foreground [a&]:hover:bg-primary/90 border-transparent',
secondary: 'bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90 border-transparent',
destructive:
'bg-destructive [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/70 border-transparent text-white',
outline: 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
},
},
defaultVariants: {
variant: 'default',
},
});
export type BadgeVariant = VariantProps<typeof badgeVariants>['variant'];
</script>
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAnchorAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
href,
class: className,
variant = 'default',
children,
...restProps
}: WithElementRef<HTMLAnchorAttributes> & {
variant?: BadgeVariant;
} = $props();
</script>
<svelte:element
this={href ? 'a' : 'span'}
bind:this={ref}
data-slot="badge"
{href}
class={cn(badgeVariants({ variant }), className)}
{...restProps}
>
{@render children?.()}
</svelte:element>

View File

@@ -1,5 +0,0 @@
export { default as Badge } from './badge.svelte';
export {
type BadgeVariant,
badgeVariants,
} from './badge.svelte';

View File

@@ -1,20 +0,0 @@
<script lang="ts">
import { Separator } from '$shared/shadcn/ui/separator/index.js';
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import type { ComponentProps } from 'svelte';
let {
ref = $bindable(null),
class: className,
orientation = 'vertical',
...restProps
}: ComponentProps<typeof Separator> = $props();
</script>
<Separator
bind:ref
data-slot="button-group-separator"
{orientation}
class={cn('bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto', className)}
{...restProps}
/>

View File

@@ -1,33 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
child,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
child?: Snippet<[{ props: Record<string, unknown> }]>;
} = $props();
const mergedProps = $derived({
...restProps,
class: cn(
"bg-muted flex items-center gap-2 rounded-md border px-4 text-sm font-medium shadow-xs [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
className,
),
});
</script>
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div bind:this={ref} {...mergedProps}>
{@render mergedProps.children?.()}
</div>
{/if}

View File

@@ -1,53 +0,0 @@
<script lang="ts" module>
import {
type VariantProps,
tv,
} from 'tailwind-variants';
export const buttonGroupVariants = tv({
base:
"flex w-fit items-stretch has-[>[data-slot=button-group]]:gap-2 [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-e-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
variants: {
orientation: {
horizontal:
'[&>*:not(:first-child)]:rounded-s-none [&>*:not(:first-child)]:border-s-0 [&>*:not(:last-child)]:rounded-e-none',
vertical:
'flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none',
},
},
defaultVariants: {
orientation: 'horizontal',
},
});
export type ButtonGroupOrientation = VariantProps<typeof buttonGroupVariants>['orientation'];
</script>
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
orientation = 'horizontal',
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
orientation?: ButtonGroupOrientation;
} = $props();
</script>
<div
bind:this={ref}
role="group"
data-slot="button-group"
data-orientation={orientation}
class={cn(buttonGroupVariants({ orientation }), className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,13 +0,0 @@
import Separator from './button-group-separator.svelte';
import Text from './button-group-text.svelte';
import Root from './button-group.svelte';
export {
Root,
//
Root as ButtonGroup,
Separator,
Separator as ButtonGroupSeparator,
Text,
Text as ButtonGroupText,
};

View File

@@ -1,94 +0,0 @@
<script lang="ts" module>
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type {
HTMLAnchorAttributes,
HTMLButtonAttributes,
} from 'svelte/elements';
import {
type VariantProps,
tv,
} from 'tailwind-variants';
export const buttonVariants = tv({
base:
"focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90 shadow-xs',
destructive:
'bg-destructive hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 text-white shadow-xs',
outline:
'bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 border shadow-xs',
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 shadow-xs',
ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
sm: 'h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5',
lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
icon: 'size-9',
'icon-sm': 'size-8',
'icon-lg': 'size-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
});
export type ButtonVariant = VariantProps<typeof buttonVariants>['variant'];
export type ButtonSize = VariantProps<typeof buttonVariants>['size'];
export type ButtonProps =
& WithElementRef<HTMLButtonAttributes>
& WithElementRef<HTMLAnchorAttributes>
& {
variant?: ButtonVariant;
size?: ButtonSize;
};
</script>
<script lang="ts">
let {
class: className,
variant = 'default',
size = 'default',
ref = $bindable(null),
href = undefined,
type = 'button',
disabled,
children,
...restProps
}: ButtonProps = $props();
</script>
{#if href}
<a
bind:this={ref}
data-slot="button"
class={cn(buttonVariants({ variant, size }), className)}
href={disabled ? undefined : href}
aria-disabled={disabled}
role={disabled ? 'link' : undefined}
tabindex={disabled ? -1 : undefined}
{...restProps}
>
{@render children?.()}
</a>
{:else}
<button
bind:this={ref}
data-slot="button"
class={cn(buttonVariants({ variant, size }), className)}
{type}
{disabled}
{...restProps}
>
{@render children?.()}
</button>
{/if}

View File

@@ -1,17 +0,0 @@
import Root, {
type ButtonProps,
type ButtonSize,
type ButtonVariant,
buttonVariants,
} from './button.svelte';
export {
type ButtonProps,
type ButtonProps as Props,
type ButtonSize,
type ButtonVariant,
buttonVariants,
Root,
//
Root as Button,
};

View File

@@ -1,39 +0,0 @@
<script lang="ts">
import {
type WithoutChildrenOrChild,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import CheckIcon from '@lucide/svelte/icons/check';
import MinusIcon from '@lucide/svelte/icons/minus';
import { Checkbox as CheckboxPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
checked = $bindable(false),
indeterminate = $bindable(false),
class: className,
...restProps
}: WithoutChildrenOrChild<CheckboxPrimitive.RootProps> = $props();
</script>
<CheckboxPrimitive.Root
bind:ref
data-slot="checkbox"
class={cn(
'border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive peer flex size-4 shrink-0 items-center justify-center rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
bind:checked
bind:indeterminate
{...restProps}
>
{#snippet children({ checked, indeterminate })}
<div data-slot="checkbox-indicator" class="text-current transition-none">
{#if checked}
<CheckIcon class="size-3.5" />
{:else if indeterminate}
<MinusIcon class="size-3.5" />
{/if}
</div>
{/snippet}
</CheckboxPrimitive.Root>

View File

@@ -1,6 +0,0 @@
import Root from './checkbox.svelte';
export {
Root,
//
Root as Checkbox,
};

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Collapsible as CollapsiblePrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: CollapsiblePrimitive.ContentProps = $props();
</script>
<CollapsiblePrimitive.Content bind:ref data-slot="collapsible-content" {...restProps} />

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Collapsible as CollapsiblePrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: CollapsiblePrimitive.TriggerProps = $props();
</script>
<CollapsiblePrimitive.Trigger bind:ref data-slot="collapsible-trigger" {...restProps} />

View File

@@ -1,11 +0,0 @@
<script lang="ts">
import { Collapsible as CollapsiblePrimitive } from 'bits-ui';
let {
ref = $bindable(null),
open = $bindable(false),
...restProps
}: CollapsiblePrimitive.RootProps = $props();
</script>
<CollapsiblePrimitive.Root bind:ref bind:open data-slot="collapsible" {...restProps} />

View File

@@ -1,13 +0,0 @@
import Content from './collapsible-content.svelte';
import Trigger from './collapsible-trigger.svelte';
import Root from './collapsible.svelte';
export {
Content,
Content as CollapsibleContent,
Root,
//
Root as Collapsible,
Trigger,
Trigger as CollapsibleTrigger,
};

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: DialogPrimitive.CloseProps = $props();
</script>
<DialogPrimitive.Close bind:ref data-slot="dialog-close" {...restProps} />

View File

@@ -1,48 +0,0 @@
<script lang="ts">
import {
type WithoutChildrenOrChild,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import XIcon from '@lucide/svelte/icons/x';
import { Dialog as DialogPrimitive } from 'bits-ui';
import type { Snippet } from 'svelte';
import type { ComponentProps } from 'svelte';
import DialogPortal from './dialog-portal.svelte';
import * as Dialog from './index.js';
let {
ref = $bindable(null),
class: className,
portalProps,
children,
showCloseButton = true,
...restProps
}: WithoutChildrenOrChild<DialogPrimitive.ContentProps> & {
portalProps?: WithoutChildrenOrChild<ComponentProps<typeof DialogPortal>>;
children: Snippet;
showCloseButton?: boolean;
} = $props();
</script>
<DialogPortal {...portalProps}>
<Dialog.Overlay />
<DialogPrimitive.Content
bind:ref
data-slot="dialog-content"
class={cn(
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
className,
)}
{...restProps}
>
{@render children?.()}
{#if showCloseButton}
<DialogPrimitive.Close
class="ring-offset-background focus:ring-ring absolute end-4 top-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
>
<XIcon />
<span class="sr-only">Close</span>
</DialogPrimitive.Close>
{/if}
</DialogPrimitive.Content>
</DialogPortal>

View File

@@ -1,17 +0,0 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Dialog as DialogPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: DialogPrimitive.DescriptionProps = $props();
</script>
<DialogPrimitive.Description
bind:ref
data-slot="dialog-description"
class={cn('text-muted-foreground text-sm', className)}
{...restProps}
/>

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="dialog-footer"
class={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="dialog-header"
class={cn('flex flex-col gap-2 text-center sm:text-start', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,20 +0,0 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Dialog as DialogPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: DialogPrimitive.OverlayProps = $props();
</script>
<DialogPrimitive.Overlay
bind:ref
data-slot="dialog-overlay"
class={cn(
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
className,
)}
{...restProps}
/>

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from 'bits-ui';
let { ...restProps }: DialogPrimitive.PortalProps = $props();
</script>
<DialogPrimitive.Portal {...restProps} />

View File

@@ -1,17 +0,0 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Dialog as DialogPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: DialogPrimitive.TitleProps = $props();
</script>
<DialogPrimitive.Title
bind:ref
data-slot="dialog-title"
class={cn('text-lg leading-none font-semibold', className)}
{...restProps}
/>

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: DialogPrimitive.TriggerProps = $props();
</script>
<DialogPrimitive.Trigger bind:ref data-slot="dialog-trigger" {...restProps} />

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from 'bits-ui';
let { open = $bindable(false), ...restProps }: DialogPrimitive.RootProps = $props();
</script>
<DialogPrimitive.Root bind:open {...restProps} />

View File

@@ -1,34 +0,0 @@
import Close from './dialog-close.svelte';
import Content from './dialog-content.svelte';
import Description from './dialog-description.svelte';
import Footer from './dialog-footer.svelte';
import Header from './dialog-header.svelte';
import Overlay from './dialog-overlay.svelte';
import Portal from './dialog-portal.svelte';
import Title from './dialog-title.svelte';
import Trigger from './dialog-trigger.svelte';
import Root from './dialog.svelte';
export {
Close,
Close as DialogClose,
Content,
Content as DialogContent,
Description,
Description as DialogDescription,
Footer,
Footer as DialogFooter,
Header,
Header as DialogHeader,
Overlay,
Overlay as DialogOverlay,
Portal,
Portal as DialogPortal,
Root,
//
Root as Dialog,
Title,
Title as DialogTitle,
Trigger,
Trigger as DialogTrigger,
};

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
let { ref = $bindable(null), ...restProps }: DrawerPrimitive.CloseProps = $props();
</script>
<DrawerPrimitive.Close bind:ref data-slot="drawer-close" {...restProps} />

View File

@@ -1,39 +0,0 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import type { WithoutChildrenOrChild } from '$shared/shadcn/utils/shadcn-utils.js';
import type { ComponentProps } from 'svelte';
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
import DrawerOverlay from './drawer-overlay.svelte';
import DrawerPortal from './drawer-portal.svelte';
let {
ref = $bindable(null),
class: className,
portalProps,
children,
...restProps
}: DrawerPrimitive.ContentProps & {
portalProps?: WithoutChildrenOrChild<ComponentProps<typeof DrawerPortal>>;
} = $props();
</script>
<DrawerPortal {...portalProps}>
<DrawerOverlay />
<DrawerPrimitive.Content
bind:ref
data-slot="drawer-content"
class={cn(
'group/drawer-content bg-background fixed z-50 flex h-auto flex-col',
'data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b',
'data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t',
'data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:end-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-s data-[vaul-drawer-direction=right]:sm:max-w-sm',
'data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:start-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-e data-[vaul-drawer-direction=left]:sm:max-w-sm',
className,
)}
{...restProps}
>
<div class="bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block">
</div>
{@render children?.()}
</DrawerPrimitive.Content>
</DrawerPortal>

View File

@@ -1,17 +0,0 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
let {
ref = $bindable(null),
class: className,
...restProps
}: DrawerPrimitive.DescriptionProps = $props();
</script>
<DrawerPrimitive.Description
bind:ref
data-slot="drawer-description"
class={cn('text-muted-foreground text-sm', className)}
{...restProps}
/>

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="drawer-footer"
class={cn('mt-auto flex flex-col gap-2 p-4', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="drawer-header"
class={cn('flex flex-col gap-1.5 p-4', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,12 +0,0 @@
<script lang="ts">
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
let {
shouldScaleBackground = true,
open = $bindable(false),
activeSnapPoint = $bindable(null),
...restProps
}: DrawerPrimitive.RootProps = $props();
</script>
<DrawerPrimitive.NestedRoot {shouldScaleBackground} bind:open bind:activeSnapPoint {...restProps} />

View File

@@ -1,20 +0,0 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
let {
ref = $bindable(null),
class: className,
...restProps
}: DrawerPrimitive.OverlayProps = $props();
</script>
<DrawerPrimitive.Overlay
bind:ref
data-slot="drawer-overlay"
class={cn(
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
className,
)}
{...restProps}
/>

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
let { ...restProps }: DrawerPrimitive.PortalProps = $props();
</script>
<DrawerPrimitive.Portal {...restProps} />

View File

@@ -1,17 +0,0 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
let {
ref = $bindable(null),
class: className,
...restProps
}: DrawerPrimitive.TitleProps = $props();
</script>
<DrawerPrimitive.Title
bind:ref
data-slot="drawer-title"
class={cn('text-foreground font-semibold', className)}
{...restProps}
/>

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
let { ref = $bindable(null), ...restProps }: DrawerPrimitive.TriggerProps = $props();
</script>
<DrawerPrimitive.Trigger bind:ref data-slot="drawer-trigger" {...restProps} />

View File

@@ -1,12 +0,0 @@
<script lang="ts">
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
let {
shouldScaleBackground = true,
open = $bindable(false),
activeSnapPoint = $bindable(null),
...restProps
}: DrawerPrimitive.RootProps = $props();
</script>
<DrawerPrimitive.Root {shouldScaleBackground} bind:open bind:activeSnapPoint {...restProps} />

View File

@@ -1,37 +0,0 @@
import Close from './drawer-close.svelte';
import Content from './drawer-content.svelte';
import Description from './drawer-description.svelte';
import Footer from './drawer-footer.svelte';
import Header from './drawer-header.svelte';
import NestedRoot from './drawer-nested.svelte';
import Overlay from './drawer-overlay.svelte';
import Portal from './drawer-portal.svelte';
import Title from './drawer-title.svelte';
import Trigger from './drawer-trigger.svelte';
import Root from './drawer.svelte';
export {
Close,
Close as DrawerClose,
Content,
Content as DrawerContent,
Description,
Description as DrawerDescription,
Footer,
Footer as DrawerFooter,
Header,
Header as DrawerHeader,
NestedRoot,
NestedRoot as DrawerNestedRoot,
Overlay,
Overlay as DrawerOverlay,
Portal,
Portal as DrawerPortal,
Root,
//
Root as Drawer,
Title,
Title as DrawerTitle,
Trigger,
Trigger as DrawerTrigger,
};

View File

@@ -1,7 +0,0 @@
import Root from './input.svelte';
export {
Root,
//
Root as Input,
};

View File

@@ -1,58 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type {
HTMLInputAttributes,
HTMLInputTypeAttribute,
} from 'svelte/elements';
type InputType = Exclude<HTMLInputTypeAttribute, 'file'>;
type Props = WithElementRef<
& Omit<HTMLInputAttributes, 'type'>
& ({ type: 'file'; files?: FileList } | { type?: InputType; files?: undefined })
>;
let {
ref = $bindable(null),
value = $bindable(),
type,
files = $bindable(),
class: className,
'data-slot': dataSlot = 'input',
...restProps
}: Props = $props();
</script>
{#if type === 'file'}
<input
bind:this={ref}
data-slot={dataSlot}
class={cn(
'selection:bg-primary dark:bg-input/30 selection:text-primary-foreground border-input ring-offset-background placeholder:text-muted-foreground flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 pt-1.5 text-sm font-medium shadow-xs transition-[color,box-shadow] outline-none disabled:cursor-not-allowed disabled:opacity-50',
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
className,
)}
type="file"
bind:files
bind:value
{...restProps}
/>
{:else}
<input
bind:this={ref}
data-slot={dataSlot}
class={cn(
'border-input bg-background selection:bg-primary dark:bg-input/30 selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground flex h-9 w-full min-w-0 rounded-md border px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
className,
)}
{type}
bind:value
{...restProps}
/>
{/if}

View File

@@ -1,34 +0,0 @@
import Actions from './item-actions.svelte';
import Content from './item-content.svelte';
import Description from './item-description.svelte';
import Footer from './item-footer.svelte';
import Group from './item-group.svelte';
import Header from './item-header.svelte';
import Media from './item-media.svelte';
import Separator from './item-separator.svelte';
import Title from './item-title.svelte';
import Root from './item.svelte';
export {
Actions,
Actions as ItemActions,
Content,
Content as ItemContent,
Description,
Description as ItemDescription,
Footer,
Footer as ItemFooter,
Group,
Group as ItemGroup,
Header,
Header as ItemHeader,
Media,
Media as ItemMedia,
Root,
//
Root as Item,
Separator,
Separator as ItemSeparator,
Title,
Title as ItemTitle,
};

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="item-actions"
class={cn('flex items-center gap-2', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="item-content"
class={cn('flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,27 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLParagraphElement>> = $props();
</script>
<p
bind:this={ref}
data-slot="item-description"
class={cn(
'text-muted-foreground line-clamp-2 text-sm leading-normal font-normal text-balance',
'[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',
className,
)}
{...restProps}
>
{@render children?.()}
</p>

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="item-footer"
class={cn('flex basis-full items-center justify-between gap-2', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,24 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
role="list"
data-slot="item-group"
class={cn('group/item-group flex flex-col', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="item-header"
class={cn('flex basis-full items-center justify-between gap-2', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,49 +0,0 @@
<script lang="ts" module>
import {
type VariantProps,
tv,
} from 'tailwind-variants';
export const itemMediaVariants = tv({
base:
'flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:translate-y-0.5 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none',
variants: {
variant: {
default: 'bg-transparent',
icon: "bg-muted size-8 rounded-sm border [&_svg:not([class*='size-'])]:size-4",
image: 'size-10 overflow-hidden rounded-sm [&_img]:size-full [&_img]:object-cover',
},
},
defaultVariants: {
variant: 'default',
},
});
export type ItemMediaVariant = VariantProps<typeof itemMediaVariants>['variant'];
</script>
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
variant = 'default',
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & { variant?: ItemMediaVariant } = $props();
</script>
<div
bind:this={ref}
data-slot="item-media"
data-variant={variant}
class={cn(itemMediaVariants({ variant }), className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,19 +0,0 @@
<script lang="ts">
import { Separator } from '$shared/shadcn/ui/separator/index.js';
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import type { ComponentProps } from 'svelte';
let {
ref = $bindable(null),
class: className,
...restProps
}: ComponentProps<typeof Separator> = $props();
</script>
<Separator
bind:ref
data-slot="item-separator"
orientation="horizontal"
class={cn('my-0', className)}
{...restProps}
/>

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="item-title"
class={cn('flex w-fit items-center gap-2 text-sm leading-snug font-medium', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,67 +0,0 @@
<script lang="ts" module>
import {
type VariantProps,
tv,
} from 'tailwind-variants';
export const itemVariants = tv({
base:
'group/item [a]:hover:bg-accent/50 focus-visible:border-ring focus-visible:ring-ring/50 flex flex-wrap items-center rounded-md border border-transparent text-sm transition-colors duration-100 outline-none focus-visible:ring-[3px] [a]:transition-colors',
variants: {
variant: {
default: 'bg-transparent',
outline: 'border-border',
muted: 'bg-muted/50',
},
size: {
default: 'gap-4 p-4',
sm: 'gap-2.5 px-4 py-3',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
});
export type ItemSize = VariantProps<typeof itemVariants>['size'];
export type ItemVariant = VariantProps<typeof itemVariants>['variant'];
</script>
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
child,
variant,
size,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
child?: Snippet<[{ props: Record<string, unknown> }]>;
variant?: ItemVariant;
size?: ItemSize;
} = $props();
const mergedProps = $derived({
class: cn(itemVariants({ variant, size }), className),
'data-slot': 'item',
'data-variant': variant,
'data-size': size,
...restProps,
});
</script>
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div bind:this={ref} {...mergedProps}>
{@render mergedProps.children?.()}
</div>
{/if}

View File

@@ -1,7 +0,0 @@
import Root from './label.svelte';
export {
Root,
//
Root as Label,
};

View File

@@ -1,20 +0,0 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Label as LabelPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: LabelPrimitive.RootProps = $props();
</script>
<LabelPrimitive.Root
bind:ref
data-slot="label"
class={cn(
'flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50',
className,
)}
{...restProps}
/>

View File

@@ -1,10 +0,0 @@
import Scrollbar from './scroll-area-scrollbar.svelte';
import Root from './scroll-area.svelte';
export {
Root,
// ,
Root as ScrollArea,
Scrollbar,
Scrollbar as ScrollAreaScrollbar,
};

View File

@@ -1,34 +0,0 @@
<script lang="ts">
import {
type WithoutChild,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import { ScrollArea as ScrollAreaPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
orientation = 'vertical',
children,
...restProps
}: WithoutChild<ScrollAreaPrimitive.ScrollbarProps> = $props();
</script>
<ScrollAreaPrimitive.Scrollbar
bind:ref
data-slot="scroll-area-scrollbar"
{orientation}
class={cn(
'flex touch-none p-px transition-colors select-none',
orientation === 'vertical' && 'h-full w-2.5 border-s border-s-transparent',
orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent',
className,
)}
{...restProps}
>
{@render children?.()}
<ScrollAreaPrimitive.Thumb
data-slot="scroll-area-thumb"
class="bg-border relative flex-1 rounded-full"
/>
</ScrollAreaPrimitive.Scrollbar>

View File

@@ -1,46 +0,0 @@
<script lang="ts">
import {
type WithoutChild,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import { ScrollArea as ScrollAreaPrimitive } from 'bits-ui';
import { Scrollbar } from './index.js';
let {
ref = $bindable(null),
viewportRef = $bindable(null),
class: className,
orientation = 'vertical',
scrollbarXClasses = '',
scrollbarYClasses = '',
children,
...restProps
}: WithoutChild<ScrollAreaPrimitive.RootProps> & {
orientation?: 'vertical' | 'horizontal' | 'both' | undefined;
scrollbarXClasses?: string | undefined;
scrollbarYClasses?: string | undefined;
viewportRef?: HTMLElement | null;
} = $props();
</script>
<ScrollAreaPrimitive.Root
bind:ref
data-slot="scroll-area"
class={cn('relative', className)}
{...restProps}
>
<ScrollAreaPrimitive.Viewport
bind:ref={viewportRef}
data-slot="scroll-area-viewport"
class="ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1"
>
{@render children?.()}
</ScrollAreaPrimitive.Viewport>
{#if orientation === 'vertical' || orientation === 'both'}
<Scrollbar orientation="vertical" class={scrollbarYClasses} />
{/if}
{#if orientation === 'horizontal' || orientation === 'both'}
<Scrollbar orientation="horizontal" class={scrollbarXClasses} />
{/if}
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>

View File

@@ -1,37 +0,0 @@
import Content from './select-content.svelte';
import GroupHeading from './select-group-heading.svelte';
import Group from './select-group.svelte';
import Item from './select-item.svelte';
import Label from './select-label.svelte';
import Portal from './select-portal.svelte';
import ScrollDownButton from './select-scroll-down-button.svelte';
import ScrollUpButton from './select-scroll-up-button.svelte';
import Separator from './select-separator.svelte';
import Trigger from './select-trigger.svelte';
import Root from './select.svelte';
export {
Content,
Content as SelectContent,
Group,
Group as SelectGroup,
GroupHeading,
GroupHeading as SelectGroupHeading,
Item,
Item as SelectItem,
Label,
Label as SelectLabel,
Portal,
Portal as SelectPortal,
Root,
//
Root as Select,
ScrollDownButton,
ScrollDownButton as SelectScrollDownButton,
ScrollUpButton,
ScrollUpButton as SelectScrollUpButton,
Separator,
Separator as SelectSeparator,
Trigger,
Trigger as SelectTrigger,
};

View File

@@ -1,48 +0,0 @@
<script lang="ts">
import {
type WithoutChild,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { WithoutChildrenOrChild } from '$shared/shadcn/utils/shadcn-utils.js';
import { Select as SelectPrimitive } from 'bits-ui';
import type { ComponentProps } from 'svelte';
import SelectPortal from './select-portal.svelte';
import SelectScrollDownButton from './select-scroll-down-button.svelte';
import SelectScrollUpButton from './select-scroll-up-button.svelte';
let {
ref = $bindable(null),
class: className,
sideOffset = 4,
portalProps,
children,
preventScroll = true,
...restProps
}: WithoutChild<SelectPrimitive.ContentProps> & {
portalProps?: WithoutChildrenOrChild<ComponentProps<typeof SelectPortal>>;
} = $props();
</script>
<SelectPortal {...portalProps}>
<SelectPrimitive.Content
bind:ref
{sideOffset}
{preventScroll}
data-slot="select-content"
class={cn(
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--bits-select-content-available-height) min-w-[8rem] origin-(--bits-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
className,
)}
{...restProps}
>
<SelectScrollUpButton />
<SelectPrimitive.Viewport
class={cn(
'h-(--bits-select-anchor-height) w-full min-w-(--bits-select-anchor-width) scroll-my-1 p-1',
)}
>
{@render children?.()}
</SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPortal>

View File

@@ -1,21 +0,0 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Select as SelectPrimitive } from 'bits-ui';
import type { ComponentProps } from 'svelte';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: ComponentProps<typeof SelectPrimitive.GroupHeading> = $props();
</script>
<SelectPrimitive.GroupHeading
bind:ref
data-slot="select-group-heading"
class={cn('text-muted-foreground px-2 py-1.5 text-xs', className)}
{...restProps}
>
{@render children?.()}
</SelectPrimitive.GroupHeading>

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Select as SelectPrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: SelectPrimitive.GroupProps = $props();
</script>
<SelectPrimitive.Group bind:ref data-slot="select-group" {...restProps} />

View File

@@ -1,41 +0,0 @@
<script lang="ts">
import {
type WithoutChild,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import CheckIcon from '@lucide/svelte/icons/check';
import { Select as SelectPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
value,
label,
children: childrenProp,
...restProps
}: WithoutChild<SelectPrimitive.ItemProps> = $props();
</script>
<SelectPrimitive.Item
bind:ref
{value}
data-slot="select-item"
class={cn(
"data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 ps-2 pe-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
className,
)}
{...restProps}
>
{#snippet children({ selected, highlighted })}
<span class="absolute end-2 flex size-3.5 items-center justify-center">
{#if selected}
<CheckIcon class="size-4" />
{/if}
</span>
{#if childrenProp}
{@render childrenProp({ selected, highlighted })}
{:else}
{label || value}
{/if}
{/snippet}
</SelectPrimitive.Item>

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {} = $props();
</script>
<div
bind:this={ref}
data-slot="select-label"
class={cn('text-muted-foreground px-2 py-1.5 text-xs', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Select as SelectPrimitive } from 'bits-ui';
let { ...restProps }: SelectPrimitive.PortalProps = $props();
</script>
<SelectPrimitive.Portal {...restProps} />

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithoutChildrenOrChild,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
import { Select as SelectPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: WithoutChildrenOrChild<SelectPrimitive.ScrollDownButtonProps> = $props();
</script>
<SelectPrimitive.ScrollDownButton
bind:ref
data-slot="select-scroll-down-button"
class={cn('flex cursor-default items-center justify-center py-1', className)}
{...restProps}
>
<ChevronDownIcon class="size-4" />
</SelectPrimitive.ScrollDownButton>

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithoutChildrenOrChild,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import ChevronUpIcon from '@lucide/svelte/icons/chevron-up';
import { Select as SelectPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: WithoutChildrenOrChild<SelectPrimitive.ScrollUpButtonProps> = $props();
</script>
<SelectPrimitive.ScrollUpButton
bind:ref
data-slot="select-scroll-up-button"
class={cn('flex cursor-default items-center justify-center py-1', className)}
{...restProps}
>
<ChevronUpIcon class="size-4" />
</SelectPrimitive.ScrollUpButton>

View File

@@ -1,18 +0,0 @@
<script lang="ts">
import { Separator } from '$shared/shadcn/ui/separator/index.js';
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import type { Separator as SeparatorPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: SeparatorPrimitive.RootProps = $props();
</script>
<Separator
bind:ref
data-slot="select-separator"
class={cn('bg-border pointer-events-none -mx-1 my-1 h-px', className)}
{...restProps}
/>

View File

@@ -1,32 +0,0 @@
<script lang="ts">
import {
type WithoutChild,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
import { Select as SelectPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
children,
size = 'default',
...restProps
}: WithoutChild<SelectPrimitive.TriggerProps> & {
size?: 'sm' | 'default';
} = $props();
</script>
<SelectPrimitive.Trigger
bind:ref
data-slot="select-trigger"
data-size={size}
class={cn(
"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none select-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
{...restProps}
>
{@render children?.()}
<ChevronDownIcon class="size-4 opacity-50" />
</SelectPrimitive.Trigger>

View File

@@ -1,11 +0,0 @@
<script lang="ts">
import { Select as SelectPrimitive } from 'bits-ui';
let {
open = $bindable(false),
value = $bindable(),
...restProps
}: SelectPrimitive.RootProps = $props();
</script>
<SelectPrimitive.Root bind:open bind:value={value as never} {...restProps} />

View File

@@ -1,7 +0,0 @@
import Root from './separator.svelte';
export {
Root,
//
Root as Separator,
};

View File

@@ -1,21 +0,0 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Separator as SeparatorPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
'data-slot': dataSlot = 'separator',
...restProps
}: SeparatorPrimitive.RootProps = $props();
</script>
<SeparatorPrimitive.Root
bind:ref
data-slot={dataSlot}
class={cn(
'bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px',
className,
)}
{...restProps}
/>

View File

@@ -1,34 +0,0 @@
import Close from './sheet-close.svelte';
import Content from './sheet-content.svelte';
import Description from './sheet-description.svelte';
import Footer from './sheet-footer.svelte';
import Header from './sheet-header.svelte';
import Overlay from './sheet-overlay.svelte';
import Portal from './sheet-portal.svelte';
import Title from './sheet-title.svelte';
import Trigger from './sheet-trigger.svelte';
import Root from './sheet.svelte';
export {
Close,
Close as SheetClose,
Content,
Content as SheetContent,
Description,
Description as SheetDescription,
Footer,
Footer as SheetFooter,
Header,
Header as SheetHeader,
Overlay,
Overlay as SheetOverlay,
Portal,
Portal as SheetPortal,
Root,
//
Root as Sheet,
Title,
Title as SheetTitle,
Trigger,
Trigger as SheetTrigger,
};

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Dialog as SheetPrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: SheetPrimitive.CloseProps = $props();
</script>
<SheetPrimitive.Close bind:ref data-slot="sheet-close" {...restProps} />

View File

@@ -1,70 +0,0 @@
<script lang="ts" module>
import {
type VariantProps,
tv,
} from 'tailwind-variants';
export const sheetVariants = tv({
base:
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
variants: {
side: {
top: 'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b',
bottom:
'data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t',
left:
'data-[state=closed]:slide-out-to-start data-[state=open]:slide-in-from-start inset-y-0 start-0 h-full w-3/4 border-e sm:max-w-sm',
right:
'data-[state=closed]:slide-out-to-end data-[state=open]:slide-in-from-end inset-y-0 end-0 h-full w-3/4 border-s sm:max-w-sm',
},
},
defaultVariants: {
side: 'right',
},
});
export type Side = VariantProps<typeof sheetVariants>['side'];
</script>
<script lang="ts">
import {
type WithoutChildrenOrChild,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import XIcon from '@lucide/svelte/icons/x';
import { Dialog as SheetPrimitive } from 'bits-ui';
import type { Snippet } from 'svelte';
import type { ComponentProps } from 'svelte';
import SheetOverlay from './sheet-overlay.svelte';
import SheetPortal from './sheet-portal.svelte';
let {
ref = $bindable(null),
class: className,
side = 'right',
portalProps,
children,
...restProps
}: WithoutChildrenOrChild<SheetPrimitive.ContentProps> & {
portalProps?: WithoutChildrenOrChild<ComponentProps<typeof SheetPortal>>;
side?: Side;
children: Snippet;
} = $props();
</script>
<SheetPortal {...portalProps}>
<SheetOverlay />
<SheetPrimitive.Content
bind:ref
data-slot="sheet-content"
class={cn(sheetVariants({ side }), className)}
{...restProps}
>
{@render children?.()}
<SheetPrimitive.Close
class="ring-offset-background focus-visible:ring-ring absolute end-4 top-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:pointer-events-none"
>
<XIcon class="size-4" />
<span class="sr-only">Close</span>
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPortal>

View File

@@ -1,17 +0,0 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Dialog as SheetPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: SheetPrimitive.DescriptionProps = $props();
</script>
<SheetPrimitive.Description
bind:ref
data-slot="sheet-description"
class={cn('text-muted-foreground text-sm', className)}
{...restProps}
/>

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="sheet-footer"
class={cn('mt-auto flex flex-col gap-2 p-4', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,23 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="sheet-header"
class={cn('flex flex-col gap-1.5 p-4', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,20 +0,0 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Dialog as SheetPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: SheetPrimitive.OverlayProps = $props();
</script>
<SheetPrimitive.Overlay
bind:ref
data-slot="sheet-overlay"
class={cn(
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
className,
)}
{...restProps}
/>

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Dialog as SheetPrimitive } from 'bits-ui';
let { ...restProps }: SheetPrimitive.PortalProps = $props();
</script>
<SheetPrimitive.Portal {...restProps} />

View File

@@ -1,17 +0,0 @@
<script lang="ts">
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import { Dialog as SheetPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
...restProps
}: SheetPrimitive.TitleProps = $props();
</script>
<SheetPrimitive.Title
bind:ref
data-slot="sheet-title"
class={cn('text-foreground font-semibold', className)}
{...restProps}
/>

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Dialog as SheetPrimitive } from 'bits-ui';
let { ref = $bindable(null), ...restProps }: SheetPrimitive.TriggerProps = $props();
</script>
<SheetPrimitive.Trigger bind:ref data-slot="sheet-trigger" {...restProps} />

View File

@@ -1,7 +0,0 @@
<script lang="ts">
import { Dialog as SheetPrimitive } from 'bits-ui';
let { open = $bindable(false), ...restProps }: SheetPrimitive.RootProps = $props();
</script>
<SheetPrimitive.Root bind:open {...restProps} />

View File

@@ -1,6 +0,0 @@
export const SIDEBAR_COOKIE_NAME = 'sidebar:state';
export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
export const SIDEBAR_WIDTH = '16rem';
export const SIDEBAR_WIDTH_MOBILE = '18rem';
export const SIDEBAR_WIDTH_ICON = '3rem';
export const SIDEBAR_KEYBOARD_SHORTCUT = 'b';

View File

@@ -1,84 +0,0 @@
import { IsMobile } from '$shared/shadcn/hooks/is-mobile.svelte.js';
import {
getContext,
setContext,
} from 'svelte';
import { SIDEBAR_KEYBOARD_SHORTCUT } from './constants.js';
type Getter<T> = () => T;
export type SidebarStateProps = {
/**
* A getter function that returns the current open state of the sidebar.
* We use a getter function here to support `bind:open` on the `Sidebar.Provider`
* component.
*/
open: Getter<boolean>;
/**
* A function that sets the open state of the sidebar. To support `bind:open`, we need
* a source of truth for changing the open state to ensure it will be synced throughout
* the sub-components and any `bind:` references.
*/
setOpen: (open: boolean) => void;
};
class SidebarState {
readonly props: SidebarStateProps;
open = $derived.by(() => this.props.open());
openMobile = $state(false);
setOpen: SidebarStateProps['setOpen'];
#isMobile: IsMobile;
state = $derived.by(() => (this.open ? 'expanded' : 'collapsed'));
constructor(props: SidebarStateProps) {
this.setOpen = props.setOpen;
this.#isMobile = new IsMobile();
this.props = props;
}
// Convenience getter for checking if the sidebar is mobile
// without this, we would need to use `sidebar.isMobile.current` everywhere
get isMobile() {
return this.#isMobile.current;
}
// Event handler to apply to the `<svelte:window>`
handleShortcutKeydown = (e: KeyboardEvent) => {
if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
this.toggle();
}
};
setOpenMobile = (value: boolean) => {
this.openMobile = value;
};
toggle = () => {
return this.#isMobile.current
? (this.openMobile = !this.openMobile)
: this.setOpen(!this.open);
};
}
const SYMBOL_KEY = 'scn-sidebar';
/**
* Instantiates a new `SidebarState` instance and sets it in the context.
*
* @param props The constructor props for the `SidebarState` class.
* @returns The `SidebarState` instance.
*/
export function setSidebar(props: SidebarStateProps): SidebarState {
return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props));
}
/**
* Retrieves the `SidebarState` instance from the context. This is a class instance,
* so you cannot destructure it.
* @returns The `SidebarState` instance.
*/
export function useSidebar(): SidebarState {
return getContext(Symbol.for(SYMBOL_KEY));
}

View File

@@ -1,75 +0,0 @@
import { useSidebar } from './context.svelte.js';
import Content from './sidebar-content.svelte';
import Footer from './sidebar-footer.svelte';
import GroupAction from './sidebar-group-action.svelte';
import GroupContent from './sidebar-group-content.svelte';
import GroupLabel from './sidebar-group-label.svelte';
import Group from './sidebar-group.svelte';
import Header from './sidebar-header.svelte';
import Input from './sidebar-input.svelte';
import Inset from './sidebar-inset.svelte';
import MenuAction from './sidebar-menu-action.svelte';
import MenuBadge from './sidebar-menu-badge.svelte';
import MenuButton from './sidebar-menu-button.svelte';
import MenuItem from './sidebar-menu-item.svelte';
import MenuSkeleton from './sidebar-menu-skeleton.svelte';
import MenuSubButton from './sidebar-menu-sub-button.svelte';
import MenuSubItem from './sidebar-menu-sub-item.svelte';
import MenuSub from './sidebar-menu-sub.svelte';
import Menu from './sidebar-menu.svelte';
import Provider from './sidebar-provider.svelte';
import Rail from './sidebar-rail.svelte';
import Separator from './sidebar-separator.svelte';
import Trigger from './sidebar-trigger.svelte';
import Root from './sidebar.svelte';
export {
Content,
Content as SidebarContent,
Footer,
Footer as SidebarFooter,
Group,
Group as SidebarGroup,
GroupAction,
GroupAction as SidebarGroupAction,
GroupContent,
GroupContent as SidebarGroupContent,
GroupLabel,
GroupLabel as SidebarGroupLabel,
Header,
Header as SidebarHeader,
Input,
Input as SidebarInput,
Inset,
Inset as SidebarInset,
Menu,
Menu as SidebarMenu,
MenuAction,
MenuAction as SidebarMenuAction,
MenuBadge,
MenuBadge as SidebarMenuBadge,
MenuButton,
MenuButton as SidebarMenuButton,
MenuItem,
MenuItem as SidebarMenuItem,
MenuSkeleton,
MenuSkeleton as SidebarMenuSkeleton,
MenuSub,
MenuSub as SidebarMenuSub,
MenuSubButton,
MenuSubButton as SidebarMenuSubButton,
MenuSubItem,
MenuSubItem as SidebarMenuSubItem,
Provider,
Provider as SidebarProvider,
Rail,
Rail as SidebarRail,
Root,
//
Root as Sidebar,
Separator,
Separator as SidebarSeparator,
Trigger,
Trigger as SidebarTrigger,
useSidebar,
};

View File

@@ -1,27 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="sidebar-content"
data-sidebar="content"
class={cn(
'flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden',
className,
)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,24 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="sidebar-footer"
data-sidebar="footer"
class={cn('flex flex-col gap-2 p-2', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,39 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { Snippet } from 'svelte';
import type { HTMLButtonAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
child,
...restProps
}: WithElementRef<HTMLButtonAttributes> & {
child?: Snippet<[{ props: Record<string, unknown> }]>;
} = $props();
const mergedProps = $derived({
class: cn(
'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute end-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
// Increases the hit area of the button on mobile.
'after:absolute after:-inset-2 md:after:hidden',
'group-data-[collapsible=icon]:hidden',
className,
),
'data-slot': 'sidebar-group-action',
'data-sidebar': 'group-action',
...restProps,
});
</script>
{#if child}
{@render child({ props: mergedProps })}
{:else}
<button bind:this={ref} {...mergedProps}>
{@render children?.()}
</button>
{/if}

View File

@@ -1,24 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="sidebar-group-content"
data-sidebar="group-content"
class={cn('w-full text-sm', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,37 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
children,
child,
class: className,
...restProps
}: WithElementRef<HTMLAttributes<HTMLElement>> & {
child?: Snippet<[{ props: Record<string, unknown> }]>;
} = $props();
const mergedProps = $derived({
class: cn(
'text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',
className,
),
'data-slot': 'sidebar-group-label',
'data-sidebar': 'group-label',
...restProps,
});
</script>
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div bind:this={ref} {...mergedProps}>
{@render children?.()}
</div>
{/if}

View File

@@ -1,24 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="sidebar-group"
data-sidebar="group"
class={cn('relative flex w-full min-w-0 flex-col p-2', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,24 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="sidebar-header"
data-sidebar="header"
class={cn('flex flex-col gap-2 p-2', className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,21 +0,0 @@
<script lang="ts">
import { Input } from '$shared/shadcn/ui/input/index.js';
import { cn } from '$shared/shadcn/utils/shadcn-utils.js';
import type { ComponentProps } from 'svelte';
let {
ref = $bindable(null),
value = $bindable(''),
class: className,
...restProps
}: ComponentProps<typeof Input> = $props();
</script>
<Input
bind:ref
bind:value
data-slot="sidebar-input"
data-sidebar="input"
class={cn('bg-background h-8 w-full shadow-none', className)}
{...restProps}
/>

View File

@@ -1,27 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
</script>
<main
bind:this={ref}
data-slot="sidebar-inset"
class={cn(
'bg-background relative flex w-full flex-1 flex-col',
'md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ms-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ms-2',
className,
)}
{...restProps}
>
{@render children?.()}
</main>

View File

@@ -1,46 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { Snippet } from 'svelte';
import type { HTMLButtonAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
showOnHover = false,
children,
child,
...restProps
}: WithElementRef<HTMLButtonAttributes> & {
child?: Snippet<[{ props: Record<string, unknown> }]>;
showOnHover?: boolean;
} = $props();
const mergedProps = $derived({
class: cn(
'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute end-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
// Increases the hit area of the button on mobile.
'after:absolute after:-inset-2 md:after:hidden',
'peer-data-[size=sm]/menu-button:top-1',
'peer-data-[size=default]/menu-button:top-1.5',
'peer-data-[size=lg]/menu-button:top-2.5',
'group-data-[collapsible=icon]:hidden',
showOnHover
&& 'peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0',
className,
),
'data-slot': 'sidebar-menu-action',
'data-sidebar': 'menu-action',
...restProps,
});
</script>
{#if child}
{@render child({ props: mergedProps })}
{:else}
<button bind:this={ref} {...mergedProps}>
{@render children?.()}
</button>
{/if}

View File

@@ -1,32 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="sidebar-menu-badge"
data-sidebar="menu-badge"
class={cn(
'text-sidebar-foreground pointer-events-none absolute end-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none',
'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',
'peer-data-[size=sm]/menu-button:top-1',
'peer-data-[size=default]/menu-button:top-1.5',
'peer-data-[size=lg]/menu-button:top-2.5',
'group-data-[collapsible=icon]:hidden',
className,
)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,114 +0,0 @@
<script lang="ts" module>
import {
type VariantProps,
tv,
} from 'tailwind-variants';
export const sidebarMenuButtonVariants = tv({
base:
'peer/menu-button ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-start text-sm outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pe-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:font-medium [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
variants: {
variant: {
default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
outline:
'bg-background hover:bg-sidebar-accent hover:text-sidebar-accent-foreground shadow-[0_0_0_1px_var(--sidebar-border)] hover:shadow-[0_0_0_1px_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!',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
});
export type SidebarMenuButtonVariant = VariantProps<
typeof sidebarMenuButtonVariants
>['variant'];
export type SidebarMenuButtonSize = VariantProps<typeof sidebarMenuButtonVariants>['size'];
</script>
<script lang="ts">
import * as Tooltip from '$shared/shadcn/ui/tooltip/index.js';
import {
type WithElementRef,
type WithoutChildrenOrChild,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import { mergeProps } from 'bits-ui';
import type {
ComponentProps,
Snippet,
} from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
import { useSidebar } from './context.svelte.js';
let {
ref = $bindable(null),
class: className,
children,
child,
variant = 'default',
size = 'default',
isActive = false,
tooltipContent,
tooltipContentProps,
...restProps
}: WithElementRef<HTMLAttributes<HTMLButtonElement>, HTMLButtonElement> & {
isActive?: boolean;
variant?: SidebarMenuButtonVariant;
size?: SidebarMenuButtonSize;
tooltipContent?: Snippet | string;
tooltipContentProps?: WithoutChildrenOrChild<ComponentProps<typeof Tooltip.Content>>;
child?: Snippet<[{ props: Record<string, unknown> }]>;
} = $props();
const sidebar = useSidebar();
const buttonProps = $derived({
class: cn(sidebarMenuButtonVariants({ variant, size }), className),
'data-slot': 'sidebar-menu-button',
'data-sidebar': 'menu-button',
'data-size': size,
'data-active': isActive,
...restProps,
});
</script>
{#snippet Button({ props }: { props?: Record<string, unknown> })}
{@const mergedProps = mergeProps(buttonProps, props)}
{#if child}
{@render child({ props: mergedProps })}
{:else}
<button bind:this={ref} {...mergedProps}>
{@render children?.()}
</button>
{/if}
{/snippet}
{#if !tooltipContent}
{@render Button({})}
{:else}
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
{@render Button({ props })}
{/snippet}
</Tooltip.Trigger>
<Tooltip.Content
side="right"
align="center"
hidden={sidebar.state !== 'collapsed' || sidebar.isMobile}
{...tooltipContentProps}
>
{#if typeof tooltipContent === 'string'}
{tooltipContent}
{:else if tooltipContent}
{@render tooltipContent()}
{/if}
</Tooltip.Content>
</Tooltip.Root>
{/if}

View File

@@ -1,24 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLLIElement>, HTMLLIElement> = $props();
</script>
<li
bind:this={ref}
data-slot="sidebar-menu-item"
data-sidebar="menu-item"
class={cn('group/menu-item relative', className)}
{...restProps}
>
{@render children?.()}
</li>

View File

@@ -1,39 +0,0 @@
<script lang="ts">
import { Skeleton } from '$shared/shadcn/ui/skeleton/index.js';
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
showIcon = false,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLElement>> & {
showIcon?: boolean;
} = $props();
// Random width between 50% and 90%
const width = `${Math.floor(Math.random() * 40) + 50}%`;
</script>
<div
bind:this={ref}
data-slot="sidebar-menu-skeleton"
data-sidebar="menu-skeleton"
class={cn('flex h-8 items-center gap-2 rounded-md px-2', className)}
{...restProps}
>
{#if showIcon}
<Skeleton class="size-4 rounded-md" data-sidebar="menu-skeleton-icon" />
{/if}
<Skeleton
class="h-4 max-w-(--skeleton-width) flex-1"
data-sidebar="menu-skeleton-text"
style="--skeleton-width: {width};"
/>
{@render children?.()}
</div>

View File

@@ -1,46 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { Snippet } from 'svelte';
import type { HTMLAnchorAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
children,
child,
class: className,
size = 'md',
isActive = false,
...restProps
}: WithElementRef<HTMLAnchorAttributes> & {
child?: Snippet<[{ props: Record<string, unknown> }]>;
size?: 'sm' | 'md';
isActive?: boolean;
} = $props();
const mergedProps = $derived({
class: cn(
'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',
size === 'sm' && 'text-xs',
size === 'md' && 'text-sm',
'group-data-[collapsible=icon]:hidden',
className,
),
'data-slot': 'sidebar-menu-sub-button',
'data-sidebar': 'menu-sub-button',
'data-size': size,
'data-active': isActive,
...restProps,
});
</script>
{#if child}
{@render child({ props: mergedProps })}
{:else}
<a bind:this={ref} {...mergedProps}>
{@render children?.()}
</a>
{/if}

View File

@@ -1,24 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
children,
class: className,
...restProps
}: WithElementRef<HTMLAttributes<HTMLLIElement>> = $props();
</script>
<li
bind:this={ref}
data-slot="sidebar-menu-sub-item"
data-sidebar="menu-sub-item"
class={cn('group/menu-sub-item relative', className)}
{...restProps}
>
{@render children?.()}
</li>

View File

@@ -1,28 +0,0 @@
<script lang="ts">
import {
type WithElementRef,
cn,
} from '$shared/shadcn/utils/shadcn-utils.js';
import type { HTMLAttributes } from 'svelte/elements';
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLUListElement>> = $props();
</script>
<ul
bind:this={ref}
data-slot="sidebar-menu-sub"
data-sidebar="menu-sub"
class={cn(
'border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-s px-2.5 py-0.5',
'group-data-[collapsible=icon]:hidden',
className,
)}
{...restProps}
>
{@render children?.()}
</ul>

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