commit before upgrading to tailwind 4

This commit is contained in:
vcoppe
2025-06-08 16:32:41 +02:00
parent 228ad1044e
commit f0230d4634
129 changed files with 4033 additions and 4468 deletions

View File

@@ -1,14 +1,16 @@
{ {
"$schema": "https://shadcn-svelte.com/schema.json", "$schema": "https://next.shadcn-svelte.com/schema.json",
"style": "default", "tailwind": {
"tailwind": { "css": "src/app.pcss",
"config": "tailwind.config.js", "baseColor": "slate"
"css": "src/app.css", },
"baseColor": "slate" "aliases": {
}, "components": "$lib/components",
"aliases": { "utils": "$lib/utils",
"components": "$lib/components", "ui": "$lib/components/ui",
"utils": "$lib/utils" "hooks": "$lib/hooks",
}, "lib": "$lib"
"typescript": true },
"typescript": true,
"registry": "https://tw3.shadcn-svelte.com/registry/default"
} }

5087
website/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -14,68 +14,70 @@
"format": "prettier --write ." "format": "prettier --write ."
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/adapter-auto": "^3.2.5", "@lucide/svelte": "^0.482.0",
"@sveltejs/adapter-static": "^3.0.5", "@sveltejs/adapter-static": "^3.0.8",
"@sveltejs/enhanced-img": "^0.3.8", "@sveltejs/enhanced-img": "^0.6.0",
"@sveltejs/kit": "^2.6.1", "@sveltejs/kit": "^2.21.2",
"@sveltejs/vite-plugin-svelte": "^3.1.2", "@sveltejs/vite-plugin-svelte": "^5.1.0",
"@types/eslint": "^8.56.12", "@types/eslint": "^9.6.1",
"@types/events": "^3.0.3", "@types/events": "^3.0.3",
"@types/file-saver": "^2.0.7", "@types/file-saver": "^2.0.7",
"@types/mapbox__tilebelt": "^1.0.4", "@types/mapbox__tilebelt": "^1.0.4",
"@types/mapbox-gl": "^3.4.0", "@types/mapbox-gl": "^3.4.1",
"@types/node": "^20.16.10", "@types/node": "^22.15.30",
"@types/png.js": "^0.2.3", "@types/png.js": "^0.2.3",
"@types/sanitize-html": "^2.13.0", "@types/sanitize-html": "^2.16.0",
"@types/sortablejs": "^1.15.8", "@types/sortablejs": "^1.15.8",
"@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/eslint-plugin": "^8.33.1",
"@typescript-eslint/parser": "^7.18.0", "@typescript-eslint/parser": "^8.33.1",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.21",
"eslint": "^8.57.1", "bits-ui": "^1.8.0",
"eslint-config-prettier": "^9.1.0", "eslint": "^9.28.0",
"eslint-plugin-svelte": "^2.44.1", "eslint-config-prettier": "^10.1.5",
"eslint-plugin-svelte": "^3.9.1",
"events": "^3.3.0", "events": "^3.3.0",
"glob": "^10.4.5", "glob": "^11.0.2",
"lucide-static": "^0.513.0",
"mdsvex": "^0.12.6", "mdsvex": "^0.12.6",
"mode-watcher": "^1.0.7",
"paneforge": "^1.0.0-next.5",
"postcss": "^8.4.47", "postcss": "^8.4.47",
"prettier": "^3.3.3", "prettier": "^3.5.3",
"prettier-plugin-svelte": "^3.2.7", "prettier-plugin-svelte": "^3.4.0",
"svelte": "^4.2.19", "svelte": "^5.33.18",
"svelte-check": "^3.8.6", "svelte-check": "^4.0.0",
"svelte-sonner": "^0.3.28",
"tailwindcss": "^3.4.13", "tailwindcss": "^3.4.13",
"tslib": "^2.7.0", "tslib": "^2.8.1",
"tsx": "^4.19.1", "tsx": "^4.19.1",
"typescript": "^5.6.2", "typescript": "^5.8.3",
"vite": "^5.4.8", "vaul-svelte": "^1.0.0-next.7",
"vite-plugin-node-polyfills": "^0.22.0" "vite": "^6.3.5",
"vite-plugin-node-polyfills": "^0.23.0"
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@docsearch/js": "^3.6.2", "@docsearch/js": "^3.9.0",
"@internationalized/date": "^3.5.5", "@internationalized/date": "^3.8.2",
"@mapbox/mapbox-gl-geocoder": "^5.0.3", "@mapbox/mapbox-gl-geocoder": "^5.0.3",
"@mapbox/sphericalmercator": "^1.2.0", "@mapbox/sphericalmercator": "^2.0.1",
"@mapbox/tilebelt": "^1.0.2", "@mapbox/tilebelt": "^2.0.2",
"@types/mapbox__sphericalmercator": "^1.2.3", "@types/mapbox__sphericalmercator": "^1.2.3",
"bits-ui": "^0.21.15", "chart.js": "^4.4.9",
"chart.js": "^4.4.4", "chartjs-plugin-zoom": "^2.2.0",
"chartjs-plugin-zoom": "^2.0.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"dexie": "^4.0.8", "dexie": "^4.0.11",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"gpx": "file:../gpx", "gpx": "file:../gpx",
"immer": "^10.1.1", "immer": "^10.1.1",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"lucide-static": "^0.460.0", "mapbox-gl": "^3.12.0",
"lucide-svelte": "^0.460.1",
"mapbox-gl": "^3.11.1",
"mapillary-js": "^4.1.2", "mapillary-js": "^4.1.2",
"mode-watcher": "^0.3.1",
"png.js": "^0.2.1", "png.js": "^0.2.1",
"sanitize-html": "^2.13.0", "sanitize-html": "^2.17.0",
"sortablejs": "^1.15.3", "sortablejs": "^1.15.6",
"svelte-sonner": "^0.3.28",
"tailwind-merge": "^2.5.2", "tailwind-merge": "^2.5.2",
"tailwind-variants": "^0.2.1" "tailwind-variants": "^0.2.1",
"tailwindcss-animate": "^1.0.7"
} }
} }

View File

@@ -511,8 +511,8 @@
// Draw selection rectangle // Draw selection rectangle
let selectionContext = overlay.getContext('2d'); let selectionContext = overlay.getContext('2d');
if (selectionContext) { if (selectionContext) {
selectionContext.fillStyle = $mode === 'dark' ? 'white' : 'black'; selectionContext.fillStyle = mode.current === 'dark' ? 'white' : 'black';
selectionContext.globalAlpha = $mode === 'dark' ? 0.2 : 0.1; selectionContext.globalAlpha = mode.current === 'dark' ? 0.2 : 0.1;
selectionContext.clearRect(0, 0, overlay.width, overlay.height); selectionContext.clearRect(0, 0, overlay.width, overlay.height);
let startPixel = chart.scales.x.getPixelForValue( let startPixel = chart.scales.x.getPixelForValue(
@@ -537,7 +537,7 @@
} }
} }
$: $slicedGPXStatistics, $mode, updateOverlay(); $: $slicedGPXStatistics, mode.current, updateOverlay();
onDestroy(() => { onDestroy(() => {
if (chart) { if (chart) {

View File

@@ -1,22 +1,20 @@
<script lang="ts"> <script lang="ts">
import { base } from '$app/paths'; import { base } from '$app/paths';
import { mode, systemPrefersMode } from 'mode-watcher'; import { mode } from 'mode-watcher';
export let iconOnly = false; export let iconOnly = false;
export let company = 'gpx.studio'; export let company = 'gpx.studio';
$: effectiveMode = $mode ?? $systemPrefersMode ?? 'light';
</script> </script>
{#if company === 'gpx.studio'} {#if company === 'gpx.studio'}
<img <img
src="{base}/{iconOnly ? 'icon' : 'logo'}{effectiveMode === 'dark' ? '-dark' : ''}.svg" src="{base}/{iconOnly ? 'icon' : 'logo'}{mode.current === 'dark' ? '-dark' : ''}.svg"
alt="Logo of gpx.studio." alt="Logo of gpx.studio."
{...$$restProps} {...$$restProps}
/> />
{:else if company === 'mapbox'} {:else if company === 'mapbox'}
<img <img
src="{base}/mapbox-logo-{effectiveMode === 'dark' ? 'white' : 'black'}.svg" src="{base}/mapbox-logo-{mode.current === 'dark' ? 'white' : 'black'}.svg"
alt="Logo of Mapbox." alt="Logo of Mapbox."
{...$$restProps} {...$$restProps}
/> />

View File

@@ -247,6 +247,7 @@
div :global(.mapboxgl-ctrl-icon) { div :global(.mapboxgl-ctrl-icon) {
@apply dark:brightness-[4.7]; @apply dark:brightness-[4.7];
@apply dark:bg-white;
} }
div :global(.mapboxgl-ctrl-geocoder) { div :global(.mapboxgl-ctrl-geocoder) {

View File

@@ -1,6 +1,6 @@
import { TrackPoint, Waypoint } from 'gpx'; import { TrackPoint, Waypoint } from 'gpx';
import mapboxgl from 'mapbox-gl'; import mapboxgl from 'mapbox-gl';
import { tick } from 'svelte'; import { tick, mount } from 'svelte';
import { get, writable, type Writable } from 'svelte/store'; import { get, writable, type Writable } from 'svelte/store';
import MapPopupComponent from './MapPopup.svelte'; import MapPopupComponent from './MapPopup.svelte';
@@ -20,12 +20,12 @@ export class MapPopup {
this.map = map; this.map = map;
this.popup = new mapboxgl.Popup(options); this.popup = new mapboxgl.Popup(options);
let component = new MapPopupComponent({ let component = mount(MapPopupComponent, {
target: document.body, target: document.body,
props: { props: {
item: this.item, item: this.item,
}, },
}); });
tick().then(() => this.popup.setDOMContent(component.container)); tick().then(() => this.popup.setDOMContent(component.container));
} }

View File

@@ -73,7 +73,7 @@
import LayerControlSettings from '$lib/components/layer-control/LayerControlSettings.svelte'; import LayerControlSettings from '$lib/components/layer-control/LayerControlSettings.svelte';
import { allowedPastes, ListFileItem, ListTrackItem } from '$lib/components/file-list/FileList'; import { allowedPastes, ListFileItem, ListTrackItem } from '$lib/components/file-list/FileList';
import Export from '$lib/components/Export.svelte'; import Export from '$lib/components/Export.svelte';
import { mode, setMode, systemPrefersMode } from 'mode-watcher'; import { mode, setMode } from 'mode-watcher';
import { _, locale } from '$lib/i18n'; import { _, locale } from '$lib/i18n';
import { languages } from '$lib/languages'; import { languages } from '$lib/languages';
import { getURLForLanguage } from '$lib/utils'; import { getURLForLanguage } from '$lib/utils';
@@ -120,8 +120,6 @@
} }
let layerSettingsOpen = false; let layerSettingsOpen = false;
$: selectedMode = $mode ?? $systemPrefersMode ?? 'light';
</script> </script>
<div class="absolute md:top-2 left-0 right-0 z-20 flex flex-row justify-center pointer-events-none"> <div class="absolute md:top-2 left-0 right-0 z-20 flex flex-row justify-center pointer-events-none">
@@ -461,7 +459,7 @@
</Menubar.Sub> </Menubar.Sub>
<Menubar.Sub> <Menubar.Sub>
<Menubar.SubTrigger> <Menubar.SubTrigger>
{#if selectedMode === 'light'} {#if mode.current === 'light' || !mode.current}
<Sun size="16" class="mr-1" /> <Sun size="16" class="mr-1" />
{:else} {:else}
<Moon size="16" class="mr-1" /> <Moon size="16" class="mr-1" />
@@ -470,7 +468,7 @@
</Menubar.SubTrigger> </Menubar.SubTrigger>
<Menubar.SubContent> <Menubar.SubContent>
<Menubar.RadioGroup <Menubar.RadioGroup
bind:value={selectedMode} value={mode.current ?? 'light'}
onValueChange={(value) => { onValueChange={(value) => {
setMode(value); setMode(value);
}} }}

View File

@@ -1,23 +1,21 @@
<script lang="ts"> <script lang="ts">
import { Button } from '$lib/components/ui/button'; import { Button } from '$lib/components/ui/button';
import { Moon, Sun } from 'lucide-svelte'; import { Moon, Sun } from 'lucide-svelte';
import { mode, setMode, systemPrefersMode } from 'mode-watcher'; import { mode, setMode } from 'mode-watcher';
import { _ } from '$lib/i18n'; import { _ } from '$lib/i18n';
export let size = '20'; export let size = '20';
$: selectedMode = $mode ?? $systemPrefersMode ?? 'light';
</script> </script>
<Button <Button
variant="ghost" variant="ghost"
class="h-8 px-1.5 {$$props.class ?? ''}" class="h-8 px-1.5 {$$props.class ?? ''}"
on:click={() => { on:click={() => {
setMode(selectedMode === 'light' ? 'dark' : 'light'); setMode(mode.current === 'light' ? 'dark' : 'light');
}} }}
aria-label={$_('menu.mode')} aria-label={$_('menu.mode')}
> >
{#if selectedMode === 'light'} {#if mode.current === 'light'}
<Sun {size} /> <Sun {size} />
{:else} {:else}
<Moon {size} /> <Moon {size} />

View File

@@ -39,4 +39,4 @@
? 'w-1 h-full cursor-col-resize border-l' ? 'w-1 h-full cursor-col-resize border-l'
: 'w-full h-1 cursor-row-resize border-t'} {orientation}" : 'w-full h-1 cursor-row-resize border-t'} {orientation}"
on:pointerdown={handleMouseDown} on:pointerdown={handleMouseDown}
/> ></div>

View File

@@ -148,7 +148,7 @@
`${c} ${Math.floor((100 * i) / nodeColors.length)}% ${Math.floor((100 * (i + 1)) / nodeColors.length)}%` `${c} ${Math.floor((100 * i) / nodeColors.length)}% ${Math.floor((100 * (i + 1)) / nodeColors.length)}%`
) )
.join(',')})" .join(',')})"
/> ></div>
{/if} {/if}
<span <span
class="w-full text-left truncate py-1 flex flex-row items-center {hidden class="w-full text-left truncate py-1 flex flex-row items-center {hidden

View File

@@ -56,7 +56,7 @@
class="inline-block mb-0.5" class="inline-block mb-0.5"
/> />
{:else} {:else}
<span class="w-4 inline-block" /> <span class="w-4 inline-block"></span>
{/if} {/if}
{$_(`gpx.symbol.${symbolKey}`)} {$_(`gpx.symbol.${symbolKey}`)}
</span> </span>

View File

@@ -1,4 +1,4 @@
import SphericalMercator from '@mapbox/sphericalmercator'; import { SphericalMercator } from '@mapbox/sphericalmercator';
import { getLayers } from './utils'; import { getLayers } from './utils';
import { get, writable } from 'svelte/store'; import { get, writable } from 'svelte/store';
import { liveQuery } from 'dexie'; import { liveQuery } from 'dexie';

View File

@@ -213,7 +213,7 @@
class="inline-block align-sub mr-0.5" class="inline-block align-sub mr-0.5"
/> />
{:else} {:else}
<span class="w-4 inline-block" /> <span class="w-4 inline-block"></span>
{/if} {/if}
{$_(`gpx.symbol.${key}`)} {$_(`gpx.symbol.${key}`)}
</span> </span>

View File

@@ -1,23 +1,24 @@
<script lang="ts"> <script lang="ts">
import { Accordion as AccordionPrimitive } from 'bits-ui'; import { Accordion as AccordionPrimitive, type WithoutChild } from "bits-ui";
import { slide } from 'svelte/transition'; import { cn } from "$lib/utils.js";
import { cn } from '$lib/utils.js';
type $$Props = AccordionPrimitive.ContentProps; let {
ref = $bindable(null),
let className: $$Props['class'] = undefined; class: className,
export let transition: $$Props['transition'] = slide; children,
export let transitionConfig: $$Props['transitionConfig'] = { ...restProps
duration: 200 }: WithoutChild<AccordionPrimitive.ContentProps> = $props();
};
export { className as class };
</script> </script>
<AccordionPrimitive.Content <AccordionPrimitive.Content
class={cn('overflow-hidden text-sm transition-all mb-4', className)} bind:ref
{transition} class={cn(
{transitionConfig} "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm transition-all",
{...$$restProps} className
)}
{...restProps}
> >
<slot /> <div class="pb-4 pt-0">
{@render children?.()}
</div>
</AccordionPrimitive.Content> </AccordionPrimitive.Content>

View File

@@ -1,14 +1,12 @@
<script lang="ts"> <script lang="ts">
import { Accordion as AccordionPrimitive } from 'bits-ui'; import { Accordion as AccordionPrimitive } from "bits-ui";
import { cn } from '$lib/utils.js'; import { cn } from "$lib/utils.js";
type $$Props = AccordionPrimitive.ItemProps; let {
ref = $bindable(null),
let className: $$Props['class'] = undefined; class: className,
export let value: $$Props['value']; ...restProps
export { className as class }; }: AccordionPrimitive.ItemProps = $props();
</script> </script>
<AccordionPrimitive.Item {value} class={cn('border-b', className)} {...$$restProps}> <AccordionPrimitive.Item bind:ref class={cn("border-b", className)} {...restProps} />
<slot />
</AccordionPrimitive.Item>

View File

@@ -1,26 +1,29 @@
<script lang="ts"> <script lang="ts">
import { Accordion as AccordionPrimitive } from "bits-ui"; import { Accordion as AccordionPrimitive, 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"; import { cn } from "$lib/utils.js";
type $$Props = AccordionPrimitive.TriggerProps; let {
type $$Events = AccordionPrimitive.TriggerEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; level = 3,
export let level: AccordionPrimitive.HeaderProps["level"] = 3; children,
export { className as class }; ...restProps
}: WithoutChild<AccordionPrimitive.TriggerProps> & {
level?: AccordionPrimitive.HeaderProps["level"];
} = $props();
</script> </script>
<AccordionPrimitive.Header {level} class="flex"> <AccordionPrimitive.Header {level} class="flex">
<AccordionPrimitive.Trigger <AccordionPrimitive.Trigger
bind:ref
class={cn( class={cn(
"flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180", "flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
className className
)} )}
{...$$restProps} {...restProps}
on:click
> >
<slot /> {@render children?.()}
<ChevronDown class="h-4 w-4 transition-transform duration-200" /> <ChevronDown class="size-4 shrink-0 transition-transform duration-200" />
</AccordionPrimitive.Trigger> </AccordionPrimitive.Trigger>
</AccordionPrimitive.Header> </AccordionPrimitive.Header>

View File

@@ -3,19 +3,11 @@
import { buttonVariants } from "$lib/components/ui/button/index.js"; import { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = AlertDialogPrimitive.ActionProps; let {
type $$Events = AlertDialogPrimitive.ActionEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; ...restProps
export { className as class }; }: AlertDialogPrimitive.ActionProps = $props();
</script> </script>
<AlertDialogPrimitive.Action <AlertDialogPrimitive.Action bind:ref class={cn(buttonVariants(), className)} {...restProps} />
class={cn(buttonVariants(), className)}
{...$$restProps}
on:click
on:keydown
let:builder
>
<slot {builder} />
</AlertDialogPrimitive.Action>

View File

@@ -3,19 +3,15 @@
import { buttonVariants } from "$lib/components/ui/button/index.js"; import { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = AlertDialogPrimitive.CancelProps; let {
type $$Events = AlertDialogPrimitive.CancelEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; ...restProps
export { className as class }; }: AlertDialogPrimitive.CancelProps = $props();
</script> </script>
<AlertDialogPrimitive.Cancel <AlertDialogPrimitive.Cancel
bind:ref
class={cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className)} class={cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className)}
{...$$restProps} {...restProps}
on:click />
on:keydown
let:builder
>
<slot {builder} />
</AlertDialogPrimitive.Cancel>

View File

@@ -1,28 +1,26 @@
<script lang="ts"> <script lang="ts">
import { AlertDialog as AlertDialogPrimitive } from "bits-ui"; import { AlertDialog as AlertDialogPrimitive, type WithoutChild } from "bits-ui";
import * as AlertDialog from "./index.js"; import AlertDialogOverlay from "./alert-dialog-overlay.svelte";
import { cn, flyAndScale } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = AlertDialogPrimitive.ContentProps; let {
ref = $bindable(null),
export let transition: $$Props["transition"] = flyAndScale; class: className,
export let transitionConfig: $$Props["transitionConfig"] = undefined; portalProps,
...restProps
let className: $$Props["class"] = undefined; }: WithoutChild<AlertDialogPrimitive.ContentProps> & {
export { className as class }; portalProps?: AlertDialogPrimitive.PortalProps;
} = $props();
</script> </script>
<AlertDialog.Portal> <AlertDialogPrimitive.Portal {...portalProps}>
<AlertDialog.Overlay /> <AlertDialogOverlay />
<AlertDialogPrimitive.Content <AlertDialogPrimitive.Content
{transition} bind:ref
{transitionConfig}
class={cn( class={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg sm:rounded-lg md:w-full", "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 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg",
className className
)} )}
{...$$restProps} {...restProps}
> />
<slot /> </AlertDialogPrimitive.Portal>
</AlertDialogPrimitive.Content>
</AlertDialog.Portal>

View File

@@ -2,15 +2,15 @@
import { AlertDialog as AlertDialogPrimitive } from "bits-ui"; import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = AlertDialogPrimitive.DescriptionProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; ...restProps
}: AlertDialogPrimitive.DescriptionProps = $props();
</script> </script>
<AlertDialogPrimitive.Description <AlertDialogPrimitive.Description
class={cn("text-sm text-muted-foreground", className)} bind:ref
{...$$restProps} class={cn("text-muted-foreground text-sm", className)}
> {...restProps}
<slot /> />
</AlertDialogPrimitive.Description>

View File

@@ -1,16 +1,20 @@
<script lang="ts"> <script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script> </script>
<div <div
bind:this={ref}
class={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)} class={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
{...$$restProps} {...restProps}
> >
<slot /> {@render children?.()}
</div> </div>

View File

@@ -1,13 +1,20 @@
<script lang="ts"> <script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script> </script>
<div class={cn("flex flex-col space-y-2 text-center sm:text-left", className)} {...$$restProps}> <div
<slot /> bind:this={ref}
class={cn("flex flex-col space-y-2 text-center sm:text-left", className)}
{...restProps}
>
{@render children?.()}
</div> </div>

View File

@@ -1,21 +1,19 @@
<script lang="ts"> <script lang="ts">
import { AlertDialog as AlertDialogPrimitive } from "bits-ui"; import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
import { fade } from "svelte/transition";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = AlertDialogPrimitive.OverlayProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export let transition: $$Props["transition"] = fade; ...restProps
export let transitionConfig: $$Props["transitionConfig"] = { }: AlertDialogPrimitive.OverlayProps = $props();
duration: 150,
};
export { className as class };
</script> </script>
<AlertDialogPrimitive.Overlay <AlertDialogPrimitive.Overlay
{transition} bind:ref
{transitionConfig} class={cn(
class={cn("fixed inset-0 z-50 bg-background/80 backdrop-blur-sm ", className)} "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/80",
{...$$restProps} className
)}
{...restProps}
/> />

View File

@@ -2,13 +2,17 @@
import { AlertDialog as AlertDialogPrimitive } from "bits-ui"; import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = AlertDialogPrimitive.TitleProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export let level: $$Props["level"] = "h3"; level = 3,
export { className as class }; ...restProps
}: AlertDialogPrimitive.TitleProps = $props();
</script> </script>
<AlertDialogPrimitive.Title class={cn("text-lg font-semibold", className)} {level} {...$$restProps}> <AlertDialogPrimitive.Title
<slot /> bind:ref
</AlertDialogPrimitive.Title> class={cn("text-lg font-semibold", className)}
{level}
{...restProps}
/>

View File

@@ -1,9 +1,7 @@
import { AlertDialog as AlertDialogPrimitive } from "bits-ui"; import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
import Title from "./alert-dialog-title.svelte"; import Title from "./alert-dialog-title.svelte";
import Action from "./alert-dialog-action.svelte"; import Action from "./alert-dialog-action.svelte";
import Cancel from "./alert-dialog-cancel.svelte"; import Cancel from "./alert-dialog-cancel.svelte";
import Portal from "./alert-dialog-portal.svelte";
import Footer from "./alert-dialog-footer.svelte"; import Footer from "./alert-dialog-footer.svelte";
import Header from "./alert-dialog-header.svelte"; import Header from "./alert-dialog-header.svelte";
import Overlay from "./alert-dialog-overlay.svelte"; import Overlay from "./alert-dialog-overlay.svelte";
@@ -12,6 +10,7 @@ import Description from "./alert-dialog-description.svelte";
const Root = AlertDialogPrimitive.Root; const Root = AlertDialogPrimitive.Root;
const Trigger = AlertDialogPrimitive.Trigger; const Trigger = AlertDialogPrimitive.Trigger;
const Portal = AlertDialogPrimitive.Portal;
export { export {
Root, Root,

View File

@@ -1,13 +1,16 @@
<script lang="ts"> <script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script> </script>
<div class={cn("text-sm [&_p]:leading-relaxed", className)} {...$$restProps}> <div bind:this={ref} class={cn("text-sm [&_p]:leading-relaxed", className)} {...restProps}>
<slot /> {@render children?.()}
</div> </div>

View File

@@ -1,21 +1,25 @@
<script lang="ts"> <script lang="ts">
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import type { HeadingLevel } from "./index.js"; import type { WithElementRef } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLHeadingElement> & { let {
level?: HeadingLevel; ref = $bindable(null),
}; class: className,
level = 5,
let className: $$Props["class"] = undefined; children,
export let level: $$Props["level"] = "h5"; ...restProps
export { className as class }; }: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
level?: 1 | 2 | 3 | 4 | 5 | 6;
} = $props();
</script> </script>
<svelte:element <div
this={level} role="heading"
aria-level={level}
bind:this={ref}
class={cn("mb-1 font-medium leading-none tracking-tight", className)} class={cn("mb-1 font-medium leading-none tracking-tight", className)}
{...$$restProps} {...restProps}
> >
<slot /> {@render children?.()}
</svelte:element> </div>

View File

@@ -1,17 +1,39 @@
<script lang="ts"> <script lang="ts" module>
import type { HTMLAttributes } from "svelte/elements"; import { type VariantProps, tv } from "tailwind-variants";
import { type Variant, alertVariants } from "./index.js";
import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement> & { export const alertVariants = tv({
variant?: Variant; base: "[&>svg]:text-foreground relative w-full rounded-lg border p-4 [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg~*]:pl-7",
}; variants: {
variant: {
default: "bg-background text-foreground",
destructive:
"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
},
},
defaultVariants: {
variant: "default",
},
});
let className: $$Props["class"] = undefined; export type AlertVariant = VariantProps<typeof alertVariants>["variant"];
export let variant: $$Props["variant"] = "default";
export { className as class };
</script> </script>
<div class={cn(alertVariants({ variant }), className)} {...$$restProps} role="alert"> <script lang="ts">
<slot /> import type { HTMLAttributes } from "svelte/elements";
import type { WithElementRef } from "bits-ui";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
variant = "default",
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
variant?: AlertVariant;
} = $props();
</script>
<div bind:this={ref} class={cn(alertVariants({ variant }), className)} {...restProps} role="alert">
{@render children?.()}
</div> </div>

View File

@@ -1,26 +1,7 @@
import { type VariantProps, tv } from "tailwind-variants";
import Root from "./alert.svelte"; import Root from "./alert.svelte";
import Description from "./alert-description.svelte"; import Description from "./alert-description.svelte";
import Title from "./alert-title.svelte"; import Title from "./alert-title.svelte";
export { alertVariants, type AlertVariant } from "./alert.svelte";
export const alertVariants = tv({
base: "relative w-full rounded-lg border p-4 [&:has(svg)]:pl-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
variants: {
variant: {
default: "bg-background text-foreground",
destructive:
"border-destructive/50 text-destructive text-destructive dark:border-destructive [&>svg]:text-destructive",
},
},
defaultVariants: {
variant: "default",
},
});
export type Variant = VariantProps<typeof alertVariants>["variant"];
export type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
export { export {
Root, Root,

View File

@@ -1,25 +1,74 @@
<script lang="ts"> <script lang="ts" module>
import { Button as ButtonPrimitive } from "bits-ui"; import type { WithElementRef } from "bits-ui";
import { type Events, type Props, buttonVariants } from "./index.js"; import type { HTMLAnchorAttributes, HTMLButtonAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js"; import { type VariantProps, tv } from "tailwind-variants";
type $$Props = Props; export const buttonVariants = tv({
type $$Events = Events; base: "ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center gap-2 whitespace-nowrap 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-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border-input bg-background hover:bg-accent hover:text-accent-foreground border",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
});
let className: $$Props["class"] = undefined; export type ButtonVariant = VariantProps<typeof buttonVariants>["variant"];
export let variant: $$Props["variant"] = "default"; export type ButtonSize = VariantProps<typeof buttonVariants>["size"];
export let size: $$Props["size"] = "default";
export let builders: $$Props["builders"] = []; export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
export { className as class }; WithElementRef<HTMLAnchorAttributes> & {
variant?: ButtonVariant;
size?: ButtonSize;
};
</script> </script>
<ButtonPrimitive.Root <script lang="ts">
{builders} import { cn } from "$lib/utils.js";
class={cn(buttonVariants({ variant, size, className }))}
type="button" let {
{...$$restProps} class: className,
on:click variant = "default",
on:keydown size = "default",
> ref = $bindable(null),
<slot /> href = undefined,
</ButtonPrimitive.Root> type = "button",
children,
...restProps
}: ButtonProps = $props();
</script>
{#if href}
<a
bind:this={ref}
class={cn(buttonVariants({ variant, size }), className)}
{href}
{...restProps}
>
{@render children?.()}
</a>
{:else}
<button
bind:this={ref}
class={cn(buttonVariants({ variant, size }), className)}
{type}
{...restProps}
>
{@render children?.()}
</button>
{/if}

View File

@@ -1,49 +1,17 @@
import { type VariantProps, tv } from "tailwind-variants"; import Root, {
import type { Button as ButtonPrimitive } from "bits-ui"; type ButtonProps,
import Root from "./button.svelte"; type ButtonSize,
type ButtonVariant,
const buttonVariants = tv({ buttonVariants,
base: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium 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", } from "./button.svelte";
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
});
type Variant = VariantProps<typeof buttonVariants>["variant"];
type Size = VariantProps<typeof buttonVariants>["size"];
type Props = ButtonPrimitive.Props & {
variant?: Variant;
size?: Size;
};
type Events = ButtonPrimitive.Events;
export { export {
Root, Root,
type Props, type ButtonProps as Props,
type Events,
// //
Root as Button, Root as Button,
type Props as ButtonProps,
type Events as ButtonEvents,
buttonVariants, buttonVariants,
type ButtonProps,
type ButtonSize,
type ButtonVariant,
}; };

View File

@@ -2,20 +2,18 @@
import { Calendar as CalendarPrimitive } from "bits-ui"; import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = CalendarPrimitive.CellProps; let {
ref = $bindable(null),
export let date: $$Props["date"]; class: className,
let className: $$Props["class"] = undefined; ...restProps
export { className as class }; }: CalendarPrimitive.CellProps = $props();
</script> </script>
<CalendarPrimitive.Cell <CalendarPrimitive.Cell
{date} bind:ref
class={cn( class={cn(
"relative h-9 w-9 p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([data-selected])]:rounded-md [&:has([data-selected])]:bg-accent [&:has([data-selected][data-outside-month])]:bg-accent/50", "[&:has([data-selected])]:bg-accent [&:has([data-selected][data-outside-month])]:bg-accent/50 relative size-9 p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([data-selected])]:rounded-md",
className className
)} )}
{...$$restProps} {...restProps}
> />
<slot />
</CalendarPrimitive.Cell>

View File

@@ -1,42 +1,30 @@
<script lang="ts"> <script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui";
import { buttonVariants } from "$lib/components/ui/button/index.js"; import { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
import { Calendar as CalendarPrimitive } from "bits-ui";
type $$Props = CalendarPrimitive.DayProps; let {
type $$Events = CalendarPrimitive.DayEvents; ref = $bindable(null),
class: className,
export let date: $$Props["date"]; ...restProps
export let month: $$Props["month"]; }: CalendarPrimitive.DayProps = $props();
let className: $$Props["class"] = undefined;
export { className as class };
</script> </script>
<CalendarPrimitive.Day <CalendarPrimitive.Day
on:click bind:ref
{date}
{month}
class={cn( class={cn(
buttonVariants({ variant: "ghost" }), buttonVariants({ variant: "ghost" }),
"h-9 w-9 p-0 font-normal ", "size-9 p-0 font-normal",
"[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground", "[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground",
// Selected // Selected
"data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:opacity-100 data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground", "data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground data-[selected]:opacity-100",
// Disabled // Disabled
"data-[disabled]:text-muted-foreground data-[disabled]:opacity-50", "data-[disabled]:text-muted-foreground data-[disabled]:opacity-50",
// Unavailable // Unavailable
"data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through", "data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through",
// Outside months // Outside months
"data-[outside-month]:pointer-events-none data-[outside-month]:text-muted-foreground data-[outside-month]:opacity-50 [&[data-outside-month][data-selected]]:bg-accent/50 [&[data-outside-month][data-selected]]:text-muted-foreground [&[data-outside-month][data-selected]]:opacity-30", "data-[outside-month]:text-muted-foreground [&[data-outside-month][data-selected]]:bg-accent/50 [&[data-outside-month][data-selected]]:text-muted-foreground data-[outside-month]:pointer-events-none data-[outside-month]:opacity-50 [&[data-outside-month][data-selected]]:opacity-30",
className className
)} )}
{...$$restProps} {...restProps}
let:selected />
let:disabled
let:unavailable
let:builder
>
<slot {selected} {disabled} {unavailable} {builder}>
{date.day}
</slot>
</CalendarPrimitive.Day>

View File

@@ -2,12 +2,11 @@
import { Calendar as CalendarPrimitive } from "bits-ui"; import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = CalendarPrimitive.GridBodyProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; ...restProps
}: CalendarPrimitive.GridBodyProps = $props();
</script> </script>
<CalendarPrimitive.GridBody class={cn(className)} {...$$restProps}> <CalendarPrimitive.GridBody bind:ref class={cn(className)} {...restProps} />
<slot />
</CalendarPrimitive.GridBody>

View File

@@ -2,12 +2,11 @@
import { Calendar as CalendarPrimitive } from "bits-ui"; import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = CalendarPrimitive.GridHeadProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; ...restProps
}: CalendarPrimitive.GridHeadProps = $props();
</script> </script>
<CalendarPrimitive.GridHead class={cn(className)} {...$$restProps}> <CalendarPrimitive.GridHead bind:ref class={cn(className)} {...restProps} />
<slot />
</CalendarPrimitive.GridHead>

View File

@@ -2,12 +2,11 @@
import { Calendar as CalendarPrimitive } from "bits-ui"; import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = CalendarPrimitive.GridRowProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; ...restProps
}: CalendarPrimitive.GridRowProps = $props();
</script> </script>
<CalendarPrimitive.GridRow class={cn("flex", className)} {...$$restProps}> <CalendarPrimitive.GridRow bind:ref class={cn("flex", className)} {...restProps} />
<slot />
</CalendarPrimitive.GridRow>

View File

@@ -2,12 +2,15 @@
import { Calendar as CalendarPrimitive } from "bits-ui"; import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = CalendarPrimitive.GridProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; ...restProps
}: CalendarPrimitive.GridProps = $props();
</script> </script>
<CalendarPrimitive.Grid class={cn("w-full border-collapse space-y-1", className)} {...$$restProps}> <CalendarPrimitive.Grid
<slot /> bind:ref
</CalendarPrimitive.Grid> class={cn("w-full border-collapse space-y-1", className)}
{...restProps}
/>

View File

@@ -2,15 +2,15 @@
import { Calendar as CalendarPrimitive } from "bits-ui"; import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = CalendarPrimitive.HeadCellProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; ...restProps
}: CalendarPrimitive.HeadCellProps = $props();
</script> </script>
<CalendarPrimitive.HeadCell <CalendarPrimitive.HeadCell
class={cn("w-9 rounded-md text-[0.8rem] font-normal text-muted-foreground", className)} bind:ref
{...$$restProps} class={cn("text-muted-foreground w-9 rounded-md text-[0.8rem] font-normal", className)}
> {...restProps}
<slot /> />
</CalendarPrimitive.HeadCell>

View File

@@ -2,15 +2,15 @@
import { Calendar as CalendarPrimitive } from "bits-ui"; import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = CalendarPrimitive.HeaderProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; ...restProps
}: CalendarPrimitive.HeaderProps = $props();
</script> </script>
<CalendarPrimitive.Header <CalendarPrimitive.Header
bind:ref
class={cn("relative flex w-full items-center justify-between pt-1", className)} class={cn("relative flex w-full items-center justify-between pt-1", className)}
{...$$restProps} {...restProps}
> />
<slot />
</CalendarPrimitive.Header>

View File

@@ -2,18 +2,11 @@
import { Calendar as CalendarPrimitive } from "bits-ui"; import { Calendar as CalendarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = CalendarPrimitive.HeadingProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; ...restProps
}: CalendarPrimitive.HeadingProps = $props();
</script> </script>
<CalendarPrimitive.Heading <CalendarPrimitive.Heading bind:ref class={cn("text-sm font-medium", className)} {...restProps} />
let:headingValue
class={cn("text-sm font-medium", className)}
{...$$restProps}
>
<slot {headingValue}>
{headingValue}
</slot>
</CalendarPrimitive.Heading>

View File

@@ -1,16 +1,20 @@
<script lang="ts"> <script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script> </script>
<div <div
bind:this={ref}
class={cn("mt-4 flex flex-col space-y-4 sm:flex-row sm:space-x-4 sm:space-y-0", className)} class={cn("mt-4 flex flex-col space-y-4 sm:flex-row sm:space-x-4 sm:space-y-0", className)}
{...$$restProps} {...restProps}
> >
<slot /> {@render children?.()}
</div> </div>

View File

@@ -1,27 +1,28 @@
<script lang="ts"> <script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui"; 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 { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = CalendarPrimitive.NextButtonProps; let {
type $$Events = CalendarPrimitive.NextButtonEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; children,
export { className as class }; ...restProps
}: CalendarPrimitive.PrevButtonProps = $props();
</script> </script>
{#snippet Fallback()}
<ChevronRight class="size-4" />
{/snippet}
<CalendarPrimitive.NextButton <CalendarPrimitive.NextButton
on:click bind:ref
class={cn( class={cn(
buttonVariants({ variant: "outline" }), buttonVariants({ variant: "outline" }),
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100", "size-7 bg-transparent p-0 opacity-50 hover:opacity-100",
className className
)} )}
{...$$restProps} children={children || Fallback}
let:builder {...restProps}
> />
<slot {builder}>
<ChevronRight class="h-4 w-4" />
</slot>
</CalendarPrimitive.NextButton>

View File

@@ -1,27 +1,28 @@
<script lang="ts"> <script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui"; 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 { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = CalendarPrimitive.PrevButtonProps; let {
type $$Events = CalendarPrimitive.PrevButtonEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; children,
export { className as class }; ...restProps
}: CalendarPrimitive.PrevButtonProps = $props();
</script> </script>
{#snippet Fallback()}
<ChevronLeft class="size-4" />
{/snippet}
<CalendarPrimitive.PrevButton <CalendarPrimitive.PrevButton
on:click bind:ref
class={cn( class={cn(
buttonVariants({ variant: "outline" }), buttonVariants({ variant: "outline" }),
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100", "size-7 bg-transparent p-0 opacity-50 hover:opacity-100",
className className
)} )}
{...$$restProps} children={children || Fallback}
let:builder {...restProps}
> />
<slot {builder}>
<ChevronLeft class="h-4 w-4" />
</slot>
</CalendarPrimitive.PrevButton>

View File

@@ -1,59 +1,61 @@
<script lang="ts"> <script lang="ts">
import { Calendar as CalendarPrimitive } from "bits-ui"; import { Calendar as CalendarPrimitive, type WithoutChildrenOrChild } from "bits-ui";
import * as Calendar from "./index.js"; import * as Calendar from "./index.js";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = CalendarPrimitive.Props; let {
ref = $bindable(null),
type $$Events = CalendarPrimitive.Events; value = $bindable(),
placeholder = $bindable(),
export let value: $$Props["value"] = undefined; class: className,
export let placeholder: $$Props["placeholder"] = undefined; weekdayFormat = "short",
export let weekdayFormat: $$Props["weekdayFormat"] = "short"; ...restProps
}: WithoutChildrenOrChild<CalendarPrimitive.RootProps> = $props();
let className: $$Props["class"] = undefined;
export { className as class };
</script> </script>
<!--
Discriminated Unions + Destructing (required for bindable) do not
get along, so we shut typescript up by casting `value` to `never`.
-->
<CalendarPrimitive.Root <CalendarPrimitive.Root
bind:value bind:value={value as never}
bind:ref
bind:placeholder bind:placeholder
{weekdayFormat} {weekdayFormat}
class={cn("p-3", className)} class={cn("p-3", className)}
{...$$restProps} {...restProps}
on:keydown
let:months
let:weekdays
> >
<Calendar.Header> {#snippet children({ months, weekdays })}
<Calendar.PrevButton /> <Calendar.Header>
<Calendar.Heading /> <Calendar.PrevButton />
<Calendar.NextButton /> <Calendar.Heading />
</Calendar.Header> <Calendar.NextButton />
<Calendar.Months> </Calendar.Header>
{#each months as month} <Calendar.Months>
<Calendar.Grid> {#each months as month (month)}
<Calendar.GridHead> <Calendar.Grid>
<Calendar.GridRow class="flex"> <Calendar.GridHead>
{#each weekdays as weekday} <Calendar.GridRow class="flex">
<Calendar.HeadCell> {#each weekdays as weekday (weekday)}
{weekday.slice(0, 2)} <Calendar.HeadCell>
</Calendar.HeadCell> {weekday.slice(0, 2)}
{/each} </Calendar.HeadCell>
</Calendar.GridRow>
</Calendar.GridHead>
<Calendar.GridBody>
{#each month.weeks as weekDates}
<Calendar.GridRow class="mt-2 w-full">
{#each weekDates as date}
<Calendar.Cell {date}>
<Calendar.Day {date} month={month.value} />
</Calendar.Cell>
{/each} {/each}
</Calendar.GridRow> </Calendar.GridRow>
{/each} </Calendar.GridHead>
</Calendar.GridBody> <Calendar.GridBody>
</Calendar.Grid> {#each month.weeks as weekDates (weekDates)}
{/each} <Calendar.GridRow class="mt-2 w-full">
</Calendar.Months> {#each weekDates as date (date)}
<Calendar.Cell {date} month={month.value}>
<Calendar.Day />
</Calendar.Cell>
{/each}
</Calendar.GridRow>
{/each}
</Calendar.GridBody>
</Calendar.Grid>
{/each}
</Calendar.Months>
{/snippet}
</CalendarPrimitive.Root> </CalendarPrimitive.Root>

View File

@@ -1,13 +1,16 @@
<script lang="ts"> <script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script> </script>
<div class={cn("p-6 pt-0", className)} {...$$restProps}> <div bind:this={ref} class={cn("p-6", className)} {...restProps}>
<slot /> {@render children?.()}
</div> </div>

View File

@@ -1,13 +1,16 @@
<script lang="ts"> <script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLParagraphElement>; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLParagraphElement>> = $props();
</script> </script>
<p class={cn("text-sm text-muted-foreground", className)} {...$$restProps}> <p bind:this={ref} class={cn("text-muted-foreground text-sm", className)} {...restProps}>
<slot /> {@render children?.()}
</p> </p>

View File

@@ -1,13 +1,16 @@
<script lang="ts"> <script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script> </script>
<div class={cn("flex items-center p-6 pt-0", className)} {...$$restProps}> <div bind:this={ref} class={cn("flex items-center p-6 pt-0", className)} {...restProps}>
<slot /> {@render children?.()}
</div> </div>

View File

@@ -1,13 +1,16 @@
<script lang="ts"> <script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script> </script>
<div class={cn("flex flex-col space-y-1.5 p-6", className)} {...$$restProps}> <div bind:this={ref} class={cn("flex flex-col space-y-1.5 p-6 pb-0", className)} {...restProps}>
<slot /> {@render children?.()}
</div> </div>

View File

@@ -1,21 +1,25 @@
<script lang="ts"> <script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import type { HeadingLevel } from "./index.js";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLHeadingElement> & { let {
tag?: HeadingLevel; ref = $bindable(null),
}; class: className,
level = 3,
let className: $$Props["class"] = undefined; children,
export let tag: $$Props["tag"] = "h3"; ...restProps
export { className as class }; }: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
level?: 1 | 2 | 3 | 4 | 5 | 6;
} = $props();
</script> </script>
<svelte:element <div
this={tag} role="heading"
class={cn("text-lg font-semibold leading-none tracking-tight", className)} aria-level={level}
{...$$restProps} bind:this={ref}
class={cn("text-2xl font-semibold leading-none tracking-tight", className)}
{...restProps}
> >
<slot /> {@render children?.()}
</svelte:element> </div>

View File

@@ -1,16 +1,20 @@
<script lang="ts"> <script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script> </script>
<div <div
class={cn("rounded-lg border bg-card text-card-foreground shadow-sm", className)} bind:this={ref}
{...$$restProps} class={cn("bg-card text-card-foreground rounded-lg border shadow-sm", className)}
{...restProps}
> >
<slot /> {@render children?.()}
</div> </div>

View File

@@ -20,5 +20,3 @@ export {
Header as CardHeader, Header as CardHeader,
Title as CardTitle, Title as CardTitle,
}; };
export type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";

View File

@@ -1,35 +1,35 @@
<script lang="ts"> <script lang="ts">
import { Checkbox as CheckboxPrimitive } from "bits-ui"; import { Checkbox as CheckboxPrimitive, type WithoutChildrenOrChild } from "bits-ui";
import Check from "lucide-svelte/icons/check"; import Check from "@lucide/svelte/icons/check";
import Minus from "lucide-svelte/icons/minus"; import Minus from "@lucide/svelte/icons/minus";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = CheckboxPrimitive.Props; let {
type $$Events = CheckboxPrimitive.Events; ref = $bindable(null),
checked = $bindable(false),
let className: $$Props["class"] = undefined; indeterminate = $bindable(false),
export let checked: $$Props["checked"] = false; class: className,
export { className as class }; ...restProps
}: WithoutChildrenOrChild<CheckboxPrimitive.RootProps> = $props();
</script> </script>
<CheckboxPrimitive.Root <CheckboxPrimitive.Root
bind:ref
class={cn( class={cn(
"peer box-content h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[disabled=true]:cursor-not-allowed data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[disabled=true]:opacity-50", "border-primary ring-offset-background focus-visible:ring-ring data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground peer box-content size-4 shrink-0 rounded-sm border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50",
className className
)} )}
bind:checked bind:checked
{...$$restProps} bind:indeterminate
on:click {...restProps}
> >
<CheckboxPrimitive.Indicator {#snippet children({ checked, indeterminate })}
class={cn("flex h-4 w-4 items-center justify-center text-current")} <div class="flex size-4 items-center justify-center text-current">
let:isChecked {#if indeterminate}
let:isIndeterminate <Minus class="size-3.5" />
> {:else}
{#if isChecked} <Check class={cn("size-3.5", !checked && "text-transparent")} />
<Check class="h-3.5 w-3.5" /> {/if}
{:else if isIndeterminate} </div>
<Minus class="h-3.5 w-3.5" /> {/snippet}
{/if}
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root> </CheckboxPrimitive.Root>

View File

@@ -1,35 +1,40 @@
<script lang="ts"> <script lang="ts">
import { ContextMenu as ContextMenuPrimitive } from "bits-ui"; import { ContextMenu as ContextMenuPrimitive, type WithoutChildrenOrChild } from "bits-ui";
import Check from "lucide-svelte/icons/check"; import Check from "@lucide/svelte/icons/check";
import Minus from "@lucide/svelte/icons/minus";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
import type { Snippet } from "svelte";
type $$Props = ContextMenuPrimitive.CheckboxItemProps; let {
type $$Events = ContextMenuPrimitive.CheckboxItemEvents; ref = $bindable(null),
checked = $bindable(false),
let className: $$Props["class"] = undefined; indeterminate = $bindable(false),
export let checked: $$Props["checked"] = undefined; class: className,
export { className as class }; children: childrenProp,
...restProps
}: WithoutChildrenOrChild<ContextMenuPrimitive.CheckboxItemProps> & {
children?: Snippet;
} = $props();
</script> </script>
<ContextMenuPrimitive.CheckboxItem <ContextMenuPrimitive.CheckboxItem
bind:ref
bind:checked bind:checked
bind:indeterminate
class={cn( 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", "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground 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-[disabled]:opacity-50",
className className
)} )}
{...$$restProps} {...restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerdown
on:pointerleave
on:pointermove
> >
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> {#snippet children({ checked, indeterminate })}
<ContextMenuPrimitive.CheckboxIndicator> <span class="absolute left-2 flex size-3.5 items-center justify-center">
<Check class="h-4 w-4" /> {#if indeterminate}
</ContextMenuPrimitive.CheckboxIndicator> <Minus class="size-3.5" />
</span> {:else}
<slot /> <Check class={cn("size-3.5", !checked && "text-transparent")} />
{/if}
</span>
{@render childrenProp?.()}
{/snippet}
</ContextMenuPrimitive.CheckboxItem> </ContextMenuPrimitive.CheckboxItem>

View File

@@ -1,24 +1,24 @@
<script lang="ts"> <script lang="ts">
import { ContextMenu as ContextMenuPrimitive } from "bits-ui"; import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = ContextMenuPrimitive.ContentProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; portalProps,
export let transition: $$Props["transition"] = flyAndScale; class: className,
export let transitionConfig: $$Props["transitionConfig"] = undefined; ...restProps
export { className as class }; }: ContextMenuPrimitive.ContentProps & {
portalProps?: ContextMenuPrimitive.PortalProps;
} = $props();
</script> </script>
<ContextMenuPrimitive.Content <ContextMenuPrimitive.Portal {...portalProps}>
{transition} <ContextMenuPrimitive.Content
{transitionConfig} bind:ref
class={cn( class={cn(
"z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none", "bg-popover text-popover-foreground z-50 min-w-[8rem] rounded-md border p-1 shadow-md focus:outline-none",
className className
)} )}
{...$$restProps} {...restProps}
on:keydown />
> </ContextMenuPrimitive.Portal>
<slot />
</ContextMenuPrimitive.Content>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
inset,
...restProps
}: ContextMenuPrimitive.GroupHeadingProps & {
inset?: boolean;
} = $props();
</script>
<ContextMenuPrimitive.GroupHeading
bind:ref
class={cn("text-foreground px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
{...restProps}
/>

View File

@@ -2,30 +2,22 @@
import { ContextMenu as ContextMenuPrimitive } from "bits-ui"; import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = ContextMenuPrimitive.ItemProps & { let {
ref = $bindable(null),
class: className,
inset,
...restProps
}: ContextMenuPrimitive.ItemProps & {
inset?: boolean; inset?: boolean;
}; } = $props();
type $$Events = ContextMenuPrimitive.ItemEvents;
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
</script> </script>
<ContextMenuPrimitive.Item <ContextMenuPrimitive.Item
bind:ref
class={cn( class={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50", "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8", inset && "pl-8",
className className
)} )}
{...$$restProps} {...restProps}
on:click />
on:keydown
on:focusin
on:focusout
on:pointerdown
on:pointerleave
on:pointermove
>
<slot />
</ContextMenuPrimitive.Item>

View File

@@ -1,35 +1,30 @@
<script lang="ts"> <script lang="ts">
import { ContextMenu as ContextMenuPrimitive } from "bits-ui"; import { ContextMenu as ContextMenuPrimitive, 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"; import { cn } from "$lib/utils.js";
type $$Props = ContextMenuPrimitive.RadioItemProps; let {
type $$Events = ContextMenuPrimitive.RadioItemEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; children: childrenProp,
export let value: ContextMenuPrimitive.RadioItemProps["value"]; ...restProps
export { className as class }; }: WithoutChild<ContextMenuPrimitive.RadioItemProps> = $props();
</script> </script>
<ContextMenuPrimitive.RadioItem <ContextMenuPrimitive.RadioItem
bind:ref
class={cn( 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", "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground 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-[disabled]:opacity-50",
className className
)} )}
{value} {...restProps}
{...$$restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerdown
on:pointerleave
on:pointermove
> >
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> {#snippet children({ checked })}
<ContextMenuPrimitive.RadioIndicator> <span class="absolute left-2 flex size-3.5 items-center justify-center">
<Circle class="h-2 w-2 fill-current" /> {#if checked}
</ContextMenuPrimitive.RadioIndicator> <Circle class="size-2 fill-current" />
</span> {/if}
<slot /> </span>
{@render childrenProp?.({ checked })}
{/snippet}
</ContextMenuPrimitive.RadioItem> </ContextMenuPrimitive.RadioItem>

View File

@@ -2,13 +2,15 @@
import { ContextMenu as ContextMenuPrimitive } from "bits-ui"; import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = ContextMenuPrimitive.SeparatorProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; ...restProps
}: ContextMenuPrimitive.SeparatorProps = $props();
</script> </script>
<ContextMenuPrimitive.Separator <ContextMenuPrimitive.Separator
class={cn("-mx-1 my-1 h-px bg-border", className)} bind:ref
{...$$restProps} class={cn("bg-border -mx-1 my-1 h-px", className)}
{...restProps}
/> />

View File

@@ -1,16 +1,20 @@
<script lang="ts"> <script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLSpanElement>; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLSpanElement>> = $props();
</script> </script>
<span <span
class={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)} bind:this={ref}
{...$$restProps} class={cn("text-muted-foreground ml-auto text-xs tracking-widest", className)}
{...restProps}
> >
<slot /> {@render children?.()}
</span> </span>

View File

@@ -1,29 +1,19 @@
<script lang="ts"> <script lang="ts">
import { ContextMenu as ContextMenuPrimitive } from "bits-ui"; import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = ContextMenuPrimitive.SubContentProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export let transition: $$Props["transition"] = flyAndScale; ...restProps
export let transitionConfig: $$Props["transitionConfig"] = { }: ContextMenuPrimitive.SubContentProps = $props();
x: -10,
y: 0,
};
export { className as class };
</script> </script>
<ContextMenuPrimitive.SubContent <ContextMenuPrimitive.SubContent
{transition} bind:ref
{transitionConfig}
class={cn( class={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none", "bg-popover text-popover-foreground z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-md focus:outline-none",
className className
)} )}
{...$$restProps} {...restProps}
on:keydown />
on:focusout
on:pointermove
>
<slot />
</ContextMenuPrimitive.SubContent>

View File

@@ -1,32 +1,28 @@
<script lang="ts"> <script lang="ts">
import { ContextMenu as ContextMenuPrimitive } from "bits-ui"; import { ContextMenu as ContextMenuPrimitive, type WithoutChild } 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"; import { cn } from "$lib/utils.js";
type $$Props = ContextMenuPrimitive.SubTriggerProps & { let {
ref = $bindable(null),
class: className,
inset,
children,
...restProps
}: WithoutChild<ContextMenuPrimitive.SubTriggerProps> & {
inset?: boolean; inset?: boolean;
}; } = $props();
type $$Events = ContextMenuPrimitive.SubTriggerEvents;
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
</script> </script>
<ContextMenuPrimitive.SubTrigger <ContextMenuPrimitive.SubTrigger
bind:ref
class={cn( class={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground", "data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none",
inset && "pl-8", inset && "pl-8",
className className
)} )}
{...$$restProps} {...restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
> >
<slot /> {@render children?.()}
<ChevronRight class="ml-auto h-4 w-4" /> <ChevronRight class="ml-auto size-4" />
</ContextMenuPrimitive.SubTrigger> </ContextMenuPrimitive.SubTrigger>

View File

@@ -1,12 +1,11 @@
import { ContextMenu as ContextMenuPrimitive } from "bits-ui"; import { ContextMenu as ContextMenuPrimitive } from "bits-ui";
import Item from "./context-menu-item.svelte"; import Item from "./context-menu-item.svelte";
import Label from "./context-menu-label.svelte"; import GroupHeading from "./context-menu-group-heading.svelte";
import Content from "./context-menu-content.svelte"; import Content from "./context-menu-content.svelte";
import Shortcut from "./context-menu-shortcut.svelte"; import Shortcut from "./context-menu-shortcut.svelte";
import RadioItem from "./context-menu-radio-item.svelte"; import RadioItem from "./context-menu-radio-item.svelte";
import Separator from "./context-menu-separator.svelte"; import Separator from "./context-menu-separator.svelte";
import RadioGroup from "./context-menu-radio-group.svelte";
import SubContent from "./context-menu-sub-content.svelte"; import SubContent from "./context-menu-sub-content.svelte";
import SubTrigger from "./context-menu-sub-trigger.svelte"; import SubTrigger from "./context-menu-sub-trigger.svelte";
import CheckboxItem from "./context-menu-checkbox-item.svelte"; import CheckboxItem from "./context-menu-checkbox-item.svelte";
@@ -15,12 +14,13 @@ const Sub = ContextMenuPrimitive.Sub;
const Root = ContextMenuPrimitive.Root; const Root = ContextMenuPrimitive.Root;
const Trigger = ContextMenuPrimitive.Trigger; const Trigger = ContextMenuPrimitive.Trigger;
const Group = ContextMenuPrimitive.Group; const Group = ContextMenuPrimitive.Group;
const RadioGroup = ContextMenuPrimitive.RadioGroup;
export { export {
Sub, Sub,
Root, Root,
Item, Item,
Label, GroupHeading,
Group, Group,
Trigger, Trigger,
Content, Content,
@@ -35,7 +35,7 @@ export {
Root as ContextMenu, Root as ContextMenu,
Sub as ContextMenuSub, Sub as ContextMenuSub,
Item as ContextMenuItem, Item as ContextMenuItem,
Label as ContextMenuLabel, GroupHeading as ContextMenuGroupHeading,
Group as ContextMenuGroup, Group as ContextMenuGroup,
Content as ContextMenuContent, Content as ContextMenuContent,
Trigger as ContextMenuTrigger, Trigger as ContextMenuTrigger,

View File

@@ -1,35 +1,40 @@
<script lang="ts"> <script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; import { DropdownMenu as DropdownMenuPrimitive, type WithoutChildrenOrChild } from "bits-ui";
import Check from "lucide-svelte/icons/check"; import Check from "@lucide/svelte/icons/check";
import Minus from "@lucide/svelte/icons/minus";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
import type { Snippet } from "svelte";
type $$Props = DropdownMenuPrimitive.CheckboxItemProps; let {
type $$Events = DropdownMenuPrimitive.CheckboxItemEvents; ref = $bindable(null),
checked = $bindable(false),
let className: $$Props["class"] = undefined; indeterminate = $bindable(false),
export let checked: $$Props["checked"] = undefined; class: className,
export { className as class }; children: childrenProp,
...restProps
}: WithoutChildrenOrChild<DropdownMenuPrimitive.CheckboxItemProps> & {
children?: Snippet;
} = $props();
</script> </script>
<DropdownMenuPrimitive.CheckboxItem <DropdownMenuPrimitive.CheckboxItem
bind:ref
bind:checked bind:checked
bind:indeterminate
class={cn( 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", "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground 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-[disabled]:opacity-50",
className className
)} )}
{...$$restProps} {...restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerdown
on:pointerleave
on:pointermove
> >
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> {#snippet children({ checked, indeterminate })}
<DropdownMenuPrimitive.CheckboxIndicator> <span class="absolute left-2 flex size-3.5 items-center justify-center">
<Check class="h-4 w-4" /> {#if indeterminate}
</DropdownMenuPrimitive.CheckboxIndicator> <Minus class="size-4" />
</span> {:else}
<slot /> <Check class={cn("size-4", !checked && "text-transparent")} />
{/if}
</span>
{@render childrenProp?.()}
{/snippet}
</DropdownMenuPrimitive.CheckboxItem> </DropdownMenuPrimitive.CheckboxItem>

View File

@@ -1,27 +1,26 @@
<script lang="ts"> <script lang="ts">
import { cn } from "$lib/utils.js";
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/utils.js";
type $$Props = DropdownMenuPrimitive.ContentProps; let {
type $$Events = DropdownMenuPrimitive.ContentEvents; ref = $bindable(null),
sideOffset = 4,
let className: $$Props["class"] = undefined; portalProps,
export let sideOffset: $$Props["sideOffset"] = 4; class: className,
export let transition: $$Props["transition"] = flyAndScale; ...restProps
export let transitionConfig: $$Props["transitionConfig"] = undefined; }: DropdownMenuPrimitive.ContentProps & {
export { className as class }; portalProps?: DropdownMenuPrimitive.PortalProps;
} = $props();
</script> </script>
<DropdownMenuPrimitive.Content <DropdownMenuPrimitive.Portal {...portalProps}>
{transition} <DropdownMenuPrimitive.Content
{transitionConfig} bind:ref
{sideOffset} {sideOffset}
class={cn( class={cn(
"z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none", "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-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-md outline-none",
className className
)} )}
{...$$restProps} {...restProps}
on:keydown />
> </DropdownMenuPrimitive.Portal>
<slot />
</DropdownMenuPrimitive.Content>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
inset,
...restProps
}: DropdownMenuPrimitive.GroupHeadingProps & {
inset?: boolean;
} = $props();
</script>
<DropdownMenuPrimitive.GroupHeading
bind:ref
class={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
{...restProps}
/>

View File

@@ -1,31 +1,23 @@
<script lang="ts"> <script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
type $$Props = DropdownMenuPrimitive.ItemProps & { let {
ref = $bindable(null),
class: className,
inset,
...restProps
}: DropdownMenuPrimitive.ItemProps & {
inset?: boolean; inset?: boolean;
}; } = $props();
type $$Events = DropdownMenuPrimitive.ItemEvents;
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
</script> </script>
<DropdownMenuPrimitive.Item <DropdownMenuPrimitive.Item
bind:ref
class={cn( class={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50", "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
inset && "pl-8", inset && "pl-8",
className className
)} )}
{...$$restProps} {...restProps}
on:click />
on:keydown
on:focusin
on:focusout
on:pointerdown
on:pointerleave
on:pointermove
>
<slot />
</DropdownMenuPrimitive.Item>

View File

@@ -1,19 +1,23 @@
<script lang="ts"> <script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
import { type WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements";
type $$Props = DropdownMenuPrimitive.LabelProps & { let {
ref = $bindable(null),
class: className,
inset,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
inset?: boolean; inset?: boolean;
}; } = $props();
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
</script> </script>
<DropdownMenuPrimitive.Label <div
bind:this={ref}
class={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)} class={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
{...$$restProps} {...restProps}
> >
<slot /> {@render children?.()}
</DropdownMenuPrimitive.Label> </div>

View File

@@ -1,35 +1,30 @@
<script lang="ts"> <script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; 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"; import { cn } from "$lib/utils.js";
type $$Props = DropdownMenuPrimitive.RadioItemProps; let {
type $$Events = DropdownMenuPrimitive.RadioItemEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; children: childrenProp,
export let value: $$Props["value"]; ...restProps
export { className as class }; }: WithoutChild<DropdownMenuPrimitive.RadioItemProps> = $props();
</script> </script>
<DropdownMenuPrimitive.RadioItem <DropdownMenuPrimitive.RadioItem
bind:ref
class={cn( 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", "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground 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-[disabled]:opacity-50",
className className
)} )}
{value} {...restProps}
{...$$restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerdown
on:pointerleave
on:pointermove
> >
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> {#snippet children({ checked })}
<DropdownMenuPrimitive.RadioIndicator> <span class="absolute left-2 flex size-3.5 items-center justify-center">
<Circle class="h-2 w-2 fill-current" /> {#if checked}
</DropdownMenuPrimitive.RadioIndicator> <Circle class="size-2 fill-current" />
</span> {/if}
<slot /> </span>
{@render childrenProp?.({ checked })}
{/snippet}
</DropdownMenuPrimitive.RadioItem> </DropdownMenuPrimitive.RadioItem>

View File

@@ -2,13 +2,15 @@
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = DropdownMenuPrimitive.SeparatorProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; ...restProps
}: DropdownMenuPrimitive.SeparatorProps = $props();
</script> </script>
<DropdownMenuPrimitive.Separator <DropdownMenuPrimitive.Separator
class={cn("-mx-1 my-1 h-px bg-muted", className)} bind:ref
{...$$restProps} class={cn("bg-muted -mx-1 my-1 h-px", className)}
{...restProps}
/> />

View File

@@ -1,13 +1,20 @@
<script lang="ts"> <script lang="ts">
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import { type WithElementRef } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLSpanElement>; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLSpanElement>> = $props();
</script> </script>
<span class={cn("ml-auto text-xs tracking-widest opacity-60", className)} {...$$restProps}> <span
<slot /> bind:this={ref}
class={cn("ml-auto text-xs tracking-widest opacity-60", className)}
{...restProps}
>
{@render children?.()}
</span> </span>

View File

@@ -1,30 +1,19 @@
<script lang="ts"> <script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = DropdownMenuPrimitive.SubContentProps; let {
type $$Events = DropdownMenuPrimitive.SubContentEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; ...restProps
export let transition: $$Props["transition"] = flyAndScale; }: DropdownMenuPrimitive.SubContentProps = $props();
export let transitionConfig: $$Props["transitionConfig"] = {
x: -10,
y: 0,
};
export { className as class };
</script> </script>
<DropdownMenuPrimitive.SubContent <DropdownMenuPrimitive.SubContent
{transition} bind:ref
{transitionConfig}
class={cn( class={cn(
"z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-lg focus:outline-none", "bg-popover text-popover-foreground z-50 min-w-[8rem] rounded-md border p-1 shadow-lg focus:outline-none",
className className
)} )}
{...$$restProps} {...restProps}
on:keydown />
on:focusout
on:pointermove
>
<slot />
</DropdownMenuPrimitive.SubContent>

View File

@@ -1,32 +1,28 @@
<script lang="ts"> <script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; 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"; import { cn } from "$lib/utils.js";
type $$Props = DropdownMenuPrimitive.SubTriggerProps & { let {
ref = $bindable(null),
class: className,
inset,
children,
...restProps
}: DropdownMenuPrimitive.SubTriggerProps & {
inset?: boolean; inset?: boolean;
}; } = $props();
type $$Events = DropdownMenuPrimitive.SubTriggerEvents;
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
</script> </script>
<DropdownMenuPrimitive.SubTrigger <DropdownMenuPrimitive.SubTrigger
bind:ref
class={cn( class={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground", "data-[highlighted]:bg-accent data-[state=open]:bg-accent flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
inset && "pl-8", inset && "pl-8",
className className
)} )}
{...$$restProps} {...restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
> >
<slot /> {@render children?.()}
<ChevronRight class="ml-auto h-4 w-4" /> <ChevronRight class="ml-auto" />
</DropdownMenuPrimitive.SubTrigger> </DropdownMenuPrimitive.SubTrigger>

View File

@@ -1,48 +1,50 @@
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import CheckboxItem from "./dropdown-menu-checkbox-item.svelte";
import Content from "./dropdown-menu-content.svelte";
import GroupHeading from "./dropdown-menu-group-heading.svelte";
import Item from "./dropdown-menu-item.svelte"; import Item from "./dropdown-menu-item.svelte";
import Label from "./dropdown-menu-label.svelte"; import Label from "./dropdown-menu-label.svelte";
import Content from "./dropdown-menu-content.svelte";
import Shortcut from "./dropdown-menu-shortcut.svelte";
import RadioItem from "./dropdown-menu-radio-item.svelte"; import RadioItem from "./dropdown-menu-radio-item.svelte";
import Separator from "./dropdown-menu-separator.svelte"; import Separator from "./dropdown-menu-separator.svelte";
import RadioGroup from "./dropdown-menu-radio-group.svelte"; import Shortcut from "./dropdown-menu-shortcut.svelte";
import SubContent from "./dropdown-menu-sub-content.svelte"; import SubContent from "./dropdown-menu-sub-content.svelte";
import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; import SubTrigger from "./dropdown-menu-sub-trigger.svelte";
import CheckboxItem from "./dropdown-menu-checkbox-item.svelte";
const Sub = DropdownMenuPrimitive.Sub; const Sub = DropdownMenuPrimitive.Sub;
const Root = DropdownMenuPrimitive.Root; const Root = DropdownMenuPrimitive.Root;
const Trigger = DropdownMenuPrimitive.Trigger; const Trigger = DropdownMenuPrimitive.Trigger;
const Group = DropdownMenuPrimitive.Group; const Group = DropdownMenuPrimitive.Group;
const RadioGroup = DropdownMenuPrimitive.RadioGroup;
export { export {
Sub,
Root,
Item,
Label,
Group,
Trigger,
Content,
Shortcut,
Separator,
RadioItem,
SubContent,
SubTrigger,
RadioGroup,
CheckboxItem, CheckboxItem,
// Content,
Root as DropdownMenu, Root as DropdownMenu,
Sub as DropdownMenuSub, CheckboxItem as DropdownMenuCheckboxItem,
Content as DropdownMenuContent,
Group as DropdownMenuGroup,
GroupHeading as DropdownMenuGroupHeading,
Item as DropdownMenuItem, Item as DropdownMenuItem,
Label as DropdownMenuLabel, Label as DropdownMenuLabel,
Group as DropdownMenuGroup, RadioGroup as DropdownMenuRadioGroup,
Content as DropdownMenuContent,
Trigger as DropdownMenuTrigger,
Shortcut as DropdownMenuShortcut,
RadioItem as DropdownMenuRadioItem, RadioItem as DropdownMenuRadioItem,
Separator as DropdownMenuSeparator, Separator as DropdownMenuSeparator,
RadioGroup as DropdownMenuRadioGroup, Shortcut as DropdownMenuShortcut,
Sub as DropdownMenuSub,
SubContent as DropdownMenuSubContent, SubContent as DropdownMenuSubContent,
SubTrigger as DropdownMenuSubTrigger, SubTrigger as DropdownMenuSubTrigger,
CheckboxItem as DropdownMenuCheckboxItem, Trigger as DropdownMenuTrigger,
Group,
GroupHeading,
Item,
Label,
RadioGroup,
RadioItem,
Root,
Separator,
Shortcut,
Sub,
SubContent,
SubTrigger,
Trigger,
}; };

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,
Content,
Trigger,
//
Root as Collapsible,
Content as CollapsibleContent,
Trigger as CollapsibleTrigger,
};

View File

@@ -1,27 +1,5 @@
import Root from "./input.svelte"; import Root from "./input.svelte";
export type FormInputEvent<T extends Event = Event> = T & {
currentTarget: EventTarget & HTMLInputElement;
};
export type InputEvents = {
blur: FormInputEvent<FocusEvent>;
change: FormInputEvent<Event>;
click: FormInputEvent<MouseEvent>;
focus: FormInputEvent<FocusEvent>;
focusin: FormInputEvent<FocusEvent>;
focusout: FormInputEvent<FocusEvent>;
keydown: FormInputEvent<KeyboardEvent>;
keypress: FormInputEvent<KeyboardEvent>;
keyup: FormInputEvent<KeyboardEvent>;
mouseover: FormInputEvent<MouseEvent>;
mouseenter: FormInputEvent<MouseEvent>;
mouseleave: FormInputEvent<MouseEvent>;
mousemove: FormInputEvent<MouseEvent>;
paste: FormInputEvent<ClipboardEvent>;
input: FormInputEvent<InputEvent>;
wheel: FormInputEvent<WheelEvent>;
};
export { export {
Root, Root,
// //

View File

@@ -1,42 +1,46 @@
<script lang="ts"> <script lang="ts">
import type { HTMLInputAttributes } from "svelte/elements"; import type { HTMLInputAttributes, HTMLInputTypeAttribute } from "svelte/elements";
import type { InputEvents } from "./index.js"; import type { WithElementRef } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLInputAttributes; type InputType = Exclude<HTMLInputTypeAttribute, "file">;
type $$Events = InputEvents;
let className: $$Props["class"] = undefined; type Props = WithElementRef<
export let value: $$Props["value"] = undefined; Omit<HTMLInputAttributes, "type"> &
export { className as class }; ({ type: "file"; files?: FileList } | { type?: InputType; files?: undefined })
>;
// Workaround for https://github.com/sveltejs/svelte/issues/9305 let {
// Fixed in Svelte 5, but not backported to 4.x. ref = $bindable(null),
export let readonly: $$Props["readonly"] = undefined; value = $bindable(),
type,
files = $bindable(),
class: className,
...restProps
}: Props = $props();
</script> </script>
<input {#if type === "file"}
class={cn( <input
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", bind:this={ref}
className class={cn(
)} "border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-base file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
bind:value className
{readonly} )}
on:blur type="file"
on:change bind:files
on:click bind:value
on:focus {...restProps}
on:focusin />
on:focusout {:else}
on:keydown <input
on:keypress bind:this={ref}
on:keyup class={cn(
on:mouseover "border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-base file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
on:mouseenter className
on:mouseleave )}
on:mousemove {type}
on:paste bind:value
on:input {...restProps}
on:wheel|passive />
{...$$restProps} {/if}
/>

View File

@@ -2,20 +2,18 @@
import { Label as LabelPrimitive } from "bits-ui"; import { Label as LabelPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = LabelPrimitive.Props; let {
type $$Events = LabelPrimitive.Events; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; ...restProps
export { className as class }; }: LabelPrimitive.RootProps = $props();
</script> </script>
<LabelPrimitive.Root <LabelPrimitive.Root
bind:ref
class={cn( class={cn(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
className className
)} )}
{...$$restProps} {...restProps}
on:mousedown />
>
<slot />
</LabelPrimitive.Root>

View File

@@ -1,10 +1,9 @@
import { Menubar as MenubarPrimitive } from "bits-ui"; import { Menubar as MenubarPrimitive } from "bits-ui";
import Root from "./menubar.svelte"; import Root from "./menubar.svelte";
import CheckboxItem from "./menubar-checkbox-item.svelte"; import CheckboxItem from "./menubar-checkbox-item.svelte";
import Content from "./menubar-content.svelte"; import Content from "./menubar-content.svelte";
import Item from "./menubar-item.svelte"; import Item from "./menubar-item.svelte";
import Label from "./menubar-label.svelte"; import GroupHeading from "./menubar-group-heading.svelte";
import RadioItem from "./menubar-radio-item.svelte"; import RadioItem from "./menubar-radio-item.svelte";
import Separator from "./menubar-separator.svelte"; import Separator from "./menubar-separator.svelte";
import Shortcut from "./menubar-shortcut.svelte"; import Shortcut from "./menubar-shortcut.svelte";
@@ -22,7 +21,7 @@ export {
CheckboxItem, CheckboxItem,
Content, Content,
Item, Item,
Label, GroupHeading,
RadioItem, RadioItem,
Separator, Separator,
Shortcut, Shortcut,
@@ -38,7 +37,7 @@ export {
CheckboxItem as MenubarCheckboxItem, CheckboxItem as MenubarCheckboxItem,
Content as MenubarContent, Content as MenubarContent,
Item as MenubarItem, Item as MenubarItem,
Label as MenubarLabel, GroupHeading as MenubarGroupHeading,
RadioItem as MenubarRadioItem, RadioItem as MenubarRadioItem,
Separator as MenubarSeparator, Separator as MenubarSeparator,
Shortcut as MenubarShortcut, Shortcut as MenubarShortcut,

View File

@@ -1,35 +1,40 @@
<script lang="ts"> <script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui"; import { Menubar as MenubarPrimitive, type WithoutChildrenOrChild } from "bits-ui";
import Check from "lucide-svelte/icons/check"; import Check from "@lucide/svelte/icons/check";
import Minus from "@lucide/svelte/icons/minus";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
import type { Snippet } from "svelte";
type $$Props = MenubarPrimitive.CheckboxItemProps; let {
type $$Events = MenubarPrimitive.CheckboxItemEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; checked = $bindable(false),
export let checked: $$Props["checked"] = false; indeterminate = $bindable(false),
export { className as class }; children: childrenProp,
...restProps
}: WithoutChildrenOrChild<MenubarPrimitive.CheckboxItemProps> & {
children?: Snippet;
} = $props();
</script> </script>
<MenubarPrimitive.CheckboxItem <MenubarPrimitive.CheckboxItem
bind:ref
bind:checked bind:checked
bind:indeterminate
class={cn( 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", "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground 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-[disabled]:opacity-50",
className className
)} )}
on:click {...restProps}
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
on:pointerdown
{...$$restProps}
> >
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> {#snippet children({ checked, indeterminate })}
<MenubarPrimitive.CheckboxIndicator> <span class="absolute left-2 flex size-3.5 items-center justify-center">
<Check class="h-4 w-4" /> {#if indeterminate}
</MenubarPrimitive.CheckboxIndicator> <Minus class="size-4" />
</span> {:else}
<slot /> <Check class={cn("size-4", !checked && "text-transparent")} />
{/if}
</span>
{@render childrenProp?.()}
{/snippet}
</MenubarPrimitive.CheckboxItem> </MenubarPrimitive.CheckboxItem>

View File

@@ -1,33 +1,32 @@
<script lang="ts"> <script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui"; import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.ContentProps; let {
type $$Events = MenubarPrimitive.ContentEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; sideOffset = 8,
export let sideOffset: $$Props["sideOffset"] = 8; alignOffset = -4,
export let alignOffset: $$Props["alignOffset"] = -4; align = "start",
export let align: $$Props["align"] = "start"; side = "bottom",
export let side: $$Props["side"] = "bottom"; portalProps,
export let transition: $$Props["transition"] = flyAndScale; ...restProps
export let transitionConfig: $$Props["transitionConfig"] = undefined; }: MenubarPrimitive.ContentProps & {
export { className as class }; portalProps?: MenubarPrimitive.PortalProps;
} = $props();
</script> </script>
<MenubarPrimitive.Content <MenubarPrimitive.Portal {...portalProps}>
{transition} <MenubarPrimitive.Content
{transitionConfig} bind:ref
{sideOffset} {sideOffset}
{align} {align}
{alignOffset} {alignOffset}
{side} {side}
class={cn( class={cn(
"z-50 min-w-[12rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none", "bg-popover text-popover-foreground z-50 min-w-[12rem] rounded-md border p-1 shadow-md focus:outline-none",
className className
)} )}
{...$$restProps} {...restProps}
on:keydown />
> </MenubarPrimitive.Portal>
<slot />
</MenubarPrimitive.Content>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
inset = undefined,
...restProps
}: MenubarPrimitive.GroupHeadingProps & {
inset?: boolean;
} = $props();
</script>
<MenubarPrimitive.GroupHeading
bind:ref
class={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
{...restProps}
/>

View File

@@ -2,30 +2,22 @@
import { Menubar as MenubarPrimitive } from "bits-ui"; import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.ItemProps & { let {
ref = $bindable(null),
class: className,
inset = undefined,
...restProps
}: MenubarPrimitive.ItemProps & {
inset?: boolean; inset?: boolean;
}; } = $props();
type $$Events = MenubarPrimitive.ItemEvents;
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
</script> </script>
<MenubarPrimitive.Item <MenubarPrimitive.Item
bind:ref
class={cn( class={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50", "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8", inset && "pl-8",
className className
)} )}
{...$$restProps} {...restProps}
on:click />
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
on:pointerdown
>
<slot />
</MenubarPrimitive.Item>

View File

@@ -1,35 +1,30 @@
<script lang="ts"> <script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui"; import { Menubar as MenubarPrimitive, 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"; import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.RadioItemProps; let {
type $$Events = MenubarPrimitive.RadioItemEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; children: childrenProp,
export let value: $$Props["value"]; ...restProps
export { className as class }; }: WithoutChild<MenubarPrimitive.RadioItemProps> = $props();
</script> </script>
<MenubarPrimitive.RadioItem <MenubarPrimitive.RadioItem
{value} bind:ref
class={cn( 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", "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground 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-[disabled]:opacity-50",
className className
)} )}
{...$$restProps} {...restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
on:pointerdown
> >
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> {#snippet children({ checked })}
<MenubarPrimitive.RadioIndicator> <span class="absolute left-2 flex size-3.5 items-center justify-center">
<Circle class="h-2 w-2 fill-current" /> {#if checked}
</MenubarPrimitive.RadioIndicator> <Circle class="size-2 fill-current" />
</span> {/if}
<slot /> </span>
{@render childrenProp?.({ checked })}
{/snippet}
</MenubarPrimitive.RadioItem> </MenubarPrimitive.RadioItem>

View File

@@ -2,10 +2,15 @@
import { Menubar as MenubarPrimitive } from "bits-ui"; import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.SeparatorProps; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; ...restProps
}: MenubarPrimitive.SeparatorProps = $props();
</script> </script>
<MenubarPrimitive.Separator class={cn("-mx-1 my-1 h-px bg-muted", className)} {...$$restProps} /> <MenubarPrimitive.Separator
bind:ref
class={cn("bg-muted -mx-1 my-1 h-px", className)}
{...restProps}
/>

View File

@@ -1,16 +1,20 @@
<script lang="ts"> <script lang="ts">
import type { HTMLAttributes } from "svelte/elements"; import type { HTMLAttributes } from "svelte/elements";
import type { WithElementRef } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLSpanElement>; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLSpanElement>> = $props();
</script> </script>
<span <span
class={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)} bind:this={ref}
{...$$restProps} class={cn("text-muted-foreground ml-auto text-xs tracking-widest", className)}
{...restProps}
> >
<slot /> {@render children?.()}
</span> </span>

View File

@@ -1,27 +1,19 @@
<script lang="ts"> <script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui"; import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.SubContentProps; let {
type $$Events = MenubarPrimitive.SubContentEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; ...restProps
export let transition: $$Props["transition"] = flyAndScale; }: MenubarPrimitive.SubContentProps = $props();
export let transitionConfig: $$Props["transitionConfig"] = { x: -10, y: 0 };
export { className as class };
</script> </script>
<MenubarPrimitive.SubContent <MenubarPrimitive.SubContent
{transition} bind:ref
{transitionConfig}
class={cn( class={cn(
"z-50 min-w-max rounded-md border bg-popover p-1 text-popover-foreground focus:outline-none", "bg-popover text-popover-foreground z-50 min-w-max rounded-md border p-1 focus:outline-none",
className className
)} )}
{...$$restProps} {...restProps}
on:focusout />
on:pointermove
on:keydown
>
<slot />
</MenubarPrimitive.SubContent>

View File

@@ -1,32 +1,28 @@
<script lang="ts"> <script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui"; import { Menubar as MenubarPrimitive, type WithoutChild } 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"; import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.SubTriggerProps & { let {
ref = $bindable(null),
class: className,
inset = undefined,
children,
...restProps
}: WithoutChild<MenubarPrimitive.SubTriggerProps> & {
inset?: boolean; inset?: boolean;
}; } = $props();
type $$Events = MenubarPrimitive.SubTriggerEvents;
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
</script> </script>
<MenubarPrimitive.SubTrigger <MenubarPrimitive.SubTrigger
bind:ref
class={cn( class={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground data-[disabled]:opacity-50", "data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8", inset && "pl-8",
className className
)} )}
on:click {...restProps}
{...$$restProps}
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
> >
<slot /> {@render children?.()}
<ChevronRight class="ml-auto h-4 w-4" /> <ChevronRight class="ml-auto size-4" />
</MenubarPrimitive.SubTrigger> </MenubarPrimitive.SubTrigger>

View File

@@ -2,22 +2,18 @@
import { Menubar as MenubarPrimitive } from "bits-ui"; import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.TriggerProps; let {
type $$Events = MenubarPrimitive.TriggerEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; ...restProps
export { className as class }; }: MenubarPrimitive.TriggerProps = $props();
</script> </script>
<MenubarPrimitive.Trigger <MenubarPrimitive.Trigger
bind:ref
class={cn( class={cn(
"flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground", "data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none",
className className
)} )}
on:click {...restProps}
on:keydown />
on:pointerenter
{...$$restProps}
>
<slot />
</MenubarPrimitive.Trigger>

View File

@@ -2,15 +2,15 @@
import { Menubar as MenubarPrimitive } from "bits-ui"; import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.Props; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export { className as class }; ...restProps
}: MenubarPrimitive.RootProps = $props();
</script> </script>
<MenubarPrimitive.Root <MenubarPrimitive.Root
class={cn("flex h-10 items-center space-x-1 rounded-md border bg-background p-1", className)} bind:ref
{...$$restProps} class={cn("bg-background flex h-10 items-center space-x-1 rounded-md border p-1", className)}
> {...restProps}
<slot /> />
</MenubarPrimitive.Root>

View File

@@ -1,22 +1,28 @@
<script lang="ts"> <script lang="ts">
import { cn } from "$lib/utils.js";
import { Popover as PopoverPrimitive } from "bits-ui"; import { Popover as PopoverPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/utils.js";
type $$Props = PopoverPrimitive.ContentProps; let {
let className: $$Props["class"] = undefined; ref = $bindable(null),
export let transition: $$Props["transition"] = flyAndScale; class: className,
export let transitionConfig: $$Props["transitionConfig"] = undefined; sideOffset = 4,
export { className as class }; align = "center",
portalProps,
...restProps
}: PopoverPrimitive.ContentProps & {
portalProps?: PopoverPrimitive.PortalProps;
} = $props();
</script> </script>
<PopoverPrimitive.Content <PopoverPrimitive.Portal {...portalProps}>
{transition} <PopoverPrimitive.Content
{transitionConfig} bind:ref
class={cn( {sideOffset}
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none", {align}
className 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-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 rounded-md border p-4 shadow-md outline-none",
{...$$restProps} className
> )}
<slot /> {...restProps}
</PopoverPrimitive.Content> />
</PopoverPrimitive.Portal>

View File

@@ -1,15 +1,10 @@
import { RadioGroup as RadioGroupPrimitive } from "bits-ui";
import Root from "./radio-group.svelte"; import Root from "./radio-group.svelte";
import Item from "./radio-group-item.svelte"; import Item from "./radio-group-item.svelte";
const Input = RadioGroupPrimitive.Input;
export { export {
Root, Root,
Input,
Item, Item,
// //
Root as RadioGroup, Root as RadioGroup,
Input as RadioGroupInput,
Item as RadioGroupItem, Item as RadioGroupItem,
}; };

View File

@@ -1,28 +1,28 @@
<script lang="ts"> <script lang="ts">
import { RadioGroup as RadioGroupPrimitive } from "bits-ui"; import { RadioGroup as RadioGroupPrimitive, type WithoutChildrenOrChild } from "bits-ui";
import Circle from "lucide-svelte/icons/circle"; import Circle from "@lucide/svelte/icons/circle";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = RadioGroupPrimitive.ItemProps; let {
type $$Events = RadioGroupPrimitive.ItemEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; ...restProps
export let value: $$Props["value"]; }: WithoutChildrenOrChild<RadioGroupPrimitive.ItemProps> = $props();
export { className as class };
</script> </script>
<RadioGroupPrimitive.Item <RadioGroupPrimitive.Item
{value} bind:ref
class={cn( class={cn(
"aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", "border-primary text-primary ring-offset-background focus-visible:ring-ring aspect-square size-4 rounded-full border focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className className
)} )}
{...$$restProps} {...restProps}
on:click
> >
<div class="flex items-center justify-center"> {#snippet children({ checked })}
<RadioGroupPrimitive.ItemIndicator> <div class="flex items-center justify-center">
<Circle class="h-2.5 w-2.5 fill-current text-current" /> {#if checked}
</RadioGroupPrimitive.ItemIndicator> <Circle class="size-2.5 fill-current text-current" />
</div> {/if}
</div>
{/snippet}
</RadioGroupPrimitive.Item> </RadioGroupPrimitive.Item>

View File

@@ -2,13 +2,12 @@
import { RadioGroup as RadioGroupPrimitive } from "bits-ui"; import { RadioGroup as RadioGroupPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = RadioGroupPrimitive.Props; let {
ref = $bindable(null),
let className: $$Props["class"] = undefined; class: className,
export let value: $$Props["value"] = undefined; value = $bindable(""),
export { className as class }; ...restProps
}: RadioGroupPrimitive.RootProps = $props();
</script> </script>
<RadioGroupPrimitive.Root bind:value class={cn("grid gap-2", className)} {...$$restProps}> <RadioGroupPrimitive.Root bind:ref bind:value class={cn("grid gap-2", className)} {...restProps} />
<slot />
</RadioGroupPrimitive.Root>

View File

@@ -1,17 +1,18 @@
<script lang="ts"> <script lang="ts">
import { ScrollArea as ScrollAreaPrimitive } from "bits-ui"; import { ScrollArea as ScrollAreaPrimitive, type WithoutChild } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = ScrollAreaPrimitive.ScrollbarProps & { let {
orientation?: "vertical" | "horizontal"; ref = $bindable(null),
}; class: className,
orientation = "vertical",
let className: $$Props["class"] = undefined; children,
export let orientation: $$Props["orientation"] = "vertical"; ...restProps
export { className as class }; }: WithoutChild<ScrollAreaPrimitive.ScrollbarProps> = $props();
</script> </script>
<ScrollAreaPrimitive.Scrollbar <ScrollAreaPrimitive.Scrollbar
bind:ref
{orientation} {orientation}
class={cn( class={cn(
"flex touch-none select-none transition-colors", "flex touch-none select-none transition-colors",
@@ -19,9 +20,10 @@
orientation === "horizontal" && "h-2.5 w-full border-t border-t-transparent p-px", orientation === "horizontal" && "h-2.5 w-full border-t border-t-transparent p-px",
className className
)} )}
{...restProps}
> >
<slot /> {@render children?.()}
<ScrollAreaPrimitive.Thumb <ScrollAreaPrimitive.Thumb
class={cn("relative rounded-full bg-border", orientation === "vertical" && "flex-1")} class={cn("bg-border relative rounded-full", orientation === "vertical" && "flex-1")}
/> />
</ScrollAreaPrimitive.Scrollbar> </ScrollAreaPrimitive.Scrollbar>

View File

@@ -1,33 +1,31 @@
<script lang="ts"> <script lang="ts">
import { ScrollArea as ScrollAreaPrimitive } from 'bits-ui'; import { ScrollArea as ScrollAreaPrimitive, type WithoutChild } from "bits-ui";
import { Scrollbar } from './index.js'; import { Scrollbar } from "./index.js";
import { cn } from '$lib/utils.js'; import { cn } from "$lib/utils.js";
type $$Props = ScrollAreaPrimitive.Props & { let {
orientation?: 'vertical' | 'horizontal' | 'both'; ref = $bindable(null),
scrollbarXClasses?: string; class: className,
scrollbarYClasses?: string; orientation = "vertical",
viewportClasses?: string; scrollbarXClasses = "",
}; scrollbarYClasses = "",
children,
let className: $$Props['class'] = undefined; ...restProps
export { className as class }; }: WithoutChild<ScrollAreaPrimitive.RootProps> & {
export let orientation = 'vertical'; orientation?: "vertical" | "horizontal" | "both" | undefined;
export let scrollbarXClasses: string = ''; scrollbarXClasses?: string | undefined;
export let scrollbarYClasses: string = ''; scrollbarYClasses?: string | undefined;
export let viewportClasses: string = ''; } = $props();
</script> </script>
<ScrollAreaPrimitive.Root {...$$restProps} class={cn('relative overflow-hidden', className)}> <ScrollAreaPrimitive.Root bind:ref {...restProps} class={cn("relative overflow-hidden", className)}>
<ScrollAreaPrimitive.Viewport class={cn('h-full w-full rounded-[inherit]', viewportClasses)}> <ScrollAreaPrimitive.Viewport class="h-full w-full rounded-[inherit]">
<ScrollAreaPrimitive.Content> {@render children?.()}
<slot />
</ScrollAreaPrimitive.Content>
</ScrollAreaPrimitive.Viewport> </ScrollAreaPrimitive.Viewport>
{#if orientation === 'vertical' || orientation === 'both'} {#if orientation === "vertical" || orientation === "both"}
<Scrollbar orientation="vertical" class={scrollbarYClasses} /> <Scrollbar orientation="vertical" class={scrollbarYClasses} />
{/if} {/if}
{#if orientation === 'horizontal' || orientation === 'both'} {#if orientation === "horizontal" || orientation === "both"}
<Scrollbar orientation="horizontal" class={scrollbarXClasses} /> <Scrollbar orientation="horizontal" class={scrollbarXClasses} />
{/if} {/if}
<ScrollAreaPrimitive.Corner /> <ScrollAreaPrimitive.Corner />

View File

@@ -1,34 +1,34 @@
import { Select as SelectPrimitive } from "bits-ui"; import { Select as SelectPrimitive } from "bits-ui";
import Label from "./select-label.svelte"; import GroupHeading from "./select-group-heading.svelte";
import Item from "./select-item.svelte"; import Item from "./select-item.svelte";
import Content from "./select-content.svelte"; import Content from "./select-content.svelte";
import Trigger from "./select-trigger.svelte"; import Trigger from "./select-trigger.svelte";
import Separator from "./select-separator.svelte"; import Separator from "./select-separator.svelte";
import ScrollDownButton from "./select-scroll-down-button.svelte";
import ScrollUpButton from "./select-scroll-up-button.svelte";
const Root = SelectPrimitive.Root; const Root = SelectPrimitive.Root;
const Group = SelectPrimitive.Group; const Group = SelectPrimitive.Group;
const Input = SelectPrimitive.Input;
const Value = SelectPrimitive.Value;
export { export {
Root, Root,
Group, Group,
Input, GroupHeading,
Label,
Item, Item,
Value,
Content, Content,
Trigger, Trigger,
Separator, Separator,
ScrollDownButton,
ScrollUpButton,
// //
Root as Select, Root as Select,
Group as SelectGroup, Group as SelectGroup,
Input as SelectInput, GroupHeading as SelectGroupHeading,
Label as SelectLabel,
Item as SelectItem, Item as SelectItem,
Value as SelectValue,
Content as SelectContent, Content as SelectContent,
Trigger as SelectTrigger, Trigger as SelectTrigger,
Separator as SelectSeparator, Separator as SelectSeparator,
ScrollDownButton as SelectScrollDownButton,
ScrollUpButton as SelectScrollUpButton,
}; };

View File

@@ -1,39 +1,39 @@
<script lang="ts"> <script lang="ts">
import { Select as SelectPrimitive } from "bits-ui"; import { Select as SelectPrimitive, type WithoutChild } from "bits-ui";
import { scale } from "svelte/transition"; import SelectScrollUpButton from "./select-scroll-up-button.svelte";
import { cn, flyAndScale } from "$lib/utils.js"; import SelectScrollDownButton from "./select-scroll-down-button.svelte";
import { cn } from "$lib/utils.js";
type $$Props = SelectPrimitive.ContentProps; let {
type $$Events = SelectPrimitive.ContentEvents; ref = $bindable(null),
class: className,
export let sideOffset: $$Props["sideOffset"] = 4; sideOffset = 4,
export let inTransition: $$Props["inTransition"] = flyAndScale; portalProps,
export let inTransitionConfig: $$Props["inTransitionConfig"] = undefined; children,
export let outTransition: $$Props["outTransition"] = scale; ...restProps
export let outTransitionConfig: $$Props["outTransitionConfig"] = { }: WithoutChild<SelectPrimitive.ContentProps> & {
start: 0.95, portalProps?: SelectPrimitive.PortalProps;
opacity: 0, } = $props();
duration: 50,
};
let className: $$Props["class"] = undefined;
export { className as class };
</script> </script>
<SelectPrimitive.Content <SelectPrimitive.Portal {...portalProps}>
{inTransition} <SelectPrimitive.Content
{inTransitionConfig} bind:ref
{outTransition} {sideOffset}
{outTransitionConfig} class={cn(
{sideOffset} "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 bg-popover text-popover-foreground relative z-50 max-h-96 min-w-[8rem] overflow-hidden 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",
class={cn( className
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md outline-none", )}
className {...restProps}
)} >
{...$$restProps} <SelectScrollUpButton />
on:keydown <SelectPrimitive.Viewport
> class={cn(
<div class="w-full p-1"> "h-[var(--bits-select-anchor-height)] w-full min-w-[var(--bits-select-anchor-width)] p-1"
<slot /> )}
</div> >
</SelectPrimitive.Content> {@render children?.()}
</SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>

View File

@@ -0,0 +1,16 @@
<script lang="ts">
import { Select as SelectPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
class: className,
...restProps
}: SelectPrimitive.GroupHeadingProps = $props();
</script>
<SelectPrimitive.GroupHeading
bind:ref
class={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
{...restProps}
/>

View File

@@ -1,40 +1,37 @@
<script lang="ts"> <script lang="ts">
import Check from "lucide-svelte/icons/check"; import Check from "@lucide/svelte/icons/check";
import { Select as SelectPrimitive } from "bits-ui"; import { Select as SelectPrimitive, type WithoutChild } from "bits-ui";
import { cn } from "$lib/utils.js"; import { cn } from "$lib/utils.js";
type $$Props = SelectPrimitive.ItemProps; let {
type $$Events = SelectPrimitive.ItemEvents; ref = $bindable(null),
class: className,
let className: $$Props["class"] = undefined; value,
export let value: $$Props["value"]; label,
export let label: $$Props["label"] = undefined; children: childrenProp,
export let disabled: $$Props["disabled"] = undefined; ...restProps
export { className as class }; }: WithoutChild<SelectPrimitive.ItemProps> = $props();
</script> </script>
<SelectPrimitive.Item <SelectPrimitive.Item
bind:ref
{value} {value}
{disabled}
{label}
class={cn( class={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50", "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex w-full 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-[disabled]:opacity-50",
className className
)} )}
{...$$restProps} {...restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
> >
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> {#snippet children({ selected, highlighted })}
<SelectPrimitive.ItemIndicator> <span class="absolute left-2 flex size-3.5 items-center justify-center">
<Check class="h-4 w-4" /> {#if selected}
</SelectPrimitive.ItemIndicator> <Check class="size-4" />
</span> {/if}
<slot> </span>
{label || value} {#if childrenProp}
</slot> {@render childrenProp({ selected, highlighted })}
{:else}
{label || value}
{/if}
{/snippet}
</SelectPrimitive.Item> </SelectPrimitive.Item>

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