diff --git a/src/lib/components/ui/accordion/accordion-content.svelte b/src/lib/components/ui/accordion/accordion-content.svelte new file mode 100644 index 0000000..b0617ae --- /dev/null +++ b/src/lib/components/ui/accordion/accordion-content.svelte @@ -0,0 +1,27 @@ + + + +
+ {@render children?.()} +
+
diff --git a/src/lib/components/ui/accordion/accordion-item.svelte b/src/lib/components/ui/accordion/accordion-item.svelte new file mode 100644 index 0000000..9d3919d --- /dev/null +++ b/src/lib/components/ui/accordion/accordion-item.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/accordion/accordion-trigger.svelte b/src/lib/components/ui/accordion/accordion-trigger.svelte new file mode 100644 index 0000000..2a46555 --- /dev/null +++ b/src/lib/components/ui/accordion/accordion-trigger.svelte @@ -0,0 +1,32 @@ + + + + + {@render children?.()} + + + diff --git a/src/lib/components/ui/accordion/accordion.svelte b/src/lib/components/ui/accordion/accordion.svelte new file mode 100644 index 0000000..b19a3c5 --- /dev/null +++ b/src/lib/components/ui/accordion/accordion.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/components/ui/accordion/index.ts b/src/lib/components/ui/accordion/index.ts new file mode 100644 index 0000000..ac343a1 --- /dev/null +++ b/src/lib/components/ui/accordion/index.ts @@ -0,0 +1,16 @@ +import Root from "./accordion.svelte"; +import Content from "./accordion-content.svelte"; +import Item from "./accordion-item.svelte"; +import Trigger from "./accordion-trigger.svelte"; + +export { + Root, + Content, + Item, + Trigger, + // + Root as Accordion, + Content as AccordionContent, + Item as AccordionItem, + Trigger as AccordionTrigger, +}; diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte new file mode 100644 index 0000000..7e63004 --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte @@ -0,0 +1,27 @@ + + + diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte new file mode 100644 index 0000000..a4ce03c --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte @@ -0,0 +1,27 @@ + + + diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte new file mode 100644 index 0000000..c9b3eb3 --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte @@ -0,0 +1,32 @@ + + + + + + diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte new file mode 100644 index 0000000..5024f3f --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte new file mode 100644 index 0000000..f4214db --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte new file mode 100644 index 0000000..d6df4d3 --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-media.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-media.svelte new file mode 100644 index 0000000..3f634f3 --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-media.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte new file mode 100644 index 0000000..9ffcc85 --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-portal.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-portal.svelte new file mode 100644 index 0000000..f0a19a8 --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte new file mode 100644 index 0000000..652da33 --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte new file mode 100644 index 0000000..b22d1d5 --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/alert-dialog/alert-dialog.svelte b/src/lib/components/ui/alert-dialog/alert-dialog.svelte new file mode 100644 index 0000000..7ea78bb --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/alert-dialog/index.ts b/src/lib/components/ui/alert-dialog/index.ts new file mode 100644 index 0000000..ca81c2a --- /dev/null +++ b/src/lib/components/ui/alert-dialog/index.ts @@ -0,0 +1,40 @@ +import Root from "./alert-dialog.svelte"; +import Portal from "./alert-dialog-portal.svelte"; +import Trigger from "./alert-dialog-trigger.svelte"; +import Title from "./alert-dialog-title.svelte"; +import Action from "./alert-dialog-action.svelte"; +import Cancel from "./alert-dialog-cancel.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"; +import Media from "./alert-dialog-media.svelte"; + +export { + Root, + Title, + Action, + Cancel, + Portal, + Footer, + Header, + Trigger, + Overlay, + Content, + Description, + Media, + // + 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, + Media as AlertDialogMedia, +}; diff --git a/src/lib/components/ui/alert/alert-action.svelte b/src/lib/components/ui/alert/alert-action.svelte new file mode 100644 index 0000000..1877d38 --- /dev/null +++ b/src/lib/components/ui/alert/alert-action.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/alert/alert-description.svelte b/src/lib/components/ui/alert/alert-description.svelte new file mode 100644 index 0000000..7ee6039 --- /dev/null +++ b/src/lib/components/ui/alert/alert-description.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/alert/alert-title.svelte b/src/lib/components/ui/alert/alert-title.svelte new file mode 100644 index 0000000..3e339a3 --- /dev/null +++ b/src/lib/components/ui/alert/alert-title.svelte @@ -0,0 +1,23 @@ + + +
svg]/alert:col-start-2 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3", + className + )} + {...restProps} +> + {@render children?.()} +
diff --git a/src/lib/components/ui/alert/alert.svelte b/src/lib/components/ui/alert/alert.svelte new file mode 100644 index 0000000..abf7487 --- /dev/null +++ b/src/lib/components/ui/alert/alert.svelte @@ -0,0 +1,43 @@ + + + + + diff --git a/src/lib/components/ui/alert/index.ts b/src/lib/components/ui/alert/index.ts new file mode 100644 index 0000000..071b113 --- /dev/null +++ b/src/lib/components/ui/alert/index.ts @@ -0,0 +1,17 @@ +import Root from "./alert.svelte"; +import Description from "./alert-description.svelte"; +import Title from "./alert-title.svelte"; +import Action from "./alert-action.svelte"; +export { alertVariants, type AlertVariant } from "./alert.svelte"; + +export { + Root, + Description, + Title, + Action, + // + Root as Alert, + Description as AlertDescription, + Title as AlertTitle, + Action as AlertAction, +}; diff --git a/src/lib/components/ui/aspect-ratio/aspect-ratio.svelte b/src/lib/components/ui/aspect-ratio/aspect-ratio.svelte new file mode 100644 index 0000000..815aab0 --- /dev/null +++ b/src/lib/components/ui/aspect-ratio/aspect-ratio.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/aspect-ratio/index.ts b/src/lib/components/ui/aspect-ratio/index.ts new file mode 100644 index 0000000..985c75f --- /dev/null +++ b/src/lib/components/ui/aspect-ratio/index.ts @@ -0,0 +1,3 @@ +import Root from "./aspect-ratio.svelte"; + +export { Root, Root as AspectRatio }; diff --git a/src/lib/components/ui/avatar/avatar-badge.svelte b/src/lib/components/ui/avatar/avatar-badge.svelte new file mode 100644 index 0000000..ca9d9ed --- /dev/null +++ b/src/lib/components/ui/avatar/avatar-badge.svelte @@ -0,0 +1,26 @@ + + +svg]:hidden", + "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2", + "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2", + className + )} + {...restProps} +> + {@render children?.()} + diff --git a/src/lib/components/ui/avatar/avatar-fallback.svelte b/src/lib/components/ui/avatar/avatar-fallback.svelte new file mode 100644 index 0000000..63c8b02 --- /dev/null +++ b/src/lib/components/ui/avatar/avatar-fallback.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/lib/components/ui/avatar/avatar-group-count.svelte b/src/lib/components/ui/avatar/avatar-group-count.svelte new file mode 100644 index 0000000..c89684a --- /dev/null +++ b/src/lib/components/ui/avatar/avatar-group-count.svelte @@ -0,0 +1,23 @@ + + +
svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3 ring-background relative flex shrink-0 items-center justify-center ring-2", + className + )} + {...restProps} +> + {@render children?.()} +
diff --git a/src/lib/components/ui/avatar/avatar-group.svelte b/src/lib/components/ui/avatar/avatar-group.svelte new file mode 100644 index 0000000..78714fc --- /dev/null +++ b/src/lib/components/ui/avatar/avatar-group.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/avatar/avatar-image.svelte b/src/lib/components/ui/avatar/avatar-image.svelte new file mode 100644 index 0000000..f41cf8f --- /dev/null +++ b/src/lib/components/ui/avatar/avatar-image.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/avatar/avatar.svelte b/src/lib/components/ui/avatar/avatar.svelte new file mode 100644 index 0000000..ea6fde5 --- /dev/null +++ b/src/lib/components/ui/avatar/avatar.svelte @@ -0,0 +1,26 @@ + + + diff --git a/src/lib/components/ui/avatar/index.ts b/src/lib/components/ui/avatar/index.ts new file mode 100644 index 0000000..38ccef8 --- /dev/null +++ b/src/lib/components/ui/avatar/index.ts @@ -0,0 +1,22 @@ +import Root from "./avatar.svelte"; +import Image from "./avatar-image.svelte"; +import Fallback from "./avatar-fallback.svelte"; +import Badge from "./avatar-badge.svelte"; +import Group from "./avatar-group.svelte"; +import GroupCount from "./avatar-group-count.svelte"; + +export { + Root, + Image, + Fallback, + Badge, + Group, + GroupCount, + // + Root as Avatar, + Image as AvatarImage, + Fallback as AvatarFallback, + Badge as AvatarBadge, + Group as AvatarGroup, + GroupCount as AvatarGroupCount, +}; diff --git a/src/lib/components/ui/badge/badge.svelte b/src/lib/components/ui/badge/badge.svelte new file mode 100644 index 0000000..51bbc23 --- /dev/null +++ b/src/lib/components/ui/badge/badge.svelte @@ -0,0 +1,49 @@ + + + + + + {@render children?.()} + diff --git a/src/lib/components/ui/badge/index.ts b/src/lib/components/ui/badge/index.ts new file mode 100644 index 0000000..64e0aa9 --- /dev/null +++ b/src/lib/components/ui/badge/index.ts @@ -0,0 +1,2 @@ +export { default as Badge } from "./badge.svelte"; +export { badgeVariants, type BadgeVariant } from "./badge.svelte"; diff --git a/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte b/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte new file mode 100644 index 0000000..9e1e22c --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte @@ -0,0 +1,23 @@ + + + diff --git a/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte b/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte new file mode 100644 index 0000000..e9c77ea --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte @@ -0,0 +1,20 @@ + + +
  • + {@render children?.()} +
  • diff --git a/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte b/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte new file mode 100644 index 0000000..e6bc17d --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte @@ -0,0 +1,31 @@ + + +{#if child} + {@render child({ props: attrs })} +{:else} + + {@render children?.()} + +{/if} diff --git a/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte b/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte new file mode 100644 index 0000000..4873cf0 --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte @@ -0,0 +1,20 @@ + + +
      + {@render children?.()} +
    diff --git a/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte b/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte new file mode 100644 index 0000000..5fb6979 --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte b/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte new file mode 100644 index 0000000..0f62fba --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte @@ -0,0 +1,27 @@ + + + diff --git a/src/lib/components/ui/breadcrumb/breadcrumb.svelte b/src/lib/components/ui/breadcrumb/breadcrumb.svelte new file mode 100644 index 0000000..29ea3f5 --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb.svelte @@ -0,0 +1,22 @@ + + + diff --git a/src/lib/components/ui/breadcrumb/index.ts b/src/lib/components/ui/breadcrumb/index.ts new file mode 100644 index 0000000..dc914ec --- /dev/null +++ b/src/lib/components/ui/breadcrumb/index.ts @@ -0,0 +1,25 @@ +import Root from "./breadcrumb.svelte"; +import Ellipsis from "./breadcrumb-ellipsis.svelte"; +import Item from "./breadcrumb-item.svelte"; +import Separator from "./breadcrumb-separator.svelte"; +import Link from "./breadcrumb-link.svelte"; +import List from "./breadcrumb-list.svelte"; +import Page from "./breadcrumb-page.svelte"; + +export { + Root, + Ellipsis, + Item, + Separator, + Link, + List, + Page, + // + Root as Breadcrumb, + Ellipsis as BreadcrumbEllipsis, + Item as BreadcrumbItem, + Separator as BreadcrumbSeparator, + Link as BreadcrumbLink, + List as BreadcrumbList, + Page as BreadcrumbPage, +}; diff --git a/src/lib/components/ui/button-group/button-group-separator.svelte b/src/lib/components/ui/button-group/button-group-separator.svelte new file mode 100644 index 0000000..a13f023 --- /dev/null +++ b/src/lib/components/ui/button-group/button-group-separator.svelte @@ -0,0 +1,23 @@ + + + diff --git a/src/lib/components/ui/button-group/button-group-text.svelte b/src/lib/components/ui/button-group/button-group-text.svelte new file mode 100644 index 0000000..67c0a28 --- /dev/null +++ b/src/lib/components/ui/button-group/button-group-text.svelte @@ -0,0 +1,28 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} +
    + {@render mergedProps.children?.()} +
    +{/if} diff --git a/src/lib/components/ui/button-group/button-group.svelte b/src/lib/components/ui/button-group/button-group.svelte new file mode 100644 index 0000000..06d48dc --- /dev/null +++ b/src/lib/components/ui/button-group/button-group.svelte @@ -0,0 +1,46 @@ + + + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/button-group/index.ts b/src/lib/components/ui/button-group/index.ts new file mode 100644 index 0000000..664167f --- /dev/null +++ b/src/lib/components/ui/button-group/index.ts @@ -0,0 +1,15 @@ +import Root, { buttonGroupVariants, type ButtonGroupOrientation } from "./button-group.svelte"; +import Text from "./button-group-text.svelte"; +import Separator from "./button-group-separator.svelte"; + +export { + Root, + Text, + Separator, + buttonGroupVariants, + type ButtonGroupOrientation, + // + Root as ButtonGroup, + Text as ButtonGroupText, + Separator as ButtonGroupSeparator, +}; diff --git a/src/lib/components/ui/button/button.svelte b/src/lib/components/ui/button/button.svelte new file mode 100644 index 0000000..89cedcb --- /dev/null +++ b/src/lib/components/ui/button/button.svelte @@ -0,0 +1,82 @@ + + + + +{#if href} + + {@render children?.()} + +{:else} + +{/if} diff --git a/src/lib/components/ui/button/index.ts b/src/lib/components/ui/button/index.ts new file mode 100644 index 0000000..fb585d7 --- /dev/null +++ b/src/lib/components/ui/button/index.ts @@ -0,0 +1,17 @@ +import Root, { + type ButtonProps, + type ButtonSize, + type ButtonVariant, + buttonVariants, +} from "./button.svelte"; + +export { + Root, + type ButtonProps as Props, + // + Root as Button, + buttonVariants, + type ButtonProps, + type ButtonSize, + type ButtonVariant, +}; diff --git a/src/lib/components/ui/calendar/calendar-caption.svelte b/src/lib/components/ui/calendar/calendar-caption.svelte new file mode 100644 index 0000000..5c93037 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-caption.svelte @@ -0,0 +1,76 @@ + + +{#snippet MonthSelect()} + { + if (!placeholder) return; + const v = Number.parseInt(e.currentTarget.value); + const newPlaceholder = placeholder.set({ month: v }); + placeholder = newPlaceholder.subtract({ months: monthIndex }); + }} + /> +{/snippet} + +{#snippet YearSelect()} + +{/snippet} + +{#if captionLayout === "dropdown"} + {@render MonthSelect()} + {@render YearSelect()} +{:else if captionLayout === "dropdown-months"} + {@render MonthSelect()} + {#if placeholder} + {formatYear(placeholder)} + {/if} +{:else if captionLayout === "dropdown-years"} + {#if placeholder} + {formatMonth(placeholder)} + {/if} + {@render YearSelect()} +{:else} + {formatMonth(month)} {formatYear(month)} +{/if} diff --git a/src/lib/components/ui/calendar/calendar-cell.svelte b/src/lib/components/ui/calendar/calendar-cell.svelte new file mode 100644 index 0000000..7ceb5e1 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-cell.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/components/ui/calendar/calendar-day.svelte b/src/lib/components/ui/calendar/calendar-day.svelte new file mode 100644 index 0000000..edc8c9d --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-day.svelte @@ -0,0 +1,33 @@ + + +span]:text-xs [&>span]:opacity-70", + className + )} + {...restProps} +/> diff --git a/src/lib/components/ui/calendar/calendar-grid-body.svelte b/src/lib/components/ui/calendar/calendar-grid-body.svelte new file mode 100644 index 0000000..8cd86de --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-grid-body.svelte @@ -0,0 +1,12 @@ + + + diff --git a/src/lib/components/ui/calendar/calendar-grid-head.svelte b/src/lib/components/ui/calendar/calendar-grid-head.svelte new file mode 100644 index 0000000..333edc4 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-grid-head.svelte @@ -0,0 +1,12 @@ + + + diff --git a/src/lib/components/ui/calendar/calendar-grid-row.svelte b/src/lib/components/ui/calendar/calendar-grid-row.svelte new file mode 100644 index 0000000..9032236 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-grid-row.svelte @@ -0,0 +1,12 @@ + + + diff --git a/src/lib/components/ui/calendar/calendar-grid.svelte b/src/lib/components/ui/calendar/calendar-grid.svelte new file mode 100644 index 0000000..5fbb18f --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-grid.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/calendar/calendar-head-cell.svelte b/src/lib/components/ui/calendar/calendar-head-cell.svelte new file mode 100644 index 0000000..131807e --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-head-cell.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/components/ui/calendar/calendar-header.svelte b/src/lib/components/ui/calendar/calendar-header.svelte new file mode 100644 index 0000000..c39e955 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-header.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/components/ui/calendar/calendar-heading.svelte b/src/lib/components/ui/calendar/calendar-heading.svelte new file mode 100644 index 0000000..a9b9810 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-heading.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/calendar/calendar-month-select.svelte b/src/lib/components/ui/calendar/calendar-month-select.svelte new file mode 100644 index 0000000..63e76f6 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-month-select.svelte @@ -0,0 +1,48 @@ + + + + + {#snippet child({ props, monthItems, selectedMonthItem })} + + + {/snippet} + + diff --git a/src/lib/components/ui/calendar/calendar-month.svelte b/src/lib/components/ui/calendar/calendar-month.svelte new file mode 100644 index 0000000..7bdafe7 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-month.svelte @@ -0,0 +1,15 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/calendar/calendar-months.svelte b/src/lib/components/ui/calendar/calendar-months.svelte new file mode 100644 index 0000000..f717a9d --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-months.svelte @@ -0,0 +1,19 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/calendar/calendar-nav.svelte b/src/lib/components/ui/calendar/calendar-nav.svelte new file mode 100644 index 0000000..27f33d7 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-nav.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/components/ui/calendar/calendar-next-button.svelte b/src/lib/components/ui/calendar/calendar-next-button.svelte new file mode 100644 index 0000000..cc5e8a9 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-next-button.svelte @@ -0,0 +1,36 @@ + + +{#snippet Fallback()} + +{/snippet} + + + {#if children} + {@render children?.()} + {:else} + {@render Fallback()} + {/if} + diff --git a/src/lib/components/ui/calendar/calendar-prev-button.svelte b/src/lib/components/ui/calendar/calendar-prev-button.svelte new file mode 100644 index 0000000..fc0dd6c --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-prev-button.svelte @@ -0,0 +1,36 @@ + + +{#snippet Fallback()} + +{/snippet} + + + {#if children} + {@render children?.()} + {:else} + {@render Fallback()} + {/if} + diff --git a/src/lib/components/ui/calendar/calendar-year-select.svelte b/src/lib/components/ui/calendar/calendar-year-select.svelte new file mode 100644 index 0000000..bb580be --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-year-select.svelte @@ -0,0 +1,47 @@ + + + + + {#snippet child({ props, yearItems, selectedYearItem })} + + + {/snippet} + + diff --git a/src/lib/components/ui/calendar/calendar.svelte b/src/lib/components/ui/calendar/calendar.svelte new file mode 100644 index 0000000..463d571 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar.svelte @@ -0,0 +1,115 @@ + + + + + {#snippet children({ months, weekdays })} + + + + + + {#each months as month, monthIndex (month)} + + + + + + + + {#each weekdays as weekday, i (i)} + + {weekday.slice(0, 2)} + + {/each} + + + + {#each month.weeks as weekDates (weekDates)} + + {#each weekDates as date (date)} + + {#if day} + {@render day({ + day: date, + outsideMonth: !isEqualMonth(date, month.value), + })} + {:else} + + {/if} + + {/each} + + {/each} + + + + {/each} + + {/snippet} + diff --git a/src/lib/components/ui/calendar/index.ts b/src/lib/components/ui/calendar/index.ts new file mode 100644 index 0000000..f3a16d2 --- /dev/null +++ b/src/lib/components/ui/calendar/index.ts @@ -0,0 +1,40 @@ +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"; +import MonthSelect from "./calendar-month-select.svelte"; +import YearSelect from "./calendar-year-select.svelte"; +import Month from "./calendar-month.svelte"; +import Nav from "./calendar-nav.svelte"; +import Caption from "./calendar-caption.svelte"; + +export { + Day, + Cell, + Grid, + Header, + Months, + GridRow, + Heading, + GridBody, + GridHead, + HeadCell, + NextButton, + PrevButton, + Nav, + Month, + YearSelect, + MonthSelect, + Caption, + // + Root as Calendar, +}; diff --git a/src/lib/components/ui/card/card-action.svelte b/src/lib/components/ui/card/card-action.svelte new file mode 100644 index 0000000..7c48844 --- /dev/null +++ b/src/lib/components/ui/card/card-action.svelte @@ -0,0 +1,23 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/card/card-content.svelte b/src/lib/components/ui/card/card-content.svelte new file mode 100644 index 0000000..4f60ee3 --- /dev/null +++ b/src/lib/components/ui/card/card-content.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/card/card-description.svelte b/src/lib/components/ui/card/card-description.svelte new file mode 100644 index 0000000..9b20ac7 --- /dev/null +++ b/src/lib/components/ui/card/card-description.svelte @@ -0,0 +1,20 @@ + + +

    + {@render children?.()} +

    diff --git a/src/lib/components/ui/card/card-footer.svelte b/src/lib/components/ui/card/card-footer.svelte new file mode 100644 index 0000000..1efff6d --- /dev/null +++ b/src/lib/components/ui/card/card-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/card/card-header.svelte b/src/lib/components/ui/card/card-header.svelte new file mode 100644 index 0000000..7eb69e1 --- /dev/null +++ b/src/lib/components/ui/card/card-header.svelte @@ -0,0 +1,23 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/card/card-title.svelte b/src/lib/components/ui/card/card-title.svelte new file mode 100644 index 0000000..1523fc5 --- /dev/null +++ b/src/lib/components/ui/card/card-title.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/card/card.svelte b/src/lib/components/ui/card/card.svelte new file mode 100644 index 0000000..2b4f81a --- /dev/null +++ b/src/lib/components/ui/card/card.svelte @@ -0,0 +1,22 @@ + + +
    img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col", className)} + {...restProps} +> + {@render children?.()} +
    diff --git a/src/lib/components/ui/card/index.ts b/src/lib/components/ui/card/index.ts new file mode 100644 index 0000000..4d3fce4 --- /dev/null +++ b/src/lib/components/ui/card/index.ts @@ -0,0 +1,25 @@ +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"; +import Action from "./card-action.svelte"; + +export { + Root, + Content, + Description, + Footer, + Header, + Title, + Action, + // + Root as Card, + Content as CardContent, + Description as CardDescription, + Footer as CardFooter, + Header as CardHeader, + Title as CardTitle, + Action as CardAction, +}; diff --git a/src/lib/components/ui/carousel/carousel-content.svelte b/src/lib/components/ui/carousel/carousel-content.svelte new file mode 100644 index 0000000..84c71f8 --- /dev/null +++ b/src/lib/components/ui/carousel/carousel-content.svelte @@ -0,0 +1,43 @@ + + +
    +
    + {@render children?.()} +
    +
    diff --git a/src/lib/components/ui/carousel/carousel-item.svelte b/src/lib/components/ui/carousel/carousel-item.svelte new file mode 100644 index 0000000..ebf1649 --- /dev/null +++ b/src/lib/components/ui/carousel/carousel-item.svelte @@ -0,0 +1,30 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/carousel/carousel-next.svelte b/src/lib/components/ui/carousel/carousel-next.svelte new file mode 100644 index 0000000..194932a --- /dev/null +++ b/src/lib/components/ui/carousel/carousel-next.svelte @@ -0,0 +1,39 @@ + + + diff --git a/src/lib/components/ui/carousel/carousel-previous.svelte b/src/lib/components/ui/carousel/carousel-previous.svelte new file mode 100644 index 0000000..5020ab8 --- /dev/null +++ b/src/lib/components/ui/carousel/carousel-previous.svelte @@ -0,0 +1,39 @@ + + + diff --git a/src/lib/components/ui/carousel/carousel.svelte b/src/lib/components/ui/carousel/carousel.svelte new file mode 100644 index 0000000..b3933b8 --- /dev/null +++ b/src/lib/components/ui/carousel/carousel.svelte @@ -0,0 +1,94 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/carousel/context.ts b/src/lib/components/ui/carousel/context.ts new file mode 100644 index 0000000..a5fd74f --- /dev/null +++ b/src/lib/components/ui/carousel/context.ts @@ -0,0 +1,58 @@ +import type { WithElementRef } from "$lib/utils.js"; +import type { + EmblaCarouselSvelteType, + default as emblaCarouselSvelte, +} from "embla-carousel-svelte"; +import { getContext, hasContext, setContext } from "svelte"; +import type { HTMLAttributes } from "svelte/elements"; + +export type CarouselAPI = + NonNullable["on:emblaInit"]> extends ( + evt: CustomEvent + ) => void + ? CarouselAPI + : never; + +type EmblaCarouselConfig = NonNullable[1]>; + +export type CarouselOptions = EmblaCarouselConfig["options"]; +export type CarouselPlugins = EmblaCarouselConfig["plugins"]; + +//// + +export type CarouselProps = { + opts?: CarouselOptions; + plugins?: CarouselPlugins; + setApi?: (api: CarouselAPI | undefined) => void; + orientation?: "horizontal" | "vertical"; +} & WithElementRef>; + +const EMBLA_CAROUSEL_CONTEXT = Symbol("EMBLA_CAROUSEL_CONTEXT"); + +export type EmblaContext = { + api: CarouselAPI | undefined; + orientation: "horizontal" | "vertical"; + scrollNext: () => void; + scrollPrev: () => void; + canScrollNext: boolean; + canScrollPrev: boolean; + handleKeyDown: (e: KeyboardEvent) => void; + options: CarouselOptions; + plugins: CarouselPlugins; + onInit: (e: CustomEvent) => void; + scrollTo: (index: number, jump?: boolean) => void; + scrollSnaps: number[]; + selectedIndex: number; +}; + +export function setEmblaContext(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 component`); + } + return getContext>(EMBLA_CAROUSEL_CONTEXT); +} diff --git a/src/lib/components/ui/carousel/index.ts b/src/lib/components/ui/carousel/index.ts new file mode 100644 index 0000000..957fc74 --- /dev/null +++ b/src/lib/components/ui/carousel/index.ts @@ -0,0 +1,19 @@ +import Root from "./carousel.svelte"; +import Content from "./carousel-content.svelte"; +import Item from "./carousel-item.svelte"; +import Previous from "./carousel-previous.svelte"; +import Next from "./carousel-next.svelte"; + +export { + Root, + Content, + Item, + Previous, + Next, + // + Root as Carousel, + Content as CarouselContent, + Item as CarouselItem, + Previous as CarouselPrevious, + Next as CarouselNext, +}; diff --git a/src/lib/components/ui/chart/chart-container.svelte b/src/lib/components/ui/chart/chart-container.svelte new file mode 100644 index 0000000..1eb8e39 --- /dev/null +++ b/src/lib/components/ui/chart/chart-container.svelte @@ -0,0 +1,80 @@ + + +
    + + {@render children?.()} +
    diff --git a/src/lib/components/ui/chart/chart-style.svelte b/src/lib/components/ui/chart/chart-style.svelte new file mode 100644 index 0000000..ea1b3b2 --- /dev/null +++ b/src/lib/components/ui/chart/chart-style.svelte @@ -0,0 +1,37 @@ + + +{#if themeContents} + {#key id} + + {themeContents} + + {/key} +{/if} diff --git a/src/lib/components/ui/chart/chart-tooltip.svelte b/src/lib/components/ui/chart/chart-tooltip.svelte new file mode 100644 index 0000000..e0da9ca --- /dev/null +++ b/src/lib/components/ui/chart/chart-tooltip.svelte @@ -0,0 +1,184 @@ + + +{#snippet TooltipLabel()} + {#if formattedLabel} +
    + {#if typeof formattedLabel === "function"} + {@render formattedLabel()} + {:else} + {formattedLabel} + {/if} +
    + {/if} +{/snippet} + + +
    + {#if !nestLabel} + {@render TooltipLabel()} + {/if} +
    + {#each visibleSeries as item, i (item.key + i)} + {@const key = `${nameKey || item.key || item.label || "value"}`} + {@const itemConfig = getPayloadConfigFromPayload( + chart.config, + item, + key, + chartCtx.tooltip.data + )} + {@const indicatorColor = color || item.config?.color || item.color} +
    svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:size-2.5", + indicator === "dot" && "items-center" + )} + > + {#if formatter && item.value !== undefined && item.label} + {@render formatter({ + value: item.value, + name: item.label, + item, + index: i, + payload: visibleSeries, + })} + {:else} + {#if itemConfig?.icon} + + {:else if !hideIndicator} +
    + {/if} +
    +
    + {#if nestLabel} + {@render TooltipLabel()} + {/if} + + {itemConfig?.label || item.label} + +
    + {#if item.value !== undefined} + + {item.value.toLocaleString()} + + {/if} +
    + {/if} +
    + {/each} +
    +
    +
    diff --git a/src/lib/components/ui/chart/chart-utils.ts b/src/lib/components/ui/chart/chart-utils.ts new file mode 100644 index 0000000..a289e35 --- /dev/null +++ b/src/lib/components/ui/chart/chart-utils.ts @@ -0,0 +1,68 @@ +import type { Tooltip } from "layerchart"; +import { getContext, setContext, type Component, type Snippet } from "svelte"; + +export const THEMES = { light: "", dark: ".dark" } as const; + +export type ChartConfig = { + [k in string]: { + label?: string; + icon?: Component; + } & ( + | { color?: string; theme?: never } + | { color?: never; theme: Record } + ); +}; + +export type ExtractSnippetParams = T extends Snippet<[infer P]> ? P : never; + +export type TooltipPayload = Tooltip.TooltipSeries; + +// Helper to extract item config from a payload. +export function getPayloadConfigFromPayload( + config: ChartConfig, + payload: TooltipPayload, + key: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + data?: Record | null +) { + if (typeof payload !== "object" || payload === null) return undefined; + + const payloadConfig = + "config" in payload && typeof payload.config === "object" && payload.config !== null + ? payload.config + : undefined; + + let configLabelKey: string = key; + + if (payload.key === key) { + configLabelKey = payload.key; + } else if (payload.label === key) { + configLabelKey = payload.label; + } else if (key in payload && typeof payload[key as keyof typeof payload] === "string") { + configLabelKey = payload[key as keyof typeof payload] as string; + } else if ( + payloadConfig !== undefined && + key in payloadConfig && + typeof payloadConfig[key as keyof typeof payloadConfig] === "string" + ) { + configLabelKey = payloadConfig[key as keyof typeof payloadConfig] as string; + } else if (data != null && key in data && typeof data[key] === "string") { + configLabelKey = data[key] as string; + } + + return configLabelKey in config ? config[configLabelKey] : config[key as keyof typeof config]; +} + +type ChartContextValue = { + config: ChartConfig; +}; + +const chartContextKey = Symbol("chart-context"); + +export function setChartContext(value: ChartContextValue) { + return setContext(chartContextKey, value); +} + +export function useChart() { + return getContext(chartContextKey); +} diff --git a/src/lib/components/ui/chart/index.ts b/src/lib/components/ui/chart/index.ts new file mode 100644 index 0000000..f22375e --- /dev/null +++ b/src/lib/components/ui/chart/index.ts @@ -0,0 +1,6 @@ +import ChartContainer from "./chart-container.svelte"; +import ChartTooltip from "./chart-tooltip.svelte"; + +export { getPayloadConfigFromPayload, type ChartConfig } from "./chart-utils.js"; + +export { ChartContainer, ChartTooltip, ChartContainer as Container, ChartTooltip as Tooltip }; diff --git a/src/lib/components/ui/checkbox/checkbox.svelte b/src/lib/components/ui/checkbox/checkbox.svelte new file mode 100644 index 0000000..27b0da6 --- /dev/null +++ b/src/lib/components/ui/checkbox/checkbox.svelte @@ -0,0 +1,39 @@ + + + + {#snippet children({ checked, indeterminate })} +
    + {#if checked} + + {:else if indeterminate} + + {/if} +
    + {/snippet} +
    diff --git a/src/lib/components/ui/checkbox/index.ts b/src/lib/components/ui/checkbox/index.ts new file mode 100644 index 0000000..6d92d94 --- /dev/null +++ b/src/lib/components/ui/checkbox/index.ts @@ -0,0 +1,6 @@ +import Root from "./checkbox.svelte"; +export { + Root, + // + Root as Checkbox, +}; diff --git a/src/lib/components/ui/collapsible/collapsible-content.svelte b/src/lib/components/ui/collapsible/collapsible-content.svelte new file mode 100644 index 0000000..bdabb55 --- /dev/null +++ b/src/lib/components/ui/collapsible/collapsible-content.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/collapsible/collapsible-trigger.svelte b/src/lib/components/ui/collapsible/collapsible-trigger.svelte new file mode 100644 index 0000000..ece7ad6 --- /dev/null +++ b/src/lib/components/ui/collapsible/collapsible-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/collapsible/collapsible.svelte b/src/lib/components/ui/collapsible/collapsible.svelte new file mode 100644 index 0000000..39cdd4e --- /dev/null +++ b/src/lib/components/ui/collapsible/collapsible.svelte @@ -0,0 +1,11 @@ + + + diff --git a/src/lib/components/ui/collapsible/index.ts b/src/lib/components/ui/collapsible/index.ts new file mode 100644 index 0000000..169b479 --- /dev/null +++ b/src/lib/components/ui/collapsible/index.ts @@ -0,0 +1,13 @@ +import Root from "./collapsible.svelte"; +import Trigger from "./collapsible-trigger.svelte"; +import Content from "./collapsible-content.svelte"; + +export { + Root, + Content, + Trigger, + // + Root as Collapsible, + Content as CollapsibleContent, + Trigger as CollapsibleTrigger, +}; diff --git a/src/lib/components/ui/command/command-dialog.svelte b/src/lib/components/ui/command/command-dialog.svelte new file mode 100644 index 0000000..63b445c --- /dev/null +++ b/src/lib/components/ui/command/command-dialog.svelte @@ -0,0 +1,42 @@ + + + + + {title} + {description} + + + + + diff --git a/src/lib/components/ui/command/command-empty.svelte b/src/lib/components/ui/command/command-empty.svelte new file mode 100644 index 0000000..6726cd8 --- /dev/null +++ b/src/lib/components/ui/command/command-empty.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/command/command-group.svelte b/src/lib/components/ui/command/command-group.svelte new file mode 100644 index 0000000..f5da0df --- /dev/null +++ b/src/lib/components/ui/command/command-group.svelte @@ -0,0 +1,32 @@ + + + + {#if heading} + + {heading} + + {/if} + + diff --git a/src/lib/components/ui/command/command-input.svelte b/src/lib/components/ui/command/command-input.svelte new file mode 100644 index 0000000..1ca256f --- /dev/null +++ b/src/lib/components/ui/command/command-input.svelte @@ -0,0 +1,34 @@ + + +
    + + + {#snippet child({ props })} + + {/snippet} + + + + + +
    diff --git a/src/lib/components/ui/command/command-item.svelte b/src/lib/components/ui/command/command-item.svelte new file mode 100644 index 0000000..4246840 --- /dev/null +++ b/src/lib/components/ui/command/command-item.svelte @@ -0,0 +1,25 @@ + + + + {@render children?.()} + + diff --git a/src/lib/components/ui/command/command-link-item.svelte b/src/lib/components/ui/command/command-link-item.svelte new file mode 100644 index 0000000..ada6d2c --- /dev/null +++ b/src/lib/components/ui/command/command-link-item.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/lib/components/ui/command/command-list.svelte b/src/lib/components/ui/command/command-list.svelte new file mode 100644 index 0000000..f663bd3 --- /dev/null +++ b/src/lib/components/ui/command/command-list.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/command/command-loading.svelte b/src/lib/components/ui/command/command-loading.svelte new file mode 100644 index 0000000..19dd298 --- /dev/null +++ b/src/lib/components/ui/command/command-loading.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/command/command-separator.svelte b/src/lib/components/ui/command/command-separator.svelte new file mode 100644 index 0000000..35c4c95 --- /dev/null +++ b/src/lib/components/ui/command/command-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/command/command-shortcut.svelte b/src/lib/components/ui/command/command-shortcut.svelte new file mode 100644 index 0000000..5322e6a --- /dev/null +++ b/src/lib/components/ui/command/command-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/command/command.svelte b/src/lib/components/ui/command/command.svelte new file mode 100644 index 0000000..c814599 --- /dev/null +++ b/src/lib/components/ui/command/command.svelte @@ -0,0 +1,25 @@ + + + diff --git a/src/lib/components/ui/command/index.ts b/src/lib/components/ui/command/index.ts new file mode 100644 index 0000000..5435fbe --- /dev/null +++ b/src/lib/components/ui/command/index.ts @@ -0,0 +1,37 @@ +import Root from "./command.svelte"; +import Loading from "./command-loading.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"; +import LinkItem from "./command-link-item.svelte"; + +export { + Root, + Dialog, + Empty, + Group, + Item, + LinkItem, + Input, + List, + Separator, + Shortcut, + Loading, + // + Root as Command, + Dialog as CommandDialog, + Empty as CommandEmpty, + Group as CommandGroup, + Item as CommandItem, + LinkItem as CommandLinkItem, + Input as CommandInput, + List as CommandList, + Separator as CommandSeparator, + Shortcut as CommandShortcut, + Loading as CommandLoading, +}; diff --git a/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte b/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte new file mode 100644 index 0000000..9ffcfbe --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte @@ -0,0 +1,41 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/src/lib/components/ui/context-menu/context-menu-content.svelte b/src/lib/components/ui/context-menu/context-menu-content.svelte new file mode 100644 index 0000000..5f32420 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-content.svelte @@ -0,0 +1,28 @@ + + + + + diff --git a/src/lib/components/ui/context-menu/context-menu-group-heading.svelte b/src/lib/components/ui/context-menu/context-menu-group-heading.svelte new file mode 100644 index 0000000..0c0f459 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-group-heading.svelte @@ -0,0 +1,21 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-group.svelte b/src/lib/components/ui/context-menu/context-menu-group.svelte new file mode 100644 index 0000000..c7c1e06 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-group.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-item.svelte b/src/lib/components/ui/context-menu/context-menu-item.svelte new file mode 100644 index 0000000..fccba28 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-item.svelte @@ -0,0 +1,27 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-label.svelte b/src/lib/components/ui/context-menu/context-menu-label.svelte new file mode 100644 index 0000000..8b9e9c6 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-label.svelte @@ -0,0 +1,24 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/context-menu/context-menu-portal.svelte b/src/lib/components/ui/context-menu/context-menu-portal.svelte new file mode 100644 index 0000000..96b1e3e --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-radio-group.svelte b/src/lib/components/ui/context-menu/context-menu-radio-group.svelte new file mode 100644 index 0000000..964cb55 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-radio-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-radio-item.svelte b/src/lib/components/ui/context-menu/context-menu-radio-item.svelte new file mode 100644 index 0000000..ad4e56f --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-radio-item.svelte @@ -0,0 +1,35 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/src/lib/components/ui/context-menu/context-menu-separator.svelte b/src/lib/components/ui/context-menu/context-menu-separator.svelte new file mode 100644 index 0000000..7f5b237 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-shortcut.svelte b/src/lib/components/ui/context-menu/context-menu-shortcut.svelte new file mode 100644 index 0000000..3305abc --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/context-menu/context-menu-sub-content.svelte b/src/lib/components/ui/context-menu/context-menu-sub-content.svelte new file mode 100644 index 0000000..fa46397 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-sub-content.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte b/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte new file mode 100644 index 0000000..af016c5 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/src/lib/components/ui/context-menu/context-menu-sub.svelte b/src/lib/components/ui/context-menu/context-menu-sub.svelte new file mode 100644 index 0000000..a03827b --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-sub.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-trigger.svelte b/src/lib/components/ui/context-menu/context-menu-trigger.svelte new file mode 100644 index 0000000..f6a1542 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-trigger.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu.svelte b/src/lib/components/ui/context-menu/context-menu.svelte new file mode 100644 index 0000000..cfaefb3 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/context-menu/index.ts b/src/lib/components/ui/context-menu/index.ts new file mode 100644 index 0000000..cbeaee1 --- /dev/null +++ b/src/lib/components/ui/context-menu/index.ts @@ -0,0 +1,52 @@ +import Root from "./context-menu.svelte"; +import Sub from "./context-menu-sub.svelte"; +import Portal from "./context-menu-portal.svelte"; +import Trigger from "./context-menu-trigger.svelte"; +import Group from "./context-menu-group.svelte"; +import RadioGroup from "./context-menu-radio-group.svelte"; +import Item from "./context-menu-item.svelte"; +import GroupHeading from "./context-menu-group-heading.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 SubContent from "./context-menu-sub-content.svelte"; +import SubTrigger from "./context-menu-sub-trigger.svelte"; +import CheckboxItem from "./context-menu-checkbox-item.svelte"; +import Label from "./context-menu-label.svelte"; + +export { + Root, + Sub, + Portal, + Item, + GroupHeading, + Label, + Group, + Trigger, + Content, + Shortcut, + Separator, + RadioItem, + SubContent, + SubTrigger, + RadioGroup, + CheckboxItem, + // + Root as ContextMenu, + Sub as ContextMenuSub, + Portal as ContextMenuPortal, + Item as ContextMenuItem, + GroupHeading as ContextMenuGroupHeading, + 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, + Label as ContextMenuLabel, +}; diff --git a/src/lib/components/ui/data-table/data-table.svelte.ts b/src/lib/components/ui/data-table/data-table.svelte.ts new file mode 100644 index 0000000..f3c30a7 --- /dev/null +++ b/src/lib/components/ui/data-table/data-table.svelte.ts @@ -0,0 +1,142 @@ +import { + type RowData, + type TableOptions, + type TableOptionsResolved, + type TableState, + type Updater, + createTable, +} from "@tanstack/table-core"; + +/** + * Creates a reactive TanStack table object for Svelte. + * @param options Table options to create the table with. + * @returns A reactive table object. + * @example + * ```svelte + * + * + * + * + * {#each table.getHeaderGroups() as headerGroup} + * + * {#each headerGroup.headers as header} + * + * {/each} + * + * {/each} + * + * + *
    + * + *
    + * ``` + */ +export function createSvelteTable(options: TableOptions) { + const resolvedOptions: TableOptionsResolved = mergeObjects( + { + state: {}, + onStateChange() {}, + renderFallbackValue: null, + mergeOptions: ( + defaultOptions: TableOptions, + options: Partial> + ) => { + return mergeObjects(defaultOptions, options); + }, + }, + options + ); + + const table = createTable(resolvedOptions); + let state = $state(table.initialState); + + function updateOptions() { + table.setOptions(() => { + return mergeObjects(resolvedOptions, options, { + state: mergeObjects(state, options.state || {}), + + onStateChange: (updater: Updater) => { + if (updater instanceof Function) state = updater(state); + else state = mergeObjects(state, updater); + + options.onStateChange?.(updater); + }, + }); + }); + } + + updateOptions(); + + $effect.pre(() => { + updateOptions(); + }); + + return table; +} + +type MaybeThunk = T | (() => T | null | undefined); +type Intersection = (T extends [infer H, ...infer R] + ? H & Intersection + : unknown) & {}; + +/** + * Lazily merges several objects (or thunks) while preserving + * getter semantics from every source. + * + * Proxy-based to avoid known WebKit recursion issue. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function mergeObjects[]>( + ...sources: Sources +): Intersection<{ [K in keyof Sources]: Sources[K] }> { + const resolve = (src: MaybeThunk): T | undefined => + typeof src === "function" ? (src() ?? undefined) : src; + + const findSourceWithKey = (key: PropertyKey) => { + for (let i = sources.length - 1; i >= 0; i--) { + const obj = resolve(sources[i]); + if (obj && key in obj) return obj; + } + return undefined; + }; + + return new Proxy(Object.create(null), { + get(_, key) { + const src = findSourceWithKey(key); + + return src?.[key as never]; + }, + + has(_, key) { + return !!findSourceWithKey(key); + }, + + ownKeys(): (string | symbol)[] { + // eslint-disable-next-line svelte/prefer-svelte-reactivity + const all = new Set(); + for (const s of sources) { + const obj = resolve(s); + if (obj) { + for (const k of Reflect.ownKeys(obj) as (string | symbol)[]) { + all.add(k); + } + } + } + return [...all]; + }, + + getOwnPropertyDescriptor(_, key) { + const src = findSourceWithKey(key); + if (!src) return undefined; + return { + configurable: true, + enumerable: true, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + value: (src as any)[key], + writable: true, + }; + }, + }) as Intersection<{ [K in keyof Sources]: Sources[K] }>; +} diff --git a/src/lib/components/ui/data-table/flex-render.svelte b/src/lib/components/ui/data-table/flex-render.svelte new file mode 100644 index 0000000..ac82a58 --- /dev/null +++ b/src/lib/components/ui/data-table/flex-render.svelte @@ -0,0 +1,40 @@ + + +{#if typeof content === "string"} + {content} +{:else if content instanceof Function} + + + {@const result = content(context as any)} + {#if result instanceof RenderComponentConfig} + {@const { component: Component, props } = result} + + {:else if result instanceof RenderSnippetConfig} + {@const { snippet, params } = result} + {@render snippet({ ...params, attach })} + {:else} + {result} + {/if} +{/if} diff --git a/src/lib/components/ui/data-table/index.ts b/src/lib/components/ui/data-table/index.ts new file mode 100644 index 0000000..5f4e77e --- /dev/null +++ b/src/lib/components/ui/data-table/index.ts @@ -0,0 +1,3 @@ +export { default as FlexRender } from "./flex-render.svelte"; +export { renderComponent, renderSnippet } from "./render-helpers.js"; +export { createSvelteTable } from "./data-table.svelte.js"; diff --git a/src/lib/components/ui/data-table/render-helpers.ts b/src/lib/components/ui/data-table/render-helpers.ts new file mode 100644 index 0000000..fa036d6 --- /dev/null +++ b/src/lib/components/ui/data-table/render-helpers.ts @@ -0,0 +1,111 @@ +import type { Component, ComponentProps, Snippet } from "svelte"; + +/** + * A helper class to make it easy to identify Svelte components in + * `columnDef.cell` and `columnDef.header` properties. + * + * > NOTE: This class should only be used internally by the adapter. If you're + * reading this and you don't know what this is for, you probably don't need it. + * + * @example + * ```svelte + * {@const result = content(context as any)} + * {#if result instanceof RenderComponentConfig} + * {@const { component: Component, props } = result} + * + * {/if} + * ``` + */ +export class RenderComponentConfig { + component: TComponent; + props: ComponentProps | Record; + constructor( + component: TComponent, + props: ComponentProps | Record = {} + ) { + this.component = component; + this.props = props; + } +} + +/** + * A helper class to make it easy to identify Svelte Snippets in `columnDef.cell` and `columnDef.header` properties. + * + * > NOTE: This class should only be used internally by the adapter. If you're + * reading this and you don't know what this is for, you probably don't need it. + * + * @example + * ```svelte + * {@const result = content(context as any)} + * {#if result instanceof RenderSnippetConfig} + * {@const { snippet, params } = result} + * {@render snippet(params)} + * {/if} + * ``` + */ +export class RenderSnippetConfig { + snippet: Snippet<[TProps]>; + params: TProps; + constructor(snippet: Snippet<[TProps]>, params: TProps) { + this.snippet = snippet; + this.params = params; + } +} + +/** + * A helper function to help create cells from Svelte components through ColumnDef's `cell` and `header` properties. + * + * This is only to be used with Svelte Components - use `renderSnippet` for Svelte Snippets. + * + * @param component A Svelte component + * @param props The props to pass to `component` + * @returns A `RenderComponentConfig` object that helps svelte-table know how to render the header/cell component. + * @example + * ```ts + * // +page.svelte + * const defaultColumns = [ + * columnHelper.accessor('name', { + * header: header => renderComponent(SortHeader, { label: 'Name', header }), + * }), + * columnHelper.accessor('state', { + * header: header => renderComponent(SortHeader, { label: 'State', header }), + * }), + * ] + * ``` + * @see {@link https://tanstack.com/table/latest/docs/guide/column-defs} + */ +export function renderComponent< + // eslint-disable-next-line @typescript-eslint/no-explicit-any + T extends Component, + Props extends ComponentProps, +>(component: T, props: Props = {} as Props) { + return new RenderComponentConfig(component, props); +} + +/** + * A helper function to help create cells from Svelte Snippets through ColumnDef's `cell` and `header` properties. + * + * The snippet must only take one parameter. + * + * This is only to be used with Snippets - use `renderComponent` for Svelte Components. + * + * @param snippet + * @param params + * @returns - A `RenderSnippetConfig` object that helps svelte-table know how to render the header/cell snippet. + * @example + * ```ts + * // +page.svelte + * const defaultColumns = [ + * columnHelper.accessor('name', { + * cell: cell => renderSnippet(nameSnippet, { name: cell.row.name }), + * }), + * columnHelper.accessor('state', { + * cell: cell => renderSnippet(stateSnippet, { state: cell.row.state }), + * }), + * ] + * ``` + * @see {@link https://tanstack.com/table/latest/docs/guide/column-defs} + */ +export function renderSnippet(snippet: Snippet<[TProps]>, params: TProps = {} as TProps) { + return new RenderSnippetConfig(snippet, params); +} diff --git a/src/lib/components/ui/dialog/dialog-close.svelte b/src/lib/components/ui/dialog/dialog-close.svelte new file mode 100644 index 0000000..de68f2f --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-close.svelte @@ -0,0 +1,11 @@ + + + diff --git a/src/lib/components/ui/dialog/dialog-content.svelte b/src/lib/components/ui/dialog/dialog-content.svelte new file mode 100644 index 0000000..c0551ee --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-content.svelte @@ -0,0 +1,48 @@ + + + + + + {@render children?.()} + {#if showCloseButton} + + {#snippet child({ props })} + + {/snippet} + + {/if} + + diff --git a/src/lib/components/ui/dialog/dialog-description.svelte b/src/lib/components/ui/dialog/dialog-description.svelte new file mode 100644 index 0000000..0102d91 --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/dialog/dialog-footer.svelte b/src/lib/components/ui/dialog/dialog-footer.svelte new file mode 100644 index 0000000..e23160a --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-footer.svelte @@ -0,0 +1,32 @@ + + +
    + {@render children?.()} + {#if showCloseButton} + + {#snippet child({ props })} + + {/snippet} + + {/if} +
    diff --git a/src/lib/components/ui/dialog/dialog-header.svelte b/src/lib/components/ui/dialog/dialog-header.svelte new file mode 100644 index 0000000..c3ce8a2 --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-header.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/dialog/dialog-overlay.svelte b/src/lib/components/ui/dialog/dialog-overlay.svelte new file mode 100644 index 0000000..19f69f0 --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-overlay.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/dialog/dialog-portal.svelte b/src/lib/components/ui/dialog/dialog-portal.svelte new file mode 100644 index 0000000..ccfa79c --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dialog/dialog-title.svelte b/src/lib/components/ui/dialog/dialog-title.svelte new file mode 100644 index 0000000..6ff1a4a --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/dialog/dialog-trigger.svelte b/src/lib/components/ui/dialog/dialog-trigger.svelte new file mode 100644 index 0000000..589ee0c --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-trigger.svelte @@ -0,0 +1,11 @@ + + + diff --git a/src/lib/components/ui/dialog/dialog.svelte b/src/lib/components/ui/dialog/dialog.svelte new file mode 100644 index 0000000..211672c --- /dev/null +++ b/src/lib/components/ui/dialog/dialog.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dialog/index.ts b/src/lib/components/ui/dialog/index.ts new file mode 100644 index 0000000..076cef5 --- /dev/null +++ b/src/lib/components/ui/dialog/index.ts @@ -0,0 +1,34 @@ +import Root from "./dialog.svelte"; +import Portal from "./dialog-portal.svelte"; +import Title from "./dialog-title.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"; +import Trigger from "./dialog-trigger.svelte"; +import Close from "./dialog-close.svelte"; + +export { + Root, + Title, + Portal, + Footer, + Header, + Trigger, + Overlay, + Content, + Description, + Close, + // + 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, + Close as DialogClose, +}; diff --git a/src/lib/components/ui/drawer/drawer-close.svelte b/src/lib/components/ui/drawer/drawer-close.svelte new file mode 100644 index 0000000..95c2479 --- /dev/null +++ b/src/lib/components/ui/drawer/drawer-close.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/drawer/drawer-content.svelte b/src/lib/components/ui/drawer/drawer-content.svelte new file mode 100644 index 0000000..c5b6cb9 --- /dev/null +++ b/src/lib/components/ui/drawer/drawer-content.svelte @@ -0,0 +1,33 @@ + + + + + + + {@render children?.()} + + diff --git a/src/lib/components/ui/drawer/drawer-description.svelte b/src/lib/components/ui/drawer/drawer-description.svelte new file mode 100644 index 0000000..2763a1a --- /dev/null +++ b/src/lib/components/ui/drawer/drawer-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/drawer/drawer-footer.svelte b/src/lib/components/ui/drawer/drawer-footer.svelte new file mode 100644 index 0000000..56a1fc6 --- /dev/null +++ b/src/lib/components/ui/drawer/drawer-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/drawer/drawer-header.svelte b/src/lib/components/ui/drawer/drawer-header.svelte new file mode 100644 index 0000000..861f956 --- /dev/null +++ b/src/lib/components/ui/drawer/drawer-header.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/drawer/drawer-nested.svelte b/src/lib/components/ui/drawer/drawer-nested.svelte new file mode 100644 index 0000000..834af94 --- /dev/null +++ b/src/lib/components/ui/drawer/drawer-nested.svelte @@ -0,0 +1,12 @@ + + + diff --git a/src/lib/components/ui/drawer/drawer-overlay.svelte b/src/lib/components/ui/drawer/drawer-overlay.svelte new file mode 100644 index 0000000..84df1e8 --- /dev/null +++ b/src/lib/components/ui/drawer/drawer-overlay.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/drawer/drawer-portal.svelte b/src/lib/components/ui/drawer/drawer-portal.svelte new file mode 100644 index 0000000..5a0dd74 --- /dev/null +++ b/src/lib/components/ui/drawer/drawer-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/drawer/drawer-title.svelte b/src/lib/components/ui/drawer/drawer-title.svelte new file mode 100644 index 0000000..fc3649b --- /dev/null +++ b/src/lib/components/ui/drawer/drawer-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/drawer/drawer-trigger.svelte b/src/lib/components/ui/drawer/drawer-trigger.svelte new file mode 100644 index 0000000..f1877d8 --- /dev/null +++ b/src/lib/components/ui/drawer/drawer-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/drawer/drawer.svelte b/src/lib/components/ui/drawer/drawer.svelte new file mode 100644 index 0000000..0cb57ff --- /dev/null +++ b/src/lib/components/ui/drawer/drawer.svelte @@ -0,0 +1,12 @@ + + + diff --git a/src/lib/components/ui/drawer/index.ts b/src/lib/components/ui/drawer/index.ts new file mode 100644 index 0000000..1656cac --- /dev/null +++ b/src/lib/components/ui/drawer/index.ts @@ -0,0 +1,38 @@ +import Root from "./drawer.svelte"; +import Content from "./drawer-content.svelte"; +import Description from "./drawer-description.svelte"; +import Overlay from "./drawer-overlay.svelte"; +import Footer from "./drawer-footer.svelte"; +import Header from "./drawer-header.svelte"; +import Title from "./drawer-title.svelte"; +import NestedRoot from "./drawer-nested.svelte"; +import Close from "./drawer-close.svelte"; +import Trigger from "./drawer-trigger.svelte"; +import Portal from "./drawer-portal.svelte"; + +export { + Root, + NestedRoot, + Content, + Description, + Overlay, + Footer, + Header, + Title, + Trigger, + Portal, + Close, + + // + Root as Drawer, + NestedRoot as DrawerNestedRoot, + Content as DrawerContent, + Description as DrawerDescription, + Overlay as DrawerOverlay, + Footer as DrawerFooter, + Header as DrawerHeader, + Title as DrawerTitle, + Trigger as DrawerTrigger, + Portal as DrawerPortal, + Close as DrawerClose, +}; diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte new file mode 100644 index 0000000..e0e1971 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 0000000..a81b48d --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,44 @@ + + + + {#snippet children({ checked, indeterminate })} + + {#if indeterminate} + + {:else if checked} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 0000000..261a5b0 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,31 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte new file mode 100644 index 0000000..433540f --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte @@ -0,0 +1,22 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte new file mode 100644 index 0000000..aca1f7b --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 0000000..c425190 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,27 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 0000000..e0c534f --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,24 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte new file mode 100644 index 0000000..274cfef --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte new file mode 100644 index 0000000..189aef4 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 0000000..c8aa07b --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,34 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 0000000..90f1b6f --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 0000000..ed7cc85 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 0000000..b5750d4 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 0000000..fab0275 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte new file mode 100644 index 0000000..f044581 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte new file mode 100644 index 0000000..cb05344 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte new file mode 100644 index 0000000..cb4bc62 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/index.ts b/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..7850c6a --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,54 @@ +import Root from "./dropdown-menu.svelte"; +import Sub from "./dropdown-menu-sub.svelte"; +import CheckboxGroup from "./dropdown-menu-checkbox-group.svelte"; +import CheckboxItem from "./dropdown-menu-checkbox-item.svelte"; +import Content from "./dropdown-menu-content.svelte"; +import Group from "./dropdown-menu-group.svelte"; +import Item from "./dropdown-menu-item.svelte"; +import Label from "./dropdown-menu-label.svelte"; +import RadioGroup from "./dropdown-menu-radio-group.svelte"; +import RadioItem from "./dropdown-menu-radio-item.svelte"; +import Separator from "./dropdown-menu-separator.svelte"; +import Shortcut from "./dropdown-menu-shortcut.svelte"; +import Trigger from "./dropdown-menu-trigger.svelte"; +import SubContent from "./dropdown-menu-sub-content.svelte"; +import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; +import GroupHeading from "./dropdown-menu-group-heading.svelte"; +import Portal from "./dropdown-menu-portal.svelte"; + +export { + CheckboxGroup, + CheckboxItem, + Content, + Portal, + Root as DropdownMenu, + CheckboxGroup as DropdownMenuCheckboxGroup, + CheckboxItem as DropdownMenuCheckboxItem, + Content as DropdownMenuContent, + Portal as DropdownMenuPortal, + Group as DropdownMenuGroup, + Item as DropdownMenuItem, + Label as DropdownMenuLabel, + RadioGroup as DropdownMenuRadioGroup, + RadioItem as DropdownMenuRadioItem, + Separator as DropdownMenuSeparator, + Shortcut as DropdownMenuShortcut, + Sub as DropdownMenuSub, + SubContent as DropdownMenuSubContent, + SubTrigger as DropdownMenuSubTrigger, + Trigger as DropdownMenuTrigger, + GroupHeading as DropdownMenuGroupHeading, + Group, + GroupHeading, + Item, + Label, + RadioGroup, + RadioItem, + Root, + Separator, + Shortcut, + Sub, + SubContent, + SubTrigger, + Trigger, +}; diff --git a/src/lib/components/ui/empty/empty-content.svelte b/src/lib/components/ui/empty/empty-content.svelte new file mode 100644 index 0000000..607b9f7 --- /dev/null +++ b/src/lib/components/ui/empty/empty-content.svelte @@ -0,0 +1,23 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/empty/empty-description.svelte b/src/lib/components/ui/empty/empty-description.svelte new file mode 100644 index 0000000..024228b --- /dev/null +++ b/src/lib/components/ui/empty/empty-description.svelte @@ -0,0 +1,23 @@ + + +
    a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4", + className + )} + {...restProps} +> + {@render children?.()} +
    diff --git a/src/lib/components/ui/empty/empty-header.svelte b/src/lib/components/ui/empty/empty-header.svelte new file mode 100644 index 0000000..7112f66 --- /dev/null +++ b/src/lib/components/ui/empty/empty-header.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/empty/empty-media.svelte b/src/lib/components/ui/empty/empty-media.svelte new file mode 100644 index 0000000..95819a4 --- /dev/null +++ b/src/lib/components/ui/empty/empty-media.svelte @@ -0,0 +1,41 @@ + + + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/empty/empty-title.svelte b/src/lib/components/ui/empty/empty-title.svelte new file mode 100644 index 0000000..4ab45eb --- /dev/null +++ b/src/lib/components/ui/empty/empty-title.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/empty/empty.svelte b/src/lib/components/ui/empty/empty.svelte new file mode 100644 index 0000000..3aef062 --- /dev/null +++ b/src/lib/components/ui/empty/empty.svelte @@ -0,0 +1,23 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/empty/index.ts b/src/lib/components/ui/empty/index.ts new file mode 100644 index 0000000..ae4c106 --- /dev/null +++ b/src/lib/components/ui/empty/index.ts @@ -0,0 +1,22 @@ +import Root from "./empty.svelte"; +import Header from "./empty-header.svelte"; +import Media from "./empty-media.svelte"; +import Title from "./empty-title.svelte"; +import Description from "./empty-description.svelte"; +import Content from "./empty-content.svelte"; + +export { + Root, + Header, + Media, + Title, + Description, + Content, + // + Root as Empty, + Header as EmptyHeader, + Media as EmptyMedia, + Title as EmptyTitle, + Description as EmptyDescription, + Content as EmptyContent, +}; diff --git a/src/lib/components/ui/field/field-content.svelte b/src/lib/components/ui/field/field-content.svelte new file mode 100644 index 0000000..1545c43 --- /dev/null +++ b/src/lib/components/ui/field/field-content.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/field/field-description.svelte b/src/lib/components/ui/field/field-description.svelte new file mode 100644 index 0000000..7518366 --- /dev/null +++ b/src/lib/components/ui/field/field-description.svelte @@ -0,0 +1,25 @@ + + +

    a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4", + className + )} + {...restProps} +> + {@render children?.()} +

    diff --git a/src/lib/components/ui/field/field-error.svelte b/src/lib/components/ui/field/field-error.svelte new file mode 100644 index 0000000..2381b36 --- /dev/null +++ b/src/lib/components/ui/field/field-error.svelte @@ -0,0 +1,58 @@ + + +{#if hasContent} + +{/if} diff --git a/src/lib/components/ui/field/field-group.svelte b/src/lib/components/ui/field/field-group.svelte new file mode 100644 index 0000000..3795195 --- /dev/null +++ b/src/lib/components/ui/field/field-group.svelte @@ -0,0 +1,23 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/field/field-label.svelte b/src/lib/components/ui/field/field-label.svelte new file mode 100644 index 0000000..da58659 --- /dev/null +++ b/src/lib/components/ui/field/field-label.svelte @@ -0,0 +1,25 @@ + + + diff --git a/src/lib/components/ui/field/field-legend.svelte b/src/lib/components/ui/field/field-legend.svelte new file mode 100644 index 0000000..75bf8d2 --- /dev/null +++ b/src/lib/components/ui/field/field-legend.svelte @@ -0,0 +1,24 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/field/field-separator.svelte b/src/lib/components/ui/field/field-separator.svelte new file mode 100644 index 0000000..5aa7739 --- /dev/null +++ b/src/lib/components/ui/field/field-separator.svelte @@ -0,0 +1,35 @@ + + +
    + + {#if children} + + {@render children()} + + {/if} +
    diff --git a/src/lib/components/ui/field/field-set.svelte b/src/lib/components/ui/field/field-set.svelte new file mode 100644 index 0000000..27ee330 --- /dev/null +++ b/src/lib/components/ui/field/field-set.svelte @@ -0,0 +1,20 @@ + + +
    [data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3 flex flex-col", className)} + {...restProps} +> + {@render children?.()} +
    diff --git a/src/lib/components/ui/field/field-title.svelte b/src/lib/components/ui/field/field-title.svelte new file mode 100644 index 0000000..30dec2c --- /dev/null +++ b/src/lib/components/ui/field/field-title.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/field/field.svelte b/src/lib/components/ui/field/field.svelte new file mode 100644 index 0000000..03d23c0 --- /dev/null +++ b/src/lib/components/ui/field/field.svelte @@ -0,0 +1,47 @@ + + + + +
    + {@render children?.()} +
    diff --git a/src/lib/components/ui/field/index.ts b/src/lib/components/ui/field/index.ts new file mode 100644 index 0000000..a644a95 --- /dev/null +++ b/src/lib/components/ui/field/index.ts @@ -0,0 +1,33 @@ +import Field from "./field.svelte"; +import Set from "./field-set.svelte"; +import Legend from "./field-legend.svelte"; +import Group from "./field-group.svelte"; +import Content from "./field-content.svelte"; +import Label from "./field-label.svelte"; +import Title from "./field-title.svelte"; +import Description from "./field-description.svelte"; +import Separator from "./field-separator.svelte"; +import Error from "./field-error.svelte"; + +export { + Field, + Set, + Legend, + Group, + Content, + Label, + Title, + Description, + Separator, + Error, + // + Set as FieldSet, + Legend as FieldLegend, + Group as FieldGroup, + Content as FieldContent, + Label as FieldLabel, + Title as FieldTitle, + Description as FieldDescription, + Separator as FieldSeparator, + Error as FieldError, +}; diff --git a/src/lib/components/ui/form/form-button.svelte b/src/lib/components/ui/form/form-button.svelte new file mode 100644 index 0000000..48d3936 --- /dev/null +++ b/src/lib/components/ui/form/form-button.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/input-group/input-group-input.svelte b/src/lib/components/ui/input-group/input-group-input.svelte new file mode 100644 index 0000000..316c0cb --- /dev/null +++ b/src/lib/components/ui/input-group/input-group-input.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/lib/components/ui/input-group/input-group-text.svelte b/src/lib/components/ui/input-group/input-group-text.svelte new file mode 100644 index 0000000..77907c6 --- /dev/null +++ b/src/lib/components/ui/input-group/input-group-text.svelte @@ -0,0 +1,19 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/input-group/input-group-textarea.svelte b/src/lib/components/ui/input-group/input-group-textarea.svelte new file mode 100644 index 0000000..9fbabe6 --- /dev/null +++ b/src/lib/components/ui/input-group/input-group-textarea.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/lib/components/ui/toggle-group/index.ts b/src/lib/components/ui/toggle-group/index.ts new file mode 100644 index 0000000..12b14b9 --- /dev/null +++ b/src/lib/components/ui/toggle-group/index.ts @@ -0,0 +1,10 @@ +import Root from "./toggle-group.svelte"; +import Item from "./toggle-group-item.svelte"; + +export { + Root, + Item, + // + Root as ToggleGroup, + Item as ToggleGroupItem, +}; diff --git a/src/lib/components/ui/toggle-group/toggle-group-item.svelte b/src/lib/components/ui/toggle-group/toggle-group-item.svelte new file mode 100644 index 0000000..f685ae3 --- /dev/null +++ b/src/lib/components/ui/toggle-group/toggle-group-item.svelte @@ -0,0 +1,35 @@ + + + diff --git a/src/lib/components/ui/toggle-group/toggle-group.svelte b/src/lib/components/ui/toggle-group/toggle-group.svelte new file mode 100644 index 0000000..98b062b --- /dev/null +++ b/src/lib/components/ui/toggle-group/toggle-group.svelte @@ -0,0 +1,75 @@ + + + + + + diff --git a/src/lib/components/ui/toggle/index.ts b/src/lib/components/ui/toggle/index.ts new file mode 100644 index 0000000..8cb2936 --- /dev/null +++ b/src/lib/components/ui/toggle/index.ts @@ -0,0 +1,13 @@ +import Root from "./toggle.svelte"; +export { + toggleVariants, + type ToggleSize, + type ToggleVariant, + type ToggleVariants, +} from "./toggle.svelte"; + +export { + Root, + // + Root as Toggle, +}; diff --git a/src/lib/components/ui/toggle/toggle.svelte b/src/lib/components/ui/toggle/toggle.svelte new file mode 100644 index 0000000..8e50317 --- /dev/null +++ b/src/lib/components/ui/toggle/toggle.svelte @@ -0,0 +1,51 @@ + + + + + diff --git a/src/lib/components/ui/tooltip/index.ts b/src/lib/components/ui/tooltip/index.ts new file mode 100644 index 0000000..1718604 --- /dev/null +++ b/src/lib/components/ui/tooltip/index.ts @@ -0,0 +1,19 @@ +import Root from "./tooltip.svelte"; +import Trigger from "./tooltip-trigger.svelte"; +import Content from "./tooltip-content.svelte"; +import Provider from "./tooltip-provider.svelte"; +import Portal from "./tooltip-portal.svelte"; + +export { + Root, + Trigger, + Content, + Provider, + Portal, + // + Root as Tooltip, + Content as TooltipContent, + Trigger as TooltipTrigger, + Provider as TooltipProvider, + Portal as TooltipPortal, +}; diff --git a/src/lib/components/ui/tooltip/tooltip-content.svelte b/src/lib/components/ui/tooltip/tooltip-content.svelte new file mode 100644 index 0000000..0cf0694 --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip-content.svelte @@ -0,0 +1,52 @@ + + + + + {@render children?.()} + + {#snippet child({ props })} +
    + {/snippet} +
    +
    +
    diff --git a/src/lib/components/ui/tooltip/tooltip-portal.svelte b/src/lib/components/ui/tooltip/tooltip-portal.svelte new file mode 100644 index 0000000..d234f7d --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/tooltip/tooltip-provider.svelte b/src/lib/components/ui/tooltip/tooltip-provider.svelte new file mode 100644 index 0000000..6dba9a6 --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip-provider.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/tooltip/tooltip-trigger.svelte b/src/lib/components/ui/tooltip/tooltip-trigger.svelte new file mode 100644 index 0000000..1acdaa4 --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/tooltip/tooltip.svelte b/src/lib/components/ui/tooltip/tooltip.svelte new file mode 100644 index 0000000..0b0f9ce --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip.svelte @@ -0,0 +1,7 @@ + + +