@warkypublic/svelix 0.1.46 → 0.2.1
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 +93 -33
- package/dist/components/BetterMenu/BetterMenu.svelte +21 -37
- package/dist/components/BetterMenu/BetterMenuAsyncButton.svelte +21 -31
- package/dist/components/BetterMenu/BetterMenuPreview.svelte +27 -29
- package/dist/components/BetterMenu/MenuRenderer.svelte +40 -51
- package/dist/components/Boxer/Boxer.svelte +492 -602
- package/dist/components/Boxer/BoxerTarget.svelte +6 -46
- package/dist/components/Boxer/BoxerTarget.svelte.d.ts +1 -0
- package/dist/components/Boxer/types.d.ts +0 -1
- package/dist/components/Button.svelte +19 -43
- package/dist/components/ButtonPreview.svelte +2 -11
- package/dist/components/CardGrid/CardGrid.svelte +489 -614
- package/dist/components/CardGrid/CardGrid.svelte.d.ts +4 -0
- package/dist/components/CardGrid/CardGridFilterPanel.svelte +111 -90
- package/dist/components/CardGrid/DefaultCard.svelte +86 -97
- package/dist/components/CardGrid/DefaultCard.svelte.d.ts +1 -0
- package/dist/components/CardGrid/ImageCardStory.svelte +87 -36
- package/dist/components/CardGrid/cardGrid.d.ts +24 -0
- package/dist/components/CardGrid/cardGrid.js +20 -0
- package/dist/components/ContentEditor/CollaboraInsertTextDemo.svelte +5 -10
- package/dist/components/ContentEditor/ContentEditor.svelte +24 -50
- package/dist/components/ContentEditor/subcomponents/AudioPlayer.svelte +17 -17
- package/dist/components/ContentEditor/subcomponents/CollaboraEditor.svelte +244 -309
- package/dist/components/ContentEditor/subcomponents/EmailViewer.svelte +2 -3
- package/dist/components/ContentEditor/subcomponents/ImageViewer.svelte +14 -15
- package/dist/components/ContentEditor/subcomponents/MarkdownViewer.svelte +74 -90
- package/dist/components/ContentEditor/subcomponents/MonacoEditor.svelte +75 -103
- package/dist/components/ContentEditor/subcomponents/Office365Editor.svelte +234 -297
- package/dist/components/ContentEditor/subcomponents/PdfViewer.svelte +14 -20
- package/dist/components/ContentEditor/subcomponents/TextEditor.svelte +122 -150
- package/dist/components/ContentEditor/subcomponents/UnknownFile.svelte +105 -126
- package/dist/components/ContentEditor/subcomponents/VideoPlayer.svelte +17 -17
- package/dist/components/ContentEditor/subcomponents/ZipViewer.svelte +2 -3
- package/dist/components/ErrorBoundary/ErrorBoundary.svelte +41 -58
- package/dist/components/ErrorBoundary/ErrorBoundaryPreview.svelte +8 -16
- package/dist/components/Former/Former.svelte +306 -424
- package/dist/components/Former/FormerButtonArea.svelte +17 -68
- package/dist/components/Former/FormerDrawer.svelte +16 -80
- package/dist/components/Former/FormerDrawerPreview.svelte +99 -89
- package/dist/components/Former/FormerModal.svelte +16 -74
- package/dist/components/Former/FormerModalPreview.svelte +99 -89
- package/dist/components/Former/FormerPreview.svelte +76 -78
- package/dist/components/Former/FormerRestApiPreview.svelte +55 -48
- package/dist/components/Former/formerOverlayHelpers.svelte.d.ts +11 -0
- package/dist/components/Former/formerOverlayHelpers.svelte.js +38 -0
- package/dist/components/Former/index.d.ts +1 -0
- package/dist/components/Former/index.js +1 -0
- package/dist/components/FormerControllers/ButtonCtrl.svelte +13 -49
- package/dist/components/FormerControllers/CtrlFieldShell.svelte +15 -0
- package/dist/components/FormerControllers/CtrlFieldShell.svelte.d.ts +12 -0
- package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrl.svelte +285 -457
- package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrlCalendar.svelte +95 -136
- package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrlPickerPanel.svelte +3 -62
- package/dist/components/FormerControllers/DateTimeCtrl/DateTimeCtrlTimeFields.svelte +143 -217
- package/dist/components/FormerControllers/IconButtonCtrl.svelte +13 -47
- package/dist/components/FormerControllers/InlineWrapper.svelte +12 -41
- package/dist/components/FormerControllers/InlineWrapperPreview.svelte +4 -26
- package/dist/components/FormerControllers/NativeSelectCtrl.svelte +7 -39
- package/dist/components/FormerControllers/NumberInputCtrl.svelte +21 -43
- package/dist/components/FormerControllers/PasswordInputCtrl.svelte +8 -33
- package/dist/components/FormerControllers/SwitchCtrl.svelte +4 -20
- package/dist/components/FormerControllers/TextAreaCtrl.svelte +7 -34
- package/dist/components/FormerControllers/TextInputCtrl.svelte +7 -34
- package/dist/components/FormerControllers/ctrlLoading.svelte.d.ts +8 -0
- package/dist/components/FormerControllers/ctrlLoading.svelte.js +43 -0
- package/dist/components/FormerControllers/index.d.ts +2 -0
- package/dist/components/FormerControllers/index.js +2 -0
- package/dist/components/FormerControllers/utils.d.ts +1 -0
- package/dist/components/FormerControllers/utils.js +3 -0
- package/dist/components/GlobalStateStore/GlobalStateStoreProvider.svelte +73 -120
- package/dist/components/Gridler/components/Gridler.svelte +344 -442
- package/dist/components/Gridler/components/GridlerCanvas.svelte +720 -1115
- package/dist/components/Gridler/components/GridlerEditor.svelte +2 -15
- package/dist/components/Gridler/components/GridlerFull.svelte +521 -841
- package/dist/components/Gridler/components/GridlerFull.svelte.d.ts +1 -1
- package/dist/components/Gridler/components/GridlerFullWithFormerPreview.svelte +194 -147
- package/dist/components/Gridler/components/GridlerSearch.svelte +7 -16
- package/dist/components/Gridler/components/GridlerSearchToggle.svelte +7 -19
- package/dist/components/Gridler/types.d.ts +1 -1
- package/dist/components/Gridler/utils/serverPaging.d.ts +1 -0
- package/dist/components/Gridler/utils/serverPaging.js +7 -0
- package/dist/components/Icons/IconAdd.svelte +1 -3
- package/dist/components/Icons/IconAlertCircle.svelte +1 -3
- package/dist/components/Icons/IconAlertTriangle.svelte +1 -3
- package/dist/components/Icons/IconCamera.svelte +1 -3
- package/dist/components/Icons/IconClose.svelte +1 -3
- package/dist/components/Icons/IconEdit.svelte +1 -3
- package/dist/components/Icons/IconFilter.svelte +1 -3
- package/dist/components/Icons/IconSearch.svelte +1 -3
- package/dist/components/Icons/IconSort.svelte +1 -3
- package/dist/components/Icons/IconTrash.svelte +1 -3
- package/dist/components/Portal/Portal.svelte +14 -38
- package/dist/components/Screenshot/Screenshot.svelte +7 -13
- package/dist/components/Svark/Svark.svelte +680 -852
- package/dist/components/Svark/SvarkContextMenu.svelte +44 -63
- package/dist/components/Svark/SvarkInfiniteLoader.svelte +2 -6
- package/dist/components/Svark/SvarkPager.svelte +2 -28
- package/dist/components/Svark/SvarkSelectionDemo.svelte +4 -8
- package/dist/components/Svark/SvarkTopBar.svelte +9 -74
- package/dist/components/SvarkGrid/SvarkGrid.svelte +877 -1123
- package/dist/components/SvarkGrid/components/SvarkColumnFilterForm.svelte +45 -58
- package/dist/components/SvarkGrid/components/SvarkContextMenu.svelte +44 -63
- package/dist/components/SvarkGrid/components/SvarkHeaderFilterCell.svelte +41 -75
- package/dist/components/SvarkGrid/components/SvarkInfiniteLoader.svelte +2 -6
- package/dist/components/SvarkGrid/components/SvarkPager.svelte +2 -28
- package/dist/components/SvarkGrid/components/SvarkSearchPopover.svelte +8 -16
- package/dist/components/SvarkGrid/components/SvarkTopBar.svelte +6 -62
- package/dist/components/SvarkGrid/internal/SvarkGridView.svelte +345 -507
- package/dist/components/VTree/VTree.svelte +454 -431
- package/dist/components/VTree/VTree.utils.d.ts +23 -0
- package/dist/components/VTree/VTree.utils.js +73 -0
- package/dist/components/VTree/VTreeContextMenu.svelte +21 -33
- package/dist/components/VTree/VTreeControlledSelectionDemo.svelte +20 -0
- package/dist/components/VTree/VTreeControlledSelectionDemo.svelte.d.ts +18 -0
- package/dist/components/VTree/VTreeCustomizationDemo.svelte +23 -0
- package/dist/components/VTree/VTreeCustomizationDemo.svelte.d.ts +18 -0
- package/dist/components/VTree/VTreeEventsDemo.svelte +48 -58
- package/dist/components/VTree/VTreeInteractionDemo.svelte +29 -0
- package/dist/components/VTree/VTreeInteractionDemo.svelte.d.ts +18 -0
- package/dist/components/VTree/VTreeMultiSelectDemo.svelte +27 -0
- package/dist/components/VTree/VTreeMultiSelectDemo.svelte.d.ts +18 -0
- package/dist/components/VTree/VTreeRow.svelte +77 -115
- package/dist/components/VTree/VTreeRow.svelte.d.ts +34 -18
- package/dist/components/VTree/VTreeSearch.svelte +6 -13
- package/dist/components/VTree/VTreeVirtualViewport.svelte +54 -143
- package/dist/components/VTree/VTreeVirtualViewport.svelte.d.ts +35 -18
- package/dist/components/VTree/types.d.ts +39 -1
- package/llm/COMPONENT_GUIDE.md +25 -0
- package/package.json +51 -50
|
@@ -1,139 +1,98 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (event.key === 'ArrowUp') {
|
|
99
|
-
event.preventDefault();
|
|
100
|
-
focusFromIndex(index, -7);
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (event.key === 'Home') {
|
|
105
|
-
event.preventDefault();
|
|
106
|
-
focusFirstAvailable();
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (event.altKey && event.key === 'PageUp') {
|
|
111
|
-
event.preventDefault();
|
|
112
|
-
for (let i = 0; i < 12; i += 1) {
|
|
113
|
-
onPrev?.();
|
|
114
|
-
}
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (event.altKey && event.key === 'PageDown') {
|
|
119
|
-
event.preventDefault();
|
|
120
|
-
for (let i = 0; i < 12; i += 1) {
|
|
121
|
-
onNext?.();
|
|
122
|
-
}
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (event.key === 'PageUp') {
|
|
127
|
-
event.preventDefault();
|
|
128
|
-
onPrev?.();
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (event.key === 'PageDown') {
|
|
133
|
-
event.preventDefault();
|
|
134
|
-
onNext?.();
|
|
135
|
-
}
|
|
136
|
-
}
|
|
1
|
+
<script lang="ts">import { WEEKDAY_LABELS } from "./DateTimeCtrl.utils";
|
|
2
|
+
let { cells, isDateSelectable, monthLabel, onNext, onPrev, onSelect, selectedIso } = $props();
|
|
3
|
+
function isCellDisabled(cell) {
|
|
4
|
+
if (!cell.inCurrentMonth) {
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
if (!isDateSelectable) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
return !isDateSelectable(cell.isoDate);
|
|
11
|
+
}
|
|
12
|
+
function focusFirstAvailable() {
|
|
13
|
+
if (typeof document === "undefined") {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const first = cells.find((cell) => !isCellDisabled(cell));
|
|
17
|
+
if (!first) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const target = document.querySelector(`button[data-iso="${first.isoDate}"]`);
|
|
21
|
+
target?.focus();
|
|
22
|
+
}
|
|
23
|
+
function focusFromIndex(startIndex, step) {
|
|
24
|
+
if (typeof document === "undefined") {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
let index = startIndex + step;
|
|
28
|
+
while (index >= 0 && index < cells.length) {
|
|
29
|
+
const nextCell = cells[index];
|
|
30
|
+
if (!isCellDisabled(nextCell)) {
|
|
31
|
+
const target = document.querySelector(`button[data-iso="${nextCell.isoDate}"]`);
|
|
32
|
+
target?.focus();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
index += step;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function handleDayKeydown(event, index, cell) {
|
|
39
|
+
if (isCellDisabled(cell)) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
onSelect?.(cell.isoDate);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (event.key === "ArrowRight") {
|
|
48
|
+
event.preventDefault();
|
|
49
|
+
focusFromIndex(index, 1);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (event.key === "ArrowLeft") {
|
|
53
|
+
event.preventDefault();
|
|
54
|
+
focusFromIndex(index, -1);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (event.key === "ArrowDown") {
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
focusFromIndex(index, 7);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (event.key === "ArrowUp") {
|
|
63
|
+
event.preventDefault();
|
|
64
|
+
focusFromIndex(index, -7);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (event.key === "Home") {
|
|
68
|
+
event.preventDefault();
|
|
69
|
+
focusFirstAvailable();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (event.altKey && event.key === "PageUp") {
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
for (let i = 0; i < 12; i += 1) {
|
|
75
|
+
onPrev?.();
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (event.altKey && event.key === "PageDown") {
|
|
80
|
+
event.preventDefault();
|
|
81
|
+
for (let i = 0; i < 12; i += 1) {
|
|
82
|
+
onNext?.();
|
|
83
|
+
}
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (event.key === "PageUp") {
|
|
87
|
+
event.preventDefault();
|
|
88
|
+
onPrev?.();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (event.key === "PageDown") {
|
|
92
|
+
event.preventDefault();
|
|
93
|
+
onNext?.();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
137
96
|
</script>
|
|
138
97
|
|
|
139
98
|
<div class="w-full min-w-[16.5rem] max-w-[22rem] rounded border border-surface-300-700 bg-surface-100-900 p-2">
|
|
@@ -1,65 +1,6 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import type { CalendarCell } from './DateTimeCtrl.utils';
|
|
5
|
-
|
|
6
|
-
export interface Props {
|
|
7
|
-
amLabel?: string;
|
|
8
|
-
calendarCells?: CalendarCell[];
|
|
9
|
-
calendarMonthLabel?: string;
|
|
10
|
-
hour?: number;
|
|
11
|
-
hoursStep?: number;
|
|
12
|
-
isDateSelectable?: (isoDate: string) => boolean;
|
|
13
|
-
maxDate?: string;
|
|
14
|
-
maxTime?: string;
|
|
15
|
-
minDate?: string;
|
|
16
|
-
minTime?: string;
|
|
17
|
-
minute?: number;
|
|
18
|
-
minutesStep?: number;
|
|
19
|
-
onNow?: () => void;
|
|
20
|
-
onClose?: () => void;
|
|
21
|
-
onSelectCalendarDate?: (isoDate: string) => void;
|
|
22
|
-
onShiftMonth?: (delta: number) => void;
|
|
23
|
-
onTimeChange?: (value: { hour: number; minute: number; second: number }) => void;
|
|
24
|
-
pmLabel?: string;
|
|
25
|
-
presets?: Array<string | { label: string; value: string }>;
|
|
26
|
-
second?: number;
|
|
27
|
-
secondsStep?: number;
|
|
28
|
-
selectedDateIso?: string;
|
|
29
|
-
showDatePicker?: boolean;
|
|
30
|
-
showTimePicker?: boolean;
|
|
31
|
-
use12Hour?: boolean;
|
|
32
|
-
withTimeDropdown?: boolean;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
let {
|
|
36
|
-
amLabel = 'AM',
|
|
37
|
-
calendarCells = [],
|
|
38
|
-
calendarMonthLabel = '',
|
|
39
|
-
hour = 0,
|
|
40
|
-
hoursStep = 1,
|
|
41
|
-
isDateSelectable,
|
|
42
|
-
maxDate,
|
|
43
|
-
maxTime,
|
|
44
|
-
minDate,
|
|
45
|
-
minTime,
|
|
46
|
-
minute = 0,
|
|
47
|
-
minutesStep = 1,
|
|
48
|
-
onNow,
|
|
49
|
-
onClose,
|
|
50
|
-
onSelectCalendarDate,
|
|
51
|
-
onShiftMonth,
|
|
52
|
-
onTimeChange,
|
|
53
|
-
pmLabel = 'PM',
|
|
54
|
-
presets = [],
|
|
55
|
-
second = 0,
|
|
56
|
-
secondsStep = 1,
|
|
57
|
-
selectedDateIso,
|
|
58
|
-
showDatePicker = false,
|
|
59
|
-
showTimePicker = false,
|
|
60
|
-
use12Hour = false,
|
|
61
|
-
withTimeDropdown = false,
|
|
62
|
-
}: Props = $props();
|
|
1
|
+
<script lang="ts">import DateTimeCtrlCalendar from "./DateTimeCtrlCalendar.svelte";
|
|
2
|
+
import DateTimeCtrlTimeFields from "./DateTimeCtrlTimeFields.svelte";
|
|
3
|
+
let { amLabel = "AM", calendarCells = [], calendarMonthLabel = "", hour = 0, hoursStep = 1, isDateSelectable, maxDate, maxTime, minDate, minTime, minute = 0, minutesStep = 1, onNow, onClose, onSelectCalendarDate, onShiftMonth, onTimeChange, pmLabel = "PM", presets = [], second = 0, secondsStep = 1, selectedDateIso, showDatePicker = false, showTimePicker = false, use12Hour = false, withTimeDropdown = false } = $props();
|
|
63
4
|
</script>
|
|
64
5
|
|
|
65
6
|
<div class="flex flex-col gap-3">
|
|
@@ -1,220 +1,146 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
parsedMinute < 0 ||
|
|
145
|
-
parsedMinute > 59 ||
|
|
146
|
-
parsedSecond < 0 ||
|
|
147
|
-
parsedSecond > 59
|
|
148
|
-
) {
|
|
149
|
-
return null;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return {
|
|
153
|
-
hour: parsedHour,
|
|
154
|
-
minute: parsedMinute,
|
|
155
|
-
second: parsedSecond,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function emit(): void {
|
|
160
|
-
const parsedHour = Number(h);
|
|
161
|
-
const parsedMinute = Number(m);
|
|
162
|
-
const parsedSecond = Number(s);
|
|
163
|
-
|
|
164
|
-
if (
|
|
165
|
-
!Number.isFinite(parsedHour) ||
|
|
166
|
-
!Number.isFinite(parsedMinute) ||
|
|
167
|
-
!Number.isFinite(parsedSecond)
|
|
168
|
-
) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const minuteValue = clamp(Math.trunc(parsedMinute), 0, 59);
|
|
173
|
-
const secondValue = clamp(Math.trunc(parsedSecond), 0, 59);
|
|
174
|
-
|
|
175
|
-
let hourValue = clamp(Math.trunc(parsedHour), 0, 23);
|
|
176
|
-
if (use12Hour) {
|
|
177
|
-
hourValue = from12Hour(parsedHour, meridian);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
onChange?.({
|
|
181
|
-
hour: hourValue,
|
|
182
|
-
minute: minuteValue,
|
|
183
|
-
second: secondValue,
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
function applyPreset(preset: string): void {
|
|
188
|
-
const parsed = parsePreset(preset);
|
|
189
|
-
if (!parsed) {
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (use12Hour) {
|
|
194
|
-
const converted = to12Hour(parsed.hour);
|
|
195
|
-
h = String(converted.displayHour);
|
|
196
|
-
meridian = converted.meridian;
|
|
197
|
-
} else {
|
|
198
|
-
h = String(parsed.hour);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
m = String(parsed.minute);
|
|
202
|
-
s = String(parsed.second);
|
|
203
|
-
emit();
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
$effect(() => {
|
|
207
|
-
if (use12Hour) {
|
|
208
|
-
const converted = to12Hour(hour);
|
|
209
|
-
h = String(converted.displayHour);
|
|
210
|
-
meridian = converted.meridian;
|
|
211
|
-
} else {
|
|
212
|
-
h = String(hour);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
m = String(minute);
|
|
216
|
-
s = String(second);
|
|
217
|
-
});
|
|
1
|
+
<script lang="ts">let { amLabel = "AM", hour = 0, hoursStep = 1, maxTime, minTime, minute = 0, minutesStep = 1, onChange, pmLabel = "PM", presets = [], second = 0, secondsStep = 1, use12Hour = false, withDropdown = false } = $props();
|
|
2
|
+
let h = $state("0");
|
|
3
|
+
let m = $state("0");
|
|
4
|
+
let s = $state("0");
|
|
5
|
+
let meridian = $state("am");
|
|
6
|
+
const safeHoursStep = $derived(Math.max(1, Math.trunc(hoursStep || 1)));
|
|
7
|
+
const safeMinutesStep = $derived(Math.max(1, Math.trunc(minutesStep || 1)));
|
|
8
|
+
const safeSecondsStep = $derived(Math.max(1, Math.trunc(secondsStep || 1)));
|
|
9
|
+
const hourOptions = $derived.by(() => {
|
|
10
|
+
const options = [];
|
|
11
|
+
if (use12Hour) {
|
|
12
|
+
for (let i = 1; i <= 12; i += safeHoursStep) {
|
|
13
|
+
options.push(i);
|
|
14
|
+
}
|
|
15
|
+
if (!options.includes(12)) {
|
|
16
|
+
options.push(12);
|
|
17
|
+
}
|
|
18
|
+
return options;
|
|
19
|
+
}
|
|
20
|
+
for (let i = 0; i <= 23; i += safeHoursStep) {
|
|
21
|
+
options.push(i);
|
|
22
|
+
}
|
|
23
|
+
if (!options.includes(23)) {
|
|
24
|
+
options.push(23);
|
|
25
|
+
}
|
|
26
|
+
return options;
|
|
27
|
+
});
|
|
28
|
+
const minuteOptions = $derived.by(() => {
|
|
29
|
+
const options = [];
|
|
30
|
+
for (let i = 0; i <= 59; i += safeMinutesStep) {
|
|
31
|
+
options.push(i);
|
|
32
|
+
}
|
|
33
|
+
if (!options.includes(59)) {
|
|
34
|
+
options.push(59);
|
|
35
|
+
}
|
|
36
|
+
return options;
|
|
37
|
+
});
|
|
38
|
+
const secondOptions = $derived.by(() => {
|
|
39
|
+
const options = [];
|
|
40
|
+
for (let i = 0; i <= 59; i += safeSecondsStep) {
|
|
41
|
+
options.push(i);
|
|
42
|
+
}
|
|
43
|
+
if (!options.includes(59)) {
|
|
44
|
+
options.push(59);
|
|
45
|
+
}
|
|
46
|
+
return options;
|
|
47
|
+
});
|
|
48
|
+
const normalizedPresets = $derived.by(() => {
|
|
49
|
+
return presets.map((preset) => {
|
|
50
|
+
if (typeof preset === "string") {
|
|
51
|
+
return {
|
|
52
|
+
label: preset,
|
|
53
|
+
value: preset
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return preset;
|
|
57
|
+
}).filter((preset) => preset.value && preset.value.trim() !== "");
|
|
58
|
+
});
|
|
59
|
+
function pad2(value) {
|
|
60
|
+
return String(value).padStart(2, "0");
|
|
61
|
+
}
|
|
62
|
+
function clamp(value, min, max) {
|
|
63
|
+
return Math.max(min, Math.min(max, value));
|
|
64
|
+
}
|
|
65
|
+
function to12Hour(inputHour) {
|
|
66
|
+
const isPm = inputHour >= 12;
|
|
67
|
+
const displayHour = inputHour % 12 === 0 ? 12 : inputHour % 12;
|
|
68
|
+
return {
|
|
69
|
+
displayHour,
|
|
70
|
+
meridian: isPm ? "pm" : "am"
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function from12Hour(displayHour, nextMeridian) {
|
|
74
|
+
const normalized = clamp(displayHour, 1, 12) % 12;
|
|
75
|
+
if (nextMeridian === "pm") {
|
|
76
|
+
return normalized + 12;
|
|
77
|
+
}
|
|
78
|
+
return normalized;
|
|
79
|
+
}
|
|
80
|
+
function parsePreset(value) {
|
|
81
|
+
const matched = /^(\d{1,2}):(\d{2})(?::(\d{2}))?$/.exec(value.trim());
|
|
82
|
+
if (!matched) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const parsedHour = Number(matched[1]);
|
|
86
|
+
const parsedMinute = Number(matched[2]);
|
|
87
|
+
const parsedSecond = Number(matched[3] ?? "0");
|
|
88
|
+
if (!Number.isInteger(parsedHour) || !Number.isInteger(parsedMinute) || !Number.isInteger(parsedSecond) || parsedHour < 0 || parsedHour > 23 || parsedMinute < 0 || parsedMinute > 59 || parsedSecond < 0 || parsedSecond > 59) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
hour: parsedHour,
|
|
93
|
+
minute: parsedMinute,
|
|
94
|
+
second: parsedSecond
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function emit() {
|
|
98
|
+
const parsedHour = Number(h);
|
|
99
|
+
const parsedMinute = Number(m);
|
|
100
|
+
const parsedSecond = Number(s);
|
|
101
|
+
if (!Number.isFinite(parsedHour) || !Number.isFinite(parsedMinute) || !Number.isFinite(parsedSecond)) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const minuteValue = clamp(Math.trunc(parsedMinute), 0, 59);
|
|
105
|
+
const secondValue = clamp(Math.trunc(parsedSecond), 0, 59);
|
|
106
|
+
let hourValue = clamp(Math.trunc(parsedHour), 0, 23);
|
|
107
|
+
if (use12Hour) {
|
|
108
|
+
hourValue = from12Hour(parsedHour, meridian);
|
|
109
|
+
}
|
|
110
|
+
onChange?.({
|
|
111
|
+
hour: hourValue,
|
|
112
|
+
minute: minuteValue,
|
|
113
|
+
second: secondValue
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
function applyPreset(preset) {
|
|
117
|
+
const parsed = parsePreset(preset);
|
|
118
|
+
if (!parsed) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (use12Hour) {
|
|
122
|
+
const converted = to12Hour(parsed.hour);
|
|
123
|
+
h = String(converted.displayHour);
|
|
124
|
+
meridian = converted.meridian;
|
|
125
|
+
} else {
|
|
126
|
+
h = String(parsed.hour);
|
|
127
|
+
}
|
|
128
|
+
m = String(parsed.minute);
|
|
129
|
+
s = String(parsed.second);
|
|
130
|
+
emit();
|
|
131
|
+
}
|
|
132
|
+
$effect(() => {
|
|
133
|
+
if (use12Hour) {
|
|
134
|
+
const converted = to12Hour(hour);
|
|
135
|
+
h = String(converted.displayHour);
|
|
136
|
+
meridian = converted.meridian;
|
|
137
|
+
} else {
|
|
138
|
+
h = String(hour);
|
|
139
|
+
}
|
|
140
|
+
m = String(minute);
|
|
141
|
+
s = String(second);
|
|
142
|
+
});
|
|
143
|
+
export {};
|
|
218
144
|
</script>
|
|
219
145
|
|
|
220
146
|
<div class="rounded border border-surface-300-700 bg-surface-100-900 p-2">
|