@loidolt/theme-svelte 0.2.0

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.
Files changed (85) hide show
  1. package/LICENSE +21 -0
  2. package/dist/components/Alert.svelte +36 -0
  3. package/dist/components/Alert.svelte.d.ts +15 -0
  4. package/dist/components/AppShell.svelte +31 -0
  5. package/dist/components/AppShell.svelte.d.ts +14 -0
  6. package/dist/components/Badge.svelte +27 -0
  7. package/dist/components/Badge.svelte.d.ts +12 -0
  8. package/dist/components/Brand.svelte +35 -0
  9. package/dist/components/Brand.svelte.d.ts +15 -0
  10. package/dist/components/Button.svelte +85 -0
  11. package/dist/components/Button.svelte.d.ts +21 -0
  12. package/dist/components/Card.svelte +43 -0
  13. package/dist/components/Card.svelte.d.ts +18 -0
  14. package/dist/components/Checkbox.svelte +54 -0
  15. package/dist/components/Checkbox.svelte.d.ts +21 -0
  16. package/dist/components/ContextBar.svelte +33 -0
  17. package/dist/components/ContextBar.svelte.d.ts +13 -0
  18. package/dist/components/Dialog.svelte +84 -0
  19. package/dist/components/Dialog.svelte.d.ts +28 -0
  20. package/dist/components/DropdownMenu.svelte +99 -0
  21. package/dist/components/DropdownMenu.svelte.d.ts +47 -0
  22. package/dist/components/Field.svelte +52 -0
  23. package/dist/components/Field.svelte.d.ts +24 -0
  24. package/dist/components/IconButton.svelte +43 -0
  25. package/dist/components/IconButton.svelte.d.ts +16 -0
  26. package/dist/components/Input.svelte +27 -0
  27. package/dist/components/Input.svelte.d.ts +11 -0
  28. package/dist/components/Label.svelte +24 -0
  29. package/dist/components/Label.svelte.d.ts +11 -0
  30. package/dist/components/NavMenu.svelte +62 -0
  31. package/dist/components/NavMenu.svelte.d.ts +43 -0
  32. package/dist/components/NumberField.svelte +78 -0
  33. package/dist/components/NumberField.svelte.d.ts +21 -0
  34. package/dist/components/PageHeader.svelte +37 -0
  35. package/dist/components/PageHeader.svelte.d.ts +15 -0
  36. package/dist/components/Panel.svelte +38 -0
  37. package/dist/components/Panel.svelte.d.ts +15 -0
  38. package/dist/components/Popover.svelte +58 -0
  39. package/dist/components/Popover.svelte.d.ts +21 -0
  40. package/dist/components/Progress.svelte +43 -0
  41. package/dist/components/Progress.svelte.d.ts +12 -0
  42. package/dist/components/RadioGroup.svelte +49 -0
  43. package/dist/components/RadioGroup.svelte.d.ts +37 -0
  44. package/dist/components/Section.svelte +39 -0
  45. package/dist/components/Section.svelte.d.ts +15 -0
  46. package/dist/components/Select.svelte +57 -0
  47. package/dist/components/Select.svelte.d.ts +41 -0
  48. package/dist/components/Separator.svelte +29 -0
  49. package/dist/components/Separator.svelte.d.ts +10 -0
  50. package/dist/components/Sidebar.svelte +35 -0
  51. package/dist/components/Sidebar.svelte.d.ts +16 -0
  52. package/dist/components/Skeleton.svelte +26 -0
  53. package/dist/components/Skeleton.svelte.d.ts +11 -0
  54. package/dist/components/Spinner.svelte +22 -0
  55. package/dist/components/Spinner.svelte.d.ts +10 -0
  56. package/dist/components/Switch.svelte +62 -0
  57. package/dist/components/Switch.svelte.d.ts +17 -0
  58. package/dist/components/Table.svelte +43 -0
  59. package/dist/components/Table.svelte.d.ts +17 -0
  60. package/dist/components/Tabs.svelte +63 -0
  61. package/dist/components/Tabs.svelte.d.ts +41 -0
  62. package/dist/components/Textarea.svelte +27 -0
  63. package/dist/components/Textarea.svelte.d.ts +11 -0
  64. package/dist/components/Toast.svelte +53 -0
  65. package/dist/components/Toast.svelte.d.ts +16 -0
  66. package/dist/components/ToastViewport.svelte +38 -0
  67. package/dist/components/ToastViewport.svelte.d.ts +13 -0
  68. package/dist/components/Tooltip.svelte +76 -0
  69. package/dist/components/Tooltip.svelte.d.ts +28 -0
  70. package/dist/components/TooltipProvider.svelte +33 -0
  71. package/dist/components/TooltipProvider.svelte.d.ts +14 -0
  72. package/dist/components/Topbar.svelte +32 -0
  73. package/dist/components/Topbar.svelte.d.ts +14 -0
  74. package/dist/components/Workspace.svelte +38 -0
  75. package/dist/components/Workspace.svelte.d.ts +12 -0
  76. package/dist/index.d.ts +46 -0
  77. package/dist/index.js +44 -0
  78. package/dist/styles.css +1 -0
  79. package/dist/toaster.svelte.d.ts +43 -0
  80. package/dist/toaster.svelte.js +82 -0
  81. package/dist/types.d.ts +39 -0
  82. package/dist/types.js +1 -0
  83. package/dist/utils.d.ts +5 -0
  84. package/dist/utils.js +7 -0
  85. package/package.json +66 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Chris Loidolt
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.
@@ -0,0 +1,36 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import type { HeadingLevel, StatusVariant } from '../types.js';
5
+ import { cx } from '../utils.js';
6
+
7
+ interface Props extends HTMLAttributes<HTMLDivElement> {
8
+ variant?: StatusVariant;
9
+ title: string;
10
+ /** Heading element used for the title, so the alert fits the page outline. */
11
+ headingLevel?: HeadingLevel;
12
+ class?: string;
13
+ children?: Snippet;
14
+ ref?: HTMLDivElement | null;
15
+ }
16
+
17
+ let {
18
+ variant = 'info',
19
+ title,
20
+ headingLevel = 3,
21
+ class: className,
22
+ children,
23
+ ref = $bindable(null),
24
+ ...rest
25
+ }: Props = $props();
26
+ </script>
27
+
28
+ <div
29
+ bind:this={ref}
30
+ class={cx('ldt-alert', `ldt-alert--${variant}`, className)}
31
+ role={variant === 'error' ? 'alert' : 'status'}
32
+ {...rest}
33
+ >
34
+ <svelte:element this={`h${headingLevel}`} class="ldt-alert__title">{title}</svelte:element>
35
+ {#if children}<div class="ldt-alert__description">{@render children()}</div>{/if}
36
+ </div>
@@ -0,0 +1,15 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { HeadingLevel, StatusVariant } from '../types.js';
4
+ interface Props extends HTMLAttributes<HTMLDivElement> {
5
+ variant?: StatusVariant;
6
+ title: string;
7
+ /** Heading element used for the title, so the alert fits the page outline. */
8
+ headingLevel?: HeadingLevel;
9
+ class?: string;
10
+ children?: Snippet;
11
+ ref?: HTMLDivElement | null;
12
+ }
13
+ declare const Alert: import("svelte").Component<Props, {}, "ref">;
14
+ type Alert = ReturnType<typeof Alert>;
15
+ export default Alert;
@@ -0,0 +1,31 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import { cx } from '../utils.js';
5
+
6
+ interface Props extends HTMLAttributes<HTMLDivElement> {
7
+ header?: Snippet;
8
+ children: Snippet;
9
+ footer?: Snippet;
10
+ /** `id` of the `<main>` element, for skip links. */
11
+ mainId?: string;
12
+ class?: string;
13
+ ref?: HTMLDivElement | null;
14
+ }
15
+
16
+ let {
17
+ header,
18
+ children,
19
+ footer,
20
+ mainId = 'main',
21
+ class: className,
22
+ ref = $bindable(null),
23
+ ...rest
24
+ }: Props = $props();
25
+ </script>
26
+
27
+ <div bind:this={ref} class={cx('ldt-app-shell', className)} {...rest}>
28
+ {#if header}<header>{@render header()}</header>{/if}
29
+ <main id={mainId}>{@render children()}</main>
30
+ {#if footer}<footer>{@render footer()}</footer>{/if}
31
+ </div>
@@ -0,0 +1,14 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ interface Props extends HTMLAttributes<HTMLDivElement> {
4
+ header?: Snippet;
5
+ children: Snippet;
6
+ footer?: Snippet;
7
+ /** `id` of the `<main>` element, for skip links. */
8
+ mainId?: string;
9
+ class?: string;
10
+ ref?: HTMLDivElement | null;
11
+ }
12
+ declare const AppShell: import("svelte").Component<Props, {}, "ref">;
13
+ type AppShell = ReturnType<typeof AppShell>;
14
+ export default AppShell;
@@ -0,0 +1,27 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import type { BadgeVariant } from '../types.js';
5
+ import { cx } from '../utils.js';
6
+
7
+ interface Props extends HTMLAttributes<HTMLSpanElement> {
8
+ variant?: BadgeVariant;
9
+ class?: string;
10
+ children: Snippet;
11
+ ref?: HTMLSpanElement | null;
12
+ }
13
+
14
+ let {
15
+ variant = 'default',
16
+ class: className,
17
+ children,
18
+ ref = $bindable(null),
19
+ ...rest
20
+ }: Props = $props();
21
+ </script>
22
+
23
+ <span
24
+ bind:this={ref}
25
+ class={cx('ldt-badge', variant !== 'default' && `ldt-badge--${variant}`, className)}
26
+ {...rest}>{@render children()}</span
27
+ >
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { BadgeVariant } from '../types.js';
4
+ interface Props extends HTMLAttributes<HTMLSpanElement> {
5
+ variant?: BadgeVariant;
6
+ class?: string;
7
+ children: Snippet;
8
+ ref?: HTMLSpanElement | null;
9
+ }
10
+ declare const Badge: import("svelte").Component<Props, {}, "ref">;
11
+ type Badge = ReturnType<typeof Badge>;
12
+ export default Badge;
@@ -0,0 +1,35 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAnchorAttributes, HTMLAttributes } from 'svelte/elements';
4
+ import { cx } from '../utils.js';
5
+
6
+ type Props = HTMLAnchorAttributes &
7
+ HTMLAttributes<HTMLSpanElement> & {
8
+ name: string;
9
+ /** Secondary line, e.g. an environment or version marker. */
10
+ meta?: string;
11
+ /** Renders an `<a>` instead of a `<span>`. */
12
+ href?: string;
13
+ mark?: Snippet;
14
+ class?: string;
15
+ ref?: HTMLElement | null;
16
+ };
17
+
18
+ let {
19
+ name,
20
+ meta,
21
+ href,
22
+ mark,
23
+ class: className,
24
+ ref = $bindable(null),
25
+ ...rest
26
+ }: Props = $props();
27
+ </script>
28
+
29
+ {#snippet content()}{#if mark}{@render mark()}{/if}<strong class="ldt-brand__name">{name}</strong
30
+ >{#if meta}<span class="ldt-brand__meta">{meta}</span>{/if}{/snippet}
31
+ {#if href}<a bind:this={ref} {href} class={cx('ldt-brand', className)} {...rest}
32
+ >{@render content()}</a
33
+ >{:else}<span bind:this={ref} class={cx('ldt-brand', className)} {...rest}
34
+ >{@render content()}</span
35
+ >{/if}
@@ -0,0 +1,15 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAnchorAttributes, HTMLAttributes } from 'svelte/elements';
3
+ type Props = HTMLAnchorAttributes & HTMLAttributes<HTMLSpanElement> & {
4
+ name: string;
5
+ /** Secondary line, e.g. an environment or version marker. */
6
+ meta?: string;
7
+ /** Renders an `<a>` instead of a `<span>`. */
8
+ href?: string;
9
+ mark?: Snippet;
10
+ class?: string;
11
+ ref?: HTMLElement | null;
12
+ };
13
+ declare const Brand: import("svelte").Component<Props, {}, "ref">;
14
+ type Brand = ReturnType<typeof Brand>;
15
+ export default Brand;
@@ -0,0 +1,85 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
4
+ import type { ActionVariant, ControlSize } from '../types.js';
5
+ import { cx } from '../utils.js';
6
+
7
+ type Props = HTMLButtonAttributes &
8
+ HTMLAnchorAttributes & {
9
+ variant?: ActionVariant;
10
+ size?: ControlSize;
11
+ /** Renders an `<a>` styled as a button. */
12
+ href?: string;
13
+ disabled?: boolean;
14
+ loading?: boolean;
15
+ /** Visible text swapped in while loading. */
16
+ loadingText?: string;
17
+ /** Announced while loading when there is no visible `loadingText`. */
18
+ loadingLabel?: string;
19
+ class?: string;
20
+ children: Snippet;
21
+ ref?: HTMLButtonElement | HTMLAnchorElement | null;
22
+ };
23
+
24
+ let {
25
+ variant = 'default',
26
+ size = 'md',
27
+ type = 'button',
28
+ href,
29
+ disabled = false,
30
+ loading = false,
31
+ loadingText,
32
+ loadingLabel = 'Loading',
33
+ class: className,
34
+ children,
35
+ onclick,
36
+ ref = $bindable(null),
37
+ ...rest
38
+ }: Props = $props();
39
+
40
+ const classes = $derived(
41
+ cx('ldt-button', `ldt-button--${variant}`, size !== 'md' && `ldt-button--${size}`, className)
42
+ );
43
+ const inert = $derived(disabled || loading);
44
+
45
+ function handleClick(event: MouseEvent) {
46
+ if (inert) {
47
+ event.preventDefault();
48
+ return;
49
+ }
50
+ onclick?.(event as MouseEvent & { currentTarget: EventTarget & HTMLButtonElement });
51
+ }
52
+ </script>
53
+
54
+ {#snippet content()}
55
+ {#if loading}<span class="ldt-spinner" aria-hidden="true"></span>{/if}
56
+ {#if loading && loadingText}{loadingText}{:else}{@render children()}{/if}
57
+ <!--
58
+ Persistently mounted: a live region only announces content that changes *after* it is in the
59
+ DOM, so mounting it alongside the message would be silent in most screen readers.
60
+ -->
61
+ <span class="ldt-sr-only" role="status">{loading && !loadingText ? loadingLabel : ''}</span>
62
+ {/snippet}
63
+
64
+ {#if href}
65
+ <a
66
+ bind:this={ref}
67
+ href={inert ? undefined : href}
68
+ class={classes}
69
+ aria-disabled={inert || undefined}
70
+ aria-busy={loading || undefined}
71
+ tabindex={inert ? -1 : undefined}
72
+ {...rest}
73
+ onclick={handleClick}>{@render content()}</a
74
+ >
75
+ {:else}
76
+ <button
77
+ bind:this={ref}
78
+ {type}
79
+ class={classes}
80
+ disabled={inert}
81
+ aria-busy={loading || undefined}
82
+ {...rest}
83
+ onclick={handleClick}>{@render content()}</button
84
+ >
85
+ {/if}
@@ -0,0 +1,21 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
3
+ import type { ActionVariant, ControlSize } from '../types.js';
4
+ type Props = HTMLButtonAttributes & HTMLAnchorAttributes & {
5
+ variant?: ActionVariant;
6
+ size?: ControlSize;
7
+ /** Renders an `<a>` styled as a button. */
8
+ href?: string;
9
+ disabled?: boolean;
10
+ loading?: boolean;
11
+ /** Visible text swapped in while loading. */
12
+ loadingText?: string;
13
+ /** Announced while loading when there is no visible `loadingText`. */
14
+ loadingLabel?: string;
15
+ class?: string;
16
+ children: Snippet;
17
+ ref?: HTMLButtonElement | HTMLAnchorElement | null;
18
+ };
19
+ declare const Button: import("svelte").Component<Props, {}, "ref">;
20
+ type Button = ReturnType<typeof Button>;
21
+ export default Button;
@@ -0,0 +1,43 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import type { HeadingLevel } from '../types.js';
5
+ import { cx } from '../utils.js';
6
+
7
+ interface Props extends HTMLAttributes<HTMLElement> {
8
+ title?: string;
9
+ description?: string;
10
+ header?: Snippet;
11
+ children: Snippet;
12
+ footer?: Snippet;
13
+ /** Root element. `div` by default — use `article` only for self-contained content. */
14
+ as?: 'div' | 'article' | 'section' | 'li';
15
+ headingLevel?: HeadingLevel;
16
+ class?: string;
17
+ ref?: HTMLElement | null;
18
+ }
19
+
20
+ let {
21
+ title,
22
+ description,
23
+ header,
24
+ children,
25
+ footer,
26
+ as = 'div',
27
+ headingLevel = 3,
28
+ class: className,
29
+ ref = $bindable(null),
30
+ ...rest
31
+ }: Props = $props();
32
+ </script>
33
+
34
+ <svelte:element this={as} bind:this={ref} class={cx('ldt-card', className)} {...rest}>
35
+ {#if header || title || description}<header class="ldt-card__header">
36
+ {#if header}{@render header()}{:else}{#if title}<svelte:element
37
+ this={`h${headingLevel}`}
38
+ class="ldt-card__title">{title}</svelte:element
39
+ >{/if}{#if description}<p class="ldt-card__description">{description}</p>{/if}{/if}
40
+ </header>{/if}
41
+ <div class="ldt-card__content">{@render children()}</div>
42
+ {#if footer}<footer class="ldt-card__footer">{@render footer()}</footer>{/if}
43
+ </svelte:element>
@@ -0,0 +1,18 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { HeadingLevel } from '../types.js';
4
+ interface Props extends HTMLAttributes<HTMLElement> {
5
+ title?: string;
6
+ description?: string;
7
+ header?: Snippet;
8
+ children: Snippet;
9
+ footer?: Snippet;
10
+ /** Root element. `div` by default — use `article` only for self-contained content. */
11
+ as?: 'div' | 'article' | 'section' | 'li';
12
+ headingLevel?: HeadingLevel;
13
+ class?: string;
14
+ ref?: HTMLElement | null;
15
+ }
16
+ declare const Card: import("svelte").Component<Props, {}, "ref">;
17
+ type Card = ReturnType<typeof Card>;
18
+ export default Card;
@@ -0,0 +1,54 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLInputAttributes } from 'svelte/elements';
4
+ import { cx } from '../utils.js';
5
+
6
+ interface Props extends Omit<HTMLInputAttributes, 'type' | 'checked'> {
7
+ checked?: boolean;
8
+ indeterminate?: boolean;
9
+ disabled?: boolean;
10
+ /**
11
+ * Visible text when there are no `children`. One of `children`, `label` or an
12
+ * `aria-labelledby` in the rest props is required, or the control is unnamed.
13
+ */
14
+ label?: string;
15
+ onCheckedChange?: (checked: boolean) => void;
16
+ /** `class` lands on the wrapping `<label>`; use `inputClass` to reach the input. */
17
+ class?: string;
18
+ inputClass?: string;
19
+ children?: Snippet;
20
+ ref?: HTMLInputElement | null;
21
+ }
22
+
23
+ let {
24
+ checked = $bindable(false),
25
+ indeterminate = $bindable(false),
26
+ disabled = false,
27
+ label,
28
+ onCheckedChange,
29
+ onchange,
30
+ class: className,
31
+ inputClass,
32
+ children,
33
+ ref = $bindable(null),
34
+ ...rest
35
+ }: Props = $props();
36
+
37
+ function handleChange(event: Event & { currentTarget: EventTarget & HTMLInputElement }): void {
38
+ onCheckedChange?.(event.currentTarget.checked);
39
+ onchange?.(event);
40
+ }
41
+ </script>
42
+
43
+ <label class={cx('ldt-choice', className)}
44
+ ><input
45
+ bind:this={ref}
46
+ type="checkbox"
47
+ class={inputClass}
48
+ bind:checked
49
+ bind:indeterminate
50
+ {disabled}
51
+ {...rest}
52
+ onchange={handleChange}
53
+ />{#if children}{@render children()}{:else if label}{label}{/if}</label
54
+ >
@@ -0,0 +1,21 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLInputAttributes } from 'svelte/elements';
3
+ interface Props extends Omit<HTMLInputAttributes, 'type' | 'checked'> {
4
+ checked?: boolean;
5
+ indeterminate?: boolean;
6
+ disabled?: boolean;
7
+ /**
8
+ * Visible text when there are no `children`. One of `children`, `label` or an
9
+ * `aria-labelledby` in the rest props is required, or the control is unnamed.
10
+ */
11
+ label?: string;
12
+ onCheckedChange?: (checked: boolean) => void;
13
+ /** `class` lands on the wrapping `<label>`; use `inputClass` to reach the input. */
14
+ class?: string;
15
+ inputClass?: string;
16
+ children?: Snippet;
17
+ ref?: HTMLInputElement | null;
18
+ }
19
+ declare const Checkbox: import("svelte").Component<Props, {}, "ref" | "checked" | "indeterminate">;
20
+ type Checkbox = ReturnType<typeof Checkbox>;
21
+ export default Checkbox;
@@ -0,0 +1,33 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import { cx } from '../utils.js';
5
+
6
+ interface Props extends HTMLAttributes<HTMLDivElement> {
7
+ section: string;
8
+ title: string;
9
+ detail?: string;
10
+ actions?: Snippet;
11
+ class?: string;
12
+ ref?: HTMLDivElement | null;
13
+ }
14
+
15
+ let {
16
+ section,
17
+ title,
18
+ detail,
19
+ actions,
20
+ class: className,
21
+ ref = $bindable(null),
22
+ ...rest
23
+ }: Props = $props();
24
+ </script>
25
+
26
+ <div bind:this={ref} class={cx('ldt-contextbar', className)} {...rest}>
27
+ <div class="ldt-contextbar__location">
28
+ <span class="ldt-contextbar__section">{section}</span><strong class="ldt-contextbar__title"
29
+ >{title}</strong
30
+ >{#if detail}<small class="ldt-contextbar__detail">{detail}</small>{/if}
31
+ </div>
32
+ {#if actions}<div class="ldt-contextbar__actions">{@render actions()}</div>{/if}
33
+ </div>
@@ -0,0 +1,13 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ interface Props extends HTMLAttributes<HTMLDivElement> {
4
+ section: string;
5
+ title: string;
6
+ detail?: string;
7
+ actions?: Snippet;
8
+ class?: string;
9
+ ref?: HTMLDivElement | null;
10
+ }
11
+ declare const ContextBar: import("svelte").Component<Props, {}, "ref">;
12
+ type ContextBar = ReturnType<typeof ContextBar>;
13
+ export default ContextBar;
@@ -0,0 +1,84 @@
1
+ <script lang="ts">
2
+ import { Dialog as DialogPrimitive } from 'bits-ui';
3
+ import type { Snippet } from 'svelte';
4
+ import type { DialogContentProps } from 'bits-ui';
5
+ import type { DialogSize, HeadingLevel, TriggerChildProps } from '../types.js';
6
+ import { cx } from '../utils.js';
7
+
8
+ type Props = Omit<DialogContentProps, 'children' | 'class' | 'child'> & {
9
+ open?: boolean;
10
+ title: string;
11
+ description?: string;
12
+ /** Trigger contents, rendered inside a button styled with `triggerClass`. */
13
+ trigger?: Snippet;
14
+ /** Full control of the trigger element — receives the props Bits needs on it. */
15
+ triggerChild?: Snippet<[TriggerChildProps]>;
16
+ triggerClass?: string;
17
+ children: Snippet;
18
+ footer?: Snippet;
19
+ /** Sets `--ldt-dialog-width` via a modifier class. Omit to inherit the CSS default. */
20
+ size?: DialogSize;
21
+ headingLevel?: HeadingLevel;
22
+ showClose?: boolean;
23
+ closeLabel?: string;
24
+ /** `class` lands on the portaled Content element. */
25
+ class?: string;
26
+ overlayClass?: string;
27
+ onOpenChange?: (open: boolean) => void;
28
+ ref?: HTMLElement | null;
29
+ };
30
+
31
+ let {
32
+ open = $bindable(false),
33
+ title,
34
+ description,
35
+ trigger,
36
+ triggerChild,
37
+ triggerClass = 'ldt-button',
38
+ children,
39
+ footer,
40
+ size,
41
+ headingLevel = 2,
42
+ showClose = true,
43
+ closeLabel = 'Close dialog',
44
+ class: className,
45
+ overlayClass,
46
+ onOpenChange,
47
+ ref = $bindable(null),
48
+ ...rest
49
+ }: Props = $props();
50
+ </script>
51
+
52
+ <DialogPrimitive.Root bind:open {onOpenChange}>
53
+ {#if triggerChild}<DialogPrimitive.Trigger
54
+ >{#snippet child(childProps)}{@render triggerChild(
55
+ childProps
56
+ )}{/snippet}</DialogPrimitive.Trigger
57
+ >{:else if trigger}<DialogPrimitive.Trigger class={triggerClass}
58
+ >{@render trigger()}</DialogPrimitive.Trigger
59
+ >{/if}
60
+ <DialogPrimitive.Portal>
61
+ <DialogPrimitive.Overlay class={cx('ldt-overlay', overlayClass)} />
62
+ <DialogPrimitive.Content
63
+ bind:ref
64
+ class={cx('ldt-dialog', size && `ldt-dialog--${size}`, className)}
65
+ {...rest}
66
+ >
67
+ <header class="ldt-dialog__header">
68
+ <div>
69
+ <DialogPrimitive.Title level={headingLevel} class="ldt-dialog__title"
70
+ >{title}</DialogPrimitive.Title
71
+ >{#if description}<DialogPrimitive.Description class="ldt-dialog__description"
72
+ >{description}</DialogPrimitive.Description
73
+ >{/if}
74
+ </div>
75
+ {#if showClose}<DialogPrimitive.Close
76
+ class="ldt-button ldt-icon-button ldt-button--ghost"
77
+ aria-label={closeLabel}>×</DialogPrimitive.Close
78
+ >{/if}
79
+ </header>
80
+ <div class="ldt-dialog__body">{@render children()}</div>
81
+ {#if footer}<footer class="ldt-dialog__footer">{@render footer()}</footer>{/if}
82
+ </DialogPrimitive.Content>
83
+ </DialogPrimitive.Portal>
84
+ </DialogPrimitive.Root>
@@ -0,0 +1,28 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { DialogContentProps } from 'bits-ui';
3
+ import type { DialogSize, HeadingLevel, TriggerChildProps } from '../types.js';
4
+ type Props = Omit<DialogContentProps, 'children' | 'class' | 'child'> & {
5
+ open?: boolean;
6
+ title: string;
7
+ description?: string;
8
+ /** Trigger contents, rendered inside a button styled with `triggerClass`. */
9
+ trigger?: Snippet;
10
+ /** Full control of the trigger element — receives the props Bits needs on it. */
11
+ triggerChild?: Snippet<[TriggerChildProps]>;
12
+ triggerClass?: string;
13
+ children: Snippet;
14
+ footer?: Snippet;
15
+ /** Sets `--ldt-dialog-width` via a modifier class. Omit to inherit the CSS default. */
16
+ size?: DialogSize;
17
+ headingLevel?: HeadingLevel;
18
+ showClose?: boolean;
19
+ closeLabel?: string;
20
+ /** `class` lands on the portaled Content element. */
21
+ class?: string;
22
+ overlayClass?: string;
23
+ onOpenChange?: (open: boolean) => void;
24
+ ref?: HTMLElement | null;
25
+ };
26
+ declare const Dialog: import("svelte").Component<Props, {}, "ref" | "open">;
27
+ type Dialog = ReturnType<typeof Dialog>;
28
+ export default Dialog;