@lavalogic/scoria 0.40.0 → 0.40.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -58
- package/dist/Components/AccordionGroup.svelte +46 -46
- package/dist/Components/AccordionGroupButton.svelte +76 -76
- package/dist/Components/Action.svelte +136 -136
- package/dist/Components/AlertModal.svelte +195 -195
- package/dist/Components/AppointmentCalendar/AppointmentCalendar.svelte +729 -729
- package/dist/Components/Base/BaseModal.svelte +125 -125
- package/dist/Components/Base/ContextWrapper.svelte +72 -72
- package/dist/Components/Base/Pagination.svelte +198 -198
- package/dist/Components/Base/Snippets.svelte +36 -36
- package/dist/Components/BigRadioSet.svelte +38 -38
- package/dist/Components/Bubble.svelte +101 -101
- package/dist/Components/Button.svelte +209 -209
- package/dist/Components/Checkbox.svelte +86 -86
- package/dist/Components/CollapsibleCard.svelte +78 -78
- package/dist/Components/Contexts/ContextMenu.svelte +164 -164
- package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
- package/dist/Components/Contexts/ContextMenuOption.svelte +60 -60
- package/dist/Components/Contexts/Toast.svelte +86 -86
- package/dist/Components/Contexts/ToastContainer.svelte +65 -65
- package/dist/Components/Contexts/Tooltip.svelte +37 -37
- package/dist/Components/DataMatrixIcon.svelte +112 -112
- package/dist/Components/DateInput.svelte +148 -148
- package/dist/Components/DatePicker.svelte +300 -300
- package/dist/Components/DesktopModal.svelte +90 -90
- package/dist/Components/Dial.svelte +204 -204
- package/dist/Components/DimensionInput.svelte +170 -170
- package/dist/Components/DragMenu/DragMenuHolder.svelte +119 -119
- package/dist/Components/DragMenu/DraggableCard.svelte +77 -77
- package/dist/Components/FileCard.svelte +24 -24
- package/dist/Components/FileUpload.svelte +236 -236
- package/dist/Components/GridInput.svelte +196 -196
- package/dist/Components/GridInputSet.svelte +29 -29
- package/dist/Components/HorizontalTabGroup.svelte +82 -82
- package/dist/Components/HorizontalTabGroupButton.svelte +44 -44
- package/dist/Components/Icon.svelte +128 -128
- package/dist/Components/Icons.js +357 -357
- package/dist/Components/InfoAlert.svelte +35 -35
- package/dist/Components/LoadingAnimation.svelte +29 -29
- package/dist/Components/LoadingModal.svelte +45 -45
- package/dist/Components/LoadingOverlay.svelte +25 -25
- package/dist/Components/Modal.svelte +258 -258
- package/dist/Components/MultiSelect.svelte +220 -220
- package/dist/Components/Nav/Nav.svelte +110 -110
- package/dist/Components/Nav/NavServiceMenuList.svelte +43 -43
- package/dist/Components/Nav/NavTab.svelte +62 -62
- package/dist/Components/Nav/ServiceMenuItem.svelte +112 -112
- package/dist/Components/Nav/ServicesNav.svelte +80 -80
- package/dist/Components/NumberInput.svelte +157 -157
- package/dist/Components/PageHeading.svelte +25 -25
- package/dist/Components/PasswordInput.svelte +88 -88
- package/dist/Components/Portal.svelte +36 -36
- package/dist/Components/ProgressBubble.svelte +107 -107
- package/dist/Components/QuerySelect.svelte +366 -366
- package/dist/Components/SingleSelect.svelte +250 -250
- package/dist/Components/StepButton.svelte +70 -70
- package/dist/Components/StepForm.svelte +140 -140
- package/dist/Components/Switch.svelte +69 -69
- package/dist/Components/Table/ARCHITECTURE.md +298 -298
- package/dist/Components/Table/Body/QuickSearchCell.svelte +679 -679
- package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +51 -51
- package/dist/Components/Table/Body/Rows/ColumnList.svelte +59 -59
- package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +454 -454
- package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +79 -79
- package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +185 -185
- package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +124 -124
- package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +131 -120
- package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +234 -234
- package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +105 -105
- package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +87 -87
- package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +126 -126
- package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +159 -159
- package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +246 -246
- package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +216 -216
- package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +252 -252
- package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +179 -179
- package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +221 -221
- package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +197 -197
- package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +190 -190
- package/dist/Components/Table/Body/Rows/TableRow.svelte +290 -290
- package/dist/Components/Table/Body/TableBody.svelte +155 -155
- package/dist/Components/Table/ColumnFactory.svelte.js +1 -0
- package/dist/Components/Table/Headers/HighlightAllHeader.svelte +41 -41
- package/dist/Components/Table/Headers/SelectAllHeader.svelte +30 -30
- package/dist/Components/Table/Headers/TableHead.svelte +415 -415
- package/dist/Components/Table/Misc/ColumnPanel.svelte +39 -39
- package/dist/Components/Table/Misc/ColumnPanelModal.svelte +39 -39
- package/dist/Components/Table/Misc/FilterInput.svelte +641 -641
- package/dist/Components/Table/Misc/FilterPanel.svelte +190 -190
- package/dist/Components/Table/Misc/FilterPanelModal.svelte +31 -31
- package/dist/Components/Table/Misc/ShareViewModal.svelte +291 -291
- package/dist/Components/Table/Misc/SidePanel.svelte +35 -35
- package/dist/Components/Table/Misc/TableConfigurationModal.svelte +644 -644
- package/dist/Components/Table/Misc/TableFooter.svelte +340 -340
- package/dist/Components/Table/Misc/TableHorizontalBar.svelte +140 -140
- package/dist/Components/Table/Misc/TableSidebar.svelte +200 -200
- package/dist/Components/Table/Misc/TableViewDropdown.svelte +105 -105
- package/dist/Components/Table/Misc/ToolboxPanel.svelte +100 -100
- package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +107 -107
- package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +192 -192
- package/dist/Components/Table/NestedTable.svelte +130 -130
- package/dist/Components/Table/Table.svelte +692 -692
- package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.d.ts +5 -0
- package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.js +3 -0
- package/dist/Components/Table/Types/Public/ColumnOptions.d.ts +10 -0
- package/dist/Components/Test/TestContextConsumer.svelte +13 -13
- package/dist/Components/TextArea.svelte +130 -130
- package/dist/Components/TextInput.svelte +176 -176
- package/dist/Components/ThreeStateRadio.svelte +131 -131
- package/dist/Components/Touch/BoolCard.svelte +45 -45
- package/dist/Components/Touch/DateModal.svelte +209 -209
- package/dist/Components/Touch/EditCard.svelte +59 -59
- package/dist/Components/Touch/InfoCard.svelte +31 -31
- package/dist/Components/Touch/InfoTextCard.svelte +28 -28
- package/dist/Components/Touch/ModalExplanation.svelte +17 -17
- package/dist/Components/Touch/NumberKeyboard.svelte +225 -225
- package/dist/Components/Touch/NumberModal.svelte +79 -79
- package/dist/Components/Touch/PlusMinusCard.svelte +46 -46
- package/dist/Components/Touch/SelectModal.svelte +127 -127
- package/dist/Components/Touch/SummaryCard.svelte +93 -93
- package/dist/Components/Touch/TextAreaModal.svelte +95 -95
- package/dist/Components/Touch/TextModal.svelte +106 -106
- package/dist/Components/Touch/TouchCard.svelte +33 -33
- package/dist/Components/Touch/TouchModal.svelte +274 -274
- package/dist/Components/Touch/UtilityButton.svelte +109 -109
- package/dist/Components/VerticalTabGroup.svelte +79 -79
- package/dist/Components/VerticalTabGroupButton.svelte +58 -58
- package/dist/Helpers/Datamatrix.d.ts +19 -19
- package/dist/Helpers/Datamatrix.js +291 -291
- package/dist/Types/Examples/ExampleModal.svelte +35 -35
- package/dist/scss/_basics.scss +12 -12
- package/dist/scss/_colours.scss +134 -134
- package/dist/scss/_mixins.scss +3392 -3392
- package/dist/scss/_motion.scss +57 -57
- package/dist/scss/_sizing.scss +85 -85
- package/dist/scss/_transitions.scss +8 -8
- package/package.json +1 -1
|
@@ -1,172 +1,172 @@
|
|
|
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;
|
|
45
|
-
}
|
|
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
|
-
|
|
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;
|
|
45
|
+
}
|
|
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
|
+
|
|
170
170
|
<style>input {
|
|
171
171
|
box-sizing: border-box;
|
|
172
172
|
height: 100%;
|
|
@@ -445,4 +445,4 @@ div.spacer {
|
|
|
445
445
|
.icon-container input:last-of-type {
|
|
446
446
|
border-radius: 0;
|
|
447
447
|
border-left-color: transparent;
|
|
448
|
-
}</style>
|
|
448
|
+
}</style>
|
|
@@ -1,121 +1,121 @@
|
|
|
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) {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
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
|
-
}
|
|
43
|
-
|
|
44
|
-
function consider(newItems: Array<Draggable<T>>) {
|
|
45
|
-
isDragging = true;
|
|
46
|
-
items = newItems;
|
|
47
|
-
}
|
|
48
|
-
function finalise(newItems: Array<Draggable<T>>) {
|
|
49
|
-
items = newItems;
|
|
50
|
-
isDragging = false;
|
|
51
|
-
onUpdate(items.map((it) => it.original));
|
|
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
|
-
|
|
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) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
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
|
+
}
|
|
43
|
+
|
|
44
|
+
function consider(newItems: Array<Draggable<T>>) {
|
|
45
|
+
isDragging = true;
|
|
46
|
+
items = newItems;
|
|
47
|
+
}
|
|
48
|
+
function finalise(newItems: Array<Draggable<T>>) {
|
|
49
|
+
items = newItems;
|
|
50
|
+
isDragging = false;
|
|
51
|
+
onUpdate(items.map((it) => it.original));
|
|
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
|
+
|
|
119
119
|
<style>.top-label {
|
|
120
120
|
position: absolute;
|
|
121
121
|
left: 0.5rem;
|
|
@@ -170,4 +170,4 @@ div.dnd {
|
|
|
170
170
|
flex: 1;
|
|
171
171
|
gap: 0.5rem;
|
|
172
172
|
padding: 0.5rem;
|
|
173
|
-
}</style>
|
|
173
|
+
}</style>
|