@lavalogic/scoria 0.40.31 → 0.40.33

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 (137) hide show
  1. package/README.md +58 -58
  2. package/dist/Components/AccordionGroup.svelte +28 -28
  3. package/dist/Components/AccordionGroupButton.svelte +60 -60
  4. package/dist/Components/Action.svelte +48 -48
  5. package/dist/Components/AlertModal.svelte +102 -102
  6. package/dist/Components/Base/ContextWrapper.svelte +45 -45
  7. package/dist/Components/Base/Pagination.svelte +135 -135
  8. package/dist/Components/Base/Snippets.svelte +25 -25
  9. package/dist/Components/BigRadioSet.svelte +34 -34
  10. package/dist/Components/Bubble.svelte +38 -38
  11. package/dist/Components/Button.svelte +83 -83
  12. package/dist/Components/Checkbox.svelte +71 -71
  13. package/dist/Components/CollapsibleCard.svelte +59 -59
  14. package/dist/Components/CollapsibleMenuGroup.svelte +43 -43
  15. package/dist/Components/ConditionBuilder/ConditionBuilder.svelte +101 -101
  16. package/dist/Components/Contexts/ContextMenu.svelte +76 -76
  17. package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
  18. package/dist/Components/Contexts/ContextMenuOption.svelte +38 -38
  19. package/dist/Components/Contexts/Toast.svelte +71 -71
  20. package/dist/Components/Contexts/ToastContainer.svelte +34 -34
  21. package/dist/Components/Contexts/Tooltip.svelte +32 -32
  22. package/dist/Components/DataMatrixIcon.svelte +37 -37
  23. package/dist/Components/DateInput.svelte +80 -80
  24. package/dist/Components/DatePicker.svelte +86 -86
  25. package/dist/Components/DesktopModal.svelte +65 -65
  26. package/dist/Components/Dial.svelte +35 -35
  27. package/dist/Components/DimensionInput.svelte +95 -95
  28. package/dist/Components/DragMenu/DragMenuHolder.svelte +53 -53
  29. package/dist/Components/DragMenu/DraggableCard.svelte +49 -49
  30. package/dist/Components/FileCard.svelte +18 -18
  31. package/dist/Components/FileUpload.svelte +115 -115
  32. package/dist/Components/GridInput.svelte +123 -123
  33. package/dist/Components/GridInputSet.svelte +21 -21
  34. package/dist/Components/HorizontalTabGroup.svelte +54 -54
  35. package/dist/Components/HorizontalTabGroupButton.svelte +32 -32
  36. package/dist/Components/Icon.svelte +68 -68
  37. package/dist/Components/Icons.d.ts +3 -3
  38. package/dist/Components/Icons.js +11 -11
  39. package/dist/Components/InfoAlert.svelte +32 -32
  40. package/dist/Components/LoadingAnimation.svelte +228 -227
  41. package/dist/Components/LoadingModal.svelte +19 -19
  42. package/dist/Components/LoadingOverlay.svelte +20 -20
  43. package/dist/Components/Modal.svelte +127 -127
  44. package/dist/Components/MultiSelect.svelte +126 -126
  45. package/dist/Components/Nav/Nav.svelte +71 -71
  46. package/dist/Components/Nav/NavServiceMenuList.svelte +37 -37
  47. package/dist/Components/Nav/NavTab.svelte +46 -46
  48. package/dist/Components/Nav/ServiceMenuItem.svelte +62 -62
  49. package/dist/Components/Nav/ServicesNav.svelte +50 -50
  50. package/dist/Components/NumberInput.svelte +98 -98
  51. package/dist/Components/OptionCards.svelte +58 -58
  52. package/dist/Components/PageHeading.svelte +21 -21
  53. package/dist/Components/PasswordInput.svelte +61 -61
  54. package/dist/Components/PopoverButton.svelte +53 -53
  55. package/dist/Components/Portal.svelte +7 -7
  56. package/dist/Components/ProgressBubble.svelte +42 -42
  57. package/dist/Components/QuerySelect.svelte +102 -102
  58. package/dist/Components/ResourceCalendar/ResourceCalendar.svelte +241 -241
  59. package/dist/Components/SidebarPanel.svelte +32 -32
  60. package/dist/Components/SingleSelect.svelte +122 -122
  61. package/dist/Components/StepButton.svelte +48 -48
  62. package/dist/Components/StepForm.svelte +58 -58
  63. package/dist/Components/Switch.svelte +43 -43
  64. package/dist/Components/Table/ARCHITECTURE.md +298 -298
  65. package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +30 -30
  66. package/dist/Components/Table/Body/Rows/ColumnList.svelte +24 -24
  67. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +165 -165
  68. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +13 -13
  69. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +120 -120
  70. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +81 -81
  71. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +92 -92
  72. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +110 -110
  73. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +54 -54
  74. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +35 -35
  75. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +64 -64
  76. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +82 -82
  77. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +88 -88
  78. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +90 -90
  79. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +96 -96
  80. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +71 -71
  81. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +124 -124
  82. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +91 -91
  83. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +88 -88
  84. package/dist/Components/Table/Body/Rows/TableRow.svelte +127 -127
  85. package/dist/Components/Table/Body/TableBody.svelte +92 -92
  86. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +25 -25
  87. package/dist/Components/Table/Headers/SelectAllHeader.svelte +20 -20
  88. package/dist/Components/Table/Headers/TableHead.svelte +175 -175
  89. package/dist/Components/Table/Misc/ColumnPanel.svelte +32 -32
  90. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +29 -29
  91. package/dist/Components/Table/Misc/FilterInput.svelte +326 -326
  92. package/dist/Components/Table/Misc/FilterPanel.svelte +79 -79
  93. package/dist/Components/Table/Misc/FilterPanelModal.svelte +21 -21
  94. package/dist/Components/Table/Misc/ShareViewModal.svelte +118 -118
  95. package/dist/Components/Table/Misc/SidePanel.svelte +24 -24
  96. package/dist/Components/Table/Misc/TableConfigurationModal.svelte +318 -318
  97. package/dist/Components/Table/Misc/TableFooter.svelte +201 -201
  98. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +112 -112
  99. package/dist/Components/Table/Misc/TableSidebar.svelte +116 -116
  100. package/dist/Components/Table/Misc/TableViewDropdown.svelte +25 -25
  101. package/dist/Components/Table/Misc/ToolboxPanel.svelte +60 -60
  102. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +63 -63
  103. package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +101 -101
  104. package/dist/Components/Table/NestedTable.svelte +29 -29
  105. package/dist/Components/Table/Table.svelte +140 -140
  106. package/dist/Components/Test/TestContextConsumer.svelte +8 -8
  107. package/dist/Components/TextArea.svelte +92 -90
  108. package/dist/Components/TextInput.svelte +128 -117
  109. package/dist/Components/ThreeStateRadio.svelte +101 -101
  110. package/dist/Components/Touch/BoolCard.svelte +27 -27
  111. package/dist/Components/Touch/DateModal.svelte +98 -98
  112. package/dist/Components/Touch/EditCard.svelte +44 -44
  113. package/dist/Components/Touch/InfoCard.svelte +25 -25
  114. package/dist/Components/Touch/InfoTextCard.svelte +22 -22
  115. package/dist/Components/Touch/ModalExplanation.svelte +13 -13
  116. package/dist/Components/Touch/NumberKeyboard.svelte +81 -81
  117. package/dist/Components/Touch/NumberModal.svelte +49 -49
  118. package/dist/Components/Touch/PlusMinusCard.svelte +40 -40
  119. package/dist/Components/Touch/SelectModal.svelte +86 -86
  120. package/dist/Components/Touch/SummaryCard.svelte +74 -74
  121. package/dist/Components/Touch/TextAreaModal.svelte +53 -53
  122. package/dist/Components/Touch/TextModal.svelte +56 -56
  123. package/dist/Components/Touch/TouchCard.svelte +28 -28
  124. package/dist/Components/Touch/TouchModal.svelte +141 -141
  125. package/dist/Components/Touch/UtilityButton.svelte +63 -63
  126. package/dist/Components/VerticalTabGroup.svelte +38 -38
  127. package/dist/Components/VerticalTabGroupButton.svelte +46 -46
  128. package/dist/Helpers/Datamatrix.d.ts +19 -19
  129. package/dist/Helpers/Datamatrix.js +291 -291
  130. package/dist/Types/Examples/ExampleModal.svelte +27 -27
  131. package/dist/paraglide/README.md +1 -1
  132. package/dist/scss/_basics.scss +12 -12
  133. package/dist/scss/_colours.scss +140 -140
  134. package/dist/scss/_motion.scss +57 -57
  135. package/dist/scss/_sizing.scss +85 -85
  136. package/dist/scss/_transitions.scss +8 -8
  137. package/package.json +1 -1
@@ -1,28 +1,28 @@
1
- <svelte:options runes />
2
-
1
+ <svelte:options runes />
2
+
3
3
  <script lang="ts">import { m as i18n } from "../paraglide/messages.js";
4
4
  import Action from "./Action.svelte";
5
5
  import { Colour } from "../scss/colours.js";
6
6
  const { file, ondelete } = $props();
7
- </script>
8
-
9
- <div
10
- role="listitem"
11
- aria-label={file.name}
12
- >
13
- <span>{file.name}</span>
14
- <Action
15
- icon={{ name: 'circle-cross' }}
16
- backgroundColour={Colour['$transparent-0']}
17
- label={i18n['scoria.action.delete']()}
18
- onclick={ondelete}
19
- />
20
- </div>
21
-
7
+ </script>
8
+
9
+ <div
10
+ role="listitem"
11
+ aria-label={file.name}
12
+ >
13
+ <span>{file.name}</span>
14
+ <Action
15
+ icon={{ name: 'circle-cross' }}
16
+ backgroundColour={Colour['$transparent-0']}
17
+ label={i18n['scoria.action.delete']()}
18
+ onclick={ondelete}
19
+ />
20
+ </div>
21
+
22
22
  <style>div {
23
23
  display: flex;
24
24
  flex-flow: row nowrap;
25
25
  flex-grow: 1;
26
26
  align-items: center;
27
27
  gap: 0.375rem;
28
- }</style>
28
+ }</style>
@@ -1,5 +1,5 @@
1
- <svelte:options runes />
2
-
1
+ <svelte:options runes />
2
+
3
3
  <script lang="ts">import { m as i18n } from "../paraglide/messages.js";
4
4
  import { cssLength } from "../Helpers/Helpers.svelte.js";
5
5
  import { Colour, ColourSet } from "../scss/colours.js";
@@ -87,118 +87,118 @@ function ondragleave(e) {
87
87
  e.preventDefault();
88
88
  dragover = false;
89
89
  }
90
- </script>
91
-
92
- <label
93
- class:dragover
94
- class:for-modal={variant === InputVariant.Modal}
95
- {ondrop}
96
- {ondragover}
97
- {ondragleave}
98
- >
99
- {#if labelTop && variant !== InputVariant.Modal}
100
- <span
101
- class="top-label"
102
- class:for-default={variant === InputVariant.Default}
103
- >{labelTop}{#if optional}<i>&nbsp;- {i18n['scoria.label.optional']()}</i>{/if}</span
104
- >
105
- {#if variant === InputVariant.Default}
106
- <span class="border"
107
- >{labelTop}{#if optional}<i>&nbsp;- {i18n['scoria.label.optional']()}</i>{/if}</span
108
- >
109
- {/if}
110
- {/if}
111
- <div
112
- class="icon-container"
113
- class:for-modal={variant == InputVariant.Modal}
114
- >
115
- {#if leftIcon}
116
- <Icon
117
- name={leftIcon.name}
118
- size={leftIcon.size ?? Size.Medium}
119
- colour={leftIcon.colour}
120
- float
121
- left={cssLength('0.75rem')}
122
- top={cssLength('50%')}
123
- anchorX={cssLength('0')}
124
- anchorY={cssLength('-50%')}
125
- clickable={!!onLeftIconClick}
126
- onclick={onLeftIconClick}
127
- />
128
- {/if}
129
- <input
130
- hidden
131
- class:left-pad={leftIcon != undefined}
132
- class:right-pad={rightIcon != undefined}
133
- class:for-modal={variant == InputVariant.Modal}
134
- {onblur}
135
- {accept}
136
- {onfocus}
137
- type="file"
138
- bind:this={inputRef}
139
- {placeholder}
140
- {required}
141
- {disabled}
142
- {multiple}
143
- onchange={onPickerChange}
144
- />
145
-
146
- <div
147
- class="file-list"
148
- role="list"
149
- aria-label={i18n['scoria.label.selected_files']()}
150
- >
151
- {#if files.length}
152
- {#each files as file, index (file)}
153
- <FileCard
154
- {file}
155
- ondelete={() => {
156
- files = files.toSpliced(index, 1);
157
- onchange?.(files);
158
- }}
159
- />
160
- {/each}
161
- {:else}
162
- <p>
163
- {#if multiple}{i18n['scoria.text.dropzone_multiple']()}{:else}{i18n['scoria.text.dropzone_single']()}{/if}
164
- </p>
165
- {/if}
166
- </div>
167
- <div class="side">
168
- <Action
169
- colourSet={ColourSet.Secondary}
170
- backgroundColour={Colour['$transparent-0']}
171
- icon={{ name: 'upload' }}
172
- label={i18n['scoria.action.upload']()}
173
- size={Size.Medium}
174
- onclick={() => {
175
- openPicker();
176
- }}
177
- />
178
- </div>
179
- {#if rightIcon}
180
- <Icon
181
- name={rightIcon.name}
182
- size={rightIcon.size ?? Size.Medium}
183
- colour={rightIcon.colour}
184
- float
185
- right={cssLength(variant == InputVariant.Modal ? '1rem' : '0.5rem')}
186
- top={cssLength('50%')}
187
- anchorX={cssLength('0')}
188
- anchorY={cssLength('-50%')}
189
- clickable={!!onRightIconClick}
190
- onclick={onRightIconClick}
191
- />
192
- {/if}
193
- {#if labelRight}
194
- <span
195
- class="right-label"
196
- class:for-modal={variant == InputVariant.Modal}>{labelRight}</span
197
- >
198
- {/if}
199
- </div>
200
- </label>
201
-
90
+ </script>
91
+
92
+ <label
93
+ class:dragover
94
+ class:for-modal={variant === InputVariant.Modal}
95
+ {ondrop}
96
+ {ondragover}
97
+ {ondragleave}
98
+ >
99
+ {#if labelTop && variant !== InputVariant.Modal}
100
+ <span
101
+ class="top-label"
102
+ class:for-default={variant === InputVariant.Default}
103
+ >{labelTop}{#if optional}<i>&nbsp;- {i18n['scoria.label.optional']()}</i>{/if}</span
104
+ >
105
+ {#if variant === InputVariant.Default}
106
+ <span class="border"
107
+ >{labelTop}{#if optional}<i>&nbsp;- {i18n['scoria.label.optional']()}</i>{/if}</span
108
+ >
109
+ {/if}
110
+ {/if}
111
+ <div
112
+ class="icon-container"
113
+ class:for-modal={variant == InputVariant.Modal}
114
+ >
115
+ {#if leftIcon}
116
+ <Icon
117
+ name={leftIcon.name}
118
+ size={leftIcon.size ?? Size.Medium}
119
+ colour={leftIcon.colour}
120
+ float
121
+ left={cssLength('0.75rem')}
122
+ top={cssLength('50%')}
123
+ anchorX={cssLength('0')}
124
+ anchorY={cssLength('-50%')}
125
+ clickable={!!onLeftIconClick}
126
+ onclick={onLeftIconClick}
127
+ />
128
+ {/if}
129
+ <input
130
+ hidden
131
+ class:left-pad={leftIcon != undefined}
132
+ class:right-pad={rightIcon != undefined}
133
+ class:for-modal={variant == InputVariant.Modal}
134
+ {onblur}
135
+ {accept}
136
+ {onfocus}
137
+ type="file"
138
+ bind:this={inputRef}
139
+ {placeholder}
140
+ {required}
141
+ {disabled}
142
+ {multiple}
143
+ onchange={onPickerChange}
144
+ />
145
+
146
+ <div
147
+ class="file-list"
148
+ role="list"
149
+ aria-label={i18n['scoria.label.selected_files']()}
150
+ >
151
+ {#if files.length}
152
+ {#each files as file, index (file)}
153
+ <FileCard
154
+ {file}
155
+ ondelete={() => {
156
+ files = files.toSpliced(index, 1);
157
+ onchange?.(files);
158
+ }}
159
+ />
160
+ {/each}
161
+ {:else}
162
+ <p>
163
+ {#if multiple}{i18n['scoria.text.dropzone_multiple']()}{:else}{i18n['scoria.text.dropzone_single']()}{/if}
164
+ </p>
165
+ {/if}
166
+ </div>
167
+ <div class="side">
168
+ <Action
169
+ colourSet={ColourSet.Secondary}
170
+ backgroundColour={Colour['$transparent-0']}
171
+ icon={{ name: 'upload' }}
172
+ label={i18n['scoria.action.upload']()}
173
+ size={Size.Medium}
174
+ onclick={() => {
175
+ openPicker();
176
+ }}
177
+ />
178
+ </div>
179
+ {#if rightIcon}
180
+ <Icon
181
+ name={rightIcon.name}
182
+ size={rightIcon.size ?? Size.Medium}
183
+ colour={rightIcon.colour}
184
+ float
185
+ right={cssLength(variant == InputVariant.Modal ? '1rem' : '0.5rem')}
186
+ top={cssLength('50%')}
187
+ anchorX={cssLength('0')}
188
+ anchorY={cssLength('-50%')}
189
+ clickable={!!onRightIconClick}
190
+ onclick={onRightIconClick}
191
+ />
192
+ {/if}
193
+ {#if labelRight}
194
+ <span
195
+ class="right-label"
196
+ class:for-modal={variant == InputVariant.Modal}>{labelRight}</span
197
+ >
198
+ {/if}
199
+ </div>
200
+ </label>
201
+
202
202
  <style>input {
203
203
  box-sizing: border-box;
204
204
  height: 100%;
@@ -402,4 +402,4 @@ label {
402
402
 
403
403
  .dragover {
404
404
  background-color: rgba(31, 129, 160, 0.4);
405
- }</style>
405
+ }</style>
@@ -1,8 +1,8 @@
1
- <svelte:options runes />
2
-
3
- <script
4
- lang="ts"
5
- module
1
+ <svelte:options runes />
2
+
3
+ <script
4
+ lang="ts"
5
+ module
6
6
  >import { dev } from "$app/environment";
7
7
  import { loadingText } from "../Helpers/Helpers.svelte.js";
8
8
  import MultiSelect from "./MultiSelect.svelte";
@@ -13,11 +13,11 @@ const textTypes = new Set([
13
13
  "email",
14
14
  "tel"
15
15
  ]);
16
- </script>
17
-
18
- <script
19
- lang="ts"
20
- generics="V extends Record<string, unknown>,VP extends ValueProp<V>"
16
+ </script>
17
+
18
+ <script
19
+ lang="ts"
20
+ generics="V extends Record<string, unknown>,VP extends ValueProp<V>"
21
21
  >const { item, first, last } = $props();
22
22
  let value = $derived(isText(item) ? item.value ?? "" : "");
23
23
  function isText(item) {
@@ -44,118 +44,118 @@ function isSingleSelectPrimitive(item) {
44
44
  function isSingleSelectObject(item) {
45
45
  return "valueAsObject" in item && item.valueAsObject;
46
46
  }
47
- </script>
48
-
49
- <label
50
- class:first
51
- class:last
52
- >
53
- <div class="left">
54
- <span
55
- class:first
56
- class:last>{item.label}</span
57
- >
58
- </div>
59
- {#if isText(item)}
60
- <TextInput
61
- disabled={item.disabled}
62
- bind:value
63
- oninput={() => {
64
- item.updater(value);
65
- }}
66
- required={item.required}
67
- invalid={item.invalid}
68
- />
69
- {:else if isSelect(item)}
70
- {#if isMultiSelect(item)}
71
- {#await item.options}
72
- {loadingText()}
73
- {:then options}
74
- {#if isMultiSelectObject<V, VP>(item)}
75
- <MultiSelect
76
- name={item.name}
77
- {options}
78
- valueAsObject={true}
79
- labelProp={item.labelProp}
80
- valueProp={item.valueProp}
81
- selectedValues={item.value}
82
- invalid={item.invalid}
83
- onchange={(v: Array<V>) => {
84
- item.updater(v);
85
- }}
86
- />
87
- {:else if isMultiSelectPrimitive(item)}
88
- <MultiSelect
89
- name={item.name}
90
- {options}
91
- valueAsObject={false}
92
- labelProp={item.labelProp}
93
- valueProp={item.valueProp}
94
- selectedValues={item.value}
95
- invalid={item.invalid}
96
- onchange={(v: Array<V[VP]>) => {
97
- // `valueAsObject={false}` → primitives, not SelectOption objects.
98
- item.updater(v);
99
- }}
100
- />
101
- {/if}
102
- {/await}
103
- {:else if isSingleSelect(item)}
104
- {#await item.options}
105
- {loadingText()}
106
- {:then options}
107
- {#if isSingleSelectObject(item)}
108
- <SingleSelect
109
- {options}
110
- name={item.name}
111
- valueAsObject={true}
112
- labelProp={item.labelProp}
113
- valueProp={item.valueProp}
114
- value={item.value}
115
- required={item.required}
116
- clearable={!item.required}
117
- disabled={item.disabled}
118
- invalid={item.invalid}
119
- onchange={(v: V | null) => {
120
- item.updater(v);
121
- }}
122
- />
123
- {:else if isSingleSelectPrimitive(item)}
124
- <SingleSelect
125
- {options}
126
- name={item.name}
127
- valueAsObject={false}
128
- labelProp={item.labelProp}
129
- valueProp={item.valueProp}
130
- value={item.value}
131
- required={item.required}
132
- clearable={!item.required}
133
- disabled={item.disabled}
134
- invalid={item.invalid}
135
- onchange={(
136
- // `valueAsObject={false}` → primitive value, not a
137
- // SelectOption. `clearable` is on (since the field is
138
- // not required) so the callback must accept null.
139
- // The annotation collapses to `unknown | null` because
140
- // `V extends Record<string, unknown>` makes `V[VP]`
141
- // itself `unknown`.
142
- // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
143
- v: V[VP] | null
144
- ) => {
145
- item.updater(v);
146
- }}
147
- />
148
- {/if}
149
- {/await}
150
- {/if}
151
- {:else if dev}
152
- {@const type = item.type}
153
- unknown type: {type}
154
- <!-- eslint-disable-next-line svelte/no-at-debug-tags -->
155
- {@debug type}
156
- {/if}
157
- </label>
158
-
47
+ </script>
48
+
49
+ <label
50
+ class:first
51
+ class:last
52
+ >
53
+ <div class="left">
54
+ <span
55
+ class:first
56
+ class:last>{item.label}</span
57
+ >
58
+ </div>
59
+ {#if isText(item)}
60
+ <TextInput
61
+ disabled={item.disabled}
62
+ bind:value
63
+ oninput={() => {
64
+ item.updater(value);
65
+ }}
66
+ required={item.required}
67
+ invalid={item.invalid}
68
+ />
69
+ {:else if isSelect(item)}
70
+ {#if isMultiSelect(item)}
71
+ {#await item.options}
72
+ {loadingText()}
73
+ {:then options}
74
+ {#if isMultiSelectObject<V, VP>(item)}
75
+ <MultiSelect
76
+ name={item.name}
77
+ {options}
78
+ valueAsObject={true}
79
+ labelProp={item.labelProp}
80
+ valueProp={item.valueProp}
81
+ selectedValues={item.value}
82
+ invalid={item.invalid}
83
+ onchange={(v: Array<V>) => {
84
+ item.updater(v);
85
+ }}
86
+ />
87
+ {:else if isMultiSelectPrimitive(item)}
88
+ <MultiSelect
89
+ name={item.name}
90
+ {options}
91
+ valueAsObject={false}
92
+ labelProp={item.labelProp}
93
+ valueProp={item.valueProp}
94
+ selectedValues={item.value}
95
+ invalid={item.invalid}
96
+ onchange={(v: Array<V[VP]>) => {
97
+ // `valueAsObject={false}` → primitives, not SelectOption objects.
98
+ item.updater(v);
99
+ }}
100
+ />
101
+ {/if}
102
+ {/await}
103
+ {:else if isSingleSelect(item)}
104
+ {#await item.options}
105
+ {loadingText()}
106
+ {:then options}
107
+ {#if isSingleSelectObject(item)}
108
+ <SingleSelect
109
+ {options}
110
+ name={item.name}
111
+ valueAsObject={true}
112
+ labelProp={item.labelProp}
113
+ valueProp={item.valueProp}
114
+ value={item.value}
115
+ required={item.required}
116
+ clearable={!item.required}
117
+ disabled={item.disabled}
118
+ invalid={item.invalid}
119
+ onchange={(v: V | null) => {
120
+ item.updater(v);
121
+ }}
122
+ />
123
+ {:else if isSingleSelectPrimitive(item)}
124
+ <SingleSelect
125
+ {options}
126
+ name={item.name}
127
+ valueAsObject={false}
128
+ labelProp={item.labelProp}
129
+ valueProp={item.valueProp}
130
+ value={item.value}
131
+ required={item.required}
132
+ clearable={!item.required}
133
+ disabled={item.disabled}
134
+ invalid={item.invalid}
135
+ onchange={(
136
+ // `valueAsObject={false}` → primitive value, not a
137
+ // SelectOption. `clearable` is on (since the field is
138
+ // not required) so the callback must accept null.
139
+ // The annotation collapses to `unknown | null` because
140
+ // `V extends Record<string, unknown>` makes `V[VP]`
141
+ // itself `unknown`.
142
+ // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
143
+ v: V[VP] | null
144
+ ) => {
145
+ item.updater(v);
146
+ }}
147
+ />
148
+ {/if}
149
+ {/await}
150
+ {/if}
151
+ {:else if dev}
152
+ {@const type = item.type}
153
+ unknown type: {type}
154
+ <!-- eslint-disable-next-line svelte/no-at-debug-tags -->
155
+ {@debug type}
156
+ {/if}
157
+ </label>
158
+
159
159
  <style>label {
160
160
  display: contents;
161
161
  --input-border-radius: 0;
@@ -174,4 +174,4 @@ label.first {
174
174
  }
175
175
  label.last {
176
176
  border-radius: 0 0 4px 4px;
177
- }</style>
177
+ }</style>
@@ -1,26 +1,26 @@
1
- <svelte:options runes />
2
-
3
- <script
4
- lang="ts"
5
- generics="V extends Record<string, unknown>,VP extends ValueProp<V>"
1
+ <svelte:options runes />
2
+
3
+ <script
4
+ lang="ts"
5
+ generics="V extends Record<string, unknown>,VP extends ValueProp<V>"
6
6
  >import GridInput from "./GridInput.svelte";
7
7
  const { items, header } = $props();
8
8
  const lastIndex = $derived(items.length - 1);
9
- </script>
10
-
11
- <div class="grid">
12
- {#if header}
13
- {@render header()}
14
- {/if}
15
- {#each items as item, index (item.label)}
16
- <GridInput
17
- {item}
18
- first={index == 0}
19
- last={index == lastIndex}
20
- />
21
- {/each}
22
- </div>
23
-
9
+ </script>
10
+
11
+ <div class="grid">
12
+ {#if header}
13
+ {@render header()}
14
+ {/if}
15
+ {#each items as item, index (item.label)}
16
+ <GridInput
17
+ {item}
18
+ first={index == 0}
19
+ last={index == lastIndex}
20
+ />
21
+ {/each}
22
+ </div>
23
+
24
24
  <style>.grid {
25
25
  display: grid;
26
26
  grid-template-columns: [label] 16rem [value] 1fr;
@@ -28,4 +28,4 @@ const lastIndex = $derived(items.length - 1);
28
28
  border: solid 1px #dae0e5;
29
29
  border-radius: 4px;
30
30
  background-color: #dae0e5;
31
- }</style>
31
+ }</style>