@lavalogic/scoria 0.33.0 → 0.35.0

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.
Files changed (130) hide show
  1. package/README.md +58 -58
  2. package/dist/Components/AccordionGroup.svelte +44 -63
  3. package/dist/Components/AccordionGroup.svelte.d.ts +2 -25
  4. package/dist/Components/AccordionGroupButton.svelte +106 -114
  5. package/dist/Components/AccordionGroupButton.svelte.d.ts +2 -2
  6. package/dist/Components/AccordionGroupButtonProps.d.ts +21 -0
  7. package/dist/Components/AccordionGroupButtonProps.js +1 -0
  8. package/dist/Components/Action.svelte +138 -138
  9. package/dist/Components/AlertModal.svelte +125 -125
  10. package/dist/Components/Base/ContextWrapper.svelte +50 -50
  11. package/dist/Components/Base/Pagination.svelte +190 -190
  12. package/dist/Components/Base/Snippets.svelte +29 -29
  13. package/dist/Components/BigRadioSet.svelte +29 -29
  14. package/dist/Components/Bubble.svelte +77 -77
  15. package/dist/Components/Button.svelte +197 -197
  16. package/dist/Components/Checkbox.svelte +68 -68
  17. package/dist/Components/CollapsibleCard.svelte +70 -70
  18. package/dist/Components/Contexts/ContextMenu.svelte +157 -157
  19. package/dist/Components/Contexts/ContextMenuDivider.svelte +11 -11
  20. package/dist/Components/Contexts/ContextMenuOption.svelte +52 -52
  21. package/dist/Components/Contexts/Toast.svelte +61 -61
  22. package/dist/Components/Contexts/ToastContainer.svelte +46 -46
  23. package/dist/Components/Contexts/Tooltip.svelte +26 -26
  24. package/dist/Components/DataMatrixIcon.svelte +41 -41
  25. package/dist/Components/DateInput.svelte +109 -109
  26. package/dist/Components/DatePicker.svelte +312 -312
  27. package/dist/Components/DesktopModal.svelte +106 -106
  28. package/dist/Components/Dial.svelte +151 -151
  29. package/dist/Components/DimensionInput.svelte +184 -184
  30. package/dist/Components/DragMenu/DragMenuHolder.svelte +106 -106
  31. package/dist/Components/DragMenu/DraggableCard.svelte +41 -41
  32. package/dist/Components/FileCard.svelte +20 -20
  33. package/dist/Components/FileUpload.svelte +196 -196
  34. package/dist/Components/GridInput.svelte +190 -190
  35. package/dist/Components/GridInputSet.svelte +22 -22
  36. package/dist/Components/HorizontalTabGroup.svelte +78 -78
  37. package/dist/Components/HorizontalTabGroupButton.svelte +96 -96
  38. package/dist/Components/Icon.svelte +97 -97
  39. package/dist/Components/Icons.js +357 -357
  40. package/dist/Components/LoadingAnimation.svelte +32 -32
  41. package/dist/Components/LoadingModal.svelte +47 -47
  42. package/dist/Components/LoadingOverlay.svelte +27 -27
  43. package/dist/Components/Modal.svelte +251 -251
  44. package/dist/Components/MultiSelect.svelte +197 -197
  45. package/dist/Components/Nav/Nav.svelte +97 -97
  46. package/dist/Components/Nav/NavServiceMenuList.svelte +34 -34
  47. package/dist/Components/Nav/NavTab.svelte +91 -91
  48. package/dist/Components/Nav/ServiceMenuItem.svelte +91 -91
  49. package/dist/Components/Nav/ServicesNav.svelte +53 -53
  50. package/dist/Components/NumberInput.svelte +144 -144
  51. package/dist/Components/PageHeading.svelte +36 -36
  52. package/dist/Components/PasswordInput.svelte +73 -73
  53. package/dist/Components/Portal.svelte +25 -25
  54. package/dist/Components/ProgressBubble.svelte +80 -80
  55. package/dist/Components/QuerySelect.svelte +411 -411
  56. package/dist/Components/SingleSelect.svelte +261 -261
  57. package/dist/Components/StepButton.svelte +120 -120
  58. package/dist/Components/StepForm.svelte +108 -108
  59. package/dist/Components/Switch.svelte +36 -36
  60. package/dist/Components/Table/Body/QuickSearchCell.svelte +632 -632
  61. package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +30 -30
  62. package/dist/Components/Table/Body/Rows/ColumnList.svelte +56 -56
  63. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +179 -179
  64. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +49 -49
  65. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +180 -180
  66. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +102 -102
  67. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +119 -119
  68. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +114 -114
  69. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +96 -96
  70. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +72 -72
  71. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +131 -131
  72. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +144 -144
  73. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +238 -238
  74. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +358 -358
  75. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +338 -338
  76. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +183 -183
  77. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +309 -309
  78. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +369 -369
  79. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +170 -170
  80. package/dist/Components/Table/Body/Rows/TableRow.svelte +259 -259
  81. package/dist/Components/Table/Body/TableBody.svelte +67 -67
  82. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +39 -39
  83. package/dist/Components/Table/Headers/SelectAllHeader.svelte +28 -28
  84. package/dist/Components/Table/Headers/TableHead.svelte +260 -260
  85. package/dist/Components/Table/Misc/ColumnPanel.svelte +78 -78
  86. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +99 -99
  87. package/dist/Components/Table/Misc/FilterInput.svelte +556 -556
  88. package/dist/Components/Table/Misc/FilterPanel.svelte +46 -46
  89. package/dist/Components/Table/Misc/FilterPanelModal.svelte +67 -67
  90. package/dist/Components/Table/Misc/SidePanel.svelte +32 -32
  91. package/dist/Components/Table/Misc/TableFooter.svelte +304 -304
  92. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +156 -156
  93. package/dist/Components/Table/Misc/TableSidebar.svelte +176 -176
  94. package/dist/Components/Table/Misc/ToolboxPanel.svelte +77 -77
  95. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +91 -91
  96. package/dist/Components/Table/NestedTable.svelte +84 -84
  97. package/dist/Components/Table/Table.svelte +492 -492
  98. package/dist/Components/Test/TestContextConsumer.svelte +13 -13
  99. package/dist/Components/TextArea.svelte +108 -108
  100. package/dist/Components/TextInput.svelte +147 -147
  101. package/dist/Components/ThreeStateRadio.svelte +124 -124
  102. package/dist/Components/Touch/BoolCard.svelte +52 -52
  103. package/dist/Components/Touch/DateModal.svelte +217 -217
  104. package/dist/Components/Touch/EditCard.svelte +52 -52
  105. package/dist/Components/Touch/InfoCard.svelte +24 -24
  106. package/dist/Components/Touch/InfoTextCard.svelte +21 -21
  107. package/dist/Components/Touch/ModalExplanation.svelte +20 -20
  108. package/dist/Components/Touch/NumberKeyboard.svelte +268 -268
  109. package/dist/Components/Touch/NumberModal.svelte +69 -69
  110. package/dist/Components/Touch/PlusMinusCard.svelte +50 -50
  111. package/dist/Components/Touch/SelectModal.svelte +105 -105
  112. package/dist/Components/Touch/SummaryCard.svelte +65 -65
  113. package/dist/Components/Touch/TextAreaModal.svelte +86 -86
  114. package/dist/Components/Touch/TextModal.svelte +123 -123
  115. package/dist/Components/Touch/TouchCard.svelte +28 -28
  116. package/dist/Components/Touch/TouchModal.svelte +259 -259
  117. package/dist/Components/Touch/UtilityButton.svelte +91 -91
  118. package/dist/Components/VerticalTabGroup.svelte +66 -66
  119. package/dist/Components/VerticalTabGroupButton.svelte +97 -97
  120. package/dist/Helpers/Datamatrix.d.ts +10 -10
  121. package/dist/Helpers/Datamatrix.js +1 -1
  122. package/dist/Helpers/Helpers.svelte.js +6 -4
  123. package/dist/Types/Examples/ExampleModal.svelte +34 -34
  124. package/dist/index.d.ts +1 -0
  125. package/dist/scss/_basics.scss +12 -12
  126. package/dist/scss/_colours.scss +134 -134
  127. package/dist/scss/_mixins.scss +3016 -3016
  128. package/dist/scss/_sizing.scss +69 -69
  129. package/dist/scss/_transitions.scss +8 -8
  130. package/package.json +2 -2
@@ -1,199 +1,199 @@
1
- <svelte:options runes />
2
-
3
- <script lang="ts" generics="V extends object, VP extends ValueProp<V>">
4
- import { autoPluralise, generateShortUUID, vowels } from '../Helpers/Helpers.svelte.js';
5
- import { Colour, ColourSet } from '../scss/colours.js';
6
- import type { ValueProp } from '../Types/Internal/Misc.js';
7
- import { Size } from '../Types/Internal/Size.js';
8
- import Svelecte from 'svelecte';
9
- import { onMount } from 'svelte';
10
- import Action from './Action.svelte';
11
- import Icon from './Icon.svelte';
12
- import type { MultiSelectProps } from './MultiSelectProps.js';
13
-
14
- // HACK selectedValues is mutated by svelecte without asking, so we sometimes have to reverse it without a callback (side effects)
15
- let {
16
- label,
17
- inputId = generateShortUUID(),
18
- options,
19
- labelProp,
20
- valueProp,
21
- width,
22
- valueAsObject = true,
23
- height,
24
- selectedValues,
25
- onchange,
26
- collapseSelection = false,
27
- name = 'Item',
28
- disabled,
29
- required,
30
- invalid
31
- }: MultiSelectProps<V, VP> = $props();
32
-
33
- const an = $derived(name && vowels.has(name.at(0)?.toLocaleLowerCase() ?? '') ? 'an' : 'a');
34
-
35
- const hidden = $state(false);
36
-
37
- onMount(() => {
38
- const input = document.getElementById(inputId);
39
- // input?.addEventListener('focus', () => {
40
- // hidden = true;
41
- // });
42
- // input?.addEventListener('blur', () => {
43
- // hidden = false;
44
- // });
45
-
46
- // HACK callback for is-open on/off
47
- const dropdownRef = input?.closest('div.svelecte')?.querySelector('.sv_dropdown') ?? undefined;
48
- const observer = new MutationObserver((mutations: Array<MutationRecord>) => {
49
- for (let i = mutations.length - 1; i > -1; i--) {
50
- const mutation = mutations[i];
51
- if (mutation.attributeName === 'class') {
52
- isExpanded = dropdownRef?.classList.contains('is-open') ?? false;
53
- }
54
- }
55
- });
56
-
57
- if (dropdownRef) {
58
- observer.observe(dropdownRef, { attributes: true });
59
- }
60
-
61
- return () => {
62
- observer.disconnect();
63
- };
64
- });
65
-
66
- let isExpanded = $state(false);
67
-
68
- const isInvalid = $derived((required && !selectedValues.length) || invalid);
69
-
70
- function usesValuesAsObjects(_values: Array<V> | Array<V[VP]>): _values is Array<V> {
71
- return valueAsObject;
72
- }
73
-
74
- function usesValuesAsPrimitives(_values: Array<V> | Array<V[VP]>): _values is Array<V[VP]> {
75
- return !valueAsObject;
76
- }
77
- </script>
78
-
79
- <div
80
- class:invalid={isInvalid}
81
- class="select-wrapper"
82
- style={`${width ? `--input-width: ${width};` : ''}${height ? `--input-height: ${height};` : ''}`}
83
- >
84
- {#if label}
85
- <label for={inputId}>
86
- <span>{label}</span>
87
- <span class="border">{label}</span>
88
- </label>
89
- {/if}
90
-
91
- <Svelecte
92
- multiple
93
- {valueAsObject}
94
- {disabled}
95
- {inputId}
96
- valueField={valueProp}
97
- labelField={labelProp}
98
- {options}
99
- searchable
100
- value={selectedValues}
101
- onChange={(e: Array<V>) => {
102
- onchange(e);
103
- }}
104
- {name}
105
- selectOnTab
106
- keepSelectionInList
107
- searchProps={{ keepSelectionInList: true }}
108
- creatable={false}
109
- collapseSelection={collapseSelection ? 'always' : null}
110
- deselectMode="toggle"
111
- highlightFirstItem={false}
112
- placeholder="Please Select {name ? `${an} ${name}` : ''}"
113
- selection={collapseSelection ? selection : undefined}
114
- >
115
- {#snippet option(opt)}
116
- {@const option = opt as V}
117
- <span class="dropdown-item">
118
- <div
119
- class="toggle-icon"
120
- class:yes={usesValuesAsObjects(selectedValues)
121
- ? selectedValues.findIndex((v) => v[valueProp] === option[valueProp]) > -1
122
- : usesValuesAsPrimitives(selectedValues)
123
- ? (selectedValues as Array<V[VP]>).findIndex((v: V[VP]) => v === option[valueProp]) >
124
- -1
125
- : false}
126
- >
127
- <Icon name="tick" size={Size.MediumSmall} />
128
- </div>
129
- {option[labelProp]}</span
130
- >
131
- {/snippet}
132
-
133
- {#snippet collapsedSelection(selectedOptions: Array<object> /*_i18n*/)}
134
- <span class="selection" class:hidden
135
- >{#if selectedOptions.length}{selectedOptions.length}
136
- {#if name}{autoPluralise(name, selectedOptions.length)}{/if} Selected
137
- {:else}Please Select {#if name}
138
- {an} {name}{/if}
139
- {/if}</span
140
- >
141
- {/snippet}
142
-
143
- {#snippet append()}
144
- <div class="icons">
145
- <Action
146
- {disabled}
147
- size={Size.Small}
148
- noTabIndex
149
- colourSet={ColourSet.Auxiliary}
150
- onclick={(e: MouseEvent) => {
151
- if (isExpanded) {
152
- e.stopPropagation();
153
- }
154
-
155
- if (selectedValues.length) {
156
- onchange([]);
157
- } else {
158
- onchange(options.concat());
159
- }
160
- }}
161
- icon={{
162
- name: selectedValues.length ? 'close-menu-cross' : 'manage-product-group',
163
- colour: Colour['$ui-blue-10']
164
- }}
165
- />
166
-
167
- <Action
168
- {disabled}
169
- size={Size.Small}
170
- noTabIndex
171
- colourSet={ColourSet.Auxiliary}
172
- icon={{
173
- name: isExpanded ? 'chevron-up' : 'chevron-down',
174
- colour: Colour['$ui-blue-10']
175
- }}
176
- />
177
- </div>
178
- {/snippet}
179
- {#snippet toggleIcon()}
180
- <div class="nothing"></div>
181
- <!-- <div class="icon-bg">
182
- <Icon name="chevron-down" size={Size.MediumSmall} />
183
- </div> -->
184
- {/snippet}
185
- </Svelecte>
186
-
187
- {#snippet selection(/*_selectedOptions: Array<unknown>*/)}
188
- <!-- {#if selectedOptions.length === 0}
189
- <span class="selection" class:hidden
190
- >Please Select {#if objectName}
191
- {an} {objectName}{/if}</span
192
- >
193
- {/if} -->
194
- {/snippet}
195
- </div>
196
-
1
+ <svelte:options runes />
2
+
3
+ <script lang="ts" generics="V extends object, VP extends ValueProp<V>">
4
+ import { autoPluralise, generateShortUUID, vowels } from '../Helpers/Helpers.svelte.js';
5
+ import { Colour, ColourSet } from '../scss/colours.js';
6
+ import type { ValueProp } from '../Types/Internal/Misc.js';
7
+ import { Size } from '../Types/Internal/Size.js';
8
+ import Svelecte from 'svelecte';
9
+ import { onMount } from 'svelte';
10
+ import Action from './Action.svelte';
11
+ import Icon from './Icon.svelte';
12
+ import type { MultiSelectProps } from './MultiSelectProps.js';
13
+
14
+ // HACK selectedValues is mutated by svelecte without asking, so we sometimes have to reverse it without a callback (side effects)
15
+ let {
16
+ label,
17
+ inputId = generateShortUUID(),
18
+ options,
19
+ labelProp,
20
+ valueProp,
21
+ width,
22
+ valueAsObject = true,
23
+ height,
24
+ selectedValues,
25
+ onchange,
26
+ collapseSelection = false,
27
+ name = 'Item',
28
+ disabled,
29
+ required,
30
+ invalid
31
+ }: MultiSelectProps<V, VP> = $props();
32
+
33
+ const an = $derived(name && vowels.has(name.at(0)?.toLocaleLowerCase() ?? '') ? 'an' : 'a');
34
+
35
+ const hidden = $state(false);
36
+
37
+ onMount(() => {
38
+ const input = document.getElementById(inputId);
39
+ // input?.addEventListener('focus', () => {
40
+ // hidden = true;
41
+ // });
42
+ // input?.addEventListener('blur', () => {
43
+ // hidden = false;
44
+ // });
45
+
46
+ // HACK callback for is-open on/off
47
+ const dropdownRef = input?.closest('div.svelecte')?.querySelector('.sv_dropdown') ?? undefined;
48
+ const observer = new MutationObserver((mutations: Array<MutationRecord>) => {
49
+ for (let i = mutations.length - 1; i > -1; i--) {
50
+ const mutation = mutations[i];
51
+ if (mutation.attributeName === 'class') {
52
+ isExpanded = dropdownRef?.classList.contains('is-open') ?? false;
53
+ }
54
+ }
55
+ });
56
+
57
+ if (dropdownRef) {
58
+ observer.observe(dropdownRef, { attributes: true });
59
+ }
60
+
61
+ return () => {
62
+ observer.disconnect();
63
+ };
64
+ });
65
+
66
+ let isExpanded = $state(false);
67
+
68
+ const isInvalid = $derived((required && !selectedValues.length) || invalid);
69
+
70
+ function usesValuesAsObjects(_values: Array<V> | Array<V[VP]>): _values is Array<V> {
71
+ return valueAsObject;
72
+ }
73
+
74
+ function usesValuesAsPrimitives(_values: Array<V> | Array<V[VP]>): _values is Array<V[VP]> {
75
+ return !valueAsObject;
76
+ }
77
+ </script>
78
+
79
+ <div
80
+ class:invalid={isInvalid}
81
+ class="select-wrapper"
82
+ style={`${width ? `--input-width: ${width};` : ''}${height ? `--input-height: ${height};` : ''}`}
83
+ >
84
+ {#if label}
85
+ <label for={inputId}>
86
+ <span>{label}</span>
87
+ <span class="border">{label}</span>
88
+ </label>
89
+ {/if}
90
+
91
+ <Svelecte
92
+ multiple
93
+ {valueAsObject}
94
+ {disabled}
95
+ {inputId}
96
+ valueField={valueProp}
97
+ labelField={labelProp}
98
+ {options}
99
+ searchable
100
+ value={selectedValues}
101
+ onChange={(e: Array<V>) => {
102
+ onchange(e);
103
+ }}
104
+ {name}
105
+ selectOnTab
106
+ keepSelectionInList
107
+ searchProps={{ keepSelectionInList: true }}
108
+ creatable={false}
109
+ collapseSelection={collapseSelection ? 'always' : null}
110
+ deselectMode="toggle"
111
+ highlightFirstItem={false}
112
+ placeholder="Please Select {name ? `${an} ${name}` : ''}"
113
+ selection={collapseSelection ? selection : undefined}
114
+ >
115
+ {#snippet option(opt)}
116
+ {@const option = opt as V}
117
+ <span class="dropdown-item">
118
+ <div
119
+ class="toggle-icon"
120
+ class:yes={usesValuesAsObjects(selectedValues)
121
+ ? selectedValues.findIndex((v) => v[valueProp] === option[valueProp]) > -1
122
+ : usesValuesAsPrimitives(selectedValues)
123
+ ? (selectedValues as Array<V[VP]>).findIndex((v: V[VP]) => v === option[valueProp]) >
124
+ -1
125
+ : false}
126
+ >
127
+ <Icon name="tick" size={Size.MediumSmall} />
128
+ </div>
129
+ {option[labelProp]}</span
130
+ >
131
+ {/snippet}
132
+
133
+ {#snippet collapsedSelection(selectedOptions: Array<object> /*_i18n*/)}
134
+ <span class="selection" class:hidden
135
+ >{#if selectedOptions.length}{selectedOptions.length}
136
+ {#if name}{autoPluralise(name, selectedOptions.length)}{/if} Selected
137
+ {:else}Please Select {#if name}
138
+ {an} {name}{/if}
139
+ {/if}</span
140
+ >
141
+ {/snippet}
142
+
143
+ {#snippet append()}
144
+ <div class="icons">
145
+ <Action
146
+ {disabled}
147
+ size={Size.Small}
148
+ noTabIndex
149
+ colourSet={ColourSet.Auxiliary}
150
+ onclick={(e: MouseEvent) => {
151
+ if (isExpanded) {
152
+ e.stopPropagation();
153
+ }
154
+
155
+ if (selectedValues.length) {
156
+ onchange([]);
157
+ } else {
158
+ onchange(options.concat());
159
+ }
160
+ }}
161
+ icon={{
162
+ name: selectedValues.length ? 'close-menu-cross' : 'manage-product-group',
163
+ colour: Colour['$ui-blue-10']
164
+ }}
165
+ />
166
+
167
+ <Action
168
+ {disabled}
169
+ size={Size.Small}
170
+ noTabIndex
171
+ colourSet={ColourSet.Auxiliary}
172
+ icon={{
173
+ name: isExpanded ? 'chevron-up' : 'chevron-down',
174
+ colour: Colour['$ui-blue-10']
175
+ }}
176
+ />
177
+ </div>
178
+ {/snippet}
179
+ {#snippet toggleIcon()}
180
+ <div class="nothing"></div>
181
+ <!-- <div class="icon-bg">
182
+ <Icon name="chevron-down" size={Size.MediumSmall} />
183
+ </div> -->
184
+ {/snippet}
185
+ </Svelecte>
186
+
187
+ {#snippet selection(/*_selectedOptions: Array<unknown>*/)}
188
+ <!-- {#if selectedOptions.length === 0}
189
+ <span class="selection" class:hidden
190
+ >Please Select {#if objectName}
191
+ {an} {objectName}{/if}</span
192
+ >
193
+ {/if} -->
194
+ {/snippet}
195
+ </div>
196
+
197
197
  <style>.select-wrapper {
198
198
  min-width: var(--input-min-width, 12rem);
199
199
  width: var(--input-width, 100%);
@@ -367,4 +367,4 @@ div.icons {
367
367
  }
368
368
  .dropdown-item .toggle-icon.yes {
369
369
  opacity: 1;
370
- }</style>
370
+ }</style>
@@ -1,99 +1,99 @@
1
- <svelte:options runes />
2
-
3
- <script lang="ts">
4
- import { Size } from '../../Types/Internal/Size.js';
5
- import Icon from '../Icon.svelte';
6
- import type { NavProps } from './NavProps.js';
7
- import ServicesNav from './ServicesNav.svelte';
8
-
9
- const { userName, extras, userDialog, serviceTabs, selectedServiceTab }: NavProps = $props();
10
-
11
- const userIcon = $derived.by(() => {
12
- const names = userName.split(' ');
13
-
14
- const initials = names.map((it) => it.charAt(0)).slice(0, 2);
15
- return initials;
16
- });
17
-
18
- const singleLetter = $derived(userIcon.length === 1);
19
- const hasLetters = $derived(userIcon.length > 0);
20
-
21
- let showServicesDialog = $state(false);
22
- let showUserDialog = $state(false);
23
- </script>
24
-
25
- <nav class="main-navigation">
26
- <span class="nav-link hoverable"> FloWMS </span>
27
- <!-- HACK swap above for below when a decent landing page has been added -->
28
- <!-- <a
29
- href={resolve(Locations.Home)}
30
- class="nav-link hoverable"
31
- >
32
- FloWMS
33
- </a> -->
34
-
35
- <div class="nav-link">
36
- <button
37
- onclick={() => {
38
- showServicesDialog = !showServicesDialog;
39
- }}
40
- >
41
- <div class="delimited">
42
- <Icon
43
- name="block-menu"
44
- size={Size.Medium}
45
- />
46
- <span>Services</span>
47
- </div>
48
- </button>
49
-
50
- {#if showServicesDialog}
51
- <ServicesNav
52
- onclose={() => {
53
- showServicesDialog = false;
54
- }}
55
- {serviceTabs}
56
- {selectedServiceTab}
57
- />
58
- {/if}
59
- </div>
60
-
61
- <div class="nav-search-container">
62
- <!-- <TextInput
63
- bind:value={searchParam}
64
- placeholder="Search for anything"
65
- leftIcon={{ name: 'search-1' }}
66
- /> -->
67
- </div>
68
- {#if extras}
69
- <div class="nav-link spaced selects">
70
- {@render extras()}
71
- </div>
72
- {/if}
73
-
74
- <div>
75
- <button
76
- onclick={() => {
77
- showUserDialog = !showUserDialog;
78
- }}
79
- >
80
- <span class="nav-link padded">
81
- <span
82
- class="user-icon"
83
- class:visible={hasLetters}
84
- class:single-letter={singleLetter}>{userIcon}</span
85
- >
86
- <span class="user-name">{userName}</span>
87
- </span>
88
- </button>
89
- {#if showUserDialog}
90
- {@render userDialog(() => {
91
- showUserDialog = false;
92
- })}
93
- {/if}
94
- </div>
95
- </nav>
96
-
1
+ <svelte:options runes />
2
+
3
+ <script lang="ts">
4
+ import { Size } from '../../Types/Internal/Size.js';
5
+ import Icon from '../Icon.svelte';
6
+ import type { NavProps } from './NavProps.js';
7
+ import ServicesNav from './ServicesNav.svelte';
8
+
9
+ const { userName, extras, userDialog, serviceTabs, selectedServiceTab }: NavProps = $props();
10
+
11
+ const userIcon = $derived.by(() => {
12
+ const names = userName.split(' ');
13
+
14
+ const initials = names.map((it) => it.charAt(0)).slice(0, 2);
15
+ return initials;
16
+ });
17
+
18
+ const singleLetter = $derived(userIcon.length === 1);
19
+ const hasLetters = $derived(userIcon.length > 0);
20
+
21
+ let showServicesDialog = $state(false);
22
+ let showUserDialog = $state(false);
23
+ </script>
24
+
25
+ <nav class="main-navigation">
26
+ <span class="nav-link hoverable"> FloWMS </span>
27
+ <!-- HACK swap above for below when a decent landing page has been added -->
28
+ <!-- <a
29
+ href={resolve(Locations.Home)}
30
+ class="nav-link hoverable"
31
+ >
32
+ FloWMS
33
+ </a> -->
34
+
35
+ <div class="nav-link">
36
+ <button
37
+ onclick={() => {
38
+ showServicesDialog = !showServicesDialog;
39
+ }}
40
+ >
41
+ <div class="delimited">
42
+ <Icon
43
+ name="block-menu"
44
+ size={Size.Medium}
45
+ />
46
+ <span>Services</span>
47
+ </div>
48
+ </button>
49
+
50
+ {#if showServicesDialog}
51
+ <ServicesNav
52
+ onclose={() => {
53
+ showServicesDialog = false;
54
+ }}
55
+ {serviceTabs}
56
+ {selectedServiceTab}
57
+ />
58
+ {/if}
59
+ </div>
60
+
61
+ <div class="nav-search-container">
62
+ <!-- <TextInput
63
+ bind:value={searchParam}
64
+ placeholder="Search for anything"
65
+ leftIcon={{ name: 'search-1' }}
66
+ /> -->
67
+ </div>
68
+ {#if extras}
69
+ <div class="nav-link spaced selects">
70
+ {@render extras()}
71
+ </div>
72
+ {/if}
73
+
74
+ <div>
75
+ <button
76
+ onclick={() => {
77
+ showUserDialog = !showUserDialog;
78
+ }}
79
+ >
80
+ <span class="nav-link padded">
81
+ <span
82
+ class="user-icon"
83
+ class:visible={hasLetters}
84
+ class:single-letter={singleLetter}>{userIcon}</span
85
+ >
86
+ <span class="user-name">{userName}</span>
87
+ </span>
88
+ </button>
89
+ {#if showUserDialog}
90
+ {@render userDialog(() => {
91
+ showUserDialog = false;
92
+ })}
93
+ {/if}
94
+ </div>
95
+ </nav>
96
+
97
97
  <style>div.overlay {
98
98
  position: fixed;
99
99
  top: calc(3.25rem + var(--env-border-height, 0));
@@ -214,4 +214,4 @@ div.delimited {
214
214
  align-items: center;
215
215
  justify-content: center;
216
216
  gap: 0.5rem;
217
- }</style>
217
+ }</style>
@@ -1,36 +1,36 @@
1
- <svelte:options runes />
2
-
3
- <script lang="ts">
4
- import { Colour } from '../../scss/colours.js';
5
- import { Size } from '../../Types/Internal/Size.js';
6
- import Icon from '../Icon.svelte';
7
- import type { NavServiceMenuListProps } from './NavServiceMenuListProps.js';
8
- import ServiceMenuItem from './ServiceMenuItem.svelte';
9
-
10
- const { title, items, icon }: NavServiceMenuListProps = $props();
11
- </script>
12
-
13
- <div class="wrapper">
14
- <h3>
15
- <div class="icon">
16
- {#if icon}
17
- <Icon
18
- size={Size.Large}
19
- colour={Colour['$font-primary']}
20
- {...icon}
21
- />
22
- {/if}
23
- </div>
24
- {title}
25
- </h3>
26
-
27
- <div class="items">
28
- {#each items as { item } (item.label)}
29
- <ServiceMenuItem {item} />
30
- {/each}
31
- </div>
32
- </div>
33
-
1
+ <svelte:options runes />
2
+
3
+ <script lang="ts">
4
+ import { Colour } from '../../scss/colours.js';
5
+ import { Size } from '../../Types/Internal/Size.js';
6
+ import Icon from '../Icon.svelte';
7
+ import type { NavServiceMenuListProps } from './NavServiceMenuListProps.js';
8
+ import ServiceMenuItem from './ServiceMenuItem.svelte';
9
+
10
+ const { title, items, icon }: NavServiceMenuListProps = $props();
11
+ </script>
12
+
13
+ <div class="wrapper">
14
+ <h3>
15
+ <div class="icon">
16
+ {#if icon}
17
+ <Icon
18
+ size={Size.Large}
19
+ colour={Colour['$font-primary']}
20
+ {...icon}
21
+ />
22
+ {/if}
23
+ </div>
24
+ {title}
25
+ </h3>
26
+
27
+ <div class="items">
28
+ {#each items as { item } (item.label)}
29
+ <ServiceMenuItem {item} />
30
+ {/each}
31
+ </div>
32
+ </div>
33
+
34
34
  <style>h3 {
35
35
  font-size: 1.5rem;
36
36
  display: flex;
@@ -54,4 +54,4 @@ h3 .icon {
54
54
  .wrapper .items {
55
55
  flex-shrink: 1;
56
56
  overflow: auto;
57
- }</style>
57
+ }</style>