mtrl 0.2.5 → 0.2.7

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.
Files changed (196) hide show
  1. package/index.ts +18 -0
  2. package/package.json +1 -1
  3. package/src/components/badge/_styles.scss +123 -115
  4. package/src/components/badge/api.ts +57 -59
  5. package/src/components/badge/badge.ts +16 -2
  6. package/src/components/badge/config.ts +65 -11
  7. package/src/components/badge/constants.ts +22 -12
  8. package/src/components/badge/features.ts +44 -40
  9. package/src/components/badge/types.ts +42 -30
  10. package/src/components/bottom-app-bar/_styles.scss +103 -0
  11. package/src/components/bottom-app-bar/bottom-app-bar.ts +196 -0
  12. package/src/components/bottom-app-bar/config.ts +73 -0
  13. package/src/components/bottom-app-bar/index.ts +11 -0
  14. package/src/components/bottom-app-bar/types.ts +108 -0
  15. package/src/components/button/_styles.scss +0 -66
  16. package/src/components/button/api.ts +5 -0
  17. package/src/components/button/button.ts +0 -2
  18. package/src/components/button/config.ts +5 -0
  19. package/src/components/button/constants.ts +0 -6
  20. package/src/components/button/index.ts +2 -2
  21. package/src/components/button/types.ts +7 -7
  22. package/src/components/card/_styles.scss +67 -25
  23. package/src/components/card/api.ts +54 -3
  24. package/src/components/card/card.ts +25 -6
  25. package/src/components/card/config.ts +189 -22
  26. package/src/components/card/constants.ts +20 -19
  27. package/src/components/card/content.ts +299 -2
  28. package/src/components/card/features.ts +158 -4
  29. package/src/components/card/index.ts +31 -9
  30. package/src/components/card/types.ts +166 -15
  31. package/src/components/checkbox/_styles.scss +0 -2
  32. package/src/components/chip/chip.ts +1 -9
  33. package/src/components/chip/constants.ts +0 -10
  34. package/src/components/chip/index.ts +1 -1
  35. package/src/components/chip/types.ts +1 -4
  36. package/src/components/datepicker/_styles.scss +358 -0
  37. package/src/components/datepicker/api.ts +272 -0
  38. package/src/components/datepicker/config.ts +144 -0
  39. package/src/components/datepicker/constants.ts +98 -0
  40. package/src/components/datepicker/datepicker.ts +346 -0
  41. package/src/components/datepicker/index.ts +9 -0
  42. package/src/components/datepicker/render.ts +452 -0
  43. package/src/components/datepicker/types.ts +268 -0
  44. package/src/components/datepicker/utils.ts +290 -0
  45. package/src/components/dialog/_styles.scss +174 -128
  46. package/src/components/dialog/api.ts +48 -13
  47. package/src/components/dialog/config.ts +9 -5
  48. package/src/components/dialog/dialog.ts +6 -3
  49. package/src/components/dialog/features.ts +290 -130
  50. package/src/components/dialog/types.ts +7 -4
  51. package/src/components/divider/_styles.scss +57 -0
  52. package/src/components/divider/config.ts +81 -0
  53. package/src/components/divider/divider.ts +37 -0
  54. package/src/components/divider/features.ts +207 -0
  55. package/src/components/divider/index.ts +5 -0
  56. package/src/components/divider/types.ts +55 -0
  57. package/src/components/extended-fab/_styles.scss +267 -0
  58. package/src/components/extended-fab/api.ts +141 -0
  59. package/src/components/extended-fab/config.ts +108 -0
  60. package/src/components/extended-fab/constants.ts +36 -0
  61. package/src/components/extended-fab/extended-fab.ts +125 -0
  62. package/src/components/extended-fab/index.ts +4 -0
  63. package/src/components/extended-fab/types.ts +287 -0
  64. package/src/components/fab/_styles.scss +225 -0
  65. package/src/components/fab/api.ts +97 -0
  66. package/src/components/fab/config.ts +94 -0
  67. package/src/components/fab/constants.ts +41 -0
  68. package/src/components/fab/fab.ts +67 -0
  69. package/src/components/fab/index.ts +4 -0
  70. package/src/components/fab/types.ts +234 -0
  71. package/src/components/navigation/_styles.scss +1 -0
  72. package/src/components/navigation/api.ts +78 -50
  73. package/src/components/navigation/features/items.ts +280 -0
  74. package/src/components/navigation/nav-item.ts +72 -23
  75. package/src/components/navigation/navigation.ts +54 -2
  76. package/src/components/navigation/types.ts +210 -188
  77. package/src/components/progress/_styles.scss +0 -65
  78. package/src/components/progress/config.ts +1 -2
  79. package/src/components/progress/constants.ts +0 -14
  80. package/src/components/progress/index.ts +1 -1
  81. package/src/components/progress/progress.ts +1 -4
  82. package/src/components/progress/types.ts +1 -4
  83. package/src/components/radios/_styles.scss +0 -45
  84. package/src/components/radios/api.ts +85 -60
  85. package/src/components/radios/config.ts +1 -2
  86. package/src/components/radios/constants.ts +0 -9
  87. package/src/components/radios/index.ts +1 -1
  88. package/src/components/radios/radio.ts +34 -11
  89. package/src/components/radios/radios.ts +2 -1
  90. package/src/components/radios/types.ts +1 -7
  91. package/src/components/search/_styles.scss +306 -0
  92. package/src/components/search/api.ts +203 -0
  93. package/src/components/search/config.ts +87 -0
  94. package/src/components/search/constants.ts +21 -0
  95. package/src/components/search/features/index.ts +4 -0
  96. package/src/components/search/features/search.ts +718 -0
  97. package/src/components/search/features/states.ts +165 -0
  98. package/src/components/search/features/structure.ts +198 -0
  99. package/src/components/search/index.ts +10 -0
  100. package/src/components/search/search.ts +52 -0
  101. package/src/components/search/types.ts +163 -0
  102. package/src/components/segmented-button/_styles.scss +117 -0
  103. package/src/components/segmented-button/config.ts +67 -0
  104. package/src/components/segmented-button/constants.ts +42 -0
  105. package/src/components/segmented-button/index.ts +4 -0
  106. package/src/components/segmented-button/segment.ts +155 -0
  107. package/src/components/segmented-button/segmented-button.ts +250 -0
  108. package/src/components/segmented-button/types.ts +219 -0
  109. package/src/components/slider/_styles.scss +221 -168
  110. package/src/components/slider/accessibility.md +59 -0
  111. package/src/components/slider/api.ts +41 -120
  112. package/src/components/slider/config.ts +51 -49
  113. package/src/components/slider/features/handlers.ts +495 -0
  114. package/src/components/slider/features/index.ts +1 -2
  115. package/src/components/slider/features/slider.ts +66 -84
  116. package/src/components/slider/features/states.ts +195 -0
  117. package/src/components/slider/features/structure.ts +141 -184
  118. package/src/components/slider/features/ui.ts +150 -201
  119. package/src/components/slider/index.ts +2 -11
  120. package/src/components/slider/slider.ts +9 -12
  121. package/src/components/slider/types.ts +39 -24
  122. package/src/components/switch/_styles.scss +0 -2
  123. package/src/components/tabs/_styles.scss +346 -154
  124. package/src/components/tabs/api.ts +178 -400
  125. package/src/components/tabs/config.ts +46 -52
  126. package/src/components/tabs/constants.ts +85 -8
  127. package/src/components/tabs/features.ts +403 -0
  128. package/src/components/tabs/index.ts +60 -3
  129. package/src/components/tabs/indicator.ts +285 -0
  130. package/src/components/tabs/responsive.ts +144 -0
  131. package/src/components/tabs/scroll-indicators.ts +149 -0
  132. package/src/components/tabs/state.ts +186 -0
  133. package/src/components/tabs/tab-api.ts +258 -0
  134. package/src/components/tabs/tab.ts +255 -0
  135. package/src/components/tabs/tabs.ts +50 -31
  136. package/src/components/tabs/types.ts +332 -128
  137. package/src/components/tabs/utils.ts +107 -0
  138. package/src/components/textfield/_styles.scss +0 -98
  139. package/src/components/textfield/config.ts +2 -3
  140. package/src/components/textfield/constants.ts +0 -14
  141. package/src/components/textfield/index.ts +2 -2
  142. package/src/components/textfield/textfield.ts +0 -2
  143. package/src/components/textfield/types.ts +1 -4
  144. package/src/components/timepicker/README.md +277 -0
  145. package/src/components/timepicker/_styles.scss +451 -0
  146. package/src/components/timepicker/api.ts +632 -0
  147. package/src/components/timepicker/clockdial.ts +482 -0
  148. package/src/components/timepicker/config.ts +130 -0
  149. package/src/components/timepicker/constants.ts +138 -0
  150. package/src/components/timepicker/index.ts +8 -0
  151. package/src/components/timepicker/render.ts +613 -0
  152. package/src/components/timepicker/timepicker.ts +117 -0
  153. package/src/components/timepicker/types.ts +336 -0
  154. package/src/components/timepicker/utils.ts +241 -0
  155. package/src/components/top-app-bar/_styles.scss +225 -0
  156. package/src/components/top-app-bar/config.ts +83 -0
  157. package/src/components/top-app-bar/index.ts +11 -0
  158. package/src/components/top-app-bar/top-app-bar.ts +316 -0
  159. package/src/components/top-app-bar/types.ts +140 -0
  160. package/src/core/build/_ripple.scss +6 -6
  161. package/src/core/build/ripple.ts +72 -95
  162. package/src/core/compose/component.ts +1 -1
  163. package/src/core/compose/features/badge.ts +79 -0
  164. package/src/core/compose/features/icon.ts +3 -1
  165. package/src/core/compose/features/index.ts +3 -1
  166. package/src/core/compose/features/ripple.ts +4 -1
  167. package/src/core/compose/features/textlabel.ts +26 -2
  168. package/src/core/dom/create.ts +5 -0
  169. package/src/index.ts +9 -0
  170. package/src/styles/abstract/_theme.scss +115 -3
  171. package/src/styles/themes/_autumn.scss +21 -0
  172. package/src/styles/themes/_base-theme.scss +61 -0
  173. package/src/styles/themes/_baseline.scss +58 -0
  174. package/src/styles/themes/_bluekhaki.scss +125 -0
  175. package/src/styles/themes/_brownbeige.scss +125 -0
  176. package/src/styles/themes/_browngreen.scss +125 -0
  177. package/src/styles/themes/_forest.scss +6 -0
  178. package/src/styles/themes/_greenbeige.scss +125 -0
  179. package/src/styles/themes/_material.scss +125 -0
  180. package/src/styles/themes/_ocean.scss +6 -0
  181. package/src/styles/themes/_sageivory.scss +125 -0
  182. package/src/styles/themes/_spring.scss +6 -0
  183. package/src/styles/themes/_summer.scss +5 -0
  184. package/src/styles/themes/_sunset.scss +5 -0
  185. package/src/styles/themes/_tealcaramel.scss +125 -0
  186. package/src/styles/themes/_winter.scss +6 -0
  187. package/src/components/card/actions.ts +0 -48
  188. package/src/components/card/header.ts +0 -88
  189. package/src/components/card/media.ts +0 -52
  190. package/src/components/navigation/features/items.js +0 -192
  191. package/src/components/slider/features/appearance.ts +0 -94
  192. package/src/components/slider/features/disabled.ts +0 -43
  193. package/src/components/slider/features/events.ts +0 -164
  194. package/src/components/slider/features/interactions.ts +0 -261
  195. package/src/components/slider/features/keyboard.ts +0 -112
  196. package/src/core/collection/adapters/mongodb.js +0 -232
@@ -0,0 +1,107 @@
1
+ // src/components/tabs/utils.ts
2
+ import { TabsComponent, TabComponent } from './types';
3
+
4
+ /**
5
+ * Gets the active tab from a component
6
+ * @param component - Component with tabs
7
+ * @returns Active tab or null
8
+ */
9
+ export function getActiveTab(component: any): TabComponent | null {
10
+ // First try the standard method
11
+ if (typeof component.getActiveTab === 'function') {
12
+ return component.getActiveTab();
13
+ }
14
+
15
+ // Fallback: check if component has tabs array
16
+ if (Array.isArray(component.tabs)) {
17
+ return component.tabs.find(tab => tab.isActive && tab.isActive());
18
+ }
19
+
20
+ // If all else fails, return null
21
+ return null;
22
+ }
23
+
24
+ /**
25
+ * Updates tab panels based on active tab
26
+ * @param component - Component with tabs
27
+ */
28
+ export function updateTabPanels(component: any): void {
29
+ // Get active tab using our helper function
30
+ const activeTab = getActiveTab(component);
31
+ if (!activeTab) return;
32
+
33
+ // Make sure getValue exists
34
+ if (typeof activeTab.getValue !== 'function') return;
35
+
36
+ const activeValue = activeTab.getValue();
37
+
38
+ // Find all tab panels in the document
39
+ const tabPanels = document.querySelectorAll(`[role="tabpanel"]`);
40
+
41
+ tabPanels.forEach(panel => {
42
+ // Get the associated tab value
43
+ const forTab = panel.getAttribute('aria-labelledby')?.replace('tab-', '');
44
+
45
+ if (forTab === activeValue) {
46
+ panel.removeAttribute('hidden');
47
+ panel.setAttribute('tabindex', '0');
48
+ } else {
49
+ panel.setAttribute('hidden', 'true');
50
+ panel.setAttribute('tabindex', '-1');
51
+ }
52
+ });
53
+ }
54
+
55
+ /**
56
+ * Sets up keyboard navigation for tabs
57
+ * @param component - Tabs component
58
+ */
59
+ export function setupKeyboardNavigation(component: any): void {
60
+ // Skip if element is missing
61
+ if (!component.element) return;
62
+
63
+ component.element.addEventListener('keydown', (event: KeyboardEvent) => {
64
+ // Only handle arrow keys when tabs container has focus
65
+ if (event.target !== event.currentTarget) return;
66
+
67
+ // Skip if getTabs or setActiveTab don't exist
68
+ if (typeof component.getTabs !== 'function' ||
69
+ typeof component.setActiveTab !== 'function') return;
70
+
71
+ const tabs = component.getTabs();
72
+ const currentTab = getActiveTab(component);
73
+ const currentIndex = currentTab ? tabs.indexOf(currentTab) : -1;
74
+
75
+ let newIndex = currentIndex;
76
+
77
+ switch (event.key) {
78
+ case 'ArrowRight':
79
+ case 'ArrowDown':
80
+ newIndex = currentIndex < tabs.length - 1 ? currentIndex + 1 : 0;
81
+ break;
82
+
83
+ case 'ArrowLeft':
84
+ case 'ArrowUp':
85
+ newIndex = currentIndex > 0 ? currentIndex - 1 : tabs.length - 1;
86
+ break;
87
+
88
+ case 'Home':
89
+ newIndex = 0;
90
+ break;
91
+
92
+ case 'End':
93
+ newIndex = tabs.length - 1;
94
+ break;
95
+
96
+ default:
97
+ return; // Don't handle other keys
98
+ }
99
+
100
+ // If a new tab should be focused
101
+ if (newIndex !== currentIndex && tabs[newIndex]) {
102
+ event.preventDefault();
103
+ tabs[newIndex].element.focus();
104
+ component.setActiveTab(tabs[newIndex]);
105
+ }
106
+ });
107
+ }
@@ -14,104 +14,6 @@ $component: '#{base.$prefix}-textfield';
14
14
  display: inline-flex;
15
15
  flex-direction: column;
16
16
  min-width: 210px;
17
-
18
- // Size variants
19
- &--small {
20
- .#{$component}-input {
21
- height: 40px;
22
- font-size: 14px;
23
- }
24
-
25
- .#{$component}-label {
26
- font-size: 14px;
27
- }
28
-
29
- .#{$component}-helper {
30
- font-size: 11px;
31
- margin-top: 2px;
32
- }
33
-
34
- &.#{$component}--filled {
35
- .#{$component}-input {
36
- padding: 16px 12px 6px;
37
-
38
- &:focus {
39
- padding-bottom: 5px;
40
- }
41
- }
42
-
43
- &:not(.#{$component}--empty) .#{$component}-label,
44
- &.#{$component}--focused .#{$component}-label {
45
- transform: translateY(-85%) scale(0.75);
46
- }
47
- }
48
-
49
- &.#{$component}--outlined {
50
- .#{$component}-input {
51
- padding: 10px 12px 11px;
52
- }
53
-
54
- &:not(.#{$component}--empty) .#{$component}-label,
55
- &.#{$component}--focused .#{$component}-label {
56
- transform: translateY(-130%) scale(0.75);
57
- }
58
-
59
- &.#{$component}--focused .#{$component}-input {
60
- height: 38px;
61
- padding: 9px 11px 10px;
62
- }
63
- }
64
- }
65
-
66
- &--medium {
67
- // Default size, styles already defined in base
68
- }
69
-
70
- &--large {
71
- .#{$component}-input {
72
- height: 64px;
73
- font-size: 16px;
74
- }
75
-
76
- .#{$component}-label {
77
- font-size: 16px;
78
- }
79
-
80
- .#{$component}-helper {
81
- font-size: 13px;
82
- margin-top: 6px;
83
- }
84
-
85
- &.#{$component}--filled {
86
- .#{$component}-input {
87
- padding: 26px 20px 8px;
88
-
89
- &:focus {
90
- padding-bottom: 7px;
91
- }
92
- }
93
-
94
- &:not(.#{$component}--empty) .#{$component}-label,
95
- &.#{$component}--focused .#{$component}-label {
96
- transform: translateY(-110%) scale(0.75);
97
- }
98
- }
99
-
100
- &.#{$component}--outlined {
101
- .#{$component}-input {
102
- padding: 16px 20px 17px;
103
- }
104
-
105
- &:not(.#{$component}--empty) .#{$component}-label,
106
- &.#{$component}--focused .#{$component}-label {
107
- transform: translateY(-170%) scale(0.75);
108
- }
109
-
110
- &.#{$component}--focused .#{$component}-input {
111
- padding: 15px 19px 16px;
112
- }
113
- }
114
- }
115
17
 
116
18
  // Label
117
19
  &-label {
@@ -5,15 +5,14 @@ import {
5
5
  BaseComponentConfig
6
6
  } from '../../core/config/component-config';
7
7
  import { TextfieldConfig, BaseComponent, ApiOptions } from './types';
8
- import { TEXTFIELD_VARIANTS, TEXTFIELD_TYPES, TEXTFIELD_SIZES } from './constants';
8
+ import { TEXTFIELD_VARIANTS, TEXTFIELD_TYPES } from './constants';
9
9
 
10
10
  /**
11
11
  * Default configuration for the Textfield component
12
12
  */
13
13
  export const defaultConfig: TextfieldConfig = {
14
14
  type: TEXTFIELD_TYPES.TEXT,
15
- variant: TEXTFIELD_VARIANTS.FILLED,
16
- size: TEXTFIELD_SIZES.MEDIUM
15
+ variant: TEXTFIELD_VARIANTS.FILLED
17
16
  };
18
17
 
19
18
  /**
@@ -8,15 +8,6 @@ export const TEXTFIELD_VARIANTS = {
8
8
  OUTLINED: 'outlined'
9
9
  } as const;
10
10
 
11
- /**
12
- * Textfield size variants
13
- */
14
- export const TEXTFIELD_SIZES = {
15
- SMALL: 'small',
16
- MEDIUM: 'medium',
17
- LARGE: 'large'
18
- } as const;
19
-
20
11
  /**
21
12
  * Textfield input types
22
13
  */
@@ -45,11 +36,6 @@ export const TEXTFIELD_SCHEMA = {
45
36
  enum: Object.values(TEXTFIELD_VARIANTS),
46
37
  required: false
47
38
  },
48
- size: {
49
- type: 'string',
50
- enum: Object.values(TEXTFIELD_SIZES),
51
- required: false
52
- },
53
39
  name: {
54
40
  type: 'string',
55
41
  required: false
@@ -1,4 +1,4 @@
1
1
  // src/components/textfield/index.ts
2
2
  export { default } from './textfield'
3
- export { TEXTFIELD_VARIANTS, TEXTFIELD_SIZES, TEXTFIELD_TYPES } from './constants'
4
- export { TextfieldConfig, TextfieldComponent } from './types'
3
+ export { TEXTFIELD_VARIANTS, TEXTFIELD_TYPES } from './constants'
4
+ export { TextfieldConfig, TextfieldComponent } from './types'
@@ -6,7 +6,6 @@ import {
6
6
  withDisabled,
7
7
  withLifecycle,
8
8
  withVariant,
9
- withSize,
10
9
  withTextInput,
11
10
  withTextLabel
12
11
  } from '../../core/compose/features';
@@ -32,7 +31,6 @@ const createTextfield = (config: TextfieldConfig = {}): TextfieldComponent => {
32
31
  withEvents(),
33
32
  withElement(getElementConfig(baseConfig)),
34
33
  withVariant(baseConfig),
35
- withSize(baseConfig),
36
34
  withTextInput(baseConfig),
37
35
  withTextLabel(baseConfig),
38
36
  withDisabled(baseConfig),
@@ -1,5 +1,5 @@
1
1
  // src/components/textfield/types.ts
2
- import { TEXTFIELD_VARIANTS, TEXTFIELD_SIZES, TEXTFIELD_TYPES } from './constants';
2
+ import { TEXTFIELD_VARIANTS, TEXTFIELD_TYPES } from './constants';
3
3
 
4
4
  /**
5
5
  * Configuration interface for the Textfield component
@@ -11,9 +11,6 @@ export interface TextfieldConfig {
11
11
  /** Visual variant (filled, outlined) */
12
12
  variant?: keyof typeof TEXTFIELD_VARIANTS | string;
13
13
 
14
- /** Size variant (small, medium, large) */
15
- size?: keyof typeof TEXTFIELD_SIZES | string;
16
-
17
14
  /** Input name attribute */
18
15
  name?: string;
19
16
 
@@ -0,0 +1,277 @@
1
+ # TimePicker Component
2
+
3
+ The `TimePicker` component provides a user-friendly interface for selecting a time. It supports both dial-based
4
+ and keyboard input selection methods, 12-hour and 24-hour formats, and customizable settings.
5
+
6
+ ## Features
7
+
8
+ - **Two Selection Methods**: Choose between a dial interface or keyboard input
9
+ - **Time Format Support**: 12-hour (AM/PM) or 24-hour format
10
+ - **Flexible Configuration**: Customize title, action buttons, and constraints
11
+ - **Responsive Layout**: Adapts between vertical and horizontal layouts based on device orientation
12
+ - **Accessibility**: Keyboard navigation and screen reader support
13
+ - **Full TypeScript Support**: Comprehensive type definitions for better development experience
14
+
15
+ ## Basic Usage
16
+
17
+ ```javascript
18
+ import { createTimePicker } from 'mtrl';
19
+
20
+ // Create a basic time picker
21
+ const timePicker = createTimePicker({
22
+ title: 'Select time',
23
+ value: '14:30', // Initial time (2:30 PM)
24
+ onConfirm: (time) => {
25
+ console.log('Selected time:', time);
26
+ // Update UI with selected time
27
+ document.getElementById('time-input').value = time;
28
+ }
29
+ });
30
+
31
+ // Create an input to trigger the time picker
32
+ const timeInput = document.createElement('input');
33
+ timeInput.id = 'time-input';
34
+ timeInput.type = 'text';
35
+ timeInput.readOnly = true;
36
+ timeInput.value = '14:30';
37
+ timeInput.addEventListener('click', () => {
38
+ timePicker.open();
39
+ });
40
+
41
+ // Add input to the DOM
42
+ document.body.appendChild(timeInput);
43
+ ```
44
+
45
+ ## Configuration Options
46
+
47
+ The `createTimePicker` function accepts a configuration object with the following properties:
48
+
49
+ | Property | Type | Default | Description |
50
+ |----------|------|---------|-------------|
51
+ | `value` | `string` | Current time | Initial time value in 24-hour format (HH:MM or HH:MM:SS) |
52
+ | `type` | `TIME_PICKER_TYPE` | `DIAL` | Type of time picker to display (DIAL or INPUT) |
53
+ | `format` | `TIME_FORMAT` | `AMPM` | Time format to use (AMPM for 12-hour or MILITARY for 24-hour) |
54
+ | `orientation` | `TIME_PICKER_ORIENTATION` | `VERTICAL` | Layout orientation (VERTICAL or HORIZONTAL) |
55
+ | `title` | `string` | `undefined` | Title text for the time picker |
56
+ | `showSeconds` | `boolean` | `false` | Whether to show seconds selector |
57
+ | `class` | `string` | `undefined` | Additional CSS classes to add to the time picker |
58
+ | `closeOnSelect` | `boolean` | `true` | Whether to close the picker when time is selected |
59
+ | `minTime` | `string` | `undefined` | Minimum selectable time in 24-hour format (HH:MM) |
60
+ | `maxTime` | `string` | `undefined` | Maximum selectable time in 24-hour format (HH:MM) |
61
+ | `minuteStep` | `number` | `1` | Step interval for minute selection |
62
+ | `secondStep` | `number` | `1` | Step interval for second selection |
63
+ | `cancelText` | `string` | `'Cancel'` | Custom text for cancel button |
64
+ | `confirmText` | `string` | `'OK'` | Custom text for confirm button |
65
+ | `isOpen` | `boolean` | `false` | Whether the time picker is initially visible |
66
+ | `container` | `string \| HTMLElement` | `document.body` | CSS selector or element to append the time picker to |
67
+ | `clockIcon` | `string` | Default SVG | Custom icon for the clock button |
68
+ | `keyboardIcon` | `string` | Default SVG | Custom icon for the keyboard button |
69
+ | `onChange` | `function` | `undefined` | Callback when time is changed |
70
+ | `onOpen` | `function` | `undefined` | Callback when time picker is opened |
71
+ | `onClose` | `function` | `undefined` | Callback when time picker is closed |
72
+ | `onConfirm` | `function` | `undefined` | Callback when time is confirmed |
73
+ | `onCancel` | `function` | `undefined` | Callback when time picker is canceled |
74
+
75
+ ## API Methods
76
+
77
+ Once created, the TimePicker instance provides the following methods:
78
+
79
+ ### Open, Close, and Toggle
80
+
81
+ ```javascript
82
+ // Open the time picker
83
+ timePicker.open();
84
+
85
+ // Close the time picker
86
+ timePicker.close();
87
+
88
+ // Toggle the time picker open/closed state
89
+ timePicker.toggle();
90
+ ```
91
+
92
+ ### Get and Set Value
93
+
94
+ ```javascript
95
+ // Get the current time value as a string (HH:MM or HH:MM:SS)
96
+ const timeString = timePicker.getValue();
97
+
98
+ // Get the current time as an object with hours, minutes, seconds, and period
99
+ const timeObject = timePicker.getTimeObject();
100
+
101
+ // Set the time value
102
+ timePicker.setValue('15:45');
103
+ ```
104
+
105
+ ### Change Configuration
106
+
107
+ ```javascript
108
+ // Switch between dial and input types
109
+ timePicker.setType(TIME_PICKER_TYPE.INPUT);
110
+
111
+ // Switch between 12-hour and 24-hour formats
112
+ timePicker.setFormat(TIME_FORMAT.MILITARY);
113
+
114
+ // Change the orientation
115
+ timePicker.setOrientation(TIME_PICKER_ORIENTATION.HORIZONTAL);
116
+
117
+ // Update the title
118
+ timePicker.setTitle('Choose departure time');
119
+ ```
120
+
121
+ ### Event Handling
122
+
123
+ ```javascript
124
+ // Listen for time changes
125
+ timePicker.on('change', (time) => {
126
+ console.log('Time changed:', time);
127
+ });
128
+
129
+ // Listen for time picker opening
130
+ timePicker.on('open', () => {
131
+ console.log('Time picker opened');
132
+ });
133
+
134
+ // Remove an event listener
135
+ timePicker.off('change', myHandler);
136
+ ```
137
+
138
+ ### Cleanup
139
+
140
+ ```javascript
141
+ // Destroy the time picker and clean up resources
142
+ timePicker.destroy();
143
+ ```
144
+
145
+ ## Advanced Examples
146
+
147
+ ### 24-Hour Time Picker with Seconds
148
+
149
+ ```javascript
150
+ import { createTimePicker, TIME_FORMAT } from 'mtrl';
151
+
152
+ const timePicker = createTimePicker({
153
+ title: 'Select time',
154
+ value: '18:30:45',
155
+ format: TIME_FORMAT.MILITARY,
156
+ showSeconds: true,
157
+ onConfirm: (time) => {
158
+ console.log('Selected time with seconds:', time);
159
+ }
160
+ });
161
+ ```
162
+
163
+ ### Time Range Selection
164
+
165
+ ```javascript
166
+ import { createTimePicker } from 'mtrl';
167
+
168
+ // Start time picker
169
+ const startTimePicker = createTimePicker({
170
+ title: 'Select start time',
171
+ value: '09:00',
172
+ minTime: '08:00',
173
+ maxTime: '16:00',
174
+ onConfirm: (time) => {
175
+ startTimeInput.value = time;
176
+
177
+ // Update end time constraints
178
+ const [hours, minutes] = time.split(':');
179
+ const startDate = new Date();
180
+ startDate.setHours(parseInt(hours, 10), parseInt(minutes, 10));
181
+
182
+ // Add minimum 30 minutes to start time
183
+ const minEndDate = new Date(startDate);
184
+ minEndDate.setMinutes(minEndDate.getMinutes() + 30);
185
+
186
+ endTimePicker.minTime = `${minEndDate.getHours()}:${minEndDate.getMinutes()}`;
187
+ }
188
+ });
189
+
190
+ // End time picker
191
+ const endTimePicker = createTimePicker({
192
+ title: 'Select end time',
193
+ value: '17:00',
194
+ minTime: '09:30', // Initial minimum (30 min after default start)
195
+ onConfirm: (time) => {
196
+ endTimeInput.value = time;
197
+ }
198
+ });
199
+ ```
200
+
201
+ ## Accessibility
202
+
203
+ The TimePicker component is designed with accessibility in mind:
204
+
205
+ - Keyboard navigation for all controls
206
+ - ARIA attributes for screen reader support
207
+ - Large touch targets for better mobile accessibility
208
+ - High contrast colors and clear visual indicators
209
+ - Support for reducing motion based on user preferences
210
+
211
+ ## Customization
212
+
213
+ ### Custom Styling
214
+
215
+ You can customize the appearance of the TimePicker by overriding the CSS variables and classes:
216
+
217
+ ```css
218
+ /* Custom time picker styling */
219
+ .mtrl-time-picker-dialog {
220
+ --mtrl-primary: #6200ee;
221
+ --mtrl-on-primary: #ffffff;
222
+ --mtrl-surface-container-high: #f5f5f5;
223
+ --mtrl-on-surface: #1d1d1d;
224
+
225
+ /* Add custom shadows */
226
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
227
+ }
228
+
229
+ /* Custom dial styling */
230
+ .mtrl-time-picker-dial-face {
231
+ background-color: rgba(98, 0, 238, 0.05);
232
+ }
233
+
234
+ /* Custom buttons */
235
+ .mtrl-time-picker-confirm {
236
+ font-weight: bold;
237
+ }
238
+ ```
239
+
240
+ ### Custom Icons
241
+
242
+ You can also provide custom icons for the clock and keyboard buttons:
243
+
244
+ ```javascript
245
+ const timePicker = createTimePicker({
246
+ // Other configuration...
247
+ clockIcon: '<svg>...</svg>', // Custom clock icon
248
+ keyboardIcon: '<svg>...</svg>' // Custom keyboard icon
249
+ });
250
+ ```
251
+
252
+ ## Browser Support
253
+
254
+ The TimePicker component supports all modern browsers:
255
+
256
+ - Chrome (latest)
257
+ - Firefox (latest)
258
+ - Safari (latest)
259
+ - Edge (latest)
260
+
261
+ ## TypeScript Support
262
+
263
+ The `TimePicker` component includes comprehensive TypeScript definitions:
264
+
265
+ ```typescript
266
+ import { createTimePicker, TIME_PICKER_TYPE, TIME_FORMAT, TimePickerConfig } from 'mtrl';
267
+
268
+ // Configuration with TypeScript
269
+ const config: TimePickerConfig = {
270
+ title: 'Select time',
271
+ value: '14:30',
272
+ type: TIME_PICKER_TYPE.DIAL,
273
+ format: TIME_FORMAT.AMPM
274
+ };
275
+
276
+ const timePicker = createTimePicker(config);
277
+ ```