@lavalogic/scoria 0.40.1 → 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,111 +1,111 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script lang="ts">
|
|
4
|
-
import { passthrough } from '../../Helpers/Helpers.svelte.js';
|
|
5
|
-
import { ColourSet } from '../../scss/colours.js';
|
|
6
|
-
import { Side } from '../../Types/Internal/Side.js';
|
|
7
|
-
import { Size } from '../../Types/Internal/Size.js';
|
|
8
|
-
import { onMount } from 'svelte';
|
|
9
|
-
import DataMatrixIcon from '../DataMatrixIcon.svelte';
|
|
10
|
-
import Icon from '../Icon.svelte';
|
|
11
|
-
import type { DataMatrixSvg } from '../DataMatrixIconProps.js';
|
|
12
|
-
import type { UtilityButtonProps } from './UtilityButtonProps.js';
|
|
13
|
-
let {
|
|
14
|
-
type = 'button',
|
|
15
|
-
colourSet = ColourSet.Secondary,
|
|
16
|
-
icon,
|
|
17
|
-
side = Side.Top,
|
|
18
|
-
size: explicitSize,
|
|
19
|
-
notifications,
|
|
20
|
-
ref = $bindable(),
|
|
21
|
-
disabled = false,
|
|
22
|
-
label,
|
|
23
|
-
onEditBarcode,
|
|
24
|
-
onclick,
|
|
25
|
-
onfocus,
|
|
26
|
-
onblur,
|
|
27
|
-
children,
|
|
28
|
-
}: UtilityButtonProps = $props();
|
|
29
|
-
|
|
30
|
-
let isMounted = $state(false);
|
|
31
|
-
|
|
32
|
-
onMount(() => {
|
|
33
|
-
isMounted = true;
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const size: Size = $derived.by(() => {
|
|
37
|
-
if (!isMounted) {
|
|
38
|
-
return Size.DoubleXLarge;
|
|
39
|
-
}
|
|
40
|
-
if (explicitSize !== undefined) {
|
|
41
|
-
return explicitSize;
|
|
42
|
-
}
|
|
43
|
-
if (icon instanceof SVGSVGElement) {
|
|
44
|
-
return Size.DoubleXLarge;
|
|
45
|
-
}
|
|
46
|
-
return icon?.size ?? Size.DoubleXLarge;
|
|
47
|
-
});
|
|
48
|
-
let slotSpan: HTMLSpanElement | undefined = $state();
|
|
49
|
-
</script>
|
|
50
|
-
|
|
51
|
-
<button
|
|
52
|
-
{type}
|
|
53
|
-
class:call-to-action={colourSet === ColourSet.Primary || colourSet === ColourSet.CallToAction}
|
|
54
|
-
{disabled}
|
|
55
|
-
class:left={side == Side.Left}
|
|
56
|
-
class:right={side == Side.Right}
|
|
57
|
-
class:top={side == Side.Top}
|
|
58
|
-
class:bottom={side == Side.Bottom}
|
|
59
|
-
bind:this={ref}
|
|
60
|
-
aria-label={label}
|
|
61
|
-
{onclick}
|
|
62
|
-
{onfocus}
|
|
63
|
-
{onblur}
|
|
64
|
-
oncontextmenu={(e) => {
|
|
65
|
-
if (onEditBarcode) {
|
|
66
|
-
e.preventDefault();
|
|
67
|
-
onEditBarcode();
|
|
68
|
-
}
|
|
69
|
-
}}
|
|
70
|
-
onkeydown={passthrough}
|
|
71
|
-
>
|
|
72
|
-
{#if isMounted && icon}
|
|
73
|
-
<div
|
|
74
|
-
class="expand"
|
|
75
|
-
class:left={side == Side.Left}
|
|
76
|
-
class:right={side == Side.Right}
|
|
77
|
-
class:top={side == Side.Top}
|
|
78
|
-
class:bottom={side == Side.Bottom}
|
|
79
|
-
>
|
|
80
|
-
{#if icon instanceof SVGSVGElement}
|
|
81
|
-
<!-- SECURITY: UtilityButton accepts a generic SVGSVGElement here for backwards
|
|
82
|
-
compatibility. The cast to DataMatrixSvg trusts the caller; DataMatrixIcon
|
|
83
|
-
additionally sanitises the cloned subtree before mounting. -->
|
|
84
|
-
<DataMatrixIcon
|
|
85
|
-
title={slotSpan?.textContent ?? '{unknown}'}
|
|
86
|
-
icon={{ kind: 'svg', svg: icon as DataMatrixSvg }}
|
|
87
|
-
/>
|
|
88
|
-
{:else}
|
|
89
|
-
{#if notifications}
|
|
90
|
-
<span class="notification">{notifications}</span>
|
|
91
|
-
{/if}
|
|
92
|
-
|
|
93
|
-
<Icon
|
|
94
|
-
{...icon}
|
|
95
|
-
{size}
|
|
96
|
-
/>
|
|
97
|
-
{/if}
|
|
98
|
-
</div>
|
|
99
|
-
{/if}
|
|
100
|
-
<span class="utility-label">
|
|
101
|
-
{#if notifications && icon instanceof SVGSVGElement}
|
|
102
|
-
<span class="notification-on-text">{notifications}</span>
|
|
103
|
-
{/if}<span bind:this={slotSpan}
|
|
104
|
-
>{#if children}{@render children()}{/if}</span
|
|
105
|
-
>
|
|
106
|
-
</span>
|
|
107
|
-
</button>
|
|
108
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script lang="ts">
|
|
4
|
+
import { passthrough } from '../../Helpers/Helpers.svelte.js';
|
|
5
|
+
import { ColourSet } from '../../scss/colours.js';
|
|
6
|
+
import { Side } from '../../Types/Internal/Side.js';
|
|
7
|
+
import { Size } from '../../Types/Internal/Size.js';
|
|
8
|
+
import { onMount } from 'svelte';
|
|
9
|
+
import DataMatrixIcon from '../DataMatrixIcon.svelte';
|
|
10
|
+
import Icon from '../Icon.svelte';
|
|
11
|
+
import type { DataMatrixSvg } from '../DataMatrixIconProps.js';
|
|
12
|
+
import type { UtilityButtonProps } from './UtilityButtonProps.js';
|
|
13
|
+
let {
|
|
14
|
+
type = 'button',
|
|
15
|
+
colourSet = ColourSet.Secondary,
|
|
16
|
+
icon,
|
|
17
|
+
side = Side.Top,
|
|
18
|
+
size: explicitSize,
|
|
19
|
+
notifications,
|
|
20
|
+
ref = $bindable(),
|
|
21
|
+
disabled = false,
|
|
22
|
+
label,
|
|
23
|
+
onEditBarcode,
|
|
24
|
+
onclick,
|
|
25
|
+
onfocus,
|
|
26
|
+
onblur,
|
|
27
|
+
children,
|
|
28
|
+
}: UtilityButtonProps = $props();
|
|
29
|
+
|
|
30
|
+
let isMounted = $state(false);
|
|
31
|
+
|
|
32
|
+
onMount(() => {
|
|
33
|
+
isMounted = true;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const size: Size = $derived.by(() => {
|
|
37
|
+
if (!isMounted) {
|
|
38
|
+
return Size.DoubleXLarge;
|
|
39
|
+
}
|
|
40
|
+
if (explicitSize !== undefined) {
|
|
41
|
+
return explicitSize;
|
|
42
|
+
}
|
|
43
|
+
if (icon instanceof SVGSVGElement) {
|
|
44
|
+
return Size.DoubleXLarge;
|
|
45
|
+
}
|
|
46
|
+
return icon?.size ?? Size.DoubleXLarge;
|
|
47
|
+
});
|
|
48
|
+
let slotSpan: HTMLSpanElement | undefined = $state();
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<button
|
|
52
|
+
{type}
|
|
53
|
+
class:call-to-action={colourSet === ColourSet.Primary || colourSet === ColourSet.CallToAction}
|
|
54
|
+
{disabled}
|
|
55
|
+
class:left={side == Side.Left}
|
|
56
|
+
class:right={side == Side.Right}
|
|
57
|
+
class:top={side == Side.Top}
|
|
58
|
+
class:bottom={side == Side.Bottom}
|
|
59
|
+
bind:this={ref}
|
|
60
|
+
aria-label={label}
|
|
61
|
+
{onclick}
|
|
62
|
+
{onfocus}
|
|
63
|
+
{onblur}
|
|
64
|
+
oncontextmenu={(e) => {
|
|
65
|
+
if (onEditBarcode) {
|
|
66
|
+
e.preventDefault();
|
|
67
|
+
onEditBarcode();
|
|
68
|
+
}
|
|
69
|
+
}}
|
|
70
|
+
onkeydown={passthrough}
|
|
71
|
+
>
|
|
72
|
+
{#if isMounted && icon}
|
|
73
|
+
<div
|
|
74
|
+
class="expand"
|
|
75
|
+
class:left={side == Side.Left}
|
|
76
|
+
class:right={side == Side.Right}
|
|
77
|
+
class:top={side == Side.Top}
|
|
78
|
+
class:bottom={side == Side.Bottom}
|
|
79
|
+
>
|
|
80
|
+
{#if icon instanceof SVGSVGElement}
|
|
81
|
+
<!-- SECURITY: UtilityButton accepts a generic SVGSVGElement here for backwards
|
|
82
|
+
compatibility. The cast to DataMatrixSvg trusts the caller; DataMatrixIcon
|
|
83
|
+
additionally sanitises the cloned subtree before mounting. -->
|
|
84
|
+
<DataMatrixIcon
|
|
85
|
+
title={slotSpan?.textContent ?? '{unknown}'}
|
|
86
|
+
icon={{ kind: 'svg', svg: icon as DataMatrixSvg }}
|
|
87
|
+
/>
|
|
88
|
+
{:else}
|
|
89
|
+
{#if notifications}
|
|
90
|
+
<span class="notification">{notifications}</span>
|
|
91
|
+
{/if}
|
|
92
|
+
|
|
93
|
+
<Icon
|
|
94
|
+
{...icon}
|
|
95
|
+
{size}
|
|
96
|
+
/>
|
|
97
|
+
{/if}
|
|
98
|
+
</div>
|
|
99
|
+
{/if}
|
|
100
|
+
<span class="utility-label">
|
|
101
|
+
{#if notifications && icon instanceof SVGSVGElement}
|
|
102
|
+
<span class="notification-on-text">{notifications}</span>
|
|
103
|
+
{/if}<span bind:this={slotSpan}
|
|
104
|
+
>{#if children}{@render children()}{/if}</span
|
|
105
|
+
>
|
|
106
|
+
</span>
|
|
107
|
+
</button>
|
|
108
|
+
|
|
109
109
|
<style>button {
|
|
110
110
|
background-color: #f4f7f9;
|
|
111
111
|
box-sizing: border-box;
|
|
@@ -194,4 +194,4 @@ button:not([disabled]).call-to-action:not([disabled]):focus, button:not([disable
|
|
|
194
194
|
}
|
|
195
195
|
button:not([disabled]).call-to-action:not([disabled]):focus {
|
|
196
196
|
outline-offset: -2px;
|
|
197
|
-
}</style>
|
|
197
|
+
}</style>
|
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
lang="ts"
|
|
5
|
-
generics="CommonDenominator"
|
|
6
|
-
>
|
|
7
|
-
import { readJSON } from '../Helpers/Storage.js';
|
|
8
|
-
import { onMount, untrack } from 'svelte';
|
|
9
|
-
import VerticalTabGroupButton from './VerticalTabGroupButton.svelte';
|
|
10
|
-
import type { VerticalTabGroupProps } from './VerticalTabGroupProps.js';
|
|
11
|
-
const {
|
|
12
|
-
name,
|
|
13
|
-
tabs,
|
|
14
|
-
selected,
|
|
15
|
-
style,
|
|
16
|
-
noscroll,
|
|
17
|
-
noTabMessage,
|
|
18
|
-
nohistory = false,
|
|
19
|
-
dense = false,
|
|
20
|
-
}: VerticalTabGroupProps<CommonDenominator> = $props();
|
|
21
|
-
|
|
22
|
-
const isNonEmptyString = (raw: unknown): raw is string =>
|
|
23
|
-
typeof raw === 'string' && raw.length > 0;
|
|
24
|
-
|
|
25
|
-
const storageKey = (key: string): string => `scoria-vertical-tab-group:${key}:active-tab`;
|
|
26
|
-
|
|
27
|
-
onMount(() => {
|
|
28
|
-
if (name && !nohistory) {
|
|
29
|
-
const tabName = readJSON(sessionStorage, storageKey(name), isNonEmptyString, '');
|
|
30
|
-
if (tabName) {
|
|
31
|
-
tabs.find((it) => it.label === tabName)?.onclick();
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
$effect(() => {
|
|
37
|
-
if (name && selected) {
|
|
38
|
-
untrack(() => {
|
|
39
|
-
try {
|
|
40
|
-
sessionStorage.setItem(storageKey(name), JSON.stringify(selected.label));
|
|
41
|
-
} catch {
|
|
42
|
-
// storage unavailable (private browsing, quota); persistence is best-effort
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
</script>
|
|
48
|
-
|
|
49
|
-
<div
|
|
50
|
-
class="wrapper"
|
|
51
|
-
class:noscroll
|
|
52
|
-
class:dense
|
|
53
|
-
{style}
|
|
54
|
-
>
|
|
55
|
-
<div class="tabs">
|
|
56
|
-
{#each tabs as option (option.label)}
|
|
57
|
-
<VerticalTabGroupButton
|
|
58
|
-
{option}
|
|
59
|
-
selected={selected?.label === option.label}
|
|
60
|
-
/>
|
|
61
|
-
{/each}
|
|
62
|
-
</div>
|
|
63
|
-
|
|
64
|
-
<div
|
|
65
|
-
class="content"
|
|
66
|
-
class:noscroll
|
|
67
|
-
class:dense
|
|
68
|
-
>
|
|
69
|
-
{#if selected}
|
|
70
|
-
{@render selected.content(selected.args)}
|
|
71
|
-
{:else}
|
|
72
|
-
<div class="wrapper bg">
|
|
73
|
-
<span class="red">{noTabMessage ?? 'No Tab Selected'}</span>
|
|
74
|
-
</div>
|
|
75
|
-
{/if}
|
|
76
|
-
</div>
|
|
77
|
-
</div>
|
|
78
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
generics="CommonDenominator"
|
|
6
|
+
>
|
|
7
|
+
import { readJSON } from '../Helpers/Storage.js';
|
|
8
|
+
import { onMount, untrack } from 'svelte';
|
|
9
|
+
import VerticalTabGroupButton from './VerticalTabGroupButton.svelte';
|
|
10
|
+
import type { VerticalTabGroupProps } from './VerticalTabGroupProps.js';
|
|
11
|
+
const {
|
|
12
|
+
name,
|
|
13
|
+
tabs,
|
|
14
|
+
selected,
|
|
15
|
+
style,
|
|
16
|
+
noscroll,
|
|
17
|
+
noTabMessage,
|
|
18
|
+
nohistory = false,
|
|
19
|
+
dense = false,
|
|
20
|
+
}: VerticalTabGroupProps<CommonDenominator> = $props();
|
|
21
|
+
|
|
22
|
+
const isNonEmptyString = (raw: unknown): raw is string =>
|
|
23
|
+
typeof raw === 'string' && raw.length > 0;
|
|
24
|
+
|
|
25
|
+
const storageKey = (key: string): string => `scoria-vertical-tab-group:${key}:active-tab`;
|
|
26
|
+
|
|
27
|
+
onMount(() => {
|
|
28
|
+
if (name && !nohistory) {
|
|
29
|
+
const tabName = readJSON(sessionStorage, storageKey(name), isNonEmptyString, '');
|
|
30
|
+
if (tabName) {
|
|
31
|
+
tabs.find((it) => it.label === tabName)?.onclick();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
$effect(() => {
|
|
37
|
+
if (name && selected) {
|
|
38
|
+
untrack(() => {
|
|
39
|
+
try {
|
|
40
|
+
sessionStorage.setItem(storageKey(name), JSON.stringify(selected.label));
|
|
41
|
+
} catch {
|
|
42
|
+
// storage unavailable (private browsing, quota); persistence is best-effort
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<div
|
|
50
|
+
class="wrapper"
|
|
51
|
+
class:noscroll
|
|
52
|
+
class:dense
|
|
53
|
+
{style}
|
|
54
|
+
>
|
|
55
|
+
<div class="tabs">
|
|
56
|
+
{#each tabs as option (option.label)}
|
|
57
|
+
<VerticalTabGroupButton
|
|
58
|
+
{option}
|
|
59
|
+
selected={selected?.label === option.label}
|
|
60
|
+
/>
|
|
61
|
+
{/each}
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<div
|
|
65
|
+
class="content"
|
|
66
|
+
class:noscroll
|
|
67
|
+
class:dense
|
|
68
|
+
>
|
|
69
|
+
{#if selected}
|
|
70
|
+
{@render selected.content(selected.args)}
|
|
71
|
+
{:else}
|
|
72
|
+
<div class="wrapper bg">
|
|
73
|
+
<span class="red">{noTabMessage ?? 'No Tab Selected'}</span>
|
|
74
|
+
</div>
|
|
75
|
+
{/if}
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
79
|
<style>.bg {
|
|
80
80
|
padding: 1.5rem;
|
|
81
81
|
background-color: #f9e9e9;
|
|
@@ -124,4 +124,4 @@
|
|
|
124
124
|
.wrapper .content.dense {
|
|
125
125
|
flex-grow: 0;
|
|
126
126
|
overflow: visible;
|
|
127
|
-
}</style>
|
|
127
|
+
}</style>
|
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
lang="ts"
|
|
5
|
-
generics="Args"
|
|
6
|
-
>
|
|
7
|
-
import { useAsyncFlag } from '../Helpers/AsyncFlag.svelte.js';
|
|
8
|
-
import { Colour } from '../scss/colours.js';
|
|
9
|
-
import { Size } from '../Types/Internal/Size.js';
|
|
10
|
-
import Icon from './Icon.svelte';
|
|
11
|
-
import type { TabGroupButtonProps } from './TabGroupButtonProps.js';
|
|
12
|
-
|
|
13
|
-
const { option, selected }: TabGroupButtonProps<Args> = $props();
|
|
14
|
-
|
|
15
|
-
const isValid = useAsyncFlag(() => option.isValid, true);
|
|
16
|
-
const disabled = useAsyncFlag(() => option.disabled, false);
|
|
17
|
-
const visible = useAsyncFlag(() => option.visible, true);
|
|
18
|
-
</script>
|
|
19
|
-
|
|
20
|
-
<button
|
|
21
|
-
class:selected
|
|
22
|
-
disabled={disabled.value}
|
|
23
|
-
onclick={() => {
|
|
24
|
-
option.onclick();
|
|
25
|
-
}}
|
|
26
|
-
type="button"
|
|
27
|
-
class="tab"
|
|
28
|
-
class:invalid={!isValid.value}
|
|
29
|
-
class:hidden={!visible.value}
|
|
30
|
-
>
|
|
31
|
-
<div
|
|
32
|
-
class="bordered"
|
|
33
|
-
class:invalid={!isValid.value}
|
|
34
|
-
>
|
|
35
|
-
{#if option.iconLeft}
|
|
36
|
-
<Icon
|
|
37
|
-
{...option.iconLeft}
|
|
38
|
-
colour={Colour['$brand-primary']}
|
|
39
|
-
/>
|
|
40
|
-
{/if}
|
|
41
|
-
{option.label}
|
|
42
|
-
{#if !isValid.value}
|
|
43
|
-
<Icon
|
|
44
|
-
name="error"
|
|
45
|
-
colour={Colour['$error-border']}
|
|
46
|
-
size={Size.Small}
|
|
47
|
-
/>
|
|
48
|
-
{:else if option.iconRight}
|
|
49
|
-
<Icon
|
|
50
|
-
colour={Colour['$brand-primary']}
|
|
51
|
-
size={Size.Small}
|
|
52
|
-
{...option.iconRight}
|
|
53
|
-
/>
|
|
54
|
-
{/if}
|
|
55
|
-
</div>
|
|
56
|
-
</button>
|
|
57
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
generics="Args"
|
|
6
|
+
>
|
|
7
|
+
import { useAsyncFlag } from '../Helpers/AsyncFlag.svelte.js';
|
|
8
|
+
import { Colour } from '../scss/colours.js';
|
|
9
|
+
import { Size } from '../Types/Internal/Size.js';
|
|
10
|
+
import Icon from './Icon.svelte';
|
|
11
|
+
import type { TabGroupButtonProps } from './TabGroupButtonProps.js';
|
|
12
|
+
|
|
13
|
+
const { option, selected }: TabGroupButtonProps<Args> = $props();
|
|
14
|
+
|
|
15
|
+
const isValid = useAsyncFlag(() => option.isValid, true);
|
|
16
|
+
const disabled = useAsyncFlag(() => option.disabled, false);
|
|
17
|
+
const visible = useAsyncFlag(() => option.visible, true);
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<button
|
|
21
|
+
class:selected
|
|
22
|
+
disabled={disabled.value}
|
|
23
|
+
onclick={() => {
|
|
24
|
+
option.onclick();
|
|
25
|
+
}}
|
|
26
|
+
type="button"
|
|
27
|
+
class="tab"
|
|
28
|
+
class:invalid={!isValid.value}
|
|
29
|
+
class:hidden={!visible.value}
|
|
30
|
+
>
|
|
31
|
+
<div
|
|
32
|
+
class="bordered"
|
|
33
|
+
class:invalid={!isValid.value}
|
|
34
|
+
>
|
|
35
|
+
{#if option.iconLeft}
|
|
36
|
+
<Icon
|
|
37
|
+
{...option.iconLeft}
|
|
38
|
+
colour={Colour['$brand-primary']}
|
|
39
|
+
/>
|
|
40
|
+
{/if}
|
|
41
|
+
{option.label}
|
|
42
|
+
{#if !isValid.value}
|
|
43
|
+
<Icon
|
|
44
|
+
name="error"
|
|
45
|
+
colour={Colour['$error-border']}
|
|
46
|
+
size={Size.Small}
|
|
47
|
+
/>
|
|
48
|
+
{:else if option.iconRight}
|
|
49
|
+
<Icon
|
|
50
|
+
colour={Colour['$brand-primary']}
|
|
51
|
+
size={Size.Small}
|
|
52
|
+
{...option.iconRight}
|
|
53
|
+
/>
|
|
54
|
+
{/if}
|
|
55
|
+
</div>
|
|
56
|
+
</button>
|
|
57
|
+
|
|
58
58
|
<style>button.tab.hidden {
|
|
59
59
|
display: none !important;
|
|
60
60
|
}
|
|
@@ -101,4 +101,4 @@
|
|
|
101
101
|
}
|
|
102
102
|
.tab.selected.invalid {
|
|
103
103
|
border-bottom-color: #aa1414;
|
|
104
|
-
}</style>
|
|
104
|
+
}</style>
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import type { DataMatrixSvg } from '../Components/DataMatrixIconProps.js';
|
|
2
|
-
|
|
3
|
-
export interface IDatamatrixOptions {
|
|
4
|
-
msg: string;
|
|
5
|
-
dim?: number;
|
|
6
|
-
rct?: number;
|
|
7
|
-
pad?: number;
|
|
8
|
-
pal?: [string, string];
|
|
9
|
-
vrb?: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Build a DATAMatrix barcode SVG. The returned element is branded as
|
|
14
|
-
* {@link DataMatrixSvg} so it can be passed directly to
|
|
15
|
-
* `DataMatrixIcon` without further casting. The underlying JS
|
|
16
|
-
* implementation produces a vanilla `SVGSVGElement`; the brand is a
|
|
17
|
-
* compile-time discipline only.
|
|
18
|
-
*/
|
|
19
|
-
export declare function DATAMatrix(value: IDatamatrixOptions | string): DataMatrixSvg;
|
|
1
|
+
import type { DataMatrixSvg } from '../Components/DataMatrixIconProps.js';
|
|
2
|
+
|
|
3
|
+
export interface IDatamatrixOptions {
|
|
4
|
+
msg: string;
|
|
5
|
+
dim?: number;
|
|
6
|
+
rct?: number;
|
|
7
|
+
pad?: number;
|
|
8
|
+
pal?: [string, string];
|
|
9
|
+
vrb?: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Build a DATAMatrix barcode SVG. The returned element is branded as
|
|
14
|
+
* {@link DataMatrixSvg} so it can be passed directly to
|
|
15
|
+
* `DataMatrixIcon` without further casting. The underlying JS
|
|
16
|
+
* implementation produces a vanilla `SVGSVGElement`; the brand is a
|
|
17
|
+
* compile-time discipline only.
|
|
18
|
+
*/
|
|
19
|
+
export declare function DATAMatrix(value: IDatamatrixOptions | string): DataMatrixSvg;
|