@lavalogic/scoria 0.40.13 → 0.40.15
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 +35 -46
- package/dist/Components/AccordionGroupButton.svelte +68 -76
- package/dist/Components/Action.svelte +103 -135
- package/dist/Components/AlertModal.svelte +171 -190
- package/dist/Components/AppointmentCalendar/AppointmentCalendar.svelte +614 -697
- package/dist/Components/Base/BaseModal.svelte +90 -116
- package/dist/Components/Base/ContextWrapper.svelte +67 -72
- package/dist/Components/Base/Pagination.svelte +173 -196
- package/dist/Components/Base/Snippets.svelte +34 -36
- package/dist/Components/BigRadioSet.svelte +36 -38
- package/dist/Components/Bubble.svelte +78 -101
- package/dist/Components/Button.svelte +175 -208
- package/dist/Components/Checkbox.svelte +75 -86
- package/dist/Components/CollapsibleCard.svelte +72 -87
- package/dist/Components/CollapsibleMenuGroup.svelte +53 -57
- package/dist/Components/ConditionBuilder/ConditionBuilder.svelte +39 -64
- package/dist/Components/Contexts/ContextMenu.svelte +141 -156
- package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
- package/dist/Components/Contexts/ContextMenuOption.svelte +53 -60
- package/dist/Components/Contexts/Toast.svelte +81 -86
- package/dist/Components/Contexts/ToastContainer.svelte +58 -62
- package/dist/Components/Contexts/Tooltip.svelte +36 -37
- package/dist/Components/DataMatrixIcon.svelte +95 -108
- package/dist/Components/DateInput.svelte +118 -146
- package/dist/Components/DatePicker.svelte +255 -294
- package/dist/Components/DesktopModal.svelte +70 -90
- package/dist/Components/Dial.svelte +167 -197
- package/dist/Components/DimensionInput.svelte +124 -169
- package/dist/Components/DragMenu/DragMenuHolder.svelte +98 -114
- package/dist/Components/DragMenu/DraggableCard.svelte +64 -76
- package/dist/Components/FileCard.svelte +21 -24
- package/dist/Components/FileUpload.svelte +190 -225
- package/dist/Components/GridInput.svelte +159 -196
- package/dist/Components/GridInputSet.svelte +24 -29
- package/dist/Components/HorizontalTabGroup.svelte +73 -89
- package/dist/Components/HorizontalTabGroupButton.svelte +40 -44
- package/dist/Components/Icon.svelte +99 -128
- package/dist/Components/Icons.js +357 -357
- package/dist/Components/InfoAlert.svelte +35 -38
- package/dist/Components/LoadingAnimation.svelte +691 -755
- package/dist/Components/LoadingModal.svelte +36 -44
- package/dist/Components/LoadingOverlay.svelte +22 -26
- package/dist/Components/Modal.svelte +204 -254
- package/dist/Components/MultiSelect.svelte +186 -216
- package/dist/Components/Nav/Nav.svelte +94 -110
- package/dist/Components/Nav/NavServiceMenuList.svelte +57 -61
- package/dist/Components/Nav/NavTab.svelte +58 -62
- package/dist/Components/Nav/ServiceMenuItem.svelte +103 -111
- package/dist/Components/Nav/ServicesNav.svelte +72 -79
- package/dist/Components/NumberInput.svelte +121 -155
- package/dist/Components/OptionCards.svelte +62 -73
- package/dist/Components/PageHeading.svelte +23 -25
- package/dist/Components/PasswordInput.svelte +69 -88
- package/dist/Components/PopoverButton.svelte +151 -0
- package/dist/Components/PopoverButton.svelte.d.ts +9 -0
- package/dist/Components/PopoverButtonProps.d.ts +21 -0
- package/dist/Components/PopoverButtonProps.js +1 -0
- package/dist/Components/Portal.svelte +29 -35
- package/dist/Components/ProgressBubble.svelte +91 -106
- package/dist/Components/QuerySelect.svelte +260 -346
- package/dist/Components/SidebarPanel.svelte +34 -36
- package/dist/Components/SingleSelect.svelte +196 -244
- package/dist/Components/StepButton.svelte +65 -70
- package/dist/Components/StepForm.svelte +115 -135
- package/dist/Components/Switch.svelte +57 -69
- package/dist/Components/Table/ARCHITECTURE.md +298 -298
- package/dist/Components/Table/Body/QuickSearchCell.svelte +578 -655
- package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +42 -51
- package/dist/Components/Table/Body/Rows/ColumnList.svelte +42 -58
- package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +403 -442
- package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +51 -78
- package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +165 -184
- package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +110 -123
- package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +134 -160
- package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +190 -231
- package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +82 -104
- package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +52 -87
- package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +122 -150
- package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +132 -159
- package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +190 -236
- package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +173 -211
- package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +204 -244
- package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +140 -177
- package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +188 -217
- package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +173 -193
- package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +166 -187
- package/dist/Components/Table/Body/Rows/TableRow.svelte +245 -288
- package/dist/Components/Table/Body/TableBody.svelte +141 -154
- package/dist/Components/Table/Headers/HighlightAllHeader.svelte +35 -41
- package/dist/Components/Table/Headers/SelectAllHeader.svelte +24 -30
- package/dist/Components/Table/Headers/TableHead.svelte +348 -402
- package/dist/Components/Table/Misc/ColumnPanel.svelte +37 -39
- package/dist/Components/Table/Misc/ColumnPanelModal.svelte +35 -39
- package/dist/Components/Table/Misc/FilterInput.svelte +556 -619
- package/dist/Components/Table/Misc/FilterPanel.svelte +170 -183
- package/dist/Components/Table/Misc/FilterPanelModal.svelte +25 -31
- package/dist/Components/Table/Misc/ShareViewModal.svelte +252 -281
- package/dist/Components/Table/Misc/SidePanel.svelte +32 -35
- package/dist/Components/Table/Misc/TableConfigurationModal.svelte +574 -629
- package/dist/Components/Table/Misc/TableFooter.svelte +326 -332
- package/dist/Components/Table/Misc/TableHorizontalBar.svelte +134 -140
- package/dist/Components/Table/Misc/TableSidebar.svelte +183 -198
- package/dist/Components/Table/Misc/TableViewDropdown.svelte +83 -103
- package/dist/Components/Table/Misc/ToolboxPanel.svelte +83 -100
- package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +88 -107
- package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +163 -190
- package/dist/Components/Table/NestedTable.svelte +102 -128
- package/dist/Components/Table/Table.svelte +531 -663
- package/dist/Components/Test/TestContextConsumer.svelte +11 -13
- package/dist/Components/TextArea.svelte +95 -130
- package/dist/Components/TextInput.svelte +125 -176
- package/dist/Components/ThreeStateRadio.svelte +111 -130
- package/dist/Components/Touch/BoolCard.svelte +33 -45
- package/dist/Components/Touch/DateModal.svelte +164 -204
- package/dist/Components/Touch/EditCard.svelte +48 -59
- package/dist/Components/Touch/InfoCard.svelte +28 -31
- package/dist/Components/Touch/InfoTextCard.svelte +26 -28
- package/dist/Components/Touch/ModalExplanation.svelte +15 -17
- package/dist/Components/Touch/NumberKeyboard.svelte +181 -218
- package/dist/Components/Touch/NumberModal.svelte +59 -79
- package/dist/Components/Touch/PlusMinusCard.svelte +43 -46
- package/dist/Components/Touch/SelectModal.svelte +111 -126
- package/dist/Components/Touch/SummaryCard.svelte +80 -93
- package/dist/Components/Touch/TextAreaModal.svelte +72 -94
- package/dist/Components/Touch/TextModal.svelte +77 -105
- package/dist/Components/Touch/TouchCard.svelte +31 -33
- package/dist/Components/Touch/TouchModal.svelte +214 -270
- package/dist/Components/Touch/UtilityButton.svelte +88 -109
- package/dist/Components/VerticalTabGroup.svelte +60 -78
- package/dist/Components/VerticalTabGroupButton.svelte +54 -58
- package/dist/Helpers/Datamatrix.d.ts +19 -19
- package/dist/Helpers/Datamatrix.js +291 -291
- package/dist/Types/Examples/ExampleModal.svelte +31 -35
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- 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,92 +1,72 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script lang="ts">
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
{
|
|
39
|
-
|
|
40
|
-
{
|
|
41
|
-
>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
(button.type === 'submit' ? ColourSet.Primary : undefined)}>{button.label}</Button
|
|
71
|
-
>
|
|
72
|
-
</div>
|
|
73
|
-
{/each}
|
|
74
|
-
{/if}
|
|
75
|
-
</div>
|
|
76
|
-
{/snippet}
|
|
77
|
-
|
|
78
|
-
<div class="body-outer">
|
|
79
|
-
{@render children()}
|
|
80
|
-
</div>
|
|
81
|
-
|
|
82
|
-
{#if isLoading}
|
|
83
|
-
<LoadingOverlay
|
|
84
|
-
absolute
|
|
85
|
-
message={loadingMessage}
|
|
86
|
-
/>
|
|
87
|
-
{/if}
|
|
88
|
-
</Modal>
|
|
89
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script lang="ts">import { ColourSet } from "../scss/colours.js";
|
|
4
|
+
import Button from "./Button.svelte";
|
|
5
|
+
import LoadingOverlay from "./LoadingOverlay.svelte";
|
|
6
|
+
import Modal from "./Modal.svelte";
|
|
7
|
+
const { onclose, onsubmit, noscroll, headerLabel, headerSubtitle, buttons, children, isLoading, mandatory, loadingMessage, staticHeight, staticWidth, minWidth, minHeight, width, height } = $props();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<Modal
|
|
11
|
+
{onclose}
|
|
12
|
+
mandatory={mandatory || isLoading}
|
|
13
|
+
{staticHeight}
|
|
14
|
+
{staticWidth}
|
|
15
|
+
{minWidth}
|
|
16
|
+
{minHeight}
|
|
17
|
+
{width}
|
|
18
|
+
{height}
|
|
19
|
+
{noscroll}
|
|
20
|
+
{onsubmit}
|
|
21
|
+
>
|
|
22
|
+
{#snippet header()}
|
|
23
|
+
<div class="outer">
|
|
24
|
+
<div class="column">
|
|
25
|
+
{#if typeof headerLabel === 'string'}
|
|
26
|
+
<h1>{headerLabel}</h1>
|
|
27
|
+
{:else}
|
|
28
|
+
{@render headerLabel()}
|
|
29
|
+
{/if}
|
|
30
|
+
{#if headerSubtitle}
|
|
31
|
+
<div class="one-line">
|
|
32
|
+
<span>{headerSubtitle}</span>
|
|
33
|
+
</div>
|
|
34
|
+
{/if}
|
|
35
|
+
</div>
|
|
36
|
+
<div class="spacer"></div>
|
|
37
|
+
</div>
|
|
38
|
+
{/snippet}
|
|
39
|
+
|
|
40
|
+
{#snippet footer()}
|
|
41
|
+
<div class="footer">
|
|
42
|
+
{#if buttons.length}
|
|
43
|
+
{#each buttons as button (button.label)}
|
|
44
|
+
<div class:left={button.left}>
|
|
45
|
+
<Button
|
|
46
|
+
type={button.type}
|
|
47
|
+
disabled={button.disabled}
|
|
48
|
+
onclick={button.callback}
|
|
49
|
+
colourSet={button.colourSet ??
|
|
50
|
+
(button.type === 'submit' ? ColourSet.Primary : undefined)}>{button.label}</Button
|
|
51
|
+
>
|
|
52
|
+
</div>
|
|
53
|
+
{/each}
|
|
54
|
+
{/if}
|
|
55
|
+
</div>
|
|
56
|
+
{/snippet}
|
|
57
|
+
|
|
58
|
+
<div class="body-outer">
|
|
59
|
+
{@render children()}
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
{#if isLoading}
|
|
63
|
+
<LoadingOverlay
|
|
64
|
+
absolute
|
|
65
|
+
message={loadingMessage}
|
|
66
|
+
/>
|
|
67
|
+
{/if}
|
|
68
|
+
</Modal>
|
|
69
|
+
|
|
90
70
|
<style>.outer {
|
|
91
71
|
padding: 1.5rem;
|
|
92
72
|
display: flex;
|
|
@@ -184,4 +164,4 @@
|
|
|
184
164
|
}
|
|
185
165
|
.outer .spacer {
|
|
186
166
|
flex-grow: 1;
|
|
187
|
-
}</style>
|
|
167
|
+
}</style>
|
|
@@ -1,206 +1,176 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
lang="ts"
|
|
5
|
-
module
|
|
6
|
-
>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
let previousY = 0;
|
|
51
|
-
|
|
52
|
-
// AbortController used to register/clean up window-level
|
|
53
|
-
// `mousemove`/`mouseup`/`touchmove`/`touchend` listeners. Stored in a
|
|
54
|
-
// single ref so a stray `mousedown` cannot leak a second set, and so
|
|
55
|
-
// the cleanup `$effect` below can detach everything on unmount even
|
|
56
|
-
// if the user navigates away mid-drag.
|
|
57
|
-
let dragAbort: AbortController | undefined;
|
|
58
|
-
|
|
59
|
-
onMount(() => {
|
|
60
|
-
setPosition();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
$effect(() => {
|
|
64
|
-
if (!dragging) {
|
|
65
|
-
const selectedPosition =
|
|
66
|
-
selected != null ? -entries.findIndex((e) => e.value === selected) * OPTION_HEIGHT : 0;
|
|
67
|
-
if (position !== selectedPosition) {
|
|
68
|
-
position = selectedPosition;
|
|
69
|
-
setPosition();
|
|
70
|
-
}
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
module
|
|
6
|
+
>import { Sizing } from "../scss/sizing.js";
|
|
7
|
+
// Pixel height of each dial option. Sourced from `sizing.ts` so the
|
|
8
|
+
// SCSS partial and TS constant stay in sync (see comment at the top
|
|
9
|
+
// of `sizing.ts`).
|
|
10
|
+
const OPTION_HEIGHT = Sizing["$dial-option-height"];
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<script
|
|
14
|
+
lang="ts"
|
|
15
|
+
generics="T"
|
|
16
|
+
>import { onMount } from "svelte";
|
|
17
|
+
let { selected, entries, type, ref = $bindable(), onsubmit, onPrevious, onNext, onchange } = $props();
|
|
18
|
+
// `position`, `offset`, `dragging` must all be `$state` so that the
|
|
19
|
+
// position-syncing `$effect` below re-runs when `dragging` flips back
|
|
20
|
+
// to `false` at the end of a drag. The previous `let` variables were
|
|
21
|
+
// invisible to Svelte's reactivity and made the `$effect`'s firing
|
|
22
|
+
// order depend on `selected` happening to change.
|
|
23
|
+
//
|
|
24
|
+
// `position` initialises to 0; the `$effect` below syncs it to the
|
|
25
|
+
// `selected`-derived position on first run. Reading `selected` /
|
|
26
|
+
// `values` directly in the initialiser would only capture their
|
|
27
|
+
// initial values (svelte warning `state_referenced_locally`), and
|
|
28
|
+
// since the effect already covers that path we keep the initialiser
|
|
29
|
+
// trivial.
|
|
30
|
+
let position = $state(0);
|
|
31
|
+
let offset = $state(0);
|
|
32
|
+
let dragging = $state(false);
|
|
33
|
+
let itemWrapper = $state();
|
|
34
|
+
let previousY = 0;
|
|
35
|
+
// AbortController used to register/clean up window-level
|
|
36
|
+
// `mousemove`/`mouseup`/`touchmove`/`touchend` listeners. Stored in a
|
|
37
|
+
// single ref so a stray `mousedown` cannot leak a second set, and so
|
|
38
|
+
// the cleanup `$effect` below can detach everything on unmount even
|
|
39
|
+
// if the user navigates away mid-drag.
|
|
40
|
+
let dragAbort;
|
|
41
|
+
onMount(() => {
|
|
42
|
+
setPosition();
|
|
43
|
+
});
|
|
44
|
+
$effect(() => {
|
|
45
|
+
if (!dragging) {
|
|
46
|
+
const selectedPosition = selected != null ? -entries.findIndex((e) => e.value === selected) * OPTION_HEIGHT : 0;
|
|
47
|
+
if (position !== selectedPosition) {
|
|
48
|
+
position = selectedPosition;
|
|
49
|
+
setPosition();
|
|
71
50
|
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
// Ensure any in-flight drag listeners are detached on unmount. The
|
|
54
|
+
// listeners would otherwise leak if the component unmounted between
|
|
55
|
+
// `onmousedown` and `onMouseUp` (rare, but possible if the parent
|
|
56
|
+
// modal closes mid-drag).
|
|
57
|
+
$effect(() => () => {
|
|
58
|
+
dragAbort?.abort();
|
|
59
|
+
});
|
|
60
|
+
function onChange(changedData) {
|
|
61
|
+
onchange({
|
|
62
|
+
type,
|
|
63
|
+
changedData
|
|
72
64
|
});
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
function onChange(changedData: T) {
|
|
83
|
-
onchange({
|
|
84
|
-
type,
|
|
85
|
-
changedData,
|
|
86
|
-
});
|
|
65
|
+
}
|
|
66
|
+
function setPosition() {
|
|
67
|
+
if (!itemWrapper) {
|
|
68
|
+
// Silently no-op if the wrapper has not yet mounted. The previous
|
|
69
|
+
// `console.warn` fired during the initial render of every dial
|
|
70
|
+
// and was noise in production logs.
|
|
71
|
+
return;
|
|
87
72
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
73
|
+
// Set transform / transition individually rather than rewriting the
|
|
74
|
+
// full `cssText`. The latter parses the entire declaration string
|
|
75
|
+
// per mousemove (~60 Hz); `setProperty` skips the parse and only
|
|
76
|
+
// updates the named declarations. The `transition-duration` scales
|
|
77
|
+
// with drag inertia, so we still need imperative updates rather
|
|
78
|
+
// than `style:transform={...}` for the dragging case.
|
|
79
|
+
const transitionDuration = `${Math.abs(offset) / 100 + .1}s`;
|
|
80
|
+
itemWrapper.style.setProperty("transition", `transform ${transitionDuration}`);
|
|
81
|
+
itemWrapper.style.setProperty("transform", `translateY(${position}px)`);
|
|
82
|
+
}
|
|
83
|
+
const onmousedown = (event) => {
|
|
84
|
+
previousY = "touches" in event ? event.touches[0].clientY : event.clientY;
|
|
85
|
+
dragging = true;
|
|
86
|
+
// One AbortController per drag. Attached to all four window
|
|
87
|
+
// listeners so a single `controller.abort()` detaches everything.
|
|
88
|
+
dragAbort?.abort();
|
|
89
|
+
dragAbort = new AbortController();
|
|
90
|
+
const { signal } = dragAbort;
|
|
91
|
+
window.addEventListener("mousemove", onMouseMove, { signal });
|
|
92
|
+
window.addEventListener("mouseup", onMouseUp, { signal });
|
|
93
|
+
window.addEventListener("touchmove", onMouseMove, { signal });
|
|
94
|
+
window.addEventListener("touchend", onMouseUp, { signal });
|
|
95
|
+
};
|
|
96
|
+
const onMouseMove = (event) => {
|
|
97
|
+
const clientY = "touches" in event ? event.touches[0].clientY : event.clientY;
|
|
98
|
+
offset = clientY - previousY;
|
|
99
|
+
const maxPosition = -entries.length * OPTION_HEIGHT;
|
|
100
|
+
const _position = position + offset;
|
|
101
|
+
position = Math.max(maxPosition, Math.min(OPTION_HEIGHT, _position));
|
|
102
|
+
previousY = "touches" in event ? event.touches[0].clientY : event.clientY;
|
|
103
|
+
setPosition();
|
|
104
|
+
};
|
|
105
|
+
const onMouseUp = () => {
|
|
106
|
+
const maxPosition = -(entries.length - 1) * OPTION_HEIGHT;
|
|
107
|
+
const rounderPosition = Math.round((position + offset * 5) / OPTION_HEIGHT) * OPTION_HEIGHT;
|
|
108
|
+
const finalPosition = Math.max(maxPosition, Math.min(0, rounderPosition));
|
|
109
|
+
dragging = false;
|
|
110
|
+
position = finalPosition;
|
|
111
|
+
dragAbort?.abort();
|
|
112
|
+
dragAbort = undefined;
|
|
113
|
+
setPosition();
|
|
114
|
+
onChange(entries[-finalPosition / OPTION_HEIGHT].value);
|
|
115
|
+
};
|
|
116
|
+
const onwheel = (e) => {
|
|
117
|
+
if (e.deltaY > 0) {
|
|
118
|
+
position = position - OPTION_HEIGHT;
|
|
106
119
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const maxPosition = -entries.length * OPTION_HEIGHT;
|
|
129
|
-
const _position = position + offset;
|
|
130
|
-
position = Math.max(maxPosition, Math.min(OPTION_HEIGHT, _position));
|
|
131
|
-
previousY = 'touches' in event ? event.touches[0].clientY : event.clientY;
|
|
132
|
-
setPosition();
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
const onMouseUp = () => {
|
|
136
|
-
const maxPosition = -(entries.length - 1) * OPTION_HEIGHT;
|
|
137
|
-
const rounderPosition = Math.round((position + offset * 5) / OPTION_HEIGHT) * OPTION_HEIGHT;
|
|
138
|
-
const finalPosition = Math.max(maxPosition, Math.min(0, rounderPosition));
|
|
139
|
-
|
|
140
|
-
dragging = false;
|
|
141
|
-
position = finalPosition;
|
|
142
|
-
|
|
143
|
-
dragAbort?.abort();
|
|
144
|
-
dragAbort = undefined;
|
|
145
|
-
|
|
146
|
-
setPosition();
|
|
147
|
-
onChange(entries[-finalPosition / OPTION_HEIGHT].value);
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
const onwheel = (e: WheelEvent) => {
|
|
151
|
-
if (e.deltaY > 0) {
|
|
152
|
-
position = position - OPTION_HEIGHT;
|
|
153
|
-
}
|
|
154
|
-
if (e.deltaY < 0) {
|
|
120
|
+
if (e.deltaY < 0) {
|
|
121
|
+
position = position + OPTION_HEIGHT;
|
|
122
|
+
}
|
|
123
|
+
onMouseUp();
|
|
124
|
+
};
|
|
125
|
+
const handledKeys = new Set([
|
|
126
|
+
"ArrowLeft",
|
|
127
|
+
"ArrowRight",
|
|
128
|
+
"ArrowUp",
|
|
129
|
+
"ArrowDown",
|
|
130
|
+
"Enter"
|
|
131
|
+
]);
|
|
132
|
+
function onkeydown(e) {
|
|
133
|
+
if (handledKeys.has(e.key)) {
|
|
134
|
+
e.preventDefault();
|
|
135
|
+
if (e.key === "ArrowLeft") {
|
|
136
|
+
onPrevious(type);
|
|
137
|
+
} else if (e.key === "ArrowRight") {
|
|
138
|
+
onNext(type);
|
|
139
|
+
} else if (e.key === "ArrowUp") {
|
|
155
140
|
position = position + OPTION_HEIGHT;
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (handledKeys.has(e.key)) {
|
|
163
|
-
e.preventDefault();
|
|
164
|
-
|
|
165
|
-
if (e.key === 'ArrowLeft') {
|
|
166
|
-
onPrevious(type);
|
|
167
|
-
} else if (e.key === 'ArrowRight') {
|
|
168
|
-
onNext(type);
|
|
169
|
-
} else if (e.key === 'ArrowUp') {
|
|
170
|
-
position = position + OPTION_HEIGHT;
|
|
171
|
-
onMouseUp();
|
|
172
|
-
} else if (e.key === 'ArrowDown') {
|
|
173
|
-
position = position - OPTION_HEIGHT;
|
|
174
|
-
onMouseUp();
|
|
175
|
-
} else if (e.key === 'Enter') {
|
|
176
|
-
onsubmit();
|
|
177
|
-
}
|
|
141
|
+
onMouseUp();
|
|
142
|
+
} else if (e.key === "ArrowDown") {
|
|
143
|
+
position = position - OPTION_HEIGHT;
|
|
144
|
+
onMouseUp();
|
|
145
|
+
} else if (e.key === "Enter") {
|
|
146
|
+
onsubmit();
|
|
178
147
|
}
|
|
179
148
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
{
|
|
188
|
-
|
|
189
|
-
{
|
|
190
|
-
{
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
</div>
|
|
203
|
-
|
|
149
|
+
}
|
|
150
|
+
</script>
|
|
151
|
+
|
|
152
|
+
<div
|
|
153
|
+
class="select-wrapper"
|
|
154
|
+
role="listbox"
|
|
155
|
+
tabindex="0"
|
|
156
|
+
bind:this={ref}
|
|
157
|
+
{onmousedown}
|
|
158
|
+
ontouchstart={onmousedown}
|
|
159
|
+
{onwheel}
|
|
160
|
+
{onkeydown}
|
|
161
|
+
>
|
|
162
|
+
<div class="selected-wrapper">
|
|
163
|
+
<ul
|
|
164
|
+
bind:this={itemWrapper}
|
|
165
|
+
class="touch-date-container"
|
|
166
|
+
>
|
|
167
|
+
{#each entries as entry (entry.value)}
|
|
168
|
+
<li>{entry.label}</li>
|
|
169
|
+
{/each}
|
|
170
|
+
</ul>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
|
|
204
174
|
<style>.select-wrapper {
|
|
205
175
|
--option-height: 50px;
|
|
206
176
|
height: calc(var(--option-height));
|
|
@@ -262,4 +232,4 @@
|
|
|
262
232
|
width: 80px;
|
|
263
233
|
height: var(--option-height);
|
|
264
234
|
user-select: none;
|
|
265
|
-
}</style>
|
|
235
|
+
}</style>
|