@torpor/ui 1.0.1 → 1.1.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.
- package/dist/ColorPicker/ColorPicker.torp +36 -75
- package/dist/ColorPicker/ColorPickerInput.torp +122 -0
- package/dist/ColorPicker/ColorPickerTypes.ts +12 -0
- package/dist/ColorPicker/index.d.ts +40 -1
- package/dist/ColorPicker/index.js +2 -1
- package/dist/CommandPalette/CommandPalette.torp +49 -47
- package/dist/CommandPalette/CommandPaletteInput.torp +51 -0
- package/dist/CommandPalette/CommandPaletteItem.torp +62 -0
- package/dist/CommandPalette/CommandPaletteList.torp +55 -0
- package/dist/CommandPalette/CommandPaletteTypes.ts +32 -0
- package/dist/CommandPalette/index.d.ts +88 -2
- package/dist/CommandPalette/index.js +4 -1
- package/dist/DataGrid/DataGrid.torp +22 -22
- package/dist/DataGrid/DataGridCell.torp +50 -0
- package/dist/DataGrid/DataGridColumnHeader.torp +54 -0
- package/dist/DataGrid/DataGridTypes.ts +17 -0
- package/dist/DataGrid/index.d.ts +57 -2
- package/dist/DataGrid/index.js +3 -2
- package/dist/DatePicker/DatePicker.torp +45 -65
- package/dist/DatePicker/DatePickerContent.torp +82 -0
- package/dist/DatePicker/DatePickerTrigger.torp +56 -0
- package/dist/DatePicker/DatePickerTypes.ts +36 -0
- package/dist/DatePicker/index.d.ts +61 -2
- package/dist/DatePicker/index.js +3 -1
- package/dist/DateRangePicker/DateRangePicker.torp +52 -76
- package/dist/DateRangePicker/DateRangePickerContent.torp +90 -0
- package/dist/DateRangePicker/DateRangePickerTrigger.torp +59 -0
- package/dist/DateRangePicker/DateRangePickerTypes.ts +41 -0
- package/dist/DateRangePicker/index.d.ts +61 -2
- package/dist/DateRangePicker/index.js +3 -1
- package/dist/Progress/Progress.torp +24 -14
- package/dist/Progress/ProgressIndicator.torp +52 -0
- package/dist/Progress/ProgressTypes.ts +8 -0
- package/dist/Progress/index.d.ts +34 -1
- package/dist/Progress/index.js +2 -1
- package/dist/Rating/Rating.torp +41 -37
- package/dist/Rating/RatingStar.torp +71 -0
- package/dist/Rating/RatingTypes.ts +22 -0
- package/dist/Rating/index.d.ts +39 -1
- package/dist/Rating/index.js +2 -1
- package/dist/Slider/Slider.torp +48 -63
- package/dist/Slider/SliderHandle.torp +107 -0
- package/dist/Slider/SliderRange.torp +36 -0
- package/dist/Slider/SliderTypes.ts +34 -0
- package/dist/Slider/index.d.ts +65 -1
- package/dist/Slider/index.js +3 -1
- package/dist/TagInput/TagInput.torp +63 -84
- package/dist/TagInput/TagInputField.torp +68 -0
- package/dist/TagInput/TagInputSuggestions.torp +79 -0
- package/dist/TagInput/TagInputTag.torp +55 -0
- package/dist/TagInput/TagInputTypes.ts +42 -0
- package/dist/TagInput/index.d.ts +93 -1
- package/dist/TagInput/index.js +4 -1
- package/dist/TimePicker/TimePicker.torp +88 -85
- package/dist/TimePicker/TimePickerPart.torp +61 -0
- package/dist/TimePicker/TimePickerPeriod.torp +48 -0
- package/dist/TimePicker/TimePickerTypes.ts +37 -0
- package/dist/TimePicker/index.d.ts +61 -1
- package/dist/TimePicker/index.js +3 -1
- package/package.json +7 -7
|
@@ -7,6 +7,13 @@ import {
|
|
|
7
7
|
} from "../Form/FormTypes";
|
|
8
8
|
import FormValues from "../Form/FormValues.torp";
|
|
9
9
|
import createFormField from "../utils/formField";
|
|
10
|
+
import TimePickerPart from "./TimePickerPart.torp";
|
|
11
|
+
import TimePickerPeriod from "./TimePickerPeriod.torp";
|
|
12
|
+
import {
|
|
13
|
+
type Part,
|
|
14
|
+
type TimePickerContext,
|
|
15
|
+
TimePickerContextName,
|
|
16
|
+
} from "./TimePickerTypes";
|
|
10
17
|
|
|
11
18
|
interface TimePickerProps {
|
|
12
19
|
/** An ID for the root element */
|
|
@@ -40,8 +47,6 @@ interface TimePickerProps {
|
|
|
40
47
|
onchange?: (value: string | undefined) => void;
|
|
41
48
|
}
|
|
42
49
|
|
|
43
|
-
type Part = "hour" | "minute" | "second";
|
|
44
|
-
|
|
45
50
|
const PAD = [2, 2, 2];
|
|
46
51
|
|
|
47
52
|
/**
|
|
@@ -52,12 +57,23 @@ const PAD = [2, 2, 2];
|
|
|
52
57
|
*
|
|
53
58
|
* The value is always the canonical 24-hour form ("HH:mm" or "HH:mm:ss"),
|
|
54
59
|
* regardless of display format.
|
|
60
|
+
*
|
|
61
|
+
* The structure of a TimePicker is:
|
|
62
|
+
*
|
|
63
|
+
* ```
|
|
64
|
+
* <TimePicker>
|
|
65
|
+
* <TimePickerPart part="hour" />
|
|
66
|
+
* <TimePickerPart part="minute" />
|
|
67
|
+
* <TimePickerPart part="second" /> (optional)
|
|
68
|
+
* <TimePickerPeriod /> (in 12-hour mode)
|
|
69
|
+
* </TimePicker>
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* With no children, the segments are rendered automatically.
|
|
55
73
|
*/
|
|
56
74
|
export default function TimePicker($props: TimePickerProps | undefined) {
|
|
57
|
-
|
|
58
|
-
let
|
|
59
|
-
let secondInput: HTMLInputElement;
|
|
60
|
-
let periodButton: HTMLButtonElement;
|
|
75
|
+
const partInputs = new Map<Part, HTMLInputElement>();
|
|
76
|
+
let periodButton: HTMLButtonElement | undefined;
|
|
61
77
|
|
|
62
78
|
// Wire up the enclosing Form and Field, if any
|
|
63
79
|
const form = createFormField(
|
|
@@ -106,7 +122,9 @@ export default function TimePicker($props: TimePickerProps | undefined) {
|
|
|
106
122
|
let $state = $watch({
|
|
107
123
|
value: undefined as string | undefined,
|
|
108
124
|
|
|
109
|
-
// The text being typed in each segment; committed on completion
|
|
125
|
+
// The text being typed in each segment; committed on completion.
|
|
126
|
+
// Cleared by every commit, so a non-empty buffer always means
|
|
127
|
+
// uncommitted typing that sync must not overwrite.
|
|
110
128
|
hourText: "",
|
|
111
129
|
minuteText: "",
|
|
112
130
|
secondText: "",
|
|
@@ -168,6 +186,13 @@ export default function TimePicker($props: TimePickerProps | undefined) {
|
|
|
168
186
|
return format(n);
|
|
169
187
|
}
|
|
170
188
|
|
|
189
|
+
function getPartLabel(part: Part): string {
|
|
190
|
+
if (part === "hour") {
|
|
191
|
+
return $props?.hour12 ? "Hour (12-hour)" : "Hour";
|
|
192
|
+
}
|
|
193
|
+
return part === "minute" ? "Minute" : "Second";
|
|
194
|
+
}
|
|
195
|
+
|
|
171
196
|
function isPM(): boolean {
|
|
172
197
|
return parts().h >= 12;
|
|
173
198
|
}
|
|
@@ -224,17 +249,22 @@ export default function TimePicker($props: TimePickerProps | undefined) {
|
|
|
224
249
|
if (sync) syncInputs();
|
|
225
250
|
}
|
|
226
251
|
|
|
227
|
-
// Keep segment inputs showing the committed values
|
|
252
|
+
// Keep segment inputs showing the committed values. A segment with
|
|
253
|
+
// uncommitted typing keeps its text; the rest always sync, even when
|
|
254
|
+
// focused -- so moving between segments never freezes their display.
|
|
228
255
|
function syncInputs() {
|
|
256
|
+
const hourInput = partInputs.get("hour");
|
|
257
|
+
const minuteInput = partInputs.get("minute");
|
|
229
258
|
if (!hourInput || !minuteInput) return;
|
|
230
259
|
const editing = (el: HTMLInputElement, buffer: string) =>
|
|
231
|
-
document.activeElement === el &&
|
|
260
|
+
document.activeElement === el && buffer !== "";
|
|
232
261
|
if (!editing(hourInput, $state.hourText)) {
|
|
233
262
|
hourInput.value = partDisplay("hour");
|
|
234
263
|
}
|
|
235
264
|
if (!editing(minuteInput, $state.minuteText)) {
|
|
236
265
|
minuteInput.value = partDisplay("minute");
|
|
237
266
|
}
|
|
267
|
+
const secondInput = partInputs.get("second");
|
|
238
268
|
if (secondInput && !editing(secondInput, $state.secondText)) {
|
|
239
269
|
secondInput.value = partDisplay("second");
|
|
240
270
|
}
|
|
@@ -257,6 +287,7 @@ export default function TimePicker($props: TimePickerProps | undefined) {
|
|
|
257
287
|
// Two digits fills the segment; move on to the next one
|
|
258
288
|
if (text.length >= (PAD[partIndex(part)] ?? 2)) {
|
|
259
289
|
commitBuffer(part, text);
|
|
290
|
+
setBuffer(part, "");
|
|
260
291
|
focusNextSegment(part);
|
|
261
292
|
}
|
|
262
293
|
}
|
|
@@ -333,9 +364,9 @@ export default function TimePicker($props: TimePickerProps | undefined) {
|
|
|
333
364
|
|
|
334
365
|
function focusNextSegment(part: Part) {
|
|
335
366
|
if (part === "hour") {
|
|
336
|
-
|
|
367
|
+
partInputs.get("minute")?.focus();
|
|
337
368
|
} else if (part === "minute" && getSeconds()) {
|
|
338
|
-
|
|
369
|
+
partInputs.get("second")?.focus();
|
|
339
370
|
} else if (part === "minute" && $props?.hour12) {
|
|
340
371
|
periodButton?.focus();
|
|
341
372
|
}
|
|
@@ -361,18 +392,50 @@ export default function TimePicker($props: TimePickerProps | undefined) {
|
|
|
361
392
|
}
|
|
362
393
|
}
|
|
363
394
|
|
|
364
|
-
function
|
|
395
|
+
function getPartValue(part: Part): number {
|
|
365
396
|
const p = parts();
|
|
366
397
|
return part === "hour" ? p.h : part === "minute" ? p.m : p.s;
|
|
367
398
|
}
|
|
368
399
|
|
|
369
|
-
function
|
|
400
|
+
function getPartText(part: Part): string {
|
|
370
401
|
if (part === "hour" && $props?.hour12) {
|
|
371
402
|
return `${partDisplay("hour")} ${isPM() ? "PM" : "AM"}`;
|
|
372
403
|
}
|
|
373
|
-
return String(
|
|
404
|
+
return String(getPartValue(part));
|
|
374
405
|
}
|
|
375
406
|
|
|
407
|
+
// Set the context to pass down to the segments and the period toggle
|
|
408
|
+
let context: TimePickerContext = {
|
|
409
|
+
getDisabled,
|
|
410
|
+
getPartLabel,
|
|
411
|
+
getPartValue,
|
|
412
|
+
getPartText,
|
|
413
|
+
partDisplay,
|
|
414
|
+
handleInput,
|
|
415
|
+
handleBlur,
|
|
416
|
+
handleSegmentKey,
|
|
417
|
+
registerPart: (part, el) => {
|
|
418
|
+
partInputs.set(part, el);
|
|
419
|
+
},
|
|
420
|
+
unregisterPart: (part, el) => {
|
|
421
|
+
if (partInputs.get(part) === el) {
|
|
422
|
+
partInputs.delete(part);
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
isPM,
|
|
426
|
+
togglePeriod,
|
|
427
|
+
handlePeriodKey,
|
|
428
|
+
registerPeriod: (el) => {
|
|
429
|
+
periodButton = el;
|
|
430
|
+
},
|
|
431
|
+
unregisterPeriod: (el) => {
|
|
432
|
+
if (periodButton === el) {
|
|
433
|
+
periodButton = undefined;
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
};
|
|
437
|
+
$context[TimePickerContextName] = context;
|
|
438
|
+
|
|
376
439
|
@render {
|
|
377
440
|
<div
|
|
378
441
|
id={$props?.id}
|
|
@@ -383,78 +446,18 @@ export default function TimePicker($props: TimePickerProps | undefined) {
|
|
|
383
446
|
data-valid={form.valid ? "valid" : "invalid"}
|
|
384
447
|
aria-describedby={form.messageId}
|
|
385
448
|
>
|
|
386
|
-
<
|
|
387
|
-
|
|
388
|
-
class="torp-time-picker-part"
|
|
389
|
-
type="text"
|
|
390
|
-
inputmode="numeric"
|
|
391
|
-
role="spinbutton"
|
|
392
|
-
value={partDisplay("hour")}
|
|
393
|
-
aria-label={$props?.hour12 ? "Hour (12-hour)" : "Hour"}
|
|
394
|
-
aria-valuemin={0}
|
|
395
|
-
aria-valuemax={23}
|
|
396
|
-
aria-valuenow={ariaNow("hour")}
|
|
397
|
-
aria-valuetext={ariaText("hour")}
|
|
398
|
-
disabled={getDisabled()}
|
|
399
|
-
tabindex={getDisabled() ? -1 : 0}
|
|
400
|
-
oninput={(e: Event) => handleInput("hour", e)}
|
|
401
|
-
onblur={(e: FocusEvent) => handleBlur("hour", e)}
|
|
402
|
-
onkeydown={(e: KeyboardEvent) => handleSegmentKey("hour", e)}
|
|
403
|
-
/>
|
|
404
|
-
<span class="torp-time-picker-separator">:</span>
|
|
405
|
-
<input
|
|
406
|
-
&ref={minuteInput}
|
|
407
|
-
class="torp-time-picker-part"
|
|
408
|
-
type="text"
|
|
409
|
-
inputmode="numeric"
|
|
410
|
-
role="spinbutton"
|
|
411
|
-
value={partDisplay("minute")}
|
|
412
|
-
aria-label="Minute"
|
|
413
|
-
aria-valuemin={0}
|
|
414
|
-
aria-valuemax={59}
|
|
415
|
-
aria-valuenow={ariaNow("minute")}
|
|
416
|
-
aria-valuetext={ariaText("minute")}
|
|
417
|
-
disabled={getDisabled()}
|
|
418
|
-
tabindex={getDisabled() ? -1 : 0}
|
|
419
|
-
oninput={(e: Event) => handleInput("minute", e)}
|
|
420
|
-
onblur={(e: FocusEvent) => handleBlur("minute", e)}
|
|
421
|
-
onkeydown={(e: KeyboardEvent) => handleSegmentKey("minute", e)}
|
|
422
|
-
/>
|
|
423
|
-
@if (getSeconds()) {
|
|
449
|
+
<slot>
|
|
450
|
+
<TimePickerPart part="hour" />
|
|
424
451
|
<span class="torp-time-picker-separator">:</span>
|
|
425
|
-
<
|
|
426
|
-
|
|
427
|
-
class="torp-time-picker-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
aria-valuemax={59}
|
|
435
|
-
aria-valuenow={ariaNow("second")}
|
|
436
|
-
aria-valuetext={ariaText("second")}
|
|
437
|
-
disabled={getDisabled()}
|
|
438
|
-
tabindex={getDisabled() ? -1 : 0}
|
|
439
|
-
oninput={(e: Event) => handleInput("second", e)}
|
|
440
|
-
onblur={(e: FocusEvent) => handleBlur("second", e)}
|
|
441
|
-
onkeydown={(e: KeyboardEvent) => handleSegmentKey("second", e)}
|
|
442
|
-
/>
|
|
443
|
-
}
|
|
444
|
-
@if ($props?.hour12) {
|
|
445
|
-
<button
|
|
446
|
-
&ref={periodButton}
|
|
447
|
-
type="button"
|
|
448
|
-
class="torp-time-picker-period"
|
|
449
|
-
disabled={getDisabled()}
|
|
450
|
-
tabindex={getDisabled() ? -1 : 0}
|
|
451
|
-
aria-label={isPM() ? "PM" : "AM"}
|
|
452
|
-
onclick={togglePeriod}
|
|
453
|
-
onkeydown={handlePeriodKey}
|
|
454
|
-
>
|
|
455
|
-
{isPM() ? "PM" : "AM"}
|
|
456
|
-
</button>
|
|
457
|
-
}
|
|
452
|
+
<TimePickerPart part="minute" />
|
|
453
|
+
@if (getSeconds()) {
|
|
454
|
+
<span class="torp-time-picker-separator">:</span>
|
|
455
|
+
<TimePickerPart part="second" />
|
|
456
|
+
}
|
|
457
|
+
@if ($props?.hour12) {
|
|
458
|
+
<TimePickerPeriod />
|
|
459
|
+
}
|
|
460
|
+
</slot>
|
|
458
461
|
</div>
|
|
459
462
|
|
|
460
463
|
<FormValues name={form.name} value={$state.value} />
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { ClassValue, StyleValue } from "@torpor/view";
|
|
2
|
+
import { type Part, type TimePickerContext, TimePickerContextName } from "./TimePickerTypes";
|
|
3
|
+
|
|
4
|
+
interface TimePickerPartProps {
|
|
5
|
+
/** An ID for the segment element */
|
|
6
|
+
id?: string;
|
|
7
|
+
/** Classes for the segment element */
|
|
8
|
+
class?: ClassValue;
|
|
9
|
+
/** Styles for the segment element */
|
|
10
|
+
style?: StyleValue;
|
|
11
|
+
/** Which segment this is: the hour, minute or second field */
|
|
12
|
+
part: Part;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* One spinbutton segment of a TimePicker -- the hour, minute or second
|
|
17
|
+
* field. Each segment can be typed into or stepped with the arrow keys.
|
|
18
|
+
*/
|
|
19
|
+
export default function TimePickerPart($props: TimePickerPartProps | undefined) {
|
|
20
|
+
// Get stuff out of the TimePicker context
|
|
21
|
+
const context = $context[TimePickerContextName] as TimePickerContext;
|
|
22
|
+
if (!context) {
|
|
23
|
+
throw new Error("TimePickerPart must be contained within a TimePicker");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getPart(): Part {
|
|
27
|
+
return $props?.part ?? "hour";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function getDisabled(): boolean {
|
|
31
|
+
return context.getDisabled();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@render {
|
|
35
|
+
<input
|
|
36
|
+
{$props?.id}
|
|
37
|
+
class={["torp-time-picker-part", $props?.class]}
|
|
38
|
+
{$props?.style}
|
|
39
|
+
type="text"
|
|
40
|
+
inputmode="numeric"
|
|
41
|
+
role="spinbutton"
|
|
42
|
+
value={context.partDisplay(getPart())}
|
|
43
|
+
aria-label={context.getPartLabel(getPart())}
|
|
44
|
+
aria-valuemin={0}
|
|
45
|
+
aria-valuemax={getPart() === "hour" ? 23 : 59}
|
|
46
|
+
aria-valuenow={context.getPartValue(getPart())}
|
|
47
|
+
aria-valuetext={context.getPartText(getPart())}
|
|
48
|
+
disabled={getDisabled()}
|
|
49
|
+
tabindex={getDisabled() ? -1 : 0}
|
|
50
|
+
oninput={(e: Event) => context.handleInput(getPart(), e)}
|
|
51
|
+
onblur={(e: FocusEvent) => context.handleBlur(getPart(), e)}
|
|
52
|
+
onkeydown={(e: KeyboardEvent) => context.handleSegmentKey(getPart(), e)}
|
|
53
|
+
onmount={(el) => {
|
|
54
|
+
context.registerPart(getPart(), el);
|
|
55
|
+
return () => {
|
|
56
|
+
context.unregisterPart(getPart(), el);
|
|
57
|
+
};
|
|
58
|
+
}}
|
|
59
|
+
/>
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ClassValue, StyleValue } from "@torpor/view";
|
|
2
|
+
import { type TimePickerContext, TimePickerContextName } from "./TimePickerTypes";
|
|
3
|
+
|
|
4
|
+
interface TimePickerPeriodProps {
|
|
5
|
+
/** An ID for the period element */
|
|
6
|
+
id?: string;
|
|
7
|
+
/** Classes for the period element */
|
|
8
|
+
class?: ClassValue;
|
|
9
|
+
/** Styles for the period element */
|
|
10
|
+
style?: StyleValue;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The AM/PM toggle of a TimePicker, shown in 12-hour mode.
|
|
15
|
+
*/
|
|
16
|
+
export default function TimePickerPeriod($props: TimePickerPeriodProps | undefined) {
|
|
17
|
+
// Get stuff out of the TimePicker context
|
|
18
|
+
const context = $context[TimePickerContextName] as TimePickerContext;
|
|
19
|
+
if (!context) {
|
|
20
|
+
throw new Error("TimePickerPeriod must be contained within a TimePicker");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getDisabled(): boolean {
|
|
24
|
+
return context.getDisabled();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@render {
|
|
28
|
+
<button
|
|
29
|
+
{$props?.id}
|
|
30
|
+
type="button"
|
|
31
|
+
class={["torp-time-picker-period", $props?.class]}
|
|
32
|
+
{$props?.style}
|
|
33
|
+
disabled={getDisabled()}
|
|
34
|
+
tabindex={getDisabled() ? -1 : 0}
|
|
35
|
+
aria-label={context.isPM() ? "PM" : "AM"}
|
|
36
|
+
onclick={() => context.togglePeriod()}
|
|
37
|
+
onkeydown={context.handlePeriodKey}
|
|
38
|
+
onmount={(el) => {
|
|
39
|
+
context.registerPeriod(el);
|
|
40
|
+
return () => {
|
|
41
|
+
context.unregisterPeriod(el);
|
|
42
|
+
};
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
{context.isPM() ? "PM" : "AM"}
|
|
46
|
+
</button>
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export const TimePickerContextName: unique symbol = Symbol.for("torp.TimePicker");
|
|
2
|
+
|
|
3
|
+
/** One of the spinbutton segments of a TimePicker */
|
|
4
|
+
export type Part = "hour" | "minute" | "second";
|
|
5
|
+
|
|
6
|
+
export interface TimePickerContext {
|
|
7
|
+
/** Whether the user cannot interact with the time picker */
|
|
8
|
+
getDisabled: () => boolean;
|
|
9
|
+
/** The accessible name for a segment */
|
|
10
|
+
getPartLabel: (part: Part) => string;
|
|
11
|
+
/** A segment's value, for aria-valuenow */
|
|
12
|
+
getPartValue: (part: Part) => number;
|
|
13
|
+
/** A segment's value as announced, for aria-valuetext */
|
|
14
|
+
getPartText: (part: Part) => string;
|
|
15
|
+
/** The text displayed in a segment */
|
|
16
|
+
partDisplay: (part: Part) => string;
|
|
17
|
+
/** Handles typing in a segment */
|
|
18
|
+
handleInput: (part: Part, e: Event) => void;
|
|
19
|
+
/** Handles a segment losing focus */
|
|
20
|
+
handleBlur: (part: Part, e: FocusEvent) => void;
|
|
21
|
+
/** Handles arrow/Home/End/Enter keys in a segment */
|
|
22
|
+
handleSegmentKey: (part: Part, e: KeyboardEvent) => void;
|
|
23
|
+
/** Called from a segment when it is added */
|
|
24
|
+
registerPart: (part: Part, el: HTMLInputElement) => void;
|
|
25
|
+
/** Called from a segment when it is removed */
|
|
26
|
+
unregisterPart: (part: Part, el: HTMLInputElement) => void;
|
|
27
|
+
/** Whether the current time is in the PM half of the day */
|
|
28
|
+
isPM: () => boolean;
|
|
29
|
+
/** Toggles between AM and PM */
|
|
30
|
+
togglePeriod: () => void;
|
|
31
|
+
/** Handles arrow keys on the period toggle */
|
|
32
|
+
handlePeriodKey: (e: KeyboardEvent) => void;
|
|
33
|
+
/** Called from the period toggle when it is added */
|
|
34
|
+
registerPeriod: (el: HTMLButtonElement) => void;
|
|
35
|
+
/** Called from the period toggle when it is removed */
|
|
36
|
+
unregisterPeriod: (el: HTMLButtonElement) => void;
|
|
37
|
+
}
|
|
@@ -41,6 +41,19 @@ interface TimePickerProps {
|
|
|
41
41
|
*
|
|
42
42
|
* The value is always the canonical 24-hour form ("HH:mm" or "HH:mm:ss"),
|
|
43
43
|
* regardless of display format.
|
|
44
|
+
*
|
|
45
|
+
* The structure of a TimePicker is:
|
|
46
|
+
*
|
|
47
|
+
* ```
|
|
48
|
+
* <TimePicker>
|
|
49
|
+
* <TimePickerPart part="hour" />
|
|
50
|
+
* <TimePickerPart part="minute" />
|
|
51
|
+
* <TimePickerPart part="second" /> (optional)
|
|
52
|
+
* <TimePickerPeriod /> (in 12-hour mode)
|
|
53
|
+
* </TimePicker>
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* With no children, the segments are rendered automatically.
|
|
44
57
|
*/
|
|
45
58
|
declare function TimePicker(
|
|
46
59
|
$parent: ParentNode,
|
|
@@ -50,4 +63,51 @@ declare function TimePicker(
|
|
|
50
63
|
$slots?: Record<string, SlotRender>,
|
|
51
64
|
): void;
|
|
52
65
|
|
|
53
|
-
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
interface TimePickerPartProps {
|
|
69
|
+
/** An ID for the segment element */
|
|
70
|
+
id?: string;
|
|
71
|
+
/** Classes for the segment element */
|
|
72
|
+
class?: ClassValue;
|
|
73
|
+
/** Styles for the segment element */
|
|
74
|
+
style?: StyleValue;
|
|
75
|
+
/** Which segment this is: the hour, minute or second field */
|
|
76
|
+
part: Part;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* One spinbutton segment of a TimePicker -- the hour, minute or second
|
|
81
|
+
* field. Each segment can be typed into or stepped with the arrow keys.
|
|
82
|
+
*/
|
|
83
|
+
declare function TimePickerPart(
|
|
84
|
+
$parent: ParentNode,
|
|
85
|
+
$anchor: Node | null,
|
|
86
|
+
$props: TimePickerPartProps | undefined,
|
|
87
|
+
$context?: Record<PropertyKey, any>,
|
|
88
|
+
$slots?: Record<string, SlotRender>,
|
|
89
|
+
): void;
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
interface TimePickerPeriodProps {
|
|
94
|
+
/** An ID for the period element */
|
|
95
|
+
id?: string;
|
|
96
|
+
/** Classes for the period element */
|
|
97
|
+
class?: ClassValue;
|
|
98
|
+
/** Styles for the period element */
|
|
99
|
+
style?: StyleValue;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The AM/PM toggle of a TimePicker, shown in 12-hour mode.
|
|
104
|
+
*/
|
|
105
|
+
declare function TimePickerPeriod(
|
|
106
|
+
$parent: ParentNode,
|
|
107
|
+
$anchor: Node | null,
|
|
108
|
+
$props: TimePickerPeriodProps | undefined,
|
|
109
|
+
$context?: Record<PropertyKey, any>,
|
|
110
|
+
$slots?: Record<string, SlotRender>,
|
|
111
|
+
): void;
|
|
112
|
+
|
|
113
|
+
export { TimePicker, TimePickerPart, TimePickerPeriod };
|
package/dist/TimePicker/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@torpor/ui",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Accessible, unstyled components for use in your Torpor front-end",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -179,8 +179,8 @@
|
|
|
179
179
|
"author": "",
|
|
180
180
|
"license": "ISC",
|
|
181
181
|
"dependencies": {
|
|
182
|
-
"@torpor/
|
|
183
|
-
"@torpor/
|
|
182
|
+
"@torpor/view": "^1.0.3",
|
|
183
|
+
"@torpor/unplugin": "^1.0.3"
|
|
184
184
|
},
|
|
185
185
|
"devDependencies": {
|
|
186
186
|
"@testing-library/dom": "^10.4.1",
|
|
@@ -193,11 +193,11 @@
|
|
|
193
193
|
"jsdom": "^30.0.1",
|
|
194
194
|
"tsx": "^4.23.5",
|
|
195
195
|
"typescript": "^7.0.2",
|
|
196
|
-
"vite": "npm:@voidzero-dev/vite-plus-core@0.
|
|
197
|
-
"vite-plus": "0.
|
|
196
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@0.3.0",
|
|
197
|
+
"vite-plus": "0.3.0",
|
|
198
198
|
"zod": "^4.4.3",
|
|
199
|
-
"@torpor/prettier": "^1.0.
|
|
200
|
-
"@torpor/check": "^1.0.
|
|
199
|
+
"@torpor/prettier": "^1.0.3",
|
|
200
|
+
"@torpor/check": "^1.0.3"
|
|
201
201
|
},
|
|
202
202
|
"scripts": {
|
|
203
203
|
"build": "tsgo --noEmit && vp pack",
|