@lavalogic/scoria 0.40.13 → 0.40.15

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 (143) hide show
  1. package/README.md +58 -58
  2. package/dist/Components/AccordionGroup.svelte +35 -46
  3. package/dist/Components/AccordionGroupButton.svelte +68 -76
  4. package/dist/Components/Action.svelte +103 -135
  5. package/dist/Components/AlertModal.svelte +171 -190
  6. package/dist/Components/AppointmentCalendar/AppointmentCalendar.svelte +614 -697
  7. package/dist/Components/Base/BaseModal.svelte +90 -116
  8. package/dist/Components/Base/ContextWrapper.svelte +67 -72
  9. package/dist/Components/Base/Pagination.svelte +173 -196
  10. package/dist/Components/Base/Snippets.svelte +34 -36
  11. package/dist/Components/BigRadioSet.svelte +36 -38
  12. package/dist/Components/Bubble.svelte +78 -101
  13. package/dist/Components/Button.svelte +175 -208
  14. package/dist/Components/Checkbox.svelte +75 -86
  15. package/dist/Components/CollapsibleCard.svelte +72 -87
  16. package/dist/Components/CollapsibleMenuGroup.svelte +53 -57
  17. package/dist/Components/ConditionBuilder/ConditionBuilder.svelte +39 -64
  18. package/dist/Components/Contexts/ContextMenu.svelte +141 -156
  19. package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
  20. package/dist/Components/Contexts/ContextMenuOption.svelte +53 -60
  21. package/dist/Components/Contexts/Toast.svelte +81 -86
  22. package/dist/Components/Contexts/ToastContainer.svelte +58 -62
  23. package/dist/Components/Contexts/Tooltip.svelte +36 -37
  24. package/dist/Components/DataMatrixIcon.svelte +95 -108
  25. package/dist/Components/DateInput.svelte +118 -146
  26. package/dist/Components/DatePicker.svelte +255 -294
  27. package/dist/Components/DesktopModal.svelte +70 -90
  28. package/dist/Components/Dial.svelte +167 -197
  29. package/dist/Components/DimensionInput.svelte +124 -169
  30. package/dist/Components/DragMenu/DragMenuHolder.svelte +98 -114
  31. package/dist/Components/DragMenu/DraggableCard.svelte +64 -76
  32. package/dist/Components/FileCard.svelte +21 -24
  33. package/dist/Components/FileUpload.svelte +190 -225
  34. package/dist/Components/GridInput.svelte +159 -196
  35. package/dist/Components/GridInputSet.svelte +24 -29
  36. package/dist/Components/HorizontalTabGroup.svelte +73 -89
  37. package/dist/Components/HorizontalTabGroupButton.svelte +40 -44
  38. package/dist/Components/Icon.svelte +99 -128
  39. package/dist/Components/Icons.js +357 -357
  40. package/dist/Components/InfoAlert.svelte +35 -38
  41. package/dist/Components/LoadingAnimation.svelte +691 -755
  42. package/dist/Components/LoadingModal.svelte +36 -44
  43. package/dist/Components/LoadingOverlay.svelte +22 -26
  44. package/dist/Components/Modal.svelte +204 -254
  45. package/dist/Components/MultiSelect.svelte +186 -216
  46. package/dist/Components/Nav/Nav.svelte +94 -110
  47. package/dist/Components/Nav/NavServiceMenuList.svelte +57 -61
  48. package/dist/Components/Nav/NavTab.svelte +58 -62
  49. package/dist/Components/Nav/ServiceMenuItem.svelte +103 -111
  50. package/dist/Components/Nav/ServicesNav.svelte +72 -79
  51. package/dist/Components/NumberInput.svelte +121 -155
  52. package/dist/Components/OptionCards.svelte +62 -73
  53. package/dist/Components/PageHeading.svelte +23 -25
  54. package/dist/Components/PasswordInput.svelte +69 -88
  55. package/dist/Components/PopoverButton.svelte +151 -0
  56. package/dist/Components/PopoverButton.svelte.d.ts +9 -0
  57. package/dist/Components/PopoverButtonProps.d.ts +21 -0
  58. package/dist/Components/PopoverButtonProps.js +1 -0
  59. package/dist/Components/Portal.svelte +29 -35
  60. package/dist/Components/ProgressBubble.svelte +91 -106
  61. package/dist/Components/QuerySelect.svelte +260 -346
  62. package/dist/Components/SidebarPanel.svelte +34 -36
  63. package/dist/Components/SingleSelect.svelte +196 -244
  64. package/dist/Components/StepButton.svelte +65 -70
  65. package/dist/Components/StepForm.svelte +115 -135
  66. package/dist/Components/Switch.svelte +57 -69
  67. package/dist/Components/Table/ARCHITECTURE.md +298 -298
  68. package/dist/Components/Table/Body/QuickSearchCell.svelte +578 -655
  69. package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +42 -51
  70. package/dist/Components/Table/Body/Rows/ColumnList.svelte +42 -58
  71. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +403 -442
  72. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +51 -78
  73. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +165 -184
  74. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +110 -123
  75. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +134 -160
  76. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +190 -231
  77. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +82 -104
  78. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +52 -87
  79. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +122 -150
  80. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +132 -159
  81. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +190 -236
  82. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +173 -211
  83. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +204 -244
  84. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +140 -177
  85. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +188 -217
  86. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +173 -193
  87. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +166 -187
  88. package/dist/Components/Table/Body/Rows/TableRow.svelte +245 -288
  89. package/dist/Components/Table/Body/TableBody.svelte +141 -154
  90. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +35 -41
  91. package/dist/Components/Table/Headers/SelectAllHeader.svelte +24 -30
  92. package/dist/Components/Table/Headers/TableHead.svelte +348 -402
  93. package/dist/Components/Table/Misc/ColumnPanel.svelte +37 -39
  94. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +35 -39
  95. package/dist/Components/Table/Misc/FilterInput.svelte +556 -619
  96. package/dist/Components/Table/Misc/FilterPanel.svelte +170 -183
  97. package/dist/Components/Table/Misc/FilterPanelModal.svelte +25 -31
  98. package/dist/Components/Table/Misc/ShareViewModal.svelte +252 -281
  99. package/dist/Components/Table/Misc/SidePanel.svelte +32 -35
  100. package/dist/Components/Table/Misc/TableConfigurationModal.svelte +574 -629
  101. package/dist/Components/Table/Misc/TableFooter.svelte +326 -332
  102. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +134 -140
  103. package/dist/Components/Table/Misc/TableSidebar.svelte +183 -198
  104. package/dist/Components/Table/Misc/TableViewDropdown.svelte +83 -103
  105. package/dist/Components/Table/Misc/ToolboxPanel.svelte +83 -100
  106. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +88 -107
  107. package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +163 -190
  108. package/dist/Components/Table/NestedTable.svelte +102 -128
  109. package/dist/Components/Table/Table.svelte +531 -663
  110. package/dist/Components/Test/TestContextConsumer.svelte +11 -13
  111. package/dist/Components/TextArea.svelte +95 -130
  112. package/dist/Components/TextInput.svelte +125 -176
  113. package/dist/Components/ThreeStateRadio.svelte +111 -130
  114. package/dist/Components/Touch/BoolCard.svelte +33 -45
  115. package/dist/Components/Touch/DateModal.svelte +164 -204
  116. package/dist/Components/Touch/EditCard.svelte +48 -59
  117. package/dist/Components/Touch/InfoCard.svelte +28 -31
  118. package/dist/Components/Touch/InfoTextCard.svelte +26 -28
  119. package/dist/Components/Touch/ModalExplanation.svelte +15 -17
  120. package/dist/Components/Touch/NumberKeyboard.svelte +181 -218
  121. package/dist/Components/Touch/NumberModal.svelte +59 -79
  122. package/dist/Components/Touch/PlusMinusCard.svelte +43 -46
  123. package/dist/Components/Touch/SelectModal.svelte +111 -126
  124. package/dist/Components/Touch/SummaryCard.svelte +80 -93
  125. package/dist/Components/Touch/TextAreaModal.svelte +72 -94
  126. package/dist/Components/Touch/TextModal.svelte +77 -105
  127. package/dist/Components/Touch/TouchCard.svelte +31 -33
  128. package/dist/Components/Touch/TouchModal.svelte +214 -270
  129. package/dist/Components/Touch/UtilityButton.svelte +88 -109
  130. package/dist/Components/VerticalTabGroup.svelte +60 -78
  131. package/dist/Components/VerticalTabGroupButton.svelte +54 -58
  132. package/dist/Helpers/Datamatrix.d.ts +19 -19
  133. package/dist/Helpers/Datamatrix.js +291 -291
  134. package/dist/Types/Examples/ExampleModal.svelte +31 -35
  135. package/dist/index.d.ts +2 -0
  136. package/dist/index.js +1 -0
  137. package/dist/scss/_basics.scss +12 -12
  138. package/dist/scss/_colours.scss +134 -134
  139. package/dist/scss/_mixins.scss +3392 -3392
  140. package/dist/scss/_motion.scss +57 -57
  141. package/dist/scss/_sizing.scss +85 -85
  142. package/dist/scss/_transitions.scss +8 -8
  143. package/package.json +1 -1
@@ -1,172 +1,127 @@
1
- <svelte:options runes />
2
-
3
- <script lang="ts">
4
- import { InputVariant } from '../Types/Internal/InputVariant.js';
5
- import type { Centimetres } from '../Types/Internal/Misc.js';
6
- import type { DimensionInputProps } from './DimensionInputProps.js';
7
-
8
- const min = 0;
9
- let {
10
- id,
11
- x = $bindable(null),
12
- y = $bindable(null),
13
- z = $bindable(null),
14
-
15
- max,
16
- labelTop = 'Dimensions',
17
- optional = true,
18
- placeholder,
19
- required = false,
20
- variant = InputVariant.Default,
21
- decimal = false,
22
- invalid = false,
23
- showErrorColours = false,
24
- disabled,
25
-
26
- leftIcon,
27
-
28
- onblur,
29
- onfocus,
30
- onkeydown,
31
- // oninput intentionally not forwarded; per-axis handleInput wires it.
32
- onchange,
33
-
34
- inputRefs = $bindable({}),
35
- 'data-type': dataType,
36
- }: DimensionInputProps = $props();
37
-
38
- function clamp(value: number): Centimetres {
39
- if (isNaN(value)) {
40
- return 0 as Centimetres;
41
- }
42
- const underMinimum = min > value;
43
- const overMaximum = max != undefined && max < value;
44
- return (underMinimum ? min : overMaximum ? max : value) as Centimetres;
1
+ <svelte:options runes />
2
+
3
+ <script lang="ts">import { InputVariant } from "../Types/Internal/InputVariant.js";
4
+ const min = 0;
5
+ let { id, x = $bindable(null), y = $bindable(null), z = $bindable(null), max, labelTop = "Dimensions", optional = true, placeholder, required = false, variant = InputVariant.Default, decimal = false, invalid = false, showErrorColours = false, disabled, leftIcon, onblur, onfocus, onkeydown, onchange, inputRefs = $bindable({}), "data-type": dataType } = $props();
6
+ function clamp(value) {
7
+ if (isNaN(value)) {
8
+ return 0;
45
9
  }
46
-
47
- function handleInput(axis: 'x' | 'y' | 'z') {
48
- return (e: Event) => {
49
- const target = e.target as HTMLInputElement;
50
- const raw = target.value;
51
- const parsed = raw === '' ? null : clamp(Number(raw));
52
- if (axis === 'x') {
53
- x = parsed;
54
- } else if (axis === 'y') {
55
- y = parsed;
56
- } else {
57
- z = parsed;
58
- }
59
- onchange?.(axis, parsed);
60
- };
61
- }
62
-
63
- const isInvalid = $derived(
64
- showErrorColours &&
65
- ((required &&
66
- (x == null ||
67
- x.toString().trim() === '' ||
68
- y == null ||
69
- y.toString().trim() === '' ||
70
- z == null ||
71
- z.toString().trim() === '')) ||
72
- invalid)
73
- );
74
-
75
- const xId = $derived(id ? `${id}-x` : undefined);
76
- const yId = $derived(id ? `${id}-y` : undefined);
77
- const zId = $derived(id ? `${id}-z` : undefined);
78
- </script>
79
-
80
- <div
81
- class="error-wrapper"
82
- class:for-modal={variant == InputVariant.Modal}
83
- class:for-table={variant == InputVariant.Table}
84
- >
85
- <span
86
- class="top-label"
87
- class:for-default={variant === InputVariant.Default}
88
- class:invalid={isInvalid}
89
- >{labelTop}{#if optional}
90
- - <span class="optional">optional</span>{/if}</span
91
- >
92
- {#if variant === InputVariant.Default}
93
- <span class="border"
94
- >{labelTop}{#if optional}
95
- - <span class="optional">optional</span>{/if}</span
96
- >
97
- {/if}
98
- <div
99
- class="icon-container"
100
- class:for-modal={variant == InputVariant.Modal}
101
- >
102
- <input
103
- id={xId}
104
- class:for-default={variant === InputVariant.Default}
105
- data-type={dataType}
106
- class:left-pad={leftIcon != undefined}
107
- class:for-modal={variant == InputVariant.Modal}
108
- type="number"
109
- value={x ?? ''}
110
- oninput={handleInput('x')}
111
- {onblur}
112
- {onfocus}
113
- {onkeydown}
114
- bind:this={inputRefs.x}
115
- {placeholder}
116
- {required}
117
- {disabled}
118
- {min}
119
- {max}
120
- step={decimal ? 0.01 : 1}
121
- />
122
- <input
123
- id={yId}
124
- class:for-default={variant === InputVariant.Default}
125
- data-type={dataType}
126
- class:left-pad={leftIcon != undefined}
127
- class:for-modal={variant == InputVariant.Modal}
128
- type="number"
129
- value={y ?? ''}
130
- oninput={handleInput('y')}
131
- {onblur}
132
- {onfocus}
133
- {onkeydown}
134
- bind:this={inputRefs.y}
135
- {placeholder}
136
- {required}
137
- {disabled}
138
- {min}
139
- {max}
140
- step={decimal ? 0.01 : 1}
141
- />
142
- <input
143
- id={zId}
144
- class:for-default={variant === InputVariant.Default}
145
- data-type={dataType}
146
- class:left-pad={leftIcon != undefined}
147
- class:for-modal={variant == InputVariant.Modal}
148
- type="number"
149
- value={z ?? ''}
150
- oninput={handleInput('z')}
151
- {onblur}
152
- {onfocus}
153
- {onkeydown}
154
- bind:this={inputRefs.z}
155
- {placeholder}
156
- {required}
157
- {disabled}
158
- {min}
159
- {max}
160
- step={decimal ? 0.01 : 1}
161
- />
162
- <div class="spacer"></div>
163
- <span
164
- class="right-label inset"
165
- class:for-modal={variant == InputVariant.Modal}>cm</span
166
- >
167
- </div>
168
- </div>
169
-
10
+ const underMinimum = min > value;
11
+ const overMaximum = max != undefined && max < value;
12
+ return underMinimum ? min : overMaximum ? max : value;
13
+ }
14
+ function handleInput(axis) {
15
+ return (e) => {
16
+ const target = e.target;
17
+ const raw = target.value;
18
+ const parsed = raw === "" ? null : clamp(Number(raw));
19
+ if (axis === "x") {
20
+ x = parsed;
21
+ } else if (axis === "y") {
22
+ y = parsed;
23
+ } else {
24
+ z = parsed;
25
+ }
26
+ onchange?.(axis, parsed);
27
+ };
28
+ }
29
+ const isInvalid = $derived(showErrorColours && (required && (x == null || x.toString().trim() === "" || y == null || y.toString().trim() === "" || z == null || z.toString().trim() === "") || invalid));
30
+ const xId = $derived(id ? `${id}-x` : undefined);
31
+ const yId = $derived(id ? `${id}-y` : undefined);
32
+ const zId = $derived(id ? `${id}-z` : undefined);
33
+ </script>
34
+
35
+ <div
36
+ class="error-wrapper"
37
+ class:for-modal={variant == InputVariant.Modal}
38
+ class:for-table={variant == InputVariant.Table}
39
+ >
40
+ <span
41
+ class="top-label"
42
+ class:for-default={variant === InputVariant.Default}
43
+ class:invalid={isInvalid}
44
+ >{labelTop}{#if optional}
45
+ - <span class="optional">optional</span>{/if}</span
46
+ >
47
+ {#if variant === InputVariant.Default}
48
+ <span class="border"
49
+ >{labelTop}{#if optional}
50
+ - <span class="optional">optional</span>{/if}</span
51
+ >
52
+ {/if}
53
+ <div
54
+ class="icon-container"
55
+ class:for-modal={variant == InputVariant.Modal}
56
+ >
57
+ <input
58
+ id={xId}
59
+ class:for-default={variant === InputVariant.Default}
60
+ data-type={dataType}
61
+ class:left-pad={leftIcon != undefined}
62
+ class:for-modal={variant == InputVariant.Modal}
63
+ type="number"
64
+ value={x ?? ''}
65
+ oninput={handleInput('x')}
66
+ {onblur}
67
+ {onfocus}
68
+ {onkeydown}
69
+ bind:this={inputRefs.x}
70
+ {placeholder}
71
+ {required}
72
+ {disabled}
73
+ {min}
74
+ {max}
75
+ step={decimal ? 0.01 : 1}
76
+ />
77
+ <input
78
+ id={yId}
79
+ class:for-default={variant === InputVariant.Default}
80
+ data-type={dataType}
81
+ class:left-pad={leftIcon != undefined}
82
+ class:for-modal={variant == InputVariant.Modal}
83
+ type="number"
84
+ value={y ?? ''}
85
+ oninput={handleInput('y')}
86
+ {onblur}
87
+ {onfocus}
88
+ {onkeydown}
89
+ bind:this={inputRefs.y}
90
+ {placeholder}
91
+ {required}
92
+ {disabled}
93
+ {min}
94
+ {max}
95
+ step={decimal ? 0.01 : 1}
96
+ />
97
+ <input
98
+ id={zId}
99
+ class:for-default={variant === InputVariant.Default}
100
+ data-type={dataType}
101
+ class:left-pad={leftIcon != undefined}
102
+ class:for-modal={variant == InputVariant.Modal}
103
+ type="number"
104
+ value={z ?? ''}
105
+ oninput={handleInput('z')}
106
+ {onblur}
107
+ {onfocus}
108
+ {onkeydown}
109
+ bind:this={inputRefs.z}
110
+ {placeholder}
111
+ {required}
112
+ {disabled}
113
+ {min}
114
+ {max}
115
+ step={decimal ? 0.01 : 1}
116
+ />
117
+ <div class="spacer"></div>
118
+ <span
119
+ class="right-label inset"
120
+ class:for-modal={variant == InputVariant.Modal}>cm</span
121
+ >
122
+ </div>
123
+ </div>
124
+
170
125
  <style>input {
171
126
  box-sizing: border-box;
172
127
  height: 100%;
@@ -445,4 +400,4 @@ div.spacer {
445
400
  .icon-container input:last-of-type {
446
401
  border-radius: 0;
447
402
  border-left-color: transparent;
448
- }</style>
403
+ }</style>
@@ -1,121 +1,105 @@
1
- <svelte:options runes />
2
-
3
- <script
4
- lang="ts"
5
- generics="T"
6
- >
7
- import { type DndEvent, dndzone } from 'svelte-dnd-action';
8
- import { flip } from 'svelte/animate';
9
- import type { DragMenuHolderProps } from './DragMenuHolderProps.js';
10
- import type { Draggable } from './Draggable.js';
11
- import DraggableCard from './DraggableCard.svelte';
12
-
13
- const {
14
- items: originalItems,
15
- onUpdate,
16
- snippet: customSnippet,
17
- transformToDraggable,
18
- flipDurationMS = 60,
19
- label,
20
- }: DragMenuHolderProps<T> = $props();
21
-
22
- let items: Array<Draggable<T>> = $state([]);
23
- /**
24
- * `true` between `consider` and `finalise` events from dndzone.
25
- * While true we suppress the `originalItems -> items` sync effect
26
- * so an unrelated parent mutation cannot replace the user's
27
- * in-progress drag state.
28
- */
29
- let isDragging = $state(false);
30
-
31
- /** Compare two id sequences. Used to skip the sync effect when nothing changed. */
32
- function sameIdSequence(a: ReadonlyArray<Draggable<T>>, b: ReadonlyArray<Draggable<T>>): boolean {
33
- if (a.length !== b.length) {
1
+ <svelte:options runes />
2
+
3
+ <script
4
+ lang="ts"
5
+ generics="T"
6
+ >import { dndzone } from "svelte-dnd-action";
7
+ import { flip } from "svelte/animate";
8
+ import DraggableCard from "./DraggableCard.svelte";
9
+ const { items: originalItems, onUpdate, snippet: customSnippet, transformToDraggable, flipDurationMS = 60, label } = $props();
10
+ let items = $state([]);
11
+ /**
12
+ * `true` between `consider` and `finalise` events from dndzone.
13
+ * While true we suppress the `originalItems -> items` sync effect
14
+ * so an unrelated parent mutation cannot replace the user's
15
+ * in-progress drag state.
16
+ */
17
+ let isDragging = $state(false);
18
+ /** Compare two id sequences. Used to skip the sync effect when nothing changed. */
19
+ function sameIdSequence(a, b) {
20
+ if (a.length !== b.length) {
21
+ return false;
22
+ }
23
+ for (let i = 0; i < a.length; i++) {
24
+ if (a[i].id !== b[i].id) {
34
25
  return false;
35
26
  }
36
- for (let i = 0; i < a.length; i++) {
37
- if (a[i].id !== b[i].id) {
38
- return false;
39
- }
40
- }
41
- return true;
42
27
  }
43
-
44
- function consider(newItems: Array<Draggable<T>>) {
45
- isDragging = true;
46
- items = newItems;
28
+ return true;
29
+ }
30
+ function consider(newItems) {
31
+ isDragging = true;
32
+ items = newItems;
33
+ }
34
+ function finalise(newItems) {
35
+ items = newItems;
36
+ isDragging = false;
37
+ onUpdate(items.map((it) => it.original));
38
+ }
39
+ $effect.pre(() => {
40
+ // Re-establish the dependency on the source array.
41
+ const next = originalItems.map(transformToDraggable);
42
+ // Skip when a drag is in progress so the user's transient
43
+ // ordering is not clobbered by an unrelated parent mutation.
44
+ if (isDragging) {
45
+ return;
47
46
  }
48
- function finalise(newItems: Array<Draggable<T>>) {
49
- items = newItems;
50
- isDragging = false;
51
- onUpdate(items.map((it) => it.original));
47
+ // Skip when the logical content is unchanged. Prevents flicker
48
+ // when the parent recreates the array reference with the same
49
+ // items (e.g. an unrelated `$derived` invalidation).
50
+ if (sameIdSequence(items, next)) {
51
+ return;
52
52
  }
53
-
54
- $effect.pre(() => {
55
- // Re-establish the dependency on the source array.
56
- const next = originalItems.map(transformToDraggable);
57
- // Skip when a drag is in progress so the user's transient
58
- // ordering is not clobbered by an unrelated parent mutation.
59
- if (isDragging) {
60
- return;
61
- }
62
- // Skip when the logical content is unchanged. Prevents flicker
63
- // when the parent recreates the array reference with the same
64
- // items (e.g. an unrelated `$derived` invalidation).
65
- if (sameIdSequence(items, next)) {
66
- return;
67
- }
68
- items = next;
69
- });
70
-
71
- const snippet = $derived(customSnippet ?? draggableWithSelect);
72
- </script>
73
-
74
- {#snippet draggableWithSelect<T>(item: Draggable<T>, index: number)}
75
- <DraggableCard
76
- title={item.title}
77
- subtitle={item.subtitle}
78
- {index}
79
- selectable
80
- selected={item.selected}
81
- />
82
- {/snippet}
83
-
84
- <div class="wrapper">
85
- {#if label}
86
- <span class="top-label">{label}</span>
87
- <span class="top-label-border">{label}</span>
88
- {/if}
89
- <div
90
- class="dnd"
91
- use:dndzone={{ items, flipDurationMs: flipDurationMS, delayTouchStart: 30 }}
92
- onconsider={(e: CustomEvent<DndEvent<Draggable<T>>>) => {
93
- consider(e.detail.items);
94
- }}
95
- onfinalize={(e: CustomEvent<DndEvent<Draggable<T>>>) => {
96
- finalise(e.detail.items);
97
- }}
98
- >
99
- <!-- svelte-ignore a11y_no_static_element_interactions -->
100
- {#each items as item, index (item.id)}
101
- <!-- svelte-ignore a11y_click_events_have_key_events -->
102
- <div
103
- class="contents"
104
- onclick={(e) => {
105
- if (item.toggleSelected) {
106
- e.stopPropagation();
107
- item.toggleSelected();
108
- }
109
- }}
110
- animate:flip={{ duration: flipDurationMS }}
111
- >
112
- <!-- eslint-disable-next-line @typescript-eslint/no-confusing-void-expression -->
113
- {@render snippet(item, index)}
114
- </div>
115
- {/each}
116
- </div>
117
- </div>
118
-
53
+ items = next;
54
+ });
55
+ const snippet = $derived(customSnippet ?? draggableWithSelect);
56
+ </script>
57
+
58
+ {#snippet draggableWithSelect<T>(item: Draggable<T>, index: number)}
59
+ <DraggableCard
60
+ title={item.title}
61
+ subtitle={item.subtitle}
62
+ {index}
63
+ selectable
64
+ selected={item.selected}
65
+ />
66
+ {/snippet}
67
+
68
+ <div class="wrapper">
69
+ {#if label}
70
+ <span class="top-label">{label}</span>
71
+ <span class="top-label-border">{label}</span>
72
+ {/if}
73
+ <div
74
+ class="dnd"
75
+ use:dndzone={{ items, flipDurationMs: flipDurationMS, delayTouchStart: 30 }}
76
+ onconsider={(e: CustomEvent<DndEvent<Draggable<T>>>) => {
77
+ consider(e.detail.items);
78
+ }}
79
+ onfinalize={(e: CustomEvent<DndEvent<Draggable<T>>>) => {
80
+ finalise(e.detail.items);
81
+ }}
82
+ >
83
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
84
+ {#each items as item, index (item.id)}
85
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
86
+ <div
87
+ class="contents"
88
+ onclick={(e) => {
89
+ if (item.toggleSelected) {
90
+ e.stopPropagation();
91
+ item.toggleSelected();
92
+ }
93
+ }}
94
+ animate:flip={{ duration: flipDurationMS }}
95
+ >
96
+ <!-- eslint-disable-next-line @typescript-eslint/no-confusing-void-expression -->
97
+ {@render snippet(item, index)}
98
+ </div>
99
+ {/each}
100
+ </div>
101
+ </div>
102
+
119
103
  <style>.top-label {
120
104
  position: absolute;
121
105
  left: 0.5rem;
@@ -170,4 +154,4 @@ div.dnd {
170
154
  flex: 1;
171
155
  gap: 0.5rem;
172
156
  padding: 0.5rem;
173
- }</style>
157
+ }</style>