@repo/components
UI components built on shadcn-svelte with custom additions.
Usage
<script lang="ts">
import { Button, Card, Dialog } from '@repo/components'
</script>
shadcn-svelte Components
All standard shadcn-svelte components are included:
Accordion, Alert, AlertDialog, Avatar, Badge, Breadcrumb, Button, Calendar, Card, Carousel, Chart, Checkbox, Collapsible, Command, ContextMenu, Dialog, Drawer, DropdownMenu, Form, HoverCard, Input, InputOTP, Label, Menubar, NavigationMenu, Pagination, Popover, Progress, RadioGroup, RangeCalendar, Resizable, ScrollArea, Select, Separator, Sheet, Skeleton, Slider, Sonner, Switch, Table, Tabs, Textarea, Toggle, ToggleGroup, Tooltip
Custom Components
Headers
Page headers for different contexts:
import { DetailHeader, InsertHeader } from '@repo/components'
<!-- Detail page with optional delete and audit logs -->
<DetailHeader title="User" deleteForm={canDelete && deleteUserForm} getAuditLogs={getAuditLogQuery} table='users' />
<!-- Insert/create page -->
<InsertHeader title="New User" />
Sidebar
Application sidebar with navigation:
import { AppSidebar, NavMain, Sidebar } from '@repo/components'
{#snippet sidebarHeader()}
<NavMain class="p-0" menu={organizationMenu} />
{/snippet}
<Sidebar.Provider>
<AppSidebar header={sidebarHeader} menu={menu} user={user} />
<Sidebar.Inset>
{@render children()}
</Sidebar.Inset>
</Sidebar.Provider>
Buttons
import { ConfirmationButton, CopyButton } from '@repo/components'
<!-- Button with confirmation dialog -->
<ConfirmationButton onConfirm={handleDelete}>Delete</ConfirmationButton>
<!-- Copy text to clipboard -->
<CopyButton text={apiKey} />
Breadcrumbs
Auto-generated breadcrumbs from page data:
import { AutomaticBreadcrumbs } from '@repo/components'
<AutomaticBreadcrumbs pageTitles={page.data.breadcrumbs} />
SEO Meta
Render head tags once from layout or page metadata:
<script lang="ts">
import { SEOMeta } from '@repo/components'
const defaultMeta = {
title: 'My App',
description: 'Default app description',
siteName: 'My App',
}
</script>
<SEOMeta pageMeta={page.data.pageMeta} {defaultMeta} title={(title) => `${title} | My App`} />
SEOMeta owns its <svelte:head> output, so do not wrap it in another <svelte:head> block.
If pageMeta.canonicalUrl and defaultMeta.canonicalUrl are missing, it falls back to PUBLIC_APP_URL plus the current route pathname.
DefinitionList
Renders an HTML <dl> with consistent label/value styling. Use for record info on detail pages and card metadata.
import { DefinitionList } from '@repo/components'
<!-- 2-column (defaults to 1) -->
<DefinitionList.Root columns={2}>
<DefinitionList.Item label='Name'>{user.name}</DefinitionList.Item>
<DefinitionList.Item label='Email'>{user.email}</DefinitionList.Item>
</DefinitionList.Root>
columns: 1 | 2 | 3 (default 1). Override gap/padding via class prop.
Styling
Customize button variants via StyleProvider:
<!-- routes/+layout.svelte -->
<script lang="ts">
import { StyleProvider } from '@repo/components'
import { buttonVariants } from '$lib/library/styling'
</script>
<StyleProvider.Root {buttonVariants}>
{@render children?.()}
</StyleProvider.Root>