@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,142 +1,142 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
lang="ts"
|
|
5
|
-
generics="CommonDenominator"
|
|
6
|
-
>
|
|
7
|
-
import { readJSON } from '../Helpers/Storage.js';
|
|
8
|
-
import { ColourSet } from '../scss/colours.js';
|
|
9
|
-
import { Size } from '../Types/Internal/Size.js';
|
|
10
|
-
import { onMount, untrack } from 'svelte';
|
|
11
|
-
import Button from './Button.svelte';
|
|
12
|
-
import StepButton from './StepButton.svelte';
|
|
13
|
-
import type { StepFormProps } from './StepFormProps.js';
|
|
14
|
-
|
|
15
|
-
const {
|
|
16
|
-
name,
|
|
17
|
-
steps,
|
|
18
|
-
currentStep,
|
|
19
|
-
noscroll = false,
|
|
20
|
-
noStepMessage = 'No Step Selected',
|
|
21
|
-
}: StepFormProps<CommonDenominator> = $props();
|
|
22
|
-
|
|
23
|
-
const isNonEmptyString = (raw: unknown): raw is string =>
|
|
24
|
-
typeof raw === 'string' && raw.length > 0;
|
|
25
|
-
|
|
26
|
-
const storageKey = (key: string): string => `scoria-step-form:${key}:active-step`;
|
|
27
|
-
|
|
28
|
-
onMount(() => {
|
|
29
|
-
if (name) {
|
|
30
|
-
const tabName = readJSON(sessionStorage, storageKey(name), isNonEmptyString, '');
|
|
31
|
-
if (tabName) {
|
|
32
|
-
steps.find((it) => it.label === tabName)?.onclick();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
const indexOfCurrent = $derived(currentStep ? steps.indexOf(currentStep) : -1);
|
|
38
|
-
|
|
39
|
-
const isReachable = (step: { disabled?: unknown; visible?: unknown } | undefined): boolean => {
|
|
40
|
-
if (step == null) {
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
// disabled may be a Promise; treat anything non-strictly-true as "reachable"
|
|
44
|
-
const disabled = step.disabled;
|
|
45
|
-
const visible = step.visible;
|
|
46
|
-
const isDisabled = disabled === true;
|
|
47
|
-
const isHidden = visible === false;
|
|
48
|
-
return !isDisabled && !isHidden;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const previous = $derived.by(() => {
|
|
52
|
-
for (let i = indexOfCurrent - 1; i > -1; i--) {
|
|
53
|
-
const candidate = steps.at(i);
|
|
54
|
-
if (candidate == null) {
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
if (isReachable(candidate)) {
|
|
58
|
-
return candidate;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return null;
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const next = $derived.by(() => {
|
|
65
|
-
for (let i = indexOfCurrent + 1; i < steps.length; i++) {
|
|
66
|
-
const candidate = steps.at(i);
|
|
67
|
-
if (candidate == null) {
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
if (isReachable(candidate)) {
|
|
71
|
-
return candidate;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return null;
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
$effect(() => {
|
|
78
|
-
if (name && currentStep) {
|
|
79
|
-
untrack(() => {
|
|
80
|
-
try {
|
|
81
|
-
sessionStorage.setItem(storageKey(name), JSON.stringify(currentStep.label));
|
|
82
|
-
} catch {
|
|
83
|
-
// storage unavailable (private browsing, quota); persistence is best-effort
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
</script>
|
|
89
|
-
|
|
90
|
-
<div
|
|
91
|
-
class:noscroll
|
|
92
|
-
class="wrapper"
|
|
93
|
-
>
|
|
94
|
-
<div class="tabs">
|
|
95
|
-
{#each steps as option, index (option.label)}
|
|
96
|
-
<StepButton
|
|
97
|
-
{option}
|
|
98
|
-
{index}
|
|
99
|
-
selected={currentStep?.label === option.label}
|
|
100
|
-
/>
|
|
101
|
-
{/each}
|
|
102
|
-
<div class="divider"></div>
|
|
103
|
-
|
|
104
|
-
<div class="steps">
|
|
105
|
-
<Button
|
|
106
|
-
size={Size.Small}
|
|
107
|
-
fullWidth
|
|
108
|
-
disabled={!previous}
|
|
109
|
-
onclick={() => {
|
|
110
|
-
previous?.onclick();
|
|
111
|
-
}}
|
|
112
|
-
colourSet={ColourSet.Secondary}>Previous</Button
|
|
113
|
-
>
|
|
114
|
-
<Button
|
|
115
|
-
size={Size.Small}
|
|
116
|
-
fullWidth
|
|
117
|
-
onclick={() => {
|
|
118
|
-
next?.onclick();
|
|
119
|
-
}}
|
|
120
|
-
disabled={!next}
|
|
121
|
-
colourSet={ColourSet.Primary}>Next</Button
|
|
122
|
-
>
|
|
123
|
-
</div>
|
|
124
|
-
</div>
|
|
125
|
-
|
|
126
|
-
<div
|
|
127
|
-
class:noscroll
|
|
128
|
-
class="content"
|
|
129
|
-
>
|
|
130
|
-
{#if currentStep}
|
|
131
|
-
{@render currentStep.content(currentStep.args)}
|
|
132
|
-
{:else}
|
|
133
|
-
<div class="wrapper bg">
|
|
134
|
-
<span class="red">{noStepMessage}</span>
|
|
135
|
-
</div>
|
|
136
|
-
{/if}
|
|
137
|
-
</div>
|
|
138
|
-
</div>
|
|
139
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
generics="CommonDenominator"
|
|
6
|
+
>
|
|
7
|
+
import { readJSON } from '../Helpers/Storage.js';
|
|
8
|
+
import { ColourSet } from '../scss/colours.js';
|
|
9
|
+
import { Size } from '../Types/Internal/Size.js';
|
|
10
|
+
import { onMount, untrack } from 'svelte';
|
|
11
|
+
import Button from './Button.svelte';
|
|
12
|
+
import StepButton from './StepButton.svelte';
|
|
13
|
+
import type { StepFormProps } from './StepFormProps.js';
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
name,
|
|
17
|
+
steps,
|
|
18
|
+
currentStep,
|
|
19
|
+
noscroll = false,
|
|
20
|
+
noStepMessage = 'No Step Selected',
|
|
21
|
+
}: StepFormProps<CommonDenominator> = $props();
|
|
22
|
+
|
|
23
|
+
const isNonEmptyString = (raw: unknown): raw is string =>
|
|
24
|
+
typeof raw === 'string' && raw.length > 0;
|
|
25
|
+
|
|
26
|
+
const storageKey = (key: string): string => `scoria-step-form:${key}:active-step`;
|
|
27
|
+
|
|
28
|
+
onMount(() => {
|
|
29
|
+
if (name) {
|
|
30
|
+
const tabName = readJSON(sessionStorage, storageKey(name), isNonEmptyString, '');
|
|
31
|
+
if (tabName) {
|
|
32
|
+
steps.find((it) => it.label === tabName)?.onclick();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const indexOfCurrent = $derived(currentStep ? steps.indexOf(currentStep) : -1);
|
|
38
|
+
|
|
39
|
+
const isReachable = (step: { disabled?: unknown; visible?: unknown } | undefined): boolean => {
|
|
40
|
+
if (step == null) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
// disabled may be a Promise; treat anything non-strictly-true as "reachable"
|
|
44
|
+
const disabled = step.disabled;
|
|
45
|
+
const visible = step.visible;
|
|
46
|
+
const isDisabled = disabled === true;
|
|
47
|
+
const isHidden = visible === false;
|
|
48
|
+
return !isDisabled && !isHidden;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const previous = $derived.by(() => {
|
|
52
|
+
for (let i = indexOfCurrent - 1; i > -1; i--) {
|
|
53
|
+
const candidate = steps.at(i);
|
|
54
|
+
if (candidate == null) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
if (isReachable(candidate)) {
|
|
58
|
+
return candidate;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const next = $derived.by(() => {
|
|
65
|
+
for (let i = indexOfCurrent + 1; i < steps.length; i++) {
|
|
66
|
+
const candidate = steps.at(i);
|
|
67
|
+
if (candidate == null) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
if (isReachable(candidate)) {
|
|
71
|
+
return candidate;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
$effect(() => {
|
|
78
|
+
if (name && currentStep) {
|
|
79
|
+
untrack(() => {
|
|
80
|
+
try {
|
|
81
|
+
sessionStorage.setItem(storageKey(name), JSON.stringify(currentStep.label));
|
|
82
|
+
} catch {
|
|
83
|
+
// storage unavailable (private browsing, quota); persistence is best-effort
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
</script>
|
|
89
|
+
|
|
90
|
+
<div
|
|
91
|
+
class:noscroll
|
|
92
|
+
class="wrapper"
|
|
93
|
+
>
|
|
94
|
+
<div class="tabs">
|
|
95
|
+
{#each steps as option, index (option.label)}
|
|
96
|
+
<StepButton
|
|
97
|
+
{option}
|
|
98
|
+
{index}
|
|
99
|
+
selected={currentStep?.label === option.label}
|
|
100
|
+
/>
|
|
101
|
+
{/each}
|
|
102
|
+
<div class="divider"></div>
|
|
103
|
+
|
|
104
|
+
<div class="steps">
|
|
105
|
+
<Button
|
|
106
|
+
size={Size.Small}
|
|
107
|
+
fullWidth
|
|
108
|
+
disabled={!previous}
|
|
109
|
+
onclick={() => {
|
|
110
|
+
previous?.onclick();
|
|
111
|
+
}}
|
|
112
|
+
colourSet={ColourSet.Secondary}>Previous</Button
|
|
113
|
+
>
|
|
114
|
+
<Button
|
|
115
|
+
size={Size.Small}
|
|
116
|
+
fullWidth
|
|
117
|
+
onclick={() => {
|
|
118
|
+
next?.onclick();
|
|
119
|
+
}}
|
|
120
|
+
disabled={!next}
|
|
121
|
+
colourSet={ColourSet.Primary}>Next</Button
|
|
122
|
+
>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<div
|
|
127
|
+
class:noscroll
|
|
128
|
+
class="content"
|
|
129
|
+
>
|
|
130
|
+
{#if currentStep}
|
|
131
|
+
{@render currentStep.content(currentStep.args)}
|
|
132
|
+
{:else}
|
|
133
|
+
<div class="wrapper bg">
|
|
134
|
+
<span class="red">{noStepMessage}</span>
|
|
135
|
+
</div>
|
|
136
|
+
{/if}
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
140
|
<style>.bg {
|
|
141
141
|
padding: 1.5rem;
|
|
142
142
|
background-color: #f9e9e9;
|
|
@@ -192,4 +192,4 @@
|
|
|
192
192
|
}
|
|
193
193
|
.wrapper .content.noscroll {
|
|
194
194
|
overflow: visible;
|
|
195
|
-
}</style>
|
|
195
|
+
}</style>
|
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script lang="ts">
|
|
4
|
-
import { generateWeakId } from '../Helpers/Helpers.svelte.js';
|
|
5
|
-
import type { SwitchProps } from './SwitchProps.js';
|
|
6
|
-
|
|
7
|
-
let {
|
|
8
|
-
value = $bindable(false),
|
|
9
|
-
id = generateWeakId(),
|
|
10
|
-
label,
|
|
11
|
-
disabled,
|
|
12
|
-
isValid,
|
|
13
|
-
onchange,
|
|
14
|
-
}: SwitchProps = $props();
|
|
15
|
-
|
|
16
|
-
let mirror: HTMLInputElement | undefined = $state();
|
|
17
|
-
|
|
18
|
-
const toggle = () => {
|
|
19
|
-
if (disabled) {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
const next = !value;
|
|
23
|
-
value = next;
|
|
24
|
-
if (mirror && onchange) {
|
|
25
|
-
mirror.checked = next;
|
|
26
|
-
mirror.dispatchEvent(new Event('change', { bubbles: true }));
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
</script>
|
|
30
|
-
|
|
31
|
-
<div class="switch-wrapper">
|
|
32
|
-
<button
|
|
33
|
-
{id}
|
|
34
|
-
class="text-label"
|
|
35
|
-
class:invalid={isValid === false}
|
|
36
|
-
type="button"
|
|
37
|
-
role="switch"
|
|
38
|
-
aria-checked={value}
|
|
39
|
-
aria-label={label}
|
|
40
|
-
onclick={toggle}
|
|
41
|
-
{disabled}
|
|
42
|
-
>
|
|
43
|
-
<span>{label}</span>
|
|
44
|
-
|
|
45
|
-
<div class="switch">
|
|
46
|
-
<div
|
|
47
|
-
class="switch-inner"
|
|
48
|
-
class:on={value}
|
|
49
|
-
>
|
|
50
|
-
<div
|
|
51
|
-
class="track"
|
|
52
|
-
class:on={value}
|
|
53
|
-
></div>
|
|
54
|
-
</div>
|
|
55
|
-
</div>
|
|
56
|
-
</button>
|
|
57
|
-
|
|
58
|
-
<input
|
|
59
|
-
name={id}
|
|
60
|
-
{onchange}
|
|
61
|
-
type="checkbox"
|
|
62
|
-
tabindex="-1"
|
|
63
|
-
aria-hidden="true"
|
|
64
|
-
checked={value}
|
|
65
|
-
bind:this={mirror}
|
|
66
|
-
/>
|
|
67
|
-
</div>
|
|
68
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script lang="ts">
|
|
4
|
+
import { generateWeakId } from '../Helpers/Helpers.svelte.js';
|
|
5
|
+
import type { SwitchProps } from './SwitchProps.js';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
value = $bindable(false),
|
|
9
|
+
id = generateWeakId(),
|
|
10
|
+
label,
|
|
11
|
+
disabled,
|
|
12
|
+
isValid,
|
|
13
|
+
onchange,
|
|
14
|
+
}: SwitchProps = $props();
|
|
15
|
+
|
|
16
|
+
let mirror: HTMLInputElement | undefined = $state();
|
|
17
|
+
|
|
18
|
+
const toggle = () => {
|
|
19
|
+
if (disabled) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const next = !value;
|
|
23
|
+
value = next;
|
|
24
|
+
if (mirror && onchange) {
|
|
25
|
+
mirror.checked = next;
|
|
26
|
+
mirror.dispatchEvent(new Event('change', { bubbles: true }));
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<div class="switch-wrapper">
|
|
32
|
+
<button
|
|
33
|
+
{id}
|
|
34
|
+
class="text-label"
|
|
35
|
+
class:invalid={isValid === false}
|
|
36
|
+
type="button"
|
|
37
|
+
role="switch"
|
|
38
|
+
aria-checked={value}
|
|
39
|
+
aria-label={label}
|
|
40
|
+
onclick={toggle}
|
|
41
|
+
{disabled}
|
|
42
|
+
>
|
|
43
|
+
<span>{label}</span>
|
|
44
|
+
|
|
45
|
+
<div class="switch">
|
|
46
|
+
<div
|
|
47
|
+
class="switch-inner"
|
|
48
|
+
class:on={value}
|
|
49
|
+
>
|
|
50
|
+
<div
|
|
51
|
+
class="track"
|
|
52
|
+
class:on={value}
|
|
53
|
+
></div>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</button>
|
|
57
|
+
|
|
58
|
+
<input
|
|
59
|
+
name={id}
|
|
60
|
+
{onchange}
|
|
61
|
+
type="checkbox"
|
|
62
|
+
tabindex="-1"
|
|
63
|
+
aria-hidden="true"
|
|
64
|
+
checked={value}
|
|
65
|
+
bind:this={mirror}
|
|
66
|
+
/>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
69
|
<style>.switch-wrapper {
|
|
70
70
|
display: contents;
|
|
71
71
|
}
|
|
@@ -174,4 +174,4 @@
|
|
|
174
174
|
|
|
175
175
|
input {
|
|
176
176
|
display: none;
|
|
177
|
-
}</style>
|
|
177
|
+
}</style>
|
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
lang="ts"
|
|
5
|
-
generics="T extends object, IdType extends Primitive"
|
|
6
|
-
>
|
|
7
|
-
import Action from '../../../Action.svelte';
|
|
8
|
-
import { Colour } from '../../../../scss/colours.js';
|
|
9
|
-
import { Size } from '../../../../Types/Internal/Size.js';
|
|
10
|
-
import { getContext } from 'svelte';
|
|
11
|
-
import { TableContext } from '../../Types/Context/TableContext.svelte.js';
|
|
12
|
-
import type { Primitive } from '../../Types/Context/TableInitOptions.js';
|
|
13
|
-
import type { ColumnHighlightProps } from './ColumnHighlightProps.js';
|
|
14
|
-
|
|
15
|
-
const { rowIndex, highlighted, toggleHighlightedRow }: ColumnHighlightProps = $props();
|
|
16
|
-
|
|
17
|
-
const tableContext = getContext<TableContext<T, IdType>>(TableContext.identifier);
|
|
18
|
-
|
|
19
|
-
const backgroundColour = $derived(highlighted ? Colour['$brand-primary'] : Colour['$ui-white']);
|
|
20
|
-
|
|
21
|
-
// Cell id is prefixed with the owning table name to avoid duplicate `id`
|
|
22
|
-
// attributes when multiple tables share the page (workorder P2).
|
|
23
|
-
const cellId = $derived(`${tableContext.tableName}-tagger-row-${rowIndex}`);
|
|
24
|
-
const label = $derived(
|
|
25
|
-
`${highlighted ? 'Unhighlight' : 'Highlight'} row ${(rowIndex + 1).toString()}`
|
|
26
|
-
);
|
|
27
|
-
</script>
|
|
28
|
-
|
|
29
|
-
<!-- Toggle semantics: `aria-pressed` is communicated through the Action's label
|
|
30
|
-
which reads either "Highlight row N" or "Unhighlight row N" depending on state. -->
|
|
31
|
-
<div
|
|
32
|
-
id={cellId}
|
|
33
|
-
class="highlight-content"
|
|
34
|
-
>
|
|
35
|
-
<div class="wrapper">
|
|
36
|
-
<Action
|
|
37
|
-
{backgroundColour}
|
|
38
|
-
hoverBackgroundColour={Colour['$brand-dark']}
|
|
39
|
-
size={Size.FillWidth}
|
|
40
|
-
{label}
|
|
41
|
-
icon={{
|
|
42
|
-
name: 'nothing',
|
|
43
|
-
}}
|
|
44
|
-
onclick={() => {
|
|
45
|
-
toggleHighlightedRow();
|
|
46
|
-
}}
|
|
47
|
-
/>
|
|
48
|
-
</div>
|
|
49
|
-
</div>
|
|
50
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
generics="T extends object, IdType extends Primitive"
|
|
6
|
+
>
|
|
7
|
+
import Action from '../../../Action.svelte';
|
|
8
|
+
import { Colour } from '../../../../scss/colours.js';
|
|
9
|
+
import { Size } from '../../../../Types/Internal/Size.js';
|
|
10
|
+
import { getContext } from 'svelte';
|
|
11
|
+
import { TableContext } from '../../Types/Context/TableContext.svelte.js';
|
|
12
|
+
import type { Primitive } from '../../Types/Context/TableInitOptions.js';
|
|
13
|
+
import type { ColumnHighlightProps } from './ColumnHighlightProps.js';
|
|
14
|
+
|
|
15
|
+
const { rowIndex, highlighted, toggleHighlightedRow }: ColumnHighlightProps = $props();
|
|
16
|
+
|
|
17
|
+
const tableContext = getContext<TableContext<T, IdType>>(TableContext.identifier);
|
|
18
|
+
|
|
19
|
+
const backgroundColour = $derived(highlighted ? Colour['$brand-primary'] : Colour['$ui-white']);
|
|
20
|
+
|
|
21
|
+
// Cell id is prefixed with the owning table name to avoid duplicate `id`
|
|
22
|
+
// attributes when multiple tables share the page (workorder P2).
|
|
23
|
+
const cellId = $derived(`${tableContext.tableName}-tagger-row-${rowIndex}`);
|
|
24
|
+
const label = $derived(
|
|
25
|
+
`${highlighted ? 'Unhighlight' : 'Highlight'} row ${(rowIndex + 1).toString()}`
|
|
26
|
+
);
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<!-- Toggle semantics: `aria-pressed` is communicated through the Action's label
|
|
30
|
+
which reads either "Highlight row N" or "Unhighlight row N" depending on state. -->
|
|
31
|
+
<div
|
|
32
|
+
id={cellId}
|
|
33
|
+
class="highlight-content"
|
|
34
|
+
>
|
|
35
|
+
<div class="wrapper">
|
|
36
|
+
<Action
|
|
37
|
+
{backgroundColour}
|
|
38
|
+
hoverBackgroundColour={Colour['$brand-dark']}
|
|
39
|
+
size={Size.FillWidth}
|
|
40
|
+
{label}
|
|
41
|
+
icon={{
|
|
42
|
+
name: 'nothing',
|
|
43
|
+
}}
|
|
44
|
+
onclick={() => {
|
|
45
|
+
toggleHighlightedRow();
|
|
46
|
+
}}
|
|
47
|
+
/>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
51
|
<style>.focusable,
|
|
52
52
|
.checkbox-cell,
|
|
53
53
|
.input-cell,
|
|
@@ -94,4 +94,4 @@ div.wrapper {
|
|
|
94
94
|
|
|
95
95
|
.wrapper {
|
|
96
96
|
overflow: hidden;
|
|
97
|
-
}</style>
|
|
97
|
+
}</style>
|
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
lang="ts"
|
|
5
|
-
generics="T extends object, IdType extends Primitive"
|
|
6
|
-
>
|
|
7
|
-
import { ColumnType } from '../../Types/Columns/ColumnType.js';
|
|
8
|
-
import type { ColumnDef } from '../../Types/Columns/Definitions/ColumnDef.svelte.js';
|
|
9
|
-
import { TableContext } from '../../Types/Context/TableContext.svelte.js';
|
|
10
|
-
import type { Primitive } from '../../Types/Context/TableInitOptions.js';
|
|
11
|
-
import { getContext } from 'svelte';
|
|
12
|
-
import type { ColumnListProps } from './ColumnListProps.js';
|
|
13
|
-
import ColumnListRow from './ColumnListRow.svelte';
|
|
14
|
-
|
|
15
|
-
const tableContext = getContext<TableContext<T, IdType>>(TableContext.identifier);
|
|
16
|
-
|
|
17
|
-
const { searchValue }: ColumnListProps = $props();
|
|
18
|
-
|
|
19
|
-
const visibleColumns: Array<ColumnDef<T>> = $derived.by(() => {
|
|
20
|
-
const lowercasedSearchValue = searchValue.toLocaleLowerCase();
|
|
21
|
-
return tableContext.columnDefs.filter(
|
|
22
|
-
(it) =>
|
|
23
|
-
it.columnType !== ColumnType.FilterOnly &&
|
|
24
|
-
(it.id.toLowerCase().includes(lowercasedSearchValue) ||
|
|
25
|
-
(typeof it.header === 'string' &&
|
|
26
|
-
it.header.toLowerCase().includes(lowercasedSearchValue)))
|
|
27
|
-
);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
function onDrop(e: DragEvent) {
|
|
31
|
-
if (!tableContext.dragTarget) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const dropTarget = (e.target as HTMLElement | undefined)?.closest('li');
|
|
36
|
-
|
|
37
|
-
if (dropTarget) {
|
|
38
|
-
tableContext.reorderColumn(dropTarget);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
</script>
|
|
42
|
-
|
|
43
|
-
<ul
|
|
44
|
-
class="column-list"
|
|
45
|
-
ondrop={onDrop}
|
|
46
|
-
>
|
|
47
|
-
<!-- HACK this is used as an anchor for dragging rows to the top -->
|
|
48
|
-
<ColumnListRow columnDef={null} />
|
|
49
|
-
|
|
50
|
-
{#each visibleColumns as columnDef (columnDef.id)}
|
|
51
|
-
<ColumnListRow {columnDef} />
|
|
52
|
-
{:else}
|
|
53
|
-
{#if searchValue.length > 0}
|
|
54
|
-
<li class="empty-state">No columns match “{searchValue}”</li>
|
|
55
|
-
{/if}
|
|
56
|
-
{/each}
|
|
57
|
-
</ul>
|
|
58
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
generics="T extends object, IdType extends Primitive"
|
|
6
|
+
>
|
|
7
|
+
import { ColumnType } from '../../Types/Columns/ColumnType.js';
|
|
8
|
+
import type { ColumnDef } from '../../Types/Columns/Definitions/ColumnDef.svelte.js';
|
|
9
|
+
import { TableContext } from '../../Types/Context/TableContext.svelte.js';
|
|
10
|
+
import type { Primitive } from '../../Types/Context/TableInitOptions.js';
|
|
11
|
+
import { getContext } from 'svelte';
|
|
12
|
+
import type { ColumnListProps } from './ColumnListProps.js';
|
|
13
|
+
import ColumnListRow from './ColumnListRow.svelte';
|
|
14
|
+
|
|
15
|
+
const tableContext = getContext<TableContext<T, IdType>>(TableContext.identifier);
|
|
16
|
+
|
|
17
|
+
const { searchValue }: ColumnListProps = $props();
|
|
18
|
+
|
|
19
|
+
const visibleColumns: Array<ColumnDef<T>> = $derived.by(() => {
|
|
20
|
+
const lowercasedSearchValue = searchValue.toLocaleLowerCase();
|
|
21
|
+
return tableContext.columnDefs.filter(
|
|
22
|
+
(it) =>
|
|
23
|
+
it.columnType !== ColumnType.FilterOnly &&
|
|
24
|
+
(it.id.toLowerCase().includes(lowercasedSearchValue) ||
|
|
25
|
+
(typeof it.header === 'string' &&
|
|
26
|
+
it.header.toLowerCase().includes(lowercasedSearchValue)))
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
function onDrop(e: DragEvent) {
|
|
31
|
+
if (!tableContext.dragTarget) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const dropTarget = (e.target as HTMLElement | undefined)?.closest('li');
|
|
36
|
+
|
|
37
|
+
if (dropTarget) {
|
|
38
|
+
tableContext.reorderColumn(dropTarget);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<ul
|
|
44
|
+
class="column-list"
|
|
45
|
+
ondrop={onDrop}
|
|
46
|
+
>
|
|
47
|
+
<!-- HACK this is used as an anchor for dragging rows to the top -->
|
|
48
|
+
<ColumnListRow columnDef={null} />
|
|
49
|
+
|
|
50
|
+
{#each visibleColumns as columnDef (columnDef.id)}
|
|
51
|
+
<ColumnListRow {columnDef} />
|
|
52
|
+
{:else}
|
|
53
|
+
{#if searchValue.length > 0}
|
|
54
|
+
<li class="empty-state">No columns match “{searchValue}”</li>
|
|
55
|
+
{/if}
|
|
56
|
+
{/each}
|
|
57
|
+
</ul>
|
|
58
|
+
|
|
59
59
|
<style>ul {
|
|
60
60
|
list-style: none;
|
|
61
61
|
background-color: #ffffff;
|
|
@@ -75,4 +75,4 @@
|
|
|
75
75
|
text-align: center;
|
|
76
76
|
color: #8096a5;
|
|
77
77
|
font-style: italic;
|
|
78
|
-
}</style>
|
|
78
|
+
}</style>
|