@juspay/svelte-ui-components 2.67.0 → 2.69.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.
|
@@ -6,6 +6,16 @@
|
|
|
6
6
|
import Button from '../Button/Button.svelte';
|
|
7
7
|
import chevronDownSvg from '../assets/chevron-down.svg?raw';
|
|
8
8
|
import checkmarkSvg from '../assets/checkmark.svg?raw';
|
|
9
|
+
import chevronRightSvg from '../assets/chevron-right.svg?raw';
|
|
10
|
+
import {
|
|
11
|
+
TIME_DISPLAY_PATTERN,
|
|
12
|
+
applyTimeDisplay,
|
|
13
|
+
formatTimeDisplay,
|
|
14
|
+
toMinutesOfDay
|
|
15
|
+
} from './timeUtils';
|
|
16
|
+
|
|
17
|
+
const clockSvg =
|
|
18
|
+
'<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" r="6.25" stroke="currentColor" stroke-width="1.5"/><path d="M8 4.5V8l2.25 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>';
|
|
9
19
|
|
|
10
20
|
let {
|
|
11
21
|
rangeStart = $bindable(null),
|
|
@@ -18,6 +28,8 @@
|
|
|
18
28
|
maxRangeDays = null,
|
|
19
29
|
presets = null,
|
|
20
30
|
presetCheckmark = false,
|
|
31
|
+
showDateInputs = false,
|
|
32
|
+
showTimeSelection = false,
|
|
21
33
|
placeholder = 'Select date',
|
|
22
34
|
dualMonth,
|
|
23
35
|
timePicker,
|
|
@@ -58,6 +70,14 @@
|
|
|
58
70
|
// made a custom calendar selection (or before any selection is made).
|
|
59
71
|
let selectedPresetLabel: string | null = $state(null);
|
|
60
72
|
|
|
73
|
+
// Built-in time-of-day selection (opt-in via showTimeSelection). Display strings
|
|
74
|
+
// are 12-hour ("02:30 PM"); they seed from the draft dates when the picker opens
|
|
75
|
+
// and are combined back onto the committed range in handleApply. showTimeRow drives
|
|
76
|
+
// the collapsible time inputs, toggled by the clock button in the date-input row.
|
|
77
|
+
let startTimeDisplay: string = $state('12:00 AM');
|
|
78
|
+
let endTimeDisplay: string = $state('11:59 PM');
|
|
79
|
+
let showTimeRow: boolean = $state(false);
|
|
80
|
+
|
|
61
81
|
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
62
82
|
|
|
63
83
|
function isBaseDisabledDate(date: Date): boolean {
|
|
@@ -170,6 +190,29 @@
|
|
|
170
190
|
return d.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });
|
|
171
191
|
}
|
|
172
192
|
|
|
193
|
+
// Read-only date-input box contents (opt-in via showDateInputs), reflecting the draft.
|
|
194
|
+
const draftStartDateLabel: string = $derived(draftStart !== null ? formatDate(draftStart) : '');
|
|
195
|
+
const draftEndDateLabel: string = $derived(draftEnd !== null ? formatDate(draftEnd) : '');
|
|
196
|
+
|
|
197
|
+
const isStartTimeValid: boolean = $derived(TIME_DISPLAY_PATTERN.test(startTimeDisplay.trim()));
|
|
198
|
+
const isEndTimeValid: boolean = $derived(TIME_DISPLAY_PATTERN.test(endTimeDisplay.trim()));
|
|
199
|
+
// Apply is blocked while a time is malformed, or while both ends fall on the same
|
|
200
|
+
// calendar day and the start time is after the end time. Different days are fine.
|
|
201
|
+
const isTimeRangeValid: boolean = $derived.by(() => {
|
|
202
|
+
if (!showTimeSelection) {
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
if (!isStartTimeValid || !isEndTimeValid) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
if (draftStart === null || draftEnd === null || !isSameDay(draftStart, draftEnd)) {
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
const startMinutes = toMinutesOfDay(startTimeDisplay);
|
|
212
|
+
const endMinutes = toMinutesOfDay(endTimeDisplay);
|
|
213
|
+
return startMinutes === null || endMinutes === null || startMinutes <= endMinutes;
|
|
214
|
+
});
|
|
215
|
+
|
|
173
216
|
const triggerLabel: string = $derived.by(() => {
|
|
174
217
|
// If an initial preset label is active (seeded on mount, not yet overridden), show it
|
|
175
218
|
if (activePresetLabel !== null) {
|
|
@@ -206,6 +249,14 @@
|
|
|
206
249
|
// by label. A direct calendar click later clears this, reverting to date matching.
|
|
207
250
|
selectedPresetLabel = committedPresetLabel;
|
|
208
251
|
|
|
252
|
+
// Seed the time inputs from the committed range's time-of-day, and collapse the
|
|
253
|
+
// time row so each open starts from the date view.
|
|
254
|
+
if (showTimeSelection) {
|
|
255
|
+
startTimeDisplay = draftStart !== null ? formatTimeDisplay(draftStart) : '12:00 AM';
|
|
256
|
+
endTimeDisplay = draftEnd !== null ? formatTimeDisplay(draftEnd) : '11:59 PM';
|
|
257
|
+
showTimeRow = false;
|
|
258
|
+
}
|
|
259
|
+
|
|
209
260
|
// Navigate left calendar so it shows the committed start month (or today)
|
|
210
261
|
const anchor = rangeStart !== null ? rangeStart : value !== null ? value : now;
|
|
211
262
|
leftYear = anchor.getFullYear();
|
|
@@ -273,10 +324,21 @@
|
|
|
273
324
|
activePresetLabel = null;
|
|
274
325
|
if (mode === 'range') {
|
|
275
326
|
if (draftStart !== null && draftEnd !== null) {
|
|
276
|
-
|
|
277
|
-
|
|
327
|
+
// Fold the time-of-day inputs onto the committed dates when time selection is on.
|
|
328
|
+
const appliedStart = showTimeSelection
|
|
329
|
+
? (applyTimeDisplay(draftStart, startTimeDisplay) ?? draftStart)
|
|
330
|
+
: draftStart;
|
|
331
|
+
const appliedEnd = showTimeSelection
|
|
332
|
+
? (applyTimeDisplay(draftEnd, endTimeDisplay) ?? draftEnd)
|
|
333
|
+
: draftEnd;
|
|
334
|
+
rangeStart = appliedStart;
|
|
335
|
+
rangeEnd = appliedEnd;
|
|
278
336
|
committedPresetLabel = selectedPresetLabel;
|
|
279
|
-
onapply?.({
|
|
337
|
+
onapply?.({
|
|
338
|
+
rangeStart: appliedStart,
|
|
339
|
+
rangeEnd: appliedEnd,
|
|
340
|
+
presetLabel: selectedPresetLabel
|
|
341
|
+
});
|
|
280
342
|
}
|
|
281
343
|
if (
|
|
282
344
|
typeof compareCalendar === 'function' &&
|
|
@@ -389,7 +451,7 @@
|
|
|
389
451
|
|
|
390
452
|
const canApply: boolean = $derived.by(() => {
|
|
391
453
|
if (mode === 'range') {
|
|
392
|
-
return draftStart !== null && draftEnd !== null;
|
|
454
|
+
return draftStart !== null && draftEnd !== null && isTimeRangeValid;
|
|
393
455
|
}
|
|
394
456
|
return draftValue !== null;
|
|
395
457
|
});
|
|
@@ -578,6 +640,68 @@
|
|
|
578
640
|
|
|
579
641
|
<!-- Calendar area -->
|
|
580
642
|
<div class="drp-calendars">
|
|
643
|
+
{#if (showDateInputs || showTimeSelection) && mode === 'range'}
|
|
644
|
+
<div class="drp-datetime-header">
|
|
645
|
+
<div class="drp-date-input-row">
|
|
646
|
+
<div class="drp-date-input" data-pw={testId ? `${testId}-start-date` : null}>
|
|
647
|
+
<span class="drp-date-input-value">{draftStartDateLabel || 'Start date'}</span>
|
|
648
|
+
</div>
|
|
649
|
+
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
650
|
+
<span class="drp-datetime-arrow" aria-hidden="true">{@html chevronRightSvg}</span>
|
|
651
|
+
<div class="drp-date-input" data-pw={testId ? `${testId}-end-date` : null}>
|
|
652
|
+
<span class="drp-date-input-value">{draftEndDateLabel || 'End date'}</span>
|
|
653
|
+
</div>
|
|
654
|
+
{#if showTimeSelection}
|
|
655
|
+
<button
|
|
656
|
+
type="button"
|
|
657
|
+
class="drp-time-toggle"
|
|
658
|
+
class:drp-time-toggle-active={showTimeRow}
|
|
659
|
+
aria-label="Toggle time selection"
|
|
660
|
+
aria-pressed={showTimeRow}
|
|
661
|
+
data-pw={testId ? `${testId}-time-toggle` : null}
|
|
662
|
+
onclick={() => (showTimeRow = !showTimeRow)}
|
|
663
|
+
>
|
|
664
|
+
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
665
|
+
<span class="drp-time-toggle-icon" aria-hidden="true">{@html clockSvg}</span>
|
|
666
|
+
</button>
|
|
667
|
+
{/if}
|
|
668
|
+
</div>
|
|
669
|
+
{#if showTimeSelection && showTimeRow}
|
|
670
|
+
<div class="drp-time-input-row">
|
|
671
|
+
<div class="drp-time-input" class:drp-time-input-invalid={!isStartTimeValid}>
|
|
672
|
+
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
673
|
+
<span class="drp-time-input-icon" aria-hidden="true">{@html clockSvg}</span>
|
|
674
|
+
<input
|
|
675
|
+
type="text"
|
|
676
|
+
class="drp-time-field"
|
|
677
|
+
bind:value={startTimeDisplay}
|
|
678
|
+
maxlength="8"
|
|
679
|
+
placeholder="12:00 AM"
|
|
680
|
+
aria-label="Start time"
|
|
681
|
+
aria-invalid={!isStartTimeValid}
|
|
682
|
+
data-pw={testId ? `${testId}-start-time` : null}
|
|
683
|
+
/>
|
|
684
|
+
</div>
|
|
685
|
+
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
686
|
+
<span class="drp-datetime-arrow" aria-hidden="true">{@html chevronRightSvg}</span>
|
|
687
|
+
<div class="drp-time-input" class:drp-time-input-invalid={!isEndTimeValid}>
|
|
688
|
+
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
689
|
+
<span class="drp-time-input-icon" aria-hidden="true">{@html clockSvg}</span>
|
|
690
|
+
<input
|
|
691
|
+
type="text"
|
|
692
|
+
class="drp-time-field"
|
|
693
|
+
bind:value={endTimeDisplay}
|
|
694
|
+
maxlength="8"
|
|
695
|
+
placeholder="11:59 PM"
|
|
696
|
+
aria-label="End time"
|
|
697
|
+
aria-invalid={!isEndTimeValid}
|
|
698
|
+
data-pw={testId ? `${testId}-end-time` : null}
|
|
699
|
+
/>
|
|
700
|
+
</div>
|
|
701
|
+
</div>
|
|
702
|
+
{/if}
|
|
703
|
+
</div>
|
|
704
|
+
{/if}
|
|
581
705
|
{#if isDualMonth}
|
|
582
706
|
<!-- Dual-month layout with shared nav -->
|
|
583
707
|
<div class="drp-dual-header">
|
|
@@ -930,6 +1054,132 @@
|
|
|
930
1054
|
flex-wrap: wrap;
|
|
931
1055
|
}
|
|
932
1056
|
|
|
1057
|
+
/* ── Built-in date + time inputs (showDateInputs / showTimeSelection) ── */
|
|
1058
|
+
.drp-datetime-header {
|
|
1059
|
+
display: flex;
|
|
1060
|
+
flex-direction: column;
|
|
1061
|
+
gap: var(--drp-datetime-gap, 8px);
|
|
1062
|
+
padding-bottom: var(--drp-datetime-padding-bottom, 12px);
|
|
1063
|
+
margin-bottom: var(--drp-datetime-margin-bottom, 4px);
|
|
1064
|
+
border-bottom: var(--drp-datetime-divider, 1px solid #e8e8e8);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
.drp-date-input-row,
|
|
1068
|
+
.drp-time-input-row {
|
|
1069
|
+
display: flex;
|
|
1070
|
+
align-items: center;
|
|
1071
|
+
gap: var(--drp-datetime-row-gap, 12px);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
.drp-date-input {
|
|
1075
|
+
flex: 1;
|
|
1076
|
+
min-width: 0;
|
|
1077
|
+
padding: var(--drp-date-input-padding, 10px 14px);
|
|
1078
|
+
border: var(--drp-date-input-border, 1px solid #d4d4d4);
|
|
1079
|
+
border-radius: var(--drp-date-input-radius, 8px);
|
|
1080
|
+
background: var(--drp-date-input-background, #ffffff);
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
.drp-date-input-value {
|
|
1084
|
+
display: block;
|
|
1085
|
+
color: var(--drp-date-input-color, #333333);
|
|
1086
|
+
font-size: var(--drp-date-input-font-size, 13px);
|
|
1087
|
+
white-space: nowrap;
|
|
1088
|
+
overflow: hidden;
|
|
1089
|
+
text-overflow: ellipsis;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
.drp-datetime-arrow {
|
|
1093
|
+
flex-shrink: 0;
|
|
1094
|
+
display: inline-flex;
|
|
1095
|
+
width: var(--drp-datetime-arrow-size, 16px);
|
|
1096
|
+
height: var(--drp-datetime-arrow-size, 16px);
|
|
1097
|
+
color: var(--drp-datetime-arrow-color, #888888);
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
.drp-datetime-arrow :global(svg) {
|
|
1101
|
+
width: 100%;
|
|
1102
|
+
height: 100%;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
.drp-time-toggle {
|
|
1106
|
+
flex-shrink: 0;
|
|
1107
|
+
display: inline-flex;
|
|
1108
|
+
align-items: center;
|
|
1109
|
+
justify-content: center;
|
|
1110
|
+
width: var(--drp-time-toggle-size, 40px);
|
|
1111
|
+
height: var(--drp-time-toggle-size, 40px);
|
|
1112
|
+
padding: 0;
|
|
1113
|
+
border: var(--drp-time-toggle-border, 1px solid #d4d4d4);
|
|
1114
|
+
border-radius: var(--drp-time-toggle-radius, 8px);
|
|
1115
|
+
background: var(--drp-time-toggle-background, #f6f7f9);
|
|
1116
|
+
color: var(--drp-time-toggle-color, #555555);
|
|
1117
|
+
cursor: pointer;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
.drp-time-toggle-active {
|
|
1121
|
+
border-color: var(--drp-time-toggle-active-border, currentColor);
|
|
1122
|
+
color: var(--drp-time-toggle-active-color, #1b85ff);
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
.drp-time-toggle-icon {
|
|
1126
|
+
display: inline-flex;
|
|
1127
|
+
width: var(--drp-time-toggle-icon-size, 16px);
|
|
1128
|
+
height: var(--drp-time-toggle-icon-size, 16px);
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
.drp-time-toggle-icon :global(svg) {
|
|
1132
|
+
width: 100%;
|
|
1133
|
+
height: 100%;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
.drp-time-input {
|
|
1137
|
+
position: relative;
|
|
1138
|
+
flex: 1;
|
|
1139
|
+
min-width: 0;
|
|
1140
|
+
display: flex;
|
|
1141
|
+
align-items: center;
|
|
1142
|
+
border: var(--drp-time-input-border, 1px solid #d4d4d4);
|
|
1143
|
+
border-radius: var(--drp-time-input-radius, 8px);
|
|
1144
|
+
background: var(--drp-time-input-background, #ffffff);
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
.drp-time-input-invalid {
|
|
1148
|
+
border-color: var(--drp-time-input-invalid-border, #e5484d);
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
.drp-time-input-icon {
|
|
1152
|
+
display: inline-flex;
|
|
1153
|
+
flex-shrink: 0;
|
|
1154
|
+
width: var(--drp-time-input-icon-size, 16px);
|
|
1155
|
+
height: var(--drp-time-input-icon-size, 16px);
|
|
1156
|
+
margin-left: var(--drp-time-input-icon-gap, 12px);
|
|
1157
|
+
color: var(--drp-time-input-icon-color, #888888);
|
|
1158
|
+
pointer-events: none;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
.drp-time-input-icon :global(svg) {
|
|
1162
|
+
width: 100%;
|
|
1163
|
+
height: 100%;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
.drp-time-field {
|
|
1167
|
+
flex: 1;
|
|
1168
|
+
min-width: 0;
|
|
1169
|
+
width: 100%;
|
|
1170
|
+
padding: var(--drp-time-field-padding, 10px 14px 10px 8px);
|
|
1171
|
+
border: none;
|
|
1172
|
+
outline: none;
|
|
1173
|
+
background: transparent;
|
|
1174
|
+
color: var(--drp-time-field-color, #333333);
|
|
1175
|
+
font-size: var(--drp-time-field-font-size, 13px);
|
|
1176
|
+
font-family: inherit;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
.drp-time-field::placeholder {
|
|
1180
|
+
color: var(--drp-time-field-placeholder-color, #aaaaaa);
|
|
1181
|
+
}
|
|
1182
|
+
|
|
933
1183
|
/* ── Compare calendar slot ── */
|
|
934
1184
|
.drp-compare-section {
|
|
935
1185
|
display: flex;
|
|
@@ -40,6 +40,18 @@ export type OptionalDateRangePickerProperties = {
|
|
|
40
40
|
* its highlighted background regardless of this flag. Default: false.
|
|
41
41
|
*/
|
|
42
42
|
presetCheckmark?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Show read-only start/end date boxes at the top of the calendar area (range mode),
|
|
45
|
+
* reflecting the current draft selection. Opt-in. Default: false.
|
|
46
|
+
*/
|
|
47
|
+
showDateInputs?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Show built-in time-of-day selection (range mode): a clock toggle in the date-input
|
|
50
|
+
* row that reveals start/end time inputs ("HH:MM AM/PM"). On Apply the entered times
|
|
51
|
+
* are folded onto the committed range's start/end. Implies the date-input row.
|
|
52
|
+
* Opt-in. Default: false.
|
|
53
|
+
*/
|
|
54
|
+
showTimeSelection?: boolean;
|
|
43
55
|
/** Placeholder shown when no range is selected. */
|
|
44
56
|
placeholder?: string;
|
|
45
57
|
/** Show two months side by side. Defaults to true for range mode, false for single. */
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Matches a 12-hour clock display such as "2:30 PM" or "02:05 am". */
|
|
2
|
+
export declare const TIME_DISPLAY_PATTERN: RegExp;
|
|
3
|
+
/** Parse a 12-hour display string into 24-hour hours/minutes, or null when invalid. */
|
|
4
|
+
export declare const parseTimeDisplay: (display: string) => {
|
|
5
|
+
hours: number;
|
|
6
|
+
minutes: number;
|
|
7
|
+
} | null;
|
|
8
|
+
/** Format a Date's time-of-day as a 12-hour display string, e.g. "02:30 PM". */
|
|
9
|
+
export declare const formatTimeDisplay: (date: Date) => string;
|
|
10
|
+
/** Return a new Date with the time-of-day from a 12-hour display string applied, or null when invalid. */
|
|
11
|
+
export declare const applyTimeDisplay: (date: Date, display: string) => Date | null;
|
|
12
|
+
/** Minutes-since-midnight for ordering comparisons, or null when the display is invalid. */
|
|
13
|
+
export declare const toMinutesOfDay: (display: string) => number | null;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Time-of-day helpers for the DateRangePicker's built-in date + time inputs.
|
|
2
|
+
/** Matches a 12-hour clock display such as "2:30 PM" or "02:05 am". */
|
|
3
|
+
export const TIME_DISPLAY_PATTERN = /^(1[0-2]|0?[1-9]):([0-5][0-9])\s?(AM|PM)$/i;
|
|
4
|
+
const pad = (n) => n.toString().padStart(2, '0');
|
|
5
|
+
/** Parse a 12-hour display string into 24-hour hours/minutes, or null when invalid. */
|
|
6
|
+
export const parseTimeDisplay = (display) => {
|
|
7
|
+
const match = TIME_DISPLAY_PATTERN.exec(display.trim());
|
|
8
|
+
if (match === null) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
let hours = Number(match[1]);
|
|
12
|
+
const minutes = Number(match[2]);
|
|
13
|
+
const meridiem = match[3].toUpperCase();
|
|
14
|
+
if (meridiem === 'PM' && hours !== 12) {
|
|
15
|
+
hours += 12;
|
|
16
|
+
}
|
|
17
|
+
else if (meridiem === 'AM' && hours === 12) {
|
|
18
|
+
hours = 0;
|
|
19
|
+
}
|
|
20
|
+
return { hours, minutes };
|
|
21
|
+
};
|
|
22
|
+
/** Format a Date's time-of-day as a 12-hour display string, e.g. "02:30 PM". */
|
|
23
|
+
export const formatTimeDisplay = (date) => {
|
|
24
|
+
const hours24 = date.getHours();
|
|
25
|
+
const meridiem = hours24 >= 12 ? 'PM' : 'AM';
|
|
26
|
+
const hours12 = hours24 % 12 === 0 ? 12 : hours24 % 12;
|
|
27
|
+
return `${pad(hours12)}:${pad(date.getMinutes())} ${meridiem}`;
|
|
28
|
+
};
|
|
29
|
+
/** Return a new Date with the time-of-day from a 12-hour display string applied, or null when invalid. */
|
|
30
|
+
export const applyTimeDisplay = (date, display) => {
|
|
31
|
+
const parsed = parseTimeDisplay(display);
|
|
32
|
+
if (parsed === null) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const next = new Date(date.getTime());
|
|
36
|
+
next.setHours(parsed.hours, parsed.minutes, 0, 0);
|
|
37
|
+
return next;
|
|
38
|
+
};
|
|
39
|
+
/** Minutes-since-midnight for ordering comparisons, or null when the display is invalid. */
|
|
40
|
+
export const toMinutesOfDay = (display) => {
|
|
41
|
+
const parsed = parseTimeDisplay(display);
|
|
42
|
+
return parsed === null ? null : parsed.hours * 60 + parsed.minutes;
|
|
43
|
+
};
|
package/dist/Modal/Modal.svelte
CHANGED
|
@@ -335,6 +335,19 @@
|
|
|
335
335
|
--cursor: var(--modal-footer-secondary-button-cursor, pointer);
|
|
336
336
|
--opacity: var(--modal-footer-secondary-button-opacity, 1);
|
|
337
337
|
--button-border: var(--modal-footer-secondary-button-border, none);
|
|
338
|
+
--disabled-background-color: var(
|
|
339
|
+
--modal-footer-secondary-button-disabled-color,
|
|
340
|
+
var(--modal-footer-secondary-button-color, #3a4550)
|
|
341
|
+
);
|
|
342
|
+
--disabled-text-color: var(
|
|
343
|
+
--modal-footer-secondary-button-disabled-text-color,
|
|
344
|
+
var(--modal-footer-secondary-button-text-color, white)
|
|
345
|
+
);
|
|
346
|
+
--disabled-border: var(
|
|
347
|
+
--modal-footer-secondary-button-disabled-border,
|
|
348
|
+
var(--modal-footer-secondary-button-border, none)
|
|
349
|
+
);
|
|
350
|
+
--disabled-opacity: var(--modal-footer-secondary-button-disabled-opacity, 0.4);
|
|
338
351
|
--button-justify-content: var(--modal-footer-secondary-button-justify-content, center);
|
|
339
352
|
--button-content-flex-direction: var(
|
|
340
353
|
--modal-footer-secondary-button-content-flex-direction,
|
|
@@ -363,6 +376,19 @@
|
|
|
363
376
|
--cursor: var(--modal-footer-primary-button-cursor, pointer);
|
|
364
377
|
--opacity: var(--modal-footer-primary-button-opacity, 1);
|
|
365
378
|
--button-border: var(--modal-footer-primary-button-border, none);
|
|
379
|
+
--disabled-background-color: var(
|
|
380
|
+
--modal-footer-primary-button-disabled-color,
|
|
381
|
+
var(--modal-footer-primary-button-color, #3a4550)
|
|
382
|
+
);
|
|
383
|
+
--disabled-text-color: var(
|
|
384
|
+
--modal-footer-primary-button-disabled-text-color,
|
|
385
|
+
var(--modal-footer-primary-button-text-color, white)
|
|
386
|
+
);
|
|
387
|
+
--disabled-border: var(
|
|
388
|
+
--modal-footer-primary-button-disabled-border,
|
|
389
|
+
var(--modal-footer-primary-button-border, none)
|
|
390
|
+
);
|
|
391
|
+
--disabled-opacity: var(--modal-footer-primary-button-disabled-opacity, 0.4);
|
|
366
392
|
--button-justify-content: var(--modal-footer-primary-button-justify-content, center);
|
|
367
393
|
--button-content-flex-direction: var(--modal-footer-primary-button-content-flex-direction, row);
|
|
368
394
|
--button-content-gap: var(--modal-footer-primary-button-content-gap, 16px);
|