@lavalogic/scoria 0.37.9 → 0.37.10
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.
|
@@ -67,14 +67,41 @@ function makeSpec(kind, def, internals = {}) {
|
|
|
67
67
|
});
|
|
68
68
|
return Object.freeze(spec);
|
|
69
69
|
}
|
|
70
|
+
/** Sensible per-kind default widths so a freshly-built table without explicit
|
|
71
|
+
* per-column `width` overrides ends up visually differentiated (rather than
|
|
72
|
+
* every column collapsing to the shared `minSize` fallback of 48px and then
|
|
73
|
+
* taking equal `1fr` shares of any remaining track space). Numbers chosen
|
|
74
|
+
* to roughly match what the legacy `<table>` element produced via the
|
|
75
|
+
* browser auto-layout algorithm for typical FloWMS column content. */
|
|
76
|
+
const KIND_DEFAULT_WIDTHS = {
|
|
77
|
+
text: 200,
|
|
78
|
+
number: 100,
|
|
79
|
+
checkbox: 80,
|
|
80
|
+
date: 140,
|
|
81
|
+
select: 160,
|
|
82
|
+
query: 160,
|
|
83
|
+
display: 150,
|
|
84
|
+
bubble: 150,
|
|
85
|
+
progress: 140,
|
|
86
|
+
validity: 60,
|
|
87
|
+
actions: 120,
|
|
88
|
+
rowSelection: 40,
|
|
89
|
+
expand: 40,
|
|
90
|
+
filterOnly: 0,
|
|
91
|
+
};
|
|
70
92
|
/** Returns the common Def props for an option object, excluding `id`.
|
|
71
93
|
* Callers pass `id` directly at the construction site so its strict
|
|
72
|
-
* literal-key narrowing survives the object spread.
|
|
73
|
-
|
|
94
|
+
* literal-key narrowing survives the object spread.
|
|
95
|
+
*
|
|
96
|
+
* `kind` selects the per-kind default width from `KIND_DEFAULT_WIDTHS`. The
|
|
97
|
+
* caller's `minWidth` / `width` values still win - the default is only
|
|
98
|
+
* applied if the consumer left the field undefined. */
|
|
99
|
+
function commonProps(opts, kind) {
|
|
100
|
+
const defaultWidth = KIND_DEFAULT_WIDTHS[kind];
|
|
74
101
|
return {
|
|
75
102
|
header: opts.header,
|
|
76
103
|
minSize: opts.minWidth,
|
|
77
|
-
width: opts.width,
|
|
104
|
+
width: opts.width ?? defaultWidth,
|
|
78
105
|
allowSorting: opts.allowSorting,
|
|
79
106
|
allowFiltering: opts.allowFiltering,
|
|
80
107
|
defaultHidden: opts.defaultHidden,
|
|
@@ -123,7 +150,7 @@ export function createColumnFactory() {
|
|
|
123
150
|
text(opts) {
|
|
124
151
|
const def = new TextInputDef({
|
|
125
152
|
id: opts.id,
|
|
126
|
-
...commonProps(opts),
|
|
153
|
+
...commonProps(opts, 'text'),
|
|
127
154
|
accessorFn: opts.accessor,
|
|
128
155
|
getDisplayValue: opts.getDisplayValue,
|
|
129
156
|
filterValueType: FilterValueType.String,
|
|
@@ -136,7 +163,7 @@ export function createColumnFactory() {
|
|
|
136
163
|
number(opts) {
|
|
137
164
|
const def = new NumberInputDef({
|
|
138
165
|
id: opts.id,
|
|
139
|
-
...commonProps(opts),
|
|
166
|
+
...commonProps(opts, 'number'),
|
|
140
167
|
accessorFn: opts.accessor,
|
|
141
168
|
getDisplayValue: opts.getDisplayValue,
|
|
142
169
|
min: opts.min ?? Number.MIN_SAFE_INTEGER,
|
|
@@ -151,7 +178,7 @@ export function createColumnFactory() {
|
|
|
151
178
|
checkbox(opts) {
|
|
152
179
|
const def = new CheckboxDef({
|
|
153
180
|
id: opts.id,
|
|
154
|
-
...commonProps(opts),
|
|
181
|
+
...commonProps(opts, 'checkbox'),
|
|
155
182
|
accessorFn: opts.accessor,
|
|
156
183
|
getDisplayValue: opts.getDisplayValue,
|
|
157
184
|
filterValueType: FilterValueType.Bool,
|
|
@@ -164,7 +191,7 @@ export function createColumnFactory() {
|
|
|
164
191
|
date(opts) {
|
|
165
192
|
const def = new DateInputDef({
|
|
166
193
|
id: opts.id,
|
|
167
|
-
...commonProps(opts),
|
|
194
|
+
...commonProps(opts, 'date'),
|
|
168
195
|
accessorFn: opts.accessor,
|
|
169
196
|
getDisplayValue: opts.getDisplayValue,
|
|
170
197
|
showTime: opts.withTime ?? false,
|
|
@@ -178,7 +205,7 @@ export function createColumnFactory() {
|
|
|
178
205
|
select(opts) {
|
|
179
206
|
const def = new SelectDef({
|
|
180
207
|
id: opts.id,
|
|
181
|
-
...commonProps(opts),
|
|
208
|
+
...commonProps(opts, 'select'),
|
|
182
209
|
accessorFn: opts.accessor,
|
|
183
210
|
getOptions: normaliseOptionsLoader(opts.options),
|
|
184
211
|
getDisplayValue: opts.getDisplayValue ?? ((row) => String(row[opts.id] ?? '')),
|
|
@@ -199,7 +226,7 @@ export function createColumnFactory() {
|
|
|
199
226
|
query(opts) {
|
|
200
227
|
const def = new QueryDef({
|
|
201
228
|
id: opts.id,
|
|
202
|
-
...commonProps(opts),
|
|
229
|
+
...commonProps(opts, 'query'),
|
|
203
230
|
accessorFn: opts.accessor,
|
|
204
231
|
// Forward the row to the consumer's query callback so it
|
|
205
232
|
// may scope results by row-level context (e.g. a `pod`
|
|
@@ -224,7 +251,7 @@ export function createColumnFactory() {
|
|
|
224
251
|
: undefined;
|
|
225
252
|
const def = new DisplayDef({
|
|
226
253
|
id,
|
|
227
|
-
...commonProps(opts),
|
|
254
|
+
...commonProps(opts, 'display'),
|
|
228
255
|
accessorFn: opts.value,
|
|
229
256
|
modal: opts.modal,
|
|
230
257
|
// Display columns have no implicit filter type (unlike the
|
|
@@ -241,7 +268,7 @@ export function createColumnFactory() {
|
|
|
241
268
|
const id = mintSyntheticId('bubble', opts.idHint);
|
|
242
269
|
const def = new BubbleDef({
|
|
243
270
|
id,
|
|
244
|
-
...commonProps(opts),
|
|
271
|
+
...commonProps(opts, 'bubble'),
|
|
245
272
|
accessorFn: opts.value,
|
|
246
273
|
getColour: opts.colour,
|
|
247
274
|
filterValueType: opts.filterValueType,
|
|
@@ -267,7 +294,7 @@ export function createColumnFactory() {
|
|
|
267
294
|
: () => 'grey';
|
|
268
295
|
const def = new ProgressBarDef({
|
|
269
296
|
id,
|
|
270
|
-
...commonProps(opts),
|
|
297
|
+
...commonProps(opts, 'progress'),
|
|
271
298
|
accessorFn: tupleAccessor,
|
|
272
299
|
getColour,
|
|
273
300
|
filterValueType: opts.filterValueType,
|
|
@@ -281,7 +308,7 @@ export function createColumnFactory() {
|
|
|
281
308
|
id,
|
|
282
309
|
header: opts?.header ?? '',
|
|
283
310
|
minSize: opts?.minWidth,
|
|
284
|
-
width: opts?.width,
|
|
311
|
+
width: opts?.width ?? KIND_DEFAULT_WIDTHS.validity,
|
|
285
312
|
defaultHidden: opts?.defaultHidden,
|
|
286
313
|
resizable: opts?.resizable ?? false,
|
|
287
314
|
debug: opts?.debug,
|
|
@@ -295,6 +322,11 @@ export function createColumnFactory() {
|
|
|
295
322
|
const def = new RowSelectionDef({
|
|
296
323
|
isSelectable: opts?.isSelectable ?? (() => true),
|
|
297
324
|
});
|
|
325
|
+
// RowSelection has no public width option - apply the per-kind
|
|
326
|
+
// default so the column does not collapse to the 48px ColumnDef
|
|
327
|
+
// fallback and share equal `1fr` track space with wider columns.
|
|
328
|
+
def.width = KIND_DEFAULT_WIDTHS.rowSelection;
|
|
329
|
+
def.minSize = KIND_DEFAULT_WIDTHS.rowSelection;
|
|
298
330
|
return makeSpec('rowSelection', def);
|
|
299
331
|
},
|
|
300
332
|
actions(opts) {
|
|
@@ -317,6 +349,8 @@ export function createColumnFactory() {
|
|
|
317
349
|
actions: wrapped,
|
|
318
350
|
isEnabled: isEnabledFn ? (item) => isEnabledFn(item) : undefined,
|
|
319
351
|
});
|
|
352
|
+
// Actions has no public width option - apply the per-kind default.
|
|
353
|
+
def.width = KIND_DEFAULT_WIDTHS.actions;
|
|
320
354
|
return makeSpec('actions', def);
|
|
321
355
|
},
|
|
322
356
|
expand(opts) {
|
|
@@ -359,6 +393,9 @@ export function createColumnFactory() {
|
|
|
359
393
|
allowCopy: opts.inner?.allowCopy,
|
|
360
394
|
},
|
|
361
395
|
});
|
|
396
|
+
// Expand has no public width option - apply the per-kind default.
|
|
397
|
+
def.width = KIND_DEFAULT_WIDTHS.expand;
|
|
398
|
+
def.minSize = KIND_DEFAULT_WIDTHS.expand;
|
|
362
399
|
return makeSpec('expand', def);
|
|
363
400
|
},
|
|
364
401
|
filterOnly(opts) {
|
|
@@ -105,8 +105,19 @@
|
|
|
105
105
|
untrack(() => {
|
|
106
106
|
if (tableContext.focusStart && ref) {
|
|
107
107
|
const { row, column: index } = tableContext.focusStart;
|
|
108
|
+
// `columnDefs[index]` can be undefined when the focus
|
|
109
|
+
// coordinate references a memory slot that no longer
|
|
110
|
+
// exists (e.g. inner expand tables remount with a
|
|
111
|
+
// different column count, or a preset hydration races
|
|
112
|
+
// the column-layout init). Guard before destructuring
|
|
113
|
+
// so an out-of-range index degrades to "no focus
|
|
114
|
+
// restored" instead of a hard crash.
|
|
115
|
+
const def = tableContext.columnDefs[index];
|
|
116
|
+
if (!def) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
108
119
|
let element = ref.querySelector(
|
|
109
|
-
`#${tableContext.tableName}-cell-${row}-${
|
|
120
|
+
`#${tableContext.tableName}-cell-${row}-${def.id}`
|
|
110
121
|
) as HTMLElement | undefined;
|
|
111
122
|
|
|
112
123
|
if (element?.tabIndex == -1) {
|
|
@@ -136,8 +147,13 @@
|
|
|
136
147
|
untrack(() => {
|
|
137
148
|
if (tableContext.focusEnd && ref) {
|
|
138
149
|
const { row, column: index } = tableContext.focusEnd;
|
|
150
|
+
// Same out-of-range guard as the focusStart effect above.
|
|
151
|
+
const def = tableContext.columnDefs[index];
|
|
152
|
+
if (!def) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
139
155
|
const cell = ref.querySelector(
|
|
140
|
-
`#${tableContext.tableName}-cell-${row}-${
|
|
156
|
+
`#${tableContext.tableName}-cell-${row}-${def.id}`
|
|
141
157
|
) as HTMLElement | undefined;
|
|
142
158
|
|
|
143
159
|
cell?.scrollIntoView({
|