@lavalogic/scoria 0.40.13 → 0.40.15
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 +35 -46
- package/dist/Components/AccordionGroupButton.svelte +68 -76
- package/dist/Components/Action.svelte +103 -135
- package/dist/Components/AlertModal.svelte +171 -190
- package/dist/Components/AppointmentCalendar/AppointmentCalendar.svelte +614 -697
- package/dist/Components/Base/BaseModal.svelte +90 -116
- package/dist/Components/Base/ContextWrapper.svelte +67 -72
- package/dist/Components/Base/Pagination.svelte +173 -196
- package/dist/Components/Base/Snippets.svelte +34 -36
- package/dist/Components/BigRadioSet.svelte +36 -38
- package/dist/Components/Bubble.svelte +78 -101
- package/dist/Components/Button.svelte +175 -208
- package/dist/Components/Checkbox.svelte +75 -86
- package/dist/Components/CollapsibleCard.svelte +72 -87
- package/dist/Components/CollapsibleMenuGroup.svelte +53 -57
- package/dist/Components/ConditionBuilder/ConditionBuilder.svelte +39 -64
- package/dist/Components/Contexts/ContextMenu.svelte +141 -156
- package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
- package/dist/Components/Contexts/ContextMenuOption.svelte +53 -60
- package/dist/Components/Contexts/Toast.svelte +81 -86
- package/dist/Components/Contexts/ToastContainer.svelte +58 -62
- package/dist/Components/Contexts/Tooltip.svelte +36 -37
- package/dist/Components/DataMatrixIcon.svelte +95 -108
- package/dist/Components/DateInput.svelte +118 -146
- package/dist/Components/DatePicker.svelte +255 -294
- package/dist/Components/DesktopModal.svelte +70 -90
- package/dist/Components/Dial.svelte +167 -197
- package/dist/Components/DimensionInput.svelte +124 -169
- package/dist/Components/DragMenu/DragMenuHolder.svelte +98 -114
- package/dist/Components/DragMenu/DraggableCard.svelte +64 -76
- package/dist/Components/FileCard.svelte +21 -24
- package/dist/Components/FileUpload.svelte +190 -225
- package/dist/Components/GridInput.svelte +159 -196
- package/dist/Components/GridInputSet.svelte +24 -29
- package/dist/Components/HorizontalTabGroup.svelte +73 -89
- package/dist/Components/HorizontalTabGroupButton.svelte +40 -44
- package/dist/Components/Icon.svelte +99 -128
- package/dist/Components/Icons.js +357 -357
- package/dist/Components/InfoAlert.svelte +35 -38
- package/dist/Components/LoadingAnimation.svelte +691 -755
- package/dist/Components/LoadingModal.svelte +36 -44
- package/dist/Components/LoadingOverlay.svelte +22 -26
- package/dist/Components/Modal.svelte +204 -254
- package/dist/Components/MultiSelect.svelte +186 -216
- package/dist/Components/Nav/Nav.svelte +94 -110
- package/dist/Components/Nav/NavServiceMenuList.svelte +57 -61
- package/dist/Components/Nav/NavTab.svelte +58 -62
- package/dist/Components/Nav/ServiceMenuItem.svelte +103 -111
- package/dist/Components/Nav/ServicesNav.svelte +72 -79
- package/dist/Components/NumberInput.svelte +121 -155
- package/dist/Components/OptionCards.svelte +62 -73
- package/dist/Components/PageHeading.svelte +23 -25
- package/dist/Components/PasswordInput.svelte +69 -88
- package/dist/Components/PopoverButton.svelte +151 -0
- package/dist/Components/PopoverButton.svelte.d.ts +9 -0
- package/dist/Components/PopoverButtonProps.d.ts +21 -0
- package/dist/Components/PopoverButtonProps.js +1 -0
- package/dist/Components/Portal.svelte +29 -35
- package/dist/Components/ProgressBubble.svelte +91 -106
- package/dist/Components/QuerySelect.svelte +260 -346
- package/dist/Components/SidebarPanel.svelte +34 -36
- package/dist/Components/SingleSelect.svelte +196 -244
- package/dist/Components/StepButton.svelte +65 -70
- package/dist/Components/StepForm.svelte +115 -135
- package/dist/Components/Switch.svelte +57 -69
- package/dist/Components/Table/ARCHITECTURE.md +298 -298
- package/dist/Components/Table/Body/QuickSearchCell.svelte +578 -655
- package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +42 -51
- package/dist/Components/Table/Body/Rows/ColumnList.svelte +42 -58
- package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +403 -442
- package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +51 -78
- package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +165 -184
- package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +110 -123
- package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +134 -160
- package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +190 -231
- package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +82 -104
- package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +52 -87
- package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +122 -150
- package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +132 -159
- package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +190 -236
- package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +173 -211
- package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +204 -244
- package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +140 -177
- package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +188 -217
- package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +173 -193
- package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +166 -187
- package/dist/Components/Table/Body/Rows/TableRow.svelte +245 -288
- package/dist/Components/Table/Body/TableBody.svelte +141 -154
- package/dist/Components/Table/Headers/HighlightAllHeader.svelte +35 -41
- package/dist/Components/Table/Headers/SelectAllHeader.svelte +24 -30
- package/dist/Components/Table/Headers/TableHead.svelte +348 -402
- package/dist/Components/Table/Misc/ColumnPanel.svelte +37 -39
- package/dist/Components/Table/Misc/ColumnPanelModal.svelte +35 -39
- package/dist/Components/Table/Misc/FilterInput.svelte +556 -619
- package/dist/Components/Table/Misc/FilterPanel.svelte +170 -183
- package/dist/Components/Table/Misc/FilterPanelModal.svelte +25 -31
- package/dist/Components/Table/Misc/ShareViewModal.svelte +252 -281
- package/dist/Components/Table/Misc/SidePanel.svelte +32 -35
- package/dist/Components/Table/Misc/TableConfigurationModal.svelte +574 -629
- package/dist/Components/Table/Misc/TableFooter.svelte +326 -332
- package/dist/Components/Table/Misc/TableHorizontalBar.svelte +134 -140
- package/dist/Components/Table/Misc/TableSidebar.svelte +183 -198
- package/dist/Components/Table/Misc/TableViewDropdown.svelte +83 -103
- package/dist/Components/Table/Misc/ToolboxPanel.svelte +83 -100
- package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +88 -107
- package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +163 -190
- package/dist/Components/Table/NestedTable.svelte +102 -128
- package/dist/Components/Table/Table.svelte +531 -663
- package/dist/Components/Test/TestContextConsumer.svelte +11 -13
- package/dist/Components/TextArea.svelte +95 -130
- package/dist/Components/TextInput.svelte +125 -176
- package/dist/Components/ThreeStateRadio.svelte +111 -130
- package/dist/Components/Touch/BoolCard.svelte +33 -45
- package/dist/Components/Touch/DateModal.svelte +164 -204
- package/dist/Components/Touch/EditCard.svelte +48 -59
- package/dist/Components/Touch/InfoCard.svelte +28 -31
- package/dist/Components/Touch/InfoTextCard.svelte +26 -28
- package/dist/Components/Touch/ModalExplanation.svelte +15 -17
- package/dist/Components/Touch/NumberKeyboard.svelte +181 -218
- package/dist/Components/Touch/NumberModal.svelte +59 -79
- package/dist/Components/Touch/PlusMinusCard.svelte +43 -46
- package/dist/Components/Touch/SelectModal.svelte +111 -126
- package/dist/Components/Touch/SummaryCard.svelte +80 -93
- package/dist/Components/Touch/TextAreaModal.svelte +72 -94
- package/dist/Components/Touch/TextModal.svelte +77 -105
- package/dist/Components/Touch/TouchCard.svelte +31 -33
- package/dist/Components/Touch/TouchModal.svelte +214 -270
- package/dist/Components/Touch/UtilityButton.svelte +88 -109
- package/dist/Components/VerticalTabGroup.svelte +60 -78
- package/dist/Components/VerticalTabGroupButton.svelte +54 -58
- package/dist/Helpers/Datamatrix.d.ts +19 -19
- package/dist/Helpers/Datamatrix.js +291 -291
- package/dist/Types/Examples/ExampleModal.svelte +31 -35
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- 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,222 +1,192 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
lang="ts"
|
|
5
|
-
generics="V extends object, VP extends ValueProp<V>"
|
|
6
|
-
>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
valueProp,
|
|
26
|
-
width,
|
|
27
|
-
valueAsObject = true,
|
|
28
|
-
height,
|
|
29
|
-
selectedValues,
|
|
30
|
-
onchange,
|
|
31
|
-
collapseSelection = false,
|
|
32
|
-
name = 'Item',
|
|
33
|
-
disabled,
|
|
34
|
-
required,
|
|
35
|
-
invalid,
|
|
36
|
-
}: MultiSelectProps<V, VP> = $props();
|
|
37
|
-
|
|
38
|
-
const an = $derived(name && vowels.has(name.at(0)?.toLocaleLowerCase() ?? '') ? 'an' : 'a');
|
|
39
|
-
|
|
40
|
-
// Pre-computed set of selected primitive keys. Used in the option snippet
|
|
41
|
-
// to avoid an O(n*m) findIndex sweep per render.
|
|
42
|
-
const selectedKeys = $derived.by(() => {
|
|
43
|
-
const s = new SvelteSet<V[VP]>();
|
|
44
|
-
if (valueAsObject) {
|
|
45
|
-
for (const v of selectedValues as Array<V>) {
|
|
46
|
-
s.add(v[valueProp]);
|
|
47
|
-
}
|
|
48
|
-
} else {
|
|
49
|
-
for (const v of selectedValues as Array<V[VP]>) {
|
|
50
|
-
s.add(v);
|
|
51
|
-
}
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
generics="V extends object, VP extends ValueProp<V>"
|
|
6
|
+
>import { autoPluralise, generateWeakId, vowels } from "../Helpers/Helpers.svelte.js";
|
|
7
|
+
import { attachDropdownPortal } from "../Helpers/dropdownPortal.js";
|
|
8
|
+
import { Colour, ColourSet } from "../scss/colours.js";
|
|
9
|
+
import { Size } from "../Types/Internal/Size.js";
|
|
10
|
+
import Svelecte from "svelecte";
|
|
11
|
+
import { SvelteSet } from "svelte/reactivity";
|
|
12
|
+
import { onMount } from "svelte";
|
|
13
|
+
import Action from "./Action.svelte";
|
|
14
|
+
import Icon from "./Icon.svelte";
|
|
15
|
+
// NOTE selectedValues is mutated by svelecte without asking, so we sometimes have to reverse it without a callback (side effects)
|
|
16
|
+
const { label, inputId = generateWeakId(), options, labelProp, valueProp, width, valueAsObject = true, height, selectedValues, onchange, collapseSelection = false, name = "Item", disabled, required, invalid } = $props();
|
|
17
|
+
const an = $derived(name && vowels.has(name.at(0)?.toLocaleLowerCase() ?? "") ? "an" : "a");
|
|
18
|
+
// Pre-computed set of selected primitive keys. Used in the option snippet
|
|
19
|
+
// to avoid an O(n*m) findIndex sweep per render.
|
|
20
|
+
const selectedKeys = $derived.by(() => {
|
|
21
|
+
const s = new SvelteSet();
|
|
22
|
+
if (valueAsObject) {
|
|
23
|
+
for (const v of selectedValues) {
|
|
24
|
+
s.add(v[valueProp]);
|
|
52
25
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
26
|
+
} else {
|
|
27
|
+
for (const v of selectedValues) {
|
|
28
|
+
s.add(v);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return s;
|
|
32
|
+
});
|
|
33
|
+
let isExpanded = $state(false);
|
|
34
|
+
onMount(() => {
|
|
35
|
+
const input = document.getElementById(inputId);
|
|
36
|
+
const svelecteRoot = input?.closest("div.svelecte");
|
|
37
|
+
const dropdownRef = svelecteRoot?.querySelector(".sv_dropdown") ?? undefined;
|
|
38
|
+
// HACK callback for is-open on/off; drives the chevron rotation
|
|
39
|
+
// in the action snippet further down.
|
|
40
|
+
const observer = new MutationObserver((mutations) => {
|
|
41
|
+
for (let i = mutations.length - 1; i > -1; i--) {
|
|
42
|
+
const mutation = mutations[i];
|
|
43
|
+
if (mutation.attributeName === "class") {
|
|
44
|
+
isExpanded = dropdownRef?.classList.contains("is-open") ?? false;
|
|
72
45
|
}
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
if (dropdownRef) {
|
|
76
|
-
observer.observe(dropdownRef, { attributes: true });
|
|
77
46
|
}
|
|
78
|
-
|
|
79
|
-
// Teleport the Svelecte dropdown to `document.body` while open
|
|
80
|
-
// so it escapes every ancestor `overflow` / `transform` /
|
|
81
|
-
// `z-index` stacking context. See `Helpers/dropdownPortal.ts`
|
|
82
|
-
// for the rationale and behaviour (auto-flip upwards on tight
|
|
83
|
-
// viewports, scroll-aware repositioning, viewport-bounded
|
|
84
|
-
// max-height).
|
|
85
|
-
const detachPortal = attachDropdownPortal({
|
|
86
|
-
getTrigger: () => svelecteRoot,
|
|
87
|
-
getDropdown: () => dropdownRef,
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
return () => {
|
|
91
|
-
observer.disconnect();
|
|
92
|
-
detachPortal();
|
|
93
|
-
};
|
|
94
47
|
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
{
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
<
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
{
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
48
|
+
if (dropdownRef) {
|
|
49
|
+
observer.observe(dropdownRef, { attributes: true });
|
|
50
|
+
}
|
|
51
|
+
// Teleport the Svelecte dropdown to `document.body` while open
|
|
52
|
+
// so it escapes every ancestor `overflow` / `transform` /
|
|
53
|
+
// `z-index` stacking context. See `Helpers/dropdownPortal.ts`
|
|
54
|
+
// for the rationale and behaviour (auto-flip upwards on tight
|
|
55
|
+
// viewports, scroll-aware repositioning, viewport-bounded
|
|
56
|
+
// max-height).
|
|
57
|
+
const detachPortal = attachDropdownPortal({
|
|
58
|
+
getTrigger: () => svelecteRoot,
|
|
59
|
+
getDropdown: () => dropdownRef
|
|
60
|
+
});
|
|
61
|
+
return () => {
|
|
62
|
+
observer.disconnect();
|
|
63
|
+
detachPortal();
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
const isInvalid = $derived(required && !selectedValues.length || invalid);
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<div
|
|
70
|
+
class:invalid={isInvalid}
|
|
71
|
+
class="select-wrapper"
|
|
72
|
+
style={`${width ? `--input-width: ${width};` : ''}${height ? `--input-height: ${height};` : ''}`}
|
|
73
|
+
>
|
|
74
|
+
{#if label}
|
|
75
|
+
<label for={inputId}>
|
|
76
|
+
<span>{label}</span>
|
|
77
|
+
<span class="border">{label}</span>
|
|
78
|
+
</label>
|
|
79
|
+
{/if}
|
|
80
|
+
|
|
81
|
+
<Svelecte
|
|
82
|
+
multiple
|
|
83
|
+
{valueAsObject}
|
|
84
|
+
{disabled}
|
|
85
|
+
{inputId}
|
|
86
|
+
valueField={valueProp}
|
|
87
|
+
labelField={labelProp}
|
|
88
|
+
{options}
|
|
89
|
+
searchable
|
|
90
|
+
value={selectedValues}
|
|
91
|
+
onChange={(e: Array<V>) => {
|
|
92
|
+
// svelecte always emits the full option objects; normalise to the
|
|
93
|
+
// shape the variant promised: primitives for AsPrimitive,
|
|
94
|
+
// objects for AsObject. This is what the discriminated
|
|
95
|
+
// `onchange` typing now guarantees to consumers.
|
|
96
|
+
if (valueAsObject) {
|
|
97
|
+
void (onchange as (v: Array<V>) => void | Promise<void>)(e);
|
|
98
|
+
} else {
|
|
99
|
+
const primitives = e.map((it) => it[valueProp]);
|
|
100
|
+
void (onchange as (v: Array<V[VP]>) => void | Promise<void>)(primitives);
|
|
101
|
+
}
|
|
102
|
+
}}
|
|
103
|
+
{name}
|
|
104
|
+
selectOnTab
|
|
105
|
+
keepSelectionInList
|
|
106
|
+
searchProps={{ keepSelectionInList: true }}
|
|
107
|
+
creatable={false}
|
|
108
|
+
collapseSelection={collapseSelection ? 'always' : null}
|
|
109
|
+
deselectMode="toggle"
|
|
110
|
+
highlightFirstItem={false}
|
|
111
|
+
placeholder="Please Select {name ? `${an} ${name}` : ''}"
|
|
112
|
+
selection={collapseSelection ? selection : undefined}
|
|
113
|
+
>
|
|
114
|
+
{#snippet option(opt)}
|
|
115
|
+
{@const option = opt as V}
|
|
116
|
+
<span class="dropdown-item">
|
|
117
|
+
<div
|
|
118
|
+
class="toggle-icon"
|
|
119
|
+
class:yes={selectedKeys.has(option[valueProp])}
|
|
120
|
+
>
|
|
121
|
+
<Icon
|
|
122
|
+
name="tick"
|
|
123
|
+
size={Size.MediumSmall}
|
|
124
|
+
/>
|
|
125
|
+
</div>
|
|
126
|
+
{option[labelProp]}</span
|
|
127
|
+
>
|
|
128
|
+
{/snippet}
|
|
129
|
+
|
|
130
|
+
{#snippet collapsedSelection(selectedOptions: Array<object> /*_i18n*/)}
|
|
131
|
+
<span class="selection"
|
|
132
|
+
>{#if selectedOptions.length}{selectedOptions.length}
|
|
133
|
+
{#if name}{autoPluralise(name, selectedOptions.length)}{/if} Selected
|
|
134
|
+
{:else}Please Select {#if name}
|
|
135
|
+
{an} {name}{/if}
|
|
136
|
+
{/if}</span
|
|
137
|
+
>
|
|
138
|
+
{/snippet}
|
|
139
|
+
|
|
140
|
+
{#snippet append()}
|
|
141
|
+
<div class="icons">
|
|
142
|
+
<Action
|
|
143
|
+
{disabled}
|
|
144
|
+
size={Size.Small}
|
|
145
|
+
noTabIndex
|
|
146
|
+
colourSet={ColourSet.Auxiliary}
|
|
147
|
+
onclick={(e: MouseEvent) => {
|
|
148
|
+
if (isExpanded) {
|
|
149
|
+
e.stopPropagation();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (selectedValues.length) {
|
|
153
|
+
// Empty array satisfies both Array<V> and Array<V[VP]>.
|
|
154
|
+
void (onchange as (v: Array<V> | Array<V[VP]>) => void | Promise<void>)([]);
|
|
155
|
+
} else if (valueAsObject) {
|
|
156
|
+
void (onchange as (v: Array<V>) => void | Promise<void>)(options.concat());
|
|
157
|
+
} else {
|
|
158
|
+
const primitives = options.map((it) => it[valueProp]);
|
|
159
|
+
void (onchange as (v: Array<V[VP]>) => void | Promise<void>)(primitives);
|
|
160
|
+
}
|
|
161
|
+
}}
|
|
162
|
+
icon={{
|
|
163
|
+
name: selectedValues.length ? 'close-menu-cross' : 'manage-product-group',
|
|
164
|
+
colour: Colour['$ui-blue-10'],
|
|
165
|
+
}}
|
|
166
|
+
/>
|
|
167
|
+
|
|
168
|
+
<Action
|
|
169
|
+
{disabled}
|
|
170
|
+
size={Size.Small}
|
|
171
|
+
noTabIndex
|
|
172
|
+
colourSet={ColourSet.Auxiliary}
|
|
173
|
+
icon={{
|
|
174
|
+
name: isExpanded ? 'chevron-up' : 'chevron-down',
|
|
175
|
+
colour: Colour['$ui-blue-10'],
|
|
176
|
+
}}
|
|
177
|
+
/>
|
|
178
|
+
</div>
|
|
179
|
+
{/snippet}
|
|
180
|
+
{#snippet toggleIcon()}
|
|
181
|
+
<div class="nothing"></div>
|
|
182
|
+
{/snippet}
|
|
183
|
+
</Svelecte>
|
|
184
|
+
|
|
185
|
+
{#snippet selection(/*_selectedOptions: Array<unknown>*/)}
|
|
186
|
+
<!-- collapsed selection rendered above -->
|
|
187
|
+
{/snippet}
|
|
188
|
+
</div>
|
|
189
|
+
|
|
220
190
|
<style>.select-wrapper {
|
|
221
191
|
min-width: var(--input-min-width, 12rem);
|
|
222
192
|
width: var(--input-width, 100%);
|
|
@@ -379,4 +349,4 @@ div.icons {
|
|
|
379
349
|
}
|
|
380
350
|
:global(.dropdown-item) .toggle-icon.yes {
|
|
381
351
|
opacity: 1;
|
|
382
|
-
}</style>
|
|
352
|
+
}</style>
|
|
@@ -1,112 +1,96 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
lang="ts"
|
|
5
|
-
generics="T"
|
|
6
|
-
>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
<span
|
|
95
|
-
class="user-icon"
|
|
96
|
-
class:visible={hasLetters}
|
|
97
|
-
class:single-letter={singleLetter}>{userIcon}</span
|
|
98
|
-
>
|
|
99
|
-
<span class="user-name">{userName}</span>
|
|
100
|
-
</span>
|
|
101
|
-
</button>
|
|
102
|
-
{#if showUserDialog}
|
|
103
|
-
{@render userDialog(() => {
|
|
104
|
-
showUserDialog = false;
|
|
105
|
-
})}
|
|
106
|
-
{/if}
|
|
107
|
-
</div>
|
|
108
|
-
</nav>
|
|
109
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
generics="T"
|
|
6
|
+
>import { afterNavigate } from "$app/navigation";
|
|
7
|
+
import { Size } from "../../Types/Internal/Size.js";
|
|
8
|
+
import Icon from "../Icon.svelte";
|
|
9
|
+
import ServicesNav from "./ServicesNav.svelte";
|
|
10
|
+
const { userName, extras, userDialog, serviceTabs, selectedServiceTab, brand } = $props();
|
|
11
|
+
const userIcon = $derived.by(() => {
|
|
12
|
+
const names = userName.split(" ");
|
|
13
|
+
const initials = names.map((it) => it.charAt(0)).slice(0, 2);
|
|
14
|
+
return initials;
|
|
15
|
+
});
|
|
16
|
+
const singleLetter = $derived(userIcon.length === 1);
|
|
17
|
+
const hasLetters = $derived(userIcon.length > 0);
|
|
18
|
+
let showServicesDialog = $state(false);
|
|
19
|
+
let showUserDialog = $state(false);
|
|
20
|
+
// Close both nav popovers after any navigation. Selecting an item in
|
|
21
|
+
// the Services menu is a navigation, so the menu must dismiss itself —
|
|
22
|
+
// without this it only closed when the consumer happened to remount
|
|
23
|
+
// `<Nav>` (e.g. on a main-area change), leaving it open when the user
|
|
24
|
+
// picked a sibling item within the same area.
|
|
25
|
+
afterNavigate(() => {
|
|
26
|
+
showServicesDialog = false;
|
|
27
|
+
showUserDialog = false;
|
|
28
|
+
});
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<nav class="main-navigation">
|
|
32
|
+
{#if typeof brand === 'string'}
|
|
33
|
+
<span class="nav-link brand">{brand}</span>
|
|
34
|
+
{:else if brand}
|
|
35
|
+
<span class="nav-link brand">{@render brand()}</span>
|
|
36
|
+
{/if}
|
|
37
|
+
|
|
38
|
+
<div class="nav-link">
|
|
39
|
+
<button
|
|
40
|
+
onclick={() => {
|
|
41
|
+
showServicesDialog = !showServicesDialog;
|
|
42
|
+
}}
|
|
43
|
+
>
|
|
44
|
+
<div class="delimited">
|
|
45
|
+
<Icon
|
|
46
|
+
name="block-menu"
|
|
47
|
+
size={Size.Medium}
|
|
48
|
+
/>
|
|
49
|
+
<span>Services</span>
|
|
50
|
+
</div>
|
|
51
|
+
</button>
|
|
52
|
+
|
|
53
|
+
{#if showServicesDialog}
|
|
54
|
+
<ServicesNav
|
|
55
|
+
onclose={() => {
|
|
56
|
+
showServicesDialog = false;
|
|
57
|
+
}}
|
|
58
|
+
{serviceTabs}
|
|
59
|
+
{selectedServiceTab}
|
|
60
|
+
/>
|
|
61
|
+
{/if}
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<div class="nav-search-container"></div>
|
|
65
|
+
{#if extras}
|
|
66
|
+
<div class="nav-link spaced selects">
|
|
67
|
+
{@render extras()}
|
|
68
|
+
</div>
|
|
69
|
+
{/if}
|
|
70
|
+
|
|
71
|
+
<div>
|
|
72
|
+
<button
|
|
73
|
+
onclick={() => {
|
|
74
|
+
showUserDialog = !showUserDialog;
|
|
75
|
+
}}
|
|
76
|
+
>
|
|
77
|
+
<span class="nav-link padded">
|
|
78
|
+
<span
|
|
79
|
+
class="user-icon"
|
|
80
|
+
class:visible={hasLetters}
|
|
81
|
+
class:single-letter={singleLetter}>{userIcon}</span
|
|
82
|
+
>
|
|
83
|
+
<span class="user-name">{userName}</span>
|
|
84
|
+
</span>
|
|
85
|
+
</button>
|
|
86
|
+
{#if showUserDialog}
|
|
87
|
+
{@render userDialog(() => {
|
|
88
|
+
showUserDialog = false;
|
|
89
|
+
})}
|
|
90
|
+
{/if}
|
|
91
|
+
</div>
|
|
92
|
+
</nav>
|
|
93
|
+
|
|
110
94
|
<style>div.overlay {
|
|
111
95
|
position: fixed;
|
|
112
96
|
top: calc(3.25rem + var(--env-border-height, 0));
|
|
@@ -230,4 +214,4 @@ div.delimited {
|
|
|
230
214
|
align-items: center;
|
|
231
215
|
justify-content: center;
|
|
232
216
|
gap: 0.5rem;
|
|
233
|
-
}</style>
|
|
217
|
+
}</style>
|