@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,82 +1,82 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
lang="ts"
|
|
5
|
-
generics="Args"
|
|
6
|
-
>
|
|
7
|
-
import { devCatch } from '../../Helpers/Helpers.svelte.js';
|
|
8
|
-
import type { TabOption } from '../../Types/Internal/TabOption.js';
|
|
9
|
-
import HorizontalTabGroup from '../HorizontalTabGroup.svelte';
|
|
10
|
-
import NavTab from './NavTab.svelte';
|
|
11
|
-
import type { ServicesNavProps } from './ServicesNavProps.js';
|
|
12
|
-
|
|
13
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-arguments
|
|
14
|
-
const { onclose, serviceTabs, selectedServiceTab }: ServicesNavProps<Args> = $props();
|
|
15
|
-
|
|
16
|
-
let dialogRef: HTMLDialogElement | undefined = $state.raw();
|
|
17
|
-
|
|
18
|
-
function fireClose(): void {
|
|
19
|
-
const result = onclose();
|
|
20
|
-
if (result instanceof Promise) {
|
|
21
|
-
result.catch((e: unknown) => {
|
|
22
|
-
devCatch(e);
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Open the dialog as soon as we mount; native showModal() gives us a
|
|
28
|
-
// real focus trap, Escape-to-close, and inert background without any
|
|
29
|
-
// manual aria-modal / tabindex bookkeeping.
|
|
30
|
-
$effect(() => {
|
|
31
|
-
const dialog = dialogRef;
|
|
32
|
-
if (dialog && !dialog.open) {
|
|
33
|
-
dialog.showModal();
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
</script>
|
|
37
|
-
|
|
38
|
-
<dialog
|
|
39
|
-
bind:this={dialogRef}
|
|
40
|
-
aria-label="Services"
|
|
41
|
-
class="overlay"
|
|
42
|
-
oncancel={(e) => {
|
|
43
|
-
// Escape fires `cancel` first; prevent the native close so we
|
|
44
|
-
// fully delegate to the parent (it owns the visibility flag).
|
|
45
|
-
e.preventDefault();
|
|
46
|
-
fireClose();
|
|
47
|
-
}}
|
|
48
|
-
onclick={(e) => {
|
|
49
|
-
// Native <dialog> click target is the dialog element itself when
|
|
50
|
-
// the user clicks the backdrop; clicks on inner content bubble
|
|
51
|
-
// up with a different target.
|
|
52
|
-
if (dialogRef === e.target) {
|
|
53
|
-
fireClose();
|
|
54
|
-
}
|
|
55
|
-
}}
|
|
56
|
-
>
|
|
57
|
-
<div
|
|
58
|
-
role="navigation"
|
|
59
|
-
aria-label="Services tabs"
|
|
60
|
-
class="services"
|
|
61
|
-
>
|
|
62
|
-
<HorizontalTabGroup
|
|
63
|
-
name="nav-services"
|
|
64
|
-
tabs={serviceTabs}
|
|
65
|
-
selected={selectedServiceTab}
|
|
66
|
-
tabComponent={navTab}
|
|
67
|
-
noRadius
|
|
68
|
-
grow
|
|
69
|
-
/>
|
|
70
|
-
</div>
|
|
71
|
-
</dialog>
|
|
72
|
-
|
|
73
|
-
{#snippet navTab(option: TabOption<Args>, selected: boolean)}
|
|
74
|
-
<NavTab
|
|
75
|
-
{option}
|
|
76
|
-
{selected}
|
|
77
|
-
/>
|
|
78
|
-
{/snippet}
|
|
79
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
generics="Args"
|
|
6
|
+
>
|
|
7
|
+
import { devCatch } from '../../Helpers/Helpers.svelte.js';
|
|
8
|
+
import type { TabOption } from '../../Types/Internal/TabOption.js';
|
|
9
|
+
import HorizontalTabGroup from '../HorizontalTabGroup.svelte';
|
|
10
|
+
import NavTab from './NavTab.svelte';
|
|
11
|
+
import type { ServicesNavProps } from './ServicesNavProps.js';
|
|
12
|
+
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-arguments
|
|
14
|
+
const { onclose, serviceTabs, selectedServiceTab }: ServicesNavProps<Args> = $props();
|
|
15
|
+
|
|
16
|
+
let dialogRef: HTMLDialogElement | undefined = $state.raw();
|
|
17
|
+
|
|
18
|
+
function fireClose(): void {
|
|
19
|
+
const result = onclose();
|
|
20
|
+
if (result instanceof Promise) {
|
|
21
|
+
result.catch((e: unknown) => {
|
|
22
|
+
devCatch(e);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Open the dialog as soon as we mount; native showModal() gives us a
|
|
28
|
+
// real focus trap, Escape-to-close, and inert background without any
|
|
29
|
+
// manual aria-modal / tabindex bookkeeping.
|
|
30
|
+
$effect(() => {
|
|
31
|
+
const dialog = dialogRef;
|
|
32
|
+
if (dialog && !dialog.open) {
|
|
33
|
+
dialog.showModal();
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<dialog
|
|
39
|
+
bind:this={dialogRef}
|
|
40
|
+
aria-label="Services"
|
|
41
|
+
class="overlay"
|
|
42
|
+
oncancel={(e) => {
|
|
43
|
+
// Escape fires `cancel` first; prevent the native close so we
|
|
44
|
+
// fully delegate to the parent (it owns the visibility flag).
|
|
45
|
+
e.preventDefault();
|
|
46
|
+
fireClose();
|
|
47
|
+
}}
|
|
48
|
+
onclick={(e) => {
|
|
49
|
+
// Native <dialog> click target is the dialog element itself when
|
|
50
|
+
// the user clicks the backdrop; clicks on inner content bubble
|
|
51
|
+
// up with a different target.
|
|
52
|
+
if (dialogRef === e.target) {
|
|
53
|
+
fireClose();
|
|
54
|
+
}
|
|
55
|
+
}}
|
|
56
|
+
>
|
|
57
|
+
<div
|
|
58
|
+
role="navigation"
|
|
59
|
+
aria-label="Services tabs"
|
|
60
|
+
class="services"
|
|
61
|
+
>
|
|
62
|
+
<HorizontalTabGroup
|
|
63
|
+
name="nav-services"
|
|
64
|
+
tabs={serviceTabs}
|
|
65
|
+
selected={selectedServiceTab}
|
|
66
|
+
tabComponent={navTab}
|
|
67
|
+
noRadius
|
|
68
|
+
grow
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
</dialog>
|
|
72
|
+
|
|
73
|
+
{#snippet navTab(option: TabOption<Args>, selected: boolean)}
|
|
74
|
+
<NavTab
|
|
75
|
+
{option}
|
|
76
|
+
{selected}
|
|
77
|
+
/>
|
|
78
|
+
{/snippet}
|
|
79
|
+
|
|
80
80
|
<style>dialog.overlay {
|
|
81
81
|
position: fixed;
|
|
82
82
|
top: calc(3.25rem + var(--env-border-height, 0));
|
|
@@ -115,4 +115,4 @@ div.services {
|
|
|
115
115
|
justify-content: stretch;
|
|
116
116
|
height: var(--services-nav-height, min(710px, 80%));
|
|
117
117
|
width: var(--services-nav-width, 800px);
|
|
118
|
-
}</style>
|
|
118
|
+
}</style>
|
|
@@ -1,159 +1,159 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script lang="ts">
|
|
4
|
-
import { cssLength } from '../Helpers/Helpers.svelte.js';
|
|
5
|
-
import { InputVariant } from '../Types/Internal/InputVariant.js';
|
|
6
|
-
import { Size } from '../Types/Internal/Size.js';
|
|
7
|
-
import Icon from './Icon.svelte';
|
|
8
|
-
import type { NumberInputProps } from './NumberInputProps.js';
|
|
9
|
-
let {
|
|
10
|
-
id,
|
|
11
|
-
value = $bindable(null),
|
|
12
|
-
min,
|
|
13
|
-
max,
|
|
14
|
-
labelTop,
|
|
15
|
-
labelRight,
|
|
16
|
-
placeholder,
|
|
17
|
-
required = false,
|
|
18
|
-
variant = InputVariant.Default,
|
|
19
|
-
decimal = false,
|
|
20
|
-
invalid = false,
|
|
21
|
-
showErrorColours = true,
|
|
22
|
-
disabled,
|
|
23
|
-
optional,
|
|
24
|
-
leftIcon,
|
|
25
|
-
rightIcon,
|
|
26
|
-
onLeftIconClick,
|
|
27
|
-
onRightIconClick,
|
|
28
|
-
|
|
29
|
-
onblur,
|
|
30
|
-
onfocus,
|
|
31
|
-
// No default `onkeydown` - see TextInput.svelte for the rationale.
|
|
32
|
-
// The legacy default (`passthrough`) blurred the input on every
|
|
33
|
-
// alphanumeric keystroke and made the field unusable.
|
|
34
|
-
onkeydown,
|
|
35
|
-
oninput,
|
|
36
|
-
|
|
37
|
-
inputRef = $bindable(),
|
|
38
|
-
'data-type': dataType,
|
|
39
|
-
}: NumberInputProps = $props();
|
|
40
|
-
|
|
41
|
-
function clamp(e: Event): void {
|
|
42
|
-
const raw = (e.target as HTMLInputElement).value;
|
|
43
|
-
if (raw === '') {
|
|
44
|
-
if (value !== null) {
|
|
45
|
-
value = null;
|
|
46
|
-
}
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
const next = Number(raw);
|
|
50
|
-
if (isNaN(next)) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const lo = min ?? -Infinity;
|
|
54
|
-
const hi = max ?? Infinity;
|
|
55
|
-
const clamped = Math.max(lo, Math.min(hi, next));
|
|
56
|
-
if (clamped !== value) {
|
|
57
|
-
value = clamped;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const isInvalid = $derived(showErrorColours && ((required && value == null) || invalid));
|
|
62
|
-
</script>
|
|
63
|
-
|
|
64
|
-
<div
|
|
65
|
-
class="error-wrapper"
|
|
66
|
-
class:for-modal={variant == InputVariant.Modal}
|
|
67
|
-
class:for-table={variant == InputVariant.Table}
|
|
68
|
-
>
|
|
69
|
-
<label
|
|
70
|
-
class:for-modal={variant == InputVariant.Modal}
|
|
71
|
-
class:for-table={variant == InputVariant.Table}
|
|
72
|
-
>
|
|
73
|
-
{#if labelTop}
|
|
74
|
-
<span
|
|
75
|
-
class="top-label"
|
|
76
|
-
class:for-default={variant === InputVariant.Default}
|
|
77
|
-
class:invalid={isInvalid}
|
|
78
|
-
>{labelTop}{#if optional}<i> - optional</i>{/if}</span
|
|
79
|
-
>
|
|
80
|
-
{#if variant === InputVariant.Default}
|
|
81
|
-
<span
|
|
82
|
-
aria-hidden="true"
|
|
83
|
-
class="border"
|
|
84
|
-
class:invalid={isInvalid}
|
|
85
|
-
>{labelTop}{#if optional}<i> - optional</i>{/if}</span
|
|
86
|
-
>
|
|
87
|
-
{/if}
|
|
88
|
-
{/if}
|
|
89
|
-
<div
|
|
90
|
-
class="icon-container"
|
|
91
|
-
class:for-modal={variant == InputVariant.Modal}
|
|
92
|
-
>
|
|
93
|
-
{#if leftIcon}
|
|
94
|
-
<Icon
|
|
95
|
-
name={leftIcon.name}
|
|
96
|
-
size={leftIcon.size ?? Size.Medium}
|
|
97
|
-
colour={leftIcon.colour}
|
|
98
|
-
float
|
|
99
|
-
left={cssLength('0.75rem')}
|
|
100
|
-
top={cssLength('50%')}
|
|
101
|
-
anchorX={cssLength('0')}
|
|
102
|
-
anchorY={cssLength('-50%')}
|
|
103
|
-
clickable={!!onLeftIconClick}
|
|
104
|
-
onclick={onLeftIconClick}
|
|
105
|
-
/>
|
|
106
|
-
{/if}
|
|
107
|
-
<input
|
|
108
|
-
{id}
|
|
109
|
-
class:invalid={isInvalid}
|
|
110
|
-
class:for-default={variant === InputVariant.Default}
|
|
111
|
-
data-type={dataType}
|
|
112
|
-
class:left-pad={leftIcon != undefined}
|
|
113
|
-
class:right-pad={rightIcon != undefined || (labelRight && variant == InputVariant.Modal)}
|
|
114
|
-
class:for-modal={variant == InputVariant.Modal}
|
|
115
|
-
type="number"
|
|
116
|
-
aria-invalid={isInvalid || undefined}
|
|
117
|
-
bind:value
|
|
118
|
-
{onblur}
|
|
119
|
-
{onfocus}
|
|
120
|
-
{onkeydown}
|
|
121
|
-
oninput={(e) => {
|
|
122
|
-
clamp(e);
|
|
123
|
-
oninput?.(e);
|
|
124
|
-
}}
|
|
125
|
-
bind:this={inputRef}
|
|
126
|
-
{placeholder}
|
|
127
|
-
{required}
|
|
128
|
-
{disabled}
|
|
129
|
-
{min}
|
|
130
|
-
{max}
|
|
131
|
-
step={decimal ? 0.01 : 1}
|
|
132
|
-
/>
|
|
133
|
-
{#if rightIcon}
|
|
134
|
-
<Icon
|
|
135
|
-
name={rightIcon.name}
|
|
136
|
-
size={rightIcon.size ?? Size.Medium}
|
|
137
|
-
colour={rightIcon.colour}
|
|
138
|
-
float
|
|
139
|
-
right={cssLength(variant == InputVariant.Modal ? '1rem' : '0.5rem')}
|
|
140
|
-
top={cssLength('50%')}
|
|
141
|
-
anchorX={cssLength('0')}
|
|
142
|
-
anchorY={cssLength('-50%')}
|
|
143
|
-
clickable={!!onRightIconClick}
|
|
144
|
-
onclick={onRightIconClick}
|
|
145
|
-
/>
|
|
146
|
-
{/if}
|
|
147
|
-
{#if labelRight}
|
|
148
|
-
<span
|
|
149
|
-
class="right-label inset"
|
|
150
|
-
class:for-modal={variant == InputVariant.Modal}>{labelRight}</span
|
|
151
|
-
>
|
|
152
|
-
{/if}
|
|
153
|
-
</div>
|
|
154
|
-
</label>
|
|
155
|
-
</div>
|
|
156
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script lang="ts">
|
|
4
|
+
import { cssLength } from '../Helpers/Helpers.svelte.js';
|
|
5
|
+
import { InputVariant } from '../Types/Internal/InputVariant.js';
|
|
6
|
+
import { Size } from '../Types/Internal/Size.js';
|
|
7
|
+
import Icon from './Icon.svelte';
|
|
8
|
+
import type { NumberInputProps } from './NumberInputProps.js';
|
|
9
|
+
let {
|
|
10
|
+
id,
|
|
11
|
+
value = $bindable(null),
|
|
12
|
+
min,
|
|
13
|
+
max,
|
|
14
|
+
labelTop,
|
|
15
|
+
labelRight,
|
|
16
|
+
placeholder,
|
|
17
|
+
required = false,
|
|
18
|
+
variant = InputVariant.Default,
|
|
19
|
+
decimal = false,
|
|
20
|
+
invalid = false,
|
|
21
|
+
showErrorColours = true,
|
|
22
|
+
disabled,
|
|
23
|
+
optional,
|
|
24
|
+
leftIcon,
|
|
25
|
+
rightIcon,
|
|
26
|
+
onLeftIconClick,
|
|
27
|
+
onRightIconClick,
|
|
28
|
+
|
|
29
|
+
onblur,
|
|
30
|
+
onfocus,
|
|
31
|
+
// No default `onkeydown` - see TextInput.svelte for the rationale.
|
|
32
|
+
// The legacy default (`passthrough`) blurred the input on every
|
|
33
|
+
// alphanumeric keystroke and made the field unusable.
|
|
34
|
+
onkeydown,
|
|
35
|
+
oninput,
|
|
36
|
+
|
|
37
|
+
inputRef = $bindable(),
|
|
38
|
+
'data-type': dataType,
|
|
39
|
+
}: NumberInputProps = $props();
|
|
40
|
+
|
|
41
|
+
function clamp(e: Event): void {
|
|
42
|
+
const raw = (e.target as HTMLInputElement).value;
|
|
43
|
+
if (raw === '') {
|
|
44
|
+
if (value !== null) {
|
|
45
|
+
value = null;
|
|
46
|
+
}
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const next = Number(raw);
|
|
50
|
+
if (isNaN(next)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const lo = min ?? -Infinity;
|
|
54
|
+
const hi = max ?? Infinity;
|
|
55
|
+
const clamped = Math.max(lo, Math.min(hi, next));
|
|
56
|
+
if (clamped !== value) {
|
|
57
|
+
value = clamped;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const isInvalid = $derived(showErrorColours && ((required && value == null) || invalid));
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<div
|
|
65
|
+
class="error-wrapper"
|
|
66
|
+
class:for-modal={variant == InputVariant.Modal}
|
|
67
|
+
class:for-table={variant == InputVariant.Table}
|
|
68
|
+
>
|
|
69
|
+
<label
|
|
70
|
+
class:for-modal={variant == InputVariant.Modal}
|
|
71
|
+
class:for-table={variant == InputVariant.Table}
|
|
72
|
+
>
|
|
73
|
+
{#if labelTop}
|
|
74
|
+
<span
|
|
75
|
+
class="top-label"
|
|
76
|
+
class:for-default={variant === InputVariant.Default}
|
|
77
|
+
class:invalid={isInvalid}
|
|
78
|
+
>{labelTop}{#if optional}<i> - optional</i>{/if}</span
|
|
79
|
+
>
|
|
80
|
+
{#if variant === InputVariant.Default}
|
|
81
|
+
<span
|
|
82
|
+
aria-hidden="true"
|
|
83
|
+
class="border"
|
|
84
|
+
class:invalid={isInvalid}
|
|
85
|
+
>{labelTop}{#if optional}<i> - optional</i>{/if}</span
|
|
86
|
+
>
|
|
87
|
+
{/if}
|
|
88
|
+
{/if}
|
|
89
|
+
<div
|
|
90
|
+
class="icon-container"
|
|
91
|
+
class:for-modal={variant == InputVariant.Modal}
|
|
92
|
+
>
|
|
93
|
+
{#if leftIcon}
|
|
94
|
+
<Icon
|
|
95
|
+
name={leftIcon.name}
|
|
96
|
+
size={leftIcon.size ?? Size.Medium}
|
|
97
|
+
colour={leftIcon.colour}
|
|
98
|
+
float
|
|
99
|
+
left={cssLength('0.75rem')}
|
|
100
|
+
top={cssLength('50%')}
|
|
101
|
+
anchorX={cssLength('0')}
|
|
102
|
+
anchorY={cssLength('-50%')}
|
|
103
|
+
clickable={!!onLeftIconClick}
|
|
104
|
+
onclick={onLeftIconClick}
|
|
105
|
+
/>
|
|
106
|
+
{/if}
|
|
107
|
+
<input
|
|
108
|
+
{id}
|
|
109
|
+
class:invalid={isInvalid}
|
|
110
|
+
class:for-default={variant === InputVariant.Default}
|
|
111
|
+
data-type={dataType}
|
|
112
|
+
class:left-pad={leftIcon != undefined}
|
|
113
|
+
class:right-pad={rightIcon != undefined || (labelRight && variant == InputVariant.Modal)}
|
|
114
|
+
class:for-modal={variant == InputVariant.Modal}
|
|
115
|
+
type="number"
|
|
116
|
+
aria-invalid={isInvalid || undefined}
|
|
117
|
+
bind:value
|
|
118
|
+
{onblur}
|
|
119
|
+
{onfocus}
|
|
120
|
+
{onkeydown}
|
|
121
|
+
oninput={(e) => {
|
|
122
|
+
clamp(e);
|
|
123
|
+
oninput?.(e);
|
|
124
|
+
}}
|
|
125
|
+
bind:this={inputRef}
|
|
126
|
+
{placeholder}
|
|
127
|
+
{required}
|
|
128
|
+
{disabled}
|
|
129
|
+
{min}
|
|
130
|
+
{max}
|
|
131
|
+
step={decimal ? 0.01 : 1}
|
|
132
|
+
/>
|
|
133
|
+
{#if rightIcon}
|
|
134
|
+
<Icon
|
|
135
|
+
name={rightIcon.name}
|
|
136
|
+
size={rightIcon.size ?? Size.Medium}
|
|
137
|
+
colour={rightIcon.colour}
|
|
138
|
+
float
|
|
139
|
+
right={cssLength(variant == InputVariant.Modal ? '1rem' : '0.5rem')}
|
|
140
|
+
top={cssLength('50%')}
|
|
141
|
+
anchorX={cssLength('0')}
|
|
142
|
+
anchorY={cssLength('-50%')}
|
|
143
|
+
clickable={!!onRightIconClick}
|
|
144
|
+
onclick={onRightIconClick}
|
|
145
|
+
/>
|
|
146
|
+
{/if}
|
|
147
|
+
{#if labelRight}
|
|
148
|
+
<span
|
|
149
|
+
class="right-label inset"
|
|
150
|
+
class:for-modal={variant == InputVariant.Modal}>{labelRight}</span
|
|
151
|
+
>
|
|
152
|
+
{/if}
|
|
153
|
+
</div>
|
|
154
|
+
</label>
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
157
|
<style>input {
|
|
158
158
|
box-sizing: border-box;
|
|
159
159
|
height: 100%;
|
|
@@ -393,4 +393,4 @@ input::-webkit-outer-spin-button,
|
|
|
393
393
|
input::-webkit-inner-spin-button {
|
|
394
394
|
-webkit-appearance: none;
|
|
395
395
|
margin: 0;
|
|
396
|
-
}</style>
|
|
396
|
+
}</style>
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script lang="ts">
|
|
4
|
-
import type { PageHeadingProps } from './PageHeadingProps.js';
|
|
5
|
-
|
|
6
|
-
let { children, subtitle, extras }: PageHeadingProps = $props();
|
|
7
|
-
</script>
|
|
8
|
-
|
|
9
|
-
<div class="outer">
|
|
10
|
-
<div class="column">
|
|
11
|
-
<h1>{@render children()}</h1>
|
|
12
|
-
<div class="one-line">
|
|
13
|
-
{#if subtitle}
|
|
14
|
-
{@render subtitle()}
|
|
15
|
-
{/if}
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
{#if extras}
|
|
19
|
-
<div class="buttons">
|
|
20
|
-
{@render extras()}
|
|
21
|
-
</div>
|
|
22
|
-
{/if}
|
|
23
|
-
</div>
|
|
24
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script lang="ts">
|
|
4
|
+
import type { PageHeadingProps } from './PageHeadingProps.js';
|
|
5
|
+
|
|
6
|
+
let { children, subtitle, extras }: PageHeadingProps = $props();
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<div class="outer">
|
|
10
|
+
<div class="column">
|
|
11
|
+
<h1>{@render children()}</h1>
|
|
12
|
+
<div class="one-line">
|
|
13
|
+
{#if subtitle}
|
|
14
|
+
{@render subtitle()}
|
|
15
|
+
{/if}
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
{#if extras}
|
|
19
|
+
<div class="buttons">
|
|
20
|
+
{@render extras()}
|
|
21
|
+
</div>
|
|
22
|
+
{/if}
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
25
|
<style>.outer {
|
|
26
26
|
padding: 1.5rem;
|
|
27
27
|
display: flex;
|
|
@@ -65,4 +65,4 @@
|
|
|
65
65
|
fill: #647d8e;
|
|
66
66
|
color: #647d8e;
|
|
67
67
|
font-size: 0.875rem;
|
|
68
|
-
}</style>
|
|
68
|
+
}</style>
|