@lavalogic/scoria 0.40.1 → 0.40.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -58
- package/dist/Components/AccordionGroup.svelte +46 -46
- package/dist/Components/AccordionGroupButton.svelte +76 -76
- package/dist/Components/Action.svelte +136 -136
- package/dist/Components/AlertModal.svelte +195 -195
- package/dist/Components/AppointmentCalendar/AppointmentCalendar.svelte +729 -729
- package/dist/Components/Base/BaseModal.svelte +125 -125
- package/dist/Components/Base/ContextWrapper.svelte +72 -72
- package/dist/Components/Base/Pagination.svelte +198 -198
- package/dist/Components/Base/Snippets.svelte +36 -36
- package/dist/Components/BigRadioSet.svelte +38 -38
- package/dist/Components/Bubble.svelte +101 -101
- package/dist/Components/Button.svelte +209 -209
- package/dist/Components/Checkbox.svelte +86 -86
- package/dist/Components/CollapsibleCard.svelte +78 -78
- package/dist/Components/Contexts/ContextMenu.svelte +164 -164
- package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
- package/dist/Components/Contexts/ContextMenuOption.svelte +60 -60
- package/dist/Components/Contexts/Toast.svelte +86 -86
- package/dist/Components/Contexts/ToastContainer.svelte +65 -65
- package/dist/Components/Contexts/Tooltip.svelte +37 -37
- package/dist/Components/DataMatrixIcon.svelte +112 -112
- package/dist/Components/DateInput.svelte +148 -148
- package/dist/Components/DatePicker.svelte +300 -300
- package/dist/Components/DesktopModal.svelte +90 -90
- package/dist/Components/Dial.svelte +204 -204
- package/dist/Components/DimensionInput.svelte +170 -170
- package/dist/Components/DragMenu/DragMenuHolder.svelte +119 -119
- package/dist/Components/DragMenu/DraggableCard.svelte +77 -77
- package/dist/Components/FileCard.svelte +24 -24
- package/dist/Components/FileUpload.svelte +236 -236
- package/dist/Components/GridInput.svelte +196 -196
- package/dist/Components/GridInputSet.svelte +29 -29
- package/dist/Components/HorizontalTabGroup.svelte +82 -82
- package/dist/Components/HorizontalTabGroupButton.svelte +44 -44
- package/dist/Components/Icon.svelte +128 -128
- package/dist/Components/Icons.js +357 -357
- package/dist/Components/InfoAlert.svelte +35 -35
- package/dist/Components/LoadingAnimation.svelte +29 -29
- package/dist/Components/LoadingModal.svelte +45 -45
- package/dist/Components/LoadingOverlay.svelte +25 -25
- package/dist/Components/Modal.svelte +258 -258
- package/dist/Components/MultiSelect.svelte +220 -220
- package/dist/Components/Nav/Nav.svelte +110 -110
- package/dist/Components/Nav/NavServiceMenuList.svelte +43 -43
- package/dist/Components/Nav/NavTab.svelte +62 -62
- package/dist/Components/Nav/ServiceMenuItem.svelte +112 -112
- package/dist/Components/Nav/ServicesNav.svelte +80 -80
- package/dist/Components/NumberInput.svelte +157 -157
- package/dist/Components/PageHeading.svelte +25 -25
- package/dist/Components/PasswordInput.svelte +88 -88
- package/dist/Components/Portal.svelte +36 -36
- package/dist/Components/ProgressBubble.svelte +107 -107
- package/dist/Components/QuerySelect.svelte +366 -366
- package/dist/Components/SingleSelect.svelte +250 -250
- package/dist/Components/StepButton.svelte +70 -70
- package/dist/Components/StepForm.svelte +140 -140
- package/dist/Components/Switch.svelte +69 -69
- package/dist/Components/Table/ARCHITECTURE.md +298 -298
- package/dist/Components/Table/Body/QuickSearchCell.svelte +679 -679
- package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +51 -51
- package/dist/Components/Table/Body/Rows/ColumnList.svelte +59 -59
- package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +454 -454
- package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +79 -79
- package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +185 -185
- package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +124 -124
- package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +131 -120
- package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +234 -234
- package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +105 -105
- package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +87 -87
- package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +126 -126
- package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +159 -159
- package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +246 -246
- package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +216 -216
- package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +252 -252
- package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +179 -179
- package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +221 -221
- package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +197 -197
- package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +190 -190
- package/dist/Components/Table/Body/Rows/TableRow.svelte +290 -290
- package/dist/Components/Table/Body/TableBody.svelte +155 -155
- package/dist/Components/Table/ColumnFactory.svelte.js +1 -0
- package/dist/Components/Table/Headers/HighlightAllHeader.svelte +41 -41
- package/dist/Components/Table/Headers/SelectAllHeader.svelte +30 -30
- package/dist/Components/Table/Headers/TableHead.svelte +415 -415
- package/dist/Components/Table/Misc/ColumnPanel.svelte +39 -39
- package/dist/Components/Table/Misc/ColumnPanelModal.svelte +39 -39
- package/dist/Components/Table/Misc/FilterInput.svelte +641 -641
- package/dist/Components/Table/Misc/FilterPanel.svelte +190 -190
- package/dist/Components/Table/Misc/FilterPanelModal.svelte +31 -31
- package/dist/Components/Table/Misc/ShareViewModal.svelte +291 -291
- package/dist/Components/Table/Misc/SidePanel.svelte +35 -35
- package/dist/Components/Table/Misc/TableConfigurationModal.svelte +644 -644
- package/dist/Components/Table/Misc/TableFooter.svelte +340 -340
- package/dist/Components/Table/Misc/TableHorizontalBar.svelte +140 -140
- package/dist/Components/Table/Misc/TableSidebar.svelte +200 -200
- package/dist/Components/Table/Misc/TableViewDropdown.svelte +105 -105
- package/dist/Components/Table/Misc/ToolboxPanel.svelte +100 -100
- package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +107 -107
- package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +192 -192
- package/dist/Components/Table/NestedTable.svelte +130 -130
- package/dist/Components/Table/Table.svelte +692 -692
- package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.d.ts +5 -0
- package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.js +3 -0
- package/dist/Components/Table/Types/Public/ColumnOptions.d.ts +10 -0
- package/dist/Components/Test/TestContextConsumer.svelte +13 -13
- package/dist/Components/TextArea.svelte +130 -130
- package/dist/Components/TextInput.svelte +176 -176
- package/dist/Components/ThreeStateRadio.svelte +131 -131
- package/dist/Components/Touch/BoolCard.svelte +45 -45
- package/dist/Components/Touch/DateModal.svelte +209 -209
- package/dist/Components/Touch/EditCard.svelte +59 -59
- package/dist/Components/Touch/InfoCard.svelte +31 -31
- package/dist/Components/Touch/InfoTextCard.svelte +28 -28
- package/dist/Components/Touch/ModalExplanation.svelte +17 -17
- package/dist/Components/Touch/NumberKeyboard.svelte +225 -225
- package/dist/Components/Touch/NumberModal.svelte +79 -79
- package/dist/Components/Touch/PlusMinusCard.svelte +46 -46
- package/dist/Components/Touch/SelectModal.svelte +127 -127
- package/dist/Components/Touch/SummaryCard.svelte +93 -93
- package/dist/Components/Touch/TextAreaModal.svelte +95 -95
- package/dist/Components/Touch/TextModal.svelte +106 -106
- package/dist/Components/Touch/TouchCard.svelte +33 -33
- package/dist/Components/Touch/TouchModal.svelte +274 -274
- package/dist/Components/Touch/UtilityButton.svelte +109 -109
- package/dist/Components/VerticalTabGroup.svelte +79 -79
- package/dist/Components/VerticalTabGroupButton.svelte +58 -58
- package/dist/Helpers/Datamatrix.d.ts +19 -19
- package/dist/Helpers/Datamatrix.js +291 -291
- package/dist/Types/Examples/ExampleModal.svelte +35 -35
- package/dist/scss/_basics.scss +12 -12
- package/dist/scss/_colours.scss +134 -134
- package/dist/scss/_mixins.scss +3392 -3392
- package/dist/scss/_motion.scss +57 -57
- package/dist/scss/_sizing.scss +85 -85
- package/dist/scss/_transitions.scss +8 -8
- package/package.json +1 -1
|
@@ -1,223 +1,223 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
lang="ts"
|
|
5
|
-
module
|
|
6
|
-
>
|
|
7
|
-
import { dev } from '$app/environment';
|
|
8
|
-
import SingleSelect from '../../../../SingleSelect.svelte';
|
|
9
|
-
import { TableContext } from '../../../Types/Context/TableContext.svelte.js';
|
|
10
|
-
import { type Primitive } from '../../../Types/Context/TableInitOptions.js';
|
|
11
|
-
import { cssLength, devCatch, loadingText } from '../../../../../Helpers/Helpers.svelte.js';
|
|
12
|
-
import type { SelectOption } from '../../../../../Types/Internal/SelectOption.js';
|
|
13
|
-
import { Validity } from '../../../../../Types/Internal/Validity.js';
|
|
14
|
-
import { getContext, tick } from 'svelte';
|
|
15
|
-
import { useAsyncEditable } from './_helpers/useAsyncEditable.svelte.js';
|
|
16
|
-
import type { TableSelectProps } from './TableSelectProps.js';
|
|
17
|
-
</script>
|
|
18
|
-
|
|
19
|
-
<script
|
|
20
|
-
lang="ts"
|
|
21
|
-
generics="T extends object, FilterValueType, RowIdType extends Primitive"
|
|
22
|
-
>
|
|
23
|
-
const { cell }: TableSelectProps<T, FilterValueType> = $props();
|
|
24
|
-
|
|
25
|
-
let tdref = $state<HTMLElement | undefined>();
|
|
26
|
-
|
|
27
|
-
const selectValue = $derived(cell.getValue() as T | Promise<T> | null | undefined);
|
|
28
|
-
|
|
29
|
-
const visibleValue = $derived(
|
|
30
|
-
cell.column.columnDef.getDisplayValue(cell.row.original, cell.row.originalIndex)
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
const optional = $derived(cell.column.columnDef.optional);
|
|
34
|
-
|
|
35
|
-
const tableContext = getContext<TableContext<T, RowIdType>>(TableContext.identifier);
|
|
36
|
-
|
|
37
|
-
const editable = useAsyncEditable<T, RowIdType>({
|
|
38
|
-
cell: () => cell,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
const optionsPromise = $derived(
|
|
42
|
-
cell.column.columnDef.getSpecificOptions?.(
|
|
43
|
-
cell.row.original,
|
|
44
|
-
editable.focusDetails.coordinates.column
|
|
45
|
-
) ?? cell.column.columnDef.getOptions()
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
function handleTab(e: KeyboardEvent) {
|
|
49
|
-
if (e.key === 'Escape') {
|
|
50
|
-
e.preventDefault();
|
|
51
|
-
e.stopPropagation();
|
|
52
|
-
editable.leaveEditingViaKeyboard(tdref);
|
|
53
|
-
}
|
|
54
|
-
if (e.key === 'Tab') {
|
|
55
|
-
e.preventDefault();
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function keydownForce(e: KeyboardEvent) {
|
|
60
|
-
handleTab(e);
|
|
61
|
-
if (!(e.key === 'ArrowUp' || e.key === 'ArrowDown')) {
|
|
62
|
-
tdref?.dispatchEvent(
|
|
63
|
-
new KeyboardEvent('keydown', {
|
|
64
|
-
key: e.key,
|
|
65
|
-
altKey: e.getModifierState('Alt'),
|
|
66
|
-
metaKey: e.getModifierState('Meta'),
|
|
67
|
-
shiftKey: e.getModifierState('Shift'),
|
|
68
|
-
ctrlKey: e.getModifierState('Control'),
|
|
69
|
-
bubbles: true,
|
|
70
|
-
})
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Track the inner select input so the keydown re-dispatcher is removed
|
|
77
|
-
* on blur or remount. This wiring is cell-specific (Select /
|
|
78
|
-
* QuerySelect only) and so lives outside the shared `useAsyncEditable`
|
|
79
|
-
* helper.
|
|
80
|
-
*/
|
|
81
|
-
let activeKeydownTarget: HTMLInputElement | undefined;
|
|
82
|
-
|
|
83
|
-
function addKeydownEvent(target: HTMLInputElement | undefined) {
|
|
84
|
-
if (activeKeydownTarget && activeKeydownTarget !== target) {
|
|
85
|
-
activeKeydownTarget.removeEventListener('keydown', keydownForce);
|
|
86
|
-
}
|
|
87
|
-
if (target) {
|
|
88
|
-
target.addEventListener('keydown', keydownForce);
|
|
89
|
-
activeKeydownTarget = target;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function removeKeydownEvent() {
|
|
94
|
-
if (activeKeydownTarget) {
|
|
95
|
-
activeKeydownTarget.removeEventListener('keydown', keydownForce);
|
|
96
|
-
activeKeydownTarget = undefined;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Wire the `edit` custom event with cleanup on tdref remount or
|
|
102
|
-
* component unmount. The listener plumbing lives in the shared
|
|
103
|
-
* `useAsyncEditable` helper.
|
|
104
|
-
*/
|
|
105
|
-
$effect(() => editable.attachEditListener(tdref));
|
|
106
|
-
|
|
107
|
-
// Drop the keydown listener if the cell unmounts.
|
|
108
|
-
$effect(() => removeKeydownEvent);
|
|
109
|
-
</script>
|
|
110
|
-
|
|
111
|
-
{#if editable.isBeingEdited}
|
|
112
|
-
<div
|
|
113
|
-
class="select-cell"
|
|
114
|
-
bind:this={tdref}
|
|
115
|
-
>
|
|
116
|
-
{#await Promise.all([optionsPromise, selectValue])}
|
|
117
|
-
{loadingText}
|
|
118
|
-
{:then [options, value]}
|
|
119
|
-
<SingleSelect
|
|
120
|
-
focusOnLoad
|
|
121
|
-
name="Item"
|
|
122
|
-
valueProp={'value' as never}
|
|
123
|
-
labelProp={'label' as never}
|
|
124
|
-
value={(value ?? null) as never}
|
|
125
|
-
options={options as never}
|
|
126
|
-
width={cssLength('100%')}
|
|
127
|
-
clearable={cell.column.columnDef.clearable}
|
|
128
|
-
onfocus={addKeydownEvent}
|
|
129
|
-
valueAsObject={false}
|
|
130
|
-
onchange={(newValue: SelectOption<T>['value'] | null) => {
|
|
131
|
-
// `valueAsObject={false}` makes SingleSelect's onchange
|
|
132
|
-
// emit the primitive key value (`SelectOption<T>['value']`,
|
|
133
|
-
// i.e. `T`) directly, which flows straight through to
|
|
134
|
-
// `onEditCell`. The `as never` prop casts work around
|
|
135
|
-
// the fact that Svelte component generics cannot be
|
|
136
|
-
// passed explicitly in template syntax: the inferred V
|
|
137
|
-
// (from `value: T`) clashes with the option type
|
|
138
|
-
// (`SelectOption<T>`), and the casts let `V` be inferred
|
|
139
|
-
// from the explicit `onchange` annotation.
|
|
140
|
-
if (newValue !== value) {
|
|
141
|
-
if (optional || newValue != null) {
|
|
142
|
-
tableContext
|
|
143
|
-
.onEditCell(cell.row.original, editable.focusDetails.coordinates, newValue ?? null)
|
|
144
|
-
.catch(devCatch);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
removeKeydownEvent();
|
|
148
|
-
tableContext.focusStartIsBeingEdited = false;
|
|
149
|
-
tick()
|
|
150
|
-
.then(() => {
|
|
151
|
-
tdref?.focus();
|
|
152
|
-
})
|
|
153
|
-
.catch(devCatch);
|
|
154
|
-
}}
|
|
155
|
-
/>
|
|
156
|
-
{:catch e}
|
|
157
|
-
{#if dev}
|
|
158
|
-
error: {e}
|
|
159
|
-
<!-- eslint-disable-next-line svelte/no-at-debug-tags -->
|
|
160
|
-
{@debug e}
|
|
161
|
-
{/if}
|
|
162
|
-
could not retrieve options
|
|
163
|
-
{/await}
|
|
164
|
-
</div>
|
|
165
|
-
{:else}
|
|
166
|
-
<!-- svelte-ignore a11y_mouse_events_have_key_events -->
|
|
167
|
-
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
168
|
-
<div
|
|
169
|
-
bind:this={tdref}
|
|
170
|
-
tabIndex="0"
|
|
171
|
-
style={editable.focusDetails.outline}
|
|
172
|
-
id={`${tableContext.tableName}-cell-${cell.row.visibleIndex}-${cell.column.id}`}
|
|
173
|
-
class="focusable editable"
|
|
174
|
-
class:multifocus={editable.focusDetails.isMultiFocused}
|
|
175
|
-
class:multifocus-start={editable.focusDetails.isMultiFocusStart}
|
|
176
|
-
class:info={editable.validity == Validity.Info}
|
|
177
|
-
class:success={editable.validity == Validity.Valid}
|
|
178
|
-
class:warning={editable.validity == Validity.Warning}
|
|
179
|
-
class:error={editable.validity == Validity.Invalid}
|
|
180
|
-
ondblclick={() => {
|
|
181
|
-
editable.handleDoubleClickFocus();
|
|
182
|
-
}}
|
|
183
|
-
onmousedown={(e) => {
|
|
184
|
-
// start focus only on left click
|
|
185
|
-
if (e.button === 0) {
|
|
186
|
-
if (e.shiftKey) {
|
|
187
|
-
e.preventDefault();
|
|
188
|
-
tableContext.setFocusEnd(editable.focusDetails.coordinates);
|
|
189
|
-
} else {
|
|
190
|
-
tableContext.startFocus(editable.focusDetails.coordinates);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}}
|
|
194
|
-
onmouseover={() => {
|
|
195
|
-
if (tableContext.isMousingDown) {
|
|
196
|
-
tableContext.setFocusEnd(editable.focusDetails.coordinates);
|
|
197
|
-
}
|
|
198
|
-
}}
|
|
199
|
-
onmouseup={() => {
|
|
200
|
-
const wasHandled = editable.handleSingleClickFocus();
|
|
201
|
-
if (!wasHandled) {
|
|
202
|
-
tableContext.endFocus(editable.focusDetails.coordinates);
|
|
203
|
-
}
|
|
204
|
-
}}
|
|
205
|
-
>
|
|
206
|
-
{#await visibleValue}
|
|
207
|
-
{loadingText}
|
|
208
|
-
{:then value}
|
|
209
|
-
{value ?? '-'}
|
|
210
|
-
{:catch e}
|
|
211
|
-
{#if dev}
|
|
212
|
-
error: {e}
|
|
213
|
-
<!-- eslint-disable-next-line svelte/no-at-debug-tags -->
|
|
214
|
-
{@debug e}
|
|
215
|
-
{/if}
|
|
216
|
-
Could not retrieve options
|
|
217
|
-
{/await}
|
|
218
|
-
</div>
|
|
219
|
-
{/if}
|
|
220
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
module
|
|
6
|
+
>
|
|
7
|
+
import { dev } from '$app/environment';
|
|
8
|
+
import SingleSelect from '../../../../SingleSelect.svelte';
|
|
9
|
+
import { TableContext } from '../../../Types/Context/TableContext.svelte.js';
|
|
10
|
+
import { type Primitive } from '../../../Types/Context/TableInitOptions.js';
|
|
11
|
+
import { cssLength, devCatch, loadingText } from '../../../../../Helpers/Helpers.svelte.js';
|
|
12
|
+
import type { SelectOption } from '../../../../../Types/Internal/SelectOption.js';
|
|
13
|
+
import { Validity } from '../../../../../Types/Internal/Validity.js';
|
|
14
|
+
import { getContext, tick } from 'svelte';
|
|
15
|
+
import { useAsyncEditable } from './_helpers/useAsyncEditable.svelte.js';
|
|
16
|
+
import type { TableSelectProps } from './TableSelectProps.js';
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<script
|
|
20
|
+
lang="ts"
|
|
21
|
+
generics="T extends object, FilterValueType, RowIdType extends Primitive"
|
|
22
|
+
>
|
|
23
|
+
const { cell }: TableSelectProps<T, FilterValueType> = $props();
|
|
24
|
+
|
|
25
|
+
let tdref = $state<HTMLElement | undefined>();
|
|
26
|
+
|
|
27
|
+
const selectValue = $derived(cell.getValue() as T | Promise<T> | null | undefined);
|
|
28
|
+
|
|
29
|
+
const visibleValue = $derived(
|
|
30
|
+
cell.column.columnDef.getDisplayValue(cell.row.original, cell.row.originalIndex)
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const optional = $derived(cell.column.columnDef.optional);
|
|
34
|
+
|
|
35
|
+
const tableContext = getContext<TableContext<T, RowIdType>>(TableContext.identifier);
|
|
36
|
+
|
|
37
|
+
const editable = useAsyncEditable<T, RowIdType>({
|
|
38
|
+
cell: () => cell,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const optionsPromise = $derived(
|
|
42
|
+
cell.column.columnDef.getSpecificOptions?.(
|
|
43
|
+
cell.row.original,
|
|
44
|
+
editable.focusDetails.coordinates.column
|
|
45
|
+
) ?? cell.column.columnDef.getOptions()
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
function handleTab(e: KeyboardEvent) {
|
|
49
|
+
if (e.key === 'Escape') {
|
|
50
|
+
e.preventDefault();
|
|
51
|
+
e.stopPropagation();
|
|
52
|
+
editable.leaveEditingViaKeyboard(tdref);
|
|
53
|
+
}
|
|
54
|
+
if (e.key === 'Tab') {
|
|
55
|
+
e.preventDefault();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function keydownForce(e: KeyboardEvent) {
|
|
60
|
+
handleTab(e);
|
|
61
|
+
if (!(e.key === 'ArrowUp' || e.key === 'ArrowDown')) {
|
|
62
|
+
tdref?.dispatchEvent(
|
|
63
|
+
new KeyboardEvent('keydown', {
|
|
64
|
+
key: e.key,
|
|
65
|
+
altKey: e.getModifierState('Alt'),
|
|
66
|
+
metaKey: e.getModifierState('Meta'),
|
|
67
|
+
shiftKey: e.getModifierState('Shift'),
|
|
68
|
+
ctrlKey: e.getModifierState('Control'),
|
|
69
|
+
bubbles: true,
|
|
70
|
+
})
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Track the inner select input so the keydown re-dispatcher is removed
|
|
77
|
+
* on blur or remount. This wiring is cell-specific (Select /
|
|
78
|
+
* QuerySelect only) and so lives outside the shared `useAsyncEditable`
|
|
79
|
+
* helper.
|
|
80
|
+
*/
|
|
81
|
+
let activeKeydownTarget: HTMLInputElement | undefined;
|
|
82
|
+
|
|
83
|
+
function addKeydownEvent(target: HTMLInputElement | undefined) {
|
|
84
|
+
if (activeKeydownTarget && activeKeydownTarget !== target) {
|
|
85
|
+
activeKeydownTarget.removeEventListener('keydown', keydownForce);
|
|
86
|
+
}
|
|
87
|
+
if (target) {
|
|
88
|
+
target.addEventListener('keydown', keydownForce);
|
|
89
|
+
activeKeydownTarget = target;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function removeKeydownEvent() {
|
|
94
|
+
if (activeKeydownTarget) {
|
|
95
|
+
activeKeydownTarget.removeEventListener('keydown', keydownForce);
|
|
96
|
+
activeKeydownTarget = undefined;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Wire the `edit` custom event with cleanup on tdref remount or
|
|
102
|
+
* component unmount. The listener plumbing lives in the shared
|
|
103
|
+
* `useAsyncEditable` helper.
|
|
104
|
+
*/
|
|
105
|
+
$effect(() => editable.attachEditListener(tdref));
|
|
106
|
+
|
|
107
|
+
// Drop the keydown listener if the cell unmounts.
|
|
108
|
+
$effect(() => removeKeydownEvent);
|
|
109
|
+
</script>
|
|
110
|
+
|
|
111
|
+
{#if editable.isBeingEdited}
|
|
112
|
+
<div
|
|
113
|
+
class="select-cell"
|
|
114
|
+
bind:this={tdref}
|
|
115
|
+
>
|
|
116
|
+
{#await Promise.all([optionsPromise, selectValue])}
|
|
117
|
+
{loadingText}
|
|
118
|
+
{:then [options, value]}
|
|
119
|
+
<SingleSelect
|
|
120
|
+
focusOnLoad
|
|
121
|
+
name="Item"
|
|
122
|
+
valueProp={'value' as never}
|
|
123
|
+
labelProp={'label' as never}
|
|
124
|
+
value={(value ?? null) as never}
|
|
125
|
+
options={options as never}
|
|
126
|
+
width={cssLength('100%')}
|
|
127
|
+
clearable={cell.column.columnDef.clearable}
|
|
128
|
+
onfocus={addKeydownEvent}
|
|
129
|
+
valueAsObject={false}
|
|
130
|
+
onchange={(newValue: SelectOption<T>['value'] | null) => {
|
|
131
|
+
// `valueAsObject={false}` makes SingleSelect's onchange
|
|
132
|
+
// emit the primitive key value (`SelectOption<T>['value']`,
|
|
133
|
+
// i.e. `T`) directly, which flows straight through to
|
|
134
|
+
// `onEditCell`. The `as never` prop casts work around
|
|
135
|
+
// the fact that Svelte component generics cannot be
|
|
136
|
+
// passed explicitly in template syntax: the inferred V
|
|
137
|
+
// (from `value: T`) clashes with the option type
|
|
138
|
+
// (`SelectOption<T>`), and the casts let `V` be inferred
|
|
139
|
+
// from the explicit `onchange` annotation.
|
|
140
|
+
if (newValue !== value) {
|
|
141
|
+
if (optional || newValue != null) {
|
|
142
|
+
tableContext
|
|
143
|
+
.onEditCell(cell.row.original, editable.focusDetails.coordinates, newValue ?? null)
|
|
144
|
+
.catch(devCatch);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
removeKeydownEvent();
|
|
148
|
+
tableContext.focusStartIsBeingEdited = false;
|
|
149
|
+
tick()
|
|
150
|
+
.then(() => {
|
|
151
|
+
tdref?.focus();
|
|
152
|
+
})
|
|
153
|
+
.catch(devCatch);
|
|
154
|
+
}}
|
|
155
|
+
/>
|
|
156
|
+
{:catch e}
|
|
157
|
+
{#if dev}
|
|
158
|
+
error: {e}
|
|
159
|
+
<!-- eslint-disable-next-line svelte/no-at-debug-tags -->
|
|
160
|
+
{@debug e}
|
|
161
|
+
{/if}
|
|
162
|
+
could not retrieve options
|
|
163
|
+
{/await}
|
|
164
|
+
</div>
|
|
165
|
+
{:else}
|
|
166
|
+
<!-- svelte-ignore a11y_mouse_events_have_key_events -->
|
|
167
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
168
|
+
<div
|
|
169
|
+
bind:this={tdref}
|
|
170
|
+
tabIndex="0"
|
|
171
|
+
style={editable.focusDetails.outline}
|
|
172
|
+
id={`${tableContext.tableName}-cell-${cell.row.visibleIndex}-${cell.column.id}`}
|
|
173
|
+
class="focusable editable"
|
|
174
|
+
class:multifocus={editable.focusDetails.isMultiFocused}
|
|
175
|
+
class:multifocus-start={editable.focusDetails.isMultiFocusStart}
|
|
176
|
+
class:info={editable.validity == Validity.Info}
|
|
177
|
+
class:success={editable.validity == Validity.Valid}
|
|
178
|
+
class:warning={editable.validity == Validity.Warning}
|
|
179
|
+
class:error={editable.validity == Validity.Invalid}
|
|
180
|
+
ondblclick={() => {
|
|
181
|
+
editable.handleDoubleClickFocus();
|
|
182
|
+
}}
|
|
183
|
+
onmousedown={(e) => {
|
|
184
|
+
// start focus only on left click
|
|
185
|
+
if (e.button === 0) {
|
|
186
|
+
if (e.shiftKey) {
|
|
187
|
+
e.preventDefault();
|
|
188
|
+
tableContext.setFocusEnd(editable.focusDetails.coordinates);
|
|
189
|
+
} else {
|
|
190
|
+
tableContext.startFocus(editable.focusDetails.coordinates);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}}
|
|
194
|
+
onmouseover={() => {
|
|
195
|
+
if (tableContext.isMousingDown) {
|
|
196
|
+
tableContext.setFocusEnd(editable.focusDetails.coordinates);
|
|
197
|
+
}
|
|
198
|
+
}}
|
|
199
|
+
onmouseup={() => {
|
|
200
|
+
const wasHandled = editable.handleSingleClickFocus();
|
|
201
|
+
if (!wasHandled) {
|
|
202
|
+
tableContext.endFocus(editable.focusDetails.coordinates);
|
|
203
|
+
}
|
|
204
|
+
}}
|
|
205
|
+
>
|
|
206
|
+
{#await visibleValue}
|
|
207
|
+
{loadingText}
|
|
208
|
+
{:then value}
|
|
209
|
+
{value ?? '-'}
|
|
210
|
+
{:catch e}
|
|
211
|
+
{#if dev}
|
|
212
|
+
error: {e}
|
|
213
|
+
<!-- eslint-disable-next-line svelte/no-at-debug-tags -->
|
|
214
|
+
{@debug e}
|
|
215
|
+
{/if}
|
|
216
|
+
Could not retrieve options
|
|
217
|
+
{/await}
|
|
218
|
+
</div>
|
|
219
|
+
{/if}
|
|
220
|
+
|
|
221
221
|
<style>.focusable,
|
|
222
222
|
.checkbox-cell,
|
|
223
223
|
.input-cell,
|
|
@@ -294,4 +294,4 @@
|
|
|
294
294
|
--sv-item-wrap-padding: 0px 0.75rem;
|
|
295
295
|
--input-height: var(--height);
|
|
296
296
|
min-width: 0;
|
|
297
|
-
}</style>
|
|
297
|
+
}</style>
|