svelora 3.0.15 → 3.0.16

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 (95) hide show
  1. package/dist/components/ConfirmDialog/ConfirmDialog.svelte +167 -0
  2. package/dist/components/ConfirmDialog/ConfirmDialog.svelte.d.ts +10 -0
  3. package/dist/components/ConfirmDialog/confirm.d.ts +9 -0
  4. package/dist/components/ConfirmDialog/confirm.js +24 -0
  5. package/dist/components/ConfirmDialog/confirm.types.d.ts +22 -0
  6. package/dist/components/ConfirmDialog/confirm.types.js +1 -0
  7. package/dist/components/ConfirmDialog/index.d.ts +4 -0
  8. package/dist/components/ConfirmDialog/index.js +2 -0
  9. package/dist/components/SortableList/SortableList.svelte +54 -0
  10. package/dist/components/SortableList/SortableList.svelte.d.ts +26 -0
  11. package/dist/components/SortableList/index.d.ts +2 -0
  12. package/dist/components/SortableList/index.js +1 -0
  13. package/dist/components/SortableList/sortable-list.types.d.ts +17 -0
  14. package/dist/components/SortableList/sortable-list.types.js +1 -0
  15. package/dist/components/Toast/Toaster.svelte +194 -137
  16. package/dist/components/Toast/index.d.ts +2 -0
  17. package/dist/components/Toast/index.js +1 -0
  18. package/dist/components/Toast/internal/AnimatedIcon.svelte +446 -0
  19. package/dist/components/Toast/internal/AnimatedIcon.svelte.d.ts +15 -0
  20. package/dist/components/Toast/internal/animated-icon.types.d.ts +1 -0
  21. package/dist/components/Toast/internal/animated-icon.types.js +1 -0
  22. package/dist/components/Toast/internal/french-toast/LICENSE.md +21 -0
  23. package/dist/components/Toast/internal/french-toast/components/CheckmarkIcon.svelte +64 -0
  24. package/dist/components/Toast/internal/french-toast/components/CheckmarkIcon.svelte.d.ts +8 -0
  25. package/dist/components/Toast/internal/french-toast/components/ErrorIcon.svelte +74 -0
  26. package/dist/components/Toast/internal/french-toast/components/ErrorIcon.svelte.d.ts +8 -0
  27. package/dist/components/Toast/internal/french-toast/components/LoaderIcon.svelte +28 -0
  28. package/dist/components/Toast/internal/french-toast/components/LoaderIcon.svelte.d.ts +8 -0
  29. package/dist/components/Toast/internal/french-toast/components/ToastBar.svelte +169 -0
  30. package/dist/components/Toast/internal/french-toast/components/ToastBar.svelte.d.ts +20 -0
  31. package/dist/components/Toast/internal/french-toast/components/ToastIcon.svelte +81 -0
  32. package/dist/components/Toast/internal/french-toast/components/ToastIcon.svelte.d.ts +7 -0
  33. package/dist/components/Toast/internal/french-toast/components/ToastMessage.svelte +13 -0
  34. package/dist/components/Toast/internal/french-toast/components/ToastMessage.svelte.d.ts +8 -0
  35. package/dist/components/Toast/internal/french-toast/components/ToastWrapper.svelte +57 -0
  36. package/dist/components/Toast/internal/french-toast/components/ToastWrapper.svelte.d.ts +12 -0
  37. package/dist/components/Toast/internal/french-toast/components/Toaster.svelte +73 -0
  38. package/dist/components/Toast/internal/french-toast/components/Toaster.svelte.d.ts +23 -0
  39. package/dist/components/Toast/internal/french-toast/core/store.svelte.d.ts +15 -0
  40. package/dist/components/Toast/internal/french-toast/core/store.svelte.js +92 -0
  41. package/dist/components/Toast/internal/french-toast/core/toast.d.ts +21 -0
  42. package/dist/components/Toast/internal/french-toast/core/toast.js +67 -0
  43. package/dist/components/Toast/internal/french-toast/core/types.d.ts +58 -0
  44. package/dist/components/Toast/internal/french-toast/core/types.js +4 -0
  45. package/dist/components/Toast/internal/french-toast/core/use-toaster.svelte.d.ts +16 -0
  46. package/dist/components/Toast/internal/french-toast/core/use-toaster.svelte.js +71 -0
  47. package/dist/components/Toast/internal/french-toast/core/utils.d.ts +6 -0
  48. package/dist/components/Toast/internal/french-toast/core/utils.js +25 -0
  49. package/dist/components/Toast/internal/french-toast/toast-context.d.ts +18 -0
  50. package/dist/components/Toast/internal/french-toast/toast-context.js +10 -0
  51. package/dist/components/Toast/internal/notify.d.ts +31 -0
  52. package/dist/components/Toast/internal/notify.js +100 -0
  53. package/dist/components/Toast/internal/toast-icons/ToastError.svelte +8 -0
  54. package/dist/components/Toast/internal/toast-icons/ToastError.svelte.d.ts +4 -0
  55. package/dist/components/Toast/internal/toast-icons/ToastInfo.svelte +8 -0
  56. package/dist/components/Toast/internal/toast-icons/ToastInfo.svelte.d.ts +4 -0
  57. package/dist/components/Toast/internal/toast-icons/ToastLoading.svelte +8 -0
  58. package/dist/components/Toast/internal/toast-icons/ToastLoading.svelte.d.ts +4 -0
  59. package/dist/components/Toast/internal/toast-icons/ToastProcessing.svelte +8 -0
  60. package/dist/components/Toast/internal/toast-icons/ToastProcessing.svelte.d.ts +4 -0
  61. package/dist/components/Toast/internal/toast-icons/ToastSuccess.svelte +8 -0
  62. package/dist/components/Toast/internal/toast-icons/ToastSuccess.svelte.d.ts +4 -0
  63. package/dist/components/Toast/internal/toast-icons/ToastWarning.svelte +8 -0
  64. package/dist/components/Toast/internal/toast-icons/ToastWarning.svelte.d.ts +4 -0
  65. package/dist/components/Toast/internal/toast-icons/index.d.ts +6 -0
  66. package/dist/components/Toast/internal/toast-icons/index.js +6 -0
  67. package/dist/components/Toast/internal/toast-icons/toast-icon.types.d.ts +4 -0
  68. package/dist/components/Toast/internal/toast-icons/toast-icon.types.js +1 -0
  69. package/dist/components/Toast/toast.d.ts +31 -16
  70. package/dist/components/Toast/toast.js +45 -20
  71. package/dist/components/Toast/toast.types.d.ts +20 -7
  72. package/dist/hooks/index.d.ts +2 -0
  73. package/dist/hooks/index.js +2 -0
  74. package/dist/hooks/internal/DragDropProviderScope.svelte +29 -0
  75. package/dist/hooks/internal/DragDropProviderScope.svelte.d.ts +7 -0
  76. package/dist/hooks/internal/SortableProvider.svelte +30 -0
  77. package/dist/hooks/internal/SortableProvider.svelte.d.ts +7 -0
  78. package/dist/hooks/internal/drag-drop-context.d.ts +12 -0
  79. package/dist/hooks/internal/drag-drop-context.js +1 -0
  80. package/dist/hooks/internal/sortable-context.d.ts +12 -0
  81. package/dist/hooks/internal/sortable-context.js +1 -0
  82. package/dist/hooks/useDragDrop/index.d.ts +1 -0
  83. package/dist/hooks/useDragDrop/index.js +1 -0
  84. package/dist/hooks/useDragDrop/useDragDrop.svelte.d.ts +40 -0
  85. package/dist/hooks/useDragDrop/useDragDrop.svelte.js +128 -0
  86. package/dist/hooks/useSortable/index.d.ts +2 -0
  87. package/dist/hooks/useSortable/index.js +2 -0
  88. package/dist/hooks/useSortable/sortable-utils.d.ts +1 -0
  89. package/dist/hooks/useSortable/sortable-utils.js +13 -0
  90. package/dist/hooks/useSortable/useSortable.svelte.d.ts +52 -0
  91. package/dist/hooks/useSortable/useSortable.svelte.js +120 -0
  92. package/dist/index.d.ts +2 -0
  93. package/dist/index.js +2 -0
  94. package/dist/mcp/svelora-docs.data.json +13 -5
  95. package/package.json +5 -3
@@ -1,14 +1,10 @@
1
- import type { ToasterProps as SonnerToasterProps } from 'svelte-sonner';
2
1
  import type { ClassNameValue } from 'tailwind-merge';
2
+ import type { Snippet } from 'svelte';
3
+ import type { DefaultToastOptions, ToastPosition } from './internal/french-toast/core/types.js';
3
4
  import type { ToastVariant } from './toast.variants.js';
4
- export type ToasterProps = Omit<SonnerToasterProps, 'class' | 'toastOptions' | 'richColors'> & {
5
+ export type ToasterProps = {
5
6
  /**
6
7
  * The visual style variant.
7
- * - `outline`: Border with surface background, semantic border accent per type (default)
8
- * - `soft`: Light tinted background per type
9
- * - `subtle`: Light tinted background + semantic border per type
10
- * - `solid`: Full semantic color background per type
11
- * - `accent`: Left color stripe with surface background
12
8
  * @default 'outline'
13
9
  */
14
10
  variant?: ToastVariant;
@@ -16,4 +12,21 @@ export type ToasterProps = Omit<SonnerToasterProps, 'class' | 'toastOptions' | '
16
12
  * Additional CSS classes for the toaster container.
17
13
  */
18
14
  class?: ClassNameValue;
15
+ position?: ToastPosition;
16
+ duration?: number;
17
+ closeButton?: boolean;
18
+ /** @deprecated French-toast does not support expand stacking. Kept for API compatibility. */
19
+ expand?: boolean;
20
+ /** @deprecated French-toast manages visible toasts internally. Kept for API compatibility. */
21
+ visibleToasts?: number;
22
+ gap?: number;
23
+ theme?: 'light' | 'dark' | 'system';
24
+ reverseOrder?: boolean;
25
+ toastOptions?: DefaultToastOptions;
26
+ successIcon?: Snippet;
27
+ errorIcon?: Snippet;
28
+ warningIcon?: Snippet;
29
+ infoIcon?: Snippet;
30
+ loadingIcon?: Snippet;
31
+ closeIcon?: Snippet;
19
32
  };
@@ -14,3 +14,5 @@ export * from './useIntersectionObserver/index.js';
14
14
  export * from './useScrollLock/index.js';
15
15
  export * from './useFocusTrap/index.js';
16
16
  export * from './useLocalStorage/index.js';
17
+ export * from './useSortable/index.js';
18
+ export * from './useDragDrop/index.js';
@@ -14,3 +14,5 @@ export * from './useIntersectionObserver/index.js';
14
14
  export * from './useScrollLock/index.js';
15
15
  export * from './useFocusTrap/index.js';
16
16
  export * from './useLocalStorage/index.js';
17
+ export * from './useSortable/index.js';
18
+ export * from './useDragDrop/index.js';
@@ -0,0 +1,29 @@
1
+ <script lang="ts">import { DragDropProvider } from "@dnd-kit/svelte";
2
+ import { getContext } from "svelte";
3
+ import { DRAG_DROP_CONTEXT_KEY } from "./drag-drop-context.js";
4
+ let { children } = $props();
5
+ const ctx = getContext(DRAG_DROP_CONTEXT_KEY);
6
+ function handleDragStart(event) {
7
+ const source = event.operation.source;
8
+ if (!source) return;
9
+ ctx.setDraggingId(String(source.id));
10
+ }
11
+ function handleDragEnd(event) {
12
+ const source = event.operation.source;
13
+ const target = event.operation.target;
14
+ ctx.setDraggingId(null);
15
+ if (!source || !target) return;
16
+ const zone = ctx.getDroppable(String(target.id));
17
+ if (!zone) return;
18
+ const payload = ctx.toPayload({
19
+ id: source.id,
20
+ data: source.data
21
+ });
22
+ if (zone.accept && !zone.accept(payload)) return;
23
+ zone.onDrop(payload);
24
+ }
25
+ </script>
26
+
27
+ <DragDropProvider onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
28
+ {@render children?.()}
29
+ </DragDropProvider>
@@ -0,0 +1,7 @@
1
+ import { type Snippet } from 'svelte';
2
+ interface Props {
3
+ children?: Snippet;
4
+ }
5
+ declare const DragDropProviderScope: import("svelte").Component<Props, {}, "">;
6
+ type DragDropProviderScope = ReturnType<typeof DragDropProviderScope>;
7
+ export default DragDropProviderScope;
@@ -0,0 +1,30 @@
1
+ <script lang="ts">import { DragDropProvider } from "@dnd-kit/svelte";
2
+ import { RestrictToHorizontalAxis, RestrictToVerticalAxis } from "@dnd-kit/abstract/modifiers";
3
+ import { isSortableOperation } from "@dnd-kit/dom/sortable";
4
+ import { getContext } from "svelte";
5
+ import { moveArrayItem } from "../useSortable/sortable-utils.js";
6
+ import { SORTABLE_CONTEXT_KEY } from "./sortable-context.js";
7
+ let { children } = $props();
8
+ const ctx = getContext(SORTABLE_CONTEXT_KEY);
9
+ const modifiers = $derived(ctx.getAxis() === "horizontal" ? [RestrictToHorizontalAxis] : ctx.getAxis() === "vertical" ? [RestrictToVerticalAxis] : []);
10
+ function handleDragStart(event) {
11
+ const source = event.operation.source;
12
+ if (!source) return;
13
+ const items = ctx.getItems();
14
+ const ownsItem = items.some((entry) => String(ctx.getId(entry)) === String(source.id));
15
+ if (!ownsItem) return;
16
+ ctx.setDraggingId(source.id);
17
+ }
18
+ function handleDragEnd(event) {
19
+ ctx.setDraggingId(null);
20
+ if (ctx.isDisabled() || !isSortableOperation(event.operation)) return;
21
+ const { source, target } = event.operation;
22
+ if (!source || !target || source.index === target.index) return;
23
+ const items = ctx.getItems();
24
+ ctx.onReorder(moveArrayItem(items, source.index, target.index));
25
+ }
26
+ </script>
27
+
28
+ <DragDropProvider {modifiers} onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
29
+ {@render children?.()}
30
+ </DragDropProvider>
@@ -0,0 +1,7 @@
1
+ import { type Snippet } from 'svelte';
2
+ interface Props {
3
+ children?: Snippet;
4
+ }
5
+ declare const SortableProvider: import("svelte").Component<Props, {}, "">;
6
+ type SortableProvider = ReturnType<typeof SortableProvider>;
7
+ export default SortableProvider;
@@ -0,0 +1,12 @@
1
+ import type { DragPayload, UseDroppableOptions } from '../useDragDrop/useDragDrop.svelte.js';
2
+ export declare const DRAG_DROP_CONTEXT_KEY: unique symbol;
3
+ export interface DragDropContextValue {
4
+ registerDroppable: <T>(id: string, options: UseDroppableOptions<T>) => void;
5
+ unregisterDroppable: (id: string) => void;
6
+ setDraggingId: (id: string | null) => void;
7
+ getDroppable: <T>(id: string) => UseDroppableOptions<T> | undefined;
8
+ toPayload: (source: {
9
+ id: string | number;
10
+ data?: unknown;
11
+ }) => DragPayload;
12
+ }
@@ -0,0 +1 @@
1
+ export const DRAG_DROP_CONTEXT_KEY = Symbol('svelora-drag-drop');
@@ -0,0 +1,12 @@
1
+ import type { UseSortableOptions } from '../useSortable/useSortable.svelte.js';
2
+ export declare const SORTABLE_CONTEXT_KEY: unique symbol;
3
+ export interface SortableContextValue<T> {
4
+ groupId: string;
5
+ getItems: UseSortableOptions<T>['getItems'];
6
+ getId: UseSortableOptions<T>['getId'];
7
+ onReorder: UseSortableOptions<T>['onReorder'];
8
+ isDisabled: () => boolean;
9
+ getAxis: () => 'vertical' | 'horizontal' | 'grid';
10
+ getHandle: () => string | undefined;
11
+ setDraggingId: (id: string | number | null) => void;
12
+ }
@@ -0,0 +1 @@
1
+ export const SORTABLE_CONTEXT_KEY = Symbol('svelora-sortable');
@@ -0,0 +1 @@
1
+ export * from './useDragDrop.svelte.js';
@@ -0,0 +1 @@
1
+ export * from './useDragDrop.svelte.js';
@@ -0,0 +1,40 @@
1
+ import type { Action } from 'svelte/action';
2
+ import type { Component } from 'svelte';
3
+ import { type Snippet } from 'svelte';
4
+ export interface DragPayload<T = unknown> {
5
+ id: string;
6
+ data?: T;
7
+ }
8
+ export interface UseDraggableOptions<T = unknown> {
9
+ /** Unique id for the draggable element. */
10
+ id: string;
11
+ /** Source drop zone id — used as the draggable type for cross-container matching. */
12
+ container: string;
13
+ data?: T;
14
+ disabled?: boolean | (() => boolean);
15
+ handle?: string;
16
+ }
17
+ export interface UseDroppableOptions<T = unknown> {
18
+ id: string;
19
+ onDrop: (payload: DragPayload<T>) => void;
20
+ accept?: (payload: DragPayload<T>) => boolean;
21
+ disabled?: boolean | (() => boolean);
22
+ }
23
+ export interface UseDragDropReturn {
24
+ /**
25
+ * Wrap drag-and-drop markup with this provider.
26
+ * Required — [@dnd-kit/svelte](https://clauderic-dnd-kit.mintlify.app/frameworks/svelte) needs a DragDropProvider ancestor.
27
+ */
28
+ readonly Provider: Component<{
29
+ children?: Snippet;
30
+ }>;
31
+ readonly draggingId: string | null;
32
+ readonly draggable: Action<HTMLElement, UseDraggableOptions>;
33
+ readonly droppable: Action<HTMLElement, UseDroppableOptions>;
34
+ }
35
+ /**
36
+ * Cross-container drag and drop powered by [@dnd-kit/svelte](https://clauderic-dnd-kit.mintlify.app/frameworks/svelte).
37
+ *
38
+ * Wrap markup in `dragDrop.Provider`, then attach `draggable` and `droppable` actions.
39
+ */
40
+ export declare function useDragDrop(): UseDragDropReturn;
@@ -0,0 +1,128 @@
1
+ import { setContext } from 'svelte';
2
+ import { createDraggable, createDroppable } from '@dnd-kit/svelte';
3
+ import DragDropProviderScope from '../internal/DragDropProviderScope.svelte';
4
+ import { DRAG_DROP_CONTEXT_KEY } from '../internal/drag-drop-context.js';
5
+ /**
6
+ * Cross-container drag and drop powered by [@dnd-kit/svelte](https://clauderic-dnd-kit.mintlify.app/frameworks/svelte).
7
+ *
8
+ * Wrap markup in `dragDrop.Provider`, then attach `draggable` and `droppable` actions.
9
+ */
10
+ export function useDragDrop() {
11
+ let draggingId = $state(null);
12
+ const droppables = new Map();
13
+ const context = {
14
+ registerDroppable(id, options) {
15
+ droppables.set(id, options);
16
+ },
17
+ unregisterDroppable(id) {
18
+ droppables.delete(id);
19
+ },
20
+ setDraggingId(id) {
21
+ draggingId = id;
22
+ },
23
+ getDroppable(id) {
24
+ return droppables.get(id);
25
+ },
26
+ toPayload(source) {
27
+ return {
28
+ id: String(source.id),
29
+ data: source.data
30
+ };
31
+ }
32
+ };
33
+ setContext(DRAG_DROP_CONTEXT_KEY, context);
34
+ const draggableAction = (node, initialOptions) => {
35
+ let currentOptions = initialOptions;
36
+ function isDisabled() {
37
+ return typeof currentOptions.disabled === 'function'
38
+ ? currentOptions.disabled()
39
+ : (currentOptions.disabled ?? false);
40
+ }
41
+ const drag = createDraggable({
42
+ id: currentOptions.id,
43
+ type: currentOptions.container,
44
+ data: (currentOptions.data ?? {}),
45
+ disabled: isDisabled()
46
+ });
47
+ const detach = drag.attach(node);
48
+ let detachHandle;
49
+ function bindHandle() {
50
+ detachHandle?.();
51
+ const selector = currentOptions.handle;
52
+ if (!selector) {
53
+ drag.draggable.handle = undefined;
54
+ detachHandle = undefined;
55
+ return;
56
+ }
57
+ const handle = node.querySelector(selector);
58
+ if (!handle) {
59
+ drag.draggable.handle = undefined;
60
+ detachHandle = undefined;
61
+ return;
62
+ }
63
+ detachHandle = drag.attachHandle(handle);
64
+ }
65
+ bindHandle();
66
+ return {
67
+ update(newOptions) {
68
+ currentOptions = newOptions;
69
+ drag.draggable.id = newOptions.id;
70
+ drag.draggable.type = newOptions.container;
71
+ drag.draggable.data = (newOptions.data ?? {});
72
+ drag.draggable.disabled = isDisabled();
73
+ bindHandle();
74
+ },
75
+ destroy() {
76
+ detach();
77
+ detachHandle?.();
78
+ node.removeAttribute('data-dragging');
79
+ if (draggingId === currentOptions.id) {
80
+ draggingId = null;
81
+ }
82
+ }
83
+ };
84
+ };
85
+ const droppableAction = (node, initialOptions) => {
86
+ let currentOptions = initialOptions;
87
+ function isDisabled() {
88
+ return typeof currentOptions.disabled === 'function'
89
+ ? currentOptions.disabled()
90
+ : (currentOptions.disabled ?? false);
91
+ }
92
+ context.registerDroppable(currentOptions.id, currentOptions);
93
+ const drop = createDroppable({
94
+ id: currentOptions.id,
95
+ disabled: isDisabled(),
96
+ accept(source) {
97
+ const payload = context.toPayload({ id: source.id, data: source.data });
98
+ if (currentOptions.accept) {
99
+ return currentOptions.accept(payload);
100
+ }
101
+ return true;
102
+ }
103
+ });
104
+ const detach = drop.attach(node);
105
+ return {
106
+ update(newOptions) {
107
+ context.unregisterDroppable(currentOptions.id);
108
+ currentOptions = newOptions;
109
+ context.registerDroppable(currentOptions.id, currentOptions);
110
+ drop.droppable.id = newOptions.id;
111
+ drop.droppable.disabled = isDisabled();
112
+ },
113
+ destroy() {
114
+ detach();
115
+ context.unregisterDroppable(currentOptions.id);
116
+ node.removeAttribute('data-droppable-active');
117
+ }
118
+ };
119
+ };
120
+ return {
121
+ get draggingId() {
122
+ return draggingId;
123
+ },
124
+ Provider: DragDropProviderScope,
125
+ draggable: draggableAction,
126
+ droppable: droppableAction
127
+ };
128
+ }
@@ -0,0 +1,2 @@
1
+ export * from './useSortable.svelte.js';
2
+ export { moveArrayItem } from './sortable-utils.js';
@@ -0,0 +1,2 @@
1
+ export * from './useSortable.svelte.js';
2
+ export { moveArrayItem } from './sortable-utils.js';
@@ -0,0 +1 @@
1
+ export declare function moveArrayItem<T>(items: T[], fromIndex: number, toIndex: number): T[];
@@ -0,0 +1,13 @@
1
+ export function moveArrayItem(items, fromIndex, toIndex) {
2
+ if (fromIndex === toIndex ||
3
+ fromIndex < 0 ||
4
+ toIndex < 0 ||
5
+ fromIndex >= items.length ||
6
+ toIndex >= items.length) {
7
+ return items;
8
+ }
9
+ const next = [...items];
10
+ const [removed] = next.splice(fromIndex, 1);
11
+ next.splice(toIndex, 0, removed);
12
+ return next;
13
+ }
@@ -0,0 +1,52 @@
1
+ import type { Action } from 'svelte/action';
2
+ import type { Component } from 'svelte';
3
+ import { type Snippet } from 'svelte';
4
+ export interface UseSortableItemParams<T> {
5
+ index: number;
6
+ item: T;
7
+ }
8
+ export interface UseSortableOptions<T> {
9
+ /** Reactive getter for the current item array. */
10
+ getItems: () => T[];
11
+ /** Stable id for each item — used for keys and reorder tracking. */
12
+ getId: (item: T) => string | number;
13
+ /** Called with the reordered array after a successful drop. */
14
+ onReorder: (items: T[]) => void;
15
+ /**
16
+ * Drag axis.
17
+ * @default 'vertical'
18
+ */
19
+ axis?: 'vertical' | 'horizontal' | 'grid' | (() => 'vertical' | 'horizontal' | 'grid');
20
+ /**
21
+ * CSS selector for the drag handle, relative to each item.
22
+ * When omitted, the whole item is draggable.
23
+ * @example '[data-sortable-handle]'
24
+ */
25
+ handle?: string | (() => string | undefined);
26
+ /**
27
+ * Disable sorting.
28
+ * @default false
29
+ */
30
+ disabled?: boolean | (() => boolean);
31
+ }
32
+ export interface UseSortableReturn<T> {
33
+ /**
34
+ * Wrap sortable markup with this provider.
35
+ * Required — [@dnd-kit/svelte](https://clauderic-dnd-kit.mintlify.app/frameworks/svelte) needs a DragDropProvider ancestor.
36
+ */
37
+ readonly Provider: Component<{
38
+ children?: Snippet;
39
+ }>;
40
+ /** Attach to the list container element (optional wrapper). */
41
+ readonly container: Action<HTMLElement>;
42
+ /** Attach to each sortable row with the current index and item. */
43
+ readonly item: Action<HTMLElement, UseSortableItemParams<T>>;
44
+ /** Id of the item currently being dragged, or null. */
45
+ readonly draggingId: string | number | null;
46
+ }
47
+ /**
48
+ * Sortable list hook powered by [@dnd-kit/svelte](https://clauderic-dnd-kit.mintlify.app/frameworks/svelte).
49
+ *
50
+ * Wrap markup in `sortable.Provider`, then attach `use:sortable.item` to each row.
51
+ */
52
+ export declare function useSortable<T>(options: UseSortableOptions<T>): UseSortableReturn<T>;
@@ -0,0 +1,120 @@
1
+ import { setContext } from 'svelte';
2
+ import { createSortable } from '@dnd-kit/svelte/sortable';
3
+ import SortableProvider from '../internal/SortableProvider.svelte';
4
+ import { SORTABLE_CONTEXT_KEY } from '../internal/sortable-context.js';
5
+ let sortableGroupCounter = 0;
6
+ /**
7
+ * Sortable list hook powered by [@dnd-kit/svelte](https://clauderic-dnd-kit.mintlify.app/frameworks/svelte).
8
+ *
9
+ * Wrap markup in `sortable.Provider`, then attach `use:sortable.item` to each row.
10
+ */
11
+ export function useSortable(options) {
12
+ const { getItems, getId, onReorder } = options;
13
+ const groupId = `svelora-sortable-${++sortableGroupCounter}`;
14
+ let draggingId = $state(null);
15
+ let listNode = $state(null);
16
+ function getAxis() {
17
+ const axis = options.axis;
18
+ return typeof axis === 'function' ? axis() : (axis ?? 'vertical');
19
+ }
20
+ function getHandle() {
21
+ const handle = options.handle;
22
+ return typeof handle === 'function' ? handle() : handle;
23
+ }
24
+ function isDisabled() {
25
+ return typeof options.disabled === 'function'
26
+ ? options.disabled()
27
+ : (options.disabled ?? false);
28
+ }
29
+ const context = {
30
+ groupId,
31
+ getItems,
32
+ getId,
33
+ onReorder,
34
+ isDisabled,
35
+ getAxis,
36
+ getHandle,
37
+ setDraggingId(id) {
38
+ draggingId = id;
39
+ }
40
+ };
41
+ setContext(SORTABLE_CONTEXT_KEY, context);
42
+ $effect(() => {
43
+ const node = listNode;
44
+ if (!node)
45
+ return;
46
+ if (draggingId != null) {
47
+ node.setAttribute('data-sortable-active', 'true');
48
+ }
49
+ else {
50
+ node.removeAttribute('data-sortable-active');
51
+ }
52
+ });
53
+ const container = (node) => {
54
+ listNode = node;
55
+ return {
56
+ destroy() {
57
+ if (listNode === node) {
58
+ listNode = null;
59
+ }
60
+ node.removeAttribute('data-sortable-active');
61
+ }
62
+ };
63
+ };
64
+ const item = (node, params) => {
65
+ let current = params;
66
+ const sortable = createSortable({
67
+ id: String(getId(current.item)),
68
+ index: current.index,
69
+ group: groupId,
70
+ data: current.item,
71
+ disabled: isDisabled()
72
+ });
73
+ const detach = sortable.attach(node);
74
+ let detachHandle;
75
+ function bindHandle() {
76
+ detachHandle?.();
77
+ const selector = getHandle();
78
+ if (!selector) {
79
+ sortable.sortable.handle = undefined;
80
+ detachHandle = undefined;
81
+ return;
82
+ }
83
+ const handle = node.querySelector(selector);
84
+ if (!handle) {
85
+ sortable.sortable.handle = undefined;
86
+ detachHandle = undefined;
87
+ return;
88
+ }
89
+ detachHandle = sortable.attachHandle(handle);
90
+ }
91
+ bindHandle();
92
+ node.setAttribute('data-sortable-item', '');
93
+ node.dataset.sortableId = String(getId(current.item));
94
+ return {
95
+ update(nextParams) {
96
+ current = nextParams;
97
+ sortable.sortable.id = String(getId(nextParams.item));
98
+ sortable.sortable.index = nextParams.index;
99
+ sortable.sortable.data = nextParams.item;
100
+ sortable.sortable.disabled = isDisabled();
101
+ node.dataset.sortableId = String(getId(nextParams.item));
102
+ bindHandle();
103
+ },
104
+ destroy() {
105
+ detach();
106
+ detachHandle?.();
107
+ node.removeAttribute('data-sortable-item');
108
+ delete node.dataset.sortableId;
109
+ }
110
+ };
111
+ };
112
+ return {
113
+ Provider: SortableProvider,
114
+ container,
115
+ item,
116
+ get draggingId() {
117
+ return draggingId;
118
+ }
119
+ };
120
+ }
package/dist/index.d.ts CHANGED
@@ -19,6 +19,7 @@ export * from './components/CodeBlock/index.js';
19
19
  export * from './components/Collapsible/index.js';
20
20
  export * from './components/ColorPicker/index.js';
21
21
  export * from './components/Command/index.js';
22
+ export * from './components/ConfirmDialog/index.js';
22
23
  export * from './components/Container/index.js';
23
24
  export * from './components/ContextMenu/index.js';
24
25
  export * from './components/DateRangePicker/index.js';
@@ -58,6 +59,7 @@ export * from './components/Sidebar/index.js';
58
59
  export * from './components/Skeleton/index.js';
59
60
  export * from './components/Slideover/index.js';
60
61
  export * from './components/Slider/index.js';
62
+ export * from './components/SortableList/index.js';
61
63
  export * from './components/Spotlight/index.js';
62
64
  export * from './components/Stepper/index.js';
63
65
  export * from './components/Switch/index.js';
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ export * from './components/CodeBlock/index.js';
20
20
  export * from './components/Collapsible/index.js';
21
21
  export * from './components/ColorPicker/index.js';
22
22
  export * from './components/Command/index.js';
23
+ export * from './components/ConfirmDialog/index.js';
23
24
  export * from './components/Container/index.js';
24
25
  export * from './components/ContextMenu/index.js';
25
26
  export * from './components/DateRangePicker/index.js';
@@ -59,6 +60,7 @@ export * from './components/Sidebar/index.js';
59
60
  export * from './components/Skeleton/index.js';
60
61
  export * from './components/Slideover/index.js';
61
62
  export * from './components/Slider/index.js';
63
+ export * from './components/SortableList/index.js';
62
64
  export * from './components/Spotlight/index.js';
63
65
  export * from './components/Stepper/index.js';
64
66
  export * from './components/Switch/index.js';