@lavalogic/scoria 0.40.14 → 0.40.16

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 (141) hide show
  1. package/README.md +58 -58
  2. package/dist/Components/AccordionGroup.svelte +35 -46
  3. package/dist/Components/AccordionGroupButton.svelte +68 -76
  4. package/dist/Components/Action.svelte +103 -135
  5. package/dist/Components/AlertModal.svelte +171 -190
  6. package/dist/Components/AppointmentCalendar/AppointmentCalendar.svelte +614 -697
  7. package/dist/Components/Base/BaseModal.svelte +90 -116
  8. package/dist/Components/Base/ContextWrapper.svelte +67 -72
  9. package/dist/Components/Base/Pagination.svelte +173 -196
  10. package/dist/Components/Base/Snippets.svelte +34 -36
  11. package/dist/Components/BigRadioSet.svelte +36 -38
  12. package/dist/Components/Bubble.svelte +78 -101
  13. package/dist/Components/Button.svelte +175 -208
  14. package/dist/Components/Checkbox.svelte +75 -86
  15. package/dist/Components/CollapsibleCard.svelte +72 -86
  16. package/dist/Components/CollapsibleMenuGroup.svelte +52 -56
  17. package/dist/Components/ConditionBuilder/ConditionBuilder.svelte +39 -64
  18. package/dist/Components/Contexts/ContextMenu.svelte +141 -156
  19. package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
  20. package/dist/Components/Contexts/ContextMenuOption.svelte +53 -60
  21. package/dist/Components/Contexts/Toast.svelte +81 -86
  22. package/dist/Components/Contexts/ToastContainer.svelte +58 -62
  23. package/dist/Components/Contexts/Tooltip.svelte +36 -37
  24. package/dist/Components/DataMatrixIcon.svelte +95 -108
  25. package/dist/Components/DateInput.svelte +118 -146
  26. package/dist/Components/DatePicker.svelte +255 -294
  27. package/dist/Components/DesktopModal.svelte +70 -90
  28. package/dist/Components/Dial.svelte +167 -197
  29. package/dist/Components/DimensionInput.svelte +124 -169
  30. package/dist/Components/DragMenu/DragMenuHolder.svelte +98 -114
  31. package/dist/Components/DragMenu/DraggableCard.svelte +64 -76
  32. package/dist/Components/FileCard.svelte +21 -24
  33. package/dist/Components/FileUpload.svelte +190 -225
  34. package/dist/Components/GridInput.svelte +159 -196
  35. package/dist/Components/GridInputSet.svelte +24 -29
  36. package/dist/Components/HorizontalTabGroup.svelte +73 -89
  37. package/dist/Components/HorizontalTabGroupButton.svelte +40 -44
  38. package/dist/Components/Icon.svelte +99 -128
  39. package/dist/Components/Icons.js +357 -357
  40. package/dist/Components/InfoAlert.svelte +35 -38
  41. package/dist/Components/LoadingAnimation.svelte +691 -755
  42. package/dist/Components/LoadingModal.svelte +36 -44
  43. package/dist/Components/LoadingOverlay.svelte +22 -26
  44. package/dist/Components/Modal.svelte +204 -254
  45. package/dist/Components/MultiSelect.svelte +186 -216
  46. package/dist/Components/Nav/Nav.svelte +94 -110
  47. package/dist/Components/Nav/NavServiceMenuList.svelte +57 -61
  48. package/dist/Components/Nav/NavTab.svelte +58 -62
  49. package/dist/Components/Nav/ServiceMenuItem.svelte +103 -111
  50. package/dist/Components/Nav/ServicesNav.svelte +72 -79
  51. package/dist/Components/NumberInput.svelte +121 -155
  52. package/dist/Components/OptionCards.svelte +62 -73
  53. package/dist/Components/PageHeading.svelte +23 -25
  54. package/dist/Components/PasswordInput.svelte +69 -88
  55. package/dist/Components/PopoverButton.svelte +69 -82
  56. package/dist/Components/Portal.svelte +29 -35
  57. package/dist/Components/ProgressBubble.svelte +91 -106
  58. package/dist/Components/QuerySelect.svelte +260 -346
  59. package/dist/Components/SidebarPanel.svelte +34 -36
  60. package/dist/Components/SingleSelect.svelte +196 -244
  61. package/dist/Components/StepButton.svelte +65 -70
  62. package/dist/Components/StepForm.svelte +115 -135
  63. package/dist/Components/Switch.svelte +57 -69
  64. package/dist/Components/Table/ARCHITECTURE.md +298 -298
  65. package/dist/Components/Table/Body/QuickSearchCell.svelte +578 -655
  66. package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +42 -51
  67. package/dist/Components/Table/Body/Rows/ColumnList.svelte +42 -58
  68. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +403 -442
  69. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +51 -78
  70. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +165 -184
  71. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +110 -123
  72. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +134 -160
  73. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +190 -231
  74. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +82 -104
  75. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +52 -87
  76. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +122 -150
  77. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +132 -159
  78. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +190 -236
  79. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +173 -211
  80. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +204 -244
  81. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +140 -177
  82. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +188 -217
  83. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +173 -193
  84. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +166 -187
  85. package/dist/Components/Table/Body/Rows/TableRow.svelte +245 -288
  86. package/dist/Components/Table/Body/TableBody.svelte +141 -154
  87. package/dist/Components/Table/ColumnFactory.svelte.js +1 -0
  88. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +35 -41
  89. package/dist/Components/Table/Headers/SelectAllHeader.svelte +24 -30
  90. package/dist/Components/Table/Headers/TableHead.svelte +348 -402
  91. package/dist/Components/Table/Misc/ColumnPanel.svelte +37 -39
  92. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +35 -39
  93. package/dist/Components/Table/Misc/FilterInput.svelte +556 -619
  94. package/dist/Components/Table/Misc/FilterPanel.svelte +170 -183
  95. package/dist/Components/Table/Misc/FilterPanelModal.svelte +25 -31
  96. package/dist/Components/Table/Misc/ShareViewModal.svelte +252 -281
  97. package/dist/Components/Table/Misc/SidePanel.svelte +32 -35
  98. package/dist/Components/Table/Misc/TableConfigurationModal.svelte +574 -629
  99. package/dist/Components/Table/Misc/TableFooter.svelte +326 -332
  100. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +134 -140
  101. package/dist/Components/Table/Misc/TableSidebar.svelte +183 -198
  102. package/dist/Components/Table/Misc/TableViewDropdown.svelte +83 -103
  103. package/dist/Components/Table/Misc/ToolboxPanel.svelte +83 -100
  104. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +88 -107
  105. package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +163 -190
  106. package/dist/Components/Table/NestedTable.svelte +102 -128
  107. package/dist/Components/Table/Table.svelte +531 -663
  108. package/dist/Components/Table/Types/Columns/Definitions/Actions/ActionsDef.svelte.d.ts +8 -6
  109. package/dist/Components/Table/Types/Columns/Definitions/Actions/ActionsDef.svelte.js +3 -3
  110. package/dist/Components/Test/TestContextConsumer.svelte +11 -13
  111. package/dist/Components/TextArea.svelte +95 -130
  112. package/dist/Components/TextInput.svelte +125 -176
  113. package/dist/Components/ThreeStateRadio.svelte +111 -130
  114. package/dist/Components/Touch/BoolCard.svelte +33 -45
  115. package/dist/Components/Touch/DateModal.svelte +164 -204
  116. package/dist/Components/Touch/EditCard.svelte +48 -59
  117. package/dist/Components/Touch/InfoCard.svelte +28 -31
  118. package/dist/Components/Touch/InfoTextCard.svelte +26 -28
  119. package/dist/Components/Touch/ModalExplanation.svelte +15 -17
  120. package/dist/Components/Touch/NumberKeyboard.svelte +181 -218
  121. package/dist/Components/Touch/NumberModal.svelte +59 -79
  122. package/dist/Components/Touch/PlusMinusCard.svelte +43 -46
  123. package/dist/Components/Touch/SelectModal.svelte +111 -126
  124. package/dist/Components/Touch/SummaryCard.svelte +80 -93
  125. package/dist/Components/Touch/TextAreaModal.svelte +72 -94
  126. package/dist/Components/Touch/TextModal.svelte +77 -105
  127. package/dist/Components/Touch/TouchCard.svelte +31 -33
  128. package/dist/Components/Touch/TouchModal.svelte +214 -270
  129. package/dist/Components/Touch/UtilityButton.svelte +88 -109
  130. package/dist/Components/VerticalTabGroup.svelte +60 -78
  131. package/dist/Components/VerticalTabGroupButton.svelte +54 -58
  132. package/dist/Helpers/Datamatrix.d.ts +19 -19
  133. package/dist/Helpers/Datamatrix.js +291 -291
  134. package/dist/Types/Examples/ExampleModal.svelte +31 -35
  135. package/dist/scss/_basics.scss +12 -12
  136. package/dist/scss/_colours.scss +134 -134
  137. package/dist/scss/_mixins.scss +3392 -3392
  138. package/dist/scss/_motion.scss +57 -57
  139. package/dist/scss/_sizing.scss +85 -85
  140. package/dist/scss/_transitions.scss +8 -8
  141. package/package.json +1 -1
@@ -2,10 +2,10 @@ import type { ColourSet } from '../../../../../../scss/colours.js';
2
2
  import type { TableActionButton } from '../../TableActionButton.js';
3
3
  import { ColumnDef, type ColumnDefProps } from '../ColumnDef.svelte.js';
4
4
  /**
5
- * Construction-time props for `ActionsDef`. Omits `header` (pinned to
6
- * `'Actions'`) and makes `id` optional: the typed column factory passes
7
- * a deterministic `actions-<n>` id, and a `generateUUID`-suffixed id is
8
- * minted only when none is supplied.
5
+ * Construction-time props for `ActionsDef`. `header` is optional and
6
+ * defaults to `'Actions'`; `id` is optional too: the typed column factory
7
+ * passes a deterministic `actions-<n>` id, and a `generateUUID`-suffixed id
8
+ * is minted only when none is supplied.
9
9
  *
10
10
  * Notes:
11
11
  * - `isEnabled` defaults to `true` for every button if omitted.
@@ -14,6 +14,8 @@ import { ColumnDef, type ColumnDefProps } from '../ColumnDef.svelte.js';
14
14
  * single `ActionsDef` can drive a row of differently-styled actions.
15
15
  */
16
16
  export interface ActionsDefProps<T extends object, in FilterValueType> extends Omit<ColumnDefProps<T, FilterValueType>, 'id' | 'header'> {
17
+ /** Optional column header; defaults to `'Actions'`. */
18
+ header?: ColumnDefProps<T, FilterValueType>['header'];
17
19
  /** The buttons rendered for every row. */
18
20
  actions: Array<TableActionButton<T>>;
19
21
  /** Per-row, per-button enable predicate; assumed `true` if missing. */
@@ -30,8 +32,8 @@ export interface ActionsDefProps<T extends object, in FilterValueType> extends O
30
32
  }
31
33
  /**
32
34
  * `ActionsDef<T, FilterValueType>` is a column whose cells render a
33
- * row of buttons. It is non-sortable, non-filterable, and pins its
34
- * header to `'Actions'`.
35
+ * row of buttons. It is non-sortable, non-filterable, and defaults its
36
+ * header to `'Actions'` (override via `props.header`).
35
37
  *
36
38
  * Note: when constructed without an explicit `id` the fallback id uses
37
39
  * `generateUUID()`, which is NOT stable across table rebuilds; consumers
@@ -3,8 +3,8 @@ import { ColumnType } from '../../ColumnType.js';
3
3
  import { ColumnDef } from '../ColumnDef.svelte.js';
4
4
  /**
5
5
  * `ActionsDef<T, FilterValueType>` is a column whose cells render a
6
- * row of buttons. It is non-sortable, non-filterable, and pins its
7
- * header to `'Actions'`.
6
+ * row of buttons. It is non-sortable, non-filterable, and defaults its
7
+ * header to `'Actions'` (override via `props.header`).
8
8
  *
9
9
  * Note: when constructed without an explicit `id` the fallback id uses
10
10
  * `generateUUID()`, which is NOT stable across table rebuilds; consumers
@@ -15,7 +15,7 @@ export class ActionsDef extends ColumnDef {
15
15
  constructor(props) {
16
16
  super({
17
17
  id: props.id ?? syntheticColumnId(`actions-${generateUUID()}`),
18
- header: 'Actions',
18
+ header: props.header ?? 'Actions',
19
19
  allowSorting: false,
20
20
  allowFiltering: false,
21
21
  });
@@ -1,13 +1,11 @@
1
- <svelte:options runes />
2
-
3
- <script lang="ts">
4
- import { TestContext } from '../../Contexts/TestContext.svelte.js';
5
- import { getContext } from 'svelte';
6
-
7
- const testContext = getContext<TestContext>(TestContext.identifier);
8
- </script>
9
-
10
- <h1>counter 1: {testContext.value1.value}</h1>
11
- <p>Ref wrapper 1 is incremented every time you click the button</p>
12
- <h2>counter 2: {testContext.value2.value}</h2>
13
- <p>ref wrapper 2 adds ref wrapper 1's value every time ref wrapper 1's value is divisible by 3</p>
1
+ <svelte:options runes />
2
+
3
+ <script lang="ts">import { TestContext } from "../../Contexts/TestContext.svelte.js";
4
+ import { getContext } from "svelte";
5
+ const testContext = getContext(TestContext.identifier);
6
+ </script>
7
+
8
+ <h1>counter 1: {testContext.value1.value}</h1>
9
+ <p>Ref wrapper 1 is incremented every time you click the button</p>
10
+ <h2>counter 2: {testContext.value2.value}</h2>
11
+ <p>ref wrapper 2 adds ref wrapper 1's value every time ref wrapper 1's value is divisible by 3</p>
@@ -1,132 +1,97 @@
1
- <svelte:options runes />
2
-
3
- <script lang="ts">
4
- import { cssLength } from '../Helpers/Helpers.svelte.js';
5
- import { InputVariant } from '../Types/Internal/InputVariant.js';
6
- import { Size } from '../Types/Internal/Size.js';
7
- import Icon from './Icon.svelte';
8
- import type { TextAreaProps } from './TextAreaProps.js';
9
-
10
- let {
11
- value = $bindable(''),
12
- labelTop,
13
- labelRight,
14
- placeholder,
15
- maxWidth = false,
16
- required = false,
17
- variant = InputVariant.Default,
18
- selectNone = false,
19
- noresize = false,
20
- uppercase = false,
21
- disabled,
22
- invalid = false,
23
- showErrorColours = true,
24
- optional = false,
25
- leftIcon,
26
- rightIcon,
27
- onLeftIconClick,
28
- onRightIconClick,
29
- rows = 4,
30
-
31
- textAreaRef = $bindable(),
32
- autocomplete,
33
- spellcheck,
34
- onblur,
35
- onfocus,
36
- // No default `onkeydown` - see TextInput.svelte for the rationale.
37
- // The legacy default (`passthrough`) blurred the textarea on every
38
- // alphanumeric keystroke and made the field unusable.
39
- onkeydown,
40
- oninput,
41
- }: TextAreaProps = $props();
42
-
43
- const isInvalid = $derived(showErrorColours && ((required && value.trim() === '') || invalid));
44
- </script>
45
-
46
- <label
47
- class:for-modal={variant === InputVariant.Modal}
48
- class:max-width={maxWidth}
49
- >
50
- {#if labelTop && variant !== InputVariant.Modal}
51
- <span
52
- class="top-label"
53
- class:for-default={variant === InputVariant.Default}
54
- class:invalid={isInvalid}
55
- >{labelTop}{#if optional}<i>&nbsp;- optional</i>{/if}</span
56
- >
57
- {#if variant === InputVariant.Default}
58
- <span
59
- aria-hidden="true"
60
- class="border"
61
- class:invalid={isInvalid}
62
- >{labelTop}{#if optional}<i>&nbsp;- optional</i>{/if}</span
63
- >
64
- {/if}
65
- {/if}
66
- <div
67
- class="icon-container"
68
- class:for-modal={variant == InputVariant.Modal}
69
- >
70
- {#if leftIcon}
71
- <Icon
72
- name={leftIcon.name}
73
- size={leftIcon.size ?? Size.Medium}
74
- colour={leftIcon.colour}
75
- float
76
- left={cssLength('0.75rem')}
77
- top={cssLength('50%')}
78
- anchorX={cssLength('0')}
79
- anchorY={cssLength('-50%')}
80
- clickable={!!onLeftIconClick}
81
- onclick={onLeftIconClick}
82
- />
83
- {/if}
84
- <textarea
85
- class:noresize
86
- class:uppercase
87
- class:invalid={isInvalid}
88
- class:select-none={selectNone}
89
- class:left-pad={leftIcon != undefined}
90
- class:right-pad={rightIcon != undefined}
91
- class:for-modal={variant == InputVariant.Modal}
92
- class:max-width={maxWidth}
93
- autocomplete={autocomplete ?? 'off'}
94
- spellcheck={spellcheck ?? true}
95
- aria-invalid={isInvalid || undefined}
96
- bind:value
97
- {onblur}
98
- {onfocus}
99
- {onkeydown}
100
- {oninput}
101
- {rows}
102
- bind:this={textAreaRef}
103
- {placeholder}
104
- {required}
105
- {disabled}
106
- ></textarea>
107
- {#if rightIcon}
108
- <Icon
109
- name={rightIcon.name}
110
- size={rightIcon.size ?? Size.Medium}
111
- colour={rightIcon.colour}
112
- float
113
- right={cssLength(variant == InputVariant.Modal ? '1rem' : '0.5rem')}
114
- top={cssLength('50%')}
115
- anchorX={cssLength('0')}
116
- anchorY={cssLength('-50%')}
117
- clickable={!!onRightIconClick}
118
- onclick={onRightIconClick}
119
- />
120
- {/if}
121
- {#if labelRight}
122
- <span
123
- class="right-label"
124
- class:for-modal={variant == InputVariant.Modal}>{labelRight}</span
125
- >
126
- {/if}
127
- </div>
128
- </label>
129
-
1
+ <svelte:options runes />
2
+
3
+ <script lang="ts">import { cssLength } from "../Helpers/Helpers.svelte.js";
4
+ import { InputVariant } from "../Types/Internal/InputVariant.js";
5
+ import { Size } from "../Types/Internal/Size.js";
6
+ import Icon from "./Icon.svelte";
7
+ let { value = $bindable(""), labelTop, labelRight, placeholder, maxWidth = false, required = false, variant = InputVariant.Default, selectNone = false, noresize = false, uppercase = false, disabled, invalid = false, showErrorColours = true, optional = false, leftIcon, rightIcon, onLeftIconClick, onRightIconClick, rows = 4, textAreaRef = $bindable(), autocomplete, spellcheck, onblur, onfocus, onkeydown, oninput } = $props();
8
+ const isInvalid = $derived(showErrorColours && (required && value.trim() === "" || invalid));
9
+ </script>
10
+
11
+ <label
12
+ class:for-modal={variant === InputVariant.Modal}
13
+ class:max-width={maxWidth}
14
+ >
15
+ {#if labelTop && variant !== InputVariant.Modal}
16
+ <span
17
+ class="top-label"
18
+ class:for-default={variant === InputVariant.Default}
19
+ class:invalid={isInvalid}
20
+ >{labelTop}{#if optional}<i>&nbsp;- optional</i>{/if}</span
21
+ >
22
+ {#if variant === InputVariant.Default}
23
+ <span
24
+ aria-hidden="true"
25
+ class="border"
26
+ class:invalid={isInvalid}
27
+ >{labelTop}{#if optional}<i>&nbsp;- optional</i>{/if}</span
28
+ >
29
+ {/if}
30
+ {/if}
31
+ <div
32
+ class="icon-container"
33
+ class:for-modal={variant == InputVariant.Modal}
34
+ >
35
+ {#if leftIcon}
36
+ <Icon
37
+ name={leftIcon.name}
38
+ size={leftIcon.size ?? Size.Medium}
39
+ colour={leftIcon.colour}
40
+ float
41
+ left={cssLength('0.75rem')}
42
+ top={cssLength('50%')}
43
+ anchorX={cssLength('0')}
44
+ anchorY={cssLength('-50%')}
45
+ clickable={!!onLeftIconClick}
46
+ onclick={onLeftIconClick}
47
+ />
48
+ {/if}
49
+ <textarea
50
+ class:noresize
51
+ class:uppercase
52
+ class:invalid={isInvalid}
53
+ class:select-none={selectNone}
54
+ class:left-pad={leftIcon != undefined}
55
+ class:right-pad={rightIcon != undefined}
56
+ class:for-modal={variant == InputVariant.Modal}
57
+ class:max-width={maxWidth}
58
+ autocomplete={autocomplete ?? 'off'}
59
+ spellcheck={spellcheck ?? true}
60
+ aria-invalid={isInvalid || undefined}
61
+ bind:value
62
+ {onblur}
63
+ {onfocus}
64
+ {onkeydown}
65
+ {oninput}
66
+ {rows}
67
+ bind:this={textAreaRef}
68
+ {placeholder}
69
+ {required}
70
+ {disabled}
71
+ ></textarea>
72
+ {#if rightIcon}
73
+ <Icon
74
+ name={rightIcon.name}
75
+ size={rightIcon.size ?? Size.Medium}
76
+ colour={rightIcon.colour}
77
+ float
78
+ right={cssLength(variant == InputVariant.Modal ? '1rem' : '0.5rem')}
79
+ top={cssLength('50%')}
80
+ anchorX={cssLength('0')}
81
+ anchorY={cssLength('-50%')}
82
+ clickable={!!onRightIconClick}
83
+ onclick={onRightIconClick}
84
+ />
85
+ {/if}
86
+ {#if labelRight}
87
+ <span
88
+ class="right-label"
89
+ class:for-modal={variant == InputVariant.Modal}>{labelRight}</span
90
+ >
91
+ {/if}
92
+ </div>
93
+ </label>
94
+
130
95
  <style>textarea {
131
96
  box-sizing: border-box;
132
97
  height: 100%;
@@ -340,4 +305,4 @@ span.border.invalid {
340
305
  .textarea-error-wrapper.for-modal {
341
306
  position: relative;
342
307
  height: 100%;
343
- }</style>
308
+ }</style>
@@ -1,178 +1,127 @@
1
- <svelte:options runes />
2
-
3
- <script lang="ts">
4
- import { cssLength, isValidEmailAddress } from '../Helpers/Helpers.svelte.js';
5
- import { Colour, ColourSet } from '../scss/colours.js';
6
- import { InputVariant } from '../Types/Internal/InputVariant.js';
7
- import { Size } from '../Types/Internal/Size.js';
8
- import Action from './Action.svelte';
9
- import Icon from './Icon.svelte';
10
- import type { TextInputProps } from './TextInputProps.js';
11
- let {
12
- id,
13
- value = $bindable(''),
14
- labelTop,
15
- optional,
16
- labelRight,
17
- placeholder,
18
- required = false,
19
- variant = InputVariant.Default,
20
- selectNone = false,
21
- uppercase = false,
22
- disabled = false,
23
- invalid = false,
24
- showErrorColours = true,
25
- rightIconDisabled = false,
26
- leftIcon,
27
- rightIcon,
28
- type,
29
- onLeftIconClick,
30
- onRightIconClick,
31
- inputRef = $bindable(),
32
- 'data-type': dataType,
33
- autocomplete,
34
- spellcheck,
35
- onblur,
36
- onfocus,
37
- // No default `onkeydown`. The legacy default was `passthrough`,
38
- // a helper that BLURS the target on every alphanumeric key (it is
39
- // a barcode-scanner aid intended for buttons - note the
40
- // `as HTMLButtonElement` cast inside it). Applied to a text input
41
- // it makes the field unusable: each keystroke blurs the input
42
- // before the value can update, so users see nothing as they type.
43
- // Inputs should accept keystrokes by default; consumers that want
44
- // the barcode-blur behaviour explicitly pass
45
- // `onkeydown={passthrough}` (preferably renamed to
46
- // `blurOnAlphanumeric` in a future patch).
47
- onkeydown,
48
- oninput,
49
- }: TextInputProps = $props();
50
-
51
- const isInvalid = $derived(
52
- showErrorColours &&
53
- !disabled &&
54
- ((required &&
55
- (!value?.trim() ||
56
- (type == 'email' &&
57
- value.length >= 3 &&
58
- value.includes('@') &&
59
- !isValidEmailAddress(value)))) ||
60
- invalid)
61
- );
62
- </script>
63
-
64
- <div
65
- class="error-wrapper"
66
- class:for-modal={variant == InputVariant.Modal}
67
- class:for-table={variant == InputVariant.Table}
68
- >
69
- <label
70
- class:for-modal={variant == InputVariant.Modal}
71
- class:for-table={variant == InputVariant.Table}
72
- >
73
- {#if labelTop}
74
- <span
75
- class="top-label"
76
- class:for-default={variant === InputVariant.Default}
77
- class:invalid={isInvalid}
78
- >{labelTop}{#if optional}<i>&nbsp;- optional</i>{/if}</span
79
- >
80
- {#if variant === InputVariant.Default}
81
- <span
82
- aria-hidden="true"
83
- class="border"
84
- class:invalid={isInvalid}
85
- >{labelTop}{#if optional}<i>&nbsp;- optional</i>{/if}</span
86
- >
87
- {/if}
88
- {/if}
89
- <div
90
- class="icon-container"
91
- class:for-modal={variant == InputVariant.Modal}
92
- >
93
- {#if leftIcon}
94
- {#if onLeftIconClick}
95
- <div class="left-icon">
96
- <Action
97
- noTabIndex
98
- colourSet={ColourSet.Auxiliary}
99
- icon={leftIcon}
100
- size={Size.Medium}
101
- onclick={onLeftIconClick}
102
- />
103
- </div>
104
- {:else}
105
- <Icon
106
- name={leftIcon.name}
107
- size={leftIcon.size ?? Size.Medium}
108
- colour={leftIcon.colour}
109
- float
110
- left={cssLength('0.75rem')}
111
- top={cssLength('50%')}
112
- anchorX={cssLength('0')}
113
- anchorY={cssLength('-50%')}
114
- />
115
- {/if}
116
- {/if}
117
- <input
118
- {id}
119
- class:for-default={variant === InputVariant.Default}
120
- class:uppercase
121
- class:invalid={isInvalid}
122
- class:select-none={selectNone}
123
- class:left-pad={leftIcon != undefined}
124
- class:right-pad={rightIcon != undefined}
125
- class:for-modal={variant == InputVariant.Modal}
126
- data-type={dataType}
127
- type={type ?? 'text'}
128
- autocomplete={autocomplete ?? (type === 'email' ? 'email' : 'off')}
129
- spellcheck={spellcheck ?? false}
130
- aria-invalid={isInvalid || undefined}
131
- bind:value
132
- {onblur}
133
- {onfocus}
134
- {onkeydown}
135
- {oninput}
136
- bind:this={inputRef}
137
- {placeholder}
138
- {required}
139
- {disabled}
140
- />
141
- {#if rightIcon}
142
- <div class="right-icon">
143
- {#if onRightIconClick}
144
- <Action
145
- noTabIndex
146
- colourSet={ColourSet.Auxiliary}
147
- disabled={rightIconDisabled}
148
- icon={rightIcon}
149
- size={Size.Medium}
150
- onclick={onRightIconClick}
151
- />
152
- {:else}
153
- <Icon
154
- name={rightIcon.name}
155
- size={rightIcon.size ?? Size.Medium}
156
- colour={rightIcon.colour ?? Colour['$font-disabled']}
157
- float
158
- right={cssLength(variant == InputVariant.Modal ? '1rem' : '0.5rem')}
159
- top={cssLength('50%')}
160
- anchorX={cssLength('0')}
161
- anchorY={cssLength('-50%')}
162
- />
163
- {/if}
164
- </div>
165
- {/if}
166
- {#if labelRight}
167
- <span
168
- class="right-label"
169
- class:for-modal={variant == InputVariant.Modal}>{labelRight}</span
170
- >
171
- {/if}
172
- </div>
173
- </label>
174
- </div>
175
-
1
+ <svelte:options runes />
2
+
3
+ <script lang="ts">import { cssLength, isValidEmailAddress } from "../Helpers/Helpers.svelte.js";
4
+ import { Colour, ColourSet } from "../scss/colours.js";
5
+ import { InputVariant } from "../Types/Internal/InputVariant.js";
6
+ import { Size } from "../Types/Internal/Size.js";
7
+ import Action from "./Action.svelte";
8
+ import Icon from "./Icon.svelte";
9
+ let { id, value = $bindable(""), labelTop, optional, labelRight, placeholder, required = false, variant = InputVariant.Default, selectNone = false, uppercase = false, disabled = false, invalid = false, showErrorColours = true, rightIconDisabled = false, leftIcon, rightIcon, type, onLeftIconClick, onRightIconClick, inputRef = $bindable(), "data-type": dataType, autocomplete, spellcheck, onblur, onfocus, onkeydown, oninput } = $props();
10
+ const isInvalid = $derived(showErrorColours && !disabled && (required && (!value?.trim() || type == "email" && value.length >= 3 && value.includes("@") && !isValidEmailAddress(value)) || invalid));
11
+ </script>
12
+
13
+ <div
14
+ class="error-wrapper"
15
+ class:for-modal={variant == InputVariant.Modal}
16
+ class:for-table={variant == InputVariant.Table}
17
+ >
18
+ <label
19
+ class:for-modal={variant == InputVariant.Modal}
20
+ class:for-table={variant == InputVariant.Table}
21
+ >
22
+ {#if labelTop}
23
+ <span
24
+ class="top-label"
25
+ class:for-default={variant === InputVariant.Default}
26
+ class:invalid={isInvalid}
27
+ >{labelTop}{#if optional}<i>&nbsp;- optional</i>{/if}</span
28
+ >
29
+ {#if variant === InputVariant.Default}
30
+ <span
31
+ aria-hidden="true"
32
+ class="border"
33
+ class:invalid={isInvalid}
34
+ >{labelTop}{#if optional}<i>&nbsp;- optional</i>{/if}</span
35
+ >
36
+ {/if}
37
+ {/if}
38
+ <div
39
+ class="icon-container"
40
+ class:for-modal={variant == InputVariant.Modal}
41
+ >
42
+ {#if leftIcon}
43
+ {#if onLeftIconClick}
44
+ <div class="left-icon">
45
+ <Action
46
+ noTabIndex
47
+ colourSet={ColourSet.Auxiliary}
48
+ icon={leftIcon}
49
+ size={Size.Medium}
50
+ onclick={onLeftIconClick}
51
+ />
52
+ </div>
53
+ {:else}
54
+ <Icon
55
+ name={leftIcon.name}
56
+ size={leftIcon.size ?? Size.Medium}
57
+ colour={leftIcon.colour}
58
+ float
59
+ left={cssLength('0.75rem')}
60
+ top={cssLength('50%')}
61
+ anchorX={cssLength('0')}
62
+ anchorY={cssLength('-50%')}
63
+ />
64
+ {/if}
65
+ {/if}
66
+ <input
67
+ {id}
68
+ class:for-default={variant === InputVariant.Default}
69
+ class:uppercase
70
+ class:invalid={isInvalid}
71
+ class:select-none={selectNone}
72
+ class:left-pad={leftIcon != undefined}
73
+ class:right-pad={rightIcon != undefined}
74
+ class:for-modal={variant == InputVariant.Modal}
75
+ data-type={dataType}
76
+ type={type ?? 'text'}
77
+ autocomplete={autocomplete ?? (type === 'email' ? 'email' : 'off')}
78
+ spellcheck={spellcheck ?? false}
79
+ aria-invalid={isInvalid || undefined}
80
+ bind:value
81
+ {onblur}
82
+ {onfocus}
83
+ {onkeydown}
84
+ {oninput}
85
+ bind:this={inputRef}
86
+ {placeholder}
87
+ {required}
88
+ {disabled}
89
+ />
90
+ {#if rightIcon}
91
+ <div class="right-icon">
92
+ {#if onRightIconClick}
93
+ <Action
94
+ noTabIndex
95
+ colourSet={ColourSet.Auxiliary}
96
+ disabled={rightIconDisabled}
97
+ icon={rightIcon}
98
+ size={Size.Medium}
99
+ onclick={onRightIconClick}
100
+ />
101
+ {:else}
102
+ <Icon
103
+ name={rightIcon.name}
104
+ size={rightIcon.size ?? Size.Medium}
105
+ colour={rightIcon.colour ?? Colour['$font-disabled']}
106
+ float
107
+ right={cssLength(variant == InputVariant.Modal ? '1rem' : '0.5rem')}
108
+ top={cssLength('50%')}
109
+ anchorX={cssLength('0')}
110
+ anchorY={cssLength('-50%')}
111
+ />
112
+ {/if}
113
+ </div>
114
+ {/if}
115
+ {#if labelRight}
116
+ <span
117
+ class="right-label"
118
+ class:for-modal={variant == InputVariant.Modal}>{labelRight}</span
119
+ >
120
+ {/if}
121
+ </div>
122
+ </label>
123
+ </div>
124
+
176
125
  <style>input {
177
126
  box-sizing: border-box;
178
127
  height: 100%;
@@ -406,4 +355,4 @@ label.for-table input {
406
355
 
407
356
  td {
408
357
  --input-border: none;
409
- }</style>
358
+ }</style>