@lavalogic/scoria 0.40.27 → 0.40.29

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 (128) hide show
  1. package/dist/Components/AccordionGroup.svelte +1 -1
  2. package/dist/Components/AlertModal.svelte +3 -2
  3. package/dist/Components/Base/BaseModal.svelte +55 -41
  4. package/dist/Components/Base/Pagination.svelte +20 -12
  5. package/dist/Components/Base/PaginationProps.d.ts +5 -0
  6. package/dist/Components/Base/Snippets.svelte +4 -3
  7. package/dist/Components/Button.svelte +9 -8
  8. package/dist/Components/Checkbox.svelte +2 -2
  9. package/dist/Components/ChipsInput.svelte +6 -6
  10. package/dist/Components/CollapsibleCard.svelte +3 -3
  11. package/dist/Components/ConditionBuilder/ConditionBuilder.svelte +7 -6
  12. package/dist/Components/Contexts/ContextMenu.svelte +3 -2
  13. package/dist/Components/Contexts/Toast.svelte +4 -3
  14. package/dist/Components/Contexts/ToastContainer.svelte +6 -5
  15. package/dist/Components/Contexts/Tooltip.svelte +2 -2
  16. package/dist/Components/DataMatrixIcon.svelte +4 -3
  17. package/dist/Components/DateInput.svelte +25 -26
  18. package/dist/Components/DesktopModal.svelte +1 -1
  19. package/dist/Components/DimensionInput.svelte +30 -31
  20. package/dist/Components/DragMenu/DragMenuHolder.svelte +6 -6
  21. package/dist/Components/DragMenu/DraggableCard.svelte +3 -3
  22. package/dist/Components/FileCard.svelte +3 -2
  23. package/dist/Components/FileUpload.svelte +24 -25
  24. package/dist/Components/GridInput.svelte +2 -2
  25. package/dist/Components/HorizontalTabGroup.svelte +1 -1
  26. package/dist/Components/Icon.svelte +8 -2
  27. package/dist/Components/IconProps.d.ts +7 -0
  28. package/dist/Components/Icons.js +365 -365
  29. package/dist/Components/LoadingAnimation.svelte +50 -30
  30. package/dist/Components/LoadingAnimation.svelte.d.ts +1 -1
  31. package/dist/Components/LoadingModal.svelte +3 -2
  32. package/dist/Components/Modal.svelte +9 -9
  33. package/dist/Components/MultiSelect.svelte +37 -18
  34. package/dist/Components/MultiSelectCommonProps.d.ts +15 -1
  35. package/dist/Components/Nav/Nav.svelte +13 -13
  36. package/dist/Components/Nav/ServiceMenuItem.svelte +2 -0
  37. package/dist/Components/Nav/ServicesNav.svelte +6 -6
  38. package/dist/Components/NumberInput.svelte +25 -26
  39. package/dist/Components/PasswordInput.svelte +25 -24
  40. package/dist/Components/PopoverButton.svelte +8 -8
  41. package/dist/Components/QuerySelect.svelte +33 -16
  42. package/dist/Components/QuerySelectProps.d.ts +10 -1
  43. package/dist/Components/ResourceCalendar/ResourceCalendar.svelte +23 -22
  44. package/dist/Components/SidebarPanel.svelte +1 -1
  45. package/dist/Components/SingleSelect.svelte +30 -15
  46. package/dist/Components/SingleSelectCommonProps.d.ts +10 -1
  47. package/dist/Components/StepForm.svelte +6 -5
  48. package/dist/Components/Switch.svelte +5 -5
  49. package/dist/Components/Table/Body/QuickSearchCell.svelte +363 -351
  50. package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +5 -6
  51. package/dist/Components/Table/Body/Rows/ColumnList.svelte +3 -2
  52. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +7 -6
  53. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +6 -7
  54. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +8 -7
  55. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +11 -9
  56. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +7 -8
  57. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +5 -5
  58. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +3 -2
  59. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +3 -3
  60. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +5 -4
  61. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +9 -6
  62. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +4 -4
  63. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +4 -4
  64. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +3 -3
  65. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +9 -7
  66. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +7 -6
  67. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +6 -7
  68. package/dist/Components/Table/Body/Rows/TableRow.svelte +6 -5
  69. package/dist/Components/Table/Body/TableBody.svelte +2 -2
  70. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +3 -2
  71. package/dist/Components/Table/Headers/SelectAllHeader.svelte +4 -3
  72. package/dist/Components/Table/Headers/TableHead.svelte +6 -5
  73. package/dist/Components/Table/Misc/ColumnPanel.svelte +5 -4
  74. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +5 -4
  75. package/dist/Components/Table/Misc/FilterInput.svelte +23 -14
  76. package/dist/Components/Table/Misc/FilterPanel.svelte +12 -11
  77. package/dist/Components/Table/Misc/FilterPanelModal.svelte +3 -2
  78. package/dist/Components/Table/Misc/ShareViewModal.svelte +25 -15
  79. package/dist/Components/Table/Misc/SidePanel.svelte +2 -2
  80. package/dist/Components/Table/Misc/TableConfigurationModal.svelte +50 -40
  81. package/dist/Components/Table/Misc/TableFooter.svelte +18 -12
  82. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +8 -7
  83. package/dist/Components/Table/Misc/TableSidebar.svelte +8 -7
  84. package/dist/Components/Table/Misc/TableViewDropdown.svelte +6 -2
  85. package/dist/Components/Table/Misc/ToolboxPanel.svelte +8 -7
  86. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +9 -8
  87. package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +23 -14
  88. package/dist/Components/Table/Misc/numberDateFilterTypes.d.ts +7 -4
  89. package/dist/Components/Table/Misc/numberDateFilterTypes.js +27 -15
  90. package/dist/Components/Table/Misc/stringFilterTypes.d.ts +7 -3
  91. package/dist/Components/Table/Misc/stringFilterTypes.js +26 -16
  92. package/dist/Components/Table/NestedTable.svelte +4 -0
  93. package/dist/Components/Table/Table.svelte +19 -18
  94. package/dist/Components/Table/Types/Columns/Definitions/Actions/ActionsDef.svelte.js +2 -1
  95. package/dist/Components/Table/Types/Columns/Definitions/RowSelection/RowSelectionDef.svelte.js +2 -1
  96. package/dist/Components/Table/Types/Context/ClipboardState.svelte.js +3 -2
  97. package/dist/Components/Table/Types/Context/ViewState.svelte.js +5 -2
  98. package/dist/Components/Table/Types/DataRepository/IDataRepository.d.ts +6 -0
  99. package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.d.ts +8 -0
  100. package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.js +14 -0
  101. package/dist/Components/Table/Types/Public/CreateTableOptions.d.ts +3 -0
  102. package/dist/Components/Table/createTable.svelte.js +3 -0
  103. package/dist/Components/TextArea.svelte +24 -23
  104. package/dist/Components/TextInput.svelte +25 -26
  105. package/dist/Components/ThreeStateRadio.svelte +21 -16
  106. package/dist/Components/Touch/BoolCard.svelte +2 -2
  107. package/dist/Components/Touch/DateModal.svelte +5 -4
  108. package/dist/Components/Touch/EditCard.svelte +7 -7
  109. package/dist/Components/Touch/NumberKeyboard.svelte +3 -2
  110. package/dist/Components/Touch/NumberModal.svelte +4 -3
  111. package/dist/Components/Touch/PlusMinusCard.svelte +6 -5
  112. package/dist/Components/Touch/SelectModal.svelte +5 -4
  113. package/dist/Components/Touch/SummaryCard.svelte +9 -9
  114. package/dist/Components/Touch/TextAreaModal.svelte +4 -3
  115. package/dist/Components/Touch/TextModal.svelte +4 -3
  116. package/dist/Components/Touch/TouchCard.svelte +4 -3
  117. package/dist/Components/Touch/TouchModal.svelte +9 -8
  118. package/dist/Components/VerticalTabGroup.svelte +5 -4
  119. package/dist/Contexts/AlertContext.svelte.d.ts +8 -5
  120. package/dist/Contexts/AlertContext.svelte.js +10 -9
  121. package/dist/Helpers/Helpers.svelte.d.ts +23 -2
  122. package/dist/Helpers/Helpers.svelte.js +37 -9
  123. package/dist/Strings/locale.d.ts +19 -0
  124. package/dist/Strings/locale.js +27 -0
  125. package/dist/index.d.ts +1 -0
  126. package/dist/index.js +1 -0
  127. package/dist/scss/_mixins.scss +3406 -3392
  128. package/package.json +14 -7
@@ -67,7 +67,7 @@ const slideDuration = $derived(reducedMotion.matches ? 0 : 200);
67
67
  gap: 1px;
68
68
  background-color: #cbd4da;
69
69
  min-width: 10rem;
70
- border-right: solid 1px #cbd4da;
70
+ border-inline-end: solid 1px #cbd4da;
71
71
  overflow: auto;
72
72
  flex-shrink: 0;
73
73
  }
@@ -3,7 +3,8 @@
3
3
  <script
4
4
  lang="ts"
5
5
  module
6
- >import { browser } from "$app/environment";
6
+ >import { m as i18n } from "../paraglide/messages.js";
7
+ import { browser } from "$app/environment";
7
8
  import { DATAMatrix } from "../Helpers/Datamatrix.js";
8
9
  // Frozen const map of scanner shortcut codes recognised by AlertModal.
9
10
  // Using `Object.values` to drive comparisons keeps the strings off the
@@ -73,7 +74,7 @@ onMount(() => {
73
74
  if (dev) {
74
75
  console.warn(`Uncaught command \`${value}\``);
75
76
  }
76
- toastContext.toast(`Unrecognised input: ${value}`);
77
+ toastContext.toast(i18n["scoria.text.unrecognised_input"]({ value }));
77
78
  return false;
78
79
  }
79
80
  }
@@ -1,29 +1,40 @@
1
- <svelte:options runes />
2
-
3
- <!--
4
- BaseModal.svelte - internal primitive that owns the `<dialog>`
5
- open/close + Escape/backdrop dismissal + autofocus plumbing
6
- shared between `Modal`, `DesktopModal`, and `TouchModal`. See
7
- `BaseModalProps.ts` for the contract.
8
-
9
- Cosmetic-free for inner content by design: each consumer renders
10
- its own header / main / footer / button-row markup as
11
- `{@render children()}`. The consumer also keeps its own
12
- footer-text rules, scanner shortcut wiring, colourSet button
13
- styling, etc. - those concerns intentionally do not live in
14
- BaseModal.
15
-
16
- The shared dialog SHELL styling (border, backdrop, zoom-in
17
- animation, the `--dialog-*` size variables and the static-height
18
- / static-width / noscroll modifier classes) is included here via
19
- the `@mixin dialog` SCSS so it is shared across all three
20
- consumer modals.
21
- -->
22
-
23
- <script lang="ts">import { devCatch } from "../../Helpers/Helpers.svelte.js";
24
- import { onMount, tick } from "svelte";
1
+ <svelte:options runes />
2
+
3
+ <!--
4
+ BaseModal.svelte - internal primitive that owns the `<dialog>`
5
+ open/close + Escape/backdrop dismissal + autofocus plumbing
6
+ shared between `Modal`, `DesktopModal`, and `TouchModal`. See
7
+ `BaseModalProps.ts` for the contract.
8
+
9
+ Cosmetic-free for inner content by design: each consumer renders
10
+ its own header / main / footer / button-row markup as
11
+ `{@render children()}`. The consumer also keeps its own
12
+ footer-text rules, scanner shortcut wiring, colourSet button
13
+ styling, etc. - those concerns intentionally do not live in
14
+ BaseModal.
15
+
16
+ The shared dialog SHELL styling (border, backdrop, zoom-in
17
+ animation, the `--dialog-*` size variables and the static-height
18
+ / static-width / noscroll modifier classes) is included here via
19
+ the `@mixin dialog` SCSS so it is shared across all three
20
+ consumer modals.
21
+ -->
22
+
23
+ <script lang="ts">import { TooltipContext } from "../../Contexts/TooltipContext.svelte.js";
24
+ import { devCatch } from "../../Helpers/Helpers.svelte.js";
25
+ import { getContext, onMount, tick } from "svelte";
26
+ import Tooltip from "../Contexts/Tooltip.svelte";
25
27
  let { value = $bindable(true), children, onclose, mandatory = false, autofocusSelector, ariaLabelledby, ariaDescribedby, closeOnEscape = true, closeOnBackdropClick = true, dialogClass, dialogStyle } = $props();
26
28
  let dialog = $state();
29
+ // A dialog opened with showModal() paints in the browser top layer,
30
+ // above every z-index on the page, including the app-root Tooltip host
31
+ // mounted by ContextWrapper. Hovering a Button / Action inside a modal
32
+ // therefore shows its tooltip BEHIND the modal. Rendering a second
33
+ // Tooltip host inside the dialog puts one in the top layer too; both
34
+ // hosts read the same app-level context, so whichever is visible paints
35
+ // the active tooltip. Skipped when no context is mounted (tests,
36
+ // context-free harnesses).
37
+ const tooltipContext = getContext(TooltipContext.identifier);
27
38
  function tryFocusSelector() {
28
39
  if (dialog && autofocusSelector != null && autofocusSelector.length > 0) {
29
40
  const target = dialog.querySelector(autofocusSelector);
@@ -80,22 +91,25 @@ function handleBackdropClick(e) {
80
91
  }
81
92
  }
82
93
  }
83
- </script>
84
-
85
- <dialog
86
- bind:this={dialog}
87
- class={dialogClass}
88
- style={dialogStyle}
89
- aria-modal="true"
90
- aria-labelledby={ariaLabelledby}
91
- aria-describedby={ariaDescribedby}
92
- onclose={handleNativeClose}
93
- onkeydown={handleKeydown}
94
- onclick={handleBackdropClick}
95
- >
96
- {@render children()}
97
- </dialog>
98
-
94
+ </script>
95
+
96
+ <dialog
97
+ bind:this={dialog}
98
+ class={dialogClass}
99
+ style={dialogStyle}
100
+ aria-modal="true"
101
+ aria-labelledby={ariaLabelledby}
102
+ aria-describedby={ariaDescribedby}
103
+ onclose={handleNativeClose}
104
+ onkeydown={handleKeydown}
105
+ onclick={handleBackdropClick}
106
+ >
107
+ {@render children()}
108
+ {#if tooltipContext}
109
+ <Tooltip />
110
+ {/if}
111
+ </dialog>
112
+
99
113
  <style>dialog {
100
114
  overflow: clip;
101
115
  background-color: #e9ecf1;
@@ -149,4 +163,4 @@ dialog .modal-main.noscroll {
149
163
  }
150
164
  dialog .footer {
151
165
  flex-shrink: 0;
152
- }</style>
166
+ }</style>
@@ -22,7 +22,8 @@ preserves button identity across page changes.
22
22
  <script
23
23
  lang="ts"
24
24
  generics="T extends object"
25
- >import { autoPluralise, generateWeakId } from "../../Helpers/Helpers.svelte.js";
25
+ >import { m as i18n } from "../../paraglide/messages.js";
26
+ import { autoPluralise, generateWeakId } from "../../Helpers/Helpers.svelte.js";
26
27
  import { Colour } from "../../scss/colours.js";
27
28
  import { Side } from "../../Types/Internal/Side.js";
28
29
  import { Size } from "../../Types/Internal/Size.js";
@@ -30,7 +31,7 @@ import { Variant } from "../../Types/Internal/Variant.js";
30
31
  import Button from "../Button.svelte";
31
32
  import Icon from "../Icon.svelte";
32
33
  import NumberInput from "../NumberInput.svelte";
33
- const { items, key, pageSize = 20, snippet, itemName = "Item", border = false, padding = "1.5rem", gap = "1.5rem", height } = $props();
34
+ const { items, key, pageSize = 20, snippet, itemName = "Item", countLabel, border = false, padding = "1.5rem", gap = "1.5rem", height } = $props();
34
35
  const _uuid = generateWeakId();
35
36
  let pageIndex = $state(0);
36
37
  const pageValue = $derived(pageIndex + 1);
@@ -83,11 +84,18 @@ const pageButtons = $derived(getPageWindow(pageIndex, lastPage, 5));
83
84
  {/each}
84
85
  <div class="spread_row bottom_row">
85
86
  <div class="block">
86
- <span>{items.length} {autoPluralise(itemName, items.length)}</span>
87
+ <span
88
+ >{countLabel
89
+ ? countLabel(items.length)
90
+ : i18n['scoria.text.item_count']({
91
+ count: items.length,
92
+ noun: autoPluralise(itemName, items.length),
93
+ })}</span
94
+ >
87
95
  </div>
88
96
 
89
97
  <div class="block records-per-page">
90
- <span>Records per Page: {pageSize}</span>
98
+ <span>{i18n['scoria.label.records_per_page']()} {pageSize}</span>
91
99
  </div>
92
100
 
93
101
  <div class="spacer"></div>
@@ -95,14 +103,14 @@ const pageButtons = $derived(getPageWindow(pageIndex, lastPage, 5));
95
103
  <div
96
104
  class="scrollable"
97
105
  role="navigation"
98
- aria-label="Pagination"
106
+ aria-label={i18n['scoria.label.pagination']()}
99
107
  >
100
108
  <div class="block">
101
109
  <Icon
102
110
  name="paper"
103
111
  colour={Colour['$ui-blue-6']}
104
112
  />
105
- <span>{lastPage} {autoPluralise('Page', lastPage)}</span>
113
+ <span>{i18n['scoria.text.page_count']({ count: lastPage })}</span>
106
114
  </div>
107
115
 
108
116
  <div class="block">
@@ -113,7 +121,7 @@ const pageButtons = $derived(getPageWindow(pageIndex, lastPage, 5));
113
121
  /></label
114
122
  >
115
123
 
116
- <label for="{_uuid}-jump-to-page">Jump to page:</label>
124
+ <label for="{_uuid}-jump-to-page">{i18n['scoria.label.jump_to_page']()}</label>
117
125
 
118
126
  <NumberInput
119
127
  id="{_uuid}-jump-to-page"
@@ -134,7 +142,7 @@ const pageButtons = $derived(getPageWindow(pageIndex, lastPage, 5));
134
142
  iconLeft={{
135
143
  name: 'left-close',
136
144
  size: Size.FillHeight,
137
- }}>Previous Page</Button
145
+ }}>{i18n['scoria.action.previous_page']()}</Button
138
146
  >
139
147
  </div>
140
148
 
@@ -145,7 +153,7 @@ const pageButtons = $derived(getPageWindow(pageIndex, lastPage, 5));
145
153
  side={Side.Bottom}
146
154
  size={Size.FillHeight}
147
155
  toggled={pageIndex + 1 === pageNumber}
148
- label={`Go to page ${pageNumber.toString()}`}
156
+ label={i18n['scoria.action.go_to_page']({ number: pageNumber })}
149
157
  onclick={() => {
150
158
  pageIndex = pageNumber - 1;
151
159
  }}>{pageNumber}</Button
@@ -165,7 +173,7 @@ const pageButtons = $derived(getPageWindow(pageIndex, lastPage, 5));
165
173
  iconRight={{
166
174
  name: 'right-close',
167
175
  size: Size.FillHeight,
168
- }}>Next Page</Button
176
+ }}>{i18n['scoria.action.next_page']()}</Button
169
177
  >
170
178
  </div>
171
179
  </div>
@@ -239,10 +247,10 @@ const pageButtons = $derived(getPageWindow(pageIndex, lastPage, 5));
239
247
  background-color: #ffffff;
240
248
  }
241
249
  .spread_row > *:first-child {
242
- border-bottom-left-radius: 4px;
250
+ border-end-start-radius: 4px;
243
251
  }
244
252
  .spread_row > *:last-child {
245
- border-bottom-right-radius: 4px;
253
+ border-end-end-radius: 4px;
246
254
  }
247
255
  .spread_row .spacer {
248
256
  flex-grow: 2;
@@ -41,6 +41,11 @@ export interface PaginationProps<T extends object> {
41
41
  * @default 'Item'
42
42
  */
43
43
  itemName?: string;
44
+ /**
45
+ * Complete item-count sentence, e.g. `(n) => `${n} orders``. When omitted the
46
+ * count is rendered from the catalogue with an English-only noun form.
47
+ */
48
+ countLabel?: (count: number) => string;
44
49
  /**
45
50
  * When `true` the wrapper draws a rounded thick border around
46
51
  * the rendered items.
@@ -10,6 +10,7 @@ async-status surfaces. The component itself renders nothing.
10
10
  module
11
11
  >import { getErrorMessage, loadingText } from "../../Helpers/Helpers.svelte.js";
12
12
  import Button from "../Button.svelte";
13
+ import { m as i18n } from "../../paraglide/messages.js";
13
14
  // The local `{#snippet _pending}` / `{#snippet _failed}` declarations
14
15
  // must be hoistable references for `export const` to bind to them.
15
16
  // Svelte 5 currently requires the snippet name to differ from the
@@ -20,15 +21,15 @@ export const failed = _failed;
20
21
  </script>
21
22
 
22
23
  {#snippet _pending()}
23
- {loadingText}
24
+ {loadingText()}
24
25
  {/snippet}
25
26
  {#snippet _failed(e: unknown, retry?: () => void)}
26
- Error: {getErrorMessage(e)}
27
+ {i18n['scoria.text.error_prefix']({ message: getErrorMessage(e) })}
27
28
  {#if retry}
28
29
  <Button
29
30
  onclick={() => {
30
31
  retry();
31
- }}>Retry</Button
32
+ }}>{i18n['scoria.action.retry_load']()}</Button
32
33
  >
33
34
  {/if}
34
35
  {/snippet}
@@ -14,6 +14,7 @@ const paddingSizesVertical = {
14
14
  [Size.Tiny]: "0.25rem",
15
15
  [Size.Small]: "0.375rem",
16
16
  [Size.MediumSmall]: "0.5rem",
17
+ // [Size.Medium]: '0.625rem',
17
18
  [Size.Medium]: "0.90625rem",
18
19
  [Size.MediumLarge]: "0.90625rem",
19
20
  [Size.Large]: "0.925rem",
@@ -230,8 +231,8 @@ $effect(() => {
230
231
  button {
231
232
  transition: border-color ease-out 0.15s 0s, background-color ease-out 0.15s 0s, color ease-out 0.15s 0s, fill ease-out 0.15s 0s;
232
233
  color: #3a4952;
233
- padding-left: var(--button-padding-left, var(--button-padding-horizontal, var(--button-padding, var(--fallback-padding-horizontal, 0))));
234
- padding-right: var(--button-padding-right, var(--button-padding-horizontal, var(--button-padding, var(--fallback-padding-horizontal, 0))));
234
+ padding-inline-start: var(--button-padding-inline-start, var(--button-padding-horizontal, var(--button-padding, var(--fallback-padding-horizontal, 0))));
235
+ padding-inline-end: var(--button-padding-inline-end, var(--button-padding-horizontal, var(--button-padding, var(--fallback-padding-horizontal, 0))));
235
236
  padding-top: var(--button-padding-top, var(--button-padding-vertical, var(--button-padding, var(--fallback-padding-vertical, 0))));
236
237
  padding-bottom: var(--button-padding-bottom, var(--button-padding-vertical, var(--button-padding, var(--fallback-padding-vertical, 0))));
237
238
  font-size: var(--font-size, 0.875rem);
@@ -443,12 +444,12 @@ button.toolbar.right, button.toolbar.left {
443
444
  padding-bottom: 1rem;
444
445
  }
445
446
  button.toolbar.right {
446
- border-left: solid 3px #ffffff;
447
- border-right: solid 3px #ffffff;
447
+ border-inline-start: solid 3px #ffffff;
448
+ border-inline-end: solid 3px #ffffff;
448
449
  }
449
450
  button.toolbar.left {
450
- border-right: solid 3px #ffffff;
451
- border-left: solid 3px #ffffff;
451
+ border-inline-end: solid 3px #ffffff;
452
+ border-inline-start: solid 3px #ffffff;
452
453
  }
453
454
  button.toolbar.top {
454
455
  border-top: solid 3px #ffffff;
@@ -473,10 +474,10 @@ button.toolbar:not([disabled]):focus, button.toolbar:not([disabled]):focus-visib
473
474
  outline-color: #1f81a0;
474
475
  }
475
476
  button.toolbar:not([disabled]).toggled.right {
476
- border-left-color: #259fc7;
477
+ border-inline-start-color: #259fc7;
477
478
  }
478
479
  button.toolbar:not([disabled]).toggled.left {
479
- border-right-color: #259fc7;
480
+ border-inline-end-color: #259fc7;
480
481
  }
481
482
  button.toolbar:not([disabled]).toggled.top {
482
483
  border-top-color: #259fc7;
@@ -113,11 +113,11 @@ import Icon from "./Icon.svelte";
113
113
  }
114
114
 
115
115
  label.text-label {
116
- padding-left: 1rem;
116
+ padding-inline-start: 1rem;
117
117
  }
118
118
 
119
119
  .checkbox-container.compact label.text-label {
120
- padding-left: 0.5rem;
120
+ padding-inline-start: 0.5rem;
121
121
  }
122
122
 
123
123
  input {
@@ -90,11 +90,11 @@ function onkeydown(e) {
90
90
 
91
91
  span.top-label {
92
92
  position: absolute;
93
- left: 0.5rem;
93
+ inset-inline-start: 0.5rem;
94
94
  font-size: 0.875rem;
95
95
  user-select: none;
96
- padding-left: 0.5rem;
97
- padding-right: 0.5rem;
96
+ padding-inline-start: 0.5rem;
97
+ padding-inline-end: 0.5rem;
98
98
  line-height: 1rem;
99
99
  padding: 0rem 0.5rem;
100
100
  top: calc(-0.875rem / 2 - 2px);
@@ -108,11 +108,11 @@ span.top-label.invalid {
108
108
 
109
109
  span.border {
110
110
  position: absolute;
111
- left: 0.5rem;
111
+ inset-inline-start: 0.5rem;
112
112
  font-size: 0.875rem;
113
113
  user-select: none;
114
- padding-left: 0.5rem;
115
- padding-right: 0.5rem;
114
+ padding-inline-start: 0.5rem;
115
+ padding-inline-end: 0.5rem;
116
116
  line-height: 1rem;
117
117
  z-index: 1;
118
118
  white-space: nowrap;
@@ -40,7 +40,7 @@ const slideDuration = $derived(reducedMotion.matches ? 0 : 200);
40
40
  <h3>{title}</h3>
41
41
  {#if subtitle}
42
42
  {#await subtitle}
43
- <span>{loadingText}</span>
43
+ <span>{loadingText()}</span>
44
44
  {:then resolvedSubtitle}
45
45
  <span>{resolvedSubtitle}</span>
46
46
  {/await}
@@ -94,7 +94,7 @@ const slideDuration = $derived(reducedMotion.matches ? 0 : 200);
94
94
  background: transparent;
95
95
  border: none;
96
96
  box-sizing: border-box;
97
- padding: 0 0.5rem 0.5rem 0.5rem;
97
+ padding: 0 0 0.5rem 0;
98
98
  }
99
99
  .heading .left {
100
100
  display: flex;
@@ -114,7 +114,7 @@ const slideDuration = $derived(reducedMotion.matches ? 0 : 200);
114
114
  font-size: 0.875rem;
115
115
  }
116
116
  .heading .indicator {
117
- margin-left: auto;
117
+ margin-inline-start: auto;
118
118
  display: inline-flex;
119
119
  align-items: center;
120
120
  }
@@ -3,11 +3,12 @@
3
3
  <script
4
4
  lang="ts"
5
5
  generics="F extends string | number, O extends string | number, V"
6
- >import SingleSelect from "../SingleSelect.svelte";
6
+ >import { m as i18n } from "../../paraglide/messages.js";
7
+ import SingleSelect from "../SingleSelect.svelte";
7
8
  import Button from "../Button.svelte";
8
9
  import { makeGroup, makeLeaf } from "./ConditionTree.js";
9
10
  import Self from "./ConditionBuilder.svelte";
10
- const { root, onChange, fields, operatorsFor, valueEditor, defaultValueFor, allowGroups = true, maxDepth = 5, addConditionLabel = "Add Condition", addGroupLabel = "Add Group", andLabel = "AND", orLabel = "OR", depth = 0 } = $props();
11
+ const { root, onChange, fields, operatorsFor, valueEditor, defaultValueFor, allowGroups = true, maxDepth = 5, addConditionLabel = i18n["scoria.action.add_condition"](), addGroupLabel = i18n["scoria.action.add_group"](), andLabel = i18n["scoria.label.combinator_and"](), orLabel = i18n["scoria.label.combinator_or"](), depth = 0 } = $props();
11
12
  function seedValue(field, operator) {
12
13
  return defaultValueFor ? defaultValueFor(field, operator) : null;
13
14
  }
@@ -66,7 +67,7 @@ function setValue(leaf, value) {
66
67
  {#if child.kind === 'leaf'}
67
68
  <div class="leaf">
68
69
  <SingleSelect
69
- label="Field"
70
+ label={i18n['scoria.label.field']()}
70
71
  options={[...fields]}
71
72
  labelProp="label"
72
73
  valueProp="value"
@@ -76,7 +77,7 @@ function setValue(leaf, value) {
76
77
  onchange={(value) => setField(child, value)}
77
78
  />
78
79
  <SingleSelect
79
- label="Operator"
80
+ label={i18n['scoria.label.operator']()}
80
81
  options={[...operatorsFor(child.field)]}
81
82
  labelProp="label"
82
83
  valueProp="value"
@@ -89,7 +90,7 @@ function setValue(leaf, value) {
89
90
  {@render valueEditor(child, (value) => setValue(child, value))}
90
91
  </div>
91
92
  <Button
92
- label="Remove condition"
93
+ label={i18n['scoria.action.remove_condition']()}
93
94
  iconLeft={{ name: 'circle-cross' }}
94
95
  onclick={() => removeChild(child)}
95
96
  />
@@ -112,7 +113,7 @@ function setValue(leaf, value) {
112
113
  depth={depth + 1}
113
114
  />
114
115
  <Button
115
- label="Remove group"
116
+ label={i18n['scoria.action.remove_group']()}
116
117
  iconLeft={{ name: 'circle-cross' }}
117
118
  onclick={() => removeChild(child)}
118
119
  />
@@ -27,7 +27,8 @@ not render `ContextMenu` directly. Open a menu through the context:
27
27
  `Escape` closes the menu and returns focus to the previously focused
28
28
  element; `ArrowUp` / `ArrowDown` cycle focus through the items.
29
29
  -->
30
- <script lang="ts">import { ContextMenuContext } from "../../Contexts/ContextMenuContext.svelte.js";
30
+ <script lang="ts">import { m as i18n } from "../../paraglide/messages.js";
31
+ import { ContextMenuContext } from "../../Contexts/ContextMenuContext.svelte.js";
31
32
  import { devCatch } from "../../Helpers/Helpers.svelte.js";
32
33
  import { getContext, tick, untrack } from "svelte";
33
34
  import { fade } from "svelte/transition";
@@ -110,7 +111,7 @@ function focusPrev() {
110
111
  bind:this={menuEl}
111
112
  style="top: {_y}px; left: {_x}px;"
112
113
  role="menu"
113
- aria-label="Context menu"
114
+ aria-label={i18n['scoria.label.context_menu']()}
114
115
  tabindex="-1"
115
116
  onkeydown={(e) => {
116
117
  if (e.key === 'Escape') {
@@ -21,7 +21,8 @@ the duration collapses to zero. The copy action is only shown when
21
21
  <script
22
22
  lang="ts"
23
23
  module
24
- >import { ColourSet } from "../../scss/colours.js";
24
+ >import { m as i18n } from "../../paraglide/messages.js";
25
+ import { ColourSet } from "../../scss/colours.js";
25
26
  import { Size } from "../../Types/Internal/Size.js";
26
27
  import { Validity } from "../../Types/Internal/Validity.js";
27
28
  import { slide } from "svelte/transition";
@@ -50,7 +51,7 @@ const slideDuration = $derived(reducedMotion.matches ? 0 : 500);
50
51
  <Action
51
52
  onclick={copy}
52
53
  icon={{ name: 'copy' }}
53
- label="Copy to clipboard"
54
+ label={i18n['scoria.action.copy_to_clipboard']()}
54
55
  size={Size.MediumLarge}
55
56
  colourSet={ColourSet.Auxiliary}
56
57
  />
@@ -67,7 +68,7 @@ const slideDuration = $derived(reducedMotion.matches ? 0 : 500);
67
68
  <Action
68
69
  size={Size.MediumLarge}
69
70
  icon={{ name: 'cross' }}
70
- label="Dismiss"
71
+ label={i18n['scoria.action.dismiss']()}
71
72
  onclick={() => {
72
73
  toast.close?.();
73
74
  }}
@@ -15,7 +15,8 @@ a single rolling region without interrupting the user; individual
15
15
  Mounted once at the app root by `ContextWrapper`; consumers should
16
16
  not render this directly.
17
17
  -->
18
- <script lang="ts">import { ToastContext } from "../../Contexts/ToastContext.svelte.js";
18
+ <script lang="ts">import { m as i18n } from "../../paraglide/messages.js";
19
+ import { ToastContext } from "../../Contexts/ToastContext.svelte.js";
19
20
  import { devCatch } from "../../Helpers/Helpers.svelte.js";
20
21
  import { Validity } from "../../Types/Internal/Validity.js";
21
22
  import { getContext } from "svelte";
@@ -30,7 +31,7 @@ function copyDataToClipboard(text) {
30
31
  if (!navigator.clipboard) {
31
32
  toastContext.toast({
32
33
  result: Validity.Invalid,
33
- message: "Cannot Copy in an Insecure Connection",
34
+ message: i18n["scoria.message.cannot_copy_insecure"](),
34
35
  copyable: false
35
36
  });
36
37
  return;
@@ -38,7 +39,7 @@ function copyDataToClipboard(text) {
38
39
  navigator.clipboard.writeText(text).catch(devCatch);
39
40
  toastContext.toast({
40
41
  result: Validity.Info,
41
- message: "Message copied to clipboard",
42
+ message: i18n["scoria.message.copied_to_clipboard"](),
42
43
  copyable: false
43
44
  });
44
45
  }
@@ -46,7 +47,7 @@ function copyDataToClipboard(text) {
46
47
 
47
48
  <section
48
49
  aria-live="polite"
49
- aria-label="Notifications"
50
+ aria-label={i18n['scoria.label.notifications']()}
50
51
  >
51
52
  {#each toastContext.toasts as toast (toast.id)}
52
53
  <Toast
@@ -62,7 +63,7 @@ function copyDataToClipboard(text) {
62
63
  user-select: none;
63
64
  gap: 0.5rem;
64
65
  bottom: var(--toast-bottom, 8rem);
65
- right: var(--toast-right, 2rem);
66
+ inset-inline-end: var(--toast-inline-end, 2rem);
66
67
  display: flex;
67
68
  position: fixed;
68
69
  flex-flow: column-reverse nowrap;
@@ -63,7 +63,7 @@ const tooltipContext = getContext(TooltipContext.identifier);
63
63
  z-index: -1;
64
64
  top: 0;
65
65
  border-radius: 4px;
66
- left: 50%;
66
+ inset-inline-start: 50%;
67
67
  translate: -50% -50%;
68
68
  transform: rotate(45deg);
69
69
  background-color: #3a4952;
@@ -81,7 +81,7 @@ const tooltipContext = getContext(TooltipContext.identifier);
81
81
  z-index: -1;
82
82
  top: 100%;
83
83
  border-radius: 4px;
84
- left: 50%;
84
+ inset-inline-start: 50%;
85
85
  translate: -50% -50%;
86
86
  transform: rotate(45deg);
87
87
  background-color: #3a4952;
@@ -1,8 +1,9 @@
1
1
  <svelte:options runes />
2
2
 
3
- <script lang="ts">import { passthrough } from "../Helpers/Helpers.svelte.js";
3
+ <script lang="ts">import { m as i18n } from "../paraglide/messages.js";
4
+ import { passthrough } from "../Helpers/Helpers.svelte.js";
4
5
  import Icon from "./Icon.svelte";
5
- const { icon, interactive = false, title, oncontextmenu, ariaLabel = "Edit Barcode Value" } = $props();
6
+ const { icon, interactive = false, title, oncontextmenu, ariaLabel = i18n["scoria.label.edit_barcode_value"]() } = $props();
6
7
  let svgContainer = $state(null);
7
8
  // Track the last SVG we mounted so the effect only re-runs when the
8
9
  // underlying SVG identity changes. Repeated parent renders that hand
@@ -68,7 +69,7 @@ $effect(() => {
68
69
  <button
69
70
  aria-label={ariaLabel}
70
71
  onkeydown={passthrough}
71
- title="Right click to edit barcode value for the {title} command"
72
+ title={i18n['scoria.text.barcode_edit_hint']({ name: title })}
72
73
  oncontextmenu={(e) => {
73
74
  if (oncontextmenu) {
74
75
  e.preventDefault();