mithril-materialized 3.6.0 → 3.8.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/analog-clock.d.ts +57 -0
- package/dist/digital-clock.d.ts +48 -0
- package/dist/index.css +201 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.esm.js +1450 -412
- package/dist/index.js +1462 -411
- package/dist/index.min.css +1 -1
- package/dist/index.umd.js +1462 -411
- package/dist/pickers.css +170 -0
- package/dist/select.d.ts +2 -1
- package/dist/time-range-picker.d.ts +51 -0
- package/dist/time-utils.d.ts +17 -0
- package/dist/timepicker.d.ts +11 -0
- package/dist/toggle-button.d.ts +46 -0
- package/dist/toggle-group.d.ts +84 -0
- package/dist/utils.d.ts +3 -10
- package/package.json +1 -1
- package/sass/components/_timepicker.scss +196 -1
- package/sass/components/_toggle-group.scss +36 -0
- package/sass/materialize.scss +1 -0
package/dist/pickers.css
CHANGED
|
@@ -353,12 +353,14 @@
|
|
|
353
353
|
.timepicker-modal {
|
|
354
354
|
max-width: 325px;
|
|
355
355
|
max-height: none;
|
|
356
|
+
overflow: hidden;
|
|
356
357
|
}
|
|
357
358
|
|
|
358
359
|
.timepicker-container.modal-content {
|
|
359
360
|
display: flex;
|
|
360
361
|
flex-direction: column;
|
|
361
362
|
padding: 0;
|
|
363
|
+
overflow: hidden;
|
|
362
364
|
}
|
|
363
365
|
|
|
364
366
|
.text-primary {
|
|
@@ -442,6 +444,10 @@
|
|
|
442
444
|
bottom: 0;
|
|
443
445
|
}
|
|
444
446
|
|
|
447
|
+
.timepicker-dial {
|
|
448
|
+
pointer-events: none;
|
|
449
|
+
}
|
|
450
|
+
|
|
445
451
|
.timepicker-minutes {
|
|
446
452
|
visibility: hidden;
|
|
447
453
|
}
|
|
@@ -456,6 +462,7 @@
|
|
|
456
462
|
position: absolute;
|
|
457
463
|
cursor: pointer;
|
|
458
464
|
font-size: 15px;
|
|
465
|
+
pointer-events: none;
|
|
459
466
|
}
|
|
460
467
|
|
|
461
468
|
.timepicker-tick.active,
|
|
@@ -521,6 +528,169 @@
|
|
|
521
528
|
padding: 0 20px;
|
|
522
529
|
}
|
|
523
530
|
|
|
531
|
+
/* Digital Clock Mode */
|
|
532
|
+
.timepicker-digital-mode {
|
|
533
|
+
padding: 20px;
|
|
534
|
+
display: flex;
|
|
535
|
+
flex-direction: column;
|
|
536
|
+
align-items: center;
|
|
537
|
+
flex: 2.5 auto;
|
|
538
|
+
overflow: hidden;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
.timepicker-digital-clock {
|
|
542
|
+
display: flex;
|
|
543
|
+
align-items: center;
|
|
544
|
+
gap: 8px;
|
|
545
|
+
margin-bottom: 20px;
|
|
546
|
+
user-select: none;
|
|
547
|
+
overflow: hidden;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
.digital-clock-column {
|
|
551
|
+
width: 80px;
|
|
552
|
+
height: 240px;
|
|
553
|
+
overflow-y: scroll;
|
|
554
|
+
overflow-x: hidden;
|
|
555
|
+
scroll-snap-type: y mandatory;
|
|
556
|
+
scrollbar-width: thin;
|
|
557
|
+
scrollbar-color: transparent transparent;
|
|
558
|
+
position: relative;
|
|
559
|
+
}
|
|
560
|
+
.digital-clock-column::-webkit-scrollbar {
|
|
561
|
+
width: 6px;
|
|
562
|
+
}
|
|
563
|
+
.digital-clock-column::-webkit-scrollbar-track {
|
|
564
|
+
background: transparent;
|
|
565
|
+
}
|
|
566
|
+
.digital-clock-column::-webkit-scrollbar-thumb {
|
|
567
|
+
background: transparent;
|
|
568
|
+
border-radius: 3px;
|
|
569
|
+
}
|
|
570
|
+
.digital-clock-column:hover {
|
|
571
|
+
scrollbar-color: rgba(0, 0, 0, 0.3) transparent;
|
|
572
|
+
}
|
|
573
|
+
.digital-clock-column:hover::-webkit-scrollbar-thumb {
|
|
574
|
+
background: rgba(0, 0, 0, 0.3);
|
|
575
|
+
}
|
|
576
|
+
.digital-clock-column:hover::-webkit-scrollbar-thumb:hover {
|
|
577
|
+
background: rgba(0, 0, 0, 0.5);
|
|
578
|
+
}
|
|
579
|
+
.digital-clock-column {
|
|
580
|
+
background: linear-gradient(to bottom, var(--mm-background-color, #fafafa) 0%, transparent 20%, transparent 80%, var(--mm-background-color, #fafafa) 100%);
|
|
581
|
+
}
|
|
582
|
+
.digital-clock-column.ampm-column {
|
|
583
|
+
width: 60px;
|
|
584
|
+
scrollbar-width: none;
|
|
585
|
+
}
|
|
586
|
+
.digital-clock-column.ampm-column::-webkit-scrollbar {
|
|
587
|
+
display: none;
|
|
588
|
+
}
|
|
589
|
+
.digital-clock-column::before, .digital-clock-column::after {
|
|
590
|
+
content: "";
|
|
591
|
+
position: absolute;
|
|
592
|
+
left: 0;
|
|
593
|
+
right: 0;
|
|
594
|
+
height: 1px;
|
|
595
|
+
pointer-events: none;
|
|
596
|
+
z-index: 1;
|
|
597
|
+
background-color: rgba(0, 0, 0, 0.1);
|
|
598
|
+
}
|
|
599
|
+
.digital-clock-column::before {
|
|
600
|
+
top: calc(50% - 24px);
|
|
601
|
+
}
|
|
602
|
+
.digital-clock-column::after {
|
|
603
|
+
top: calc(50% + 24px);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
.digital-clock-item {
|
|
607
|
+
height: 48px;
|
|
608
|
+
display: flex;
|
|
609
|
+
align-items: center;
|
|
610
|
+
justify-content: center;
|
|
611
|
+
font-size: 1.5rem;
|
|
612
|
+
font-weight: 300;
|
|
613
|
+
scroll-snap-align: center;
|
|
614
|
+
cursor: pointer;
|
|
615
|
+
color: rgba(0, 0, 0, 0.4);
|
|
616
|
+
transition: all 0.2s ease;
|
|
617
|
+
}
|
|
618
|
+
.digital-clock-item:hover:not(.padding):not(.disabled) {
|
|
619
|
+
background-color: rgba(0, 0, 0, 0.05);
|
|
620
|
+
}
|
|
621
|
+
.digital-clock-item.selected {
|
|
622
|
+
color: var(--mm-primary-color, #26a69a);
|
|
623
|
+
font-weight: 500;
|
|
624
|
+
font-size: 2rem;
|
|
625
|
+
}
|
|
626
|
+
.digital-clock-item.disabled {
|
|
627
|
+
color: rgba(0, 0, 0, 0.15);
|
|
628
|
+
cursor: not-allowed;
|
|
629
|
+
pointer-events: none;
|
|
630
|
+
}
|
|
631
|
+
.digital-clock-item.padding {
|
|
632
|
+
pointer-events: none;
|
|
633
|
+
cursor: default;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
.digital-clock-separator {
|
|
637
|
+
font-size: 2rem;
|
|
638
|
+
font-weight: 300;
|
|
639
|
+
margin: 0 4px;
|
|
640
|
+
color: rgba(0, 0, 0, 0.6);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/* Time Range Picker Styles */
|
|
644
|
+
.timerange-display-vertical {
|
|
645
|
+
flex: 1 auto;
|
|
646
|
+
background-color: #26a69a;
|
|
647
|
+
padding: 20px;
|
|
648
|
+
display: flex;
|
|
649
|
+
flex-direction: column;
|
|
650
|
+
gap: 20px;
|
|
651
|
+
min-width: 200px;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
.timerange-time-section {
|
|
655
|
+
color: rgba(255, 255, 255, 0.6);
|
|
656
|
+
}
|
|
657
|
+
.timerange-time-section.active {
|
|
658
|
+
color: rgb(255, 255, 255);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
.timerange-label {
|
|
662
|
+
font-size: 0.9rem;
|
|
663
|
+
font-weight: 300;
|
|
664
|
+
margin-bottom: 8px;
|
|
665
|
+
opacity: 0.8;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
.timerange-time {
|
|
669
|
+
font-size: 3rem;
|
|
670
|
+
font-weight: 300;
|
|
671
|
+
letter-spacing: 0.05em;
|
|
672
|
+
min-width: 200px;
|
|
673
|
+
display: flex;
|
|
674
|
+
align-items: baseline;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
.timerange-hours {
|
|
678
|
+
display: inline-block;
|
|
679
|
+
min-width: 2ch;
|
|
680
|
+
text-align: right;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
.timerange-minutes {
|
|
684
|
+
display: inline-block;
|
|
685
|
+
min-width: 2ch;
|
|
686
|
+
text-align: left;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
.timerange-ampm {
|
|
690
|
+
font-size: 1.5rem;
|
|
691
|
+
margin-left: 8px;
|
|
692
|
+
}
|
|
693
|
+
|
|
524
694
|
/* Media Queries */
|
|
525
695
|
@media only screen and (min-width : 601px) {
|
|
526
696
|
.timepicker-modal {
|
package/dist/select.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Attributes, Component } from 'mithril';
|
|
2
2
|
import { InputOption } from './option';
|
|
3
|
+
export type SortSelected<T extends string | number> = 'asc' | 'desc' | 'none' | ((a: InputOption<T>, b: InputOption<T>) => number);
|
|
3
4
|
export interface SelectAttrs<T extends string | number> extends Attributes {
|
|
4
5
|
/** Options to select from */
|
|
5
6
|
options: InputOption<T>[];
|
|
@@ -48,7 +49,7 @@ export interface SelectAttrs<T extends string | number> extends Attributes {
|
|
|
48
49
|
/** Max height of the dropdown menu, default '400px' */
|
|
49
50
|
maxHeight?: string;
|
|
50
51
|
/** Sort selected items: 'asc' (alphabetically A-Z), 'desc' (Z-A), 'none' (insertion order), or custom sort function */
|
|
51
|
-
sortSelected?:
|
|
52
|
+
sortSelected?: SortSelected<T>;
|
|
52
53
|
}
|
|
53
54
|
/** Select component */
|
|
54
55
|
export declare const Select: <T extends string | number>() => Component<SelectAttrs<T>>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { FactoryComponent } from 'mithril';
|
|
2
|
+
import { InputAttrs } from './input-options';
|
|
3
|
+
export interface TimepickerI18n {
|
|
4
|
+
cancel?: string;
|
|
5
|
+
clear?: string;
|
|
6
|
+
done?: string;
|
|
7
|
+
next?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface TimeRangePickerAttrs extends Omit<InputAttrs<string>, 'defaultValue' | 'onchange'> {
|
|
10
|
+
/** Starting time value in HH:MM or HH:MM AM/PM format */
|
|
11
|
+
startValue?: string;
|
|
12
|
+
/** Ending time value in HH:MM or HH:MM AM/PM format */
|
|
13
|
+
endValue?: string;
|
|
14
|
+
/** Enable validation: end time must be after start time */
|
|
15
|
+
validateRange?: boolean;
|
|
16
|
+
/** Callback when time range changes */
|
|
17
|
+
onchange?: (startTime: string, endTime: string) => void;
|
|
18
|
+
/** i18n for time range picker */
|
|
19
|
+
i18n?: TimepickerI18n;
|
|
20
|
+
/** Use 12-hour format with AM/PM */
|
|
21
|
+
twelveHour?: boolean;
|
|
22
|
+
/** Display mode: 'analog' or 'digital' (default: 'digital') */
|
|
23
|
+
displayMode?: 'analog' | 'digital';
|
|
24
|
+
/** Step for minute increments (default 5) */
|
|
25
|
+
minuteStep?: number;
|
|
26
|
+
/** Step for hour increments (default 1) */
|
|
27
|
+
hourStep?: number;
|
|
28
|
+
/** Minimum selectable time in HH:MM or HH:MM AM/PM format */
|
|
29
|
+
minTime?: string;
|
|
30
|
+
/** Maximum selectable time in HH:MM or HH:MM AM/PM format */
|
|
31
|
+
maxTime?: string;
|
|
32
|
+
/** Show clear button */
|
|
33
|
+
showClearBtn?: boolean;
|
|
34
|
+
/** Dial radius for analog clock (default: 135) */
|
|
35
|
+
dialRadius?: number;
|
|
36
|
+
/** Outer radius for analog clock (default: 105) */
|
|
37
|
+
outerRadius?: number;
|
|
38
|
+
/** Inner radius for analog clock (default: 70) */
|
|
39
|
+
innerRadius?: number;
|
|
40
|
+
/** Tick radius for analog clock (default: 20) */
|
|
41
|
+
tickRadius?: number;
|
|
42
|
+
/** Round by 5 minutes for analog clock (default: false) */
|
|
43
|
+
roundBy5?: boolean;
|
|
44
|
+
/** Vibrate on value change for analog clock (default: true) */
|
|
45
|
+
vibrate?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* TimeRangePicker component for selecting time ranges
|
|
49
|
+
* Custom implementation with embedded digital clock picker
|
|
50
|
+
*/
|
|
51
|
+
export declare const TimeRangePicker: FactoryComponent<TimeRangePickerAttrs>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utility functions for TimePicker and TimeRangePicker components
|
|
3
|
+
*/
|
|
4
|
+
export interface TimeValue {
|
|
5
|
+
hours: number;
|
|
6
|
+
minutes: number;
|
|
7
|
+
amOrPm: 'AM' | 'PM';
|
|
8
|
+
}
|
|
9
|
+
export declare const addLeadingZero: (num: number) => string;
|
|
10
|
+
export declare const parseTime: (timeStr: string, twelveHour: boolean) => TimeValue;
|
|
11
|
+
export declare const formatTime: (time: TimeValue, twelveHour: boolean) => string;
|
|
12
|
+
export declare const timeToMinutes: (time: TimeValue, twelveHour: boolean) => number;
|
|
13
|
+
export declare const generateHourOptions: (twelveHour: boolean, hourStep: number) => number[];
|
|
14
|
+
export declare const generateMinuteOptions: (minuteStep: number) => number[];
|
|
15
|
+
export declare const isTimeDisabled: (hours: number, minutes: number, amOrPm: "AM" | "PM", minTime?: string, maxTime?: string, twelveHour?: boolean) => boolean;
|
|
16
|
+
export declare const scrollToValue: (container: HTMLElement, index: number, itemHeight: number, animated?: boolean) => void;
|
|
17
|
+
export declare const snapToNearestItem: (container: HTMLElement, itemHeight: number, onSnap: (index: number) => void) => void;
|
package/dist/timepicker.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export interface TimepickerI18n {
|
|
|
4
4
|
cancel?: string;
|
|
5
5
|
clear?: string;
|
|
6
6
|
done?: string;
|
|
7
|
+
next?: string;
|
|
7
8
|
}
|
|
8
9
|
export interface TimepickerOptions {
|
|
9
10
|
dialRadius?: number;
|
|
@@ -20,6 +21,16 @@ export interface TimepickerOptions {
|
|
|
20
21
|
twelveHour?: boolean;
|
|
21
22
|
vibrate?: boolean;
|
|
22
23
|
roundBy5?: boolean;
|
|
24
|
+
/** Display mode: 'analog' (default) or 'digital' */
|
|
25
|
+
displayMode?: 'analog' | 'digital';
|
|
26
|
+
/** Step for minute increments in digital mode (default 5) */
|
|
27
|
+
minuteStep?: number;
|
|
28
|
+
/** Step for hour increments (default 1) */
|
|
29
|
+
hourStep?: number;
|
|
30
|
+
/** Minimum selectable time in HH:MM or HH:MM AM/PM format */
|
|
31
|
+
minTime?: string;
|
|
32
|
+
/** Maximum selectable time in HH:MM or HH:MM AM/PM format */
|
|
33
|
+
maxTime?: string;
|
|
23
34
|
onOpen?: () => void;
|
|
24
35
|
onOpenStart?: () => void;
|
|
25
36
|
onOpenEnd?: () => void;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { FactoryComponent, Attributes, Vnode } from 'mithril';
|
|
2
|
+
/**
|
|
3
|
+
* Attributes for the ToggleButton component.
|
|
4
|
+
*
|
|
5
|
+
* A toggle button is a button that can be in a checked or unchecked state.
|
|
6
|
+
* It is typically used within a ToggleGroup to create button groups where
|
|
7
|
+
* one or more buttons can be selected.
|
|
8
|
+
*/
|
|
9
|
+
export interface ToggleButtonAttrs extends Attributes {
|
|
10
|
+
/** The value of the button. This is returned when the button is selected. */
|
|
11
|
+
value: string | number;
|
|
12
|
+
/** The label text to display next to the icon. */
|
|
13
|
+
label?: string;
|
|
14
|
+
/** The name of the Material Design icon to display. */
|
|
15
|
+
iconName?: string;
|
|
16
|
+
/** A custom SVG icon vnode to display instead of a Material icon. */
|
|
17
|
+
icon?: Vnode<any, any>;
|
|
18
|
+
/** Additional CSS class for the icon element. */
|
|
19
|
+
iconClass?: string;
|
|
20
|
+
/** Whether the button is in a checked/selected state. */
|
|
21
|
+
checked?: boolean;
|
|
22
|
+
/** Whether the button is disabled and cannot be interacted with. */
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
/** Optional tooltip text to display on hover. */
|
|
25
|
+
tooltip?: string;
|
|
26
|
+
/** Callback function invoked when the button is clicked. */
|
|
27
|
+
onchange?: () => void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* ToggleButton component.
|
|
31
|
+
*
|
|
32
|
+
* A button that can be toggled on/off. Typically used within a ToggleGroup
|
|
33
|
+
* to create grouped button controls where one or more buttons can be selected.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* m(ToggleButton, {
|
|
38
|
+
* value: 'bold',
|
|
39
|
+
* iconName: 'format_bold',
|
|
40
|
+
* checked: true,
|
|
41
|
+
* tooltip: 'Bold',
|
|
42
|
+
* onchange: () => console.log('Toggled')
|
|
43
|
+
* })
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare const ToggleButton: FactoryComponent<ToggleButtonAttrs>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { FactoryComponent, Attributes } from 'mithril';
|
|
2
|
+
import { ToggleButtonAttrs } from './toggle-button';
|
|
3
|
+
/**
|
|
4
|
+
* Attributes for the ToggleGroup component.
|
|
5
|
+
*
|
|
6
|
+
* A toggle group is a container for multiple toggle buttons that manages their
|
|
7
|
+
* selection state. It can operate in single-select or multi-select mode.
|
|
8
|
+
*/
|
|
9
|
+
export interface ToggleGroupAttrs extends Attributes {
|
|
10
|
+
/**
|
|
11
|
+
* The current value(s) of the toggle group (controlled mode).
|
|
12
|
+
* - Single-select: a single value
|
|
13
|
+
* - Multi-select: an array of values
|
|
14
|
+
*/
|
|
15
|
+
value?: string | number | Array<string | number>;
|
|
16
|
+
/**
|
|
17
|
+
* The default value(s) for uncontrolled mode.
|
|
18
|
+
* Use this when you want the component to manage its own state.
|
|
19
|
+
*/
|
|
20
|
+
defaultValue?: string | number | Array<string | number>;
|
|
21
|
+
/** Whether all buttons in the group are disabled. */
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Callback invoked when the selection changes.
|
|
25
|
+
* @param value - The new value (single value or array depending on `multiple`)
|
|
26
|
+
*/
|
|
27
|
+
onchange?: (value: string | number | Array<string | number>) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Array of button configurations to display in the group.
|
|
30
|
+
* Each item can have its own icon, label, tooltip, and disabled state.
|
|
31
|
+
*/
|
|
32
|
+
items: Array<ToggleButtonAttrs>;
|
|
33
|
+
/**
|
|
34
|
+
* Whether to allow multiple buttons to be selected simultaneously.
|
|
35
|
+
* - false (default): only one button can be selected at a time
|
|
36
|
+
* - true: multiple buttons can be selected
|
|
37
|
+
*/
|
|
38
|
+
multiple?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* ToggleGroup component.
|
|
42
|
+
*
|
|
43
|
+
* A group of toggle buttons that can operate in single-select or multi-select mode.
|
|
44
|
+
* The component supports both controlled and uncontrolled modes.
|
|
45
|
+
*
|
|
46
|
+
* **Controlled mode**: Manage the state externally using the `value` prop.
|
|
47
|
+
* **Uncontrolled mode**: Let the component manage its own state using `defaultValue`.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* // Single-select, controlled mode
|
|
52
|
+
* let selected = 'left';
|
|
53
|
+
* m(ToggleGroup, {
|
|
54
|
+
* value: selected,
|
|
55
|
+
* onchange: (v) => selected = v,
|
|
56
|
+
* items: [
|
|
57
|
+
* { value: 'left', iconName: 'format_align_left', tooltip: 'Align Left' },
|
|
58
|
+
* { value: 'center', iconName: 'format_align_center', tooltip: 'Align Center' },
|
|
59
|
+
* { value: 'right', iconName: 'format_align_right', tooltip: 'Align Right' }
|
|
60
|
+
* ]
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* // Multi-select, controlled mode
|
|
64
|
+
* let selected = ['bold', 'italic'];
|
|
65
|
+
* m(ToggleGroup, {
|
|
66
|
+
* multiple: true,
|
|
67
|
+
* value: selected,
|
|
68
|
+
* onchange: (v) => selected = v,
|
|
69
|
+
* items: [
|
|
70
|
+
* { value: 'bold', iconName: 'format_bold', tooltip: 'Bold' },
|
|
71
|
+
* { value: 'italic', iconName: 'format_italic', tooltip: 'Italic' },
|
|
72
|
+
* { value: 'underline', iconName: 'format_underlined', tooltip: 'Underline' }
|
|
73
|
+
* ]
|
|
74
|
+
* });
|
|
75
|
+
*
|
|
76
|
+
* // Uncontrolled mode
|
|
77
|
+
* m(ToggleGroup, {
|
|
78
|
+
* defaultValue: 'left',
|
|
79
|
+
* onchange: (v) => console.log('Changed to:', v),
|
|
80
|
+
* items: [...]
|
|
81
|
+
* });
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export declare const ToggleGroup: FactoryComponent<ToggleGroupAttrs>;
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { SortSelected } from './select';
|
|
2
|
+
import { InputOption } from '.';
|
|
1
3
|
/**
|
|
2
4
|
* Create a unique ID
|
|
3
5
|
* @see https://stackoverflow.com/a/2117523/319711
|
|
@@ -20,16 +22,7 @@ export declare const isNumeric: (n: string | number) => boolean;
|
|
|
20
22
|
* @param sortConfig - Sort configuration: 'asc', 'desc', 'none', or custom comparator function
|
|
21
23
|
* @returns Sorted array (or original if 'none' or undefined)
|
|
22
24
|
*/
|
|
23
|
-
export declare const sortOptions: <T extends string | number>(options: {
|
|
24
|
-
id: T;
|
|
25
|
-
label?: string;
|
|
26
|
-
}[], sortConfig?: "asc" | "desc" | "none" | ((a: {
|
|
27
|
-
id: T;
|
|
28
|
-
label?: string;
|
|
29
|
-
}, b: {
|
|
30
|
-
id: T;
|
|
31
|
-
label?: string;
|
|
32
|
-
}) => number)) => {
|
|
25
|
+
export declare const sortOptions: <T extends string | number>(options: InputOption<T>[], sortConfig?: SortSelected<T>) => {
|
|
33
26
|
id: T;
|
|
34
27
|
label?: string;
|
|
35
28
|
}[];
|
package/package.json
CHANGED
|
@@ -81,12 +81,14 @@
|
|
|
81
81
|
.timepicker-modal {
|
|
82
82
|
max-width: 325px;
|
|
83
83
|
max-height: none;
|
|
84
|
+
overflow: hidden;
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
.timepicker-container.modal-content {
|
|
87
88
|
display: flex;
|
|
88
89
|
flex-direction: column;
|
|
89
90
|
padding: 0;
|
|
91
|
+
overflow: hidden;
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
.text-primary {
|
|
@@ -171,6 +173,10 @@
|
|
|
171
173
|
top: 0;
|
|
172
174
|
bottom: 0;
|
|
173
175
|
}
|
|
176
|
+
|
|
177
|
+
.timepicker-dial {
|
|
178
|
+
pointer-events: none;
|
|
179
|
+
}
|
|
174
180
|
.timepicker-minutes {
|
|
175
181
|
visibility: hidden;
|
|
176
182
|
}
|
|
@@ -185,6 +191,7 @@
|
|
|
185
191
|
position: absolute;
|
|
186
192
|
cursor: pointer;
|
|
187
193
|
font-size: 15px;
|
|
194
|
+
pointer-events: none;
|
|
188
195
|
}
|
|
189
196
|
|
|
190
197
|
.timepicker-tick.active,
|
|
@@ -248,6 +255,194 @@
|
|
|
248
255
|
padding: 0 20px;
|
|
249
256
|
}
|
|
250
257
|
|
|
258
|
+
/* Digital Clock Mode */
|
|
259
|
+
.timepicker-digital-mode {
|
|
260
|
+
padding: 20px;
|
|
261
|
+
display: flex;
|
|
262
|
+
flex-direction: column;
|
|
263
|
+
align-items: center;
|
|
264
|
+
flex: 2.5 auto;
|
|
265
|
+
overflow: hidden;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.timepicker-digital-clock {
|
|
269
|
+
display: flex;
|
|
270
|
+
align-items: center;
|
|
271
|
+
gap: 8px;
|
|
272
|
+
margin-bottom: 20px;
|
|
273
|
+
user-select: none;
|
|
274
|
+
overflow: hidden;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.digital-clock-column {
|
|
278
|
+
width: 80px;
|
|
279
|
+
height: 240px;
|
|
280
|
+
overflow-y: scroll;
|
|
281
|
+
overflow-x: hidden;
|
|
282
|
+
scroll-snap-type: y mandatory;
|
|
283
|
+
scrollbar-width: thin;
|
|
284
|
+
scrollbar-color: transparent transparent;
|
|
285
|
+
position: relative;
|
|
286
|
+
|
|
287
|
+
&::-webkit-scrollbar {
|
|
288
|
+
width: 6px;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
&::-webkit-scrollbar-track {
|
|
292
|
+
background: transparent;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
&::-webkit-scrollbar-thumb {
|
|
296
|
+
background: transparent;
|
|
297
|
+
border-radius: 3px;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Show scrollbar on hover
|
|
301
|
+
&:hover {
|
|
302
|
+
scrollbar-color: rgba(0, 0, 0, 0.3) transparent;
|
|
303
|
+
|
|
304
|
+
&::-webkit-scrollbar-thumb {
|
|
305
|
+
background: rgba(0, 0, 0, 0.3);
|
|
306
|
+
|
|
307
|
+
&:hover {
|
|
308
|
+
background: rgba(0, 0, 0, 0.5);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Gradient fade at edges - theme aware
|
|
314
|
+
background: linear-gradient(
|
|
315
|
+
to bottom,
|
|
316
|
+
var(--mm-background-color, #fafafa) 0%,
|
|
317
|
+
transparent 20%,
|
|
318
|
+
transparent 80%,
|
|
319
|
+
var(--mm-background-color, #fafafa) 100%
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
&.ampm-column {
|
|
323
|
+
width: 60px;
|
|
324
|
+
scrollbar-width: none;
|
|
325
|
+
|
|
326
|
+
&::-webkit-scrollbar {
|
|
327
|
+
display: none;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Selection indicator lines
|
|
332
|
+
&::before,
|
|
333
|
+
&::after {
|
|
334
|
+
content: '';
|
|
335
|
+
position: absolute;
|
|
336
|
+
left: 0;
|
|
337
|
+
right: 0;
|
|
338
|
+
height: 1px;
|
|
339
|
+
pointer-events: none;
|
|
340
|
+
z-index: 1;
|
|
341
|
+
background-color: rgba(0, 0, 0, 0.1);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
&::before {
|
|
345
|
+
top: calc(50% - 24px);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
&::after {
|
|
349
|
+
top: calc(50% + 24px);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.digital-clock-item {
|
|
354
|
+
height: 48px;
|
|
355
|
+
display: flex;
|
|
356
|
+
align-items: center;
|
|
357
|
+
justify-content: center;
|
|
358
|
+
font-size: 1.5rem;
|
|
359
|
+
font-weight: 300;
|
|
360
|
+
scroll-snap-align: center;
|
|
361
|
+
cursor: pointer;
|
|
362
|
+
color: rgba(0, 0, 0, 0.4);
|
|
363
|
+
transition: all 0.2s ease;
|
|
364
|
+
|
|
365
|
+
&:hover:not(.padding):not(.disabled) {
|
|
366
|
+
background-color: rgba(0, 0, 0, 0.05);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
&.selected {
|
|
370
|
+
color: var(--mm-primary-color, variables.$secondary-color);
|
|
371
|
+
font-weight: 500;
|
|
372
|
+
font-size: 2rem;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
&.disabled {
|
|
376
|
+
color: rgba(0, 0, 0, 0.15);
|
|
377
|
+
cursor: not-allowed;
|
|
378
|
+
pointer-events: none;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
&.padding {
|
|
382
|
+
pointer-events: none;
|
|
383
|
+
cursor: default;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.digital-clock-separator {
|
|
388
|
+
font-size: 2rem;
|
|
389
|
+
font-weight: 300;
|
|
390
|
+
margin: 0 4px;
|
|
391
|
+
color: rgba(0, 0, 0, 0.6);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/* Time Range Picker Styles */
|
|
395
|
+
.timerange-display-vertical {
|
|
396
|
+
flex: 1 auto;
|
|
397
|
+
background-color: variables.$secondary-color;
|
|
398
|
+
padding: 20px;
|
|
399
|
+
display: flex;
|
|
400
|
+
flex-direction: column;
|
|
401
|
+
gap: 20px;
|
|
402
|
+
min-width: 200px;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.timerange-time-section {
|
|
406
|
+
color: rgba(255, 255, 255, 0.6);
|
|
407
|
+
|
|
408
|
+
&.active {
|
|
409
|
+
color: rgba(255, 255, 255, 1);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.timerange-label {
|
|
414
|
+
font-size: 0.9rem;
|
|
415
|
+
font-weight: 300;
|
|
416
|
+
margin-bottom: 8px;
|
|
417
|
+
opacity: 0.8;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
.timerange-time {
|
|
421
|
+
font-size: 3rem;
|
|
422
|
+
font-weight: 300;
|
|
423
|
+
letter-spacing: 0.05em;
|
|
424
|
+
min-width: 200px; // Prevent width changes when time updates
|
|
425
|
+
display: flex;
|
|
426
|
+
align-items: baseline;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
.timerange-hours {
|
|
430
|
+
display: inline-block;
|
|
431
|
+
min-width: 2ch;
|
|
432
|
+
text-align: right;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.timerange-minutes {
|
|
436
|
+
display: inline-block;
|
|
437
|
+
min-width: 2ch;
|
|
438
|
+
text-align: left;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.timerange-ampm {
|
|
442
|
+
font-size: 1.5rem;
|
|
443
|
+
margin-left: 8px;
|
|
444
|
+
}
|
|
445
|
+
|
|
251
446
|
/* Media Queries */
|
|
252
447
|
@media #{variables.$medium-and-up} {
|
|
253
448
|
.timepicker-modal {
|
|
@@ -269,4 +464,4 @@
|
|
|
269
464
|
text-align: center;
|
|
270
465
|
margin-top: 1.2rem;
|
|
271
466
|
}
|
|
272
|
-
}
|
|
467
|
+
}
|