@skeletonlabs/skeleton-svelte 1.0.0-next.8 → 1.0.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 (117) hide show
  1. package/README.md +1 -1
  2. package/dist/components/Accordion/Accordion.svelte +49 -52
  3. package/dist/components/Accordion/Accordion.svelte.d.ts +2 -14
  4. package/dist/components/Accordion/AccordionItem.svelte +43 -37
  5. package/dist/components/Accordion/AccordionItem.svelte.d.ts +2 -14
  6. package/dist/components/Accordion/context.js +2 -1
  7. package/dist/components/Accordion/index.d.ts +4 -0
  8. package/dist/components/Accordion/index.js +1 -1
  9. package/dist/components/Accordion/types.d.ts +7 -9
  10. package/dist/components/AppBar/AppBar.svelte +43 -40
  11. package/dist/components/AppBar/AppBar.svelte.d.ts +2 -14
  12. package/dist/components/Avatar/Avatar.svelte +56 -44
  13. package/dist/components/Avatar/Avatar.svelte.d.ts +2 -14
  14. package/dist/components/Avatar/types.d.ts +3 -3
  15. package/dist/components/Combobox/Combobox.svelte +144 -0
  16. package/dist/components/Combobox/Combobox.svelte.d.ts +18 -0
  17. package/dist/components/Combobox/types.d.ts +64 -0
  18. package/dist/components/Combobox/types.js +1 -0
  19. package/dist/components/FileUpload/FileUpload.svelte +70 -63
  20. package/dist/components/FileUpload/FileUpload.svelte.d.ts +2 -14
  21. package/dist/components/FileUpload/types.d.ts +3 -4
  22. package/dist/components/Modal/Modal.svelte +87 -0
  23. package/dist/components/Modal/Modal.svelte.d.ts +4 -0
  24. package/dist/components/Modal/types.d.ts +57 -0
  25. package/dist/components/Modal/types.js +1 -0
  26. package/dist/components/Navigation/NavBar.svelte +48 -0
  27. package/dist/components/Navigation/NavBar.svelte.d.ts +5 -0
  28. package/dist/components/Navigation/NavRail.svelte +90 -0
  29. package/dist/components/Navigation/NavRail.svelte.d.ts +5 -0
  30. package/dist/components/Navigation/NavTile.svelte +87 -0
  31. package/dist/components/Navigation/NavTile.svelte.d.ts +5 -0
  32. package/dist/components/Navigation/context.js +7 -0
  33. package/dist/components/Navigation/index.d.ts +6 -0
  34. package/dist/components/{Nav → Navigation}/index.js +1 -1
  35. package/dist/components/{Nav → Navigation}/types.d.ts +5 -3
  36. package/dist/components/Pagination/Pagination.svelte +58 -67
  37. package/dist/components/Pagination/Pagination.svelte.d.ts +2 -14
  38. package/dist/components/Pagination/types.d.ts +15 -15
  39. package/dist/components/Popover/Popover.svelte +78 -0
  40. package/dist/components/Popover/Popover.svelte.d.ts +4 -0
  41. package/dist/components/Popover/types.d.ts +42 -0
  42. package/dist/components/Popover/types.js +1 -0
  43. package/dist/components/Progress/Progress.svelte +44 -38
  44. package/dist/components/Progress/Progress.svelte.d.ts +2 -14
  45. package/dist/components/Progress/types.d.ts +1 -1
  46. package/dist/components/ProgressRing/ProgressRing.svelte +58 -46
  47. package/dist/components/ProgressRing/ProgressRing.svelte.d.ts +2 -14
  48. package/dist/components/ProgressRing/types.d.ts +3 -1
  49. package/dist/components/Rating/Rating.svelte +101 -57
  50. package/dist/components/Rating/Rating.svelte.d.ts +2 -14
  51. package/dist/components/Rating/types.d.ts +1 -5
  52. package/dist/components/Segment/Segment.svelte +59 -67
  53. package/dist/components/Segment/Segment.svelte.d.ts +3 -15
  54. package/dist/components/Segment/SegmentItem.svelte +28 -21
  55. package/dist/components/Segment/SegmentItem.svelte.d.ts +2 -14
  56. package/dist/components/Segment/context.js +3 -2
  57. package/dist/components/Segment/index.d.ts +4 -0
  58. package/dist/components/Segment/index.js +1 -1
  59. package/dist/components/Segment/types.d.ts +8 -10
  60. package/dist/components/Slider/Slider.svelte +67 -72
  61. package/dist/components/Slider/Slider.svelte.d.ts +2 -14
  62. package/dist/components/Slider/types.d.ts +5 -9
  63. package/dist/components/Switch/Switch.svelte +75 -90
  64. package/dist/components/Switch/Switch.svelte.d.ts +2 -14
  65. package/dist/components/Switch/types.d.ts +2 -8
  66. package/dist/components/Tabs/Tabs.svelte +59 -0
  67. package/dist/components/Tabs/Tabs.svelte.d.ts +5 -0
  68. package/dist/components/Tabs/TabsControl.svelte +51 -0
  69. package/dist/components/Tabs/TabsControl.svelte.d.ts +5 -0
  70. package/dist/components/Tabs/TabsPanel.svelte +23 -0
  71. package/dist/components/Tabs/TabsPanel.svelte.d.ts +5 -0
  72. package/dist/components/{Tab → Tabs}/context.js +3 -2
  73. package/dist/components/Tabs/index.d.ts +5 -0
  74. package/dist/components/{Tab → Tabs}/index.js +1 -1
  75. package/dist/components/{Tab → Tabs}/types.d.ts +1 -3
  76. package/dist/components/TagsInput/TagsInput.svelte +48 -54
  77. package/dist/components/TagsInput/TagsInput.svelte.d.ts +2 -14
  78. package/dist/components/TagsInput/types.d.ts +3 -7
  79. package/dist/components/Toast/ToastProvider.svelte +133 -0
  80. package/dist/components/Toast/ToastProvider.svelte.d.ts +4 -0
  81. package/dist/components/Toast/types.d.ts +87 -0
  82. package/dist/components/Tooltip/Tooltip.svelte +79 -0
  83. package/dist/components/Tooltip/Tooltip.svelte.d.ts +4 -0
  84. package/dist/components/Tooltip/types.d.ts +44 -0
  85. package/dist/components/Tooltip/types.js +1 -0
  86. package/dist/index.d.ts +8 -2
  87. package/dist/index.js +11 -2
  88. package/dist/internal/create-context.d.ts +6 -0
  89. package/dist/internal/create-context.js +3 -3
  90. package/dist/internal/test-utils.d.ts +3 -0
  91. package/dist/internal/test-utils.js +9 -0
  92. package/package.json +43 -54
  93. package/dist/components/Accordion/Accordion.svelte.spec.js +0 -4
  94. package/dist/components/Nav/NavBar.svelte +0 -45
  95. package/dist/components/Nav/NavBar.svelte.d.ts +0 -17
  96. package/dist/components/Nav/NavRail.svelte +0 -79
  97. package/dist/components/Nav/NavRail.svelte.d.ts +0 -17
  98. package/dist/components/Nav/NavTile.svelte +0 -76
  99. package/dist/components/Nav/NavTile.svelte.d.ts +0 -17
  100. package/dist/components/Nav/context.js +0 -7
  101. package/dist/components/Tab/Tabs.svelte +0 -65
  102. package/dist/components/Tab/Tabs.svelte.d.ts +0 -17
  103. package/dist/components/Tab/TabsControl.svelte +0 -42
  104. package/dist/components/Tab/TabsControl.svelte.d.ts +0 -17
  105. package/dist/components/Tab/TabsPanel.svelte +0 -18
  106. package/dist/components/Tab/TabsPanel.svelte.d.ts +0 -17
  107. package/dist/internal/noop.d.ts +0 -1
  108. package/dist/internal/noop.js +0 -2
  109. package/dist/internal/snippets.d.ts +0 -3
  110. package/dist/internal/snippets.js +0 -45
  111. package/dist/internal/use-id.d.ts +0 -2
  112. package/dist/internal/use-id.js +0 -5
  113. /package/dist/components/{Nav → Navigation}/context.d.ts +0 -0
  114. /package/dist/components/{Nav → Navigation}/types.js +0 -0
  115. /package/dist/components/{Tab → Tabs}/context.d.ts +0 -0
  116. /package/dist/components/{Tab → Tabs}/types.js +0 -0
  117. /package/dist/components/{Accordion/Accordion.svelte.spec.d.ts → Toast/types.js} +0 -0
@@ -0,0 +1,59 @@
1
+ <script lang="ts">
2
+ import * as tabs from '@zag-js/tabs';
3
+ import { useMachine, normalizeProps } from '@zag-js/svelte';
4
+ import type { TabsProps } from './types.js';
5
+ import { setTabContext } from './context.js';
6
+
7
+ const {
8
+ fluid = false,
9
+ // Root
10
+ base = 'w-full',
11
+ classes = '',
12
+ // List
13
+ listBase = 'flex',
14
+ listJustify = 'justify-start',
15
+ listBorder = 'border-b-[1px] border-surface-200-800',
16
+ listMargin = 'mb-4',
17
+ listGap = 'gap-2',
18
+ listClasses = '',
19
+ // Content
20
+ contentBase = '',
21
+ contentClasses = '',
22
+ // Snippets
23
+ list,
24
+ content,
25
+ // Zag
26
+ ...zagProps
27
+ }: TabsProps = $props();
28
+
29
+ // Zag
30
+ const id = $props.id();
31
+ const service = useMachine(tabs.machine, () => ({
32
+ id: id,
33
+ ...zagProps
34
+ }));
35
+ const api = $derived(tabs.connect(service, normalizeProps));
36
+
37
+ // Set Context
38
+ setTabContext({
39
+ get api() {
40
+ return api;
41
+ },
42
+ get fluid() {
43
+ return fluid;
44
+ }
45
+ });
46
+ </script>
47
+
48
+ <!-- @component Use tabs to quickly switch between different views and pages. -->
49
+
50
+ <div {...api.getRootProps()} class="{base} {classes}" data-testid="tabs">
51
+ <!-- List -->
52
+ <div {...api.getListProps()} class="{listBase} {listJustify} {listBorder} {listMargin} {listGap} {listClasses}" data-testid="tabs-list">
53
+ {@render list?.()}
54
+ </div>
55
+ <!-- Content -->
56
+ <div class="{contentBase} {contentClasses}" data-testid="tabs-content">
57
+ {@render content?.()}
58
+ </div>
59
+ </div>
@@ -0,0 +1,5 @@
1
+ import type { TabsProps } from './types.js';
2
+ /** Use tabs to quickly switch between different views and pages. */
3
+ declare const Tabs: import("svelte").Component<TabsProps, {}, "">;
4
+ type Tabs = ReturnType<typeof Tabs>;
5
+ export default Tabs;
@@ -0,0 +1,51 @@
1
+ <script lang="ts">
2
+ import { getTabContext } from './context.js';
3
+ import type { TabsControlProps } from './types.js';
4
+
5
+ const {
6
+ // Root
7
+ base = 'border-b-[1px] border-transparent',
8
+ padding = 'pb-2',
9
+ translateX = 'translate-y-[1px]',
10
+ classes = '',
11
+ // Label
12
+ labelBase = 'btn hover:preset-tonal-primary',
13
+ labelClasses = '',
14
+ // State
15
+ stateInactive = '[&:not(:hover)]:opacity-50',
16
+ stateActive = 'border-b-surface-950-50 opacity-100',
17
+ stateLabelInactive = '',
18
+ stateLabelActive = '',
19
+ // Snippets
20
+ lead,
21
+ children,
22
+ // Zag
23
+ ...zagProps
24
+ }: TabsControlProps = $props();
25
+
26
+ // Get Context
27
+ const ctx = getTabContext();
28
+ const state = $derived(ctx.api.getTriggerState(zagProps));
29
+
30
+ // Reactive
31
+ const rxActive = $derived(state.selected ? stateActive : stateInactive);
32
+ const rxLabelActive = $derived(state.selected ? stateLabelActive : stateLabelInactive);
33
+
34
+ // Styles
35
+ const commonWidth = $derived(ctx.fluid ? '100%' : '');
36
+ </script>
37
+
38
+ <!-- @component A individual tab trigger element. -->
39
+
40
+ <button
41
+ {...ctx.api.getTriggerProps(zagProps)}
42
+ class="{base} {padding} {translateX} {rxActive} {classes}"
43
+ style:width={commonWidth}
44
+ data-testid="tabs-control"
45
+ >
46
+ <!-- Label -->
47
+ <div class="{labelBase} {rxLabelActive} {labelClasses}" style:width={commonWidth} data-testid="tabs-control-label">
48
+ {#if lead}<span>{@render lead()}</span>{/if}
49
+ <span>{@render children?.()}</span>
50
+ </div>
51
+ </button>
@@ -0,0 +1,5 @@
1
+ import type { TabsControlProps } from './types.js';
2
+ /** A individual tab trigger element. */
3
+ declare const TabsControl: import("svelte").Component<TabsControlProps, {}, "">;
4
+ type TabsControl = ReturnType<typeof TabsControl>;
5
+ export default TabsControl;
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import { getTabContext } from './context.js';
3
+ import type { TabsPanelProps } from './types.js';
4
+
5
+ const {
6
+ // Root
7
+ base = '',
8
+ classes = '',
9
+ // Children
10
+ children,
11
+ // Zag
12
+ ...zagProps
13
+ }: TabsPanelProps = $props();
14
+
15
+ // Get Context
16
+ const ctx = getTabContext();
17
+ </script>
18
+
19
+ <!-- @component A individual tab panel of content. -->
20
+
21
+ <div {...ctx.api.getContentProps(zagProps)} class="{base} {classes}" data-testid="tabs-panel">
22
+ {@render children?.()}
23
+ </div>
@@ -0,0 +1,5 @@
1
+ import type { TabsPanelProps } from './types.js';
2
+ /** A individual tab panel of content. */
3
+ declare const TabsPanel: import("svelte").Component<TabsPanelProps, {}, "">;
4
+ type TabsPanel = ReturnType<typeof TabsPanel>;
5
+ export default TabsPanel;
@@ -1,6 +1,7 @@
1
+ var _a;
1
2
  import * as tabs from '@zag-js/tabs';
2
3
  import { createContext } from '../../internal/create-context.js';
3
- export const [setTabContext, getTabContext, key] = createContext({
4
+ export var setTabContext = (_a = createContext({
4
5
  fluid: false,
5
6
  api: {}
6
- });
7
+ }), _a[0]), getTabContext = _a[1], key = _a[2];
@@ -0,0 +1,5 @@
1
+ declare const _default: import("svelte").Component<import("./types").TabsProps, {}, ""> & {
2
+ Control: import("svelte").Component<import("./types").TabsControlProps, {}, "">;
3
+ Panel: import("svelte").Component<import("./types").TabsPanelProps, {}, "">;
4
+ };
5
+ export default _default;
@@ -1,4 +1,4 @@
1
1
  import Tabs from './Tabs.svelte';
2
2
  import Control from './TabsControl.svelte';
3
3
  import Panel from './TabsPanel.svelte';
4
- export default Object.assign(Tabs, { Control, Panel });
4
+ export default /* @__PURE__ */ Object.assign(Tabs, { Control: Control, Panel: Panel });
@@ -4,9 +4,7 @@ export interface TabsContextState {
4
4
  fluid: boolean;
5
5
  api: ReturnType<typeof tabs.connect>;
6
6
  }
7
- export interface TabsProps extends Omit<tabs.Context, 'id' | 'orientation' | 'onValueChange'> {
8
- /** Set the active value. */
9
- value?: string;
7
+ export interface TabsProps extends Omit<tabs.Props, 'id' | 'orientation'> {
10
8
  /** Set tabs to stretch to fill the available width. */
11
9
  fluid?: boolean;
12
10
  /** Set base classes for the root element. */
@@ -1,56 +1,50 @@
1
- <script lang="ts">import * as tagsInput from "@zag-js/tags-input";
2
- import { useMachine, normalizeProps } from "@zag-js/svelte";
3
- import { useId } from "../../internal/use-id.js";
4
- let {
5
- value = $bindable(),
6
- placeholder = "",
7
- // Root
8
- base = "grid input",
9
- gap = "gap-2",
10
- padding = "p-3",
11
- classes = "",
12
- // Input: Add
13
- inputBase = "input-ghost",
14
- inputClasses = "",
15
- // Tag List
16
- tagListBase = "flex gap-2",
17
- tagListClasses = "",
18
- // Tag
19
- tagBase = "chip",
20
- tagBackground = "preset-filled",
21
- tagClasses = "",
22
- // Input: Edit
23
- inputEditBase = "chip-input -translate-y-0.25",
24
- tagEditBackground = "preset-outlined-surface-200-800",
25
- inputEditClasses,
26
- // Delete Button
27
- buttonDeleteBase = "",
28
- buttonDeleteClasses = "",
29
- // State
30
- stateDisabled = "disabled",
31
- // Snippets
32
- buttonDelete,
33
- // Zag
34
- ...zagProps
35
- } = $props();
36
- const [snapshot, send] = useMachine(
37
- tagsInput.machine({
38
- id: useId(),
39
- onValueChange: (details) => {
40
- value = details.value;
41
- }
42
- }),
43
- {
44
- context: {
45
- ...zagProps,
46
- get value() {
47
- return $state.snapshot(value);
48
- }
49
- }
50
- }
51
- );
52
- const api = $derived(tagsInput.connect(snapshot, send, normalizeProps));
53
- const rxDisabled = $derived(snapshot.context.disabled ? stateDisabled : "");
1
+ <script lang="ts">
2
+ import * as tagsInput from '@zag-js/tags-input';
3
+ import { useMachine, normalizeProps } from '@zag-js/svelte';
4
+ import type { TagsInputProps } from './types.js';
5
+
6
+ // Props
7
+ const {
8
+ placeholder = '',
9
+ // Root
10
+ base = 'grid input !h-auto',
11
+ gap = 'gap-2',
12
+ padding = 'p-3',
13
+ classes = '',
14
+ // Input: Add
15
+ inputBase = 'input-ghost',
16
+ inputClasses = '',
17
+ // Tag List
18
+ tagListBase = 'flex flex-wrap gap-1',
19
+ tagListClasses = '',
20
+ // Tag
21
+ tagBase = 'chip',
22
+ tagBackground = 'preset-filled',
23
+ tagClasses = '',
24
+ // Input: Edit
25
+ tagEditInputBase = 'input',
26
+ tagEditInputClasses = '',
27
+ // Delete Button
28
+ buttonDeleteBase = '',
29
+ buttonDeleteClasses = '',
30
+ // State
31
+ stateDisabled = 'disabled',
32
+ // Snippets
33
+ buttonDelete,
34
+ // Zag
35
+ ...zagProps
36
+ }: TagsInputProps = $props();
37
+
38
+ // Zag
39
+ const id = $props.id();
40
+ const service = useMachine(tagsInput.machine, () => ({
41
+ id: id,
42
+ ...zagProps
43
+ }));
44
+ const api = $derived(tagsInput.connect(service, normalizeProps));
45
+
46
+ // Reactive
47
+ const rxDisabled = $derived(service.prop('disabled') ? stateDisabled : '');
54
48
  </script>
55
49
 
56
50
  <!-- @component Capture a set of values from users via input and suggestions. -->
@@ -89,7 +83,7 @@ const rxDisabled = $derived(snapshot.context.disabled ? stateDisabled : "");
89
83
  <!-- Editing -->
90
84
  <input
91
85
  {...api.getItemInputProps({ index, value })}
92
- class="{inputEditBase} {tagEditBackground} {inputEditClasses}"
86
+ class="{tagEditInputBase} {tagEditInputClasses}"
93
87
  style:display={itemState.editing ? '' : 'none'}
94
88
  data-testid="tags-input-edit"
95
89
  />
@@ -1,17 +1,5 @@
1
1
  import type { TagsInputProps } from './types.js';
2
- 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> {
3
- new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
- $$bindings?: Bindings;
5
- } & Exports;
6
- (internal: unknown, props: Props & {
7
- $$events?: Events;
8
- $$slots?: Slots;
9
- }): Exports;
10
- z_$$bindings?: Bindings;
11
- }
12
2
  /** Capture a set of values from users via input and suggestions. */
13
- declare const TagsInput: $$__sveltets_2_IsomorphicComponent<TagsInputProps, {
14
- [evt: string]: CustomEvent<any>;
15
- }, {}, {}, "value">;
16
- type TagsInput = InstanceType<typeof TagsInput>;
3
+ declare const TagsInput: import("svelte").Component<TagsInputProps, {}, "">;
4
+ type TagsInput = ReturnType<typeof TagsInput>;
17
5
  export default TagsInput;
@@ -1,8 +1,6 @@
1
1
  import * as tagsInput from '@zag-js/tags-input';
2
2
  import type { Snippet } from 'svelte';
3
- export interface TagsInputProps extends Omit<tagsInput.Context, 'id' | 'value'> {
4
- /** Set the tag values. */
5
- value?: tagsInput.Context['value'];
3
+ export interface TagsInputProps extends Omit<tagsInput.Props, 'id'> {
6
4
  /** Set the add tag input placeholder. */
7
5
  placeholder?: string;
8
6
  /** Set base classes for the root. */
@@ -28,11 +26,9 @@ export interface TagsInputProps extends Omit<tagsInput.Context, 'id' | 'value'>
28
26
  /** Provide arbitrary classes to each tag. */
29
27
  tagClasses?: string;
30
28
  /** Set base classes for the edit tag input. */
31
- inputEditBase?: string;
32
- /** Set background classes for the edit tag input. */
33
- tagEditBackground?: string;
29
+ tagEditInputBase?: string;
34
30
  /** Provide arbitrary classes to the edit tag input. */
35
- inputEditClasses?: string;
31
+ tagEditInputClasses?: string;
36
32
  /** Set base classes for the delete button. */
37
33
  buttonDeleteBase?: string;
38
34
  /** Provide arbitrary classes to the delete button. */
@@ -0,0 +1,133 @@
1
+ <script lang="ts">
2
+ import { setContext } from 'svelte';
3
+ import { flip } from 'svelte/animate';
4
+ import { fade } from 'svelte/transition';
5
+
6
+ import type { PlacementStyles, Toast, ToastProviderProps } from './types.js';
7
+
8
+ const {
9
+ placement = 'bottom-end',
10
+ offset = '16px',
11
+ dismissLabel = '',
12
+ // Group
13
+ base = 'fixed flex flex-col items-end',
14
+ gap = 'gap-4',
15
+ zIndex = 'z-[888]',
16
+ classes = '',
17
+ // Toast
18
+ toastBase = 'card py-2 px-3 grid grid-cols-[1fr_auto] items-center',
19
+ toastPadding = 'py-2 px-3',
20
+ toastGap = 'gap-4',
21
+ toastShadow = 'shadow-xl',
22
+ toastClasses = '',
23
+ // Message
24
+ messageBase = 'grid grid-cols-1 max-w-xs text-xs',
25
+ messageTitle = 'font-bold',
26
+ messageDescription = '',
27
+ messageClasses = '',
28
+ // Dismiss Button
29
+ buttonDismissBase = 'btn-icon btn-icon-sm text-base',
30
+ buttonDimissPreset = '',
31
+ buttonDismissHover = 'hover:preset-tonal',
32
+ buttonDismissClasses = '',
33
+ // State
34
+ stateInfo = 'preset-filled',
35
+ stateError = 'preset-filled-error-500',
36
+ stateSuccess = 'preset-filled-success-500',
37
+ // Snippets
38
+ children
39
+ }: ToastProviderProps = $props();
40
+
41
+ // Local
42
+ const defaults: Record<string, Toast> = {
43
+ info: { duration: 5000 },
44
+ error: { duration: 5000 },
45
+ success: { duration: 2000 }
46
+ };
47
+ const placementOptions: Record<string, PlacementStyles> = {
48
+ 'top-start': { top: offset, left: offset, 'align-items': 'flex-start' },
49
+ 'top-end': { top: offset, right: offset, 'align-items': 'flex-end' },
50
+ 'bottom-start': { bottom: offset, left: offset, 'align-items': 'flex-start' },
51
+ 'bottom-end': { bottom: offset, right: offset, 'align-items': 'flex-end' }
52
+ };
53
+
54
+ // State
55
+ let toastQueue: Toast[] = $state([]);
56
+
57
+ // Context
58
+ const id = $props.id();
59
+ setContext('toast', {
60
+ create: (toast: Toast) => {
61
+ // Set default settings
62
+ toast = {
63
+ ...defaults[String(toast.type || 'info')],
64
+ ...toast,
65
+ id: id
66
+ };
67
+ // Push to Queue
68
+ toastQueue.push(toast);
69
+ // Set duration timeout
70
+ setTimeout(() => {
71
+ dismiss(toast.id);
72
+ }, toast.duration);
73
+ }
74
+ });
75
+
76
+ function formatStyleAttr(style: PlacementStyles) {
77
+ return Object.entries(style)
78
+ .map(([k, v]) => `${k}:${v}`)
79
+ .join(';');
80
+ }
81
+
82
+ function dismiss(id: string | undefined) {
83
+ if (!id) return;
84
+ toastQueue = toastQueue.filter((t) => t.id !== id);
85
+ }
86
+
87
+ function getStateClasses(type?: string) {
88
+ // prettier-ignore
89
+ switch (type) {
90
+ case 'error': return stateError;
91
+ case 'success': return stateSuccess;
92
+ default: return stateInfo;
93
+ }
94
+ }
95
+ </script>
96
+
97
+ <!-- Toast Group -->
98
+ {#if toastQueue.length}
99
+ <div
100
+ class="{base} {gap} {zIndex} {classes}"
101
+ style={formatStyleAttr(placementOptions[placement])}
102
+ data-part="root"
103
+ data-testid="toast-provider"
104
+ >
105
+ {#each toastQueue as toast, i (toast)}
106
+ {@const stateClasses = getStateClasses(toast.type)}
107
+ <!-- Toast -->
108
+ <div
109
+ data-index={i}
110
+ data-type={toast.type}
111
+ class="{toastBase} {toastPadding} {toastGap} {toastShadow} {toastClasses} {stateClasses}"
112
+ animate:flip={{ duration: 200 }}
113
+ transition:fade={{ duration: 200 }}
114
+ >
115
+ <!-- Message -->
116
+ <div class="{messageBase} {messageClasses}">
117
+ {#if toast.title}<div class={messageTitle}>{toast.title}</div>{/if}
118
+ <div class={messageDescription}>{toast.description}</div>
119
+ </div>
120
+ <!-- Dismiss -->
121
+ <button
122
+ type="button"
123
+ class="{buttonDismissBase} {buttonDimissPreset} {buttonDismissHover} {buttonDismissClasses}"
124
+ onclick={() => dismiss(toast.id)}
125
+ >
126
+ {#if dismissLabel}{dismissLabel}{:else}&times;{/if}
127
+ </button>
128
+ </div>
129
+ {/each}
130
+ </div>
131
+ {/if}
132
+
133
+ {@render children?.()}
@@ -0,0 +1,4 @@
1
+ import type { ToastProviderProps } from './types.js';
2
+ declare const ToastProvider: import("svelte").Component<ToastProviderProps, {}, "">;
3
+ type ToastProvider = ReturnType<typeof ToastProvider>;
4
+ export default ToastProvider;
@@ -0,0 +1,87 @@
1
+ import type { Snippet } from 'svelte';
2
+ export interface PlacementStyles {
3
+ top?: string;
4
+ bottom?: string;
5
+ left?: string;
6
+ right?: string;
7
+ 'align-items'?: string;
8
+ }
9
+ export interface Toast {
10
+ /** The unique toast ID. */
11
+ id?: string;
12
+ /** The unique toast title text. */
13
+ title?: string;
14
+ /** The unique toast description text. */
15
+ description?: string;
16
+ /**
17
+ * Define the toast type.
18
+ * @default info
19
+ */
20
+ type?: 'info' | 'error' | 'success';
21
+ /** The duration of the toast. Default varies by type. */
22
+ duration?: number;
23
+ }
24
+ /** Provides access to the Toast Context API. */
25
+ export interface ToastContext {
26
+ /** Used to create display a new Toast instance. */
27
+ create: (toast: Toast) => void;
28
+ }
29
+ export interface ToastProviderProps {
30
+ /**
31
+ * Offset from the viewport edge.
32
+ * @default bottom-end
33
+ */
34
+ placement?: 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end';
35
+ /**
36
+ * Offset from the viewport edge.
37
+ * @default 16px
38
+ */
39
+ offset?: string;
40
+ /**
41
+ * The dismiss button label text.
42
+ * @default &times;
43
+ */
44
+ dismissLabel?: string;
45
+ /** Provide base classes for the root element. */
46
+ base?: string;
47
+ /** Provide gap classes for the root element. */
48
+ gap?: string;
49
+ /** Provide z-index classes for the root element. */
50
+ zIndex?: string;
51
+ /** Provide arbitrary classes for the root element. */
52
+ classes?: string;
53
+ /** Provide base classes for the toast cards. */
54
+ toastBase?: string;
55
+ /** Provide padding classes for the toast cards. */
56
+ toastPadding?: string;
57
+ /** Provide gap classes for the toast cards. */
58
+ toastGap?: string;
59
+ /** Provide shadow classes for the toast cards. */
60
+ toastShadow?: string;
61
+ /** Provide arbitrary classes for the toast cards. */
62
+ toastClasses?: string;
63
+ /** Provide base classes for the message region. */
64
+ messageBase?: string;
65
+ /** Provide classes for the message title text. */
66
+ messageTitle?: string;
67
+ /** Provide classes for the message description text. */
68
+ messageDescription?: string;
69
+ /** Provide arbitrary classes for the message region. */
70
+ messageClasses?: string;
71
+ /** Provide base classes for the dismiss button. */
72
+ buttonDismissBase?: string;
73
+ /** Provide preset classes for the dismiss button. */
74
+ buttonDimissPreset?: string;
75
+ /** Provide hover classes for the dismiss button. */
76
+ buttonDismissHover?: string;
77
+ /** Provide arbitrary classes for the dismiss button. */
78
+ buttonDismissClasses?: string;
79
+ /** Provide base classes for info toasts. */
80
+ stateInfo?: string;
81
+ /** Provide base classes for error toasts. */
82
+ stateError?: string;
83
+ /** Provide base classes for success toasts. */
84
+ stateSuccess?: string;
85
+ /** The default child slot for the toast provider. */
86
+ children?: Snippet;
87
+ }
@@ -0,0 +1,79 @@
1
+ <script lang="ts">
2
+ import { fade } from 'svelte/transition';
3
+
4
+ import * as tooltip from '@zag-js/tooltip';
5
+ import { useMachine, normalizeProps, mergeProps } from '@zag-js/svelte';
6
+ import type { TooltipProps } from './types.js';
7
+
8
+ const {
9
+ arrow = false,
10
+ zIndex = 'auto',
11
+ // Base
12
+ base = '',
13
+ classes = '',
14
+ // Trigger
15
+ triggerBase = '',
16
+ triggerBackground = '',
17
+ triggerClasses = '',
18
+ triggerAriaLabel = '',
19
+ // Positioner
20
+ positionerBase = '',
21
+ positionerClasses = '',
22
+ // Content
23
+ contentBase = '',
24
+ contentBackground = '',
25
+ contentClasses = '',
26
+ // Arrow
27
+ arrowBase = '',
28
+ arrowBackground = '!bg-white',
29
+ arrowClasses = '',
30
+ // Snippets
31
+ trigger,
32
+ content,
33
+ // Events
34
+ onmouseover,
35
+ onclick,
36
+ // Zag ---
37
+ ...zagProps
38
+ }: TooltipProps = $props();
39
+
40
+ // Zag
41
+ const id = $props.id();
42
+ const service = useMachine(tooltip.machine, () => ({
43
+ id: id,
44
+ ...zagProps
45
+ }));
46
+ const api = $derived(tooltip.connect(service, normalizeProps));
47
+ const triggerProps = $derived(mergeProps(api.getTriggerProps(), { onmouseover, onclick }));
48
+ </script>
49
+
50
+ <span class="{base} {classes}" data-testid="tooltip">
51
+ <!-- Snippet: Trigger -->
52
+ {#if trigger}
53
+ <button {...triggerProps} class="{triggerBase} {triggerBackground} {triggerClasses}" type="button" aria-label={triggerAriaLabel}>
54
+ {@render trigger()}
55
+ </button>
56
+ {/if}
57
+ <!-- Tooltip Content -->
58
+ {#if api.open}
59
+ <div {...api.getPositionerProps()} transition:fade={{ duration: 100 }} class="{positionerBase} {positionerClasses}">
60
+ <!-- Arrow -->
61
+ {#if arrow}
62
+ <div {...api.getArrowProps()}>
63
+ <div {...api.getArrowTipProps()} class="{arrowBase} {arrowBackground} {arrowClasses}"></div>
64
+ </div>
65
+ {/if}
66
+ <!-- Snippet Content -->
67
+ <div {...api.getContentProps()} class="{contentBase} {contentBackground} {contentClasses}" style="z-index: {zIndex};">
68
+ {@render content?.()}
69
+ </div>
70
+ </div>
71
+ {/if}
72
+ </span>
73
+
74
+ <style>
75
+ :global([data-part='arrow']) {
76
+ --arrow-size: 10px;
77
+ --arrow-background: white;
78
+ }
79
+ </style>
@@ -0,0 +1,4 @@
1
+ import type { TooltipProps } from './types.js';
2
+ declare const Tooltip: import("svelte").Component<TooltipProps, {}, "">;
3
+ type Tooltip = ReturnType<typeof Tooltip>;
4
+ export default Tooltip;