update shadcn components

This commit is contained in:
David Senoner 2025-05-19 15:00:16 +02:00
parent 3f6ac523f8
commit 2ea45109d1
65 changed files with 268 additions and 171 deletions

View file

@ -1,6 +1,6 @@
<script>
import { Accordion as AccordionPrimitive } from "bits-ui";
import ChevronDown from "lucide-svelte/icons/chevron-down";
import ChevronDown from "@lucide/svelte/icons/chevron-down";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, level = 3, children, ...restProps } = $props();

View file

@ -3,10 +3,10 @@
import AlertDialogOverlay from "./alert-dialog-overlay.svelte";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, ...restProps } = $props();
let { ref = $bindable(null), class: className, portalProps, ...restProps } = $props();
</script>
<AlertDialogPrimitive.Portal>
<AlertDialogPrimitive.Portal {...portalProps}>
<AlertDialogOverlay />
<AlertDialogPrimitive.Content
bind:ref

View file

@ -7,6 +7,6 @@
<AvatarPrimitive.Fallback
bind:ref
class={cn("flex h-full w-full items-center justify-center rounded-full bg-muted", className)}
class={cn("flex size-full items-center justify-center bg-muted", className)}
{...restProps}
/>

View file

@ -5,8 +5,4 @@
let { ref = $bindable(null), class: className, ...restProps } = $props();
</script>
<AvatarPrimitive.Image
bind:ref
class={cn("aspect-square h-full w-full", className)}
{...restProps}
/>
<AvatarPrimitive.Image bind:ref class={cn("aspect-square size-full", className)} {...restProps} />

View file

@ -36,7 +36,7 @@
this={href ? "a" : "span"}
bind:this={ref}
{href}
class={cn(badgeVariants({ variant, className }))}
class={cn(badgeVariants({ variant }), className)}
{...restProps}
>
{@render children?.()}

View file

@ -1,5 +1,5 @@
<script>
import Ellipsis from "lucide-svelte/icons/ellipsis";
import Ellipsis from "@lucide/svelte/icons/ellipsis";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, ...restProps } = $props();

View file

@ -1,5 +1,5 @@
<script>
import ChevronRight from "lucide-svelte/icons/chevron-right";
import ChevronRight from "@lucide/svelte/icons/chevron-right";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, children, ...restProps } = $props();

View file

@ -1,6 +1,6 @@
<script>
import { Calendar as CalendarPrimitive } from "bits-ui";
import ChevronRight from "lucide-svelte/icons/chevron-right";
import ChevronRight from "@lucide/svelte/icons/chevron-right";
import { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js";

View file

@ -1,6 +1,6 @@
<script>
import { Calendar as CalendarPrimitive } from "bits-ui";
import ChevronLeft from "lucide-svelte/icons/chevron-left";
import ChevronLeft from "@lucide/svelte/icons/chevron-left";
import { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js";

View file

@ -32,11 +32,11 @@ get along, so we shut typescript up by casting `value` to `never`.
<Calendar.NextButton />
</Calendar.Header>
<Calendar.Months>
{#each months as month}
{#each months as month (month)}
<Calendar.Grid>
<Calendar.GridHead>
<Calendar.GridRow class="flex">
{#each weekdays as weekday}
{#each weekdays as weekday (weekday)}
<Calendar.HeadCell>
{weekday.slice(0, 2)}
</Calendar.HeadCell>
@ -44,9 +44,9 @@ get along, so we shut typescript up by casting `value` to `never`.
</Calendar.GridRow>
</Calendar.GridHead>
<Calendar.GridBody>
{#each month.weeks as weekDates}
{#each month.weeks as weekDates (weekDates)}
<Calendar.GridRow class="mt-2 w-full">
{#each weekDates as date}
{#each weekDates as date (date)}
<Calendar.Cell {date} month={month.value}>
<Calendar.Day />
</Calendar.Cell>

View file

@ -8,7 +8,7 @@
role="heading"
aria-level={level}
bind:this={ref}
class={cn("text-lg font-semibold leading-none tracking-tight", className)}
class={cn("text-2xl font-semibold leading-none tracking-tight", className)}
{...restProps}
>
{@render children?.()}

View file

@ -1,5 +1,5 @@
<script>
import ArrowRight from "lucide-svelte/icons/arrow-right";
import ArrowRight from "@lucide/svelte/icons/arrow-right";
import { getEmblaContext } from "./context.js";
import { cn } from "$lib/utils.js";
import { Button } from "$lib/components/ui/button/index.js";

View file

@ -1,5 +1,5 @@
<script>
import ArrowLeft from "lucide-svelte/icons/arrow-left";
import ArrowLeft from "@lucide/svelte/icons/arrow-left";
import { getEmblaContext } from "./context.js";
import { cn } from "$lib/utils.js";
import { Button } from "$lib/components/ui/button/index.js";

View file

@ -36,7 +36,7 @@
function scrollNext() {
carouselState.api?.scrollNext();
}
function scrollTo(index, jump) {
function scrollTo(index, jump?) {
carouselState.api?.scrollTo(index, jump);
}

View file

@ -1,5 +1,4 @@
import { getContext, hasContext, setContext } from "svelte";
////
const EMBLA_CAROUSEL_CONTEXT = Symbol("EMBLA_CAROUSEL_CONTEXT");

View file

@ -1,12 +1,13 @@
<script>
import { Checkbox as CheckboxPrimitive } from "bits-ui";
import Check from "lucide-svelte/icons/check";
import Minus from "lucide-svelte/icons/minus";
import Check from "@lucide/svelte/icons/check";
import Minus from "@lucide/svelte/icons/minus";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
checked = $bindable(false),
indeterminate = $bindable(false),
class: className,
...restProps
} = $props();
@ -19,11 +20,12 @@
className,
)}
bind:checked
bind:indeterminate
{...restProps}
>
{#snippet children({ checked })}
{#snippet children({ checked, indeterminate })}
<div class="flex size-4 items-center justify-center text-current">
{#if checked === "indeterminate"}
{#if indeterminate}
<Minus class="size-3.5" />
{:else}
<Check class={cn("size-3.5", !checked && "text-transparent")} />

View file

@ -6,13 +6,14 @@
open = $bindable(false),
ref = $bindable(null),
value = $bindable(""),
portalProps,
children,
...restProps
} = $props();
</script>
<Dialog.Root bind:open {...restProps}>
<Dialog.Content class="overflow-hidden p-0 shadow-lg">
<Dialog.Content class="overflow-hidden p-0 shadow-lg" {portalProps}>
<Command
class="[&_[data-command-group]:not([hidden])_~[data-command-group]]:pt-0 [&_[data-command-group]]:px-2 [&_[data-command-input-wrapper]_svg]:h-5 [&_[data-command-input-wrapper]_svg]:w-5 [&_[data-command-input]]:h-12 [&_[data-command-item]]:px-2 [&_[data-command-item]]:py-3 [&_[data-command-item]_svg]:h-5 [&_[data-command-item]_svg]:w-5"
{...restProps}

View file

@ -1,13 +1,21 @@
<script>
import { Command as CommandPrimitive } from "bits-ui";
import { Command as CommandPrimitive, useId } from "bits-ui";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, children, heading, ...restProps } = $props();
let {
ref = $bindable(null),
class: className,
children,
heading,
value,
...restProps
} = $props();
</script>
<CommandPrimitive.Group
class={cn("overflow-hidden p-1 text-foreground", className)}
bind:ref
value={value ?? heading ?? `----${useId()}`}
{...restProps}
>
{#if heading}

View file

@ -1,6 +1,6 @@
<script>
import { Command as CommandPrimitive } from "bits-ui";
import Search from "lucide-svelte/icons/search";
import Search from "@lucide/svelte/icons/search";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, value = $bindable(""), ...restProps } = $props();
@ -10,7 +10,7 @@
<Search class="mr-2 size-4 shrink-0 opacity-50" />
<CommandPrimitive.Input
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",
"flex h-11 w-full rounded-md bg-transparent py-3 text-base outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className,
)}
bind:ref

View file

@ -7,7 +7,7 @@
<CommandPrimitive.LinkItem
class={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
className,
)}
bind:ref

View file

@ -1,12 +1,12 @@
<script>
import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
import Check from "lucide-svelte/icons/check";
import Minus from "lucide-svelte/icons/minus";
import Check from "@lucide/svelte/icons/check";
import Minus from "@lucide/svelte/icons/minus";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
checked = $bindable(false),
indeterminate = $bindable(false),
class: className,
children: childrenProp,
...restProps
@ -16,20 +16,21 @@
<ContextMenuPrimitive.CheckboxItem
bind:ref
bind:checked
bind:indeterminate
class={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50",
className,
)}
{...restProps}
>
{#snippet children({ checked })}
{#snippet children({ checked, indeterminate })}
<span class="absolute left-2 flex size-3.5 items-center justify-center">
{#if checked === "indeterminate"}
{#if indeterminate}
<Minus class="size-3.5" />
{:else}
<Check class={cn("size-3.5", !checked && "text-transparent")} />
{/if}
</span>
{@render childrenProp?.({ checked })}
{@render childrenProp?.()}
{/snippet}
</ContextMenuPrimitive.CheckboxItem>

View file

@ -2,14 +2,16 @@
import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, ...restProps } = $props();
let { ref = $bindable(null), portalProps, class: className, ...restProps } = $props();
</script>
<ContextMenuPrimitive.Content
bind:ref
class={cn(
"z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none",
className,
)}
{...restProps}
/>
<ContextMenuPrimitive.Portal {...portalProps}>
<ContextMenuPrimitive.Content
bind:ref
class={cn(
"z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none",
className,
)}
{...restProps}
/>
</ContextMenuPrimitive.Portal>

View file

@ -1,6 +1,6 @@
<script>
import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
import Circle from "lucide-svelte/icons/circle";
import Circle from "@lucide/svelte/icons/circle";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, children: childrenProp, ...restProps } = $props();

View file

@ -1,6 +1,6 @@
<script>
import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
import ChevronRight from "lucide-svelte/icons/chevron-right";
import ChevronRight from "@lucide/svelte/icons/chevron-right";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, inset, children, ...restProps } = $props();

View file

@ -1,3 +1,24 @@
function _optionalChain(ops) {
let lastAccessLHS = undefined;
let value = ops[0];
let i = 1;
while (i < ops.length) {
const op = ops[i];
const fn = ops[i + 1];
i += 2;
if ((op === "optionalAccess" || op === "optionalCall") && value == null) {
return undefined;
}
if (op === "access" || op === "optionalAccess") {
lastAccessLHS = value;
value = fn(value);
} else if (op === "call" || op === "optionalCall") {
value = fn((...args) => value.call(lastAccessLHS, ...args));
lastAccessLHS = undefined;
}
}
return value;
}
import { createTable } from "@tanstack/table-core";
/**
@ -52,7 +73,13 @@ export function createSvelteTable(options) {
if (updater instanceof Function) state = updater(state);
else state = mergeObjects(state, updater);
options.onStateChange?.(updater);
_optionalChain([
options,
"access",
(_) => _.onStateChange,
"optionalCall",
(_2) => _2(updater),
]);
},
});
});

View file

@ -1,8 +1,8 @@
<script>
import {
RenderComponentConfig,
RenderSnippetConfig,
} from "$lib/components/ui/data-table/render-helpers.js";
<script
lang="ts"
generics="TData, TValue, TContext extends HeaderContext<TData, TValue> | CellContext<TData, TValue>"
>
import { RenderComponentConfig, RenderSnippetConfig } from "./render-helpers.js";
let { content, context } = $props();
</script>

View file

@ -15,8 +15,6 @@
* ```
*/
export class RenderComponentConfig {
component;
props;
constructor(component, props = {}) {
this.component = component;
this.props = props;
@ -39,8 +37,6 @@ export class RenderComponentConfig {
* ```
*/
export class RenderSnippetConfig {
snippet;
params;
constructor(snippet, params) {
this.snippet = snippet;
this.params = params;

View file

@ -1,13 +1,13 @@
<script>
import { Dialog as DialogPrimitive } from "bits-ui";
import X from "lucide-svelte/icons/x";
import X from "@lucide/svelte/icons/x";
import * as Dialog from "./index.js";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, children, ...restProps } = $props();
let { ref = $bindable(null), class: className, portalProps, children, ...restProps } = $props();
</script>
<Dialog.Portal>
<Dialog.Portal {...portalProps}>
<Dialog.Overlay />
<DialogPrimitive.Content
bind:ref

View file

@ -3,10 +3,10 @@
import DrawerOverlay from "./drawer-overlay.svelte";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, children, ...restProps } = $props();
let { ref = $bindable(null), class: className, portalProps, children, ...restProps } = $props();
</script>
<DrawerPrimitive.Portal>
<DrawerPrimitive.Portal {...portalProps}>
<DrawerOverlay />
<DrawerPrimitive.Content
bind:ref

View file

@ -1,12 +1,12 @@
<script>
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import Check from "lucide-svelte/icons/check";
import Minus from "lucide-svelte/icons/minus";
import Check from "@lucide/svelte/icons/check";
import Minus from "@lucide/svelte/icons/minus";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
checked = $bindable(false),
indeterminate = $bindable(false),
class: className,
children: childrenProp,
...restProps
@ -16,20 +16,21 @@
<DropdownMenuPrimitive.CheckboxItem
bind:ref
bind:checked
bind:indeterminate
class={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50",
className,
)}
{...restProps}
>
{#snippet children({ checked })}
{#snippet children({ checked, indeterminate })}
<span class="absolute left-2 flex size-3.5 items-center justify-center">
{#if checked === "indeterminate"}
{#if indeterminate}
<Minus class="size-4" />
{:else}
<Check class={cn("size-4", !checked && "text-transparent")} />
{/if}
</span>
{@render childrenProp?.({ checked })}
{@render childrenProp?.()}
{/snippet}
</DropdownMenuPrimitive.CheckboxItem>

View file

@ -2,15 +2,23 @@
import { cn } from "$lib/utils.js";
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
let { ref = $bindable(null), sideOffset = 4, class: className, ...restProps } = $props();
let {
ref = $bindable(null),
sideOffset = 4,
portalProps,
class: className,
...restProps
} = $props();
</script>
<DropdownMenuPrimitive.Content
bind:ref
{sideOffset}
class={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...restProps}
/>
<DropdownMenuPrimitive.Portal {...portalProps}>
<DropdownMenuPrimitive.Content
bind:ref
{sideOffset}
class={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...restProps}
/>
</DropdownMenuPrimitive.Portal>

View file

@ -1,6 +1,5 @@
<script>
import { cn } from "$lib/utils.js";
import {} from "bits-ui";
let { ref = $bindable(null), class: className, inset, children, ...restProps } = $props();
</script>

View file

@ -1,6 +1,6 @@
<script>
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import Circle from "lucide-svelte/icons/circle";
import Circle from "@lucide/svelte/icons/circle";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, children: childrenProp, ...restProps } = $props();

View file

@ -1,5 +1,4 @@
<script>
import {} from "bits-ui";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, children, ...restProps } = $props();

View file

@ -1,6 +1,6 @@
<script>
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import ChevronRight from "lucide-svelte/icons/chevron-right";
import ChevronRight from "@lucide/svelte/icons/chevron-right";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, inset, children, ...restProps } = $props();

View file

@ -20,7 +20,7 @@
{#if childrenProp}
{@render childrenProp({ errors, errorProps })}
{:else}
{#each errors as error}
{#each errors as error (error)}
<div {...errorProps} class={cn(errorClasses)}>{error}</div>
{/each}
{/if}

View file

@ -7,17 +7,20 @@
class: className,
align = "center",
sideOffset = 4,
portalProps,
...restProps
} = $props();
</script>
<HoverCardPrimitive.Content
bind:ref
{align}
{sideOffset}
class={cn(
"z-50 mt-3 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none",
className,
)}
{...restProps}
/>
<HoverCardPrimitive.Portal {...portalProps}>
<HoverCardPrimitive.Content
bind:ref
{align}
{sideOffset}
class={cn(
"z-50 mt-3 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none",
className,
)}
{...restProps}
/>
</HoverCardPrimitive.Portal>

View file

@ -0,0 +1,15 @@
import { Collapsible as CollapsiblePrimitive } from "bits-ui";
const Root = CollapsiblePrimitive.Root;
const Trigger = CollapsiblePrimitive.Trigger;
const Content = CollapsiblePrimitive.Content;
export {
//
Root as Collapsible,
Content as CollapsibleContent,
Trigger as CollapsibleTrigger,
Content,
Root,
Trigger,
};

View file

@ -1,5 +1,5 @@
<script>
import Dot from "lucide-svelte/icons/dot";
import Dot from "@lucide/svelte/icons/dot";
let { ref = $bindable(null), children, ...restProps } = $props();
</script>

View file

@ -1,13 +1,13 @@
<script>
import { Menubar as MenubarPrimitive } from "bits-ui";
import Check from "lucide-svelte/icons/check";
import Minus from "lucide-svelte/icons/minus";
import Check from "@lucide/svelte/icons/check";
import Minus from "@lucide/svelte/icons/minus";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
checked = $bindable(false),
indeterminate = $bindable(false),
children: childrenProp,
...restProps
} = $props();
@ -16,20 +16,21 @@
<MenubarPrimitive.CheckboxItem
bind:ref
bind:checked
bind:indeterminate
class={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50",
className,
)}
{...restProps}
>
{#snippet children({ checked })}
{#snippet children({ checked, indeterminate })}
<span class="absolute left-2 flex size-3.5 items-center justify-center">
{#if checked === "indeterminate"}
{#if indeterminate}
<Minus class="size-4" />
{:else}
<Check class={cn("size-4", !checked && "text-transparent")} />
{/if}
</span>
{@render childrenProp?.({ checked })}
{@render childrenProp?.()}
{/snippet}
</MenubarPrimitive.CheckboxItem>

View file

@ -9,19 +9,22 @@
alignOffset = -4,
align = "start",
side = "bottom",
portalProps,
...restProps
} = $props();
</script>
<MenubarPrimitive.Content
bind:ref
{sideOffset}
{align}
{alignOffset}
{side}
class={cn(
"z-50 min-w-[12rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none",
className,
)}
{...restProps}
/>
<MenubarPrimitive.Portal {...portalProps}>
<MenubarPrimitive.Content
bind:ref
{sideOffset}
{align}
{alignOffset}
{side}
class={cn(
"z-50 min-w-[12rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none",
className,
)}
{...restProps}
/>
</MenubarPrimitive.Portal>

View file

@ -1,6 +1,6 @@
<script>
import { Menubar as MenubarPrimitive } from "bits-ui";
import Circle from "lucide-svelte/icons/circle";
import Circle from "@lucide/svelte/icons/circle";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, children: childrenProp, ...restProps } = $props();

View file

@ -1,6 +1,6 @@
<script>
import { Menubar as MenubarPrimitive } from "bits-ui";
import ChevronRight from "lucide-svelte/icons/chevron-right";
import ChevronRight from "@lucide/svelte/icons/chevron-right";
import { cn } from "$lib/utils.js";
let {

View file

@ -1,5 +1,5 @@
<script>
import Ellipsis from "lucide-svelte/icons/ellipsis";
import Ellipsis from "@lucide/svelte/icons/ellipsis";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, ...restProps } = $props();

View file

@ -1,6 +1,6 @@
<script>
import { Pagination as PaginationPrimitive } from "bits-ui";
import ChevronRight from "lucide-svelte/icons/chevron-right";
import ChevronRight from "@lucide/svelte/icons/chevron-right";
import { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js";

View file

@ -1,6 +1,6 @@
<script>
import { Pagination as PaginationPrimitive } from "bits-ui";
import ChevronLeft from "lucide-svelte/icons/chevron-left";
import ChevronLeft from "@lucide/svelte/icons/chevron-left";
import { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js";

View file

@ -7,11 +7,12 @@
class: className,
sideOffset = 4,
align = "center",
portalProps,
...restProps
} = $props();
</script>
<PopoverPrimitive.Portal>
<PopoverPrimitive.Portal {...portalProps}>
<PopoverPrimitive.Content
bind:ref
{sideOffset}

View file

@ -1,6 +1,6 @@
<script>
import { RadioGroup as RadioGroupPrimitive } from "bits-ui";
import Circle from "lucide-svelte/icons/circle";
import Circle from "@lucide/svelte/icons/circle";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, ...restProps } = $props();

View file

@ -1,6 +1,6 @@
<script>
import { RangeCalendar as RangeCalendarPrimitive } from "bits-ui";
import ChevronRight from "lucide-svelte/icons/chevron-right";
import ChevronRight from "@lucide/svelte/icons/chevron-right";
import { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js";

View file

@ -1,6 +1,6 @@
<script>
import { RangeCalendar as RangeCalendarPrimitive } from "bits-ui";
import ChevronLeft from "lucide-svelte/icons/chevron-left";
import ChevronLeft from "@lucide/svelte/icons/chevron-left";
import { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js";

View file

@ -28,11 +28,11 @@
<RangeCalendar.NextButton />
</RangeCalendar.Header>
<RangeCalendar.Months>
{#each months as month}
{#each months as month (month)}
<RangeCalendar.Grid>
<RangeCalendar.GridHead>
<RangeCalendar.GridRow class="flex">
{#each weekdays as weekday}
{#each weekdays as weekday (weekday)}
<RangeCalendar.HeadCell>
{weekday.slice(0, 2)}
</RangeCalendar.HeadCell>
@ -40,9 +40,9 @@
</RangeCalendar.GridRow>
</RangeCalendar.GridHead>
<RangeCalendar.GridBody>
{#each month.weeks as weekDates}
{#each month.weeks as weekDates (weekDates)}
<RangeCalendar.GridRow class="mt-2 w-full">
{#each weekDates as date}
{#each weekDates as date (date)}
<RangeCalendar.Cell {date} month={month.value}>
<RangeCalendar.Day />
</RangeCalendar.Cell>

View file

@ -1,5 +1,5 @@
<script>
import GripVertical from "lucide-svelte/icons/grip-vertical";
import GripVertical from "@lucide/svelte/icons/grip-vertical";
import * as ResizablePrimitive from "paneforge";
import { cn } from "$lib/utils.js";

View file

@ -8,12 +8,13 @@
ref = $bindable(null),
class: className,
sideOffset = 4,
portalProps,
children,
...restProps
} = $props();
</script>
<SelectPrimitive.Portal>
<SelectPrimitive.Portal {...portalProps}>
<SelectPrimitive.Content
bind:ref
{sideOffset}

View file

@ -1,5 +1,5 @@
<script>
import Check from "lucide-svelte/icons/check";
import Check from "@lucide/svelte/icons/check";
import { Select as SelectPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";

View file

@ -1,5 +1,5 @@
<script>
import ChevronDown from "lucide-svelte/icons/chevron-down";
import ChevronDown from "@lucide/svelte/icons/chevron-down";
import { Select as SelectPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";

View file

@ -1,5 +1,5 @@
<script>
import ChevronUp from "lucide-svelte/icons/chevron-up";
import ChevronUp from "@lucide/svelte/icons/chevron-up";
import { Select as SelectPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";

View file

@ -1,6 +1,6 @@
<script>
import { Select as SelectPrimitive } from "bits-ui";
import ChevronDown from "lucide-svelte/icons/chevron-down";
import ChevronDown from "@lucide/svelte/icons/chevron-down";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, children, ...restProps } = $props();

View file

@ -3,14 +3,25 @@ import { getContext, setContext } from "svelte";
import { SIDEBAR_KEYBOARD_SHORTCUT } from "./constants.js";
class SidebarState {
props;
open = $derived.by(() => this.props.open());
openMobile = $state(false);
setOpen;
__init() {
this.open = $derived.by(() => this.props.open());
}
__init2() {
this.openMobile = $state(false);
}
#isMobile;
state = $derived.by(() => (this.open ? "expanded" : "collapsed"));
__init3() {
this.state = $derived.by(() => (this.open ? "expanded" : "collapsed"));
}
constructor(props) {
SidebarState.prototype.__init.call(this);
SidebarState.prototype.__init2.call(this);
SidebarState.prototype.__init3.call(this);
SidebarState.prototype.__init4.call(this);
SidebarState.prototype.__init5.call(this);
SidebarState.prototype.__init6.call(this);
this.setOpen = props.setOpen;
this.#isMobile = new IsMobile();
this.props = props;
@ -23,20 +34,28 @@ class SidebarState {
}
// Event handler to apply to the `<svelte:window>`
handleShortcutKeydown = (e) => {
if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
this.toggle();
}
};
__init4() {
this.handleShortcutKeydown = (e) => {
if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
this.toggle();
}
};
}
setOpenMobile = (value) => {
this.openMobile = value;
};
__init5() {
this.setOpenMobile = (value) => {
this.openMobile = value;
};
}
toggle = () => {
return this.#isMobile.current ? (this.openMobile = !this.openMobile) : this.setOpen(!this.open);
};
__init6() {
this.toggle = () => {
return this.#isMobile.current
? (this.openMobile = !this.openMobile)
: this.setOpen(!this.open);
};
}
}
const SYMBOL_KEY = "scn-sidebar";

View file

@ -2,20 +2,39 @@
import { Slider as SliderPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
let { ref = $bindable(null), value = $bindable([0]), class: className, ...restProps } = $props();
let {
ref = $bindable(null),
value = $bindable(),
orientation = "horizontal",
class: className,
...restProps
} = $props();
</script>
<!--
Discriminated Unions + Destructing (required for bindable) do not
get along, so we shut typescript up by casting `value` to `never`.
-->
<SliderPrimitive.Root
bind:ref
bind:value
class={cn("relative flex w-full touch-none select-none items-center", className)}
{orientation}
class={cn(
"relative flex touch-none select-none items-center data-[orientation='vertical']:h-full data-[orientation='vertical']:min-h-44 data-[orientation='horizontal']:w-full data-[orientation='vertical']:w-auto data-[orientation='vertical']:flex-col",
className,
)}
{...restProps}
>
{#snippet children({ thumbs })}
<span class="relative h-2 w-full grow overflow-hidden rounded-full bg-secondary">
<SliderPrimitive.Range class="absolute h-full bg-primary" />
<span
data-orientation={orientation}
class="relative grow overflow-hidden rounded-full bg-secondary data-[orientation='horizontal']:h-2 data-[orientation='vertical']:h-full data-[orientation='horizontal']:w-full data-[orientation='vertical']:w-2"
>
<SliderPrimitive.Range
class="absolute bg-primary data-[orientation='horizontal']:h-full data-[orientation='vertical']:w-full"
/>
</span>
{#each thumbs as thumb}
{#each thumbs as thumb (thumb)}
<SliderPrimitive.Thumb
index={thumb}
class="block size-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"

View file

@ -2,11 +2,11 @@
import { Toaster as Sonner } from "svelte-sonner";
import { mode } from "mode-watcher";
let restProps = $props();
let { ...restProps } = $props();
</script>
<Sonner
theme={$mode}
theme={mode.current}
class="toaster group"
toastOptions={{
classes: {

View file

@ -14,7 +14,7 @@
bind:ref
bind:checked
class={cn(
"peer inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
className,
)}
{...restProps}

View file

@ -4,10 +4,6 @@
let { ref = $bindable(null), class: className, children, ...restProps } = $props();
</script>
<tfoot
bind:this={ref}
class={cn("bg-muted/50 font-medium text-primary-foreground", className)}
{...restProps}
>
<tfoot bind:this={ref} class={cn("bg-muted/50 font-medium", className)} {...restProps}>
{@render children?.()}
</tfoot>

View file

@ -7,7 +7,7 @@
<textarea
bind:this={ref}
class={cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background 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",
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background 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 md:text-sm",
className,
)}
bind:value

View file

@ -1,6 +1,6 @@
<script>
import { ToggleGroup as ToggleGroupPrimitive } from "bits-ui";
import { getToggleGroupCtx } from "$lib/components/ui/toggle-group/toggle-group.svelte";
import { getToggleGroupCtx } from "./toggle-group.svelte";
import { cn } from "$lib/utils.js";
import { toggleVariants } from "$lib/components/ui/toggle/index.js";

View file

@ -2,16 +2,16 @@
import { tv } from "tailwind-variants";
export const toggleVariants = tv({
base: "ring-offset-background hover:bg-muted hover:text-muted-foreground focus-visible:ring-ring data-[state=on]:bg-accent data-[state=on]:text-accent-foreground inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
base: "ring-offset-background hover:bg-muted hover:text-muted-foreground focus-visible:ring-ring data-[state=on]:bg-accent data-[state=on]:text-accent-foreground inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
variants: {
variant: {
default: "bg-transparent",
outline: "border-input hover:bg-accent hover:text-accent-foreground border bg-transparent",
},
size: {
default: "h-10 px-3",
sm: "h-9 px-2.5",
lg: "h-11 px-5",
default: "h-10 min-w-10 px-3",
sm: "h-9 min-w-9 px-2.5",
lg: "h-11 min-w-11 px-5",
},
},
defaultVariants: {
@ -38,6 +38,6 @@
<TogglePrimitive.Root
bind:ref
bind:pressed
class={cn(toggleVariants({ variant, size, className }))}
class={cn(toggleVariants({ variant, size }), className)}
{...restProps}
/>