added svelte-shadcn
This commit is contained in:
@@ -18,6 +18,13 @@ module.exports = {
|
|||||||
args: 'after-used',
|
args: 'after-used',
|
||||||
argsIgnorePattern: '^_'
|
argsIgnorePattern: '^_'
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"@typescript-eslint/no-unused-vars": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"argsIgnorePattern": "^_",
|
||||||
|
"varsIgnorePattern": "^\$\$(Props|Events|Slots|Generic)$"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
plugins: ['svelte3', '@typescript-eslint', 'unused-imports'],
|
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"
|
"src/**/*.{js,ts,svelte,css,scss,postcss,md,json}": "prettier --write --ignore-unknown"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@changesets/cli": "^2.26.1",
|
"@changesets/cli": "^2.27.1",
|
||||||
"@fontsource/roboto": "^4.5.8",
|
"@fontsource/roboto": "^5.0.8",
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
"@fortawesome/fontawesome-svg-core": "^6.5.1",
|
||||||
"@fortawesome/free-brands-svg-icons": "^6.4.0",
|
"@fortawesome/free-brands-svg-icons": "^6.5.1",
|
||||||
"@fortawesome/free-regular-svg-icons": "^6.4.0",
|
"@fortawesome/free-regular-svg-icons": "^6.5.1",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
||||||
"@sveltejs/vite-plugin-svelte": "^2.2.0",
|
"@sveltejs/vite-plugin-svelte": "^3.0.1",
|
||||||
"@tauri-apps/api": "^1.3.0",
|
"@tauri-apps/api": "^1.5.3",
|
||||||
"@tauri-apps/cli": "^1.3.1",
|
"@tauri-apps/cli": "^1.5.9",
|
||||||
"@tsconfig/svelte": "^4.0.1",
|
"@tsconfig/svelte": "^5.0.2",
|
||||||
"@types/node": "18.15.3",
|
"@types/node": "20.11.5",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.6",
|
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
||||||
"@typescript-eslint/parser": "^5.59.6",
|
"@typescript-eslint/parser": "^6.19.0",
|
||||||
"autoprefixer": "^10.4.14",
|
"autoprefixer": "^10.4.17",
|
||||||
"daisyui": "^2.51.6",
|
"eslint": "^8.56.0",
|
||||||
"eslint": "^8.40.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-config-prettier": "^8.8.0",
|
|
||||||
"eslint-plugin-json": "^3.1.0",
|
"eslint-plugin-json": "^3.1.0",
|
||||||
"eslint-plugin-svelte3": "^4.0.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",
|
"husky": "^8.0.3",
|
||||||
"lint-staged": "^13.2.2",
|
"lint-staged": "^15.2.0",
|
||||||
"postcss": "^8.4.23",
|
"postcss": "^8.4.33",
|
||||||
"postcss-load-config": "^4.0.1",
|
"postcss-load-config": "^5.0.2",
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^3.2.4",
|
||||||
"prettier-plugin-svelte": "^2.10.0",
|
"prettier-plugin-svelte": "^3.1.2",
|
||||||
"prettier-plugin-tailwindcss": "^0.3.0",
|
"prettier-plugin-tailwindcss": "^0.5.11",
|
||||||
"svelte": "^3.59.1",
|
"svelte": "^4.2.9",
|
||||||
"svelte-check": "^3.3.2",
|
"svelte-check": "^3.6.3",
|
||||||
"svelte-fa": "^3.0.3",
|
"svelte-fa": "^4.0.2",
|
||||||
"svelte-preprocess": "^5.0.3",
|
"svelte-preprocess": "^5.1.3",
|
||||||
"svelte-spa-router": "^3.3.0",
|
"svelte-spa-router": "^4.0.1",
|
||||||
"tailwindcss": "^3.3.2",
|
"tailwindcss": "^3.4.1",
|
||||||
"tailwindcss-hero-patterns": "^0.1.2",
|
"tailwindcss-hero-patterns": "^0.1.2",
|
||||||
"tslib": "^2.5.1",
|
"tslib": "^2.6.2",
|
||||||
"typescript": "^5.0.4",
|
"typescript": "^5.3.3",
|
||||||
"vite": "^4.3.7"
|
"vite": "^5.0.11"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@8.5.0",
|
"packageManager": "pnpm@8.5.0",
|
||||||
"engineStrict": true,
|
"engineStrict": false,
|
||||||
"engines": {
|
"engines": {
|
||||||
"pnpm": ">=8.5.0",
|
"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