@lavalogic/scoria 0.37.14 → 0.37.15

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.
@@ -111,6 +111,12 @@ function commonProps(opts, kind) {
111
111
  width: opts.width ?? defaultWidth,
112
112
  maxWidth: opts.maxWidth,
113
113
  wrapValue: opts.wrapValue,
114
+ // `widthIsFixed` is true only when the caller passed an explicit
115
+ // `width`. The grid template uses this to render the track as
116
+ // fixed `${W}px` for explicit widths, leaving the per-kind-default
117
+ // columns on `minmax(W, 1fr)` so they absorb any horizontal space
118
+ // the fixed columns leave behind.
119
+ widthIsFixed: opts.width != null,
114
120
  allowSorting: opts.allowSorting,
115
121
  allowFiltering: opts.allowFiltering,
116
122
  defaultHidden: opts.defaultHidden,
@@ -285,7 +291,12 @@ export function createColumnFactory() {
285
291
  // typed kinds where the factory pins one based on the
286
292
  // column kind). Consumers opt in by passing the type they
287
293
  // want the filter input rendered as.
288
- filterValueType: opts.filterValueType,
294
+ // Default to string-typed filter when the caller did not specify
295
+ // one, so a display column with no explicit `filterValueType`
296
+ // still appears in the filter UI (matches the `DisplayDef →
297
+ // stringFilter (undefined case)` mapping in
298
+ // `setupDefaultColumnDefs`).
299
+ filterValueType: opts.filterValueType ?? FilterValueType.String,
289
300
  getSortingFn: opts.getSortingFn,
290
301
  getOptions: normalisedOptions,
291
302
  });
@@ -298,7 +309,12 @@ export function createColumnFactory() {
298
309
  ...commonProps(opts, 'bubble'),
299
310
  accessorFn: opts.value,
300
311
  getColour: opts.colour,
301
- filterValueType: opts.filterValueType,
312
+ // Default to a string-typed filter so bubble columns appear in
313
+ // the quick-filter row and advanced filter panel by default
314
+ // (matches the `BubbleDef → stringFilter` mapping in
315
+ // `setupDefaultColumnDefs`). Caller can override to any other
316
+ // `filterValueType`, or pass `allowFiltering: false` to opt out.
317
+ filterValueType: opts.filterValueType ?? FilterValueType.String,
302
318
  });
303
319
  return makeSpec('bubble', def);
304
320
  },
@@ -324,7 +340,10 @@ export function createColumnFactory() {
324
340
  ...commonProps(opts, 'progress'),
325
341
  accessorFn: tupleAccessor,
326
342
  getColour,
327
- filterValueType: opts.filterValueType,
343
+ // Default to number-typed filter so progress columns appear in
344
+ // the filter UI by default (matches `ProgressBarDef →
345
+ // numberFilter` in `setupDefaultColumnDefs`).
346
+ filterValueType: opts.filterValueType ?? FilterValueType.Number,
328
347
  });
329
348
  return makeSpec('progress', def);
330
349
  },
@@ -336,6 +355,7 @@ export function createColumnFactory() {
336
355
  header: opts?.header ?? '',
337
356
  minSize: opts?.minWidth ?? KIND_DEFAULT_WIDTHS.validity,
338
357
  width: opts?.width ?? KIND_DEFAULT_WIDTHS.validity,
358
+ widthIsFixed: opts?.width != null,
339
359
  defaultHidden: opts?.defaultHidden,
340
360
  resizable: opts?.resizable ?? false,
341
361
  debug: opts?.debug,
@@ -354,6 +374,7 @@ export function createColumnFactory() {
354
374
  // fallback and share equal `1fr` track space with wider columns.
355
375
  def.width = KIND_DEFAULT_WIDTHS.rowSelection;
356
376
  def.minSize = KIND_DEFAULT_WIDTHS.rowSelection;
377
+ def.widthIsFixed = true;
357
378
  return makeSpec('rowSelection', def);
358
379
  },
359
380
  actions(opts) {
@@ -378,6 +399,7 @@ export function createColumnFactory() {
378
399
  });
379
400
  // Actions has no public width option - apply the per-kind default.
380
401
  def.width = KIND_DEFAULT_WIDTHS.actions;
402
+ def.widthIsFixed = true;
381
403
  return makeSpec('actions', def);
382
404
  },
383
405
  expand(opts) {
@@ -423,6 +445,7 @@ export function createColumnFactory() {
423
445
  // Expand has no public width option - apply the per-kind default.
424
446
  def.width = KIND_DEFAULT_WIDTHS.expand;
425
447
  def.minSize = KIND_DEFAULT_WIDTHS.expand;
448
+ def.widthIsFixed = true;
426
449
  return makeSpec('expand', def);
427
450
  },
428
451
  filterOnly(opts) {
@@ -356,17 +356,20 @@
356
356
  // 20px to match the existing visual).
357
357
  // - Each other track uses one of two strategies based on the
358
358
  // column's `userResized` flag:
359
- // - `userResized = false` (default): `minmax(width, maxWidth ?? 1fr)`.
360
- // The column is at least `width` wide and grows to share any
361
- // leftover horizontal space with its sibling tracks. If the
362
- // column has a `maxWidth`, that pixel value is the upper bound
363
- // instead - the column never grows past `maxWidth`, and cells
364
- // whose content exceeds the track ellipsise (or wrap, when the
365
- // column opts in to `wrapValue`). The `1fr` upper bound was
366
- // chosen over `max-content` because `max-content` is unstable
367
- // under row virtualisation: tracks resize as rows scroll in
368
- // and out of the rendered window because the auto-min/max
369
- // consults only the currently-rendered cells.
359
+ // - `userResized = false`: track depends on whether the consumer
360
+ // supplied an explicit `width` and / or `maxWidth`:
361
+ // - `widthIsFixed` (consumer-supplied `width`, no `maxWidth`):
362
+ // fixed `${width}px` track. Stays at exactly that pixel value
363
+ // regardless of leftover container width.
364
+ // - `maxWidth` set (with or without explicit width): the track
365
+ // becomes `minmax(${width}px, ${maxWidth}px)`, a bounded flex
366
+ // that grows up to `maxWidth` and is then capped.
367
+ // - Neither (the column is on its per-kind default width):
368
+ // `minmax(${width}px, 1fr)`, the column flexes to absorb any
369
+ // horizontal space the fixed-width tracks leave behind.
370
+ // This produces the "specify widths for the columns you care
371
+ // about; let the rest fill the gap" behaviour that mirrors the
372
+ // legacy `<table>` element when only some columns set a width.
370
373
  // - `userResized = true`: `${width}px` (fixed). The column sits
371
374
  // at exactly the size the user dragged it to, and dragging the
372
375
  // handle again only changes this column.
@@ -378,14 +381,23 @@
378
381
  const colsTemplate = $derived.by(() => {
379
382
  void tableContext.columnSizing;
380
383
  const track = (col: {
381
- columnDef: { width: number; maxWidth?: number; userResized: boolean };
384
+ columnDef: {
385
+ width: number;
386
+ maxWidth?: number;
387
+ userResized: boolean;
388
+ widthIsFixed: boolean;
389
+ };
382
390
  }) => {
383
391
  if (col.columnDef.userResized) {
384
392
  return `${col.columnDef.width}px`;
385
393
  }
386
- const upper =
387
- col.columnDef.maxWidth != null ? `${col.columnDef.maxWidth}px` : '1fr';
388
- return `minmax(${col.columnDef.width}px, ${upper})`;
394
+ if (col.columnDef.maxWidth != null) {
395
+ return `minmax(${col.columnDef.width}px, ${col.columnDef.maxWidth}px)`;
396
+ }
397
+ if (col.columnDef.widthIsFixed) {
398
+ return `${col.columnDef.width}px`;
399
+ }
400
+ return `minmax(${col.columnDef.width}px, 1fr)`;
389
401
  };
390
402
  const tracks: Array<string> = ['20px'];
391
403
  for (const col of leftColumns) {
@@ -53,6 +53,14 @@ export interface ColumnDefProps<T extends object, in FilterFnType, out OptionsTy
53
53
  * Cell content beyond the track is ellipsised, or wraps when
54
54
  * `wrapValue` is also set. */
55
55
  maxWidth?: Pixels;
56
+ /** Set by the column factory when the consumer supplied an explicit
57
+ * `width` (vs. the factory's per-kind default). The grid template
58
+ * treats an explicit width as fixed (`${width}px` track) and a
59
+ * per-kind default as flexible (`minmax(width, 1fr)` track), so a
60
+ * table whose specified widths total less than the container leaves
61
+ * the unspecified columns to absorb the trailing space rather than
62
+ * every column expanding by equal `1fr` shares. */
63
+ widthIsFixed?: boolean;
56
64
  /** When true, cell content that does not fit wraps onto new lines
57
65
  * and the row's height grows to fit. When false (default) overflow
58
66
  * is clipped with ellipsis. Surfaces as the `--wrap-value` CSS
@@ -148,6 +156,12 @@ export declare abstract class ColumnDef<T extends object, in FilterFnType = neve
148
156
  * clipped with ellipsis (false). */
149
157
  get wrapValue(): boolean;
150
158
  set wrapValue(v: boolean);
159
+ private _widthIsFixed;
160
+ /** Set by the column factory when the consumer supplied an explicit
161
+ * `width`. Drives the grid-template branch: true = fixed `${width}px`
162
+ * track, false = `minmax(width, 1fr)` flex track. */
163
+ get widthIsFixed(): boolean;
164
+ set widthIsFixed(v: boolean);
151
165
  private _isResizing;
152
166
  /** Whether the resize handle is currently active. */
153
167
  get isResizing(): boolean;
@@ -38,6 +38,7 @@ export class ColumnDef {
38
38
  this._width = $state(props.width ?? props.minSize ?? 48);
39
39
  this._maxWidth = $state(props.maxWidth);
40
40
  this._wrapValue = $state(props.wrapValue ?? false);
41
+ this._widthIsFixed = $state(props.widthIsFixed ?? false);
41
42
  this.isEditable = $derived(props.isEditable ?? (() => Promise.resolve(false)));
42
43
  this.resizable = $derived(props.resizable ?? true);
43
44
  this.header = $derived(props.header);
@@ -108,6 +109,16 @@ export class ColumnDef {
108
109
  set wrapValue(v) {
109
110
  this._wrapValue = v;
110
111
  }
112
+ _widthIsFixed;
113
+ /** Set by the column factory when the consumer supplied an explicit
114
+ * `width`. Drives the grid-template branch: true = fixed `${width}px`
115
+ * track, false = `minmax(width, 1fr)` flex track. */
116
+ get widthIsFixed() {
117
+ return this._widthIsFixed;
118
+ }
119
+ set widthIsFixed(v) {
120
+ this._widthIsFixed = v;
121
+ }
111
122
  _isResizing = $state(false);
112
123
  /** Whether the resize handle is currently active. */
113
124
  get isResizing() {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lavalogic/scoria",
3
3
  "description": "Svelte components used for the FloWMS Web Frontend",
4
- "version": "0.37.14",
4
+ "version": "0.37.15",
5
5
  "publishConfig": {
6
6
  "access": "restricted"
7
7
  },