@lavalogic/scoria 0.37.26 → 0.37.28

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.
@@ -298,7 +298,7 @@ label {
298
298
 
299
299
  .error-wrapper {
300
300
  display: block;
301
- height: max(var(--input-height, 3rem));
301
+ height: max(var(--input-height, 3rem), 2rem);
302
302
  width: var(--input-width, 100%);
303
303
  }
304
304
  .error-wrapper.for-table {
@@ -320,7 +320,7 @@ label {
320
320
 
321
321
  .error-wrapper {
322
322
  display: block;
323
- height: max(var(--input-height, 3rem));
323
+ height: max(var(--input-height, 3rem), 2rem);
324
324
  width: var(--input-width, 100%);
325
325
  }
326
326
  .error-wrapper.for-table {
@@ -386,7 +386,7 @@ label {
386
386
 
387
387
  .error-wrapper {
388
388
  display: block;
389
- height: max(var(--input-height, 3rem));
389
+ height: max(var(--input-height, 3rem), 2rem);
390
390
  width: var(--input-width, 100%);
391
391
  }
392
392
  .error-wrapper.for-table {
@@ -307,7 +307,7 @@ label {
307
307
 
308
308
  .error-wrapper {
309
309
  display: block;
310
- height: max(var(--input-height, 3rem));
310
+ height: max(var(--input-height, 3rem), 2rem);
311
311
  width: var(--input-width, 100%);
312
312
  }
313
313
  .error-wrapper.for-table {
@@ -238,7 +238,7 @@ label {
238
238
 
239
239
  .error-wrapper {
240
240
  display: block;
241
- height: max(var(--input-height, 3rem));
241
+ height: max(var(--input-height, 3rem), 2rem);
242
242
  width: var(--input-width, 100%);
243
243
  }
244
244
  .error-wrapper.for-table {
@@ -4,7 +4,6 @@
4
4
  lang="ts"
5
5
  generics="T extends object, FilterValueType, RowIdType extends Primitive"
6
6
  >
7
- import Portal from '../../../../Portal.svelte';
8
7
  import type { AbstractDisplayDef } from '../../../Types/Columns/Definitions/Display/AbstractDisplayDef.svelte.js';
9
8
  import { TableContext } from '../../../Types/Context/TableContext.svelte.js';
10
9
  import { type Primitive } from '../../../Types/Context/TableInitOptions.js';
@@ -210,19 +209,22 @@
210
209
  </div>
211
210
  {#if showModal && modalComponent}
212
211
  <!--
213
- Mirrors the `ValidityCell` pattern: portal the modal to
214
- `document.body` so the surrounding sticky / overflow:hidden
215
- ancestors (header, pinned columns, virtualised viewport) never
216
- clip it. The component receives the public
217
- `DisplayModalProps<T>` shape `{ row, close }`.
212
+ The component receives the public `DisplayModalProps<T>` shape
213
+ `{ row, close }`. The dialog is NOT wrapped in
214
+ `<Portal target={document.body}>` any more. `<dialog>` opened
215
+ via `showModal()` enters the browser's top layer, so it already
216
+ escapes overflow:hidden / sticky / transform ancestors without
217
+ needing to be re-parented. Moving the `<div>` ancestor mid-mount
218
+ (Portal's $effect runs during the same microtask round as
219
+ BaseModal's `tick().then` `dialog.showModal()`) was popping the
220
+ dialog out of the top layer and leaving it to render inline at
221
+ the bottom of the page.
218
222
  -->
219
- <Portal target={document.body}>
220
- {@const ModalComponent = modalComponent}
221
- <ModalComponent
222
- row={cell.row.original}
223
- close={onclose}
224
- />
225
- </Portal>
223
+ {@const ModalComponent = modalComponent}
224
+ <ModalComponent
225
+ row={cell.row.original}
226
+ close={onclose}
227
+ />
226
228
  {/if}
227
229
 
228
230
  <style>.focusable,
@@ -6,7 +6,6 @@
6
6
  >
7
7
  import Action from '../../../../Action.svelte';
8
8
  import type { IconProps } from '../../../../IconProps.js';
9
- import Portal from '../../../../Portal.svelte';
10
9
  import type { AbstractDisplayDef } from '../../../Types/Columns/Definitions/Display/AbstractDisplayDef.svelte.js';
11
10
  import { TableContext } from '../../../Types/Context/TableContext.svelte.js';
12
11
  import type { TableFocusDetails } from '../../../Types/Focus/TableFocusDetails.svelte.js';
@@ -161,22 +160,30 @@
161
160
  />
162
161
  </div>
163
162
  {#if showModal}
164
- <Portal target={document.body}>
165
- <!--
166
- `ColumnDef.modal` is declared as
167
- `Component<DisplayModalProps<TRow>>` on the public column
168
- options, which exposes a stable `{ row, close }` prop
169
- shape. Cell renderers used to hand a legacy
170
- `{ cell, onclose, onsubmit }` triple here, which made the
171
- public type lie about the runtime shape - migrated to
172
- `{ row, close }` so consumer-authored modals can rely on
173
- the documented type.
174
- -->
175
- <ColumnDef.modal
176
- row={cell.row.original}
177
- close={onclose}
178
- />
179
- </Portal>
163
+ <!--
164
+ `ColumnDef.modal` is declared as
165
+ `Component<DisplayModalProps<TRow>>` on the public column
166
+ options, which exposes a stable `{ row, close }` prop
167
+ shape. Cell renderers used to hand a legacy
168
+ `{ cell, onclose, onsubmit }` triple here, which made the
169
+ public type lie about the runtime shape - migrated to
170
+ `{ row, close }` so consumer-authored modals can rely on
171
+ the documented type.
172
+
173
+ The dialog is NOT wrapped in `<Portal target={document.body}>`
174
+ any more. `<dialog>` opened via `showModal()` enters the
175
+ browser's top layer, so it already escapes overflow:hidden /
176
+ sticky / transform ancestors without needing to be re-parented.
177
+ Moving the `<div>` ancestor mid-mount (Portal's $effect runs
178
+ during the same microtask round as BaseModal's `tick().then`
179
+ `dialog.showModal()`) was popping the dialog out of the top
180
+ layer and leaving it to render inline at the bottom of the
181
+ page.
182
+ -->
183
+ <ColumnDef.modal
184
+ row={cell.row.original}
185
+ close={onclose}
186
+ />
180
187
  {/if}
181
188
  </div>
182
189
 
@@ -1,4 +1,3 @@
1
- import { memoiseRowAccessor } from '../../../../../../Helpers/memoiseByRow.js';
2
1
  import { AccessorDef } from './AccessorDef.svelte.js';
3
2
  import { AccessorType } from './AccessorType.js';
4
3
  /**
@@ -11,10 +10,14 @@ import { AccessorType } from './AccessorType.js';
11
10
  export class SelectDef extends AccessorDef {
12
11
  constructor(props) {
13
12
  super(props);
14
- // Row-keyed WeakMap cache around the per-row options provider. For
15
- // Promise returns the Promise itself is cached, so {#await} resolves
16
- // once per row rather than per render.
17
- this.getSpecificOptions = $derived(memoiseRowAccessor(props.getSpecificOptions));
13
+ // Pass through `props.getSpecificOptions` unchanged. The previous
14
+ // `memoiseRowAccessor` wrapper cached the per-row option set by
15
+ // row identity, which made the cached option list stick around
16
+ // even when the row's mutable properties changed - subtle but
17
+ // real bug surface for any cell that wants different options
18
+ // after a sibling property is edited. Svelte's `$derived` in
19
+ // `TableSelect` already memoises the call correctly.
20
+ this.getSpecificOptions = $derived(props.getSpecificOptions);
18
21
  this.optional = $derived(props.optional ?? false);
19
22
  this.clearable = $derived(props.clearable ?? true);
20
23
  this._filterFn = $state(props.filterFn);
@@ -1,4 +1,3 @@
1
- import { memoiseRowAccessor } from '../../../../../Helpers/memoiseByRow.js';
2
1
  import { ColumnType } from '../ColumnType.js';
3
2
  /**
4
3
  * `ColumnDef<T, FilterFnType, OptionsType, TValue>` is the abstract base
@@ -46,12 +45,24 @@ export class ColumnDef {
46
45
  this.resizable = $derived(props.resizable ?? true);
47
46
  this.header = $derived(props.header);
48
47
  this._filterValueType = $derived(props.filterValueType);
49
- // Row-keyed WeakMap cache so a 1000-row render invokes the user
50
- // callback at most once per row. Reassigning props.getDisplayValue
51
- // re-derives the wrapper and discards the stale cache automatically.
52
- // Async returns: the Promise itself is cached, so repeated reads
53
- // return the same Promise and Svelte's {#await} resolves once.
54
- this.getDisplayValue = $derived(memoiseRowAccessor(props.getDisplayValue));
48
+ // Pass through `props.getDisplayValue` unchanged.
49
+ //
50
+ // We used to wrap this with `memoiseRowAccessor`, which caches the
51
+ // result by row identity in a WeakMap. That broke every editable
52
+ // cell whose display depends on a mutable row property: after a
53
+ // user edited e.g. `item.receiptLineId`, the next render still
54
+ // got the cached `null` from the first call and rows never
55
+ // updated (visible on the Receipt pod table's SKU column - the
56
+ // dropdown selection appeared not to take effect and the
57
+ // downstream Title / UoM columns never populated).
58
+ //
59
+ // Svelte's `$derived` at the cell layer (`TableSelect`,
60
+ // `FocusableImmutableCell`, ...) already memoises correctly: it
61
+ // only re-runs the user callback when its reactive inputs change
62
+ // (cell, row identity, column def, or any state read inside the
63
+ // user function's synchronous portion). The per-Def WeakMap was
64
+ // an extra correctness-eating layer.
65
+ this.getDisplayValue = $derived(props.getDisplayValue);
55
66
  this.debug = $derived(props.debug ?? false);
56
67
  this.getSortingFn = $derived(props.getSortingFn);
57
68
  this.getOptions = $derived(props.getOptions);
@@ -326,7 +326,7 @@ label {
326
326
 
327
327
  .error-wrapper {
328
328
  display: block;
329
- height: max(var(--input-height, 3rem));
329
+ height: max(var(--input-height, 3rem), 2rem);
330
330
  width: var(--input-width, 100%);
331
331
  }
332
332
  .error-wrapper.for-table {
@@ -1065,9 +1065,14 @@
1065
1065
 
1066
1066
  .error-wrapper {
1067
1067
  display: block;
1068
- // width: 100%;
1069
- // height: max(var(--input-height, #{sizing.$input-height}), 2rem);
1070
- height: max(var(--input-height, #{sizing.$input-height}));
1068
+ // `max()` requires at least two arguments. The previous
1069
+ // `height: max(var(--input-height, 3rem))` was invalid CSS and
1070
+ // the browser dropped the rule, leaving the wrapper at
1071
+ // `height: auto`, which collapsed inputs inside modals (e.g.
1072
+ // the Edit Receipt Attributes Line Details tab) to ~30px
1073
+ // because the inner `<input>` uses `height: 100%`. Use the
1074
+ // two-argument form that matches `.textarea-error-wrapper`.
1075
+ height: max(var(--input-height, #{sizing.$input-height}), 2rem);
1071
1076
  width: var(--input-width, 100%);
1072
1077
 
1073
1078
  &.for-table {
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.26",
4
+ "version": "0.37.28",
5
5
  "publishConfig": {
6
6
  "access": "restricted"
7
7
  },