Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import Ellipsis from 'lucide-svelte/icons/ellipsis';
import Ellipsis from '@lucide/svelte/icons/ellipsis';
import type { WithElementRef, WithoutChildren } from 'bits-ui';
import type { HTMLAttributes } from 'svelte/elements';
import { cn } from '$lib/utils.js';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import ChevronRight from 'lucide-svelte/icons/chevron-right';
import ChevronRight from '@lucide/svelte/icons/chevron-right';
import type { WithElementRef } from 'bits-ui';
import type { HTMLLiAttributes } from 'svelte/elements';
import { cn } from '$lib/utils.js';
Expand Down
4 changes: 3 additions & 1 deletion src/lib/components/ui/command/command-group.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<script lang="ts">
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,
value,
...restProps
}: CommandPrimitive.GroupProps & {
heading?: string;
Expand All @@ -16,6 +17,7 @@
<CommandPrimitive.Group
class={cn('overflow-hidden p-1 text-foreground', className)}
bind:ref
value={value ?? heading ?? `----${useId()}`}
{...restProps}
>
{#if heading}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/ui/command/command-input.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
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 {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/ui/command/command-item.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<CommandPrimitive.Item
class={cn(
'relative flex scale-95 cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none duration-200 aria-selected:scale-100 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',
'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
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/ui/command/command-link-item.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<CommandPrimitive.LinkItem
class={cn(
'relative flex scale-95 cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none duration-200 aria-selected:scale-100 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
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive, type WithoutChildrenOrChild } 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';
import type { Snippet } from 'svelte';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive, type WithoutChild } from 'bits-ui';
import Circle from 'lucide-svelte/icons/circle';
import Circle from '@lucide/svelte/icons/circle';
import { cn } from '$lib/utils.js';

let {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
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 {
Expand Down
15 changes: 15 additions & 0 deletions src/lib/components/ui/index.ts
Original file line number Diff line number Diff line change
@@ -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,
Content,
Trigger,
//
Root as Collapsible,
Content as CollapsibleContent,
Trigger as CollapsibleTrigger
};
46 changes: 35 additions & 11 deletions src/lib/components/ui/input/input.svelte
Original file line number Diff line number Diff line change
@@ -1,22 +1,46 @@
<script lang="ts">
import type { HTMLInputAttributes } from 'svelte/elements';
import type { HTMLInputAttributes, HTMLInputTypeAttribute } from 'svelte/elements';
import type { WithElementRef } from 'bits-ui';
import { cn } from '$lib/utils.js';

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,
...restProps
}: WithElementRef<HTMLInputAttributes> = $props();
}: Props = $props();
</script>

<input
bind:this={ref}
class={cn(
'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
className
)}
bind:value
{...restProps}
/>
{#if type === 'file'}
<input
bind:this={ref}
class={cn(
'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
className
)}
type="file"
bind:files
bind:value
{...restProps}
/>
{:else}
<input
bind:this={ref}
class={cn(
'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
className
)}
{type}
bind:value
{...restProps}
/>
{/if}
2 changes: 1 addition & 1 deletion src/lib/components/ui/select/select-item.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import Check from 'lucide-svelte/icons/check';
import Check from '@lucide/svelte/icons/check';
import { Select as SelectPrimitive, type WithoutChild } from 'bits-ui';
import { cn } from '$lib/utils.js';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import ChevronDown from 'lucide-svelte/icons/chevron-down';
import ChevronDown from '@lucide/svelte/icons/chevron-down';
import { Select as SelectPrimitive, type WithoutChildrenOrChild } from 'bits-ui';
import { cn } from '$lib/utils.js';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import ChevronUp from 'lucide-svelte/icons/chevron-up';
import ChevronUp from '@lucide/svelte/icons/chevron-up';
import { Select as SelectPrimitive, type WithoutChildrenOrChild } from 'bits-ui';
import { cn } from '$lib/utils.js';

Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/ui/select/select-trigger.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import { Select as SelectPrimitive, type WithoutChild } 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 {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/ui/sheet/sheet-content.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

<script lang="ts">
import { Dialog as SheetPrimitive, type WithoutChildrenOrChild } from 'bits-ui';
import X from 'lucide-svelte/icons/x';
import X from '@lucide/svelte/icons/x';
import type { Snippet } from 'svelte';
import SheetOverlay from './sheet-overlay.svelte';
import { cn } from '$lib/utils.js';
Expand Down
10 changes: 2 additions & 8 deletions src/lib/components/ui/sidebar/sidebar-provider.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,20 @@
ref = $bindable(null),
open = $bindable(true),
onOpenChange = () => {},
controlledOpen = false,
class: className,
style,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
open?: boolean;
onOpenChange?: (open: boolean) => void;
controlledOpen?: boolean;
} = $props();

const sidebar = setSidebar({
open: () => open,
setOpen: (value: boolean) => {
if (controlledOpen) {
onOpenChange(value);
} else {
open = value;
onOpenChange(value);
}
open = value;
onOpenChange(value);

// This sets the cookie to keep the sidebar state.
document.cookie = `${SIDEBAR_COOKIE_NAME}=${open}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/ui/sidebar/sidebar-trigger.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { Button } from '$lib/components/ui/button/index.js';
import { cn } from '$lib/utils.js';
import PanelLeft from 'lucide-svelte/icons/panel-left';
import PanelLeft from '@lucide/svelte/icons/panel-left';
import type { ComponentProps } from 'svelte';
import { useSidebar } from './context.svelte.js';

Expand Down
17 changes: 6 additions & 11 deletions src/lib/components/ui/sidebar/sidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
{#if collapsible === 'none'}
<div
class={cn(
'flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground',
'flex h-full w-[var(--sidebar-width)] flex-col bg-sidebar text-sidebar-foreground',
className
)}
bind:this={ref}
Expand All @@ -35,16 +35,11 @@
{@render children?.()}
</div>
{:else if sidebar.isMobile}
<Sheet.Root
controlledOpen
open={sidebar.openMobile}
onOpenChange={sidebar.setOpenMobile}
{...restProps}
>
<Sheet.Root bind:open={() => sidebar.openMobile, (v) => sidebar.setOpenMobile(v)} {...restProps}>
<Sheet.Content
data-sidebar="sidebar"
data-mobile="true"
class="w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
class="w-[var(--sidebar-width)] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
style="--sidebar-width: {SIDEBAR_WIDTH_MOBILE};"
{side}
>
Expand All @@ -70,19 +65,19 @@
'group-data-[side=right]:rotate-180',
variant === 'floating' || variant === 'inset'
? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'
: 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]'
: 'group-data-[collapsible=icon]:w-[var(--sidebar-width-icon)]'
)}
></div>
<div
class={cn(
'fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] duration-200 ease-out md:flex',
'fixed inset-y-0 z-10 hidden h-svh w-[var(--sidebar-width)] transition-[left,right,width] duration-200 ease-out md:flex',
side === 'left'
? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'
: 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',
// Adjust the padding for floating and inset variants.
variant === 'floating' || variant === 'inset'
? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'
: 'group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l',
: 'group-data-[collapsible=icon]:w-[var(--sidebar-width-icon)] group-data-[side=left]:border-r group-data-[side=right]:border-l',
className
)}
{...restProps}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/ui/sonner/sonner.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { Toaster as Sonner, type ToasterProps as SonnerProps } from 'svelte-sonner';
import { mode } from 'mode-watcher';

let restProps: SonnerProps = $props();
let { ...restProps }: SonnerProps = $props();
</script>

<Sonner
Expand Down
23 changes: 1 addition & 22 deletions src/lib/components/ui/textarea/index.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,7 @@
import Root from './textarea.svelte';

type FormTextareaEvent<T extends Event = Event> = T & {
currentTarget: EventTarget & HTMLTextAreaElement;
};

type TextareaEvents = {
blur: FormTextareaEvent<FocusEvent>;
change: FormTextareaEvent<Event>;
click: FormTextareaEvent<MouseEvent>;
focus: FormTextareaEvent<FocusEvent>;
keydown: FormTextareaEvent<KeyboardEvent>;
keypress: FormTextareaEvent<KeyboardEvent>;
keyup: FormTextareaEvent<KeyboardEvent>;
mouseover: FormTextareaEvent<MouseEvent>;
mouseenter: FormTextareaEvent<MouseEvent>;
mouseleave: FormTextareaEvent<MouseEvent>;
paste: FormTextareaEvent<ClipboardEvent>;
input: FormTextareaEvent<InputEvent>;
};

export {
Root,
//
Root as Textarea,
type TextareaEvents,
type FormTextareaEvent
Root as Textarea
};
24 changes: 3 additions & 21 deletions src/lib/hooks/is-mobile.svelte.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,9 @@
import { untrack } from 'svelte';
import { MediaQuery } from 'svelte/reactivity';

const MOBILE_BREAKPOINT = 768;

export class IsMobile {
#current = $state<boolean>(false);

export class IsMobile extends MediaQuery {
constructor() {
$effect(() => {
return untrack(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => {
this.#current = window.innerWidth < MOBILE_BREAKPOINT;
};
mql.addEventListener('change', onChange);
onChange();
return () => {
mql.removeEventListener('change', onChange);
};
});
});
}

get current() {
return this.#current;
super(`max-width: ${MOBILE_BREAKPOINT - 1}px`);
}
}
Loading