@noahbaumgartner/svelte-ui 0.0.5 → 0.0.7
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/LICENSE +21 -0
- package/README.md +20 -5
- package/dist/components/accordion/Accordion.svelte +16 -6
- package/dist/components/accordion/Accordion.svelte.d.ts +3 -1
- package/dist/components/accordion/AccordionItem.svelte +106 -67
- package/dist/components/accordion/AccordionItem.svelte.d.ts +5 -1
- package/dist/components/alert-dialog/AlertDialog.svelte +108 -76
- package/dist/components/alert-dialog/AlertDialog.svelte.d.ts +5 -2
- package/dist/components/avatar/Avatar.svelte +71 -49
- package/dist/components/avatar/Avatar.svelte.d.ts +5 -2
- package/dist/components/avatar-group/AvatarGroup.svelte +72 -45
- package/dist/components/avatar-group/AvatarGroup.svelte.d.ts +5 -1
- package/dist/components/badge/Badge.svelte +50 -28
- package/dist/components/badge/Badge.svelte.d.ts +6 -4
- package/dist/components/breadcrumb/Breadcrumb.svelte +21 -17
- package/dist/components/breadcrumb/Breadcrumb.svelte.d.ts +3 -1
- package/dist/components/breadcrumb/BreadcrumbEllipsis.svelte +17 -6
- package/dist/components/breadcrumb/BreadcrumbEllipsis.svelte.d.ts +5 -2
- package/dist/components/breadcrumb/BreadcrumbItem.svelte +75 -36
- package/dist/components/breadcrumb/BreadcrumbItem.svelte.d.ts +8 -5
- package/dist/components/breadcrumb/BreadcrumbSeparator.svelte +32 -9
- package/dist/components/breadcrumb/BreadcrumbSeparator.svelte.d.ts +10 -17
- package/dist/components/button/Button.svelte +206 -168
- package/dist/components/button/Button.svelte.d.ts +9 -5
- package/dist/components/button-group/ButtonGroup.svelte +52 -55
- package/dist/components/button-group/ButtonGroup.svelte.d.ts +3 -1
- package/dist/components/calendar/Calendar.svelte +232 -144
- package/dist/components/calendar/Calendar.svelte.d.ts +19 -2
- package/dist/components/calendar/dates.d.ts +4 -1
- package/dist/components/calendar/dates.js +8 -2
- package/dist/components/card/Card.svelte +48 -32
- package/dist/components/card/Card.svelte.d.ts +3 -1
- package/dist/components/card/CardAction.svelte +11 -7
- package/dist/components/card/CardAction.svelte.d.ts +3 -1
- package/dist/components/card/CardContent.svelte +8 -4
- package/dist/components/card/CardContent.svelte.d.ts +3 -1
- package/dist/components/card/CardDescription.svelte +11 -7
- package/dist/components/card/CardDescription.svelte.d.ts +3 -1
- package/dist/components/card/CardFooter.svelte +15 -11
- package/dist/components/card/CardFooter.svelte.d.ts +3 -1
- package/dist/components/card/CardHeader.svelte +15 -11
- package/dist/components/card/CardHeader.svelte.d.ts +3 -1
- package/dist/components/card/CardTitle.svelte +11 -7
- package/dist/components/card/CardTitle.svelte.d.ts +3 -1
- package/dist/components/checkbox/Checkbox.svelte +152 -61
- package/dist/components/checkbox/Checkbox.svelte.d.ts +5 -2
- package/dist/components/color-picker/ColorPicker.svelte +131 -78
- package/dist/components/color-picker/ColorPicker.svelte.d.ts +10 -1
- package/dist/components/context-menu/ContextMenu.svelte +78 -61
- package/dist/components/context-menu/ContextMenu.svelte.d.ts +5 -2
- package/dist/components/context-menu/ContextMenuInfo.svelte +91 -0
- package/dist/components/context-menu/ContextMenuInfo.svelte.d.ts +19 -0
- package/dist/components/context-menu/ContextMenuItem.svelte +102 -57
- package/dist/components/context-menu/ContextMenuItem.svelte.d.ts +10 -5
- package/dist/components/context-menu/ContextMenuLabel.svelte +28 -0
- package/dist/components/context-menu/ContextMenuLabel.svelte.d.ts +10 -0
- package/dist/components/context-menu/ContextMenuSeparator.svelte +29 -0
- package/dist/components/context-menu/ContextMenuSeparator.svelte.d.ts +8 -0
- package/dist/components/dialog/Dialog.svelte +149 -108
- package/dist/components/dialog/Dialog.svelte.d.ts +7 -2
- package/dist/components/drawer/Drawer.svelte +240 -189
- package/dist/components/drawer/Drawer.svelte.d.ts +7 -2
- package/dist/components/empty-state/EmptyState.svelte +67 -47
- package/dist/components/empty-state/EmptyState.svelte.d.ts +7 -4
- package/dist/components/entry/Entry.svelte +53 -42
- package/dist/components/entry/Entry.svelte.d.ts +2 -1
- package/dist/components/field/Field.svelte +66 -45
- package/dist/components/field/Field.svelte.d.ts +2 -1
- package/dist/components/field/FieldContent.svelte +11 -8
- package/dist/components/field/FieldContent.svelte.d.ts +2 -1
- package/dist/components/field/FieldDescription.svelte +18 -15
- package/dist/components/field/FieldDescription.svelte.d.ts +2 -1
- package/dist/components/field/FieldError.svelte +22 -13
- package/dist/components/field/FieldError.svelte.d.ts +2 -1
- package/dist/components/field/FieldGroup.svelte +15 -12
- package/dist/components/field/FieldGroup.svelte.d.ts +2 -1
- package/dist/components/field/FieldLegend.svelte +23 -14
- package/dist/components/field/FieldLegend.svelte.d.ts +2 -1
- package/dist/components/field/FieldSeparator.svelte +12 -9
- package/dist/components/field/FieldSeparator.svelte.d.ts +2 -1
- package/dist/components/field/FieldSet.svelte +18 -15
- package/dist/components/field/FieldSet.svelte.d.ts +2 -1
- package/dist/components/footer/Footer.svelte +63 -47
- package/dist/components/footer/Footer.svelte.d.ts +2 -1
- package/dist/components/footer/FooterColumn.svelte +17 -14
- package/dist/components/footer/FooterColumn.svelte.d.ts +2 -1
- package/dist/components/image/Image.svelte +61 -0
- package/dist/components/image/Image.svelte.d.ts +18 -0
- package/dist/components/input/Input.svelte +307 -208
- package/dist/components/input/Input.svelte.d.ts +12 -1
- package/dist/components/input-group/InputGroup.svelte +101 -61
- package/dist/components/input-group/InputGroup.svelte.d.ts +2 -1
- package/dist/components/input-group/InputGroupAddon.svelte +58 -49
- package/dist/components/kbd/Kbd.svelte +39 -30
- package/dist/components/kbd/Kbd.svelte.d.ts +2 -1
- package/dist/components/kbd/KbdGroup.svelte +15 -12
- package/dist/components/kbd/KbdGroup.svelte.d.ts +2 -1
- package/dist/components/label/Label.svelte +47 -28
- package/dist/components/label/Label.svelte.d.ts +2 -1
- package/dist/components/link/Link.svelte +71 -17
- package/dist/components/link/Link.svelte.d.ts +2 -1
- package/dist/components/mesh-gradient/MeshGradient.svelte +33 -22
- package/dist/components/mesh-gradient/MeshGradient.svelte.d.ts +2 -3
- package/dist/components/navbar/Navbar.svelte +149 -99
- package/dist/components/navbar/Navbar.svelte.d.ts +4 -2
- package/dist/components/navigation-menu/NavigationMenu.svelte +37 -20
- package/dist/components/navigation-menu/NavigationMenu.svelte.d.ts +4 -2
- package/dist/components/navigation-menu/NavigationMenuItem.svelte +131 -89
- package/dist/components/navigation-menu/NavigationMenuItem.svelte.d.ts +4 -2
- package/dist/components/navigation-menu/NavigationMenuLink.svelte +90 -51
- package/dist/components/navigation-menu/NavigationMenuLink.svelte.d.ts +7 -5
- package/dist/components/number-stepper/NumberStepper.svelte +39 -20
- package/dist/components/number-stepper/NumberStepper.svelte.d.ts +6 -1
- package/dist/components/popover/Popover.svelte +85 -65
- package/dist/components/popover/Popover.svelte.d.ts +5 -2
- package/dist/components/preview-card/PreviewCard.svelte +116 -98
- package/dist/components/preview-card/PreviewCard.svelte.d.ts +9 -6
- package/dist/components/progress/Progress.svelte +61 -38
- package/dist/components/progress/Progress.svelte.d.ts +2 -1
- package/dist/components/radio-group/RadioGroup.svelte +24 -19
- package/dist/components/radio-group/RadioGroup.svelte.d.ts +2 -1
- package/dist/components/radio-group/RadioGroupItem.svelte +101 -54
- package/dist/components/radio-group/RadioGroupItem.svelte.d.ts +2 -1
- package/dist/components/section/Section.svelte +114 -0
- package/dist/components/section/Section.svelte.d.ts +22 -0
- package/dist/components/select/Select.svelte +216 -133
- package/dist/components/select/Select.svelte.d.ts +11 -2
- package/dist/components/separator/Separator.svelte +21 -10
- package/dist/components/separator/Separator.svelte.d.ts +2 -1
- package/dist/components/sidebar/Sidebar.svelte +142 -108
- package/dist/components/sidebar/Sidebar.svelte.d.ts +6 -1
- package/dist/components/sidebar/SidebarContent.svelte +15 -12
- package/dist/components/sidebar/SidebarContent.svelte.d.ts +2 -1
- package/dist/components/sidebar/SidebarFooter.svelte +10 -7
- package/dist/components/sidebar/SidebarFooter.svelte.d.ts +2 -1
- package/dist/components/sidebar/SidebarGroup.svelte +35 -25
- package/dist/components/sidebar/SidebarGroup.svelte.d.ts +2 -1
- package/dist/components/sidebar/SidebarHeader.svelte +21 -16
- package/dist/components/sidebar/SidebarHeader.svelte.d.ts +6 -1
- package/dist/components/sidebar/SidebarInset.svelte +11 -8
- package/dist/components/sidebar/SidebarInset.svelte.d.ts +2 -1
- package/dist/components/sidebar/SidebarMenu.svelte +13 -10
- package/dist/components/sidebar/SidebarMenu.svelte.d.ts +2 -1
- package/dist/components/sidebar/SidebarMenuItem.svelte +195 -114
- package/dist/components/sidebar/SidebarMenuItem.svelte.d.ts +11 -5
- package/dist/components/sidebar/SidebarProvider.svelte +18 -9
- package/dist/components/sidebar/SidebarProvider.svelte.d.ts +2 -1
- package/dist/components/sidebar/SidebarSeparator.svelte +6 -1
- package/dist/components/sidebar/SidebarSeparator.svelte.d.ts +6 -17
- package/dist/components/sidebar/SidebarTrigger.svelte +17 -5
- package/dist/components/sidebar/SidebarTrigger.svelte.d.ts +4 -2
- package/dist/components/skeleton/Skeleton.svelte +26 -16
- package/dist/components/skeleton/Skeleton.svelte.d.ts +4 -2
- package/dist/components/spinner/Spinner.svelte +71 -46
- package/dist/components/spinner/Spinner.svelte.d.ts +2 -1
- package/dist/components/switch/Switch.svelte +126 -65
- package/dist/components/switch/Switch.svelte.d.ts +4 -2
- package/dist/components/table/Table.svelte +135 -76
- package/dist/components/table/Table.svelte.d.ts +12 -2
- package/dist/components/tabs/Tabs.svelte +173 -116
- package/dist/components/tabs/Tabs.svelte.d.ts +10 -8
- package/dist/components/textarea/Textarea.svelte +76 -42
- package/dist/components/textarea/Textarea.svelte.d.ts +4 -1
- package/dist/components/time-picker/TimePicker.svelte +214 -85
- package/dist/components/time-picker/TimePicker.svelte.d.ts +18 -1
- package/dist/components/toaster/Toaster.svelte +132 -70
- package/dist/components/toaster/Toaster.svelte.d.ts +18 -2
- package/dist/components/toaster/toast.svelte.d.ts +3 -3
- package/dist/components/toggle/Toggle.svelte +25 -4
- package/dist/components/toggle/Toggle.svelte.d.ts +1 -1
- package/dist/components/tooltip/Tooltip.svelte +87 -58
- package/dist/components/tooltip/Tooltip.svelte.d.ts +4 -2
- package/dist/icon.d.ts +12 -0
- package/dist/icon.js +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5 -0
- package/dist/internal/icons/ArrowDown.svelte +14 -0
- package/dist/internal/icons/ArrowDown.svelte.d.ts +4 -0
- package/dist/internal/icons/ArrowUp.svelte +14 -0
- package/dist/internal/icons/ArrowUp.svelte.d.ts +4 -0
- package/dist/internal/icons/Calendar.svelte +16 -0
- package/dist/internal/icons/Calendar.svelte.d.ts +4 -0
- package/dist/internal/icons/Check.svelte +8 -0
- package/dist/internal/icons/Check.svelte.d.ts +4 -0
- package/dist/internal/icons/ChevronDown.svelte +8 -0
- package/dist/internal/icons/ChevronDown.svelte.d.ts +4 -0
- package/dist/internal/icons/ChevronLeft.svelte +8 -0
- package/dist/internal/icons/ChevronLeft.svelte.d.ts +4 -0
- package/dist/internal/icons/ChevronRight.svelte +8 -0
- package/dist/internal/icons/ChevronRight.svelte.d.ts +4 -0
- package/dist/internal/icons/ChevronUp.svelte +8 -0
- package/dist/internal/icons/ChevronUp.svelte.d.ts +4 -0
- package/dist/internal/icons/ChevronsUpDown.svelte +14 -0
- package/dist/internal/icons/ChevronsUpDown.svelte.d.ts +4 -0
- package/dist/internal/icons/Clock.svelte +14 -0
- package/dist/internal/icons/Clock.svelte.d.ts +4 -0
- package/dist/internal/icons/Ellipsis.svelte +15 -0
- package/dist/internal/icons/Ellipsis.svelte.d.ts +4 -0
- package/dist/internal/icons/Icon.svelte +33 -0
- package/dist/internal/icons/Icon.svelte.d.ts +8 -0
- package/dist/internal/icons/Minus.svelte +8 -0
- package/dist/internal/icons/Minus.svelte.d.ts +4 -0
- package/dist/internal/icons/PanelLeft.svelte +14 -0
- package/dist/internal/icons/PanelLeft.svelte.d.ts +4 -0
- package/dist/internal/icons/Plus.svelte +14 -0
- package/dist/internal/icons/Plus.svelte.d.ts +4 -0
- package/dist/internal/icons/User.svelte +14 -0
- package/dist/internal/icons/User.svelte.d.ts +4 -0
- package/dist/internal/icons/X.svelte +14 -0
- package/dist/internal/icons/X.svelte.d.ts +4 -0
- package/dist/styles/tokens.css +39 -41
- package/package.json +5 -10
- package/dist/icons.d.ts +0 -2
- package/dist/icons.js +0 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Noah Baumgartner
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Then use the components:
|
|
|
25
25
|
```svelte
|
|
26
26
|
<script lang="ts">
|
|
27
27
|
import { Button, Card, CardHeader, CardTitle, CardContent } from '@noahbaumgartner/svelte-ui';
|
|
28
|
-
import { Plus } from '@
|
|
28
|
+
import { Plus } from '@lucide/svelte';
|
|
29
29
|
</script>
|
|
30
30
|
|
|
31
31
|
<Card>
|
|
@@ -40,21 +40,32 @@ Then use the components:
|
|
|
40
40
|
|
|
41
41
|
### Icons
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
The library ships no icons and works with any icon library. Every `icon` prop takes a Svelte component, so use [Lucide](https://lucide.dev), [Phosphor](https://phosphoricons.com), your own SVG components or anything else:
|
|
44
|
+
|
|
45
|
+
```svelte
|
|
46
|
+
<script>
|
|
47
|
+
import { Button } from '@noahbaumgartner/svelte-ui';
|
|
48
|
+
import Plus from '@lucide/svelte/icons/plus';
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<Button icon={Plus}>New project</Button>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
An icon component receives `class` and `aria-hidden` and is sized with CSS, so it should render a single `<svg>` that fills its box. The `IconComponent` type describes what the props accept.
|
|
44
55
|
|
|
45
56
|
### Theming
|
|
46
57
|
|
|
47
|
-
All colours are derived from two variables, `--base` and `--ink`, mixed into a grey scale. Light and dark mode follow `prefers-color-scheme` by default; force one with a `data-theme` attribute on `<html>`:
|
|
58
|
+
All colours are derived from two variables, `--ui-base` and `--ui-ink`, mixed into a grey scale. Light and dark mode follow `prefers-color-scheme` by default; force one with a `data-theme` attribute on `<html>`:
|
|
48
59
|
|
|
49
60
|
```html
|
|
50
61
|
<html data-theme="dark"></html>
|
|
51
62
|
```
|
|
52
63
|
|
|
53
|
-
Set `--accent` to colour checked controls, primary buttons and focus rings. It defaults to `--ink`, and the foreground colour on top of it is picked automatically for contrast:
|
|
64
|
+
Set `--ui-accent` to colour checked controls, primary buttons and focus rings. It defaults to `--ui-ink`, and the foreground colour on top of it is picked automatically for contrast:
|
|
54
65
|
|
|
55
66
|
```css
|
|
56
67
|
:root {
|
|
57
|
-
--accent: #2563eb;
|
|
68
|
+
--ui-accent: #2563eb;
|
|
58
69
|
}
|
|
59
70
|
```
|
|
60
71
|
|
|
@@ -94,3 +105,7 @@ Components live in `src/lib/components/<name>/`, each next to its `.stories.svel
|
|
|
94
105
|
## Releasing
|
|
95
106
|
|
|
96
107
|
Publishing a GitHub release triggers [`.github/workflows/publish.yml`](.github/workflows/publish.yml), which sets the package version from the release tag (e.g. `v0.2.0` → `0.2.0`), type-checks, and stages the publish on npm with provenance. The staged version then has to be approved with 2FA (`npm stage approve <stage-id>` or on npmjs.com).
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
[MIT](LICENSE)
|
|
@@ -6,11 +6,19 @@
|
|
|
6
6
|
type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
|
|
7
7
|
/** Lets several items be open at once. By default opening one closes the others. */
|
|
8
8
|
multiple?: boolean;
|
|
9
|
+
/** The root element. Bindable. */
|
|
10
|
+
ref?: HTMLDivElement | null;
|
|
9
11
|
/** AccordionItems. */
|
|
10
12
|
children: Snippet;
|
|
11
13
|
};
|
|
12
14
|
|
|
13
|
-
let {
|
|
15
|
+
let {
|
|
16
|
+
multiple = false,
|
|
17
|
+
ref = $bindable(null),
|
|
18
|
+
class: className,
|
|
19
|
+
children,
|
|
20
|
+
...rest
|
|
21
|
+
}: Props = $props();
|
|
14
22
|
|
|
15
23
|
const name = $props.id();
|
|
16
24
|
|
|
@@ -21,14 +29,16 @@
|
|
|
21
29
|
});
|
|
22
30
|
</script>
|
|
23
31
|
|
|
24
|
-
<div {...rest} class={['accordion', className]}>
|
|
32
|
+
<div {...rest} bind:this={ref} class={['accordion', className]}>
|
|
25
33
|
{@render children()}
|
|
26
34
|
</div>
|
|
27
35
|
|
|
28
36
|
<style>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
@layer svelte-ui {
|
|
38
|
+
.accordion {
|
|
39
|
+
display: flex;
|
|
40
|
+
flex-direction: column;
|
|
41
|
+
width: 100%;
|
|
42
|
+
}
|
|
33
43
|
}
|
|
34
44
|
</style>
|
|
@@ -3,9 +3,11 @@ import type { HTMLAttributes } from 'svelte/elements';
|
|
|
3
3
|
type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
|
|
4
4
|
/** Lets several items be open at once. By default opening one closes the others. */
|
|
5
5
|
multiple?: boolean;
|
|
6
|
+
/** The root element. Bindable. */
|
|
7
|
+
ref?: HTMLDivElement | null;
|
|
6
8
|
/** AccordionItems. */
|
|
7
9
|
children: Snippet;
|
|
8
10
|
};
|
|
9
|
-
declare const Accordion: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
declare const Accordion: import("svelte").Component<Props, {}, "ref">;
|
|
10
12
|
type Accordion = ReturnType<typeof Accordion>;
|
|
11
13
|
export default Accordion;
|
|
@@ -1,106 +1,145 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLDetailsAttributes } from 'svelte/elements';
|
|
4
|
-
import
|
|
4
|
+
import ChevronDown from '../../internal/icons/ChevronDown.svelte';
|
|
5
5
|
import { getAccordionContext } from './context.js';
|
|
6
6
|
|
|
7
7
|
type Props = Omit<HTMLDetailsAttributes, 'children' | 'title' | 'name'> & {
|
|
8
8
|
/** Whether the item is expanded. Bindable. */
|
|
9
9
|
open?: boolean;
|
|
10
|
+
/** The details element. Bindable. */
|
|
11
|
+
ref?: HTMLDetailsElement | null;
|
|
10
12
|
/** The always visible heading that toggles the item. */
|
|
11
13
|
title: string;
|
|
14
|
+
/** Replaces the title text, e.g. to add an icon or badge. */
|
|
15
|
+
heading?: Snippet;
|
|
12
16
|
/** The content shown while the item is open. */
|
|
13
17
|
children: Snippet;
|
|
14
18
|
};
|
|
15
19
|
|
|
16
|
-
let {
|
|
20
|
+
let {
|
|
21
|
+
open = $bindable(false),
|
|
22
|
+
ref = $bindable(null),
|
|
23
|
+
title,
|
|
24
|
+
heading,
|
|
25
|
+
class: className,
|
|
26
|
+
children,
|
|
27
|
+
...rest
|
|
28
|
+
}: Props = $props();
|
|
17
29
|
|
|
18
30
|
const accordion = getAccordionContext();
|
|
19
31
|
</script>
|
|
20
32
|
|
|
21
|
-
<details
|
|
33
|
+
<details
|
|
34
|
+
{...rest}
|
|
35
|
+
bind:this={ref}
|
|
36
|
+
bind:open
|
|
37
|
+
name={accordion.name}
|
|
38
|
+
class={['accordion-item', className]}
|
|
39
|
+
>
|
|
22
40
|
<summary class="accordion-trigger">
|
|
23
|
-
<span class="accordion-title">
|
|
41
|
+
<span class="accordion-title">
|
|
42
|
+
{#if heading}{@render heading()}{:else}{title}{/if}
|
|
43
|
+
</span>
|
|
24
44
|
<ChevronDown class="accordion-chevron" aria-hidden="true" />
|
|
25
45
|
</summary>
|
|
26
46
|
<div class="accordion-content">{@render children()}</div>
|
|
27
47
|
</details>
|
|
28
48
|
|
|
29
49
|
<style>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
50
|
+
@layer svelte-ui {
|
|
51
|
+
.accordion-item {
|
|
52
|
+
font-size: 13px;
|
|
53
|
+
color: var(--color-text);
|
|
54
|
+
border-bottom: 1px solid var(--color-border);
|
|
55
|
+
/* Lets the height animate to and from `auto` where the browser supports it */
|
|
56
|
+
interpolate-size: allow-keywords;
|
|
57
|
+
}
|
|
37
58
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
59
|
+
.accordion-item:last-child {
|
|
60
|
+
border-bottom: 0;
|
|
61
|
+
}
|
|
41
62
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
.accordion-trigger {
|
|
64
|
+
display: flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
justify-content: space-between;
|
|
67
|
+
gap: 12px;
|
|
68
|
+
padding: 14px 0;
|
|
69
|
+
font-weight: 500;
|
|
70
|
+
list-style: none;
|
|
71
|
+
border-radius: 6px;
|
|
72
|
+
outline: none;
|
|
73
|
+
cursor: pointer;
|
|
74
|
+
user-select: none;
|
|
75
|
+
}
|
|
55
76
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
77
|
+
.accordion-trigger::-webkit-details-marker {
|
|
78
|
+
display: none;
|
|
79
|
+
}
|
|
59
80
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
81
|
+
.accordion-trigger:hover .accordion-title {
|
|
82
|
+
text-decoration: underline;
|
|
83
|
+
text-underline-offset: 3px;
|
|
84
|
+
}
|
|
64
85
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
86
|
+
.accordion-trigger:focus-visible {
|
|
87
|
+
outline: 2px solid var(--color-accent);
|
|
88
|
+
outline-offset: 2px;
|
|
89
|
+
}
|
|
69
90
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
91
|
+
.accordion-trigger :global(.accordion-chevron) {
|
|
92
|
+
width: 16px;
|
|
93
|
+
height: 16px;
|
|
94
|
+
flex-shrink: 0;
|
|
95
|
+
color: var(--color-text-muted);
|
|
96
|
+
transition: rotate 200ms ease;
|
|
97
|
+
}
|
|
77
98
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
99
|
+
.accordion-item[open] > .accordion-trigger :global(.accordion-chevron) {
|
|
100
|
+
rotate: 180deg;
|
|
101
|
+
}
|
|
81
102
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
103
|
+
.accordion-item::details-content {
|
|
104
|
+
block-size: 0;
|
|
105
|
+
overflow: clip;
|
|
106
|
+
transition:
|
|
107
|
+
block-size 200ms ease,
|
|
108
|
+
content-visibility 200ms allow-discrete;
|
|
109
|
+
}
|
|
89
110
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
111
|
+
.accordion-item[open]::details-content {
|
|
112
|
+
block-size: auto;
|
|
113
|
+
}
|
|
93
114
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
115
|
+
.accordion-content {
|
|
116
|
+
padding-bottom: 14px;
|
|
117
|
+
line-height: 1.5;
|
|
118
|
+
color: var(--color-text-secondary);
|
|
119
|
+
}
|
|
99
120
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
121
|
+
@media (pointer: coarse) {
|
|
122
|
+
.accordion-trigger {
|
|
123
|
+
min-height: 44px;
|
|
124
|
+
box-sizing: border-box;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@media (forced-colors: active) {
|
|
129
|
+
.accordion-trigger:focus-visible {
|
|
130
|
+
outline-color: Highlight;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.accordion-item {
|
|
134
|
+
border-bottom-color: CanvasText;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@media (prefers-reduced-motion: reduce) {
|
|
139
|
+
.accordion-item::details-content,
|
|
140
|
+
.accordion-trigger :global(.accordion-chevron) {
|
|
141
|
+
transition: none;
|
|
142
|
+
}
|
|
104
143
|
}
|
|
105
144
|
}
|
|
106
145
|
</style>
|
|
@@ -3,11 +3,15 @@ import type { HTMLDetailsAttributes } from 'svelte/elements';
|
|
|
3
3
|
type Props = Omit<HTMLDetailsAttributes, 'children' | 'title' | 'name'> & {
|
|
4
4
|
/** Whether the item is expanded. Bindable. */
|
|
5
5
|
open?: boolean;
|
|
6
|
+
/** The details element. Bindable. */
|
|
7
|
+
ref?: HTMLDetailsElement | null;
|
|
6
8
|
/** The always visible heading that toggles the item. */
|
|
7
9
|
title: string;
|
|
10
|
+
/** Replaces the title text, e.g. to add an icon or badge. */
|
|
11
|
+
heading?: Snippet;
|
|
8
12
|
/** The content shown while the item is open. */
|
|
9
13
|
children: Snippet;
|
|
10
14
|
};
|
|
11
|
-
declare const AccordionItem: import("svelte").Component<Props, {}, "open">;
|
|
15
|
+
declare const AccordionItem: import("svelte").Component<Props, {}, "ref" | "open">;
|
|
12
16
|
type AccordionItem = ReturnType<typeof AccordionItem>;
|
|
13
17
|
export default AccordionItem;
|
|
@@ -7,10 +7,16 @@
|
|
|
7
7
|
|
|
8
8
|
<script lang="ts">
|
|
9
9
|
import type { Snippet } from 'svelte';
|
|
10
|
+
import type { HTMLDialogAttributes } from 'svelte/elements';
|
|
10
11
|
|
|
11
|
-
type Props =
|
|
12
|
+
type Props = Omit<
|
|
13
|
+
HTMLDialogAttributes,
|
|
14
|
+
'open' | 'title' | 'children' | 'role' | 'aria-labelledby' | 'aria-describedby'
|
|
15
|
+
> & {
|
|
12
16
|
/** Whether the dialog is open. Bindable. Escape closes it. */
|
|
13
17
|
open?: boolean;
|
|
18
|
+
/** The dialog element. Bindable. */
|
|
19
|
+
ref?: HTMLDialogElement | null;
|
|
14
20
|
title: string;
|
|
15
21
|
description?: string;
|
|
16
22
|
/** Renders the trigger. Spread the given props onto it, e.g. `<Button {...props} />`. Omit to control `open` yourself. */
|
|
@@ -21,10 +27,19 @@
|
|
|
21
27
|
children?: Snippet;
|
|
22
28
|
};
|
|
23
29
|
|
|
24
|
-
let {
|
|
30
|
+
let {
|
|
31
|
+
open = $bindable(false),
|
|
32
|
+
ref = $bindable(null),
|
|
33
|
+
title,
|
|
34
|
+
description,
|
|
35
|
+
trigger,
|
|
36
|
+
actions,
|
|
37
|
+
children,
|
|
38
|
+
class: className,
|
|
39
|
+
...rest
|
|
40
|
+
}: Props = $props();
|
|
25
41
|
|
|
26
42
|
const id = $props.id();
|
|
27
|
-
let dialogEl: HTMLDialogElement;
|
|
28
43
|
|
|
29
44
|
const triggerProps: AlertDialogTriggerProps = {
|
|
30
45
|
onclick: () => (open = true),
|
|
@@ -36,13 +51,14 @@
|
|
|
36
51
|
}
|
|
37
52
|
|
|
38
53
|
$effect(() => {
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
|
|
54
|
+
if (!ref) return;
|
|
55
|
+
if (open && !ref.open) {
|
|
56
|
+
ref.showModal();
|
|
57
|
+
Array.from(ref.querySelectorAll<HTMLElement>('.alert-dialog-actions :is(button, a)'))
|
|
42
58
|
.at(-1)
|
|
43
59
|
?.focus();
|
|
44
|
-
} else if (!open &&
|
|
45
|
-
|
|
60
|
+
} else if (!open && ref.open) {
|
|
61
|
+
ref.close();
|
|
46
62
|
}
|
|
47
63
|
});
|
|
48
64
|
</script>
|
|
@@ -50,11 +66,12 @@
|
|
|
50
66
|
{@render trigger?.(triggerProps)}
|
|
51
67
|
|
|
52
68
|
<dialog
|
|
53
|
-
|
|
69
|
+
{...rest}
|
|
70
|
+
bind:this={ref}
|
|
54
71
|
role="alertdialog"
|
|
55
72
|
aria-labelledby="{id}-title"
|
|
56
73
|
aria-describedby={description ? `${id}-description` : undefined}
|
|
57
|
-
class=
|
|
74
|
+
class={['alert-dialog', className]}
|
|
58
75
|
onkeydown={(event) => {
|
|
59
76
|
if (event.key !== 'Escape') return;
|
|
60
77
|
event.preventDefault();
|
|
@@ -79,83 +96,98 @@
|
|
|
79
96
|
</dialog>
|
|
80
97
|
|
|
81
98
|
<style>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
99
|
+
@layer svelte-ui {
|
|
100
|
+
/* Locks page scrolling while open; the gutter keeps the layout from shifting */
|
|
101
|
+
:global(html:has(.alert-dialog[open])) {
|
|
102
|
+
overflow: hidden;
|
|
103
|
+
scrollbar-gutter: stable;
|
|
104
|
+
}
|
|
87
105
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
106
|
+
.alert-dialog {
|
|
107
|
+
box-sizing: border-box;
|
|
108
|
+
width: calc(100% - 32px);
|
|
109
|
+
max-width: 420px;
|
|
110
|
+
padding: 20px;
|
|
111
|
+
background-color: var(--color-bg);
|
|
112
|
+
color: var(--color-text);
|
|
113
|
+
border: 1px solid var(--color-border);
|
|
114
|
+
border-radius: 14px;
|
|
115
|
+
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.16);
|
|
116
|
+
outline: none;
|
|
117
|
+
opacity: 0;
|
|
118
|
+
scale: 0.95;
|
|
119
|
+
transition:
|
|
120
|
+
opacity 140ms ease,
|
|
121
|
+
scale 140ms ease,
|
|
122
|
+
display 140ms allow-discrete,
|
|
123
|
+
overlay 140ms allow-discrete;
|
|
124
|
+
}
|
|
107
125
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
126
|
+
.alert-dialog[open] {
|
|
127
|
+
opacity: 1;
|
|
128
|
+
scale: 1;
|
|
129
|
+
}
|
|
112
130
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
131
|
+
.alert-dialog::backdrop {
|
|
132
|
+
background-color: rgba(0, 0, 0, 0);
|
|
133
|
+
transition:
|
|
134
|
+
background-color 140ms ease,
|
|
135
|
+
display 140ms allow-discrete,
|
|
136
|
+
overlay 140ms allow-discrete;
|
|
137
|
+
}
|
|
120
138
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
139
|
+
.alert-dialog[open]::backdrop {
|
|
140
|
+
background-color: rgba(0, 0, 0, 0.4);
|
|
141
|
+
}
|
|
124
142
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
143
|
+
@starting-style {
|
|
144
|
+
.alert-dialog[open] {
|
|
145
|
+
opacity: 0;
|
|
146
|
+
scale: 0.95;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.alert-dialog[open]::backdrop {
|
|
150
|
+
background-color: rgba(0, 0, 0, 0);
|
|
151
|
+
}
|
|
129
152
|
}
|
|
130
153
|
|
|
131
|
-
.alert-dialog
|
|
132
|
-
|
|
154
|
+
.alert-dialog-title {
|
|
155
|
+
margin: 0;
|
|
156
|
+
font-size: 15px;
|
|
157
|
+
font-weight: 600;
|
|
133
158
|
}
|
|
134
|
-
}
|
|
135
159
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
160
|
+
.alert-dialog-description {
|
|
161
|
+
margin: 6px 0 0;
|
|
162
|
+
font-size: 13px;
|
|
163
|
+
line-height: 1.5;
|
|
164
|
+
color: var(--color-text-muted);
|
|
165
|
+
}
|
|
141
166
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
color: var(--color-text-muted);
|
|
147
|
-
}
|
|
167
|
+
.alert-dialog-body {
|
|
168
|
+
margin-top: 16px;
|
|
169
|
+
font-size: 13px;
|
|
170
|
+
}
|
|
148
171
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
172
|
+
@media (prefers-reduced-motion: reduce) {
|
|
173
|
+
.alert-dialog,
|
|
174
|
+
.alert-dialog::backdrop {
|
|
175
|
+
transition: none;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
153
178
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
179
|
+
@media (forced-colors: active) {
|
|
180
|
+
.alert-dialog {
|
|
181
|
+
border-color: CanvasText;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.alert-dialog-actions {
|
|
186
|
+
display: flex;
|
|
187
|
+
flex-wrap: wrap;
|
|
188
|
+
justify-content: center;
|
|
189
|
+
gap: 4px;
|
|
190
|
+
margin-top: 20px;
|
|
191
|
+
}
|
|
160
192
|
}
|
|
161
193
|
</style>
|
|
@@ -3,9 +3,12 @@ export type AlertDialogTriggerProps = {
|
|
|
3
3
|
'aria-haspopup': 'dialog';
|
|
4
4
|
};
|
|
5
5
|
import type { Snippet } from 'svelte';
|
|
6
|
-
type
|
|
6
|
+
import type { HTMLDialogAttributes } from 'svelte/elements';
|
|
7
|
+
type Props = Omit<HTMLDialogAttributes, 'open' | 'title' | 'children' | 'role' | 'aria-labelledby' | 'aria-describedby'> & {
|
|
7
8
|
/** Whether the dialog is open. Bindable. Escape closes it. */
|
|
8
9
|
open?: boolean;
|
|
10
|
+
/** The dialog element. Bindable. */
|
|
11
|
+
ref?: HTMLDialogElement | null;
|
|
9
12
|
title: string;
|
|
10
13
|
description?: string;
|
|
11
14
|
/** Renders the trigger. Spread the given props onto it, e.g. `<Button {...props} />`. Omit to control `open` yourself. */
|
|
@@ -15,6 +18,6 @@ type Props = {
|
|
|
15
18
|
/** Extra content between the description and the buttons. */
|
|
16
19
|
children?: Snippet;
|
|
17
20
|
};
|
|
18
|
-
declare const AlertDialog: import("svelte").Component<Props, {}, "open">;
|
|
21
|
+
declare const AlertDialog: import("svelte").Component<Props, {}, "ref" | "open">;
|
|
19
22
|
type AlertDialog = ReturnType<typeof AlertDialog>;
|
|
20
23
|
export default AlertDialog;
|