@lavalogic/scoria 0.24.0 → 0.25.0

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 (26) hide show
  1. package/dist/Components/Base/ContextWrapper.svelte +1 -0
  2. package/dist/Components/Base/Pagination.svelte +28 -7
  3. package/dist/Components/Base/Pagination.svelte.d.ts +8 -0
  4. package/dist/Components/Base/PaginationProps.d.ts +4 -2
  5. package/dist/Components/Base/Snippets.svelte +3 -0
  6. package/dist/Components/Base/Snippets.svelte.d.ts +1 -0
  7. package/dist/Components/Contexts/ContextMenu.svelte +87 -8
  8. package/dist/Components/Contexts/ContextMenuOption.svelte +35 -9
  9. package/dist/Components/Contexts/ContextMenuOptionProps.d.ts +1 -0
  10. package/dist/Components/Contexts/MaybeFocusable.d.ts +3 -0
  11. package/dist/Components/Contexts/MaybeFocusable.js +1 -0
  12. package/dist/Components/Contexts/Toast.svelte +18 -10
  13. package/dist/Components/HorizontalTabGroup.svelte +0 -23
  14. package/dist/Components/Table/Body/Rows/TableRow.svelte +86 -60
  15. package/dist/Components/Table/Body/Rows/TableRow.svelte.d.ts +22 -13
  16. package/dist/Components/Table/Body/TableBody.svelte +23 -28
  17. package/dist/Components/Table/Body/TableBody.svelte.d.ts +10 -2
  18. package/dist/Components/Table/Body/TableBodyProps.d.ts +2 -0
  19. package/dist/Components/Table/ColumnDefinitions/ExampleItemColumnDefRepository.svelte.js +1 -1
  20. package/dist/Components/Table/Table.svelte +54 -56
  21. package/dist/Components/Table/Types/Context/TableContext.svelte.d.ts +1 -1
  22. package/dist/Components/Table/Types/Context/TableContext.svelte.js +4 -1
  23. package/dist/Components/Touch/NumberKeyboard.svelte +58 -19
  24. package/dist/Components/VerticalTabGroup.svelte +1 -29
  25. package/dist/Types/Internal/TabOption.d.ts +0 -1
  26. package/package.json +1 -1
@@ -34,6 +34,7 @@
34
34
  setContext(AlertContext.identifier, alertContext);
35
35
 
36
36
  // NOTE known limitation. Not expected to mutate after instantiation
37
+ // svelte-ignore state_referenced_locally
37
38
  const untypedListenerContext = new UntypedInputContext(debug);
38
39
  setContext(UntypedInputContext.identifier, untypedListenerContext);
39
40
  </script>
@@ -1,6 +1,17 @@
1
1
  <svelte:options runes />
2
2
 
3
- <script lang="ts" generics="T extends object">
3
+ <!-- @component
4
+ Allows for automated pagination of local content in cases where a collection may become a performance concern
5
+
6
+ ### Usage
7
+ ```svelte
8
+ <Pagination snippet={itemSnippet} pageSize={20} items={dataWrapper.value} key="id" />
9
+ ```
10
+ -->
11
+ <script
12
+ lang="ts"
13
+ generics="T extends object"
14
+ >
4
15
  import { autoPluralise, generateShortUUID } from '../../Helpers/Helpers.svelte.js';
5
16
  import { Colour } from '../../scss/colours.js';
6
17
  import { Side } from '../../Types/Internal/Side.js';
@@ -20,7 +31,7 @@
20
31
  border = false,
21
32
  padding = '1.5rem', //sizing.$regular-padding
22
33
  gap = '1.5rem', // sizing.$regular-gap
23
- height
34
+ height,
24
35
  }: PaginationProps<T> = $props();
25
36
 
26
37
  const _uuid = generateShortUUID();
@@ -101,18 +112,28 @@
101
112
 
102
113
  <div class="scrollable">
103
114
  <div class="block">
104
- <Icon name="paper" colour={Colour['$ui-blue-6']} />
115
+ <Icon
116
+ name="paper"
117
+ colour={Colour['$ui-blue-6']}
118
+ />
105
119
  <span>{lastPage} {autoPluralise('Page', lastPage)}</span>
106
120
  </div>
107
121
 
108
122
  <div class="block">
109
123
  <label for="{_uuid}-jump-to-page"
110
- ><Icon name="arrow-move-horizontal" colour={Colour['$ui-blue-6']} /></label
124
+ ><Icon
125
+ name="arrow-move-horizontal"
126
+ colour={Colour['$ui-blue-6']}
127
+ /></label
111
128
  >
112
129
 
113
130
  <label for="{_uuid}-jump-to-page">Jump to page:</label>
114
131
 
115
- <NumberInput id="{_uuid}-jump-to-page" value={pageValue} oninput={onNumberInput} />
132
+ <NumberInput
133
+ id="{_uuid}-jump-to-page"
134
+ value={pageValue}
135
+ oninput={onNumberInput}
136
+ />
116
137
  </div>
117
138
 
118
139
  <div class="block nopad page-arrow">
@@ -126,7 +147,7 @@
126
147
  size={Size.FillHeight}
127
148
  iconLeft={{
128
149
  name: 'left-close',
129
- size: Size.FillHeight
150
+ size: Size.FillHeight,
130
151
  }}>Previous Page</Button
131
152
  >
132
153
  </div>
@@ -158,7 +179,7 @@
158
179
  disabled={pageIndex == lastPageIndex}
159
180
  iconRight={{
160
181
  name: 'right-close',
161
- size: Size.FillHeight
182
+ size: Size.FillHeight,
162
183
  }}>Next Page</Button
163
184
  >
164
185
  </div>
@@ -20,6 +20,14 @@ interface $$IsomorphicComponent {
20
20
  <T extends object>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
21
21
  z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
22
22
  }
23
+ /**
24
+ * Allows for automated pagination of local content in cases where a collection may become a performance concern
25
+ *
26
+ * ### Usage
27
+ * ```svelte
28
+ * <Pagination snippet={itemSnippet} pageSize={20} items={dataWrapper.value} key="id" />
29
+ * ```
30
+ */
23
31
  declare const Pagination: $$IsomorphicComponent;
24
32
  type Pagination<T extends object> = InstanceType<typeof Pagination<T>>;
25
33
  export default Pagination;
@@ -1,9 +1,11 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  export interface PaginationProps<T extends object> {
3
- items: Array<T>;
3
+ /** Used to index each item for a unique key. Duplicate values will result in error */
4
4
  key: string & keyof T;
5
- pageSize?: number;
5
+ items: Array<T>;
6
+ /** Second argument is the index */
6
7
  snippet: Snippet<[T, number]>;
8
+ pageSize?: number;
7
9
  itemName?: string;
8
10
  border?: boolean;
9
11
  padding?: string;
@@ -1,5 +1,8 @@
1
1
  <svelte:options runes />
2
2
 
3
+ <!-- @component
4
+ An empty component that only exists to export common snippets
5
+ -->
3
6
  <script
4
7
  lang="ts"
5
8
  module
@@ -1,5 +1,6 @@
1
1
  export declare const pending: () => ReturnType<import("svelte").Snippet>;
2
2
  export declare const failed: (e: unknown, retry?: () => void) => ReturnType<import("svelte").Snippet>;
3
+ /** An empty component that only exists to export common snippets */
3
4
  declare const Snippets: import("svelte").Component<Record<string, never>, {}, "">;
4
5
  type Snippets = ReturnType<typeof Snippets>;
5
6
  export default Snippets;
@@ -1,11 +1,17 @@
1
1
  <svelte:options runes />
2
2
 
3
+ <!--
4
+ @component
5
+
6
+
7
+ -->
3
8
  <script lang="ts">
4
9
  import { ContextMenuContext } from '../../Contexts/ContextMenuContext.svelte.js';
5
10
  import { devCatch } from '../../Helpers/Helpers.svelte.js';
6
- import { getContext, tick } from 'svelte';
11
+ import { getContext, tick, untrack } from 'svelte';
7
12
  import { fade } from 'svelte/transition';
8
13
  import ContextMenuOption from './ContextMenuOption.svelte';
14
+ import type { MaybeFocusable } from './MaybeFocusable.js';
9
15
 
10
16
  const contextMenuContext = getContext<ContextMenuContext>(ContextMenuContext.identifier);
11
17
 
@@ -36,8 +42,8 @@
36
42
  .catch(devCatch);
37
43
  }
38
44
 
39
- let menuEl: HTMLDivElement | undefined = $state();
40
- function onPageClick(e: MouseEvent) {
45
+ let menuEl = $state<HTMLUListElement | undefined>();
46
+ function closeOnClickOutside(e: MouseEvent) {
41
47
  if (!menuEl) {
42
48
  return;
43
49
  }
@@ -46,14 +52,81 @@
46
52
  }
47
53
  contextMenuContext.closeMenu();
48
54
  }
55
+
56
+ let previousElement = $state<MaybeFocusable | null | undefined>();
57
+
58
+ $effect.pre(() => {
59
+ if (contextMenuContext.showMenu) {
60
+ untrack(() => {
61
+ previousElement = document.activeElement as MaybeFocusable;
62
+ });
63
+ }
64
+ });
65
+
66
+ function refocusPrevious() {
67
+ previousElement?.focus?.();
68
+ }
69
+
70
+ function focusNext() {
71
+ if (!menuEl) {
72
+ return;
73
+ }
74
+ const items = [...menuEl.querySelectorAll<HTMLElement>('[role="menuitem"]')];
75
+ const index = items.indexOf(document.activeElement as HTMLElement);
76
+ const found = items.at((index + 1) % items.length);
77
+ if (!found) {
78
+ console.warn(`could not find next item`);
79
+ }
80
+ found?.focus();
81
+ }
82
+
83
+ function focusPrev() {
84
+ if (!menuEl) {
85
+ return;
86
+ }
87
+ const items = [...menuEl.querySelectorAll<HTMLElement>('[role="menuitem"]')];
88
+ const index = items.indexOf(document.activeElement as HTMLElement);
89
+
90
+ const found = items.at((index - 1 + items.length) % items.length);
91
+ if (!found) {
92
+ console.warn('could not find prev item');
93
+ }
94
+ found?.focus();
95
+ }
49
96
  </script>
50
97
 
51
- <svelte:body onclick={onPageClick} />
98
+ <svelte:body onclick={closeOnClickOutside} />
52
99
 
53
100
  {#if contextMenuContext.showMenu}
54
- <div transition:fade={{ duration: 50 }} bind:this={menuEl} style="top: {_y}px; left: {_x}px;">
55
- {#each contextMenuContext.items as item (item)}
101
+ <ul
102
+ transition:fade={{ duration: 50 }}
103
+ bind:this={menuEl}
104
+ style="top: {_y}px; left: {_x}px;"
105
+ role="menu"
106
+ aria-label="Context menu"
107
+ onkeydown={(e) => {
108
+ if (e.key === 'Escape') {
109
+ e.stopImmediatePropagation();
110
+ e.stopPropagation();
111
+ e.preventDefault();
112
+ contextMenuContext.closeMenu();
113
+ refocusPrevious();
114
+ } else if (e.key == 'ArrowUp') {
115
+ e.stopImmediatePropagation();
116
+ e.stopPropagation();
117
+ e.preventDefault();
118
+ focusPrev();
119
+ } else if (e.key == 'ArrowDown') {
120
+ e.stopImmediatePropagation();
121
+ e.stopPropagation();
122
+ e.preventDefault();
123
+ focusNext();
124
+ }
125
+ }}
126
+ >
127
+ {#each contextMenuContext.items as item, index (item)}
56
128
  <ContextMenuOption
129
+ {index}
57
130
  disabled={item.disabled}
58
131
  onclick={() => {
59
132
  item.callback();
@@ -62,17 +135,23 @@
62
135
  text={item.text}
63
136
  />
64
137
  {/each}
65
- </div>
138
+ </ul>
66
139
  {/if}
67
140
 
68
141
  <style>
69
- div {
142
+ ul {
143
+ padding: 4px;
70
144
  position: fixed;
71
145
  display: grid;
72
146
  border: 1px solid #0003;
73
147
  box-shadow: 2px 2px 5px 0px #0002;
148
+ gap: 4px;
74
149
  background: white;
75
150
  z-index: 9999;
76
151
  line-height: initial;
77
152
  }
153
+
154
+ ul:focus {
155
+ outline: none;
156
+ }
78
157
  </style>
@@ -1,21 +1,40 @@
1
1
  <svelte:options runes />
2
2
 
3
3
  <script lang="ts">
4
+ import { devCatch } from '../../Helpers/Helpers.svelte.js';
5
+ import { tick } from 'svelte';
4
6
  import type { ContextMenuOptionProps } from './ContextMenuOptionProps.js';
5
7
 
6
8
  let {
7
9
  text = $bindable(''),
10
+ index,
8
11
  disabled = false,
9
12
  onclick,
10
- children
13
+ children,
11
14
  }: ContextMenuOptionProps = $props();
15
+
16
+ let element = $state<HTMLButtonElement | undefined>();
17
+
18
+ $effect(() => {
19
+ void element;
20
+ if (index == 0) {
21
+ tick()
22
+ .then(() => {
23
+ if (element) {
24
+ element.focus();
25
+ }
26
+ })
27
+ .catch(devCatch);
28
+ }
29
+ });
12
30
  </script>
13
31
 
14
- <!-- svelte-ignore a11y_click_events_have_key_events -->
15
- <!-- svelte-ignore a11y_no_static_element_interactions -->
16
- <div
32
+ <button
17
33
  class="context-menu-item"
34
+ role="menuitem"
18
35
  class:disabled
36
+ tabindex={index}
37
+ bind:this={element}
19
38
  onclick={(e) => {
20
39
  e.stopImmediatePropagation();
21
40
  e.stopPropagation();
@@ -28,9 +47,11 @@
28
47
  {:else if children}
29
48
  {@render children()}
30
49
  {/if}
31
- </div>
50
+ </button>
32
51
 
33
- <style>div {
52
+ <style>button {
53
+ background-color: #ffffff;
54
+ border: none;
34
55
  padding: 4px 15px;
35
56
  cursor: default;
36
57
  font-size: 14px;
@@ -40,14 +61,19 @@
40
61
  user-select: none;
41
62
  }
42
63
 
43
- div:hover {
64
+ button:focus,
65
+ button:focus-within {
66
+ outline: solid 1px #259fc7;
67
+ }
68
+
69
+ button:hover {
44
70
  background: rgba(0, 0, 0, 0.1333333333);
45
71
  }
46
72
 
47
- div.disabled {
73
+ button.disabled {
48
74
  color: rgba(0, 0, 0, 0.4);
49
75
  }
50
76
 
51
- div.disabled:hover {
77
+ button.disabled:hover {
52
78
  background: #ffffff;
53
79
  }</style>
@@ -1,5 +1,6 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  export interface ContextMenuOptionProps {
3
+ index: number;
3
4
  text?: string;
4
5
  disabled?: boolean | undefined;
5
6
  onclick?: (e: MouseEvent) => void;
@@ -0,0 +1,3 @@
1
+ export interface MaybeFocusable {
2
+ focus?: () => void;
3
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,9 @@
1
1
  <svelte:options runes />
2
2
 
3
- <script lang="ts" module>
3
+ <script
4
+ lang="ts"
5
+ module
6
+ >
4
7
  import { ColourSet } from '../../scss/colours.js';
5
8
  import { Size } from '../../Types/Internal/Size.js';
6
9
  import { Validity } from '../../Types/Internal/Validity.js';
@@ -14,7 +17,9 @@
14
17
  let { toast, copy }: ToastProps = $props();
15
18
  </script>
16
19
 
17
- <article
20
+ <output
21
+ role={toast.result == Validity.Invalid ? 'alert' : 'status'}
22
+ aria-live={toast.result == Validity.Invalid ? 'assertive' : 'polite'}
18
23
  class:info={toast.result == Validity.Info}
19
24
  class:success={toast.result == Validity.Valid}
20
25
  class:warning={toast.result == Validity.Warning}
@@ -31,7 +36,10 @@
31
36
  colourSet={ColourSet.Auxiliary}
32
37
  />
33
38
  {:else}
34
- <Icon name="info" size={Size.MediumLarge} />
39
+ <Icon
40
+ name="info"
41
+ size={Size.MediumLarge}
42
+ />
35
43
  {/if}
36
44
  </div>
37
45
  <span>{toast.message}</span>
@@ -48,36 +56,36 @@
48
56
  </div>
49
57
  {/if}
50
58
  </div>
51
- </article>
59
+ </output>
52
60
 
53
- <style>article {
61
+ <style>output {
54
62
  font-weight: 700;
55
63
  font-size: 1.125rem;
56
64
  padding: 0.75rem;
57
65
  border-radius: 4px;
58
66
  }
59
- article.info, article.success {
67
+ output.info, output.success {
60
68
  color: #ffffff;
61
69
  --colour: #ffffff;
62
70
  background-color: #259fc7;
63
71
  }
64
- article.warning {
72
+ output.warning {
65
73
  color: #ffffff;
66
74
  --colour: #ffffff;
67
75
  background-color: #e7b500;
68
76
  }
69
- article.error {
77
+ output.error {
70
78
  color: #ffffff;
71
79
  --colour: #ffffff;
72
80
  background-color: #aa1414;
73
81
  }
74
- article > div {
82
+ output > div {
75
83
  display: flex;
76
84
  flex-flow: row nowrap;
77
85
  gap: 0.75rem;
78
86
  align-items: center;
79
87
  }
80
- article span {
88
+ output span {
81
89
  text-wrap: nowrap;
82
90
  word-break: keep-all;
83
91
  overflow: hidden;
@@ -4,8 +4,6 @@
4
4
  lang="ts"
5
5
  generics="CommonDenominator"
6
6
  >
7
- import { dev } from '$app/environment';
8
-
9
7
  import HorizontalTabGroupButton from './HorizontalTabGroupButton.svelte';
10
8
  import type { HorizontalTabGroupProps } from './HorizontalTabGroupProps.js';
11
9
  let {
@@ -16,27 +14,6 @@
16
14
  noRadius = false,
17
15
  grow = false,
18
16
  }: HorizontalTabGroupProps<CommonDenominator> = $props();
19
-
20
- $effect(() => {
21
- if (!dev) {
22
- return;
23
- }
24
- for (const tab of tabs) {
25
- if (tab.debug) {
26
- $inspect(
27
- tab.label,
28
- tab.content,
29
- tab.onclick,
30
- tab.args,
31
- tab.iconLeft,
32
- tab.iconRight,
33
- tab.isValid,
34
- tab.disabled,
35
- tab.visible
36
- );
37
- }
38
- }
39
- });
40
17
  </script>
41
18
 
42
19
  <div
@@ -2,7 +2,7 @@
2
2
 
3
3
  <script
4
4
  lang="ts"
5
- generics="T extends object"
5
+ generics="T extends object, RowIdType extends Primitive"
6
6
  >
7
7
  import { dev } from '$app/environment';
8
8
  import { devCatch, generateShortUUID } from '../../../../Helpers/Helpers.svelte.js';
@@ -12,10 +12,12 @@
12
12
  import type { DefsWrapper } from '../../Types/Columns/DefsWrapper.js';
13
13
  import type { TableCell } from '../../Types/Columns/TableCell.js';
14
14
  import { TableContext } from '../../Types/Context/TableContext.svelte.js';
15
+ import { type Primitive } from '../../Types/Context/TableInitOptions.js';
15
16
  import ColumnHighlight from './ColumnHighlight.svelte';
16
17
  import TableColumn from './Columns/TableColumn.svelte';
17
18
  import type { TableRowProps } from './TableRowProps.js';
18
- const tableContext = getContext<TableContext<T, never>>(TableContext.identifier);
19
+
20
+ const tableContext = getContext<TableContext<T, RowIdType>>(TableContext.identifier);
19
21
 
20
22
  const { row, side, odd = false, customHeight, includeHighlight }: TableRowProps<T> = $props();
21
23
 
@@ -50,10 +52,28 @@
50
52
  let prevExpandedColumnDef: ExpandDef<T, object> | undefined = $state();
51
53
 
52
54
  const rowIndex = $derived(cells.at(0) && cells[0].row.visibleIndex);
53
- const highlighted = $derived(
54
- rowIndex != undefined &&
55
- tableContext.highlightedItems.has(tableContext.selectionExtractor(row.original))
56
- );
55
+ let id = $state<RowIdType | undefined>();
56
+ const highlighted = $derived(id != undefined && tableContext.highlightedItems.has(id));
57
+
58
+ $effect(() => {
59
+ void row.original;
60
+ void tableContext.selectionExtractor;
61
+
62
+ if (rowIndex != undefined) {
63
+ const maybePromise = tableContext.selectionExtractor(row.original);
64
+ if (maybePromise instanceof Promise) {
65
+ maybePromise
66
+ .then((it) => {
67
+ id = it;
68
+ })
69
+ .catch(devCatch);
70
+ } else {
71
+ id = maybePromise;
72
+ }
73
+ } else {
74
+ id = undefined;
75
+ }
76
+ });
57
77
 
58
78
  const showHighlightButton = $derived(rowIndex != null && includeHighlight);
59
79
 
@@ -94,66 +114,70 @@
94
114
  }
95
115
  }
96
116
 
97
- //FIXME the below threw errors before. Please investigate
98
- // let trRef: HTMLTableRowElement | undefined = $state();
99
- // let _trHeight = $state(0);
100
- // export const trHeight = {
101
- // get value() {
102
- // return _trHeight;
103
- // },
104
- // };
105
-
106
- // $effect(() => {
107
- // void trRef;
108
- // return untrack(() => {
109
- // if (trRef) {
110
- // const observer = new ResizeObserver((entries) => {
111
- // if (customHeight) {
112
- // _trHeight = 0;
113
- // } else {
114
- // _trHeight = entries[0].borderBoxSize[0].blockSize;
115
- // }
116
- // });
117
- // observer.observe(trRef);
118
-
119
- // const currentTrRef = trRef;
120
- // return () => {
121
- // observer.unobserve(currentTrRef);
122
- // };
123
- // }
124
- // return () => {};
125
- // });
126
- // });
127
-
128
- // let innerTrRef: HTMLTableRowElement | undefined = $state();
129
- // let _innerTrHeight = $state(0);
130
- // export const innerTrHeight = {
131
- // get value() {
132
- // return _innerTrHeight;
133
- // }
134
- // };
135
- // $effect(() => {
136
- // if (innerTrRef) {
137
- // const observer = new ResizeObserver((entries) => {
138
- // _innerTrHeight = entries[0].borderBoxSize[0].blockSize;
139
- // });
140
- // observer.observe(innerTrRef);
141
-
142
- // const currentinnerTrRef = innerTrRef;
143
- // return () => observer.unobserve(currentTrRef);
144
- // }
145
- // });
117
+ let trRef: HTMLTableRowElement | undefined = $state();
118
+ let _trHeight = $state(0);
119
+
120
+ let innerTrRef: HTMLTableRowElement | undefined = $state();
121
+ let _innerTrHeight = $state(0);
122
+
123
+ $effect(() => {
124
+ void trRef;
125
+ void customHeight;
126
+
127
+ return untrack(() => {
128
+ if (trRef && customHeight == null) {
129
+ const observer = new ResizeObserver((entries) => {
130
+ _trHeight = entries[0].borderBoxSize[0].blockSize;
131
+ });
132
+ observer.observe(trRef);
133
+
134
+ const currenttrRef = trRef;
135
+ return () => {
136
+ observer.unobserve(currenttrRef);
137
+ _trHeight = 0;
138
+ };
139
+ } else {
140
+ _trHeight = 0;
141
+ }
142
+ return () => {};
143
+ });
144
+ });
145
+
146
+ $effect(() => {
147
+ void innerTrRef;
148
+ return untrack(() => {
149
+ if (innerTrRef) {
150
+ const observer = new ResizeObserver((entries) => {
151
+ _innerTrHeight = entries[0].borderBoxSize[0].blockSize;
152
+ });
153
+ observer.observe(innerTrRef);
154
+
155
+ const currentinnerTrRef = innerTrRef;
156
+ return () => {
157
+ observer.unobserve(currentinnerTrRef);
158
+ };
159
+ } else {
160
+ _innerTrHeight = 0;
161
+ }
162
+ return () => {};
163
+ });
164
+ });
165
+
166
+ const _totalTrHeight = $derived(_trHeight + _innerTrHeight);
167
+ export const totalTrHeight = {
168
+ get value() {
169
+ return _totalTrHeight;
170
+ },
171
+ };
146
172
  </script>
147
173
 
148
- <!-- onMouseEnter={onMouseEnter}
149
- onMouseLeave={onMouseLeave} -->
150
174
  <tr
151
175
  class:hoverable
152
176
  class:alt={tableContext.alternateRowColours && odd}
153
177
  class:highlighted
154
178
  style={customHeight ? `height: ${customHeight}px !important;` : null}
179
+ bind:this={trRef}
155
180
  >
156
- <!-- bind:this={trRef} -->
157
181
  {#if showHighlightButton}
158
182
  <ColumnHighlight
159
183
  rowIndex={rowIndex ??
@@ -181,8 +205,10 @@ onMouseLeave={onMouseLeave} -->
181
205
  {#if expandedColumnDef}
182
206
  <!-- TODO re-test and re-implement these -->
183
207
  <!-- transition:slide={{ duration: 150, axis: 'y', delay: 0 }} -->
184
- <!-- bind:this={innerTrRef} -->
185
- <tr class="inner-table">
208
+ <tr
209
+ class="inner-table"
210
+ bind:this={innerTrRef}
211
+ >
186
212
  {#await innerDataPromise}
187
213
  <td {colspan}>loading&hellip;</td>
188
214
  {:then data}
@@ -1,25 +1,34 @@
1
+ import { type Primitive } from '../../Types/Context/TableInitOptions.js';
1
2
  import type { TableRowProps } from './TableRowProps.js';
2
- declare function $$render<T extends object>(): {
3
+ declare function $$render<T extends object, RowIdType extends Primitive>(): {
3
4
  props: TableRowProps<T>;
4
- exports: {};
5
+ exports: {
6
+ totalTrHeight: {
7
+ readonly value: number;
8
+ };
9
+ };
5
10
  bindings: "";
6
11
  slots: {};
7
12
  events: {};
8
13
  };
9
- declare class __sveltets_Render<T extends object> {
10
- props(): ReturnType<typeof $$render<T>>['props'];
11
- events(): ReturnType<typeof $$render<T>>['events'];
12
- slots(): ReturnType<typeof $$render<T>>['slots'];
14
+ declare class __sveltets_Render<T extends object, RowIdType extends Primitive> {
15
+ props(): ReturnType<typeof $$render<T, RowIdType>>['props'];
16
+ events(): ReturnType<typeof $$render<T, RowIdType>>['events'];
17
+ slots(): ReturnType<typeof $$render<T, RowIdType>>['slots'];
13
18
  bindings(): "";
14
- exports(): {};
19
+ exports(): {
20
+ totalTrHeight: {
21
+ readonly value: number;
22
+ };
23
+ };
15
24
  }
16
25
  interface $$IsomorphicComponent {
17
- new <T extends object>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
18
- $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
19
- } & ReturnType<__sveltets_Render<T>['exports']>;
20
- <T extends object>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
21
- z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
26
+ new <T extends object, RowIdType extends Primitive>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T, RowIdType>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T, RowIdType>['props']>, ReturnType<__sveltets_Render<T, RowIdType>['events']>, ReturnType<__sveltets_Render<T, RowIdType>['slots']>> & {
27
+ $$bindings?: ReturnType<__sveltets_Render<T, RowIdType>['bindings']>;
28
+ } & ReturnType<__sveltets_Render<T, RowIdType>['exports']>;
29
+ <T extends object, RowIdType extends Primitive>(internal: unknown, props: ReturnType<__sveltets_Render<T, RowIdType>['props']> & {}): ReturnType<__sveltets_Render<T, RowIdType>['exports']>;
30
+ z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
22
31
  }
23
32
  declare const TableRow: $$IsomorphicComponent;
24
- type TableRow<T extends object> = InstanceType<typeof TableRow<T>>;
33
+ type TableRow<T extends object, RowIdType extends Primitive> = InstanceType<typeof TableRow<T, RowIdType>>;
25
34
  export default TableRow;
@@ -4,38 +4,34 @@
4
4
  lang="ts"
5
5
  generics="T extends object"
6
6
  >
7
+ import type { RefWrapper } from '../../../Types/Internal/RefWrapper.js';
7
8
  import { getContext } from 'svelte';
8
9
  import { TableContext } from '../Types/Context/TableContext.svelte.js';
9
10
  import QuickSearchCell from './QuickSearchCell.svelte';
10
11
  import TableRow from './Rows/TableRow.svelte';
11
12
  import type { TableBodyProps } from './TableBodyProps.js';
12
13
 
13
- let {
14
- side,
15
- // heights,
16
- columns,
17
- includeHighlight,
18
- }: TableBodyProps<T> = $props();
14
+ let { side, heights, columns, includeHighlight }: TableBodyProps<T> = $props();
19
15
 
20
16
  const tableContext = getContext<TableContext<T, never>>(TableContext.identifier);
21
17
 
22
- // type HasHeight = {
23
- // trHeight: RefWrapper<number>;
24
- // };
25
- // const rows: Array<TableRow<T>> = $state([]);
26
- // const _rowHeights = $derived(
27
- // // HACK terrible type casting due to svelte type gen not being liked by eslint
28
- // rows.map((it) => (it as HasHeight | undefined)?.trHeight.value ?? 0)
29
- // );
30
- // export const rowHeights = {
31
- // get value() {
32
- // return _rowHeights;
33
- // }
34
- // };
18
+ type HasHeight = {
19
+ totalTrHeight?: RefWrapper<number>;
20
+ };
21
+ const rows: Array<TableRow<T, never>> = $state([]);
35
22
 
36
- // $inspect(tableContext.paginationRowModel).with((...v) => {
37
- // console.trace(...v);
38
- // });
23
+ const _rowHeights = $derived(
24
+ // HACK terrible type casting due to svelte type gen not being liked by eslint
25
+ rows.map((it) => {
26
+ return (it as HasHeight | undefined)?.totalTrHeight?.value ?? 0;
27
+ })
28
+ );
29
+
30
+ export const rowHeights = {
31
+ get value() {
32
+ return _rowHeights;
33
+ },
34
+ };
39
35
  </script>
40
36
 
41
37
  <tbody>
@@ -54,18 +50,17 @@
54
50
  {/if}
55
51
 
56
52
  {#each tableContext.paginationRowModel.rows as row, index (row.visibleIndex)}
57
- <!-- {@const customHeight = heights[index]?.applyTo.includes(side)
58
- ? heights[index].maxHeight
59
- : undefined} -->
60
- <!-- {customHeight} -->
53
+ {@const customHeight = heights[index]?.applyTo.includes(side)
54
+ ? heights[index].maxHeight
55
+ : undefined}
61
56
  <TableRow
62
- customHeight={undefined}
57
+ {customHeight}
63
58
  {includeHighlight}
64
59
  {row}
65
60
  {side}
66
61
  odd={index % 2 == 1}
62
+ bind:this={rows[index]}
67
63
  />
68
- <!-- bind:this={rows[index]} -->
69
64
  {/each}
70
65
  </tbody>
71
66
 
@@ -1,7 +1,11 @@
1
1
  import type { TableBodyProps } from './TableBodyProps.js';
2
2
  declare function $$render<T extends object>(): {
3
3
  props: TableBodyProps<T>;
4
- exports: {};
4
+ exports: {
5
+ rowHeights: {
6
+ readonly value: number[];
7
+ };
8
+ };
5
9
  bindings: "";
6
10
  slots: {};
7
11
  events: {};
@@ -11,7 +15,11 @@ declare class __sveltets_Render<T extends object> {
11
15
  events(): ReturnType<typeof $$render<T>>['events'];
12
16
  slots(): ReturnType<typeof $$render<T>>['slots'];
13
17
  bindings(): "";
14
- exports(): {};
18
+ exports(): {
19
+ rowHeights: {
20
+ readonly value: number[];
21
+ };
22
+ };
15
23
  }
16
24
  interface $$IsomorphicComponent {
17
25
  new <T extends object>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
@@ -1,6 +1,8 @@
1
1
  import type { Column } from '../Types/Columns/Column.js';
2
+ import type { HeightData } from './HeightData.js';
2
3
  export interface TableBodyProps<T extends object> {
3
4
  side: 'left' | 'centre' | 'right';
5
+ heights: Array<HeightData<T>>;
4
6
  columns: Array<Column<T>>;
5
7
  includeHighlight: boolean;
6
8
  }
@@ -60,7 +60,7 @@ export function generateExampleItemColumnDefs(modal) {
60
60
  new ValidityDef({
61
61
  header: 'Valid',
62
62
  id: 'valid',
63
- debug: true,
63
+ // debug: true,
64
64
  isValid,
65
65
  modal,
66
66
  }),
@@ -12,6 +12,7 @@
12
12
  import type { RefWrapper } from '../../Types/Internal/RefWrapper.js';
13
13
  import { getContext, onMount, setContext, tick, untrack } from 'svelte';
14
14
  import LoadingOverlay from '../LoadingOverlay.svelte';
15
+ import type { HeightData } from './Body/HeightData.js';
15
16
  import { shownPopup } from './Body/Rows/Columns/ActionsCell.svelte';
16
17
  import TableBody from './Body/TableBody.svelte';
17
18
  import TableHead from './Headers/TableHead.svelte';
@@ -48,6 +49,7 @@
48
49
  const { nested = false, tableContext }: TableProps<T, IdType> = $props();
49
50
 
50
51
  // NOTE: known limitation. This is passed as a wrapper, and they should never require reassignment. It is deeply reactive
52
+ // svelte-ignore state_referenced_locally
51
53
  setContext(TableContext.identifier, tableContext);
52
54
 
53
55
  const { openContextMenu: _openContextMenu } = getContext<ContextMenuContext>(
@@ -181,16 +183,7 @@
181
183
  const minNestedHeight = $derived(20 * remPxRatio);
182
184
 
183
185
  // HACK please figure this one out
184
- // let nestedHeight = $state(minNestedHeight);
185
-
186
- //intentionally not using derived here as we sometimes need to manually change it
187
- // while also allowing it to auto-pickup min height mutations
188
- // eslint-disable-next-line svelte/prefer-writable-derived
189
- let nestedHeight = $state(0);
190
-
191
- $effect(() => {
192
- nestedHeight = minNestedHeight;
193
- });
186
+ let nestedHeight = $derived(minNestedHeight);
194
187
 
195
188
  let tableRef: HTMLDivElement | undefined = undefined;
196
189
  let mousedDownEmptySpace = $state(false);
@@ -275,46 +268,51 @@
275
268
  }
276
269
  });
277
270
 
278
- // type SvelteTableElement = {
279
- // rowHeights: RefWrapper<Array<number>>;
280
- // };
281
-
282
- // let leftTable: SvelteTableElement | undefined = $state();
283
- // let centreTable: SvelteTableElement | undefined = $state();
284
- // let rightTable: SvelteTableElement | undefined = $state();
285
-
286
- // const totalRowSizes: Array<HeightData<T>> = $derived.by(() => {
287
- // if (!leftTable || !centreTable || !rightTable) {
288
- // return [];
289
- // }
290
- // const centre = centreTable.rowHeights.value;
291
- // const right = rightTable.rowHeights.value;
292
-
293
- // return leftTable.rowHeights.value.map((_leftHeight, index) => {
294
- // const leftHeight = _leftHeight || 0;
295
- // const centreHeight = centre[index] || 0;
296
- // const rightHeight = right[index] || 0;
297
-
298
- // const maxHeight = Math.max(leftHeight, centreHeight, rightHeight);
299
- // const applyTo: HeightData<T>['applyTo'] = [];
300
-
301
- // if (leftHeight < maxHeight) {
302
- // applyTo.push('left');
303
- // }
304
- // if (centreHeight < maxHeight) {
305
- // applyTo.push('centre');
306
- // }
307
- // if (rightHeight < maxHeight) {
308
- // applyTo.push('right');
309
- // }
310
-
311
- // return {
312
- // index,
313
- // applyTo,
314
- // maxHeight
315
- // };
316
- // });
317
- // });
271
+ type SvelteTableElement = {
272
+ rowHeights: RefWrapper<Array<number>>;
273
+ };
274
+
275
+ let leftTable: SvelteTableElement | undefined = $state();
276
+ let centreTable: SvelteTableElement | undefined = $state();
277
+ let rightTable: SvelteTableElement | undefined = $state();
278
+
279
+ const totalRowSizes: Array<HeightData<T>> = $derived.by(() => {
280
+ if (!leftTable || !centreTable || !rightTable) {
281
+ return [];
282
+ }
283
+
284
+ // console.debug(`got refs for all tables`);
285
+ const centre = centreTable.rowHeights.value;
286
+ const right = rightTable.rowHeights.value;
287
+
288
+ return leftTable.rowHeights.value.map((_leftHeight, index) => {
289
+ const leftHeight = _leftHeight || 0;
290
+ const centreHeight = centre[index] || 0;
291
+ const rightHeight = right[index] || 0;
292
+
293
+ const maxHeight = Math.max(leftHeight, centreHeight, rightHeight);
294
+ const applyTo: HeightData<T>['applyTo'] = [];
295
+
296
+ if (leftHeight < maxHeight) {
297
+ // console.debug(`left (${leftHeight}) was lower than max (${maxHeight})`);
298
+ applyTo.push('left');
299
+ }
300
+ if (centreHeight < maxHeight) {
301
+ // console.debug(`centre (${centreHeight}) was lower than max (${maxHeight})`);
302
+ applyTo.push('centre');
303
+ }
304
+ if (rightHeight < maxHeight) {
305
+ // console.debug(`right (${rightHeight}) was lower than max (${maxHeight})`);
306
+ applyTo.push('right');
307
+ }
308
+
309
+ return {
310
+ index,
311
+ applyTo,
312
+ maxHeight,
313
+ };
314
+ });
315
+ });
318
316
  </script>
319
317
 
320
318
  <svelte:window
@@ -427,9 +425,9 @@
427
425
  includeHighlight={appropriateSide == 'left'}
428
426
  columns={leftColumns}
429
427
  side="left"
428
+ heights={totalRowSizes}
429
+ bind:this={leftTable}
430
430
  />
431
- <!-- heights={totalRowSizes} -->
432
- <!-- bind:this={leftTable} -->
433
431
  </table>
434
432
  <!-- {/if} -->
435
433
 
@@ -447,9 +445,9 @@
447
445
  includeHighlight={appropriateSide == 'centre'}
448
446
  columns={centreColumns}
449
447
  side="centre"
448
+ heights={totalRowSizes}
449
+ bind:this={centreTable}
450
450
  />
451
- <!-- heights={totalRowSizes}
452
- bind:this={centreTable} -->
453
451
  </table>
454
452
  <!-- {/if} -->
455
453
 
@@ -466,9 +464,9 @@
466
464
  includeHighlight={appropriateSide == 'right'}
467
465
  columns={rightColumns}
468
466
  side="right"
467
+ heights={totalRowSizes}
468
+ bind:this={rightTable}
469
469
  />
470
- <!-- heights={totalRowSizes}
471
- bind:this={rightTable} -->
472
470
  </table>
473
471
  <!-- {/if} -->
474
472
  </div>
@@ -77,7 +77,7 @@ export declare class TableContext<T extends object, RowIdType extends Primitive>
77
77
  private _focusedRowIndices;
78
78
  get focusedRowIndices(): ReadonlySet<number>;
79
79
  private readonly _highlightedItems;
80
- get highlightedItems(): SvelteMap<Awaited<unknown>, T>;
80
+ get highlightedItems(): SvelteMap<RowIdType, T>;
81
81
  _focusedColumnIds: ReadonlySet<string>;
82
82
  get focusedColumnIds(): ReadonlySet<string>;
83
83
  private _isMousingDown;
@@ -314,7 +314,6 @@ export class TableContext {
314
314
  if (browser) {
315
315
  this._getUserDefaults();
316
316
  const removeInvalidPresets = () => {
317
- console.warn('invalid presets. removing:', localStorage.getItem(`${this.userId}-${tableName}-presets`));
318
317
  localStorage.removeItem(`${this.userId}-${tableName}-presets`);
319
318
  localStorage.removeItem(`${this.userId}-${tableName}-selected-preset-name`);
320
319
  const visibilityState = {};
@@ -1241,6 +1240,7 @@ export class TableContext {
1241
1240
  };
1242
1241
  onHighlightAll = () => {
1243
1242
  if (this.allHighlighted) {
1243
+ // console.debug('All were highlighted. Clearing');
1244
1244
  this.highlightedItems.clear();
1245
1245
  return Promise.resolve();
1246
1246
  }
@@ -2155,6 +2155,9 @@ export class TableContext {
2155
2155
  }
2156
2156
  indices.set(item, rowIndex);
2157
2157
  }
2158
+ selectedRows.sort((left, right) => {
2159
+ return (indices.get(left) ?? -1) - (indices.get(right) ?? -1);
2160
+ });
2158
2161
  // TODO somewhere between here and the ending of the copy functionality, we end up with issues where instead of it using the accessor fn, it tries to pick up the select option, and ends up using the value ("1", etc)
2159
2162
  const selectedCells = [];
2160
2163
  const rowLength = selectedRows.length;
@@ -3,7 +3,7 @@
3
3
  <script lang="ts">
4
4
  import { devCatch, passthrough } from '../../Helpers/Helpers.svelte.js';
5
5
  import { InputVariant } from '../../Types/Internal/InputVariant.js';
6
- import { tick } from 'svelte';
6
+ import { tick, untrack } from 'svelte';
7
7
  import Icon from '../Icon.svelte';
8
8
  import TextInput from '../TextInput.svelte';
9
9
  import type { NumberKeyboardProps } from './NumberKeyboardProps.js';
@@ -17,10 +17,29 @@
17
17
  max,
18
18
  decimal = false,
19
19
  inputRef = $bindable(),
20
- coerceValue = true
20
+ coerceValue = false,
21
21
  }: NumberKeyboardProps = $props();
22
22
 
23
- let _value: string = $derived(value?.toFixed(decimal ? 2 : 0) ?? '');
23
+ let _value: string = $derived(
24
+ value != null && value % 1 == 0 ? value.toString() : getDecimalValue()
25
+ );
26
+
27
+ function getDecimalPlaces(value: number): number {
28
+ const str = value.toString();
29
+ if (!str.includes('.')) {
30
+ return decimal ? 2 : 0;
31
+ }
32
+ return str.split('.')[1].length;
33
+ }
34
+
35
+ const decimalPlaces = $derived(
36
+ min != null ? getDecimalPlaces(min) : max != null ? getDecimalPlaces(max) : decimal ? 2 : 0
37
+ );
38
+
39
+ function getDecimalValue(): string {
40
+ //HACK this absolutely moronic line is intentional. It's the best way to allow arbitrary decimal places without adding leading zeroes
41
+ return value ? parseFloat(value.toFixed(decimalPlaces)).toString() : '';
42
+ }
24
43
 
25
44
  const newValue = $derived.by(() => {
26
45
  const v = decimal ? parseFloat(_value) : parseInt(_value);
@@ -32,22 +51,32 @@
32
51
 
33
52
  $effect(() => {
34
53
  {
35
- value = coerceValue
36
- ? min != undefined && newValue != null && min > newValue
37
- ? min
38
- : max != undefined && newValue != null && max < newValue
39
- ? max
40
- : newValue
41
- : newValue;
54
+ if (coerceValue) {
55
+ const v =
56
+ min != undefined && newValue != null && min > newValue
57
+ ? min
58
+ : max != undefined && newValue != null && max < newValue
59
+ ? max
60
+ : newValue;
42
61
 
43
- tick()
44
- .then(() => {
45
- inputRef?.focus();
46
- })
47
- .catch(devCatch);
62
+ value = v;
63
+ } else {
64
+ value = newValue;
65
+ }
66
+
67
+ untrack(() => {
68
+ refocus();
69
+ });
48
70
  }
49
71
  });
50
72
 
73
+ function refocus() {
74
+ tick()
75
+ .then(() => {
76
+ inputRef?.focus();
77
+ })
78
+ .catch(devCatch);
79
+ }
51
80
  function getPrevValue() {
52
81
  if (inputRef) {
53
82
  if (
@@ -62,6 +91,7 @@
62
91
 
63
92
  function addDecimal() {
64
93
  _value = getPrevValue() + '.';
94
+ refocus();
65
95
  }
66
96
 
67
97
  /* due to the fact that number inputs won't allow a leading dot, we have to use a text input
@@ -74,16 +104,24 @@
74
104
 
75
105
  function backspace() {
76
106
  const preVvalue = getPrevValue();
77
- _value = preVvalue && _value.slice(0, _value.length - 1);
107
+ const v = preVvalue && _value.slice(0, _value.length - 1);
108
+ _value = v;
78
109
  }
79
110
 
80
111
  function minus() {
81
- _value = (((decimal ? parseFloat(_value) : parseInt(_value)) || 0) - 1).toString();
112
+ const v = ((decimal ? parseFloat(_value) : parseInt(_value)) || 0) - 1;
113
+
114
+ _value = (min != null ? Math.max(min, v) : v).toString();
82
115
  }
83
116
 
84
117
  function plus() {
85
- _value = (((decimal ? parseFloat(_value) : parseInt(_value)) || 0) + 1).toString();
118
+ const v = ((decimal ? parseFloat(_value) : parseInt(_value)) || 0) + 1;
119
+
120
+ _value = (max != null ? Math.min(max, v) : v).toString();
86
121
  }
122
+
123
+ const lessThanMin = $derived(min != null && (value == null || value < min));
124
+ const moreThanMax = $derived(max != null && (value == null || value > max));
87
125
  </script>
88
126
 
89
127
  <div class="number-input-wrapper">
@@ -98,6 +136,7 @@
98
136
  bind:value={_value}
99
137
  variant={InputVariant.Modal}
100
138
  required
139
+ invalid={lessThanMin || moreThanMax}
101
140
  />
102
141
  {#if max != undefined}
103
142
  <TextInput
@@ -204,7 +243,7 @@
204
243
  <button
205
244
  onkeydown={passthrough}
206
245
  type="button"
207
- disabled={!decimal || (value != null && value % 1 !== 0)}
246
+ disabled={!decimal || (value != null && value % 1 !== 0) || _value.endsWith('.')}
208
247
  onclick={addDecimal}>.</button
209
248
  >
210
249
  <button
@@ -2,18 +2,11 @@
2
2
 
3
3
  <script
4
4
  lang="ts"
5
- module
5
+ generics="CommonDenominator"
6
6
  >
7
- import { dev } from '$app/environment';
8
7
  import { onMount, untrack } from 'svelte';
9
8
  import VerticalTabGroupButton from './VerticalTabGroupButton.svelte';
10
9
  import type { VerticalTabGroupProps } from './VerticalTabGroupProps.js';
11
- </script>
12
-
13
- <script
14
- lang="ts"
15
- generics="CommonDenominator"
16
- >
17
10
  let {
18
11
  name,
19
12
  tabs,
@@ -24,27 +17,6 @@
24
17
  nohistory = false,
25
18
  }: VerticalTabGroupProps<CommonDenominator> = $props();
26
19
 
27
- $effect(() => {
28
- if (!dev) {
29
- return;
30
- }
31
- for (const tab of tabs) {
32
- if (tab.debug) {
33
- $inspect(
34
- tab.label,
35
- tab.content,
36
- tab.onclick,
37
- tab.args,
38
- tab.iconLeft,
39
- tab.iconRight,
40
- tab.isValid,
41
- tab.disabled,
42
- tab.visible
43
- );
44
- }
45
- }
46
- });
47
-
48
20
  onMount(() => {
49
21
  if (name && !nohistory) {
50
22
  const tabName = sessionStorage.getItem(`${name}-active-tab`);
@@ -5,7 +5,6 @@ export interface TabOption<Args> {
5
5
  content: Snippet<[Args]>;
6
6
  onclick: () => void;
7
7
  args: Args;
8
- debug?: boolean;
9
8
  iconLeft?: IconProps;
10
9
  iconRight?: IconProps;
11
10
  isValid?: boolean | Promise<boolean>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lavalogic/scoria",
3
3
  "description": "Svelte components used for the FloWMS Web Frontend",
4
- "version": "0.24.0",
4
+ "version": "0.25.0",
5
5
  "publishConfig": {
6
6
  "access": "restricted"
7
7
  },