@lavalogic/scoria 0.38.12 → 0.38.13
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/dist/Components/AccordionGroup.svelte +46 -46
- package/dist/Components/AccordionGroupButton.svelte +76 -76
- package/dist/Components/Action.svelte +136 -136
- package/dist/Components/AppointmentCalendar/AppointmentCalendar.svelte +712 -702
- 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/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/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/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/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/NavServiceMenuList.svelte +43 -43
- package/dist/Components/Nav/NavTab.svelte +62 -62
- 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/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/Body/Rows/ColumnHighlight.svelte +51 -51
- package/dist/Components/Table/Body/Rows/ColumnList.svelte +59 -59
- package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +79 -79
- package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +120 -120
- 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/TableRowSelectionCheckbox.svelte +179 -179
- 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/Headers/HighlightAllHeader.svelte +41 -41
- package/dist/Components/Table/Headers/SelectAllHeader.svelte +30 -30
- package/dist/Components/Table/Misc/SidePanel.svelte +35 -35
- package/dist/Components/Table/Misc/ToolboxPanel.svelte +100 -100
- package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +107 -107
- 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/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/_motion.scss +57 -57
- package/dist/scss/_sizing.scss +85 -85
- package/package.json +30 -30
|
@@ -1,276 +1,276 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
module
|
|
5
|
-
lang="ts"
|
|
6
|
-
>
|
|
7
|
-
import { browser } from '$app/environment';
|
|
8
|
-
import { DATAMatrix } from '../../Helpers/Datamatrix.js';
|
|
9
|
-
import { useAsyncFlag } from '../../Helpers/AsyncFlag.svelte.js';
|
|
10
|
-
import { passthrough } from '../../Helpers/Helpers.svelte.js';
|
|
11
|
-
import { ColourSet } from '../../scss/colours.js';
|
|
12
|
-
import { Size } from '../../Types/Internal/Size.js';
|
|
13
|
-
import { onMount } from 'svelte';
|
|
14
|
-
import Action from '../Action.svelte';
|
|
15
|
-
import BaseModal from '../Base/BaseModal.svelte';
|
|
16
|
-
import DataMatrixIcon from '../DataMatrixIcon.svelte';
|
|
17
|
-
import type { TouchModalProps } from './TouchModalProps.js';
|
|
18
|
-
</script>
|
|
19
|
-
|
|
20
|
-
<script lang="ts">
|
|
21
|
-
let {
|
|
22
|
-
header,
|
|
23
|
-
buttons,
|
|
24
|
-
mandatory = false,
|
|
25
|
-
staticHeight = false,
|
|
26
|
-
staticWidth = false,
|
|
27
|
-
minWidth = '400px',
|
|
28
|
-
minHeight = '280px',
|
|
29
|
-
width,
|
|
30
|
-
height,
|
|
31
|
-
onShowCallback,
|
|
32
|
-
defaultTimer,
|
|
33
|
-
isValid = true,
|
|
34
|
-
noscroll = false,
|
|
35
|
-
onsubmit,
|
|
36
|
-
headerExtra,
|
|
37
|
-
explanation,
|
|
38
|
-
children,
|
|
39
|
-
footer,
|
|
40
|
-
onclose,
|
|
41
|
-
row,
|
|
42
|
-
wrap,
|
|
43
|
-
submitRef = $bindable(),
|
|
44
|
-
}: TouchModalProps = $props();
|
|
45
|
-
|
|
46
|
-
let open = $state(true);
|
|
47
|
-
let form: HTMLFormElement | undefined = $state();
|
|
48
|
-
let timeout: ReturnType<typeof setTimeout> | undefined = undefined;
|
|
49
|
-
let paused = $state(false);
|
|
50
|
-
let isActive = $state(false);
|
|
51
|
-
|
|
52
|
-
// Pre-compute barcode SVGs once per `buttons` array. Building a DataMatrix
|
|
53
|
-
// barcode is non-trivial; rebuilding inside the each-block re-runs the
|
|
54
|
-
// encoder on every render.
|
|
55
|
-
//
|
|
56
|
-
// `DATAMatrix` calls `document.createElement` internally, which is
|
|
57
|
-
// undefined during SvelteKit's server render. Returning `null` on the
|
|
58
|
-
// server keeps the SVG slots empty for SSR; the client re-renders with
|
|
59
|
-
// the real encoded payload after hydration.
|
|
60
|
-
const barcodeIcons = $derived.by(
|
|
61
|
-
() =>
|
|
62
|
-
buttons?.map((b) =>
|
|
63
|
-
b.barcodeValue != null && browser ? DATAMatrix(b.barcodeValue) : null
|
|
64
|
-
) ?? []
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
// Resolve each button's `isValid` once at the component level rather than
|
|
68
|
-
// inside the each-block. `useAsyncFlag` debounces stale resolutions, holds
|
|
69
|
-
// the previous value until a new Promise settles, and stops the
|
|
70
|
-
// `{#await}` flicker the previous implementation exhibited.
|
|
71
|
-
const buttonValidities = useAsyncFlag(
|
|
72
|
-
() => Promise.all((buttons ?? []).map((b) => Promise.resolve(b.isValid ?? true))),
|
|
73
|
-
[] as Array<boolean>
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
onMount(() => {
|
|
77
|
-
queueMicrotask(() => {
|
|
78
|
-
onShowCallback?.();
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
const activeTimer = setTimeout(() => {
|
|
82
|
-
isActive = true;
|
|
83
|
-
}, 200);
|
|
84
|
-
|
|
85
|
-
if (defaultTimer) {
|
|
86
|
-
timeout = setTimeout(() => {
|
|
87
|
-
if (open) {
|
|
88
|
-
if (defaultTimer.action === 'submit') {
|
|
89
|
-
form?.requestSubmit();
|
|
90
|
-
defaultTimer.callback?.();
|
|
91
|
-
} else {
|
|
92
|
-
open = false;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}, defaultTimer.time);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return () => {
|
|
99
|
-
clearTimeout(activeTimer);
|
|
100
|
-
clearTimer();
|
|
101
|
-
};
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
function clearTimer() {
|
|
105
|
-
if (timeout != undefined) {
|
|
106
|
-
paused = true;
|
|
107
|
-
clearTimeout(timeout);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function handleEsc(e: KeyboardEvent) {
|
|
112
|
-
if (e.key === 'Escape') {
|
|
113
|
-
e.preventDefault();
|
|
114
|
-
if (!mandatory) {
|
|
115
|
-
open = false;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function requestClose() {
|
|
121
|
-
open = false;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const dialogClassNames = $derived(
|
|
125
|
-
[
|
|
126
|
-
staticHeight ? 'static-height' : null,
|
|
127
|
-
staticWidth ? 'static-width' : null,
|
|
128
|
-
noscroll ? 'noscroll' : null,
|
|
129
|
-
]
|
|
130
|
-
.filter((c): c is string => c !== null)
|
|
131
|
-
.join(' ')
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
const dialogStyle = $derived(
|
|
135
|
-
`--timer: ${defaultTimer ? defaultTimer.time.toString() + 'ms' : 'unset'};` +
|
|
136
|
-
`--dialog-min-width: ${minWidth};` +
|
|
137
|
-
`--dialog-min-height: ${minHeight};` +
|
|
138
|
-
(height != null ? `--dialog-height: ${height};` : '') +
|
|
139
|
-
(width != null ? `--dialog-width: ${width};` : '')
|
|
140
|
-
);
|
|
141
|
-
</script>
|
|
142
|
-
|
|
143
|
-
<BaseModal
|
|
144
|
-
bind:value={open}
|
|
145
|
-
{onclose}
|
|
146
|
-
{mandatory}
|
|
147
|
-
dialogClass={dialogClassNames}
|
|
148
|
-
{dialogStyle}
|
|
149
|
-
>
|
|
150
|
-
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
151
|
-
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
152
|
-
<form
|
|
153
|
-
method="dialog"
|
|
154
|
-
bind:this={form}
|
|
155
|
-
onsubmit={(e) => {
|
|
156
|
-
e.preventDefault();
|
|
157
|
-
clearTimer();
|
|
158
|
-
if (isActive) {
|
|
159
|
-
onsubmit?.(e);
|
|
160
|
-
}
|
|
161
|
-
}}
|
|
162
|
-
onclick={clearTimer}
|
|
163
|
-
class="modal-root"
|
|
164
|
-
>
|
|
165
|
-
<div class="modal-header">
|
|
166
|
-
{#if mandatory}
|
|
167
|
-
<div class="title-wrapper">
|
|
168
|
-
<h3 class="modal-heading">{header}</h3>
|
|
169
|
-
</div>
|
|
170
|
-
{:else}
|
|
171
|
-
<div class="title-wrapper">
|
|
172
|
-
<h3 class="modal-heading padded">{header}</h3>
|
|
173
|
-
<div class="close-button">
|
|
174
|
-
<Action
|
|
175
|
-
size={Size.Large}
|
|
176
|
-
onclick={requestClose}
|
|
177
|
-
icon={{
|
|
178
|
-
name: 'cross',
|
|
179
|
-
size: Size.DoubleXLarge,
|
|
180
|
-
}}
|
|
181
|
-
onkeydown={handleEsc}
|
|
182
|
-
colourSet={ColourSet.Primary}
|
|
183
|
-
label="Close Modal"
|
|
184
|
-
/>
|
|
185
|
-
</div>
|
|
186
|
-
</div>
|
|
187
|
-
{/if}
|
|
188
|
-
|
|
189
|
-
{#if headerExtra}
|
|
190
|
-
{@render headerExtra()}
|
|
191
|
-
{/if}
|
|
192
|
-
</div>
|
|
193
|
-
|
|
194
|
-
{#if defaultTimer}
|
|
195
|
-
<div class="bar-container">
|
|
196
|
-
<div
|
|
197
|
-
class:paused
|
|
198
|
-
class="bar-timer"
|
|
199
|
-
></div>
|
|
200
|
-
</div>
|
|
201
|
-
{/if}
|
|
202
|
-
|
|
203
|
-
<div
|
|
204
|
-
class="modal-main"
|
|
205
|
-
class:row
|
|
206
|
-
class:wrap
|
|
207
|
-
class:noscroll
|
|
208
|
-
>
|
|
209
|
-
{#if explanation}
|
|
210
|
-
{@render explanation()}
|
|
211
|
-
{/if}
|
|
212
|
-
{@render children()}
|
|
213
|
-
</div>
|
|
214
|
-
|
|
215
|
-
{#if footer}
|
|
216
|
-
{@render footer()}
|
|
217
|
-
{:else if buttons?.length}
|
|
218
|
-
<div class="modal-footer">
|
|
219
|
-
{#each buttons as button, index (button.label)}
|
|
220
|
-
{@const buttonIsValid = buttonValidities.value[index] ?? true}
|
|
221
|
-
{#if button.callback}
|
|
222
|
-
<div class="button-barcode-set">
|
|
223
|
-
{#if barcodeIcons[index]}
|
|
224
|
-
<DataMatrixIcon
|
|
225
|
-
title={button.label}
|
|
226
|
-
icon={{ kind: 'svg', svg: barcodeIcons[index] }}
|
|
227
|
-
/>
|
|
228
|
-
{/if}
|
|
229
|
-
<button
|
|
230
|
-
class:call-to-action={button.colourSet === ColourSet.CallToAction}
|
|
231
|
-
class:primary={button.colourSet === ColourSet.Primary}
|
|
232
|
-
class:secondary-colour={button.colourSet === ColourSet.Secondary}
|
|
233
|
-
class:warning={button.colourSet === ColourSet.Warning}
|
|
234
|
-
class:error={button.colourSet === ColourSet.Error}
|
|
235
|
-
class:info={button.colourSet === ColourSet.Info}
|
|
236
|
-
onkeydown={passthrough}
|
|
237
|
-
disabled={!buttonIsValid}
|
|
238
|
-
class:margin-left={button.margin === 'left'}
|
|
239
|
-
class:margin-right={button.margin === 'right'}
|
|
240
|
-
type={button.type ?? 'button'}
|
|
241
|
-
onclick={button.callback}>{button.label}</button
|
|
242
|
-
>
|
|
243
|
-
</div>
|
|
244
|
-
{:else}
|
|
245
|
-
<div class="button-barcode-set">
|
|
246
|
-
{#if barcodeIcons[index]}
|
|
247
|
-
<DataMatrixIcon
|
|
248
|
-
title={button.label}
|
|
249
|
-
icon={{ kind: 'svg', svg: barcodeIcons[index] }}
|
|
250
|
-
/>
|
|
251
|
-
{/if}
|
|
252
|
-
<button
|
|
253
|
-
class:call-to-action={button.colourSet === ColourSet.CallToAction}
|
|
254
|
-
class:primary={button.colourSet === ColourSet.Primary}
|
|
255
|
-
class:secondary-colour={button.colourSet === ColourSet.Secondary}
|
|
256
|
-
class:warning={button.colourSet === ColourSet.Warning}
|
|
257
|
-
class:error={button.colourSet === ColourSet.Error}
|
|
258
|
-
class:info={button.colourSet === ColourSet.Info}
|
|
259
|
-
onkeydown={passthrough}
|
|
260
|
-
disabled={!buttonIsValid || !isValid}
|
|
261
|
-
class:margin-left={button.margin === 'left'}
|
|
262
|
-
class:margin-right={button.margin === 'right'}
|
|
263
|
-
bind:this={submitRef}
|
|
264
|
-
type={button.type ?? 'submit'}>{button.label}</button
|
|
265
|
-
>
|
|
266
|
-
</div>
|
|
267
|
-
{/if}
|
|
268
|
-
{/each}
|
|
269
|
-
</div>
|
|
270
|
-
{/if}
|
|
271
|
-
</form>
|
|
272
|
-
</BaseModal>
|
|
273
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
module
|
|
5
|
+
lang="ts"
|
|
6
|
+
>
|
|
7
|
+
import { browser } from '$app/environment';
|
|
8
|
+
import { DATAMatrix } from '../../Helpers/Datamatrix.js';
|
|
9
|
+
import { useAsyncFlag } from '../../Helpers/AsyncFlag.svelte.js';
|
|
10
|
+
import { passthrough } from '../../Helpers/Helpers.svelte.js';
|
|
11
|
+
import { ColourSet } from '../../scss/colours.js';
|
|
12
|
+
import { Size } from '../../Types/Internal/Size.js';
|
|
13
|
+
import { onMount } from 'svelte';
|
|
14
|
+
import Action from '../Action.svelte';
|
|
15
|
+
import BaseModal from '../Base/BaseModal.svelte';
|
|
16
|
+
import DataMatrixIcon from '../DataMatrixIcon.svelte';
|
|
17
|
+
import type { TouchModalProps } from './TouchModalProps.js';
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<script lang="ts">
|
|
21
|
+
let {
|
|
22
|
+
header,
|
|
23
|
+
buttons,
|
|
24
|
+
mandatory = false,
|
|
25
|
+
staticHeight = false,
|
|
26
|
+
staticWidth = false,
|
|
27
|
+
minWidth = '400px',
|
|
28
|
+
minHeight = '280px',
|
|
29
|
+
width,
|
|
30
|
+
height,
|
|
31
|
+
onShowCallback,
|
|
32
|
+
defaultTimer,
|
|
33
|
+
isValid = true,
|
|
34
|
+
noscroll = false,
|
|
35
|
+
onsubmit,
|
|
36
|
+
headerExtra,
|
|
37
|
+
explanation,
|
|
38
|
+
children,
|
|
39
|
+
footer,
|
|
40
|
+
onclose,
|
|
41
|
+
row,
|
|
42
|
+
wrap,
|
|
43
|
+
submitRef = $bindable(),
|
|
44
|
+
}: TouchModalProps = $props();
|
|
45
|
+
|
|
46
|
+
let open = $state(true);
|
|
47
|
+
let form: HTMLFormElement | undefined = $state();
|
|
48
|
+
let timeout: ReturnType<typeof setTimeout> | undefined = undefined;
|
|
49
|
+
let paused = $state(false);
|
|
50
|
+
let isActive = $state(false);
|
|
51
|
+
|
|
52
|
+
// Pre-compute barcode SVGs once per `buttons` array. Building a DataMatrix
|
|
53
|
+
// barcode is non-trivial; rebuilding inside the each-block re-runs the
|
|
54
|
+
// encoder on every render.
|
|
55
|
+
//
|
|
56
|
+
// `DATAMatrix` calls `document.createElement` internally, which is
|
|
57
|
+
// undefined during SvelteKit's server render. Returning `null` on the
|
|
58
|
+
// server keeps the SVG slots empty for SSR; the client re-renders with
|
|
59
|
+
// the real encoded payload after hydration.
|
|
60
|
+
const barcodeIcons = $derived.by(
|
|
61
|
+
() =>
|
|
62
|
+
buttons?.map((b) =>
|
|
63
|
+
b.barcodeValue != null && browser ? DATAMatrix(b.barcodeValue) : null
|
|
64
|
+
) ?? []
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// Resolve each button's `isValid` once at the component level rather than
|
|
68
|
+
// inside the each-block. `useAsyncFlag` debounces stale resolutions, holds
|
|
69
|
+
// the previous value until a new Promise settles, and stops the
|
|
70
|
+
// `{#await}` flicker the previous implementation exhibited.
|
|
71
|
+
const buttonValidities = useAsyncFlag(
|
|
72
|
+
() => Promise.all((buttons ?? []).map((b) => Promise.resolve(b.isValid ?? true))),
|
|
73
|
+
[] as Array<boolean>
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
onMount(() => {
|
|
77
|
+
queueMicrotask(() => {
|
|
78
|
+
onShowCallback?.();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const activeTimer = setTimeout(() => {
|
|
82
|
+
isActive = true;
|
|
83
|
+
}, 200);
|
|
84
|
+
|
|
85
|
+
if (defaultTimer) {
|
|
86
|
+
timeout = setTimeout(() => {
|
|
87
|
+
if (open) {
|
|
88
|
+
if (defaultTimer.action === 'submit') {
|
|
89
|
+
form?.requestSubmit();
|
|
90
|
+
defaultTimer.callback?.();
|
|
91
|
+
} else {
|
|
92
|
+
open = false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}, defaultTimer.time);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return () => {
|
|
99
|
+
clearTimeout(activeTimer);
|
|
100
|
+
clearTimer();
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
function clearTimer() {
|
|
105
|
+
if (timeout != undefined) {
|
|
106
|
+
paused = true;
|
|
107
|
+
clearTimeout(timeout);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function handleEsc(e: KeyboardEvent) {
|
|
112
|
+
if (e.key === 'Escape') {
|
|
113
|
+
e.preventDefault();
|
|
114
|
+
if (!mandatory) {
|
|
115
|
+
open = false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function requestClose() {
|
|
121
|
+
open = false;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const dialogClassNames = $derived(
|
|
125
|
+
[
|
|
126
|
+
staticHeight ? 'static-height' : null,
|
|
127
|
+
staticWidth ? 'static-width' : null,
|
|
128
|
+
noscroll ? 'noscroll' : null,
|
|
129
|
+
]
|
|
130
|
+
.filter((c): c is string => c !== null)
|
|
131
|
+
.join(' ')
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
const dialogStyle = $derived(
|
|
135
|
+
`--timer: ${defaultTimer ? defaultTimer.time.toString() + 'ms' : 'unset'};` +
|
|
136
|
+
`--dialog-min-width: ${minWidth};` +
|
|
137
|
+
`--dialog-min-height: ${minHeight};` +
|
|
138
|
+
(height != null ? `--dialog-height: ${height};` : '') +
|
|
139
|
+
(width != null ? `--dialog-width: ${width};` : '')
|
|
140
|
+
);
|
|
141
|
+
</script>
|
|
142
|
+
|
|
143
|
+
<BaseModal
|
|
144
|
+
bind:value={open}
|
|
145
|
+
{onclose}
|
|
146
|
+
{mandatory}
|
|
147
|
+
dialogClass={dialogClassNames}
|
|
148
|
+
{dialogStyle}
|
|
149
|
+
>
|
|
150
|
+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
151
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
152
|
+
<form
|
|
153
|
+
method="dialog"
|
|
154
|
+
bind:this={form}
|
|
155
|
+
onsubmit={(e) => {
|
|
156
|
+
e.preventDefault();
|
|
157
|
+
clearTimer();
|
|
158
|
+
if (isActive) {
|
|
159
|
+
onsubmit?.(e);
|
|
160
|
+
}
|
|
161
|
+
}}
|
|
162
|
+
onclick={clearTimer}
|
|
163
|
+
class="modal-root"
|
|
164
|
+
>
|
|
165
|
+
<div class="modal-header">
|
|
166
|
+
{#if mandatory}
|
|
167
|
+
<div class="title-wrapper">
|
|
168
|
+
<h3 class="modal-heading">{header}</h3>
|
|
169
|
+
</div>
|
|
170
|
+
{:else}
|
|
171
|
+
<div class="title-wrapper">
|
|
172
|
+
<h3 class="modal-heading padded">{header}</h3>
|
|
173
|
+
<div class="close-button">
|
|
174
|
+
<Action
|
|
175
|
+
size={Size.Large}
|
|
176
|
+
onclick={requestClose}
|
|
177
|
+
icon={{
|
|
178
|
+
name: 'cross',
|
|
179
|
+
size: Size.DoubleXLarge,
|
|
180
|
+
}}
|
|
181
|
+
onkeydown={handleEsc}
|
|
182
|
+
colourSet={ColourSet.Primary}
|
|
183
|
+
label="Close Modal"
|
|
184
|
+
/>
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
{/if}
|
|
188
|
+
|
|
189
|
+
{#if headerExtra}
|
|
190
|
+
{@render headerExtra()}
|
|
191
|
+
{/if}
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
{#if defaultTimer}
|
|
195
|
+
<div class="bar-container">
|
|
196
|
+
<div
|
|
197
|
+
class:paused
|
|
198
|
+
class="bar-timer"
|
|
199
|
+
></div>
|
|
200
|
+
</div>
|
|
201
|
+
{/if}
|
|
202
|
+
|
|
203
|
+
<div
|
|
204
|
+
class="modal-main"
|
|
205
|
+
class:row
|
|
206
|
+
class:wrap
|
|
207
|
+
class:noscroll
|
|
208
|
+
>
|
|
209
|
+
{#if explanation}
|
|
210
|
+
{@render explanation()}
|
|
211
|
+
{/if}
|
|
212
|
+
{@render children()}
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
{#if footer}
|
|
216
|
+
{@render footer()}
|
|
217
|
+
{:else if buttons?.length}
|
|
218
|
+
<div class="modal-footer">
|
|
219
|
+
{#each buttons as button, index (button.label)}
|
|
220
|
+
{@const buttonIsValid = buttonValidities.value[index] ?? true}
|
|
221
|
+
{#if button.callback}
|
|
222
|
+
<div class="button-barcode-set">
|
|
223
|
+
{#if barcodeIcons[index]}
|
|
224
|
+
<DataMatrixIcon
|
|
225
|
+
title={button.label}
|
|
226
|
+
icon={{ kind: 'svg', svg: barcodeIcons[index] }}
|
|
227
|
+
/>
|
|
228
|
+
{/if}
|
|
229
|
+
<button
|
|
230
|
+
class:call-to-action={button.colourSet === ColourSet.CallToAction}
|
|
231
|
+
class:primary={button.colourSet === ColourSet.Primary}
|
|
232
|
+
class:secondary-colour={button.colourSet === ColourSet.Secondary}
|
|
233
|
+
class:warning={button.colourSet === ColourSet.Warning}
|
|
234
|
+
class:error={button.colourSet === ColourSet.Error}
|
|
235
|
+
class:info={button.colourSet === ColourSet.Info}
|
|
236
|
+
onkeydown={passthrough}
|
|
237
|
+
disabled={!buttonIsValid}
|
|
238
|
+
class:margin-left={button.margin === 'left'}
|
|
239
|
+
class:margin-right={button.margin === 'right'}
|
|
240
|
+
type={button.type ?? 'button'}
|
|
241
|
+
onclick={button.callback}>{button.label}</button
|
|
242
|
+
>
|
|
243
|
+
</div>
|
|
244
|
+
{:else}
|
|
245
|
+
<div class="button-barcode-set">
|
|
246
|
+
{#if barcodeIcons[index]}
|
|
247
|
+
<DataMatrixIcon
|
|
248
|
+
title={button.label}
|
|
249
|
+
icon={{ kind: 'svg', svg: barcodeIcons[index] }}
|
|
250
|
+
/>
|
|
251
|
+
{/if}
|
|
252
|
+
<button
|
|
253
|
+
class:call-to-action={button.colourSet === ColourSet.CallToAction}
|
|
254
|
+
class:primary={button.colourSet === ColourSet.Primary}
|
|
255
|
+
class:secondary-colour={button.colourSet === ColourSet.Secondary}
|
|
256
|
+
class:warning={button.colourSet === ColourSet.Warning}
|
|
257
|
+
class:error={button.colourSet === ColourSet.Error}
|
|
258
|
+
class:info={button.colourSet === ColourSet.Info}
|
|
259
|
+
onkeydown={passthrough}
|
|
260
|
+
disabled={!buttonIsValid || !isValid}
|
|
261
|
+
class:margin-left={button.margin === 'left'}
|
|
262
|
+
class:margin-right={button.margin === 'right'}
|
|
263
|
+
bind:this={submitRef}
|
|
264
|
+
type={button.type ?? 'submit'}>{button.label}</button
|
|
265
|
+
>
|
|
266
|
+
</div>
|
|
267
|
+
{/if}
|
|
268
|
+
{/each}
|
|
269
|
+
</div>
|
|
270
|
+
{/if}
|
|
271
|
+
</form>
|
|
272
|
+
</BaseModal>
|
|
273
|
+
|
|
274
274
|
<style>dialog {
|
|
275
275
|
overflow: clip;
|
|
276
276
|
background-color: #e9ecf1;
|
|
@@ -518,4 +518,4 @@ div.bar-container div.bar-timer.paused {
|
|
|
518
518
|
animation-play-state: paused;
|
|
519
519
|
opacity: 0%;
|
|
520
520
|
transition: opacity 300ms 0s ease-out;
|
|
521
|
-
}</style>
|
|
521
|
+
}</style>
|