@noahbaumgartner/svelte-ui 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -0
- package/dist/components/alert-dialog/AlertDialog.svelte +161 -0
- package/dist/components/alert-dialog/AlertDialog.svelte.d.ts +20 -0
- package/dist/components/avatar/Avatar.svelte +85 -0
- package/dist/components/avatar/Avatar.svelte.d.ts +12 -0
- package/dist/components/badge/Badge.svelte +49 -0
- package/dist/components/badge/Badge.svelte.d.ts +12 -0
- package/dist/components/breadcrumb/Breadcrumb.svelte +37 -0
- package/dist/components/breadcrumb/Breadcrumb.svelte.d.ts +9 -0
- package/dist/components/breadcrumb/BreadcrumbEllipsis.svelte +32 -0
- package/dist/components/breadcrumb/BreadcrumbEllipsis.svelte.d.ts +10 -0
- package/dist/components/breadcrumb/BreadcrumbItem.svelte +71 -0
- package/dist/components/breadcrumb/BreadcrumbItem.svelte.d.ts +12 -0
- package/dist/components/breadcrumb/BreadcrumbSeparator.svelte +18 -0
- package/dist/components/breadcrumb/BreadcrumbSeparator.svelte.d.ts +18 -0
- package/dist/components/button/Button.svelte +247 -0
- package/dist/components/button/Button.svelte.d.ts +24 -0
- package/dist/components/button-group/ButtonGroup.svelte +89 -0
- package/dist/components/button-group/ButtonGroup.svelte.d.ts +12 -0
- package/dist/components/calendar/Calendar.svelte +401 -0
- package/dist/components/calendar/Calendar.svelte.d.ts +17 -0
- package/dist/components/calendar/dates.d.ts +12 -0
- package/dist/components/calendar/dates.js +48 -0
- package/dist/components/card/Card.svelte +55 -0
- package/dist/components/card/Card.svelte.d.ts +10 -0
- package/dist/components/card/CardAction.svelte +24 -0
- package/dist/components/card/CardAction.svelte.d.ts +9 -0
- package/dist/components/card/CardContent.svelte +20 -0
- package/dist/components/card/CardContent.svelte.d.ts +8 -0
- package/dist/components/card/CardDescription.svelte +23 -0
- package/dist/components/card/CardDescription.svelte.d.ts +8 -0
- package/dist/components/card/CardFooter.svelte +28 -0
- package/dist/components/card/CardFooter.svelte.d.ts +9 -0
- package/dist/components/card/CardHeader.svelte +29 -0
- package/dist/components/card/CardHeader.svelte.d.ts +9 -0
- package/dist/components/card/CardTitle.svelte +23 -0
- package/dist/components/card/CardTitle.svelte.d.ts +8 -0
- package/dist/components/checkbox/Checkbox.svelte +93 -0
- package/dist/components/checkbox/Checkbox.svelte.d.ts +5 -0
- package/dist/components/color-picker/ColorPicker.svelte +233 -0
- package/dist/components/color-picker/ColorPicker.svelte.d.ts +10 -0
- package/dist/components/context-menu/ContextMenu.svelte +201 -0
- package/dist/components/context-menu/ContextMenu.svelte.d.ts +14 -0
- package/dist/components/context-menu/ContextMenuItem.svelte +105 -0
- package/dist/components/context-menu/ContextMenuItem.svelte.d.ts +14 -0
- package/dist/components/context-menu/context.d.ts +14 -0
- package/dist/components/context-menu/context.js +2 -0
- package/dist/components/dialog/Dialog.svelte +225 -0
- package/dist/components/dialog/Dialog.svelte.d.ts +22 -0
- package/dist/components/field/Field.svelte +78 -0
- package/dist/components/field/Field.svelte.d.ts +11 -0
- package/dist/components/field/FieldContent.svelte +25 -0
- package/dist/components/field/FieldContent.svelte.d.ts +9 -0
- package/dist/components/field/FieldDescription.svelte +34 -0
- package/dist/components/field/FieldDescription.svelte.d.ts +9 -0
- package/dist/components/field/FieldError.svelte +45 -0
- package/dist/components/field/FieldError.svelte.d.ts +11 -0
- package/dist/components/field/FieldGroup.svelte +30 -0
- package/dist/components/field/FieldGroup.svelte.d.ts +9 -0
- package/dist/components/field/FieldLegend.svelte +34 -0
- package/dist/components/field/FieldLegend.svelte.d.ts +10 -0
- package/dist/components/field/FieldSeparator.svelte +31 -0
- package/dist/components/field/FieldSeparator.svelte.d.ts +9 -0
- package/dist/components/field/FieldSet.svelte +33 -0
- package/dist/components/field/FieldSet.svelte.d.ts +9 -0
- package/dist/components/input/Input.svelte +459 -0
- package/dist/components/input/Input.svelte.d.ts +10 -0
- package/dist/components/input-group/InputGroup.svelte +88 -0
- package/dist/components/input-group/InputGroup.svelte.d.ts +9 -0
- package/dist/components/input-group/InputGroupAddon.svelte +88 -0
- package/dist/components/input-group/InputGroupAddon.svelte.d.ts +11 -0
- package/dist/components/kbd/Kbd.svelte +46 -0
- package/dist/components/kbd/Kbd.svelte.d.ts +8 -0
- package/dist/components/kbd/KbdGroup.svelte +27 -0
- package/dist/components/kbd/KbdGroup.svelte.d.ts +8 -0
- package/dist/components/label/Label.svelte +48 -0
- package/dist/components/label/Label.svelte.d.ts +9 -0
- package/dist/components/link/Link.svelte +40 -0
- package/dist/components/link/Link.svelte.d.ts +10 -0
- package/dist/components/navbar/Navbar.svelte +266 -0
- package/dist/components/navbar/Navbar.svelte.d.ts +26 -0
- package/dist/components/navigation-menu/NavigationMenu.svelte +95 -0
- package/dist/components/navigation-menu/NavigationMenu.svelte.d.ts +12 -0
- package/dist/components/navigation-menu/NavigationMenuItem.svelte +257 -0
- package/dist/components/navigation-menu/NavigationMenuItem.svelte.d.ts +15 -0
- package/dist/components/navigation-menu/NavigationMenuLink.svelte +91 -0
- package/dist/components/navigation-menu/NavigationMenuLink.svelte.d.ts +16 -0
- package/dist/components/navigation-menu/context.d.ts +15 -0
- package/dist/components/navigation-menu/context.js +2 -0
- package/dist/components/popover/Popover.svelte +295 -0
- package/dist/components/popover/Popover.svelte.d.ts +34 -0
- package/dist/components/radio-group/RadioGroup.svelte +86 -0
- package/dist/components/radio-group/RadioGroup.svelte.d.ts +16 -0
- package/dist/components/radio-group/RadioGroupItem.svelte +95 -0
- package/dist/components/radio-group/RadioGroupItem.svelte.d.ts +7 -0
- package/dist/components/radio-group/context.d.ts +9 -0
- package/dist/components/radio-group/context.js +2 -0
- package/dist/components/separator/Separator.svelte +41 -0
- package/dist/components/separator/Separator.svelte.d.ts +10 -0
- package/dist/components/sidebar/Sidebar.svelte +180 -0
- package/dist/components/sidebar/Sidebar.svelte.d.ts +14 -0
- package/dist/components/sidebar/SidebarContent.svelte +30 -0
- package/dist/components/sidebar/SidebarContent.svelte.d.ts +9 -0
- package/dist/components/sidebar/SidebarFooter.svelte +23 -0
- package/dist/components/sidebar/SidebarFooter.svelte.d.ts +8 -0
- package/dist/components/sidebar/SidebarGroup.svelte +55 -0
- package/dist/components/sidebar/SidebarGroup.svelte.d.ts +11 -0
- package/dist/components/sidebar/SidebarHeader.svelte +23 -0
- package/dist/components/sidebar/SidebarHeader.svelte.d.ts +8 -0
- package/dist/components/sidebar/SidebarInset.svelte +25 -0
- package/dist/components/sidebar/SidebarInset.svelte.d.ts +9 -0
- package/dist/components/sidebar/SidebarMenu.svelte +27 -0
- package/dist/components/sidebar/SidebarMenu.svelte.d.ts +9 -0
- package/dist/components/sidebar/SidebarMenuItem.svelte +221 -0
- package/dist/components/sidebar/SidebarMenuItem.svelte.d.ts +23 -0
- package/dist/components/sidebar/SidebarProvider.svelte +62 -0
- package/dist/components/sidebar/SidebarProvider.svelte.d.ts +11 -0
- package/dist/components/sidebar/SidebarSeparator.svelte +5 -0
- package/dist/components/sidebar/SidebarSeparator.svelte.d.ts +18 -0
- package/dist/components/sidebar/SidebarTrigger.svelte +24 -0
- package/dist/components/sidebar/SidebarTrigger.svelte.d.ts +7 -0
- package/dist/components/sidebar/context.d.ts +15 -0
- package/dist/components/sidebar/context.js +2 -0
- package/dist/components/skeleton/Skeleton.svelte +30 -0
- package/dist/components/skeleton/Skeleton.svelte.d.ts +5 -0
- package/dist/components/spinner/Spinner.svelte +72 -0
- package/dist/components/spinner/Spinner.svelte.d.ts +9 -0
- package/dist/components/switch/Switch.svelte +88 -0
- package/dist/components/switch/Switch.svelte.d.ts +5 -0
- package/dist/components/table/Table.svelte +276 -0
- package/dist/components/table/Table.svelte.d.ts +60 -0
- package/dist/components/textarea/Textarea.svelte +57 -0
- package/dist/components/textarea/Textarea.svelte.d.ts +4 -0
- package/dist/components/time-picker/TimePicker.svelte +162 -0
- package/dist/components/time-picker/TimePicker.svelte.d.ts +11 -0
- package/dist/components/toaster/Toaster.svelte +151 -0
- package/dist/components/toaster/Toaster.svelte.d.ts +7 -0
- package/dist/components/toaster/toast.svelte.d.ts +28 -0
- package/dist/components/toaster/toast.svelte.js +22 -0
- package/dist/components/toggle/Toggle.svelte +31 -0
- package/dist/components/toggle/Toggle.svelte.d.ts +8 -0
- package/dist/components/tooltip/Tooltip.svelte +224 -0
- package/dist/components/tooltip/Tooltip.svelte.d.ts +27 -0
- package/dist/icons.d.ts +2 -0
- package/dist/icons.js +4 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.js +66 -0
- package/dist/styles/tokens.css +50 -0
- package/package.json +88 -0
package/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Svelte library
|
|
2
|
+
|
|
3
|
+
Everything you need to build a Svelte library, powered by [`sv`](https://npmjs.com/package/sv).
|
|
4
|
+
|
|
5
|
+
Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
|
|
6
|
+
|
|
7
|
+
## Creating a project
|
|
8
|
+
|
|
9
|
+
If you're seeing this, you've probably already done this step. Congrats!
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
# create a new project in the current directory
|
|
13
|
+
npx sv create
|
|
14
|
+
|
|
15
|
+
# create a new project in my-app
|
|
16
|
+
npx sv create my-app
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
To recreate this project with the same configuration:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
# recreate this project
|
|
23
|
+
npx sv@0.17.1 create --template library --types ts --add storybook vitest="usages:unit,component" eslint prettier --install npm svelte-ui
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Developing
|
|
27
|
+
|
|
28
|
+
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
npm run dev
|
|
32
|
+
|
|
33
|
+
# or start the server and open the app in a new browser tab
|
|
34
|
+
npm run dev -- --open
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
|
|
38
|
+
|
|
39
|
+
## Building
|
|
40
|
+
|
|
41
|
+
To build your library:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
npm pack
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
To create a production version of your showcase app:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
npm run build
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
You can preview the production build with `npm run preview`.
|
|
54
|
+
|
|
55
|
+
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
|
|
56
|
+
|
|
57
|
+
## Publishing
|
|
58
|
+
|
|
59
|
+
Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
|
|
60
|
+
|
|
61
|
+
To publish your library to [npm](https://www.npmjs.com):
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
npm publish
|
|
65
|
+
```
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
export type AlertDialogTriggerProps = {
|
|
3
|
+
onclick: () => void;
|
|
4
|
+
'aria-haspopup': 'dialog';
|
|
5
|
+
};
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<script lang="ts">
|
|
9
|
+
import type { Snippet } from 'svelte';
|
|
10
|
+
|
|
11
|
+
type Props = {
|
|
12
|
+
/** Whether the dialog is open. Bindable. Escape closes it. */
|
|
13
|
+
open?: boolean;
|
|
14
|
+
title: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
/** Renders the trigger. Spread the given props onto it, e.g. `<Button {...props} />`. Omit to control `open` yourself. */
|
|
17
|
+
trigger?: Snippet<[AlertDialogTriggerProps]>;
|
|
18
|
+
/** The Buttons, primary first and least destructive last; the last one gets the focus on open. Call `close` to close the dialog. */
|
|
19
|
+
actions: Snippet<[close: () => void]>;
|
|
20
|
+
/** Extra content between the description and the buttons. */
|
|
21
|
+
children?: Snippet;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
let { open = $bindable(false), title, description, trigger, actions, children }: Props = $props();
|
|
25
|
+
|
|
26
|
+
const id = $props.id();
|
|
27
|
+
let dialogEl: HTMLDialogElement;
|
|
28
|
+
|
|
29
|
+
const triggerProps: AlertDialogTriggerProps = {
|
|
30
|
+
onclick: () => (open = true),
|
|
31
|
+
'aria-haspopup': 'dialog'
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
function close() {
|
|
35
|
+
open = false;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
$effect(() => {
|
|
39
|
+
if (open && !dialogEl.open) {
|
|
40
|
+
dialogEl.showModal();
|
|
41
|
+
Array.from(dialogEl.querySelectorAll<HTMLElement>('.alert-dialog-actions :is(button, a)'))
|
|
42
|
+
.at(-1)
|
|
43
|
+
?.focus();
|
|
44
|
+
} else if (!open && dialogEl.open) {
|
|
45
|
+
dialogEl.close();
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
{@render trigger?.(triggerProps)}
|
|
51
|
+
|
|
52
|
+
<dialog
|
|
53
|
+
bind:this={dialogEl}
|
|
54
|
+
role="alertdialog"
|
|
55
|
+
aria-labelledby="{id}-title"
|
|
56
|
+
aria-describedby={description ? `${id}-description` : undefined}
|
|
57
|
+
class="alert-dialog"
|
|
58
|
+
onkeydown={(event) => {
|
|
59
|
+
if (event.key !== 'Escape') return;
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
close();
|
|
62
|
+
}}
|
|
63
|
+
oncancel={(event) => {
|
|
64
|
+
event.preventDefault();
|
|
65
|
+
close();
|
|
66
|
+
}}
|
|
67
|
+
onclose={() => (open = false)}
|
|
68
|
+
>
|
|
69
|
+
<h2 id="{id}-title" class="alert-dialog-title">{title}</h2>
|
|
70
|
+
{#if description}
|
|
71
|
+
<p id="{id}-description" class="alert-dialog-description">{description}</p>
|
|
72
|
+
{/if}
|
|
73
|
+
{#if children}
|
|
74
|
+
<div class="alert-dialog-body">{@render children()}</div>
|
|
75
|
+
{/if}
|
|
76
|
+
<div class="alert-dialog-actions">
|
|
77
|
+
{@render actions(close)}
|
|
78
|
+
</div>
|
|
79
|
+
</dialog>
|
|
80
|
+
|
|
81
|
+
<style>
|
|
82
|
+
/* Locks page scrolling while open; the gutter keeps the layout from shifting */
|
|
83
|
+
:global(html:has(.alert-dialog[open])) {
|
|
84
|
+
overflow: hidden;
|
|
85
|
+
scrollbar-gutter: stable;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.alert-dialog {
|
|
89
|
+
box-sizing: border-box;
|
|
90
|
+
width: calc(100% - 32px);
|
|
91
|
+
max-width: 420px;
|
|
92
|
+
padding: 20px;
|
|
93
|
+
background-color: var(--color-bg);
|
|
94
|
+
color: var(--color-text);
|
|
95
|
+
border: 1px solid var(--color-border);
|
|
96
|
+
border-radius: 14px;
|
|
97
|
+
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.16);
|
|
98
|
+
outline: none;
|
|
99
|
+
opacity: 0;
|
|
100
|
+
scale: 0.95;
|
|
101
|
+
transition:
|
|
102
|
+
opacity 140ms ease,
|
|
103
|
+
scale 140ms ease,
|
|
104
|
+
display 140ms allow-discrete,
|
|
105
|
+
overlay 140ms allow-discrete;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.alert-dialog[open] {
|
|
109
|
+
opacity: 1;
|
|
110
|
+
scale: 1;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.alert-dialog::backdrop {
|
|
114
|
+
background-color: rgba(0, 0, 0, 0);
|
|
115
|
+
transition:
|
|
116
|
+
background-color 140ms ease,
|
|
117
|
+
display 140ms allow-discrete,
|
|
118
|
+
overlay 140ms allow-discrete;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.alert-dialog[open]::backdrop {
|
|
122
|
+
background-color: rgba(0, 0, 0, 0.4);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@starting-style {
|
|
126
|
+
.alert-dialog[open] {
|
|
127
|
+
opacity: 0;
|
|
128
|
+
scale: 0.95;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.alert-dialog[open]::backdrop {
|
|
132
|
+
background-color: rgba(0, 0, 0, 0);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.alert-dialog-title {
|
|
137
|
+
margin: 0;
|
|
138
|
+
font-size: 15px;
|
|
139
|
+
font-weight: 600;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.alert-dialog-description {
|
|
143
|
+
margin: 6px 0 0;
|
|
144
|
+
font-size: 13px;
|
|
145
|
+
line-height: 1.5;
|
|
146
|
+
color: var(--color-text-muted);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.alert-dialog-body {
|
|
150
|
+
margin-top: 16px;
|
|
151
|
+
font-size: 13px;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.alert-dialog-actions {
|
|
155
|
+
display: flex;
|
|
156
|
+
flex-wrap: wrap;
|
|
157
|
+
justify-content: center;
|
|
158
|
+
gap: 4px;
|
|
159
|
+
margin-top: 20px;
|
|
160
|
+
}
|
|
161
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type AlertDialogTriggerProps = {
|
|
2
|
+
onclick: () => void;
|
|
3
|
+
'aria-haspopup': 'dialog';
|
|
4
|
+
};
|
|
5
|
+
import type { Snippet } from 'svelte';
|
|
6
|
+
type Props = {
|
|
7
|
+
/** Whether the dialog is open. Bindable. Escape closes it. */
|
|
8
|
+
open?: boolean;
|
|
9
|
+
title: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
/** Renders the trigger. Spread the given props onto it, e.g. `<Button {...props} />`. Omit to control `open` yourself. */
|
|
12
|
+
trigger?: Snippet<[AlertDialogTriggerProps]>;
|
|
13
|
+
/** The Buttons, primary first and least destructive last; the last one gets the focus on open. Call `close` to close the dialog. */
|
|
14
|
+
actions: Snippet<[close: () => void]>;
|
|
15
|
+
/** Extra content between the description and the buttons. */
|
|
16
|
+
children?: Snippet;
|
|
17
|
+
};
|
|
18
|
+
declare const AlertDialog: import("svelte").Component<Props, {}, "open">;
|
|
19
|
+
type AlertDialog = ReturnType<typeof AlertDialog>;
|
|
20
|
+
export default AlertDialog;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { User } from '@lucide/svelte';
|
|
4
|
+
|
|
5
|
+
type Props = Omit<HTMLAttributes<HTMLSpanElement>, 'children'> & {
|
|
6
|
+
src?: string;
|
|
7
|
+
/** Describes the person; also the accessible name when the fallback is shown. */
|
|
8
|
+
alt: string;
|
|
9
|
+
/** Shown when there is no `src` or the image fails to load, e.g. initials. Defaults to a user icon. */
|
|
10
|
+
fallback?: string;
|
|
11
|
+
size?: 'sm' | 'md' | 'lg';
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
let { src, alt, fallback, size = 'md', class: className, ...rest }: Props = $props();
|
|
15
|
+
|
|
16
|
+
let failedSrc = $state<string>();
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<span {...rest} class={['avatar', `avatar--${size}`, className]}>
|
|
20
|
+
{#if src && src !== failedSrc}
|
|
21
|
+
<img class="avatar-image" {src} {alt} onerror={() => (failedSrc = src)} />
|
|
22
|
+
{:else}
|
|
23
|
+
<span class="avatar-fallback" role="img" aria-label={alt}>
|
|
24
|
+
{#if fallback}
|
|
25
|
+
{fallback}
|
|
26
|
+
{:else}
|
|
27
|
+
<User class="avatar-icon" aria-hidden="true" />
|
|
28
|
+
{/if}
|
|
29
|
+
</span>
|
|
30
|
+
{/if}
|
|
31
|
+
</span>
|
|
32
|
+
|
|
33
|
+
<style>
|
|
34
|
+
.avatar {
|
|
35
|
+
display: inline-flex;
|
|
36
|
+
flex-shrink: 0;
|
|
37
|
+
overflow: hidden;
|
|
38
|
+
background-color: var(--color-surface);
|
|
39
|
+
color: var(--color-text-secondary);
|
|
40
|
+
user-select: none;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.avatar--sm {
|
|
44
|
+
width: 24px;
|
|
45
|
+
height: 24px;
|
|
46
|
+
border-radius: 8px;
|
|
47
|
+
font-size: 10px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.avatar--md {
|
|
51
|
+
width: 32px;
|
|
52
|
+
height: 32px;
|
|
53
|
+
border-radius: 10px;
|
|
54
|
+
font-size: 12px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.avatar--lg {
|
|
58
|
+
width: 40px;
|
|
59
|
+
height: 40px;
|
|
60
|
+
border-radius: 12px;
|
|
61
|
+
font-size: 14px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.avatar-image {
|
|
65
|
+
width: 100%;
|
|
66
|
+
height: 100%;
|
|
67
|
+
object-fit: cover;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.avatar-fallback {
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
justify-content: center;
|
|
74
|
+
width: 100%;
|
|
75
|
+
height: 100%;
|
|
76
|
+
font-family: inherit;
|
|
77
|
+
font-weight: 500;
|
|
78
|
+
text-transform: uppercase;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.avatar-fallback :global(.avatar-icon) {
|
|
82
|
+
width: 60%;
|
|
83
|
+
height: 60%;
|
|
84
|
+
}
|
|
85
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
type Props = Omit<HTMLAttributes<HTMLSpanElement>, 'children'> & {
|
|
3
|
+
src?: string;
|
|
4
|
+
/** Describes the person; also the accessible name when the fallback is shown. */
|
|
5
|
+
alt: string;
|
|
6
|
+
/** Shown when there is no `src` or the image fails to load, e.g. initials. Defaults to a user icon. */
|
|
7
|
+
fallback?: string;
|
|
8
|
+
size?: 'sm' | 'md' | 'lg';
|
|
9
|
+
};
|
|
10
|
+
declare const Avatar: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type Avatar = ReturnType<typeof Avatar>;
|
|
12
|
+
export default Avatar;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import type { LucideIcon } from '@lucide/svelte';
|
|
5
|
+
|
|
6
|
+
type Props = Omit<HTMLAttributes<HTMLSpanElement>, 'children'> & {
|
|
7
|
+
variant?: 'primary' | 'secondary';
|
|
8
|
+
/** Any Lucide icon (import from `svelte-ui/icons`). */
|
|
9
|
+
icon?: LucideIcon;
|
|
10
|
+
children: Snippet;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
let { variant = 'secondary', icon: Icon, class: className, children, ...rest }: Props = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<span {...rest} class={['badge', `badge--${variant}`, className]}>
|
|
17
|
+
{#if Icon}<Icon class="badge-icon" aria-hidden="true" />{/if}
|
|
18
|
+
{@render children()}
|
|
19
|
+
</span>
|
|
20
|
+
|
|
21
|
+
<style>
|
|
22
|
+
.badge {
|
|
23
|
+
display: inline-flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
gap: 4px;
|
|
26
|
+
width: fit-content;
|
|
27
|
+
padding: 2px 8px;
|
|
28
|
+
font-family: inherit;
|
|
29
|
+
font-size: 12px;
|
|
30
|
+
border-radius: 6px;
|
|
31
|
+
user-select: none;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.badge--primary {
|
|
35
|
+
background-color: var(--color-accent);
|
|
36
|
+
color: var(--color-accent-foreground);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.badge--secondary {
|
|
40
|
+
background-color: var(--color-surface);
|
|
41
|
+
color: var(--color-text);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.badge :global(.badge-icon) {
|
|
45
|
+
width: 12px;
|
|
46
|
+
height: 12px;
|
|
47
|
+
flex-shrink: 0;
|
|
48
|
+
}
|
|
49
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { LucideIcon } from '@lucide/svelte';
|
|
4
|
+
type Props = Omit<HTMLAttributes<HTMLSpanElement>, 'children'> & {
|
|
5
|
+
variant?: 'primary' | 'secondary';
|
|
6
|
+
/** Any Lucide icon (import from `svelte-ui/icons`). */
|
|
7
|
+
icon?: LucideIcon;
|
|
8
|
+
children: Snippet;
|
|
9
|
+
};
|
|
10
|
+
declare const Badge: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type Badge = ReturnType<typeof Badge>;
|
|
12
|
+
export default Badge;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
|
|
5
|
+
type Props = Omit<HTMLAttributes<HTMLElement>, 'children'> & {
|
|
6
|
+
/** `BreadcrumbItem`s and `BreadcrumbEllipsis`es. */
|
|
7
|
+
children: Snippet;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
let { class: className, children, ...rest }: Props = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<nav aria-label="Breadcrumb" {...rest} class={['breadcrumb', className]}>
|
|
14
|
+
<ol class="breadcrumb-list">
|
|
15
|
+
{@render children()}
|
|
16
|
+
</ol>
|
|
17
|
+
</nav>
|
|
18
|
+
|
|
19
|
+
<style>
|
|
20
|
+
.breadcrumb-list {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-wrap: wrap;
|
|
23
|
+
align-items: center;
|
|
24
|
+
gap: 6px;
|
|
25
|
+
margin: 0;
|
|
26
|
+
padding: 0;
|
|
27
|
+
list-style: none;
|
|
28
|
+
font-size: 13px;
|
|
29
|
+
color: var(--color-text-muted);
|
|
30
|
+
overflow-wrap: anywhere;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* Each item renders its own trailing separator; the last one has nothing to separate */
|
|
34
|
+
.breadcrumb-list :global(.breadcrumb-separator:last-child) {
|
|
35
|
+
display: none;
|
|
36
|
+
}
|
|
37
|
+
</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
type Props = Omit<HTMLAttributes<HTMLElement>, 'children'> & {
|
|
4
|
+
/** `BreadcrumbItem`s and `BreadcrumbEllipsis`es. */
|
|
5
|
+
children: Snippet;
|
|
6
|
+
};
|
|
7
|
+
declare const Breadcrumb: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type Breadcrumb = ReturnType<typeof Breadcrumb>;
|
|
9
|
+
export default Breadcrumb;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import Ellipsis from '@lucide/svelte/icons/ellipsis';
|
|
4
|
+
import Button from '../button/Button.svelte';
|
|
5
|
+
import ContextMenu from '../context-menu/ContextMenu.svelte';
|
|
6
|
+
import BreadcrumbSeparator from './BreadcrumbSeparator.svelte';
|
|
7
|
+
|
|
8
|
+
type Props = {
|
|
9
|
+
/** Accessible name of the menu trigger. */
|
|
10
|
+
label?: string;
|
|
11
|
+
/** `ContextMenuItem`s for the collapsed items. */
|
|
12
|
+
children: Snippet;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
let { label = 'More', children }: Props = $props();
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<li class="breadcrumb-ellipsis">
|
|
19
|
+
<ContextMenu>
|
|
20
|
+
{#snippet trigger(props)}
|
|
21
|
+
<Button {...props} variant="ghost" size="sm" icon={Ellipsis} {label} />
|
|
22
|
+
{/snippet}
|
|
23
|
+
{@render children()}
|
|
24
|
+
</ContextMenu>
|
|
25
|
+
</li>
|
|
26
|
+
<BreadcrumbSeparator />
|
|
27
|
+
|
|
28
|
+
<style>
|
|
29
|
+
.breadcrumb-ellipsis {
|
|
30
|
+
display: inline-flex;
|
|
31
|
+
}
|
|
32
|
+
</style>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type Props = {
|
|
3
|
+
/** Accessible name of the menu trigger. */
|
|
4
|
+
label?: string;
|
|
5
|
+
/** `ContextMenuItem`s for the collapsed items. */
|
|
6
|
+
children: Snippet;
|
|
7
|
+
};
|
|
8
|
+
declare const BreadcrumbEllipsis: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type BreadcrumbEllipsis = ReturnType<typeof BreadcrumbEllipsis>;
|
|
10
|
+
export default BreadcrumbEllipsis;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { LucideIcon } from '@lucide/svelte';
|
|
4
|
+
import BreadcrumbSeparator from './BreadcrumbSeparator.svelte';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
/** Links the item. Without it, the item is the current page. */
|
|
8
|
+
href?: string;
|
|
9
|
+
/** Any Lucide icon (import from `svelte-ui/icons`). */
|
|
10
|
+
icon?: LucideIcon;
|
|
11
|
+
children: Snippet;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
let { href, icon: Icon, children }: Props = $props();
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
{#snippet content()}
|
|
18
|
+
{#if Icon}<Icon class="breadcrumb-item-icon" aria-hidden="true" />{/if}
|
|
19
|
+
{@render children()}
|
|
20
|
+
{/snippet}
|
|
21
|
+
|
|
22
|
+
<li class="breadcrumb-item">
|
|
23
|
+
{#if href}
|
|
24
|
+
<!-- href comes from the consumer, who resolves it; this library has no routes -->
|
|
25
|
+
<!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
|
|
26
|
+
<a {href} class="breadcrumb-link">{@render content()}</a>
|
|
27
|
+
{:else}
|
|
28
|
+
<span aria-current="page" class="breadcrumb-page">{@render content()}</span>
|
|
29
|
+
{/if}
|
|
30
|
+
</li>
|
|
31
|
+
<BreadcrumbSeparator />
|
|
32
|
+
|
|
33
|
+
<style>
|
|
34
|
+
.breadcrumb-item {
|
|
35
|
+
display: inline-flex;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.breadcrumb-link,
|
|
39
|
+
.breadcrumb-page {
|
|
40
|
+
display: inline-flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
gap: 6px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.breadcrumb-link {
|
|
46
|
+
color: inherit;
|
|
47
|
+
text-decoration: none;
|
|
48
|
+
outline: none;
|
|
49
|
+
border-radius: 4px;
|
|
50
|
+
transition: color 200ms ease;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.breadcrumb-link:hover {
|
|
54
|
+
color: var(--color-text);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.breadcrumb-link:focus-visible {
|
|
58
|
+
outline: 2px solid var(--color-accent);
|
|
59
|
+
outline-offset: 2px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.breadcrumb-page {
|
|
63
|
+
color: var(--color-text);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.breadcrumb-item :global(.breadcrumb-item-icon) {
|
|
67
|
+
width: 14px;
|
|
68
|
+
height: 14px;
|
|
69
|
+
flex-shrink: 0;
|
|
70
|
+
}
|
|
71
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { LucideIcon } from '@lucide/svelte';
|
|
3
|
+
type Props = {
|
|
4
|
+
/** Links the item. Without it, the item is the current page. */
|
|
5
|
+
href?: string;
|
|
6
|
+
/** Any Lucide icon (import from `svelte-ui/icons`). */
|
|
7
|
+
icon?: LucideIcon;
|
|
8
|
+
children: Snippet;
|
|
9
|
+
};
|
|
10
|
+
declare const BreadcrumbItem: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type BreadcrumbItem = ReturnType<typeof BreadcrumbItem>;
|
|
12
|
+
export default BreadcrumbItem;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<li role="presentation" aria-hidden="true" class="breadcrumb-separator">
|
|
6
|
+
<ChevronRight />
|
|
7
|
+
</li>
|
|
8
|
+
|
|
9
|
+
<style>
|
|
10
|
+
.breadcrumb-separator {
|
|
11
|
+
display: flex;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.breadcrumb-separator :global(svg) {
|
|
15
|
+
width: 14px;
|
|
16
|
+
height: 14px;
|
|
17
|
+
}
|
|
18
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const BreadcrumbSeparator: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type BreadcrumbSeparator = InstanceType<typeof BreadcrumbSeparator>;
|
|
18
|
+
export default BreadcrumbSeparator;
|