@lavalogic/scoria 0.40.31 → 0.40.33

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.
Files changed (137) hide show
  1. package/README.md +58 -58
  2. package/dist/Components/AccordionGroup.svelte +28 -28
  3. package/dist/Components/AccordionGroupButton.svelte +60 -60
  4. package/dist/Components/Action.svelte +48 -48
  5. package/dist/Components/AlertModal.svelte +102 -102
  6. package/dist/Components/Base/ContextWrapper.svelte +45 -45
  7. package/dist/Components/Base/Pagination.svelte +135 -135
  8. package/dist/Components/Base/Snippets.svelte +25 -25
  9. package/dist/Components/BigRadioSet.svelte +34 -34
  10. package/dist/Components/Bubble.svelte +38 -38
  11. package/dist/Components/Button.svelte +83 -83
  12. package/dist/Components/Checkbox.svelte +71 -71
  13. package/dist/Components/CollapsibleCard.svelte +59 -59
  14. package/dist/Components/CollapsibleMenuGroup.svelte +43 -43
  15. package/dist/Components/ConditionBuilder/ConditionBuilder.svelte +101 -101
  16. package/dist/Components/Contexts/ContextMenu.svelte +76 -76
  17. package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
  18. package/dist/Components/Contexts/ContextMenuOption.svelte +38 -38
  19. package/dist/Components/Contexts/Toast.svelte +71 -71
  20. package/dist/Components/Contexts/ToastContainer.svelte +34 -34
  21. package/dist/Components/Contexts/Tooltip.svelte +32 -32
  22. package/dist/Components/DataMatrixIcon.svelte +37 -37
  23. package/dist/Components/DateInput.svelte +80 -80
  24. package/dist/Components/DatePicker.svelte +86 -86
  25. package/dist/Components/DesktopModal.svelte +65 -65
  26. package/dist/Components/Dial.svelte +35 -35
  27. package/dist/Components/DimensionInput.svelte +95 -95
  28. package/dist/Components/DragMenu/DragMenuHolder.svelte +53 -53
  29. package/dist/Components/DragMenu/DraggableCard.svelte +49 -49
  30. package/dist/Components/FileCard.svelte +18 -18
  31. package/dist/Components/FileUpload.svelte +115 -115
  32. package/dist/Components/GridInput.svelte +123 -123
  33. package/dist/Components/GridInputSet.svelte +21 -21
  34. package/dist/Components/HorizontalTabGroup.svelte +54 -54
  35. package/dist/Components/HorizontalTabGroupButton.svelte +32 -32
  36. package/dist/Components/Icon.svelte +68 -68
  37. package/dist/Components/Icons.d.ts +3 -3
  38. package/dist/Components/Icons.js +11 -11
  39. package/dist/Components/InfoAlert.svelte +32 -32
  40. package/dist/Components/LoadingAnimation.svelte +228 -227
  41. package/dist/Components/LoadingModal.svelte +19 -19
  42. package/dist/Components/LoadingOverlay.svelte +20 -20
  43. package/dist/Components/Modal.svelte +127 -127
  44. package/dist/Components/MultiSelect.svelte +126 -126
  45. package/dist/Components/Nav/Nav.svelte +71 -71
  46. package/dist/Components/Nav/NavServiceMenuList.svelte +37 -37
  47. package/dist/Components/Nav/NavTab.svelte +46 -46
  48. package/dist/Components/Nav/ServiceMenuItem.svelte +62 -62
  49. package/dist/Components/Nav/ServicesNav.svelte +50 -50
  50. package/dist/Components/NumberInput.svelte +98 -98
  51. package/dist/Components/OptionCards.svelte +58 -58
  52. package/dist/Components/PageHeading.svelte +21 -21
  53. package/dist/Components/PasswordInput.svelte +61 -61
  54. package/dist/Components/PopoverButton.svelte +53 -53
  55. package/dist/Components/Portal.svelte +7 -7
  56. package/dist/Components/ProgressBubble.svelte +42 -42
  57. package/dist/Components/QuerySelect.svelte +102 -102
  58. package/dist/Components/ResourceCalendar/ResourceCalendar.svelte +241 -241
  59. package/dist/Components/SidebarPanel.svelte +32 -32
  60. package/dist/Components/SingleSelect.svelte +122 -122
  61. package/dist/Components/StepButton.svelte +48 -48
  62. package/dist/Components/StepForm.svelte +58 -58
  63. package/dist/Components/Switch.svelte +43 -43
  64. package/dist/Components/Table/ARCHITECTURE.md +298 -298
  65. package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +30 -30
  66. package/dist/Components/Table/Body/Rows/ColumnList.svelte +24 -24
  67. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +165 -165
  68. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +13 -13
  69. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +120 -120
  70. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +81 -81
  71. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +92 -92
  72. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +110 -110
  73. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +54 -54
  74. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +35 -35
  75. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +64 -64
  76. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +82 -82
  77. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +88 -88
  78. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +90 -90
  79. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +96 -96
  80. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +71 -71
  81. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +124 -124
  82. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +91 -91
  83. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +88 -88
  84. package/dist/Components/Table/Body/Rows/TableRow.svelte +127 -127
  85. package/dist/Components/Table/Body/TableBody.svelte +92 -92
  86. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +25 -25
  87. package/dist/Components/Table/Headers/SelectAllHeader.svelte +20 -20
  88. package/dist/Components/Table/Headers/TableHead.svelte +175 -175
  89. package/dist/Components/Table/Misc/ColumnPanel.svelte +32 -32
  90. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +29 -29
  91. package/dist/Components/Table/Misc/FilterInput.svelte +326 -326
  92. package/dist/Components/Table/Misc/FilterPanel.svelte +79 -79
  93. package/dist/Components/Table/Misc/FilterPanelModal.svelte +21 -21
  94. package/dist/Components/Table/Misc/ShareViewModal.svelte +118 -118
  95. package/dist/Components/Table/Misc/SidePanel.svelte +24 -24
  96. package/dist/Components/Table/Misc/TableConfigurationModal.svelte +318 -318
  97. package/dist/Components/Table/Misc/TableFooter.svelte +201 -201
  98. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +112 -112
  99. package/dist/Components/Table/Misc/TableSidebar.svelte +116 -116
  100. package/dist/Components/Table/Misc/TableViewDropdown.svelte +25 -25
  101. package/dist/Components/Table/Misc/ToolboxPanel.svelte +60 -60
  102. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +63 -63
  103. package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +101 -101
  104. package/dist/Components/Table/NestedTable.svelte +29 -29
  105. package/dist/Components/Table/Table.svelte +140 -140
  106. package/dist/Components/Test/TestContextConsumer.svelte +8 -8
  107. package/dist/Components/TextArea.svelte +92 -90
  108. package/dist/Components/TextInput.svelte +128 -117
  109. package/dist/Components/ThreeStateRadio.svelte +101 -101
  110. package/dist/Components/Touch/BoolCard.svelte +27 -27
  111. package/dist/Components/Touch/DateModal.svelte +98 -98
  112. package/dist/Components/Touch/EditCard.svelte +44 -44
  113. package/dist/Components/Touch/InfoCard.svelte +25 -25
  114. package/dist/Components/Touch/InfoTextCard.svelte +22 -22
  115. package/dist/Components/Touch/ModalExplanation.svelte +13 -13
  116. package/dist/Components/Touch/NumberKeyboard.svelte +81 -81
  117. package/dist/Components/Touch/NumberModal.svelte +49 -49
  118. package/dist/Components/Touch/PlusMinusCard.svelte +40 -40
  119. package/dist/Components/Touch/SelectModal.svelte +86 -86
  120. package/dist/Components/Touch/SummaryCard.svelte +74 -74
  121. package/dist/Components/Touch/TextAreaModal.svelte +53 -53
  122. package/dist/Components/Touch/TextModal.svelte +56 -56
  123. package/dist/Components/Touch/TouchCard.svelte +28 -28
  124. package/dist/Components/Touch/TouchModal.svelte +141 -141
  125. package/dist/Components/Touch/UtilityButton.svelte +63 -63
  126. package/dist/Components/VerticalTabGroup.svelte +38 -38
  127. package/dist/Components/VerticalTabGroupButton.svelte +46 -46
  128. package/dist/Helpers/Datamatrix.d.ts +19 -19
  129. package/dist/Helpers/Datamatrix.js +291 -291
  130. package/dist/Types/Examples/ExampleModal.svelte +27 -27
  131. package/dist/paraglide/README.md +1 -1
  132. package/dist/scss/_basics.scss +12 -12
  133. package/dist/scss/_colours.scss +140 -140
  134. package/dist/scss/_motion.scss +57 -57
  135. package/dist/scss/_sizing.scss +85 -85
  136. package/dist/scss/_transitions.scss +8 -8
  137. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
- <svelte:options runes />
2
-
3
- <script
4
- lang="ts"
5
- generics="T extends object, IdType extends Primitive"
1
+ <svelte:options runes />
2
+
3
+ <script
4
+ lang="ts"
5
+ generics="T extends object, IdType extends Primitive"
6
6
  >import Action from "../../../Action.svelte";
7
7
  import { Colour } from "../../../../scss/colours.js";
8
8
  import { Size } from "../../../../Types/Internal/Size.js";
@@ -15,30 +15,30 @@ const backgroundColour = $derived(highlighted ? Colour["$brand-primary"] : Colou
15
15
  // attributes when multiple tables share the page (workorder P2).
16
16
  const cellId = $derived(`${tableContext.tableName}-tagger-row-${rowIndex}`);
17
17
  const label = $derived(`${highlighted ? "Unhighlight" : "Highlight"} row ${(rowIndex + 1).toString()}`);
18
- </script>
19
-
20
- <!-- Toggle semantics: `aria-pressed` is communicated through the Action's label
21
- which reads either "Highlight row N" or "Unhighlight row N" depending on state. -->
22
- <div
23
- id={cellId}
24
- class="highlight-content"
25
- >
26
- <div class="wrapper">
27
- <Action
28
- {backgroundColour}
29
- hoverBackgroundColour={Colour['$brand-dark']}
30
- size={Size.FillWidth}
31
- {label}
32
- icon={{
33
- name: 'nothing',
34
- }}
35
- onclick={() => {
36
- toggleHighlightedRow();
37
- }}
38
- />
39
- </div>
40
- </div>
41
-
18
+ </script>
19
+
20
+ <!-- Toggle semantics: `aria-pressed` is communicated through the Action's label
21
+ which reads either "Highlight row N" or "Unhighlight row N" depending on state. -->
22
+ <div
23
+ id={cellId}
24
+ class="highlight-content"
25
+ >
26
+ <div class="wrapper">
27
+ <Action
28
+ {backgroundColour}
29
+ hoverBackgroundColour={Colour['$brand-dark']}
30
+ size={Size.FillWidth}
31
+ {label}
32
+ icon={{
33
+ name: 'nothing',
34
+ }}
35
+ onclick={() => {
36
+ toggleHighlightedRow();
37
+ }}
38
+ />
39
+ </div>
40
+ </div>
41
+
42
42
  <style>.focusable,
43
43
  .checkbox-cell,
44
44
  .input-cell,
@@ -84,4 +84,4 @@ div.wrapper {
84
84
 
85
85
  .wrapper {
86
86
  overflow: hidden;
87
- }</style>
87
+ }</style>
@@ -1,8 +1,8 @@
1
- <svelte:options runes />
2
-
3
- <script
4
- lang="ts"
5
- generics="T extends object, IdType extends Primitive"
1
+ <svelte:options runes />
2
+
3
+ <script
4
+ lang="ts"
5
+ generics="T extends object, IdType extends Primitive"
6
6
  >import { m as i18n } from "../../../../paraglide/messages.js";
7
7
  import { ColumnType } from "../../Types/Columns/ColumnType.js";
8
8
  import { TableContext } from "../../Types/Context/TableContext.svelte.js";
@@ -23,24 +23,24 @@ function onDrop(e) {
23
23
  tableContext.reorderColumn(dropTarget);
24
24
  }
25
25
  }
26
- </script>
27
-
28
- <ul
29
- class="column-list"
30
- ondrop={onDrop}
31
- >
32
- <!-- HACK this is used as an anchor for dragging rows to the top -->
33
- <ColumnListRow columnDef={null} />
34
-
35
- {#each visibleColumns as columnDef (columnDef.id)}
36
- <ColumnListRow {columnDef} />
37
- {:else}
38
- {#if searchValue.length > 0}
39
- <li class="empty-state">{i18n['scoria.text.no_columns_match']({ query: searchValue })}</li>
40
- {/if}
41
- {/each}
42
- </ul>
43
-
26
+ </script>
27
+
28
+ <ul
29
+ class="column-list"
30
+ ondrop={onDrop}
31
+ >
32
+ <!-- HACK this is used as an anchor for dragging rows to the top -->
33
+ <ColumnListRow columnDef={null} />
34
+
35
+ {#each visibleColumns as columnDef (columnDef.id)}
36
+ <ColumnListRow {columnDef} />
37
+ {:else}
38
+ {#if searchValue.length > 0}
39
+ <li class="empty-state">{i18n['scoria.text.no_columns_match']({ query: searchValue })}</li>
40
+ {/if}
41
+ {/each}
42
+ </ul>
43
+
44
44
  <style>ul {
45
45
  list-style: none;
46
46
  background-color: #ffffff;
@@ -60,4 +60,4 @@ function onDrop(e) {
60
60
  text-align: center;
61
61
  color: #8096a5;
62
62
  font-style: italic;
63
- }</style>
63
+ }</style>
@@ -1,8 +1,8 @@
1
- <svelte:options runes />
2
-
3
- <script
4
- lang="ts"
5
- generics="T extends object, IdType extends Primitive"
1
+ <svelte:options runes />
2
+
3
+ <script
4
+ lang="ts"
5
+ generics="T extends object, IdType extends Primitive"
6
6
  >import Action from "../../../Action.svelte";
7
7
  import Checkbox from "../../../Checkbox.svelte";
8
8
  import ThreeStateRadio from "../../../ThreeStateRadio.svelte";
@@ -254,165 +254,165 @@ function onRowKeydown(e) {
254
254
  tableContext.moveColumnTo(currentIndex, targetIndex);
255
255
  });
256
256
  }
257
- </script>
258
-
259
- {#if columnDef}
260
- {@const reorderLabel = typeof columnDef.header === 'string' ? columnDef.header : columnDef.id}
261
- <!--
262
- The `<li>` is a structural container for the eye, pin selector,
263
- label, and reorder buttons - none activated by clicking the `<li>`
264
- itself. The `onkeydown` here only captures Alt+Arrow / Alt+Home /
265
- Alt+End bubbling up from whichever inner control has focus to
266
- drive the reorder shortcut; the `<li>` is not an interactive
267
- widget. The structure is a free-form list of cards (not a tree
268
- or listbox), so the right call is to silence the warning rather
269
- than fake `role="treeitem"` / `role="option"`.
270
- -->
271
- <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
272
- <li
273
- bind:this={rowEl}
274
- class="single-column"
275
- class:targeted={isBeingTargeted}
276
- class:draggable={tableContext.allowColumnReordering}
277
- id="{tableContext.tableName}-column-settings-{columnDef.id}"
278
- draggable={tableContext.allowColumnReordering}
279
- onkeydown={onRowKeydown}
280
- {@attach (node: HTMLLIElement) => {
281
- // Capture-phase `mousedown` and `pointerdown` listeners. Both
282
- // must fire BEFORE the synthetic click on the visibility /
283
- // pin checkbox focuses its hidden input, because that focus
284
- // triggers an auto-scroll to bring the 1x1px clip-pathed
285
- // input into view. Capture phase runs before target / bubble,
286
- // so this listener reliably snapshots the user's true
287
- // pre-click scroll position.
288
- //
289
- // Both event types are wired because browsers differ on which
290
- // fires first; the second is a cheap no-op snapshot.
291
- const snapshot = (): void => {
292
- snapshotScrollPosition();
293
- };
294
- node.addEventListener('pointerdown', snapshot, { capture: true });
295
- node.addEventListener('mousedown', snapshot, { capture: true });
296
- return () => {
297
- node.removeEventListener('pointerdown', snapshot, { capture: true });
298
- node.removeEventListener('mousedown', snapshot, { capture: true });
299
- };
300
- }}
301
- ondragstart={() => {
302
- tableContext.dragTarget = columnDef;
303
- }}
304
- ondragend={disableDragVisual}
305
- ondragover={(e) => {
306
- e.preventDefault();
307
- if (tableContext.dragTarget?.id !== columnDef.id) {
308
- isBeingTargeted = true;
309
- }
310
- }}
311
- ondragleave={disableDragVisual}
312
- ondrop={disableDragVisual}
313
- >
314
- <!--
315
- `.row-main` stacks the column label on top and the visibility /
316
- pin controls underneath so the label gets the full card width
317
- to wrap into. `.reorder-buttons` is a sibling outside
318
- `.row-main` so the up / down arrows stay vertically centred on
319
- the right edge of the card.
320
- -->
321
- <div class="row-main">
322
- <span
323
- class="column-label"
324
- title={typeof columnDef.header === 'string' ? columnDef.header : columnDef.id}
325
- >
326
- {#if typeof columnDef.header === 'function'}
327
- <!-- FIXME this needs testing -->
328
- {@render columnDef.header()}
329
- {:else}
330
- {columnDef.header}
331
- {/if}
332
- </span>
333
-
334
- <div class="row-controls">
335
- <div class="visibility-wrapper">
336
- <Checkbox
337
- icon={{ name: 'assessment', size: Size.MediumSmall }}
338
- size={Size.FillWidth}
339
- id={`is-visible-${tableContext.tableName}-${columnDef.id}`}
340
- value={tableContext.columnVisibility[columnDef.id] !== false}
341
- onchange={onVisibilityChange}
342
- />
343
- </div>
344
-
345
- {#if tableContext.allowColumnReordering}
346
- <!--
347
- Tri-state pin selector. The three `Ternary` slots map to:
348
- False -> pinned LEFT (pin-left icon, leftmost)
349
- Neutral -> unpinned (circle-cross icon, middle)
350
- True -> pinned RIGHT (pin-right icon, rightmost)
351
- Expand columns can never be pinned and disable the group.
352
- -->
353
- <div class="pin-selector">
354
- <ThreeStateRadio
355
- value={pinSide}
356
- noLabel={i18n['scoria.action.pin_left']()}
357
- neutralLabel={i18n['scoria.label.unpinned']()}
358
- yesLabel={i18n['scoria.action.pin_right']()}
359
- noIcon={{ name: 'pin-left', size: Size.MediumSmall }}
360
- neutralIcon={{ name: 'circle-cross', size: Size.MediumSmall }}
361
- yesIcon={{ name: 'pin-right', size: Size.MediumSmall }}
362
- onchange={(next: Ternary) => {
363
- setPin(next);
364
- }}
365
- />
366
- </div>
367
- {/if}
368
- </div>
369
- </div>
370
-
371
- {#if tableContext.allowColumnReordering}
372
- <!--
373
- Up / down "move" buttons make column reordering
374
- discoverable without relying on the user noticing a
375
- drag-cursor. The whole row remains draggable for power
376
- users. Buttons disable at the list boundaries so a no-op
377
- `moveColumnTo` is never dispatched.
378
- -->
379
- <div class="reorder-buttons">
380
- <Action
381
- icon={{ name: 'chevron-up', size: Size.Medium }}
382
- size={Size.Medium}
383
- paddingSize={Size.Small}
384
- label={i18n['scoria.action.move_column_up']({ name: reorderLabel })}
385
- disabled={isAtTop}
386
- onclick={moveUp}
387
- />
388
- <Action
389
- icon={{ name: 'chevron-down', size: Size.Medium }}
390
- size={Size.Medium}
391
- paddingSize={Size.Small}
392
- label={i18n['scoria.action.move_column_down']({ name: reorderLabel })}
393
- disabled={isAtBottom}
394
- onclick={moveDown}
395
- />
396
- </div>
397
- {/if}
398
- </li>
399
- {:else}
400
- <li
401
- id="{tableContext.tableName}-column-settings-top-anchor"
402
- class="single-column anchor"
403
- class:targeted={isBeingTargeted}
404
- ondragover={(e) => {
405
- e.preventDefault();
406
-
407
- if (tableContext.dragTarget?.id !== undefined) {
408
- isBeingTargeted = true;
409
- }
410
- }}
411
- ondragleave={disableDragVisual}
412
- ondrop={disableDragVisual}
413
- ></li>
414
- {/if}
415
-
257
+ </script>
258
+
259
+ {#if columnDef}
260
+ {@const reorderLabel = typeof columnDef.header === 'string' ? columnDef.header : columnDef.id}
261
+ <!--
262
+ The `<li>` is a structural container for the eye, pin selector,
263
+ label, and reorder buttons - none activated by clicking the `<li>`
264
+ itself. The `onkeydown` here only captures Alt+Arrow / Alt+Home /
265
+ Alt+End bubbling up from whichever inner control has focus to
266
+ drive the reorder shortcut; the `<li>` is not an interactive
267
+ widget. The structure is a free-form list of cards (not a tree
268
+ or listbox), so the right call is to silence the warning rather
269
+ than fake `role="treeitem"` / `role="option"`.
270
+ -->
271
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
272
+ <li
273
+ bind:this={rowEl}
274
+ class="single-column"
275
+ class:targeted={isBeingTargeted}
276
+ class:draggable={tableContext.allowColumnReordering}
277
+ id="{tableContext.tableName}-column-settings-{columnDef.id}"
278
+ draggable={tableContext.allowColumnReordering}
279
+ onkeydown={onRowKeydown}
280
+ {@attach (node: HTMLLIElement) => {
281
+ // Capture-phase `mousedown` and `pointerdown` listeners. Both
282
+ // must fire BEFORE the synthetic click on the visibility /
283
+ // pin checkbox focuses its hidden input, because that focus
284
+ // triggers an auto-scroll to bring the 1x1px clip-pathed
285
+ // input into view. Capture phase runs before target / bubble,
286
+ // so this listener reliably snapshots the user's true
287
+ // pre-click scroll position.
288
+ //
289
+ // Both event types are wired because browsers differ on which
290
+ // fires first; the second is a cheap no-op snapshot.
291
+ const snapshot = (): void => {
292
+ snapshotScrollPosition();
293
+ };
294
+ node.addEventListener('pointerdown', snapshot, { capture: true });
295
+ node.addEventListener('mousedown', snapshot, { capture: true });
296
+ return () => {
297
+ node.removeEventListener('pointerdown', snapshot, { capture: true });
298
+ node.removeEventListener('mousedown', snapshot, { capture: true });
299
+ };
300
+ }}
301
+ ondragstart={() => {
302
+ tableContext.dragTarget = columnDef;
303
+ }}
304
+ ondragend={disableDragVisual}
305
+ ondragover={(e) => {
306
+ e.preventDefault();
307
+ if (tableContext.dragTarget?.id !== columnDef.id) {
308
+ isBeingTargeted = true;
309
+ }
310
+ }}
311
+ ondragleave={disableDragVisual}
312
+ ondrop={disableDragVisual}
313
+ >
314
+ <!--
315
+ `.row-main` stacks the column label on top and the visibility /
316
+ pin controls underneath so the label gets the full card width
317
+ to wrap into. `.reorder-buttons` is a sibling outside
318
+ `.row-main` so the up / down arrows stay vertically centred on
319
+ the right edge of the card.
320
+ -->
321
+ <div class="row-main">
322
+ <span
323
+ class="column-label"
324
+ title={typeof columnDef.header === 'string' ? columnDef.header : columnDef.id}
325
+ >
326
+ {#if typeof columnDef.header === 'function'}
327
+ <!-- FIXME this needs testing -->
328
+ {@render columnDef.header()}
329
+ {:else}
330
+ {columnDef.header}
331
+ {/if}
332
+ </span>
333
+
334
+ <div class="row-controls">
335
+ <div class="visibility-wrapper">
336
+ <Checkbox
337
+ icon={{ name: 'assessment', size: Size.MediumSmall }}
338
+ size={Size.FillWidth}
339
+ id={`is-visible-${tableContext.tableName}-${columnDef.id}`}
340
+ value={tableContext.columnVisibility[columnDef.id] !== false}
341
+ onchange={onVisibilityChange}
342
+ />
343
+ </div>
344
+
345
+ {#if tableContext.allowColumnReordering}
346
+ <!--
347
+ Tri-state pin selector. The three `Ternary` slots map to:
348
+ False -> pinned LEFT (pin-left icon, leftmost)
349
+ Neutral -> unpinned (circle-cross icon, middle)
350
+ True -> pinned RIGHT (pin-right icon, rightmost)
351
+ Expand columns can never be pinned and disable the group.
352
+ -->
353
+ <div class="pin-selector">
354
+ <ThreeStateRadio
355
+ value={pinSide}
356
+ noLabel={i18n['scoria.action.pin_left']()}
357
+ neutralLabel={i18n['scoria.label.unpinned']()}
358
+ yesLabel={i18n['scoria.action.pin_right']()}
359
+ noIcon={{ name: 'pin-left', size: Size.MediumSmall }}
360
+ neutralIcon={{ name: 'circle-cross', size: Size.MediumSmall }}
361
+ yesIcon={{ name: 'pin-right', size: Size.MediumSmall }}
362
+ onchange={(next: Ternary) => {
363
+ setPin(next);
364
+ }}
365
+ />
366
+ </div>
367
+ {/if}
368
+ </div>
369
+ </div>
370
+
371
+ {#if tableContext.allowColumnReordering}
372
+ <!--
373
+ Up / down "move" buttons make column reordering
374
+ discoverable without relying on the user noticing a
375
+ drag-cursor. The whole row remains draggable for power
376
+ users. Buttons disable at the list boundaries so a no-op
377
+ `moveColumnTo` is never dispatched.
378
+ -->
379
+ <div class="reorder-buttons">
380
+ <Action
381
+ icon={{ name: 'chevron-up', size: Size.Medium }}
382
+ size={Size.Medium}
383
+ paddingSize={Size.Small}
384
+ label={i18n['scoria.action.move_column_up']({ name: reorderLabel })}
385
+ disabled={isAtTop}
386
+ onclick={moveUp}
387
+ />
388
+ <Action
389
+ icon={{ name: 'chevron-down', size: Size.Medium }}
390
+ size={Size.Medium}
391
+ paddingSize={Size.Small}
392
+ label={i18n['scoria.action.move_column_down']({ name: reorderLabel })}
393
+ disabled={isAtBottom}
394
+ onclick={moveDown}
395
+ />
396
+ </div>
397
+ {/if}
398
+ </li>
399
+ {:else}
400
+ <li
401
+ id="{tableContext.tableName}-column-settings-top-anchor"
402
+ class="single-column anchor"
403
+ class:targeted={isBeingTargeted}
404
+ ondragover={(e) => {
405
+ e.preventDefault();
406
+
407
+ if (tableContext.dragTarget?.id !== undefined) {
408
+ isBeingTargeted = true;
409
+ }
410
+ }}
411
+ ondragleave={disableDragVisual}
412
+ ondrop={disableDragVisual}
413
+ ></li>
414
+ {/if}
415
+
416
416
  <style>li {
417
417
  box-sizing: border-box;
418
418
  }
@@ -523,4 +523,4 @@ li.single-column:not(.anchor):last-of-type {
523
523
  --colour: #1f81a0;
524
524
  color: #1f81a0;
525
525
  background-color: transparent;
526
- }</style>
526
+ }</style>
@@ -1,8 +1,8 @@
1
- <svelte:options runes />
2
-
3
- <script
4
- lang="ts"
5
- module
1
+ <svelte:options runes />
2
+
3
+ <script
4
+ lang="ts"
5
+ module
6
6
  >import { AccessorDef } from "../../../Types/Columns/Definitions/Accessors/AccessorDef.svelte.js";
7
7
  import FocusableImmutableCell from "./FocusableImmutableCell.svelte";
8
8
  import TableCheckbox from "./TableCheckbox.svelte";
@@ -26,11 +26,11 @@ const cellTypes = Object.freeze({
26
26
  Checkbox: TableCheckbox,
27
27
  Text: TableTextInput
28
28
  });
29
- </script>
30
-
31
- <script
32
- lang="ts"
33
- generics="T extends object"
29
+ </script>
30
+
31
+ <script
32
+ lang="ts"
33
+ generics="T extends object"
34
34
  >/** Single cell to render for the supplied {@link TableCell}. The accessor type discriminator is read off `cell.column.columnDef`. */
35
35
  const { cell } = $props();
36
36
  const CurrentComponent = $derived(getAppropriateAccessorDef(cell.column.columnDef));
@@ -47,6 +47,6 @@ function getAppropriateAccessorDef(columnDef) {
47
47
  }
48
48
  return FocusableImmutableCell;
49
49
  }
50
- </script>
51
-
52
- <CurrentComponent {cell} />
50
+ </script>
51
+
52
+ <CurrentComponent {cell} />