@lavalogic/scoria 0.40.32 → 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 (135) 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/InfoAlert.svelte +32 -32
  38. package/dist/Components/LoadingAnimation.svelte +228 -227
  39. package/dist/Components/LoadingModal.svelte +19 -19
  40. package/dist/Components/LoadingOverlay.svelte +20 -20
  41. package/dist/Components/Modal.svelte +127 -127
  42. package/dist/Components/MultiSelect.svelte +126 -126
  43. package/dist/Components/Nav/Nav.svelte +71 -71
  44. package/dist/Components/Nav/NavServiceMenuList.svelte +37 -37
  45. package/dist/Components/Nav/NavTab.svelte +46 -46
  46. package/dist/Components/Nav/ServiceMenuItem.svelte +62 -62
  47. package/dist/Components/Nav/ServicesNav.svelte +50 -50
  48. package/dist/Components/NumberInput.svelte +98 -98
  49. package/dist/Components/OptionCards.svelte +58 -58
  50. package/dist/Components/PageHeading.svelte +21 -21
  51. package/dist/Components/PasswordInput.svelte +61 -61
  52. package/dist/Components/PopoverButton.svelte +53 -53
  53. package/dist/Components/Portal.svelte +7 -7
  54. package/dist/Components/ProgressBubble.svelte +42 -42
  55. package/dist/Components/QuerySelect.svelte +102 -102
  56. package/dist/Components/ResourceCalendar/ResourceCalendar.svelte +241 -241
  57. package/dist/Components/SidebarPanel.svelte +32 -32
  58. package/dist/Components/SingleSelect.svelte +122 -122
  59. package/dist/Components/StepButton.svelte +48 -48
  60. package/dist/Components/StepForm.svelte +58 -58
  61. package/dist/Components/Switch.svelte +43 -43
  62. package/dist/Components/Table/ARCHITECTURE.md +298 -298
  63. package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +30 -30
  64. package/dist/Components/Table/Body/Rows/ColumnList.svelte +24 -24
  65. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +165 -165
  66. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +13 -13
  67. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +120 -120
  68. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +81 -81
  69. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +92 -92
  70. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +110 -110
  71. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +54 -54
  72. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +35 -35
  73. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +64 -64
  74. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +82 -82
  75. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +88 -88
  76. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +90 -90
  77. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +96 -96
  78. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +71 -71
  79. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +124 -124
  80. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +91 -91
  81. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +88 -88
  82. package/dist/Components/Table/Body/Rows/TableRow.svelte +127 -127
  83. package/dist/Components/Table/Body/TableBody.svelte +92 -92
  84. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +25 -25
  85. package/dist/Components/Table/Headers/SelectAllHeader.svelte +20 -20
  86. package/dist/Components/Table/Headers/TableHead.svelte +175 -175
  87. package/dist/Components/Table/Misc/ColumnPanel.svelte +32 -32
  88. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +29 -29
  89. package/dist/Components/Table/Misc/FilterInput.svelte +326 -326
  90. package/dist/Components/Table/Misc/FilterPanel.svelte +79 -79
  91. package/dist/Components/Table/Misc/FilterPanelModal.svelte +21 -21
  92. package/dist/Components/Table/Misc/ShareViewModal.svelte +118 -118
  93. package/dist/Components/Table/Misc/SidePanel.svelte +24 -24
  94. package/dist/Components/Table/Misc/TableConfigurationModal.svelte +318 -318
  95. package/dist/Components/Table/Misc/TableFooter.svelte +201 -201
  96. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +112 -112
  97. package/dist/Components/Table/Misc/TableSidebar.svelte +116 -116
  98. package/dist/Components/Table/Misc/TableViewDropdown.svelte +25 -25
  99. package/dist/Components/Table/Misc/ToolboxPanel.svelte +60 -60
  100. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +63 -63
  101. package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +101 -101
  102. package/dist/Components/Table/NestedTable.svelte +29 -29
  103. package/dist/Components/Table/Table.svelte +140 -140
  104. package/dist/Components/Test/TestContextConsumer.svelte +8 -8
  105. package/dist/Components/TextArea.svelte +92 -90
  106. package/dist/Components/TextInput.svelte +128 -117
  107. package/dist/Components/ThreeStateRadio.svelte +101 -101
  108. package/dist/Components/Touch/BoolCard.svelte +27 -27
  109. package/dist/Components/Touch/DateModal.svelte +98 -98
  110. package/dist/Components/Touch/EditCard.svelte +44 -44
  111. package/dist/Components/Touch/InfoCard.svelte +25 -25
  112. package/dist/Components/Touch/InfoTextCard.svelte +22 -22
  113. package/dist/Components/Touch/ModalExplanation.svelte +13 -13
  114. package/dist/Components/Touch/NumberKeyboard.svelte +81 -81
  115. package/dist/Components/Touch/NumberModal.svelte +49 -49
  116. package/dist/Components/Touch/PlusMinusCard.svelte +40 -40
  117. package/dist/Components/Touch/SelectModal.svelte +86 -86
  118. package/dist/Components/Touch/SummaryCard.svelte +74 -74
  119. package/dist/Components/Touch/TextAreaModal.svelte +53 -53
  120. package/dist/Components/Touch/TextModal.svelte +56 -56
  121. package/dist/Components/Touch/TouchCard.svelte +28 -28
  122. package/dist/Components/Touch/TouchModal.svelte +141 -141
  123. package/dist/Components/Touch/UtilityButton.svelte +63 -63
  124. package/dist/Components/VerticalTabGroup.svelte +38 -38
  125. package/dist/Components/VerticalTabGroupButton.svelte +46 -46
  126. package/dist/Helpers/Datamatrix.d.ts +19 -19
  127. package/dist/Helpers/Datamatrix.js +291 -291
  128. package/dist/Types/Examples/ExampleModal.svelte +27 -27
  129. package/dist/paraglide/README.md +1 -1
  130. package/dist/scss/_basics.scss +12 -12
  131. package/dist/scss/_colours.scss +140 -140
  132. package/dist/scss/_motion.scss +57 -57
  133. package/dist/scss/_sizing.scss +85 -85
  134. package/dist/scss/_transitions.scss +8 -8
  135. 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} />