@lavalogic/scoria 0.35.0 → 0.36.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 (126) hide show
  1. package/README.md +58 -58
  2. package/dist/Components/AccordionGroup.svelte +42 -42
  3. package/dist/Components/AccordionGroupButton.svelte +99 -99
  4. package/dist/Components/Action.svelte +138 -138
  5. package/dist/Components/AlertModal.svelte +125 -125
  6. package/dist/Components/Base/ContextWrapper.svelte +50 -50
  7. package/dist/Components/Base/Pagination.svelte +190 -190
  8. package/dist/Components/Base/Snippets.svelte +29 -29
  9. package/dist/Components/BigRadioSet.svelte +29 -29
  10. package/dist/Components/Bubble.svelte +77 -77
  11. package/dist/Components/Button.svelte +197 -197
  12. package/dist/Components/Checkbox.svelte +68 -68
  13. package/dist/Components/CollapsibleCard.svelte +70 -70
  14. package/dist/Components/Contexts/ContextMenu.svelte +157 -157
  15. package/dist/Components/Contexts/ContextMenuDivider.svelte +11 -11
  16. package/dist/Components/Contexts/ContextMenuOption.svelte +52 -52
  17. package/dist/Components/Contexts/Toast.svelte +61 -61
  18. package/dist/Components/Contexts/ToastContainer.svelte +46 -46
  19. package/dist/Components/Contexts/Tooltip.svelte +26 -26
  20. package/dist/Components/DataMatrixIcon.svelte +41 -41
  21. package/dist/Components/DateInput.svelte +109 -109
  22. package/dist/Components/DatePicker.svelte +312 -312
  23. package/dist/Components/DesktopModal.svelte +106 -106
  24. package/dist/Components/Dial.svelte +151 -151
  25. package/dist/Components/DimensionInput.svelte +184 -184
  26. package/dist/Components/DragMenu/DragMenuHolder.svelte +106 -106
  27. package/dist/Components/DragMenu/DraggableCard.svelte +41 -41
  28. package/dist/Components/FileCard.svelte +20 -20
  29. package/dist/Components/FileUpload.svelte +196 -196
  30. package/dist/Components/GridInput.svelte +190 -190
  31. package/dist/Components/GridInputSet.svelte +22 -22
  32. package/dist/Components/HorizontalTabGroup.svelte +78 -78
  33. package/dist/Components/HorizontalTabGroupButton.svelte +96 -96
  34. package/dist/Components/Icon.svelte +97 -97
  35. package/dist/Components/Icons.js +357 -357
  36. package/dist/Components/LoadingAnimation.svelte +32 -32
  37. package/dist/Components/LoadingModal.svelte +47 -47
  38. package/dist/Components/LoadingOverlay.svelte +27 -27
  39. package/dist/Components/Modal.svelte +251 -251
  40. package/dist/Components/MultiSelect.svelte +197 -197
  41. package/dist/Components/Nav/Nav.svelte +97 -97
  42. package/dist/Components/Nav/NavServiceMenuList.svelte +34 -34
  43. package/dist/Components/Nav/NavTab.svelte +91 -91
  44. package/dist/Components/Nav/ServiceMenuItem.svelte +91 -91
  45. package/dist/Components/Nav/ServicesNav.svelte +53 -53
  46. package/dist/Components/NumberInput.svelte +144 -144
  47. package/dist/Components/PageHeading.svelte +36 -36
  48. package/dist/Components/PasswordInput.svelte +73 -73
  49. package/dist/Components/Portal.svelte +25 -25
  50. package/dist/Components/ProgressBubble.svelte +80 -80
  51. package/dist/Components/QuerySelect.svelte +411 -411
  52. package/dist/Components/SingleSelect.svelte +261 -261
  53. package/dist/Components/StepButton.svelte +120 -120
  54. package/dist/Components/StepForm.svelte +108 -108
  55. package/dist/Components/Switch.svelte +36 -36
  56. package/dist/Components/Table/Body/QuickSearchCell.svelte +632 -632
  57. package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +30 -30
  58. package/dist/Components/Table/Body/Rows/ColumnList.svelte +56 -56
  59. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +179 -179
  60. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +49 -49
  61. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +180 -180
  62. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +102 -102
  63. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +119 -119
  64. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +114 -114
  65. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +96 -96
  66. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +72 -72
  67. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +131 -131
  68. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +144 -144
  69. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +238 -238
  70. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +358 -358
  71. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +338 -338
  72. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +183 -183
  73. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +309 -309
  74. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +369 -369
  75. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +170 -170
  76. package/dist/Components/Table/Body/Rows/TableRow.svelte +259 -259
  77. package/dist/Components/Table/Body/TableBody.svelte +67 -67
  78. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +39 -39
  79. package/dist/Components/Table/Headers/SelectAllHeader.svelte +28 -28
  80. package/dist/Components/Table/Headers/TableHead.svelte +260 -260
  81. package/dist/Components/Table/Misc/ColumnPanel.svelte +78 -78
  82. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +99 -99
  83. package/dist/Components/Table/Misc/FilterInput.svelte +556 -556
  84. package/dist/Components/Table/Misc/FilterPanel.svelte +46 -46
  85. package/dist/Components/Table/Misc/FilterPanelModal.svelte +67 -67
  86. package/dist/Components/Table/Misc/SidePanel.svelte +32 -32
  87. package/dist/Components/Table/Misc/TableFooter.svelte +304 -304
  88. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +156 -156
  89. package/dist/Components/Table/Misc/TableSidebar.svelte +176 -176
  90. package/dist/Components/Table/Misc/ToolboxPanel.svelte +77 -77
  91. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +91 -91
  92. package/dist/Components/Table/NestedTable.svelte +84 -84
  93. package/dist/Components/Table/Table.svelte +492 -492
  94. package/dist/Components/Test/TestContextConsumer.svelte +13 -13
  95. package/dist/Components/TextArea.svelte +108 -108
  96. package/dist/Components/TextInput.svelte +147 -147
  97. package/dist/Components/ThreeStateRadio.svelte +124 -124
  98. package/dist/Components/Touch/BoolCard.svelte +52 -52
  99. package/dist/Components/Touch/DateModal.svelte +217 -217
  100. package/dist/Components/Touch/EditCard.svelte +52 -52
  101. package/dist/Components/Touch/InfoCard.svelte +24 -24
  102. package/dist/Components/Touch/InfoTextCard.svelte +21 -21
  103. package/dist/Components/Touch/ModalExplanation.svelte +20 -20
  104. package/dist/Components/Touch/NumberKeyboard.svelte +268 -268
  105. package/dist/Components/Touch/NumberModal.svelte +69 -69
  106. package/dist/Components/Touch/PlusMinusCard.svelte +50 -50
  107. package/dist/Components/Touch/SelectModal.svelte +105 -105
  108. package/dist/Components/Touch/SummaryCard.svelte +65 -65
  109. package/dist/Components/Touch/TextAreaModal.svelte +86 -86
  110. package/dist/Components/Touch/TextModal.svelte +123 -123
  111. package/dist/Components/Touch/TouchCard.svelte +28 -28
  112. package/dist/Components/Touch/TouchModal.svelte +259 -259
  113. package/dist/Components/Touch/UtilityButton.svelte +91 -91
  114. package/dist/Components/VerticalTabGroup.svelte +66 -66
  115. package/dist/Components/VerticalTabGroupButton.svelte +97 -97
  116. package/dist/Helpers/Datamatrix.d.ts +10 -10
  117. package/dist/Helpers/Datamatrix.js +1 -1
  118. package/dist/Helpers/Helpers.svelte.d.ts +1 -0
  119. package/dist/Helpers/Helpers.svelte.js +15 -0
  120. package/dist/Types/Examples/ExampleModal.svelte +34 -34
  121. package/dist/scss/_basics.scss +12 -12
  122. package/dist/scss/_colours.scss +134 -134
  123. package/dist/scss/_mixins.scss +3016 -3016
  124. package/dist/scss/_sizing.scss +69 -69
  125. package/dist/scss/_transitions.scss +8 -8
  126. package/package.json +30 -30
@@ -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>