@lavalogic/scoria 0.40.0 → 0.40.2
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.
- package/README.md +58 -58
- package/dist/Components/AccordionGroup.svelte +46 -46
- package/dist/Components/AccordionGroupButton.svelte +76 -76
- package/dist/Components/Action.svelte +136 -136
- package/dist/Components/AlertModal.svelte +195 -195
- package/dist/Components/AppointmentCalendar/AppointmentCalendar.svelte +729 -729
- package/dist/Components/Base/BaseModal.svelte +125 -125
- package/dist/Components/Base/ContextWrapper.svelte +72 -72
- package/dist/Components/Base/Pagination.svelte +198 -198
- package/dist/Components/Base/Snippets.svelte +36 -36
- package/dist/Components/BigRadioSet.svelte +38 -38
- package/dist/Components/Bubble.svelte +101 -101
- package/dist/Components/Button.svelte +209 -209
- package/dist/Components/Checkbox.svelte +86 -86
- package/dist/Components/CollapsibleCard.svelte +78 -78
- package/dist/Components/Contexts/ContextMenu.svelte +164 -164
- package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
- package/dist/Components/Contexts/ContextMenuOption.svelte +60 -60
- package/dist/Components/Contexts/Toast.svelte +86 -86
- package/dist/Components/Contexts/ToastContainer.svelte +65 -65
- package/dist/Components/Contexts/Tooltip.svelte +37 -37
- package/dist/Components/DataMatrixIcon.svelte +112 -112
- package/dist/Components/DateInput.svelte +148 -148
- package/dist/Components/DatePicker.svelte +300 -300
- package/dist/Components/DesktopModal.svelte +90 -90
- package/dist/Components/Dial.svelte +204 -204
- package/dist/Components/DimensionInput.svelte +170 -170
- package/dist/Components/DragMenu/DragMenuHolder.svelte +119 -119
- package/dist/Components/DragMenu/DraggableCard.svelte +77 -77
- package/dist/Components/FileCard.svelte +24 -24
- package/dist/Components/FileUpload.svelte +236 -236
- package/dist/Components/GridInput.svelte +196 -196
- package/dist/Components/GridInputSet.svelte +29 -29
- package/dist/Components/HorizontalTabGroup.svelte +82 -82
- package/dist/Components/HorizontalTabGroupButton.svelte +44 -44
- package/dist/Components/Icon.svelte +128 -128
- package/dist/Components/Icons.js +357 -357
- package/dist/Components/InfoAlert.svelte +35 -35
- package/dist/Components/LoadingAnimation.svelte +29 -29
- package/dist/Components/LoadingModal.svelte +45 -45
- package/dist/Components/LoadingOverlay.svelte +25 -25
- package/dist/Components/Modal.svelte +258 -258
- package/dist/Components/MultiSelect.svelte +220 -220
- package/dist/Components/Nav/Nav.svelte +110 -110
- package/dist/Components/Nav/NavServiceMenuList.svelte +43 -43
- package/dist/Components/Nav/NavTab.svelte +62 -62
- package/dist/Components/Nav/ServiceMenuItem.svelte +112 -112
- package/dist/Components/Nav/ServicesNav.svelte +80 -80
- package/dist/Components/NumberInput.svelte +157 -157
- package/dist/Components/PageHeading.svelte +25 -25
- package/dist/Components/PasswordInput.svelte +88 -88
- package/dist/Components/Portal.svelte +36 -36
- package/dist/Components/ProgressBubble.svelte +107 -107
- package/dist/Components/QuerySelect.svelte +366 -366
- package/dist/Components/SingleSelect.svelte +250 -250
- package/dist/Components/StepButton.svelte +70 -70
- package/dist/Components/StepForm.svelte +140 -140
- package/dist/Components/Switch.svelte +69 -69
- package/dist/Components/Table/ARCHITECTURE.md +298 -298
- package/dist/Components/Table/Body/QuickSearchCell.svelte +679 -679
- package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +51 -51
- package/dist/Components/Table/Body/Rows/ColumnList.svelte +59 -59
- package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +454 -454
- package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +79 -79
- package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +185 -185
- package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +124 -124
- package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +131 -120
- package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +234 -234
- package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +105 -105
- package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +87 -87
- package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +126 -126
- package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +159 -159
- package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +246 -246
- package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +216 -216
- package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +252 -252
- package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +179 -179
- package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +221 -221
- package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +197 -197
- package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +190 -190
- package/dist/Components/Table/Body/Rows/TableRow.svelte +290 -290
- package/dist/Components/Table/Body/TableBody.svelte +155 -155
- package/dist/Components/Table/ColumnFactory.svelte.js +1 -0
- package/dist/Components/Table/Headers/HighlightAllHeader.svelte +41 -41
- package/dist/Components/Table/Headers/SelectAllHeader.svelte +30 -30
- package/dist/Components/Table/Headers/TableHead.svelte +415 -415
- package/dist/Components/Table/Misc/ColumnPanel.svelte +39 -39
- package/dist/Components/Table/Misc/ColumnPanelModal.svelte +39 -39
- package/dist/Components/Table/Misc/FilterInput.svelte +641 -641
- package/dist/Components/Table/Misc/FilterPanel.svelte +190 -190
- package/dist/Components/Table/Misc/FilterPanelModal.svelte +31 -31
- package/dist/Components/Table/Misc/ShareViewModal.svelte +291 -291
- package/dist/Components/Table/Misc/SidePanel.svelte +35 -35
- package/dist/Components/Table/Misc/TableConfigurationModal.svelte +644 -644
- package/dist/Components/Table/Misc/TableFooter.svelte +340 -340
- package/dist/Components/Table/Misc/TableHorizontalBar.svelte +140 -140
- package/dist/Components/Table/Misc/TableSidebar.svelte +200 -200
- package/dist/Components/Table/Misc/TableViewDropdown.svelte +105 -105
- package/dist/Components/Table/Misc/ToolboxPanel.svelte +100 -100
- package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +107 -107
- package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +192 -192
- package/dist/Components/Table/NestedTable.svelte +130 -130
- package/dist/Components/Table/Table.svelte +692 -692
- package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.d.ts +5 -0
- package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.js +3 -0
- package/dist/Components/Table/Types/Public/ColumnOptions.d.ts +10 -0
- package/dist/Components/Test/TestContextConsumer.svelte +13 -13
- package/dist/Components/TextArea.svelte +130 -130
- package/dist/Components/TextInput.svelte +176 -176
- package/dist/Components/ThreeStateRadio.svelte +131 -131
- package/dist/Components/Touch/BoolCard.svelte +45 -45
- package/dist/Components/Touch/DateModal.svelte +209 -209
- package/dist/Components/Touch/EditCard.svelte +59 -59
- package/dist/Components/Touch/InfoCard.svelte +31 -31
- package/dist/Components/Touch/InfoTextCard.svelte +28 -28
- package/dist/Components/Touch/ModalExplanation.svelte +17 -17
- package/dist/Components/Touch/NumberKeyboard.svelte +225 -225
- package/dist/Components/Touch/NumberModal.svelte +79 -79
- package/dist/Components/Touch/PlusMinusCard.svelte +46 -46
- package/dist/Components/Touch/SelectModal.svelte +127 -127
- package/dist/Components/Touch/SummaryCard.svelte +93 -93
- package/dist/Components/Touch/TextAreaModal.svelte +95 -95
- package/dist/Components/Touch/TextModal.svelte +106 -106
- package/dist/Components/Touch/TouchCard.svelte +33 -33
- package/dist/Components/Touch/TouchModal.svelte +274 -274
- package/dist/Components/Touch/UtilityButton.svelte +109 -109
- package/dist/Components/VerticalTabGroup.svelte +79 -79
- package/dist/Components/VerticalTabGroupButton.svelte +58 -58
- package/dist/Helpers/Datamatrix.d.ts +19 -19
- package/dist/Helpers/Datamatrix.js +291 -291
- package/dist/Types/Examples/ExampleModal.svelte +35 -35
- package/dist/scss/_basics.scss +12 -12
- package/dist/scss/_colours.scss +134 -134
- package/dist/scss/_mixins.scss +3392 -3392
- package/dist/scss/_motion.scss +57 -57
- package/dist/scss/_sizing.scss +85 -85
- package/dist/scss/_transitions.scss +8 -8
- package/package.json +1 -1
|
@@ -1,200 +1,200 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<!--
|
|
4
|
-
@component
|
|
5
|
-
Generic local-collection paginator. Renders a window of items via a
|
|
6
|
-
`snippet` plus a control bar with page-number buttons, a jump-to-page
|
|
7
|
-
input, and previous/next buttons. The component is generic over
|
|
8
|
-
`T extends object` with a `key: keyof T` used as the
|
|
9
|
-
`{#each}` key inside the rendered page.
|
|
10
|
-
|
|
11
|
-
### Usage
|
|
12
|
-
|
|
13
|
-
```svelte
|
|
14
|
-
<Pagination snippet={itemSnippet} pageSize={20} items={dataWrapper.value} key="id" />
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
The `pageButtons` window (up to five numbered buttons) is recomputed
|
|
18
|
-
via `$derived`, not via an `$effect`, so the page bar diffs in a
|
|
19
|
-
single reactive pass and the keyed `{#each pageButtons as page ...}`
|
|
20
|
-
preserves button identity across page changes.
|
|
21
|
-
-->
|
|
22
|
-
<script
|
|
23
|
-
lang="ts"
|
|
24
|
-
generics="T extends object"
|
|
25
|
-
>
|
|
26
|
-
import { autoPluralise, generateWeakId } from '../../Helpers/Helpers.svelte.js';
|
|
27
|
-
import { Colour } from '../../scss/colours.js';
|
|
28
|
-
import { Side } from '../../Types/Internal/Side.js';
|
|
29
|
-
import { Size } from '../../Types/Internal/Size.js';
|
|
30
|
-
import { Variant } from '../../Types/Internal/Variant.js';
|
|
31
|
-
import Button from '../Button.svelte';
|
|
32
|
-
import Icon from '../Icon.svelte';
|
|
33
|
-
import NumberInput from '../NumberInput.svelte';
|
|
34
|
-
import type { PaginationProps } from './PaginationProps.js';
|
|
35
|
-
|
|
36
|
-
const {
|
|
37
|
-
items,
|
|
38
|
-
key,
|
|
39
|
-
pageSize = 20,
|
|
40
|
-
snippet,
|
|
41
|
-
itemName = 'Item',
|
|
42
|
-
border = false,
|
|
43
|
-
padding = '1.5rem', // sizing.$regular-padding
|
|
44
|
-
gap = '1.5rem', // sizing.$regular-gap
|
|
45
|
-
height,
|
|
46
|
-
}: PaginationProps<T> = $props();
|
|
47
|
-
|
|
48
|
-
const _uuid = generateWeakId();
|
|
49
|
-
let pageIndex = $state(0);
|
|
50
|
-
const pageValue = $derived(pageIndex + 1);
|
|
51
|
-
const startIndex = $derived(pageIndex * pageSize);
|
|
52
|
-
const pageItems = $derived(items.slice(startIndex, startIndex + pageSize));
|
|
53
|
-
|
|
54
|
-
const lastPage = $derived(Math.ceil(items.length / pageSize));
|
|
55
|
-
const lastPageIndex = $derived(lastPage - 1);
|
|
56
|
-
|
|
57
|
-
// Debounced jump-to-page handler. Reads the raw event because the
|
|
58
|
-
// debounce drives state, not the input value directly; binding to
|
|
59
|
-
// `pageValue` would defeat the debounce.
|
|
60
|
-
let debounceTimeout = -1;
|
|
61
|
-
function onNumberInput(e: Event) {
|
|
62
|
-
const value = (e.target as HTMLInputElement).value;
|
|
63
|
-
const page = Number(value);
|
|
64
|
-
|
|
65
|
-
clearTimeout(debounceTimeout);
|
|
66
|
-
if (!isNaN(page)) {
|
|
67
|
-
debounceTimeout = setTimeout(() => {
|
|
68
|
-
pageIndex = Math.max(page - 1, 0);
|
|
69
|
-
}, 400) as unknown as number;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Compute the window of up to five page numbers shown in the
|
|
75
|
-
* control bar. Centred on the current page where possible and
|
|
76
|
-
* clamped against both ends. Pulled into a stand-alone helper so
|
|
77
|
-
* the windowing logic is unit-testable from outside the component.
|
|
78
|
-
*/
|
|
79
|
-
function getPageWindow(
|
|
80
|
-
currentIndex: number,
|
|
81
|
-
totalPages: number,
|
|
82
|
-
windowSize: number
|
|
83
|
-
): Array<number> {
|
|
84
|
-
const start = Math.min(totalPages - 2, currentIndex - 1);
|
|
85
|
-
const clampedStart = Math.max(1, Math.min(start, totalPages - (windowSize - 1)));
|
|
86
|
-
const count = Math.min(totalPages, windowSize);
|
|
87
|
-
const out = new Array<number>(count);
|
|
88
|
-
for (let i = 0; i < count; i++) {
|
|
89
|
-
out[i] = clampedStart + i;
|
|
90
|
-
}
|
|
91
|
-
return out;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const pageButtons = $derived(getPageWindow(pageIndex, lastPage, 5));
|
|
95
|
-
</script>
|
|
96
|
-
|
|
97
|
-
<div
|
|
98
|
-
class="wrapper"
|
|
99
|
-
class:border
|
|
100
|
-
style:padding
|
|
101
|
-
style:gap
|
|
102
|
-
style:height
|
|
103
|
-
>
|
|
104
|
-
{#each pageItems as item, index (item[key])}
|
|
105
|
-
{@render snippet(item, index)}
|
|
106
|
-
{/each}
|
|
107
|
-
<div class="spread_row bottom_row">
|
|
108
|
-
<div class="block">
|
|
109
|
-
<span>{items.length} {autoPluralise(itemName, items.length)}</span>
|
|
110
|
-
</div>
|
|
111
|
-
|
|
112
|
-
<div class="block records-per-page">
|
|
113
|
-
<span>Records per Page: {pageSize}</span>
|
|
114
|
-
</div>
|
|
115
|
-
|
|
116
|
-
<div class="spacer"></div>
|
|
117
|
-
|
|
118
|
-
<div
|
|
119
|
-
class="scrollable"
|
|
120
|
-
role="navigation"
|
|
121
|
-
aria-label="Pagination"
|
|
122
|
-
>
|
|
123
|
-
<div class="block">
|
|
124
|
-
<Icon
|
|
125
|
-
name="paper"
|
|
126
|
-
colour={Colour['$ui-blue-6']}
|
|
127
|
-
/>
|
|
128
|
-
<span>{lastPage} {autoPluralise('Page', lastPage)}</span>
|
|
129
|
-
</div>
|
|
130
|
-
|
|
131
|
-
<div class="block">
|
|
132
|
-
<label for="{_uuid}-jump-to-page"
|
|
133
|
-
><Icon
|
|
134
|
-
name="arrow-move-horizontal"
|
|
135
|
-
colour={Colour['$ui-blue-6']}
|
|
136
|
-
/></label
|
|
137
|
-
>
|
|
138
|
-
|
|
139
|
-
<label for="{_uuid}-jump-to-page">Jump to page:</label>
|
|
140
|
-
|
|
141
|
-
<NumberInput
|
|
142
|
-
id="{_uuid}-jump-to-page"
|
|
143
|
-
value={pageValue}
|
|
144
|
-
oninput={onNumberInput}
|
|
145
|
-
/>
|
|
146
|
-
</div>
|
|
147
|
-
|
|
148
|
-
<div class="block nopad page-arrow">
|
|
149
|
-
<Button
|
|
150
|
-
variant={Variant.Toolbar}
|
|
151
|
-
disabled={pageIndex === 0}
|
|
152
|
-
side={Side.Bottom}
|
|
153
|
-
onclick={() => {
|
|
154
|
-
pageIndex = Math.max(pageIndex - 1, 0);
|
|
155
|
-
}}
|
|
156
|
-
size={Size.FillHeight}
|
|
157
|
-
iconLeft={{
|
|
158
|
-
name: 'left-close',
|
|
159
|
-
size: Size.FillHeight,
|
|
160
|
-
}}>Previous Page</Button
|
|
161
|
-
>
|
|
162
|
-
</div>
|
|
163
|
-
|
|
164
|
-
{#each pageButtons as pageNumber (pageNumber)}
|
|
165
|
-
<div class="block nopad">
|
|
166
|
-
<Button
|
|
167
|
-
variant={Variant.Toolbar}
|
|
168
|
-
side={Side.Bottom}
|
|
169
|
-
size={Size.FillHeight}
|
|
170
|
-
toggled={pageIndex + 1 === pageNumber}
|
|
171
|
-
label={`Go to page ${pageNumber.toString()}`}
|
|
172
|
-
onclick={() => {
|
|
173
|
-
pageIndex = pageNumber - 1;
|
|
174
|
-
}}>{pageNumber}</Button
|
|
175
|
-
>
|
|
176
|
-
</div>
|
|
177
|
-
{/each}
|
|
178
|
-
|
|
179
|
-
<div class="block nopad page-arrow">
|
|
180
|
-
<Button
|
|
181
|
-
variant={Variant.Toolbar}
|
|
182
|
-
side={Side.Bottom}
|
|
183
|
-
size={Size.FillHeight}
|
|
184
|
-
onclick={() => {
|
|
185
|
-
pageIndex = Math.min(pageIndex + 1, lastPageIndex);
|
|
186
|
-
}}
|
|
187
|
-
disabled={pageIndex == lastPageIndex}
|
|
188
|
-
iconRight={{
|
|
189
|
-
name: 'right-close',
|
|
190
|
-
size: Size.FillHeight,
|
|
191
|
-
}}>Next Page</Button
|
|
192
|
-
>
|
|
193
|
-
</div>
|
|
194
|
-
</div>
|
|
195
|
-
</div>
|
|
196
|
-
</div>
|
|
197
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
@component
|
|
5
|
+
Generic local-collection paginator. Renders a window of items via a
|
|
6
|
+
`snippet` plus a control bar with page-number buttons, a jump-to-page
|
|
7
|
+
input, and previous/next buttons. The component is generic over
|
|
8
|
+
`T extends object` with a `key: keyof T` used as the
|
|
9
|
+
`{#each}` key inside the rendered page.
|
|
10
|
+
|
|
11
|
+
### Usage
|
|
12
|
+
|
|
13
|
+
```svelte
|
|
14
|
+
<Pagination snippet={itemSnippet} pageSize={20} items={dataWrapper.value} key="id" />
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The `pageButtons` window (up to five numbered buttons) is recomputed
|
|
18
|
+
via `$derived`, not via an `$effect`, so the page bar diffs in a
|
|
19
|
+
single reactive pass and the keyed `{#each pageButtons as page ...}`
|
|
20
|
+
preserves button identity across page changes.
|
|
21
|
+
-->
|
|
22
|
+
<script
|
|
23
|
+
lang="ts"
|
|
24
|
+
generics="T extends object"
|
|
25
|
+
>
|
|
26
|
+
import { autoPluralise, generateWeakId } from '../../Helpers/Helpers.svelte.js';
|
|
27
|
+
import { Colour } from '../../scss/colours.js';
|
|
28
|
+
import { Side } from '../../Types/Internal/Side.js';
|
|
29
|
+
import { Size } from '../../Types/Internal/Size.js';
|
|
30
|
+
import { Variant } from '../../Types/Internal/Variant.js';
|
|
31
|
+
import Button from '../Button.svelte';
|
|
32
|
+
import Icon from '../Icon.svelte';
|
|
33
|
+
import NumberInput from '../NumberInput.svelte';
|
|
34
|
+
import type { PaginationProps } from './PaginationProps.js';
|
|
35
|
+
|
|
36
|
+
const {
|
|
37
|
+
items,
|
|
38
|
+
key,
|
|
39
|
+
pageSize = 20,
|
|
40
|
+
snippet,
|
|
41
|
+
itemName = 'Item',
|
|
42
|
+
border = false,
|
|
43
|
+
padding = '1.5rem', // sizing.$regular-padding
|
|
44
|
+
gap = '1.5rem', // sizing.$regular-gap
|
|
45
|
+
height,
|
|
46
|
+
}: PaginationProps<T> = $props();
|
|
47
|
+
|
|
48
|
+
const _uuid = generateWeakId();
|
|
49
|
+
let pageIndex = $state(0);
|
|
50
|
+
const pageValue = $derived(pageIndex + 1);
|
|
51
|
+
const startIndex = $derived(pageIndex * pageSize);
|
|
52
|
+
const pageItems = $derived(items.slice(startIndex, startIndex + pageSize));
|
|
53
|
+
|
|
54
|
+
const lastPage = $derived(Math.ceil(items.length / pageSize));
|
|
55
|
+
const lastPageIndex = $derived(lastPage - 1);
|
|
56
|
+
|
|
57
|
+
// Debounced jump-to-page handler. Reads the raw event because the
|
|
58
|
+
// debounce drives state, not the input value directly; binding to
|
|
59
|
+
// `pageValue` would defeat the debounce.
|
|
60
|
+
let debounceTimeout = -1;
|
|
61
|
+
function onNumberInput(e: Event) {
|
|
62
|
+
const value = (e.target as HTMLInputElement).value;
|
|
63
|
+
const page = Number(value);
|
|
64
|
+
|
|
65
|
+
clearTimeout(debounceTimeout);
|
|
66
|
+
if (!isNaN(page)) {
|
|
67
|
+
debounceTimeout = setTimeout(() => {
|
|
68
|
+
pageIndex = Math.max(page - 1, 0);
|
|
69
|
+
}, 400) as unknown as number;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Compute the window of up to five page numbers shown in the
|
|
75
|
+
* control bar. Centred on the current page where possible and
|
|
76
|
+
* clamped against both ends. Pulled into a stand-alone helper so
|
|
77
|
+
* the windowing logic is unit-testable from outside the component.
|
|
78
|
+
*/
|
|
79
|
+
function getPageWindow(
|
|
80
|
+
currentIndex: number,
|
|
81
|
+
totalPages: number,
|
|
82
|
+
windowSize: number
|
|
83
|
+
): Array<number> {
|
|
84
|
+
const start = Math.min(totalPages - 2, currentIndex - 1);
|
|
85
|
+
const clampedStart = Math.max(1, Math.min(start, totalPages - (windowSize - 1)));
|
|
86
|
+
const count = Math.min(totalPages, windowSize);
|
|
87
|
+
const out = new Array<number>(count);
|
|
88
|
+
for (let i = 0; i < count; i++) {
|
|
89
|
+
out[i] = clampedStart + i;
|
|
90
|
+
}
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const pageButtons = $derived(getPageWindow(pageIndex, lastPage, 5));
|
|
95
|
+
</script>
|
|
96
|
+
|
|
97
|
+
<div
|
|
98
|
+
class="wrapper"
|
|
99
|
+
class:border
|
|
100
|
+
style:padding
|
|
101
|
+
style:gap
|
|
102
|
+
style:height
|
|
103
|
+
>
|
|
104
|
+
{#each pageItems as item, index (item[key])}
|
|
105
|
+
{@render snippet(item, index)}
|
|
106
|
+
{/each}
|
|
107
|
+
<div class="spread_row bottom_row">
|
|
108
|
+
<div class="block">
|
|
109
|
+
<span>{items.length} {autoPluralise(itemName, items.length)}</span>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<div class="block records-per-page">
|
|
113
|
+
<span>Records per Page: {pageSize}</span>
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
<div class="spacer"></div>
|
|
117
|
+
|
|
118
|
+
<div
|
|
119
|
+
class="scrollable"
|
|
120
|
+
role="navigation"
|
|
121
|
+
aria-label="Pagination"
|
|
122
|
+
>
|
|
123
|
+
<div class="block">
|
|
124
|
+
<Icon
|
|
125
|
+
name="paper"
|
|
126
|
+
colour={Colour['$ui-blue-6']}
|
|
127
|
+
/>
|
|
128
|
+
<span>{lastPage} {autoPluralise('Page', lastPage)}</span>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<div class="block">
|
|
132
|
+
<label for="{_uuid}-jump-to-page"
|
|
133
|
+
><Icon
|
|
134
|
+
name="arrow-move-horizontal"
|
|
135
|
+
colour={Colour['$ui-blue-6']}
|
|
136
|
+
/></label
|
|
137
|
+
>
|
|
138
|
+
|
|
139
|
+
<label for="{_uuid}-jump-to-page">Jump to page:</label>
|
|
140
|
+
|
|
141
|
+
<NumberInput
|
|
142
|
+
id="{_uuid}-jump-to-page"
|
|
143
|
+
value={pageValue}
|
|
144
|
+
oninput={onNumberInput}
|
|
145
|
+
/>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<div class="block nopad page-arrow">
|
|
149
|
+
<Button
|
|
150
|
+
variant={Variant.Toolbar}
|
|
151
|
+
disabled={pageIndex === 0}
|
|
152
|
+
side={Side.Bottom}
|
|
153
|
+
onclick={() => {
|
|
154
|
+
pageIndex = Math.max(pageIndex - 1, 0);
|
|
155
|
+
}}
|
|
156
|
+
size={Size.FillHeight}
|
|
157
|
+
iconLeft={{
|
|
158
|
+
name: 'left-close',
|
|
159
|
+
size: Size.FillHeight,
|
|
160
|
+
}}>Previous Page</Button
|
|
161
|
+
>
|
|
162
|
+
</div>
|
|
163
|
+
|
|
164
|
+
{#each pageButtons as pageNumber (pageNumber)}
|
|
165
|
+
<div class="block nopad">
|
|
166
|
+
<Button
|
|
167
|
+
variant={Variant.Toolbar}
|
|
168
|
+
side={Side.Bottom}
|
|
169
|
+
size={Size.FillHeight}
|
|
170
|
+
toggled={pageIndex + 1 === pageNumber}
|
|
171
|
+
label={`Go to page ${pageNumber.toString()}`}
|
|
172
|
+
onclick={() => {
|
|
173
|
+
pageIndex = pageNumber - 1;
|
|
174
|
+
}}>{pageNumber}</Button
|
|
175
|
+
>
|
|
176
|
+
</div>
|
|
177
|
+
{/each}
|
|
178
|
+
|
|
179
|
+
<div class="block nopad page-arrow">
|
|
180
|
+
<Button
|
|
181
|
+
variant={Variant.Toolbar}
|
|
182
|
+
side={Side.Bottom}
|
|
183
|
+
size={Size.FillHeight}
|
|
184
|
+
onclick={() => {
|
|
185
|
+
pageIndex = Math.min(pageIndex + 1, lastPageIndex);
|
|
186
|
+
}}
|
|
187
|
+
disabled={pageIndex == lastPageIndex}
|
|
188
|
+
iconRight={{
|
|
189
|
+
name: 'right-close',
|
|
190
|
+
size: Size.FillHeight,
|
|
191
|
+
}}>Next Page</Button
|
|
192
|
+
>
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
|
|
198
198
|
<style>.wrapper {
|
|
199
199
|
display: flex;
|
|
200
200
|
flex: 1;
|
|
@@ -269,4 +269,4 @@ preserves button identity across page changes.
|
|
|
269
269
|
}
|
|
270
270
|
.spread_row .spacer {
|
|
271
271
|
flex-grow: 2;
|
|
272
|
-
}</style>
|
|
272
|
+
}</style>
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<!-- @component
|
|
4
|
-
An empty component that only exists to export common snippets
|
|
5
|
-
(`pending` and `failed`) for re-use by `{#await}` blocks and other
|
|
6
|
-
async-status surfaces. The component itself renders nothing.
|
|
7
|
-
-->
|
|
8
|
-
<script
|
|
9
|
-
lang="ts"
|
|
10
|
-
module
|
|
11
|
-
>
|
|
12
|
-
import { getErrorMessage, loadingText } from '../../Helpers/Helpers.svelte.js';
|
|
13
|
-
import Button from '../Button.svelte';
|
|
14
|
-
|
|
15
|
-
// The local `{#snippet _pending}` / `{#snippet _failed}` declarations
|
|
16
|
-
// must be hoistable references for `export const` to bind to them.
|
|
17
|
-
// Svelte 5 currently requires the snippet name to differ from the
|
|
18
|
-
// exported binding, so we use an underscore prefix on the local
|
|
19
|
-
// declaration and expose the un-prefixed name as the public surface.
|
|
20
|
-
export const pending = _pending;
|
|
21
|
-
export const failed = _failed;
|
|
22
|
-
</script>
|
|
23
|
-
|
|
24
|
-
{#snippet _pending()}
|
|
25
|
-
{loadingText}
|
|
26
|
-
{/snippet}
|
|
27
|
-
{#snippet _failed(e: unknown, retry?: () => void)}
|
|
28
|
-
Error: {getErrorMessage(e)}
|
|
29
|
-
{#if retry}
|
|
30
|
-
<Button
|
|
31
|
-
onclick={() => {
|
|
32
|
-
retry();
|
|
33
|
-
}}>Retry</Button
|
|
34
|
-
>
|
|
35
|
-
{/if}
|
|
36
|
-
{/snippet}
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<!-- @component
|
|
4
|
+
An empty component that only exists to export common snippets
|
|
5
|
+
(`pending` and `failed`) for re-use by `{#await}` blocks and other
|
|
6
|
+
async-status surfaces. The component itself renders nothing.
|
|
7
|
+
-->
|
|
8
|
+
<script
|
|
9
|
+
lang="ts"
|
|
10
|
+
module
|
|
11
|
+
>
|
|
12
|
+
import { getErrorMessage, loadingText } from '../../Helpers/Helpers.svelte.js';
|
|
13
|
+
import Button from '../Button.svelte';
|
|
14
|
+
|
|
15
|
+
// The local `{#snippet _pending}` / `{#snippet _failed}` declarations
|
|
16
|
+
// must be hoistable references for `export const` to bind to them.
|
|
17
|
+
// Svelte 5 currently requires the snippet name to differ from the
|
|
18
|
+
// exported binding, so we use an underscore prefix on the local
|
|
19
|
+
// declaration and expose the un-prefixed name as the public surface.
|
|
20
|
+
export const pending = _pending;
|
|
21
|
+
export const failed = _failed;
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
{#snippet _pending()}
|
|
25
|
+
{loadingText}
|
|
26
|
+
{/snippet}
|
|
27
|
+
{#snippet _failed(e: unknown, retry?: () => void)}
|
|
28
|
+
Error: {getErrorMessage(e)}
|
|
29
|
+
{#if retry}
|
|
30
|
+
<Button
|
|
31
|
+
onclick={() => {
|
|
32
|
+
retry();
|
|
33
|
+
}}>Retry</Button
|
|
34
|
+
>
|
|
35
|
+
{/if}
|
|
36
|
+
{/snippet}
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
lang="ts"
|
|
5
|
-
generics="T"
|
|
6
|
-
>
|
|
7
|
-
import type { BigRadioOption } from '../Types/Internal/BigRadioOption.js';
|
|
8
|
-
import type { BigRadioSetProps } from './BigRadioSetProps.js';
|
|
9
|
-
let { name, options, selected = $bindable(), onchange }: BigRadioSetProps<T> = $props();
|
|
10
|
-
</script>
|
|
11
|
-
|
|
12
|
-
<div
|
|
13
|
-
class="wrapper"
|
|
14
|
-
role="radiogroup"
|
|
15
|
-
>
|
|
16
|
-
{#each options as option (option.value)}
|
|
17
|
-
<!-- eslint-disable-next-line @typescript-eslint/no-confusing-void-expression -->
|
|
18
|
-
{@render radio(option)}
|
|
19
|
-
{/each}
|
|
20
|
-
</div>
|
|
21
|
-
|
|
22
|
-
{#snippet radio(option: BigRadioOption<T>)}
|
|
23
|
-
<label class:selected={selected === option.value}>
|
|
24
|
-
<input
|
|
25
|
-
type="radio"
|
|
26
|
-
{name}
|
|
27
|
-
bind:group={selected}
|
|
28
|
-
value={option.value}
|
|
29
|
-
onchange={() => void onchange?.(option.value)}
|
|
30
|
-
/>
|
|
31
|
-
<div class="text">
|
|
32
|
-
<h5 class="title">{option.label}</h5>
|
|
33
|
-
<p class="note">{option.info}</p>
|
|
34
|
-
</div>
|
|
35
|
-
</label>
|
|
36
|
-
{/snippet}
|
|
37
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
generics="T"
|
|
6
|
+
>
|
|
7
|
+
import type { BigRadioOption } from '../Types/Internal/BigRadioOption.js';
|
|
8
|
+
import type { BigRadioSetProps } from './BigRadioSetProps.js';
|
|
9
|
+
let { name, options, selected = $bindable(), onchange }: BigRadioSetProps<T> = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<div
|
|
13
|
+
class="wrapper"
|
|
14
|
+
role="radiogroup"
|
|
15
|
+
>
|
|
16
|
+
{#each options as option (option.value)}
|
|
17
|
+
<!-- eslint-disable-next-line @typescript-eslint/no-confusing-void-expression -->
|
|
18
|
+
{@render radio(option)}
|
|
19
|
+
{/each}
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
{#snippet radio(option: BigRadioOption<T>)}
|
|
23
|
+
<label class:selected={selected === option.value}>
|
|
24
|
+
<input
|
|
25
|
+
type="radio"
|
|
26
|
+
{name}
|
|
27
|
+
bind:group={selected}
|
|
28
|
+
value={option.value}
|
|
29
|
+
onchange={() => void onchange?.(option.value)}
|
|
30
|
+
/>
|
|
31
|
+
<div class="text">
|
|
32
|
+
<h5 class="title">{option.label}</h5>
|
|
33
|
+
<p class="note">{option.info}</p>
|
|
34
|
+
</div>
|
|
35
|
+
</label>
|
|
36
|
+
{/snippet}
|
|
37
|
+
|
|
38
38
|
<style>.wrapper {
|
|
39
39
|
display: flex;
|
|
40
40
|
flex-flow: row wrap;
|
|
@@ -87,4 +87,4 @@ label.selected {
|
|
|
87
87
|
}
|
|
88
88
|
label.selected h5 {
|
|
89
89
|
color: #ffffff;
|
|
90
|
-
}</style>
|
|
90
|
+
}</style>
|