@lavalogic/scoria 0.40.0 → 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,248 +1,248 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
lang="ts"
|
|
5
|
-
generics="T extends object, RowIdType extends Primitive"
|
|
6
|
-
>
|
|
7
|
-
import { dev } from '$app/environment';
|
|
8
|
-
import { TableContext } from '../../../Types/Context/TableContext.svelte.js';
|
|
9
|
-
import { type Primitive } from '../../../Types/Context/TableInitOptions.js';
|
|
10
|
-
import type { CellCoordinates } from '../../../Types/Coordinates/CellCoordinates.js';
|
|
11
|
-
import type { TableFocusDetails } from '../../../Types/Focus/TableFocusDetails.svelte.js';
|
|
12
|
-
import DateModal from '../../../../Touch/DateModal.svelte';
|
|
13
|
-
import { devCatch, isValidityTuple } from '../../../../../Helpers/Helpers.svelte.js';
|
|
14
|
-
import { Validity } from '../../../../../Types/Internal/Validity.js';
|
|
15
|
-
import { getContext, tick } from 'svelte';
|
|
16
|
-
import type { TableDatePickerProps } from './TableDatePickerProps.js';
|
|
17
|
-
|
|
18
|
-
const { cell }: TableDatePickerProps<T> = $props();
|
|
19
|
-
|
|
20
|
-
const value = $derived(cell.getValue());
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Narrowed `Date` view of the raw value. Templates fall back to parsing a
|
|
24
|
-
* string with `new Date(value)`; that parse happens once per render and
|
|
25
|
-
* could be hoisted into a $derived in a follow-up (see workorder).
|
|
26
|
-
*/
|
|
27
|
-
const dateValue = $derived(value && value instanceof Date ? value : undefined);
|
|
28
|
-
|
|
29
|
-
const tableContext = getContext<TableContext<T, RowIdType>>(TableContext.identifier);
|
|
30
|
-
|
|
31
|
-
const columnDef = $derived(cell.column.columnDef);
|
|
32
|
-
const coordinates: CellCoordinates = $derived({
|
|
33
|
-
row: cell.row.visibleIndex,
|
|
34
|
-
column: columnDef.index,
|
|
35
|
-
id: columnDef.id,
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
const editable = $derived(
|
|
39
|
-
cell.column.columnDef.isEditable(cell.row.original, cell.row.originalIndex)
|
|
40
|
-
);
|
|
41
|
-
const focusDetails: TableFocusDetails<T, RowIdType> = $derived(
|
|
42
|
-
tableContext._focus.getFocusDetailsFor(cell)
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
let modalLock = $state(false);
|
|
46
|
-
|
|
47
|
-
const wantsToBeEdited = $derived(
|
|
48
|
-
tableContext.focusStart?.column === focusDetails.coordinates.column &&
|
|
49
|
-
tableContext.focusEnd?.column === focusDetails.coordinates.column &&
|
|
50
|
-
tableContext.focusStart.row === focusDetails.coordinates.row &&
|
|
51
|
-
tableContext.focusEnd.row === focusDetails.coordinates.row &&
|
|
52
|
-
tableContext.focusStartIsBeingEdited
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
function handleEditable(isEditable: boolean): Promise<void> {
|
|
56
|
-
if (isEditable) {
|
|
57
|
-
return tick().then(() => {
|
|
58
|
-
modalLock = true;
|
|
59
|
-
});
|
|
60
|
-
} else {
|
|
61
|
-
if (modalLock) {
|
|
62
|
-
return tick().then(() => {
|
|
63
|
-
if (!tableContext.singleClickEditing) {
|
|
64
|
-
tableContext.focusStartIsBeingEdited = false;
|
|
65
|
-
}
|
|
66
|
-
modalLock = false;
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return Promise.resolve();
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
$effect(() => {
|
|
75
|
-
void editable;
|
|
76
|
-
if (wantsToBeEdited) {
|
|
77
|
-
if (editable instanceof Promise) {
|
|
78
|
-
editable
|
|
79
|
-
.then((isEditable) => {
|
|
80
|
-
return handleEditable(isEditable);
|
|
81
|
-
})
|
|
82
|
-
.catch(devCatch);
|
|
83
|
-
} else {
|
|
84
|
-
handleEditable(editable).catch(devCatch);
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
tick()
|
|
88
|
-
.then(() => {
|
|
89
|
-
modalLock = false;
|
|
90
|
-
tableContext.focusStartIsBeingEdited = false;
|
|
91
|
-
})
|
|
92
|
-
.catch(devCatch);
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
let tdref: HTMLElement | undefined = $state();
|
|
97
|
-
|
|
98
|
-
const id = $derived(`${tableContext.tableName}-cell-${cell.row.visibleIndex}-${cell.column.id}`);
|
|
99
|
-
async function handleSingleClick(event?: Event) {
|
|
100
|
-
if (
|
|
101
|
-
(await editable) &&
|
|
102
|
-
tableContext.singleClickEditing &&
|
|
103
|
-
(!event || !event.target || (event.target as HTMLElement).id === id)
|
|
104
|
-
) {
|
|
105
|
-
tableContext.focusStartIsBeingEdited = true;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
let validity: Validity = $state(Validity.Valid);
|
|
110
|
-
let reason = $state<string | undefined>();
|
|
111
|
-
|
|
112
|
-
$effect(() => {
|
|
113
|
-
const validityPromise = focusDetails.validity;
|
|
114
|
-
|
|
115
|
-
validityPromise
|
|
116
|
-
.then((v) => {
|
|
117
|
-
if (!v) {
|
|
118
|
-
validity = Validity.Neutral;
|
|
119
|
-
reason = undefined;
|
|
120
|
-
} else if (isValidityTuple(v)) {
|
|
121
|
-
validity = v.value;
|
|
122
|
-
reason = v.reason;
|
|
123
|
-
} else {
|
|
124
|
-
validity = v;
|
|
125
|
-
reason = undefined;
|
|
126
|
-
}
|
|
127
|
-
})
|
|
128
|
-
.catch(devCatch);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
const handleDoubleClick = async () => {
|
|
132
|
-
if (await editable) {
|
|
133
|
-
tableContext.focusStartIsBeingEdited = true;
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
function refocusTd() {
|
|
138
|
-
tableContext.focusStartIsBeingEdited = false;
|
|
139
|
-
modalLock = false;
|
|
140
|
-
tick()
|
|
141
|
-
.then(() => {
|
|
142
|
-
tdref?.focus();
|
|
143
|
-
})
|
|
144
|
-
.catch(devCatch);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function tryHandleDoubleClick() {
|
|
148
|
-
handleDoubleClick().catch(devCatch);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Effect wires the custom `edit` event to the keyboard-triggered double-click
|
|
153
|
-
* handler. The cleanup returns a removeEventListener so a remounted `tdref`
|
|
154
|
-
* does not accumulate stale listeners (P1 workorder finding).
|
|
155
|
-
*/
|
|
156
|
-
$effect(() => {
|
|
157
|
-
const node = tdref;
|
|
158
|
-
if (!node) {
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
node.addEventListener('edit', tryHandleDoubleClick);
|
|
162
|
-
return () => {
|
|
163
|
-
node.removeEventListener('edit', tryHandleDoubleClick);
|
|
164
|
-
};
|
|
165
|
-
});
|
|
166
|
-
</script>
|
|
167
|
-
|
|
168
|
-
<!-- svelte-ignore a11y_mouse_events_have_key_events -->
|
|
169
|
-
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
170
|
-
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
171
|
-
<div
|
|
172
|
-
{id}
|
|
173
|
-
style={focusDetails.outline}
|
|
174
|
-
aria-label={reason}
|
|
175
|
-
tabIndex="0"
|
|
176
|
-
bind:this={tdref}
|
|
177
|
-
class:editable
|
|
178
|
-
class="focusable"
|
|
179
|
-
class:multifocus={focusDetails.isMultiFocused}
|
|
180
|
-
class:multifocus-start={focusDetails.isMultiFocusStart}
|
|
181
|
-
class:info={validity == Validity.Info}
|
|
182
|
-
class:success={validity == Validity.Valid}
|
|
183
|
-
class:warning={validity == Validity.Warning}
|
|
184
|
-
class:error={validity == Validity.Invalid}
|
|
185
|
-
onmousedown={(e) => {
|
|
186
|
-
// start focus only on left click
|
|
187
|
-
if (e.button === 0) {
|
|
188
|
-
if (e.shiftKey) {
|
|
189
|
-
e.preventDefault();
|
|
190
|
-
tableContext.setFocusEnd(coordinates);
|
|
191
|
-
} else {
|
|
192
|
-
tableContext.startFocus(coordinates);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}}
|
|
196
|
-
onmouseover={() => {
|
|
197
|
-
if (tableContext.isMousingDown) {
|
|
198
|
-
tableContext.setFocusEnd(coordinates);
|
|
199
|
-
}
|
|
200
|
-
}}
|
|
201
|
-
onmouseup={() => {
|
|
202
|
-
tableContext.endFocus(coordinates);
|
|
203
|
-
}}
|
|
204
|
-
onclick={() => {
|
|
205
|
-
handleSingleClick().catch(devCatch);
|
|
206
|
-
}}
|
|
207
|
-
ondblclick={() => {
|
|
208
|
-
handleDoubleClick().catch(devCatch);
|
|
209
|
-
}}
|
|
210
|
-
>
|
|
211
|
-
{#if modalLock}
|
|
212
|
-
<DateModal
|
|
213
|
-
header="Edit {columnDef.header}"
|
|
214
|
-
value={dateValue ?? null}
|
|
215
|
-
showTime={cell.column.columnDef.showTime}
|
|
216
|
-
cancelEditing={() => {
|
|
217
|
-
refocusTd();
|
|
218
|
-
}}
|
|
219
|
-
confirm={(e) => {
|
|
220
|
-
tableContext.onEditCell(cell.row.original, coordinates, e).catch(devCatch);
|
|
221
|
-
refocusTd();
|
|
222
|
-
}}
|
|
223
|
-
/>
|
|
224
|
-
{/if}
|
|
225
|
-
|
|
226
|
-
{#if !value}
|
|
227
|
-
-
|
|
228
|
-
{:else if typeof value === 'string'}
|
|
229
|
-
{@const parsed = new Date(value)}
|
|
230
|
-
{isNaN(parsed.getFullYear()) ? value : parsed.toLocaleString()}
|
|
231
|
-
{:else if value instanceof Date}
|
|
232
|
-
{#if cell.column.columnDef.showTime}
|
|
233
|
-
{value.toLocaleString()}
|
|
234
|
-
{:else}
|
|
235
|
-
{value.toLocaleDateString()}
|
|
236
|
-
{/if}
|
|
237
|
-
{:else if dev}
|
|
238
|
-
<!-- eslint-disable-next-line svelte/no-at-debug-tags -->
|
|
239
|
-
{@debug value}
|
|
240
|
-
Error reading value
|
|
241
|
-
{:else}
|
|
242
|
-
-
|
|
243
|
-
{/if}
|
|
244
|
-
</div>
|
|
245
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
generics="T extends object, RowIdType extends Primitive"
|
|
6
|
+
>
|
|
7
|
+
import { dev } from '$app/environment';
|
|
8
|
+
import { TableContext } from '../../../Types/Context/TableContext.svelte.js';
|
|
9
|
+
import { type Primitive } from '../../../Types/Context/TableInitOptions.js';
|
|
10
|
+
import type { CellCoordinates } from '../../../Types/Coordinates/CellCoordinates.js';
|
|
11
|
+
import type { TableFocusDetails } from '../../../Types/Focus/TableFocusDetails.svelte.js';
|
|
12
|
+
import DateModal from '../../../../Touch/DateModal.svelte';
|
|
13
|
+
import { devCatch, isValidityTuple } from '../../../../../Helpers/Helpers.svelte.js';
|
|
14
|
+
import { Validity } from '../../../../../Types/Internal/Validity.js';
|
|
15
|
+
import { getContext, tick } from 'svelte';
|
|
16
|
+
import type { TableDatePickerProps } from './TableDatePickerProps.js';
|
|
17
|
+
|
|
18
|
+
const { cell }: TableDatePickerProps<T> = $props();
|
|
19
|
+
|
|
20
|
+
const value = $derived(cell.getValue());
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Narrowed `Date` view of the raw value. Templates fall back to parsing a
|
|
24
|
+
* string with `new Date(value)`; that parse happens once per render and
|
|
25
|
+
* could be hoisted into a $derived in a follow-up (see workorder).
|
|
26
|
+
*/
|
|
27
|
+
const dateValue = $derived(value && value instanceof Date ? value : undefined);
|
|
28
|
+
|
|
29
|
+
const tableContext = getContext<TableContext<T, RowIdType>>(TableContext.identifier);
|
|
30
|
+
|
|
31
|
+
const columnDef = $derived(cell.column.columnDef);
|
|
32
|
+
const coordinates: CellCoordinates = $derived({
|
|
33
|
+
row: cell.row.visibleIndex,
|
|
34
|
+
column: columnDef.index,
|
|
35
|
+
id: columnDef.id,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const editable = $derived(
|
|
39
|
+
cell.column.columnDef.isEditable(cell.row.original, cell.row.originalIndex)
|
|
40
|
+
);
|
|
41
|
+
const focusDetails: TableFocusDetails<T, RowIdType> = $derived(
|
|
42
|
+
tableContext._focus.getFocusDetailsFor(cell)
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
let modalLock = $state(false);
|
|
46
|
+
|
|
47
|
+
const wantsToBeEdited = $derived(
|
|
48
|
+
tableContext.focusStart?.column === focusDetails.coordinates.column &&
|
|
49
|
+
tableContext.focusEnd?.column === focusDetails.coordinates.column &&
|
|
50
|
+
tableContext.focusStart.row === focusDetails.coordinates.row &&
|
|
51
|
+
tableContext.focusEnd.row === focusDetails.coordinates.row &&
|
|
52
|
+
tableContext.focusStartIsBeingEdited
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
function handleEditable(isEditable: boolean): Promise<void> {
|
|
56
|
+
if (isEditable) {
|
|
57
|
+
return tick().then(() => {
|
|
58
|
+
modalLock = true;
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
if (modalLock) {
|
|
62
|
+
return tick().then(() => {
|
|
63
|
+
if (!tableContext.singleClickEditing) {
|
|
64
|
+
tableContext.focusStartIsBeingEdited = false;
|
|
65
|
+
}
|
|
66
|
+
modalLock = false;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return Promise.resolve();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
$effect(() => {
|
|
75
|
+
void editable;
|
|
76
|
+
if (wantsToBeEdited) {
|
|
77
|
+
if (editable instanceof Promise) {
|
|
78
|
+
editable
|
|
79
|
+
.then((isEditable) => {
|
|
80
|
+
return handleEditable(isEditable);
|
|
81
|
+
})
|
|
82
|
+
.catch(devCatch);
|
|
83
|
+
} else {
|
|
84
|
+
handleEditable(editable).catch(devCatch);
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
tick()
|
|
88
|
+
.then(() => {
|
|
89
|
+
modalLock = false;
|
|
90
|
+
tableContext.focusStartIsBeingEdited = false;
|
|
91
|
+
})
|
|
92
|
+
.catch(devCatch);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
let tdref: HTMLElement | undefined = $state();
|
|
97
|
+
|
|
98
|
+
const id = $derived(`${tableContext.tableName}-cell-${cell.row.visibleIndex}-${cell.column.id}`);
|
|
99
|
+
async function handleSingleClick(event?: Event) {
|
|
100
|
+
if (
|
|
101
|
+
(await editable) &&
|
|
102
|
+
tableContext.singleClickEditing &&
|
|
103
|
+
(!event || !event.target || (event.target as HTMLElement).id === id)
|
|
104
|
+
) {
|
|
105
|
+
tableContext.focusStartIsBeingEdited = true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
let validity: Validity = $state(Validity.Valid);
|
|
110
|
+
let reason = $state<string | undefined>();
|
|
111
|
+
|
|
112
|
+
$effect(() => {
|
|
113
|
+
const validityPromise = focusDetails.validity;
|
|
114
|
+
|
|
115
|
+
validityPromise
|
|
116
|
+
.then((v) => {
|
|
117
|
+
if (!v) {
|
|
118
|
+
validity = Validity.Neutral;
|
|
119
|
+
reason = undefined;
|
|
120
|
+
} else if (isValidityTuple(v)) {
|
|
121
|
+
validity = v.value;
|
|
122
|
+
reason = v.reason;
|
|
123
|
+
} else {
|
|
124
|
+
validity = v;
|
|
125
|
+
reason = undefined;
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
.catch(devCatch);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const handleDoubleClick = async () => {
|
|
132
|
+
if (await editable) {
|
|
133
|
+
tableContext.focusStartIsBeingEdited = true;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
function refocusTd() {
|
|
138
|
+
tableContext.focusStartIsBeingEdited = false;
|
|
139
|
+
modalLock = false;
|
|
140
|
+
tick()
|
|
141
|
+
.then(() => {
|
|
142
|
+
tdref?.focus();
|
|
143
|
+
})
|
|
144
|
+
.catch(devCatch);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function tryHandleDoubleClick() {
|
|
148
|
+
handleDoubleClick().catch(devCatch);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Effect wires the custom `edit` event to the keyboard-triggered double-click
|
|
153
|
+
* handler. The cleanup returns a removeEventListener so a remounted `tdref`
|
|
154
|
+
* does not accumulate stale listeners (P1 workorder finding).
|
|
155
|
+
*/
|
|
156
|
+
$effect(() => {
|
|
157
|
+
const node = tdref;
|
|
158
|
+
if (!node) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
node.addEventListener('edit', tryHandleDoubleClick);
|
|
162
|
+
return () => {
|
|
163
|
+
node.removeEventListener('edit', tryHandleDoubleClick);
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
</script>
|
|
167
|
+
|
|
168
|
+
<!-- svelte-ignore a11y_mouse_events_have_key_events -->
|
|
169
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
170
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
171
|
+
<div
|
|
172
|
+
{id}
|
|
173
|
+
style={focusDetails.outline}
|
|
174
|
+
aria-label={reason}
|
|
175
|
+
tabIndex="0"
|
|
176
|
+
bind:this={tdref}
|
|
177
|
+
class:editable
|
|
178
|
+
class="focusable"
|
|
179
|
+
class:multifocus={focusDetails.isMultiFocused}
|
|
180
|
+
class:multifocus-start={focusDetails.isMultiFocusStart}
|
|
181
|
+
class:info={validity == Validity.Info}
|
|
182
|
+
class:success={validity == Validity.Valid}
|
|
183
|
+
class:warning={validity == Validity.Warning}
|
|
184
|
+
class:error={validity == Validity.Invalid}
|
|
185
|
+
onmousedown={(e) => {
|
|
186
|
+
// start focus only on left click
|
|
187
|
+
if (e.button === 0) {
|
|
188
|
+
if (e.shiftKey) {
|
|
189
|
+
e.preventDefault();
|
|
190
|
+
tableContext.setFocusEnd(coordinates);
|
|
191
|
+
} else {
|
|
192
|
+
tableContext.startFocus(coordinates);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}}
|
|
196
|
+
onmouseover={() => {
|
|
197
|
+
if (tableContext.isMousingDown) {
|
|
198
|
+
tableContext.setFocusEnd(coordinates);
|
|
199
|
+
}
|
|
200
|
+
}}
|
|
201
|
+
onmouseup={() => {
|
|
202
|
+
tableContext.endFocus(coordinates);
|
|
203
|
+
}}
|
|
204
|
+
onclick={() => {
|
|
205
|
+
handleSingleClick().catch(devCatch);
|
|
206
|
+
}}
|
|
207
|
+
ondblclick={() => {
|
|
208
|
+
handleDoubleClick().catch(devCatch);
|
|
209
|
+
}}
|
|
210
|
+
>
|
|
211
|
+
{#if modalLock}
|
|
212
|
+
<DateModal
|
|
213
|
+
header="Edit {columnDef.header}"
|
|
214
|
+
value={dateValue ?? null}
|
|
215
|
+
showTime={cell.column.columnDef.showTime}
|
|
216
|
+
cancelEditing={() => {
|
|
217
|
+
refocusTd();
|
|
218
|
+
}}
|
|
219
|
+
confirm={(e) => {
|
|
220
|
+
tableContext.onEditCell(cell.row.original, coordinates, e).catch(devCatch);
|
|
221
|
+
refocusTd();
|
|
222
|
+
}}
|
|
223
|
+
/>
|
|
224
|
+
{/if}
|
|
225
|
+
|
|
226
|
+
{#if !value}
|
|
227
|
+
-
|
|
228
|
+
{:else if typeof value === 'string'}
|
|
229
|
+
{@const parsed = new Date(value)}
|
|
230
|
+
{isNaN(parsed.getFullYear()) ? value : parsed.toLocaleString()}
|
|
231
|
+
{:else if value instanceof Date}
|
|
232
|
+
{#if cell.column.columnDef.showTime}
|
|
233
|
+
{value.toLocaleString()}
|
|
234
|
+
{:else}
|
|
235
|
+
{value.toLocaleDateString()}
|
|
236
|
+
{/if}
|
|
237
|
+
{:else if dev}
|
|
238
|
+
<!-- eslint-disable-next-line svelte/no-at-debug-tags -->
|
|
239
|
+
{@debug value}
|
|
240
|
+
Error reading value
|
|
241
|
+
{:else}
|
|
242
|
+
-
|
|
243
|
+
{/if}
|
|
244
|
+
</div>
|
|
245
|
+
|
|
246
246
|
<style>.focusable,
|
|
247
247
|
.checkbox-cell,
|
|
248
248
|
.input-cell,
|
|
@@ -308,4 +308,4 @@
|
|
|
308
308
|
|
|
309
309
|
[role=cell] {
|
|
310
310
|
position: static;
|
|
311
|
-
}</style>
|
|
311
|
+
}</style>
|