added svelte-shadcn
This commit is contained in:
@@ -18,6 +18,13 @@ module.exports = {
|
||||
args: 'after-used',
|
||||
argsIgnorePattern: '^_'
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"argsIgnorePattern": "^_",
|
||||
"varsIgnorePattern": "^\$\$(Props|Events|Slots|Generic)$"
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: ['svelte3', '@typescript-eslint', 'unused-imports'],
|
||||
|
13
components.json
Normal file
13
components.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "https://shadcn-svelte.com/schema.json",
|
||||
"style": "default",
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.ts",
|
||||
"css": "src/styles.pcss",
|
||||
"baseColor": "zinc"
|
||||
},
|
||||
"aliases": {
|
||||
"components": "$lib/components",
|
||||
"utils": "$lib/utils"
|
||||
}
|
||||
}
|
85
package.json
85
package.json
@@ -29,48 +29,63 @@
|
||||
"src/**/*.{js,ts,svelte,css,scss,postcss,md,json}": "prettier --write --ignore-unknown"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.26.1",
|
||||
"@fontsource/roboto": "^4.5.8",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.4.0",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.4.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^2.2.0",
|
||||
"@tauri-apps/api": "^1.3.0",
|
||||
"@tauri-apps/cli": "^1.3.1",
|
||||
"@tsconfig/svelte": "^4.0.1",
|
||||
"@types/node": "18.15.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.6",
|
||||
"@typescript-eslint/parser": "^5.59.6",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"daisyui": "^2.51.6",
|
||||
"eslint": "^8.40.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"@changesets/cli": "^2.27.1",
|
||||
"@fontsource/roboto": "^5.0.8",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.5.1",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.5.1",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.5.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.1",
|
||||
"@tauri-apps/api": "^1.5.3",
|
||||
"@tauri-apps/cli": "^1.5.9",
|
||||
"@tsconfig/svelte": "^5.0.2",
|
||||
"@types/node": "20.11.5",
|
||||
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
||||
"@typescript-eslint/parser": "^6.19.0",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-json": "^3.1.0",
|
||||
"eslint-plugin-svelte3": "^4.0.0",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"eslint-plugin-unused-imports": "^3.0.0",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^13.2.2",
|
||||
"postcss": "^8.4.23",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-svelte": "^2.10.0",
|
||||
"prettier-plugin-tailwindcss": "^0.3.0",
|
||||
"svelte": "^3.59.1",
|
||||
"svelte-check": "^3.3.2",
|
||||
"svelte-fa": "^3.0.3",
|
||||
"svelte-preprocess": "^5.0.3",
|
||||
"svelte-spa-router": "^3.3.0",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"lint-staged": "^15.2.0",
|
||||
"postcss": "^8.4.33",
|
||||
"postcss-load-config": "^5.0.2",
|
||||
"prettier": "^3.2.4",
|
||||
"prettier-plugin-svelte": "^3.1.2",
|
||||
"prettier-plugin-tailwindcss": "^0.5.11",
|
||||
"svelte": "^4.2.9",
|
||||
"svelte-check": "^3.6.3",
|
||||
"svelte-fa": "^4.0.2",
|
||||
"svelte-preprocess": "^5.1.3",
|
||||
"svelte-spa-router": "^4.0.1",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"tailwindcss-hero-patterns": "^0.1.2",
|
||||
"tslib": "^2.5.1",
|
||||
"typescript": "^5.0.4",
|
||||
"vite": "^4.3.7"
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.0.11"
|
||||
},
|
||||
"packageManager": "pnpm@8.5.0",
|
||||
"engineStrict": true,
|
||||
"engineStrict": false,
|
||||
"engines": {
|
||||
"pnpm": ">=8.5.0",
|
||||
"node": ">18.0.0 <19.0.0"
|
||||
"node": ">20.0.0 <21.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@internationalized/date": "^3.5.1",
|
||||
"bits-ui": "^0.14.0",
|
||||
"clsx": "^2.1.0",
|
||||
"cmdk-sv": "^0.0.13",
|
||||
"embla-carousel-svelte": "8.0.0-rc19",
|
||||
"formsnap": "^0.4.2",
|
||||
"lucide-svelte": "^0.312.0",
|
||||
"mode-watcher": "^0.1.2",
|
||||
"svelte-sonner": "^0.3.11",
|
||||
"sveltekit-superforms": "^1.13.3",
|
||||
"tailwind-merge": "^2.2.0",
|
||||
"tailwind-variants": "^0.1.20",
|
||||
"vaul-svelte": "^0.0.7",
|
||||
"zod": "^3.22.4"
|
||||
}
|
||||
}
|
||||
|
2271
pnpm-lock.yaml
generated
2271
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
24
src/lib/components/ui/accordion/accordion-content.svelte
Normal file
24
src/lib/components/ui/accordion/accordion-content.svelte
Normal file
@@ -0,0 +1,24 @@
|
||||
<script lang="ts">
|
||||
import { Accordion as AccordionPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
import { slide } from 'svelte/transition';
|
||||
|
||||
type $$Props = AccordionPrimitive.ContentProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let transition: $$Props['transition'] = slide;
|
||||
export let transitionConfig: $$Props['transitionConfig'] = {
|
||||
duration: 200
|
||||
};
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AccordionPrimitive.Content
|
||||
class={cn('overflow-hidden text-sm transition-all', className)}
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
{...$$restProps}>
|
||||
<div class="pb-4 pt-0">
|
||||
<slot />
|
||||
</div>
|
||||
</AccordionPrimitive.Content>
|
17
src/lib/components/ui/accordion/accordion-item.svelte
Normal file
17
src/lib/components/ui/accordion/accordion-item.svelte
Normal file
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { Accordion as AccordionPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = AccordionPrimitive.ItemProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let value: $$Props['value'];
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AccordionPrimitive.Item
|
||||
{value}
|
||||
class={cn('border-b', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</AccordionPrimitive.Item>
|
25
src/lib/components/ui/accordion/accordion-trigger.svelte
Normal file
25
src/lib/components/ui/accordion/accordion-trigger.svelte
Normal file
@@ -0,0 +1,25 @@
|
||||
<script lang="ts">
|
||||
import { Accordion as AccordionPrimitive } from 'bits-ui';
|
||||
import { ChevronDown } from 'lucide-svelte';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = AccordionPrimitive.TriggerProps;
|
||||
type $$Events = AccordionPrimitive.TriggerEvents;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let level: AccordionPrimitive.HeaderProps['level'] = 3;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AccordionPrimitive.Header {level} class="flex">
|
||||
<AccordionPrimitive.Trigger
|
||||
class={cn(
|
||||
'flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:click>
|
||||
<slot />
|
||||
<ChevronDown class="h-4 w-4 transition-transform duration-200" />
|
||||
</AccordionPrimitive.Trigger>
|
||||
</AccordionPrimitive.Header>
|
17
src/lib/components/ui/accordion/index.ts
Normal file
17
src/lib/components/ui/accordion/index.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Accordion as AccordionPrimitive } from 'bits-ui';
|
||||
import Content from './accordion-content.svelte';
|
||||
import Item from './accordion-item.svelte';
|
||||
import Trigger from './accordion-trigger.svelte';
|
||||
const Root = AccordionPrimitive.Root;
|
||||
|
||||
export {
|
||||
Root,
|
||||
Content,
|
||||
Item,
|
||||
Trigger,
|
||||
//
|
||||
Root as Accordion,
|
||||
Content as AccordionContent,
|
||||
Item as AccordionItem,
|
||||
Trigger as AccordionTrigger
|
||||
};
|
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
||||
import { buttonVariants } from '$lib/components/ui/button';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = AlertDialogPrimitive.ActionProps;
|
||||
type $$Events = AlertDialogPrimitive.ActionEvents;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AlertDialogPrimitive.Action
|
||||
class={cn(buttonVariants(), className)}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
let:builder>
|
||||
<slot {builder} />
|
||||
</AlertDialogPrimitive.Action>
|
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
||||
import { buttonVariants } from '$lib/components/ui/button';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = AlertDialogPrimitive.CancelProps;
|
||||
type $$Events = AlertDialogPrimitive.CancelEvents;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AlertDialogPrimitive.Cancel
|
||||
class={cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', className)}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
let:builder>
|
||||
<slot {builder} />
|
||||
</AlertDialogPrimitive.Cancel>
|
@@ -0,0 +1,27 @@
|
||||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
||||
import * as AlertDialog from '.';
|
||||
import { cn, flyAndScale } from '$lib/utils';
|
||||
|
||||
type $$Props = AlertDialogPrimitive.ContentProps;
|
||||
|
||||
export let transition: $$Props['transition'] = flyAndScale;
|
||||
export let transitionConfig: $$Props['transitionConfig'] = undefined;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AlertDialog.Portal>
|
||||
<AlertDialog.Overlay />
|
||||
<AlertDialogPrimitive.Content
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
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',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</AlertDialogPrimitive.Content>
|
||||
</AlertDialog.Portal>
|
@@ -0,0 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = AlertDialogPrimitive.DescriptionProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AlertDialogPrimitive.Description
|
||||
class={cn('text-sm text-muted-foreground', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</AlertDialogPrimitive.Description>
|
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn(
|
||||
'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
@@ -0,0 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn('flex flex-col space-y-2 text-center sm:text-left', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
import { fade } from 'svelte/transition';
|
||||
|
||||
type $$Props = AlertDialogPrimitive.OverlayProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let transition: $$Props['transition'] = fade;
|
||||
export let transitionConfig: $$Props['transitionConfig'] = {
|
||||
duration: 150
|
||||
};
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AlertDialogPrimitive.Overlay
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
class={cn('fixed inset-0 z-50 bg-background/80 backdrop-blur-sm ', className)}
|
||||
{...$$restProps} />
|
@@ -0,0 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
||||
|
||||
type $$Props = AlertDialogPrimitive.PortalProps;
|
||||
</script>
|
||||
|
||||
<AlertDialogPrimitive.Portal {...$$restProps}>
|
||||
<slot />
|
||||
</AlertDialogPrimitive.Portal>
|
17
src/lib/components/ui/alert-dialog/alert-dialog-title.svelte
Normal file
17
src/lib/components/ui/alert-dialog/alert-dialog-title.svelte
Normal file
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = AlertDialogPrimitive.TitleProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let level: $$Props['level'] = 'h3';
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AlertDialogPrimitive.Title
|
||||
class={cn('text-lg font-semibold', className)}
|
||||
{level}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</AlertDialogPrimitive.Title>
|
40
src/lib/components/ui/alert-dialog/index.ts
Normal file
40
src/lib/components/ui/alert-dialog/index.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
||||
|
||||
const Root = AlertDialogPrimitive.Root;
|
||||
const Trigger = AlertDialogPrimitive.Trigger;
|
||||
|
||||
import Title from './alert-dialog-title.svelte';
|
||||
import Action from './alert-dialog-action.svelte';
|
||||
import Cancel from './alert-dialog-cancel.svelte';
|
||||
import Portal from './alert-dialog-portal.svelte';
|
||||
import Footer from './alert-dialog-footer.svelte';
|
||||
import Header from './alert-dialog-header.svelte';
|
||||
import Overlay from './alert-dialog-overlay.svelte';
|
||||
import Content from './alert-dialog-content.svelte';
|
||||
import Description from './alert-dialog-description.svelte';
|
||||
|
||||
export {
|
||||
Root,
|
||||
Title,
|
||||
Action,
|
||||
Cancel,
|
||||
Portal,
|
||||
Footer,
|
||||
Header,
|
||||
Trigger,
|
||||
Overlay,
|
||||
Content,
|
||||
Description,
|
||||
//
|
||||
Root as AlertDialog,
|
||||
Title as AlertDialogTitle,
|
||||
Action as AlertDialogAction,
|
||||
Cancel as AlertDialogCancel,
|
||||
Portal as AlertDialogPortal,
|
||||
Footer as AlertDialogFooter,
|
||||
Header as AlertDialogHeader,
|
||||
Trigger as AlertDialogTrigger,
|
||||
Overlay as AlertDialogOverlay,
|
||||
Content as AlertDialogContent,
|
||||
Description as AlertDialogDescription
|
||||
};
|
13
src/lib/components/ui/alert/alert-description.svelte
Normal file
13
src/lib/components/ui/alert/alert-description.svelte
Normal file
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div class={cn('text-sm [&_p]:leading-relaxed', className)} {...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
20
src/lib/components/ui/alert/alert-title.svelte
Normal file
20
src/lib/components/ui/alert/alert-title.svelte
Normal file
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import type { HeadingLevel } from '.';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLHeadingElement> & {
|
||||
level?: HeadingLevel;
|
||||
};
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let level: $$Props['level'] = 'h5';
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<svelte:element
|
||||
this={level}
|
||||
class={cn('mb-1 font-medium leading-none tracking-tight', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</svelte:element>
|
20
src/lib/components/ui/alert/alert.svelte
Normal file
20
src/lib/components/ui/alert/alert.svelte
Normal file
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import { alertVariants, type Variant } from '.';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement> & {
|
||||
variant?: Variant;
|
||||
};
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let variant: $$Props['variant'] = 'default';
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn(alertVariants({ variant }), className)}
|
||||
{...$$restProps}
|
||||
role="alert">
|
||||
<slot />
|
||||
</div>
|
33
src/lib/components/ui/alert/index.ts
Normal file
33
src/lib/components/ui/alert/index.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { tv, type VariantProps } from 'tailwind-variants';
|
||||
|
||||
import Root from './alert.svelte';
|
||||
import Description from './alert-description.svelte';
|
||||
import Title from './alert-title.svelte';
|
||||
|
||||
export const alertVariants = tv({
|
||||
base: 'relative w-full rounded-lg border p-4 [&>svg]:absolute [&>svg]:text-foreground [&>svg]:left-4 [&>svg]:top-4 [&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11',
|
||||
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'bg-background text-foreground',
|
||||
destructive:
|
||||
'text-destructive border-destructive/50 dark:border-destructive [&>svg]:text-destructive text-destructive'
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'default'
|
||||
}
|
||||
});
|
||||
|
||||
export type Variant = VariantProps<typeof alertVariants>['variant'];
|
||||
export type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
||||
|
||||
export {
|
||||
Root,
|
||||
Description,
|
||||
Title,
|
||||
//
|
||||
Root as Alert,
|
||||
Description as AlertDescription,
|
||||
Title as AlertTitle
|
||||
};
|
11
src/lib/components/ui/aspect-ratio/aspect-ratio.svelte
Normal file
11
src/lib/components/ui/aspect-ratio/aspect-ratio.svelte
Normal file
@@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
import { AspectRatio as AspectRatioPrimitive } from 'bits-ui';
|
||||
|
||||
type $$Props = AspectRatioPrimitive.Props;
|
||||
|
||||
export let ratio: $$Props['ratio'] = 4 / 3;
|
||||
</script>
|
||||
|
||||
<AspectRatioPrimitive.Root {ratio} {...$$restProps}>
|
||||
<slot />
|
||||
</AspectRatioPrimitive.Root>
|
3
src/lib/components/ui/aspect-ratio/index.ts
Normal file
3
src/lib/components/ui/aspect-ratio/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import Root from './aspect-ratio.svelte';
|
||||
|
||||
export { Root, Root as AspectRatio };
|
18
src/lib/components/ui/avatar/avatar-fallback.svelte
Normal file
18
src/lib/components/ui/avatar/avatar-fallback.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { Avatar as AvatarPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = AvatarPrimitive.FallbackProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AvatarPrimitive.Fallback
|
||||
class={cn(
|
||||
'flex h-full w-full items-center justify-center rounded-full bg-muted',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</AvatarPrimitive.Fallback>
|
17
src/lib/components/ui/avatar/avatar-image.svelte
Normal file
17
src/lib/components/ui/avatar/avatar-image.svelte
Normal file
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { Avatar as AvatarPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = AvatarPrimitive.ImageProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let src: $$Props['src'] = undefined;
|
||||
export let alt: $$Props['alt'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AvatarPrimitive.Image
|
||||
{src}
|
||||
{alt}
|
||||
class={cn('aspect-square h-full w-full', className)}
|
||||
{...$$restProps} />
|
20
src/lib/components/ui/avatar/avatar.svelte
Normal file
20
src/lib/components/ui/avatar/avatar.svelte
Normal file
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { Avatar as AvatarPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = AvatarPrimitive.Props;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let delayMs: $$Props['delayMs'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AvatarPrimitive.Root
|
||||
{delayMs}
|
||||
class={cn(
|
||||
'relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</AvatarPrimitive.Root>
|
13
src/lib/components/ui/avatar/index.ts
Normal file
13
src/lib/components/ui/avatar/index.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import Root from './avatar.svelte';
|
||||
import Image from './avatar-image.svelte';
|
||||
import Fallback from './avatar-fallback.svelte';
|
||||
|
||||
export {
|
||||
Root,
|
||||
Image,
|
||||
Fallback,
|
||||
//
|
||||
Root as Avatar,
|
||||
Image as AvatarImage,
|
||||
Fallback as AvatarFallback
|
||||
};
|
17
src/lib/components/ui/badge/badge.svelte
Normal file
17
src/lib/components/ui/badge/badge.svelte
Normal file
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import { badgeVariants, type Variant } from '.';
|
||||
|
||||
let className: string | undefined | null = undefined;
|
||||
export let href: string | undefined = undefined;
|
||||
export let variant: Variant = 'default';
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<svelte:element
|
||||
this={href ? 'a' : 'span'}
|
||||
{href}
|
||||
class={cn(badgeVariants({ variant, className }))}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</svelte:element>
|
22
src/lib/components/ui/badge/index.ts
Normal file
22
src/lib/components/ui/badge/index.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { tv, type VariantProps } from 'tailwind-variants';
|
||||
export { default as Badge } from './badge.svelte';
|
||||
|
||||
export const badgeVariants = tv({
|
||||
base: 'inline-flex items-center border rounded-full px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none select-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
'bg-primary hover:bg-primary/80 border-transparent text-primary-foreground',
|
||||
secondary:
|
||||
'bg-secondary hover:bg-secondary/80 border-transparent text-secondary-foreground',
|
||||
destructive:
|
||||
'bg-destructive hover:bg-destructive/80 border-transparent text-destructive-foreground',
|
||||
outline: 'text-foreground'
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'default'
|
||||
}
|
||||
});
|
||||
|
||||
export type Variant = VariantProps<typeof badgeVariants>['variant'];
|
24
src/lib/components/ui/button/button.svelte
Normal file
24
src/lib/components/ui/button/button.svelte
Normal file
@@ -0,0 +1,24 @@
|
||||
<script lang="ts">
|
||||
import { Button as ButtonPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
import { buttonVariants, type Props, type Events } from '.';
|
||||
|
||||
type $$Props = Props;
|
||||
type $$Events = Events;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let variant: $$Props['variant'] = 'default';
|
||||
export let size: $$Props['size'] = 'default';
|
||||
export let builders: $$Props['builders'] = [];
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<ButtonPrimitive.Root
|
||||
{builders}
|
||||
class={cn(buttonVariants({ variant, size, className }))}
|
||||
type="button"
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown>
|
||||
<slot />
|
||||
</ButtonPrimitive.Root>
|
50
src/lib/components/ui/button/index.ts
Normal file
50
src/lib/components/ui/button/index.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import Root from './button.svelte';
|
||||
import { tv, type VariantProps } from 'tailwind-variants';
|
||||
import type { Button as ButtonPrimitive } from 'bits-ui';
|
||||
|
||||
const buttonVariants = tv({
|
||||
base: 'inline-flex items-center justify-center rounded-md text-sm font-medium whitespace-nowrap 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',
|
||||
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 {
|
||||
Root,
|
||||
type Props,
|
||||
type Events,
|
||||
//
|
||||
Root as Button,
|
||||
type Props as ButtonProps,
|
||||
type Events as ButtonEvents,
|
||||
buttonVariants
|
||||
};
|
20
src/lib/components/ui/calendar/calendar-cell.svelte
Normal file
20
src/lib/components/ui/calendar/calendar-cell.svelte
Normal file
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CalendarPrimitive.CellProps;
|
||||
|
||||
export let date: $$Props['date'];
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.Cell
|
||||
{date}
|
||||
class={cn(
|
||||
'relative h-9 w-9 p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([data-selected])]:bg-accent first:[&:has([data-selected])]:rounded-l-md last:[&:has([data-selected])]:rounded-r-md [&:has([data-selected][data-outside-month])]:bg-accent/50',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</CalendarPrimitive.Cell>
|
41
src/lib/components/ui/calendar/calendar-day.svelte
Normal file
41
src/lib/components/ui/calendar/calendar-day.svelte
Normal file
@@ -0,0 +1,41 @@
|
||||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
||||
import { buttonVariants } from '$lib/components/ui/button';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CalendarPrimitive.DayProps;
|
||||
type $$Events = CalendarPrimitive.DayEvents;
|
||||
|
||||
export let date: $$Props['date'];
|
||||
export let month: $$Props['month'];
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.Day
|
||||
on:click
|
||||
{date}
|
||||
{month}
|
||||
class={cn(
|
||||
buttonVariants({ variant: 'ghost' }),
|
||||
'h-9 w-9 p-0 font-normal ',
|
||||
'[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',
|
||||
// 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',
|
||||
// Disabled
|
||||
'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',
|
||||
// Unavailable
|
||||
'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',
|
||||
// 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',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
let:selected
|
||||
let:disabled
|
||||
let:unavailable
|
||||
let:builder>
|
||||
<slot {selected} {disabled} {unavailable} {builder}>
|
||||
{date.day}
|
||||
</slot>
|
||||
</CalendarPrimitive.Day>
|
13
src/lib/components/ui/calendar/calendar-grid-body.svelte
Normal file
13
src/lib/components/ui/calendar/calendar-grid-body.svelte
Normal file
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CalendarPrimitive.GridBodyProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.GridBody class={cn(className)} {...$$restProps}>
|
||||
<slot />
|
||||
</CalendarPrimitive.GridBody>
|
13
src/lib/components/ui/calendar/calendar-grid-head.svelte
Normal file
13
src/lib/components/ui/calendar/calendar-grid-head.svelte
Normal file
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CalendarPrimitive.GridHeadProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.GridHead class={cn(className)} {...$$restProps}>
|
||||
<slot />
|
||||
</CalendarPrimitive.GridHead>
|
13
src/lib/components/ui/calendar/calendar-grid-row.svelte
Normal file
13
src/lib/components/ui/calendar/calendar-grid-row.svelte
Normal file
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CalendarPrimitive.GridRowProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.GridRow class={cn('flex', className)} {...$$restProps}>
|
||||
<slot />
|
||||
</CalendarPrimitive.GridRow>
|
15
src/lib/components/ui/calendar/calendar-grid.svelte
Normal file
15
src/lib/components/ui/calendar/calendar-grid.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CalendarPrimitive.GridProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.Grid
|
||||
class={cn('w-full border-collapse space-y-1', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</CalendarPrimitive.Grid>
|
18
src/lib/components/ui/calendar/calendar-head-cell.svelte
Normal file
18
src/lib/components/ui/calendar/calendar-head-cell.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CalendarPrimitive.HeadCellProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.HeadCell
|
||||
class={cn(
|
||||
'w-9 rounded-md text-[0.8rem] font-normal text-muted-foreground',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</CalendarPrimitive.HeadCell>
|
18
src/lib/components/ui/calendar/calendar-header.svelte
Normal file
18
src/lib/components/ui/calendar/calendar-header.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CalendarPrimitive.HeaderProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.Header
|
||||
class={cn(
|
||||
'relative flex w-full items-center justify-between pt-1',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</CalendarPrimitive.Header>
|
18
src/lib/components/ui/calendar/calendar-heading.svelte
Normal file
18
src/lib/components/ui/calendar/calendar-heading.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CalendarPrimitive.HeadingProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.Heading
|
||||
let:headingValue
|
||||
class={cn('text-sm font-medium', className)}
|
||||
{...$$restProps}>
|
||||
<slot {headingValue}>
|
||||
{headingValue}
|
||||
</slot>
|
||||
</CalendarPrimitive.Heading>
|
18
src/lib/components/ui/calendar/calendar-months.svelte
Normal file
18
src/lib/components/ui/calendar/calendar-months.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn(
|
||||
'mt-4 flex flex-col space-y-4 sm:flex-row sm:space-x-4 sm:space-y-0',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
26
src/lib/components/ui/calendar/calendar-next-button.svelte
Normal file
26
src/lib/components/ui/calendar/calendar-next-button.svelte
Normal file
@@ -0,0 +1,26 @@
|
||||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
||||
import { ChevronRight } from 'lucide-svelte';
|
||||
import { buttonVariants } from '$lib/components/ui/button';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CalendarPrimitive.NextButtonProps;
|
||||
type $$Events = CalendarPrimitive.NextButtonEvents;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.NextButton
|
||||
on:click
|
||||
class={cn(
|
||||
buttonVariants({ variant: 'outline' }),
|
||||
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
let:builder>
|
||||
<slot {builder}>
|
||||
<ChevronRight class="h-4 w-4" />
|
||||
</slot>
|
||||
</CalendarPrimitive.NextButton>
|
26
src/lib/components/ui/calendar/calendar-prev-button.svelte
Normal file
26
src/lib/components/ui/calendar/calendar-prev-button.svelte
Normal file
@@ -0,0 +1,26 @@
|
||||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
||||
import { ChevronLeft } from 'lucide-svelte';
|
||||
import { buttonVariants } from '$lib/components/ui/button';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CalendarPrimitive.PrevButtonProps;
|
||||
type $$Events = CalendarPrimitive.PrevButtonEvents;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.PrevButton
|
||||
on:click
|
||||
class={cn(
|
||||
buttonVariants({ variant: 'outline' }),
|
||||
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
let:builder>
|
||||
<slot {builder}>
|
||||
<ChevronLeft class="h-4 w-4" />
|
||||
</slot>
|
||||
</CalendarPrimitive.PrevButton>
|
58
src/lib/components/ui/calendar/calendar.svelte
Normal file
58
src/lib/components/ui/calendar/calendar.svelte
Normal file
@@ -0,0 +1,58 @@
|
||||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
||||
import * as Calendar from '.';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CalendarPrimitive.Props;
|
||||
|
||||
type $$Events = CalendarPrimitive.Events;
|
||||
|
||||
export let value: $$Props['value'] = undefined;
|
||||
export let placeholder: $$Props['placeholder'] = undefined;
|
||||
export let weekdayFormat: $$Props['weekdayFormat'] = 'short';
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.Root
|
||||
bind:value
|
||||
bind:placeholder
|
||||
{weekdayFormat}
|
||||
class={cn('p-3', className)}
|
||||
{...$$restProps}
|
||||
on:keydown
|
||||
let:months
|
||||
let:weekdays>
|
||||
<Calendar.Header>
|
||||
<Calendar.PrevButton />
|
||||
<Calendar.Heading />
|
||||
<Calendar.NextButton />
|
||||
</Calendar.Header>
|
||||
<Calendar.Months>
|
||||
{#each months as month}
|
||||
<Calendar.Grid>
|
||||
<Calendar.GridHead>
|
||||
<Calendar.GridRow class="flex">
|
||||
{#each weekdays as weekday}
|
||||
<Calendar.HeadCell>
|
||||
{weekday.slice(0, 2)}
|
||||
</Calendar.HeadCell>
|
||||
{/each}
|
||||
</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}
|
||||
</Calendar.GridRow>
|
||||
{/each}
|
||||
</Calendar.GridBody>
|
||||
</Calendar.Grid>
|
||||
{/each}
|
||||
</Calendar.Months>
|
||||
</CalendarPrimitive.Root>
|
30
src/lib/components/ui/calendar/index.ts
Normal file
30
src/lib/components/ui/calendar/index.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import Root from './calendar.svelte';
|
||||
import Cell from './calendar-cell.svelte';
|
||||
import Day from './calendar-day.svelte';
|
||||
import Grid from './calendar-grid.svelte';
|
||||
import Header from './calendar-header.svelte';
|
||||
import Months from './calendar-months.svelte';
|
||||
import GridRow from './calendar-grid-row.svelte';
|
||||
import Heading from './calendar-heading.svelte';
|
||||
import GridBody from './calendar-grid-body.svelte';
|
||||
import GridHead from './calendar-grid-head.svelte';
|
||||
import HeadCell from './calendar-head-cell.svelte';
|
||||
import NextButton from './calendar-next-button.svelte';
|
||||
import PrevButton from './calendar-prev-button.svelte';
|
||||
|
||||
export {
|
||||
Day,
|
||||
Cell,
|
||||
Grid,
|
||||
Header,
|
||||
Months,
|
||||
GridRow,
|
||||
Heading,
|
||||
GridBody,
|
||||
GridHead,
|
||||
HeadCell,
|
||||
NextButton,
|
||||
PrevButton,
|
||||
//
|
||||
Root as Calendar
|
||||
};
|
13
src/lib/components/ui/card/card-content.svelte
Normal file
13
src/lib/components/ui/card/card-content.svelte
Normal file
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div class={cn('p-6 pt-0', className)} {...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
13
src/lib/components/ui/card/card-description.svelte
Normal file
13
src/lib/components/ui/card/card-description.svelte
Normal file
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLParagraphElement>;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<p class={cn('text-sm text-muted-foreground', className)} {...$$restProps}>
|
||||
<slot />
|
||||
</p>
|
13
src/lib/components/ui/card/card-footer.svelte
Normal file
13
src/lib/components/ui/card/card-footer.svelte
Normal file
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div class={cn('flex items-center p-6 pt-0', className)} {...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
13
src/lib/components/ui/card/card-header.svelte
Normal file
13
src/lib/components/ui/card/card-header.svelte
Normal file
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div class={cn('flex flex-col space-y-1.5 p-6', className)} {...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
20
src/lib/components/ui/card/card-title.svelte
Normal file
20
src/lib/components/ui/card/card-title.svelte
Normal file
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HeadingLevel } from '.';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLHeadingElement> & {
|
||||
tag?: HeadingLevel;
|
||||
};
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let tag: $$Props['tag'] = 'h3';
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<svelte:element
|
||||
this={tag}
|
||||
class={cn('text-lg font-semibold leading-none tracking-tight', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</svelte:element>
|
18
src/lib/components/ui/card/card.svelte
Normal file
18
src/lib/components/ui/card/card.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn(
|
||||
'rounded-lg border bg-card text-card-foreground shadow-sm',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
24
src/lib/components/ui/card/index.ts
Normal file
24
src/lib/components/ui/card/index.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import Root from './card.svelte';
|
||||
import Content from './card-content.svelte';
|
||||
import Description from './card-description.svelte';
|
||||
import Footer from './card-footer.svelte';
|
||||
import Header from './card-header.svelte';
|
||||
import Title from './card-title.svelte';
|
||||
|
||||
export {
|
||||
Root,
|
||||
Content,
|
||||
Description,
|
||||
Footer,
|
||||
Header,
|
||||
Title,
|
||||
//
|
||||
Root as Card,
|
||||
Content as CardContent,
|
||||
Description as CardDescription,
|
||||
Footer as CardFooter,
|
||||
Header as CardHeader,
|
||||
Title as CardTitle
|
||||
};
|
||||
|
||||
export type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
25
src/lib/components/ui/carousel/carousel-content.svelte
Normal file
25
src/lib/components/ui/carousel/carousel-content.svelte
Normal file
@@ -0,0 +1,25 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils.js';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import { getEmblaContext } from './context.js';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
|
||||
const { orientation } = getEmblaContext('<Carousel.Content/>');
|
||||
</script>
|
||||
|
||||
<div class="overflow-hidden">
|
||||
<div
|
||||
class={cn(
|
||||
'flex',
|
||||
$orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col',
|
||||
className
|
||||
)}
|
||||
data-embla-container=""
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
24
src/lib/components/ui/carousel/carousel-item.svelte
Normal file
24
src/lib/components/ui/carousel/carousel-item.svelte
Normal file
@@ -0,0 +1,24 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import { getEmblaContext } from './context.js';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
|
||||
const { orientation } = getEmblaContext('<Carousel.Item/>');
|
||||
</script>
|
||||
|
||||
<div
|
||||
role="group"
|
||||
aria-roledescription="slide"
|
||||
class={cn(
|
||||
'min-w-0 shrink-0 grow-0 basis-full',
|
||||
$orientation === 'horizontal' ? 'pl-4' : 'pt-4',
|
||||
className
|
||||
)}
|
||||
data-embla-slide=""
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
39
src/lib/components/ui/carousel/carousel-next.svelte
Normal file
39
src/lib/components/ui/carousel/carousel-next.svelte
Normal file
@@ -0,0 +1,39 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Button,
|
||||
type Props,
|
||||
buttonVariants
|
||||
} from '$lib/components/ui/button/index.js';
|
||||
import { cn } from '$lib/utils';
|
||||
import { ArrowRight } from 'lucide-svelte';
|
||||
import type { VariantProps } from 'tailwind-variants';
|
||||
import { getEmblaContext } from './context.js';
|
||||
|
||||
type $$Props = Props;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
export let variant: VariantProps<typeof buttonVariants>['variant'] =
|
||||
'outline';
|
||||
export let size: VariantProps<typeof buttonVariants>['size'] = 'icon';
|
||||
const { orientation, canScrollNext, scrollNext, handleKeyDown } =
|
||||
getEmblaContext('<Carousel.Next/>');
|
||||
</script>
|
||||
|
||||
<Button
|
||||
{variant}
|
||||
{size}
|
||||
class={cn(
|
||||
'absolute h-8 w-8 rounded-full',
|
||||
$orientation === 'horizontal'
|
||||
? '-right-12 top-1/2 -translate-y-1/2'
|
||||
: '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',
|
||||
className
|
||||
)}
|
||||
disabled={!$canScrollNext}
|
||||
on:click={scrollNext}
|
||||
on:keydown={handleKeyDown}
|
||||
{...$$restProps}>
|
||||
<ArrowRight class="h-4 w-4" />
|
||||
<span class="sr-only">Next slide</span>
|
||||
</Button>
|
40
src/lib/components/ui/carousel/carousel-previous.svelte
Normal file
40
src/lib/components/ui/carousel/carousel-previous.svelte
Normal file
@@ -0,0 +1,40 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Button,
|
||||
type Props,
|
||||
buttonVariants
|
||||
} from '$lib/components/ui/button/index.js';
|
||||
import { cn } from '$lib/utils.js';
|
||||
import { ArrowLeft } from 'lucide-svelte';
|
||||
import type { VariantProps } from 'tailwind-variants';
|
||||
import { getEmblaContext } from './context.js';
|
||||
|
||||
type $$Props = Props;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
export let variant: VariantProps<typeof buttonVariants>['variant'] =
|
||||
'outline';
|
||||
export let size: VariantProps<typeof buttonVariants>['size'] = 'icon';
|
||||
|
||||
const { orientation, canScrollPrev, scrollPrev, handleKeyDown } =
|
||||
getEmblaContext('<Carousel.Previous/>');
|
||||
</script>
|
||||
|
||||
<Button
|
||||
{variant}
|
||||
{size}
|
||||
class={cn(
|
||||
'absolute h-8 w-8 rounded-full',
|
||||
$orientation === 'horizontal'
|
||||
? '-left-12 top-1/2 -translate-y-1/2'
|
||||
: '-top-12 left-1/2 -translate-x-1/2 rotate-90',
|
||||
className
|
||||
)}
|
||||
disabled={!$canScrollPrev}
|
||||
on:click={scrollPrev}
|
||||
on:keydown={handleKeyDown}
|
||||
{...$$restProps}>
|
||||
<ArrowLeft class="h-4 w-4" />
|
||||
<span class="sr-only">Previous slide</span>
|
||||
</Button>
|
97
src/lib/components/ui/carousel/carousel.svelte
Normal file
97
src/lib/components/ui/carousel/carousel.svelte
Normal file
@@ -0,0 +1,97 @@
|
||||
<script lang="ts">
|
||||
import emblaCarouselSvelte from 'embla-carousel-svelte';
|
||||
import {
|
||||
setEmblaContex,
|
||||
type CarouselProps,
|
||||
type CarouselAPI
|
||||
} from './context.js';
|
||||
import { cn } from '$lib/utils.js';
|
||||
import { writable } from 'svelte/store';
|
||||
import { onDestroy } from 'svelte';
|
||||
|
||||
type $$Props = CarouselProps;
|
||||
|
||||
export let opts = {};
|
||||
export let plugins: NonNullable<$$Props['plugins']> = [];
|
||||
export let api: $$Props['api'] = undefined;
|
||||
export let orientation: NonNullable<$$Props['orientation']> = 'horizontal';
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
|
||||
const apiStore = writable<CarouselAPI | undefined>(undefined);
|
||||
const orientationStore = writable(orientation);
|
||||
const canScrollPrev = writable(false);
|
||||
const canScrollNext = writable(false);
|
||||
|
||||
$: orientationStore.set(orientation);
|
||||
|
||||
function scrollPrev() {
|
||||
api?.scrollPrev();
|
||||
}
|
||||
function scrollNext() {
|
||||
api?.scrollNext();
|
||||
}
|
||||
|
||||
function onSelect(api: CarouselAPI) {
|
||||
if (!api) return;
|
||||
canScrollPrev.set(api.canScrollPrev());
|
||||
canScrollNext.set(api.canScrollNext());
|
||||
}
|
||||
|
||||
$: if (api) {
|
||||
onSelect(api);
|
||||
api.on('select', onSelect);
|
||||
api.on('reInit', onSelect);
|
||||
}
|
||||
|
||||
function handleKeyDown(e: KeyboardEvent) {
|
||||
if (e.key === 'ArrowLeft') {
|
||||
e.preventDefault();
|
||||
scrollPrev();
|
||||
} else if (e.key === 'ArrowRight') {
|
||||
e.preventDefault();
|
||||
scrollNext();
|
||||
}
|
||||
}
|
||||
|
||||
setEmblaContex({
|
||||
api: apiStore,
|
||||
scrollPrev,
|
||||
scrollNext,
|
||||
orientation: orientationStore,
|
||||
canScrollNext,
|
||||
canScrollPrev,
|
||||
handleKeyDown
|
||||
});
|
||||
|
||||
function onInit(event: CustomEvent<CarouselAPI>) {
|
||||
api = event.detail;
|
||||
console.log(api.slideNodes());
|
||||
apiStore.set(api);
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
api?.off('select', onSelect);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn('relative', className)}
|
||||
use:emblaCarouselSvelte={{
|
||||
options: {
|
||||
container: '[data-embla-container]',
|
||||
slides: '[data-embla-slide]',
|
||||
...opts,
|
||||
axis: $orientationStore === 'horizontal' ? 'x' : 'y'
|
||||
},
|
||||
plugins
|
||||
}}
|
||||
on:emblaInit={onInit}
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
role="region"
|
||||
aria-roledescription="carousel"
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
52
src/lib/components/ui/carousel/context.ts
Normal file
52
src/lib/components/ui/carousel/context.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import type { EmblaCarouselSvelteType } from 'embla-carousel-svelte';
|
||||
import type emblaCarouselSvelte from 'embla-carousel-svelte';
|
||||
import { getContext, hasContext, setContext } from 'svelte';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import type { Writable, Readable } from 'svelte/store';
|
||||
|
||||
export type CarouselAPI =
|
||||
NonNullable<
|
||||
NonNullable<EmblaCarouselSvelteType['$$_attributes']>['on:emblaInit']
|
||||
> extends (evt: CustomEvent<infer CarouselAPI>) => void
|
||||
? CarouselAPI
|
||||
: never;
|
||||
|
||||
type EmblaCarouselConfig = NonNullable<
|
||||
Parameters<typeof emblaCarouselSvelte>[1]
|
||||
>;
|
||||
|
||||
export type CarouselOptions = EmblaCarouselConfig['options'];
|
||||
export type CarouselPlugins = EmblaCarouselConfig['plugins'];
|
||||
|
||||
////
|
||||
|
||||
export type CarouselProps = {
|
||||
opts?: CarouselOptions;
|
||||
plugins?: CarouselPlugins;
|
||||
api?: CarouselAPI;
|
||||
orientation?: 'horizontal' | 'vertical';
|
||||
} & HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
const EMBLA_CAROUSEL_CONTEXT = Symbol('EMBLA_CAROUSEL_CONTEXT');
|
||||
|
||||
type EmblaContext = {
|
||||
api: Writable<CarouselAPI | undefined>;
|
||||
orientation: Writable<'horizontal' | 'vertical'>;
|
||||
scrollNext: () => void;
|
||||
scrollPrev: () => void;
|
||||
canScrollNext: Readable<boolean>;
|
||||
canScrollPrev: Readable<boolean>;
|
||||
handleKeyDown: (e: KeyboardEvent) => void;
|
||||
};
|
||||
|
||||
export function setEmblaContex(config: EmblaContext): EmblaContext {
|
||||
setContext(EMBLA_CAROUSEL_CONTEXT, config);
|
||||
return config;
|
||||
}
|
||||
|
||||
export function getEmblaContext(name = 'This component') {
|
||||
if (!hasContext(EMBLA_CAROUSEL_CONTEXT)) {
|
||||
throw new Error(`${name} must be used within a <Carousel.Root> component`);
|
||||
}
|
||||
return getContext<ReturnType<typeof setEmblaContex>>(EMBLA_CAROUSEL_CONTEXT);
|
||||
}
|
5
src/lib/components/ui/carousel/index.ts
Normal file
5
src/lib/components/ui/carousel/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export { default as Root } from './carousel.svelte';
|
||||
export { default as Content } from './carousel-content.svelte';
|
||||
export { default as Item } from './carousel-item.svelte';
|
||||
export { default as Previous } from './carousel-previous.svelte';
|
||||
export { default as Next } from './carousel-next.svelte';
|
32
src/lib/components/ui/checkbox/checkbox.svelte
Normal file
32
src/lib/components/ui/checkbox/checkbox.svelte
Normal file
@@ -0,0 +1,32 @@
|
||||
<script lang="ts">
|
||||
import { Checkbox as CheckboxPrimitive } from 'bits-ui';
|
||||
import { Check, Minus } from 'lucide-svelte';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CheckboxPrimitive.Props;
|
||||
type $$Events = CheckboxPrimitive.Events;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let checked: $$Props['checked'] = false;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CheckboxPrimitive.Root
|
||||
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',
|
||||
className
|
||||
)}
|
||||
bind:checked
|
||||
{...$$restProps}
|
||||
on:click>
|
||||
<CheckboxPrimitive.Indicator
|
||||
class={cn('flex h-4 w-4 items-center justify-center text-current')}
|
||||
let:isChecked
|
||||
let:isIndeterminate>
|
||||
{#if isChecked}
|
||||
<Check class="h-3.5 w-3.5" />
|
||||
{:else if isIndeterminate}
|
||||
<Minus class="h-3.5 w-3.5" />
|
||||
{/if}
|
||||
</CheckboxPrimitive.Indicator>
|
||||
</CheckboxPrimitive.Root>
|
6
src/lib/components/ui/checkbox/index.ts
Normal file
6
src/lib/components/ui/checkbox/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import Root from './checkbox.svelte';
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Checkbox
|
||||
};
|
15
src/lib/components/ui/collapsible/collapsible-content.svelte
Normal file
15
src/lib/components/ui/collapsible/collapsible-content.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { Collapsible as CollapsiblePrimitive } from 'bits-ui';
|
||||
import { slide } from 'svelte/transition';
|
||||
|
||||
type $$Props = CollapsiblePrimitive.ContentProps;
|
||||
|
||||
export let transition: $$Props['transition'] = slide;
|
||||
export let transitionConfig: $$Props['transitionConfig'] = {
|
||||
duration: 150
|
||||
};
|
||||
</script>
|
||||
|
||||
<CollapsiblePrimitive.Content {transition} {transitionConfig} {...$$restProps}>
|
||||
<slot />
|
||||
</CollapsiblePrimitive.Content>
|
15
src/lib/components/ui/collapsible/index.ts
Normal file
15
src/lib/components/ui/collapsible/index.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Collapsible as CollapsiblePrimitive } from 'bits-ui';
|
||||
import Content from './collapsible-content.svelte';
|
||||
|
||||
const Root = CollapsiblePrimitive.Root;
|
||||
const Trigger = CollapsiblePrimitive.Trigger;
|
||||
|
||||
export {
|
||||
Root,
|
||||
Content,
|
||||
Trigger,
|
||||
//
|
||||
Root as Collapsible,
|
||||
Content as CollapsibleContent,
|
||||
Trigger as CollapsibleTrigger
|
||||
};
|
22
src/lib/components/ui/command/command-dialog.svelte
Normal file
22
src/lib/components/ui/command/command-dialog.svelte
Normal file
@@ -0,0 +1,22 @@
|
||||
<script lang="ts">
|
||||
import Command from './command.svelte';
|
||||
import * as Dialog from '$lib/components/ui/dialog';
|
||||
import type { Dialog as DialogPrimitive } from 'bits-ui';
|
||||
import type { Command as CommandPrimitive } from 'cmdk-sv';
|
||||
|
||||
type $$Props = DialogPrimitive.Props & CommandPrimitive.CommandProps;
|
||||
|
||||
export let open: $$Props['open'] = false;
|
||||
export let value: $$Props['value'] = undefined;
|
||||
</script>
|
||||
|
||||
<Dialog.Root bind:open {...$$restProps}>
|
||||
<Dialog.Content class="overflow-hidden p-0 shadow-lg">
|
||||
<Command
|
||||
class="[&_[data-cmdk-group-heading]]:px-2 [&_[data-cmdk-group-heading]]:font-medium [&_[data-cmdk-group-heading]]:text-muted-foreground [&_[data-cmdk-group]:not([hidden])_~[data-cmdk-group]]:pt-0 [&_[data-cmdk-group]]:px-2 [&_[data-cmdk-input-wrapper]_svg]:h-5 [&_[data-cmdk-input-wrapper]_svg]:w-5 [&_[data-cmdk-input]]:h-12 [&_[data-cmdk-item]]:px-2 [&_[data-cmdk-item]]:py-3 [&_[data-cmdk-item]_svg]:h-5 [&_[data-cmdk-item]_svg]:w-5"
|
||||
{...$$restProps}
|
||||
bind:value>
|
||||
<slot />
|
||||
</Command>
|
||||
</Dialog.Content>
|
||||
</Dialog.Root>
|
14
src/lib/components/ui/command/command-empty.svelte
Normal file
14
src/lib/components/ui/command/command-empty.svelte
Normal file
@@ -0,0 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { Command as CommandPrimitive } from 'cmdk-sv';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CommandPrimitive.EmptyProps;
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CommandPrimitive.Empty
|
||||
class={cn('py-6 text-center text-sm', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</CommandPrimitive.Empty>
|
17
src/lib/components/ui/command/command-group.svelte
Normal file
17
src/lib/components/ui/command/command-group.svelte
Normal file
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { Command as CommandPrimitive } from 'cmdk-sv';
|
||||
import { cn } from '$lib/utils';
|
||||
type $$Props = CommandPrimitive.GroupProps;
|
||||
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CommandPrimitive.Group
|
||||
class={cn(
|
||||
'overflow-hidden p-1 text-foreground [&_[data-cmdk-group-heading]]:px-2 [&_[data-cmdk-group-heading]]:py-1.5 [&_[data-cmdk-group-heading]]:text-xs [&_[data-cmdk-group-heading]]:font-medium [&_[data-cmdk-group-heading]]:text-muted-foreground',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</CommandPrimitive.Group>
|
22
src/lib/components/ui/command/command-input.svelte
Normal file
22
src/lib/components/ui/command/command-input.svelte
Normal file
@@ -0,0 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { Command as CommandPrimitive } from 'cmdk-sv';
|
||||
import { Search } from 'lucide-svelte';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CommandPrimitive.InputProps;
|
||||
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
export let value: string = '';
|
||||
</script>
|
||||
|
||||
<div class="flex items-center border-b px-2" data-cmdk-input-wrapper="">
|
||||
<Search class="mr-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
<CommandPrimitive.Input
|
||||
class={cn(
|
||||
'flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
bind:value />
|
||||
</div>
|
18
src/lib/components/ui/command/command-item.svelte
Normal file
18
src/lib/components/ui/command/command-item.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { Command as CommandPrimitive } from 'cmdk-sv';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CommandPrimitive.ItemProps;
|
||||
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CommandPrimitive.Item
|
||||
class={cn(
|
||||
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</CommandPrimitive.Item>
|
14
src/lib/components/ui/command/command-list.svelte
Normal file
14
src/lib/components/ui/command/command-list.svelte
Normal file
@@ -0,0 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { Command as CommandPrimitive } from 'cmdk-sv';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CommandPrimitive.ListProps;
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CommandPrimitive.List
|
||||
class={cn('max-h-[300px] overflow-y-auto overflow-x-hidden', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</CommandPrimitive.List>
|
12
src/lib/components/ui/command/command-separator.svelte
Normal file
12
src/lib/components/ui/command/command-separator.svelte
Normal file
@@ -0,0 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { Command as CommandPrimitive } from 'cmdk-sv';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CommandPrimitive.SeparatorProps;
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CommandPrimitive.Separator
|
||||
class={cn('-mx-1 h-px bg-border', className)}
|
||||
{...$$restProps} />
|
15
src/lib/components/ui/command/command-shortcut.svelte
Normal file
15
src/lib/components/ui/command/command-shortcut.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLSpanElement>;
|
||||
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<span
|
||||
class={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</span>
|
21
src/lib/components/ui/command/command.svelte
Normal file
21
src/lib/components/ui/command/command.svelte
Normal file
@@ -0,0 +1,21 @@
|
||||
<script lang="ts">
|
||||
import { Command as CommandPrimitive } from 'cmdk-sv';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = CommandPrimitive.CommandProps;
|
||||
|
||||
export let value: $$Props['value'] = undefined;
|
||||
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CommandPrimitive.Root
|
||||
class={cn(
|
||||
'flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground',
|
||||
className
|
||||
)}
|
||||
bind:value
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</CommandPrimitive.Root>
|
37
src/lib/components/ui/command/index.ts
Normal file
37
src/lib/components/ui/command/index.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Command as CommandPrimitive } from 'cmdk-sv';
|
||||
|
||||
import Root from './command.svelte';
|
||||
import Dialog from './command-dialog.svelte';
|
||||
import Empty from './command-empty.svelte';
|
||||
import Group from './command-group.svelte';
|
||||
import Item from './command-item.svelte';
|
||||
import Input from './command-input.svelte';
|
||||
import List from './command-list.svelte';
|
||||
import Separator from './command-separator.svelte';
|
||||
import Shortcut from './command-shortcut.svelte';
|
||||
|
||||
const Loading = CommandPrimitive.Loading;
|
||||
|
||||
export {
|
||||
Root,
|
||||
Dialog,
|
||||
Empty,
|
||||
Group,
|
||||
Item,
|
||||
Input,
|
||||
List,
|
||||
Separator,
|
||||
Shortcut,
|
||||
Loading,
|
||||
//
|
||||
Root as Command,
|
||||
Dialog as CommandDialog,
|
||||
Empty as CommandEmpty,
|
||||
Group as CommandGroup,
|
||||
Item as CommandItem,
|
||||
Input as CommandInput,
|
||||
List as CommandList,
|
||||
Separator as CommandSeparator,
|
||||
Shortcut as CommandShortcut,
|
||||
Loading as CommandLoading
|
||||
};
|
@@ -0,0 +1,34 @@
|
||||
<script lang="ts">
|
||||
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
import { Check } from 'lucide-svelte';
|
||||
|
||||
type $$Props = ContextMenuPrimitive.CheckboxItemProps;
|
||||
type $$Events = ContextMenuPrimitive.CheckboxItemEvents;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let checked: $$Props['checked'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.CheckboxItem
|
||||
bind:checked
|
||||
class={cn(
|
||||
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
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">
|
||||
<ContextMenuPrimitive.CheckboxIndicator>
|
||||
<Check class="h-4 w-4" />
|
||||
</ContextMenuPrimitive.CheckboxIndicator>
|
||||
</span>
|
||||
<slot />
|
||||
</ContextMenuPrimitive.CheckboxItem>
|
@@ -0,0 +1,23 @@
|
||||
<script lang="ts">
|
||||
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui';
|
||||
import { cn, flyAndScale } from '$lib/utils';
|
||||
|
||||
type $$Props = ContextMenuPrimitive.ContentProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let transition: $$Props['transition'] = flyAndScale;
|
||||
export let transitionConfig: $$Props['transitionConfig'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.Content
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
class={cn(
|
||||
'z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:keydown>
|
||||
<slot />
|
||||
</ContextMenuPrimitive.Content>
|
30
src/lib/components/ui/context-menu/context-menu-item.svelte
Normal file
30
src/lib/components/ui/context-menu/context-menu-item.svelte
Normal file
@@ -0,0 +1,30 @@
|
||||
<script lang="ts">
|
||||
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = ContextMenuPrimitive.ItemProps & {
|
||||
inset?: boolean;
|
||||
};
|
||||
type $$Events = ContextMenuPrimitive.ItemEvents;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let inset: $$Props['inset'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.Item
|
||||
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',
|
||||
inset && 'pl-8',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
on:focusin
|
||||
on:focusout
|
||||
on:pointerdown
|
||||
on:pointerleave
|
||||
on:pointermove>
|
||||
<slot />
|
||||
</ContextMenuPrimitive.Item>
|
22
src/lib/components/ui/context-menu/context-menu-label.svelte
Normal file
22
src/lib/components/ui/context-menu/context-menu-label.svelte
Normal file
@@ -0,0 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = ContextMenuPrimitive.LabelProps & {
|
||||
inset?: boolean;
|
||||
};
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let inset: $$Props['inset'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.Label
|
||||
class={cn(
|
||||
'px-2 py-1.5 text-sm font-semibold text-foreground',
|
||||
inset && 'pl-8',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</ContextMenuPrimitive.Label>
|
@@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui';
|
||||
|
||||
type $$Props = ContextMenuPrimitive.RadioGroupProps;
|
||||
|
||||
export let value: $$Props['value'] = undefined;
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.RadioGroup {...$$restProps} bind:value>
|
||||
<slot />
|
||||
</ContextMenuPrimitive.RadioGroup>
|
@@ -0,0 +1,34 @@
|
||||
<script lang="ts">
|
||||
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
import { Circle } from 'lucide-svelte';
|
||||
|
||||
type $$Props = ContextMenuPrimitive.RadioItemProps;
|
||||
type $$Events = ContextMenuPrimitive.RadioItemEvents;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let value: ContextMenuPrimitive.RadioItemProps['value'];
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.RadioItem
|
||||
class={cn(
|
||||
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50',
|
||||
className
|
||||
)}
|
||||
{value}
|
||||
{...$$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">
|
||||
<ContextMenuPrimitive.RadioIndicator>
|
||||
<Circle class="h-2 w-2 fill-current" />
|
||||
</ContextMenuPrimitive.RadioIndicator>
|
||||
</span>
|
||||
<slot />
|
||||
</ContextMenuPrimitive.RadioItem>
|
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = ContextMenuPrimitive.SeparatorProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.Separator
|
||||
class={cn('-mx-1 my-1 h-px bg-border', className)}
|
||||
{...$$restProps} />
|
@@ -0,0 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLSpanElement>;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<span
|
||||
class={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</span>
|
@@ -0,0 +1,28 @@
|
||||
<script lang="ts">
|
||||
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui';
|
||||
import { cn, flyAndScale } from '$lib/utils';
|
||||
|
||||
type $$Props = ContextMenuPrimitive.SubContentProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let transition: $$Props['transition'] = flyAndScale;
|
||||
export let transitionConfig: $$Props['transitionConfig'] = {
|
||||
x: -10,
|
||||
y: 0
|
||||
};
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.SubContent
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
class={cn(
|
||||
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:keydown
|
||||
on:focusout
|
||||
on:pointermove>
|
||||
<slot />
|
||||
</ContextMenuPrimitive.SubContent>
|
@@ -0,0 +1,31 @@
|
||||
<script lang="ts">
|
||||
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
import { ChevronRight } from 'lucide-svelte';
|
||||
|
||||
type $$Props = ContextMenuPrimitive.SubTriggerProps & {
|
||||
inset?: boolean;
|
||||
};
|
||||
type $$Events = ContextMenuPrimitive.SubTriggerEvents;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let inset: $$Props['inset'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<ContextMenuPrimitive.SubTrigger
|
||||
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',
|
||||
inset && 'pl-8',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
on:focusin
|
||||
on:focusout
|
||||
on:pointerleave
|
||||
on:pointermove>
|
||||
<slot />
|
||||
<ChevronRight class="ml-auto h-4 w-4" />
|
||||
</ContextMenuPrimitive.SubTrigger>
|
49
src/lib/components/ui/context-menu/index.ts
Normal file
49
src/lib/components/ui/context-menu/index.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui';
|
||||
|
||||
import Item from './context-menu-item.svelte';
|
||||
import Label from './context-menu-label.svelte';
|
||||
import Content from './context-menu-content.svelte';
|
||||
import Shortcut from './context-menu-shortcut.svelte';
|
||||
import RadioItem from './context-menu-radio-item.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 SubTrigger from './context-menu-sub-trigger.svelte';
|
||||
import CheckboxItem from './context-menu-checkbox-item.svelte';
|
||||
|
||||
const Sub = ContextMenuPrimitive.Sub;
|
||||
const Root = ContextMenuPrimitive.Root;
|
||||
const Trigger = ContextMenuPrimitive.Trigger;
|
||||
const Group = ContextMenuPrimitive.Group;
|
||||
|
||||
export {
|
||||
Sub,
|
||||
Root,
|
||||
Item,
|
||||
Label,
|
||||
Group,
|
||||
Trigger,
|
||||
Content,
|
||||
Shortcut,
|
||||
Separator,
|
||||
RadioItem,
|
||||
SubContent,
|
||||
SubTrigger,
|
||||
RadioGroup,
|
||||
CheckboxItem,
|
||||
//
|
||||
Root as ContextMenu,
|
||||
Sub as ContextMenuSub,
|
||||
Item as ContextMenuItem,
|
||||
Label as ContextMenuLabel,
|
||||
Group as ContextMenuGroup,
|
||||
Content as ContextMenuContent,
|
||||
Trigger as ContextMenuTrigger,
|
||||
Shortcut as ContextMenuShortcut,
|
||||
RadioItem as ContextMenuRadioItem,
|
||||
Separator as ContextMenuSeparator,
|
||||
RadioGroup as ContextMenuRadioGroup,
|
||||
SubContent as ContextMenuSubContent,
|
||||
SubTrigger as ContextMenuSubTrigger,
|
||||
CheckboxItem as ContextMenuCheckboxItem
|
||||
};
|
34
src/lib/components/ui/dialog/dialog-content.svelte
Normal file
34
src/lib/components/ui/dialog/dialog-content.svelte
Normal file
@@ -0,0 +1,34 @@
|
||||
<script lang="ts">
|
||||
import { Dialog as DialogPrimitive } from 'bits-ui';
|
||||
import * as Dialog from '.';
|
||||
import { cn, flyAndScale } from '$lib/utils';
|
||||
import { X } from 'lucide-svelte';
|
||||
|
||||
type $$Props = DialogPrimitive.ContentProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let transition: $$Props['transition'] = flyAndScale;
|
||||
export let transitionConfig: $$Props['transitionConfig'] = {
|
||||
duration: 200
|
||||
};
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<Dialog.Portal>
|
||||
<Dialog.Overlay />
|
||||
<DialogPrimitive.Content
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
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',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
<DialogPrimitive.Close
|
||||
class="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
||||
<X class="h-4 w-4" />
|
||||
<span class="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
</DialogPrimitive.Content>
|
||||
</Dialog.Portal>
|
15
src/lib/components/ui/dialog/dialog-description.svelte
Normal file
15
src/lib/components/ui/dialog/dialog-description.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { Dialog as DialogPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = DialogPrimitive.DescriptionProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DialogPrimitive.Description
|
||||
class={cn('text-sm text-muted-foreground', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</DialogPrimitive.Description>
|
18
src/lib/components/ui/dialog/dialog-footer.svelte
Normal file
18
src/lib/components/ui/dialog/dialog-footer.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn(
|
||||
'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
15
src/lib/components/ui/dialog/dialog-header.svelte
Normal file
15
src/lib/components/ui/dialog/dialog-header.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn('flex flex-col space-y-1.5 text-center sm:text-left', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
20
src/lib/components/ui/dialog/dialog-overlay.svelte
Normal file
20
src/lib/components/ui/dialog/dialog-overlay.svelte
Normal file
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { Dialog as DialogPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
import { fade } from 'svelte/transition';
|
||||
|
||||
type $$Props = DialogPrimitive.OverlayProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export let transition: $$Props['transition'] = fade;
|
||||
export let transitionConfig: $$Props['transitionConfig'] = {
|
||||
duration: 150
|
||||
};
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DialogPrimitive.Overlay
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
class={cn('fixed inset-0 z-50 bg-background/80 backdrop-blur-sm', className)}
|
||||
{...$$restProps} />
|
8
src/lib/components/ui/dialog/dialog-portal.svelte
Normal file
8
src/lib/components/ui/dialog/dialog-portal.svelte
Normal file
@@ -0,0 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { Dialog as DialogPrimitive } from 'bits-ui';
|
||||
type $$Props = DialogPrimitive.PortalProps;
|
||||
</script>
|
||||
|
||||
<DialogPrimitive.Portal {...$$restProps}>
|
||||
<slot />
|
||||
</DialogPrimitive.Portal>
|
15
src/lib/components/ui/dialog/dialog-title.svelte
Normal file
15
src/lib/components/ui/dialog/dialog-title.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { Dialog as DialogPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = DialogPrimitive.TitleProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DialogPrimitive.Title
|
||||
class={cn('text-lg font-semibold leading-none tracking-tight', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</DialogPrimitive.Title>
|
34
src/lib/components/ui/dialog/index.ts
Normal file
34
src/lib/components/ui/dialog/index.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Dialog as DialogPrimitive } from 'bits-ui';
|
||||
|
||||
const Root = DialogPrimitive.Root;
|
||||
const Trigger = DialogPrimitive.Trigger;
|
||||
|
||||
import Title from './dialog-title.svelte';
|
||||
import Portal from './dialog-portal.svelte';
|
||||
import Footer from './dialog-footer.svelte';
|
||||
import Header from './dialog-header.svelte';
|
||||
import Overlay from './dialog-overlay.svelte';
|
||||
import Content from './dialog-content.svelte';
|
||||
import Description from './dialog-description.svelte';
|
||||
|
||||
export {
|
||||
Root,
|
||||
Title,
|
||||
Portal,
|
||||
Footer,
|
||||
Header,
|
||||
Trigger,
|
||||
Overlay,
|
||||
Content,
|
||||
Description,
|
||||
//
|
||||
Root as Dialog,
|
||||
Title as DialogTitle,
|
||||
Portal as DialogPortal,
|
||||
Footer as DialogFooter,
|
||||
Header as DialogHeader,
|
||||
Trigger as DialogTrigger,
|
||||
Overlay as DialogOverlay,
|
||||
Content as DialogContent,
|
||||
Description as DialogDescription
|
||||
};
|
23
src/lib/components/ui/drawer/drawer-content.svelte
Normal file
23
src/lib/components/ui/drawer/drawer-content.svelte
Normal file
@@ -0,0 +1,23 @@
|
||||
<script lang="ts">
|
||||
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
|
||||
import DrawerOverlay from './drawer-overlay.svelte';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = DrawerPrimitive.ContentProps;
|
||||
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DrawerPrimitive.Portal>
|
||||
<DrawerOverlay />
|
||||
<DrawerPrimitive.Content
|
||||
class={cn(
|
||||
'fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background',
|
||||
className
|
||||
)}
|
||||
{...$$restProps}>
|
||||
<div class="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
|
||||
<slot />
|
||||
</DrawerPrimitive.Content>
|
||||
</DrawerPrimitive.Portal>
|
17
src/lib/components/ui/drawer/drawer-description.svelte
Normal file
17
src/lib/components/ui/drawer/drawer-description.svelte
Normal file
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = DrawerPrimitive.DescriptionProps;
|
||||
|
||||
export let el: $$Props['el'] = undefined;
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DrawerPrimitive.Description
|
||||
bind:el
|
||||
class={cn('text-sm text-muted-foreground', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</DrawerPrimitive.Description>
|
19
src/lib/components/ui/drawer/drawer-footer.svelte
Normal file
19
src/lib/components/ui/drawer/drawer-footer.svelte
Normal file
@@ -0,0 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement> & {
|
||||
el?: HTMLDivElement;
|
||||
};
|
||||
|
||||
export let el: $$Props['el'] = undefined;
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
bind:this={el}
|
||||
class={cn('mt-auto flex flex-col gap-2 p-4', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
18
src/lib/components/ui/drawer/drawer-header.svelte
Normal file
18
src/lib/components/ui/drawer/drawer-header.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement> & {
|
||||
el?: HTMLDivElement;
|
||||
};
|
||||
export let el: $$Props['el'] = undefined;
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
bind:this={el}
|
||||
class={cn('grid gap-1.5 p-4 text-center sm:text-left', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
17
src/lib/components/ui/drawer/drawer-overlay.svelte
Normal file
17
src/lib/components/ui/drawer/drawer-overlay.svelte
Normal file
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = DrawerPrimitive.OverlayProps;
|
||||
|
||||
export let el: $$Props['el'] = undefined;
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DrawerPrimitive.Overlay
|
||||
bind:el
|
||||
class={cn('fixed inset-0 z-50 bg-black/80', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</DrawerPrimitive.Overlay>
|
17
src/lib/components/ui/drawer/drawer-title.svelte
Normal file
17
src/lib/components/ui/drawer/drawer-title.svelte
Normal file
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
type $$Props = DrawerPrimitive.TitleProps;
|
||||
|
||||
export let el: $$Props['el'] = undefined;
|
||||
let className: $$Props['class'] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<DrawerPrimitive.Title
|
||||
bind:el
|
||||
class={cn('text-lg font-semibold leading-none tracking-tight', className)}
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</DrawerPrimitive.Title>
|
16
src/lib/components/ui/drawer/drawer.svelte
Normal file
16
src/lib/components/ui/drawer/drawer.svelte
Normal file
@@ -0,0 +1,16 @@
|
||||
<script lang="ts">
|
||||
import { Drawer as DrawerPrimitive } from 'vaul-svelte';
|
||||
|
||||
type $$Props = DrawerPrimitive.Props;
|
||||
export let shouldScaleBackground: $$Props['shouldScaleBackground'] = true;
|
||||
export let open: $$Props['open'] = false;
|
||||
export let activeSnapPoint: $$Props['activeSnapPoint'] = undefined;
|
||||
</script>
|
||||
|
||||
<DrawerPrimitive.Root
|
||||
{shouldScaleBackground}
|
||||
bind:open
|
||||
bind:activeSnapPoint
|
||||
{...$$restProps}>
|
||||
<slot />
|
||||
</DrawerPrimitive.Root>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user