mtrl 0.2.8 → 0.3.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.
Files changed (64) hide show
  1. package/index.ts +4 -0
  2. package/package.json +1 -1
  3. package/src/components/button/button.ts +34 -5
  4. package/src/components/navigation/api.ts +131 -96
  5. package/src/components/navigation/features/controller.ts +273 -0
  6. package/src/components/navigation/features/items.ts +133 -64
  7. package/src/components/navigation/navigation.ts +17 -2
  8. package/src/components/navigation/system/core.ts +302 -0
  9. package/src/components/navigation/system/events.ts +240 -0
  10. package/src/components/navigation/system/index.ts +184 -0
  11. package/src/components/navigation/system/mobile.ts +278 -0
  12. package/src/components/navigation/system/state.ts +77 -0
  13. package/src/components/navigation/system/types.ts +364 -0
  14. package/src/components/slider/config.ts +20 -2
  15. package/src/components/slider/features/controller.ts +737 -0
  16. package/src/components/slider/features/handlers.ts +18 -16
  17. package/src/components/slider/features/index.ts +3 -2
  18. package/src/components/slider/features/range.ts +104 -0
  19. package/src/components/slider/schema.ts +141 -0
  20. package/src/components/slider/slider.ts +34 -13
  21. package/src/components/switch/api.ts +16 -0
  22. package/src/components/switch/config.ts +1 -18
  23. package/src/components/switch/features.ts +198 -0
  24. package/src/components/switch/index.ts +1 -0
  25. package/src/components/switch/switch.ts +3 -3
  26. package/src/components/switch/types.ts +14 -2
  27. package/src/components/textfield/api.ts +53 -0
  28. package/src/components/textfield/features.ts +322 -0
  29. package/src/components/textfield/textfield.ts +8 -0
  30. package/src/components/textfield/types.ts +12 -3
  31. package/src/components/timepicker/clockdial.ts +1 -4
  32. package/src/core/compose/features/textinput.ts +15 -2
  33. package/src/core/composition/features/dom.ts +45 -0
  34. package/src/core/composition/features/icon.ts +131 -0
  35. package/src/core/composition/features/index.ts +12 -0
  36. package/src/core/composition/features/label.ts +155 -0
  37. package/src/core/composition/features/layout.ts +47 -0
  38. package/src/core/composition/index.ts +26 -0
  39. package/src/core/index.ts +1 -1
  40. package/src/core/layout/README.md +350 -0
  41. package/src/core/layout/array.ts +181 -0
  42. package/src/core/layout/create.ts +55 -0
  43. package/src/core/layout/index.ts +26 -0
  44. package/src/core/layout/object.ts +124 -0
  45. package/src/core/layout/processor.ts +58 -0
  46. package/src/core/layout/result.ts +85 -0
  47. package/src/core/layout/types.ts +125 -0
  48. package/src/core/layout/utils.ts +136 -0
  49. package/src/index.ts +1 -0
  50. package/src/styles/abstract/_variables.scss +28 -0
  51. package/src/styles/components/_navigation-mobile.scss +244 -0
  52. package/src/styles/components/_navigation-system.scss +151 -0
  53. package/src/styles/components/_switch.scss +133 -69
  54. package/src/styles/components/_textfield.scss +259 -27
  55. package/demo/build.ts +0 -349
  56. package/demo/index.html +0 -110
  57. package/demo/main.js +0 -448
  58. package/demo/styles.css +0 -239
  59. package/server.ts +0 -86
  60. package/src/components/slider/features/slider.ts +0 -318
  61. package/src/components/slider/features/structure.ts +0 -181
  62. package/src/components/slider/features/ui.ts +0 -388
  63. package/src/components/textfield/constants.ts +0 -100
  64. package/src/core/layout/index.js +0 -95
@@ -0,0 +1,77 @@
1
+ // src/components/navigation/system/state.ts
2
+
3
+ import { NavigationSystemConfig, NavigationSystemState } from './types';
4
+
5
+ /**
6
+ * Create the initial state for the navigation system
7
+ *
8
+ * @param options - Configuration options
9
+ * @returns Initial system state
10
+ */
11
+ export const createInitialState = (options: NavigationSystemConfig = {}): NavigationSystemState => {
12
+ return {
13
+ rail: null,
14
+ drawer: null,
15
+ activeSection: options.activeSection || null,
16
+ activeSubsection: options.activeSubsection || null,
17
+ items: options.items || {},
18
+ mouseInDrawer: false,
19
+ mouseInRail: false,
20
+ hoverTimer: null,
21
+ closeTimer: null,
22
+ processingChange: false,
23
+ isMobile: false,
24
+ overlayElement: null,
25
+ closeButtonElement: null,
26
+ resizeObserver: null,
27
+ outsideClickHandler: null,
28
+ outsideClickHandlerSet: false
29
+ };
30
+ };
31
+
32
+ /**
33
+ * Create default configuration with sensible defaults
34
+ *
35
+ * @param options - User-provided configuration
36
+ * @returns Complete configuration with defaults
37
+ */
38
+ export const createConfig = (options: NavigationSystemConfig = {}): Required<Pick<NavigationSystemConfig,
39
+ 'animateDrawer' | 'showLabelsOnRail' | 'hideDrawerOnClick' | 'expanded' |
40
+ 'hoverDelay' | 'closeDelay' | 'railOptions' | 'drawerOptions'>> => {
41
+ return {
42
+ // Display options
43
+ animateDrawer: options.animateDrawer !== false,
44
+ showLabelsOnRail: options.showLabelsOnRail !== false,
45
+ hideDrawerOnClick: options.hideDrawerOnClick || false,
46
+ expanded: options.expanded === true,
47
+
48
+ // Timing options (ms)
49
+ hoverDelay: options.hoverDelay || 200,
50
+ closeDelay: options.closeDelay || 100,
51
+
52
+ // Component options
53
+ railOptions: options.railOptions || {},
54
+ drawerOptions: options.drawerOptions || {}
55
+ };
56
+ };
57
+
58
+ /**
59
+ * Create mobile configuration with defaults
60
+ *
61
+ * @param options - User-provided configuration
62
+ * @returns Mobile-specific configuration
63
+ */
64
+ export const createMobileConfig = (options: NavigationSystemConfig = {}): Required<Pick<NavigationSystemConfig,
65
+ 'breakpoint' | 'lockBodyScroll' | 'hideOnClickOutside' | 'enableSwipeGestures' |
66
+ 'optimizeForTouch' | 'overlayClass' | 'closeButtonClass' | 'bodyLockClass'>> => {
67
+ return {
68
+ breakpoint: options.breakpoint || 960,
69
+ lockBodyScroll: options.lockBodyScroll !== false,
70
+ hideOnClickOutside: options.hideOnClickOutside !== false,
71
+ enableSwipeGestures: options.enableSwipeGestures !== false,
72
+ optimizeForTouch: options.optimizeForTouch !== false,
73
+ overlayClass: options.overlayClass || 'mtrl-nav-overlay',
74
+ closeButtonClass: options.closeButtonClass || 'mtrl-nav-close-btn',
75
+ bodyLockClass: options.bodyLockClass || 'mtrl-body-drawer-open'
76
+ };
77
+ };
@@ -0,0 +1,364 @@
1
+ // src/components/navigation/system/types.ts
2
+
3
+ /**
4
+ * Configuration options for the navigation system
5
+ */
6
+ export interface NavigationSystemConfig {
7
+ /**
8
+ * Screen width breakpoint for mobile mode (in pixels)
9
+ * @default 960
10
+ */
11
+ breakpoint?: number;
12
+
13
+ /**
14
+ * Prevent body scrolling when mobile drawer is open
15
+ * @default true
16
+ */
17
+ lockBodyScroll?: boolean;
18
+
19
+ /**
20
+ * Close drawer when clicking outside of it in mobile mode
21
+ * @default true
22
+ */
23
+ hideOnClickOutside?: boolean;
24
+
25
+ /**
26
+ * Enable swipe gestures for mobile navigation
27
+ * @default true
28
+ */
29
+ enableSwipeGestures?: boolean;
30
+
31
+ /**
32
+ * Optimize touch targets for mobile devices
33
+ * @default true
34
+ */
35
+ optimizeForTouch?: boolean;
36
+
37
+ /**
38
+ * CSS class for the overlay element
39
+ * @default 'mtrl-nav-overlay'
40
+ */
41
+ overlayClass?: string;
42
+
43
+ /**
44
+ * CSS class for the close button
45
+ * @default 'mtrl-nav-close-btn'
46
+ */
47
+ closeButtonClass?: string;
48
+
49
+ /**
50
+ * CSS class applied to body when drawer is open (to prevent scrolling)
51
+ * @default 'mtrl-body-drawer-open'
52
+ */
53
+ bodyLockClass?: string;
54
+
55
+ /**
56
+ * Display labels on rail navigation items
57
+ * @default true
58
+ */
59
+ showLabelsOnRail?: boolean;
60
+
61
+ /**
62
+ * Hide drawer when an item is clicked
63
+ * @default false
64
+ */
65
+ hideDrawerOnClick?: boolean;
66
+
67
+ /**
68
+ * Start with drawer expanded
69
+ * @default false
70
+ */
71
+ expanded?: boolean;
72
+
73
+ /**
74
+ * Delay before opening drawer on hover (in ms)
75
+ * @default 200
76
+ */
77
+ hoverDelay?: number;
78
+
79
+ /**
80
+ * Delay before closing drawer after mouseleave (in ms)
81
+ * @default 100
82
+ */
83
+ closeDelay?: number;
84
+
85
+ /**
86
+ * ID of the initially active section
87
+ */
88
+ activeSection?: string;
89
+
90
+ /**
91
+ * ID of the initially active subsection
92
+ */
93
+ activeSubsection?: string;
94
+
95
+ /**
96
+ * Navigation items configuration
97
+ */
98
+ items?: Record<string, NavigationSection>;
99
+
100
+ /**
101
+ * Additional options for the rail component
102
+ */
103
+ railOptions?: Record<string, any>;
104
+
105
+ /**
106
+ * Additional options for the drawer component
107
+ */
108
+ drawerOptions?: Record<string, any>;
109
+ }
110
+
111
+ /**
112
+ * Navigation section configuration
113
+ */
114
+ export interface NavigationSection {
115
+ /**
116
+ * Display label for the section
117
+ */
118
+ label: string;
119
+
120
+ /**
121
+ * Icon for the section
122
+ */
123
+ icon?: string;
124
+
125
+ /**
126
+ * Subsection items
127
+ */
128
+ items?: NavigationItem[];
129
+ }
130
+
131
+ /**
132
+ * Navigation item configuration
133
+ */
134
+ export interface NavigationItem {
135
+ /**
136
+ * Unique identifier for the item
137
+ */
138
+ id: string;
139
+
140
+ /**
141
+ * Display label for the item
142
+ */
143
+ label: string;
144
+
145
+ /**
146
+ * Icon for the item
147
+ */
148
+ icon?: string;
149
+
150
+ /**
151
+ * Whether the item is currently active
152
+ */
153
+ active?: boolean;
154
+
155
+ /**
156
+ * Additional properties
157
+ */
158
+ [key: string]: any;
159
+ }
160
+
161
+ /**
162
+ * Navigation system state interface
163
+ */
164
+ export interface NavigationSystemState {
165
+ /**
166
+ * Rail navigation component instance
167
+ */
168
+ rail: any;
169
+
170
+ /**
171
+ * Drawer navigation component instance
172
+ */
173
+ drawer: any;
174
+
175
+ /**
176
+ * ID of the active section
177
+ */
178
+ activeSection: string | null;
179
+
180
+ /**
181
+ * ID of the active subsection
182
+ */
183
+ activeSubsection: string | null;
184
+
185
+ /**
186
+ * Navigation items configuration
187
+ */
188
+ items: Record<string, NavigationSection>;
189
+
190
+ /**
191
+ * Whether the mouse is currently inside the drawer
192
+ */
193
+ mouseInDrawer: boolean;
194
+
195
+ /**
196
+ * Whether the mouse is currently inside the rail
197
+ */
198
+ mouseInRail: boolean;
199
+
200
+ /**
201
+ * Timer ID for hover delay
202
+ */
203
+ hoverTimer: number | null;
204
+
205
+ /**
206
+ * Timer ID for close delay
207
+ */
208
+ closeTimer: number | null;
209
+
210
+ /**
211
+ * Whether the system is currently processing a change
212
+ */
213
+ processingChange: boolean;
214
+
215
+ /**
216
+ * Whether the system is in mobile mode
217
+ */
218
+ isMobile: boolean;
219
+
220
+ /**
221
+ * Overlay element for mobile mode
222
+ */
223
+ overlayElement: HTMLElement | null;
224
+
225
+ /**
226
+ * Close button element for mobile mode
227
+ */
228
+ closeButtonElement: HTMLElement | null;
229
+
230
+ /**
231
+ * ResizeObserver instance for responsive behavior
232
+ */
233
+ resizeObserver: ResizeObserver | null;
234
+
235
+ /**
236
+ * Handler function for outside clicks
237
+ */
238
+ outsideClickHandler: ((event: Event) => void) | null;
239
+
240
+ /**
241
+ * Whether outside click handling is set up
242
+ */
243
+ outsideClickHandlerSet: boolean;
244
+ }
245
+
246
+ /**
247
+ * View change event data
248
+ */
249
+ export interface ViewChangeEvent {
250
+ /**
251
+ * Whether the system is now in mobile mode
252
+ */
253
+ mobile: boolean;
254
+
255
+ /**
256
+ * Whether the system was previously in mobile mode
257
+ */
258
+ previousMobile: boolean;
259
+
260
+ /**
261
+ * Current window width
262
+ */
263
+ width: number;
264
+ }
265
+
266
+ /**
267
+ * Navigation system API interface
268
+ */
269
+ export interface NavigationSystem {
270
+ /**
271
+ * Initialize the navigation system
272
+ */
273
+ initialize(): NavigationSystem;
274
+
275
+ /**
276
+ * Clean up resources
277
+ */
278
+ cleanup(): void;
279
+
280
+ /**
281
+ * Navigate to a specific section and subsection
282
+ * @param section - Section ID
283
+ * @param subsection - Subsection ID (optional)
284
+ * @param silent - Whether to suppress change events
285
+ */
286
+ navigateTo(section: string, subsection?: string, silent?: boolean): void;
287
+
288
+ /**
289
+ * Get the rail navigation component
290
+ */
291
+ getRail(): any;
292
+
293
+ /**
294
+ * Get the drawer navigation component
295
+ */
296
+ getDrawer(): any;
297
+
298
+ /**
299
+ * Get the active section ID
300
+ */
301
+ getActiveSection(): string | null;
302
+
303
+ /**
304
+ * Get the active subsection ID
305
+ */
306
+ getActiveSubsection(): string | null;
307
+
308
+ /**
309
+ * Show the drawer
310
+ */
311
+ showDrawer(): void;
312
+
313
+ /**
314
+ * Hide the drawer
315
+ */
316
+ hideDrawer(): void;
317
+
318
+ /**
319
+ * Check if the drawer is visible
320
+ */
321
+ isDrawerVisible(): boolean;
322
+
323
+ /**
324
+ * Update configuration
325
+ * @param newConfig - New configuration options
326
+ */
327
+ configure(newConfig: Partial<NavigationSystemConfig>): NavigationSystem;
328
+
329
+ /**
330
+ * Set processing change state
331
+ * @param isProcessing - Whether a change is being processed
332
+ */
333
+ setProcessingChange(isProcessing: boolean): void;
334
+
335
+ /**
336
+ * Check if a change is being processed
337
+ */
338
+ isProcessingChange(): boolean;
339
+
340
+ /**
341
+ * Check if the system is in mobile mode
342
+ */
343
+ isMobile(): boolean;
344
+
345
+ /**
346
+ * Check and update mobile state
347
+ */
348
+ checkMobileState(): void;
349
+
350
+ /**
351
+ * Handler for section changes
352
+ */
353
+ onSectionChange?: (sectionId: string, eventData: any) => void;
354
+
355
+ /**
356
+ * Handler for item selection
357
+ */
358
+ onItemSelect?: (event: any) => void;
359
+
360
+ /**
361
+ * Handler for view changes (mobile/desktop)
362
+ */
363
+ onViewChange?: (event: ViewChangeEvent) => void;
364
+ }
@@ -5,6 +5,7 @@ import {
5
5
  } from '../../core/config/component-config';
6
6
  import { SliderConfig } from './types';
7
7
  import { SLIDER_COLORS, SLIDER_SIZES } from './constants';
8
+ import { createSliderSchema } from './schema';
8
9
 
9
10
  /**
10
11
  * Default configuration for the Slider component
@@ -31,8 +32,25 @@ export const defaultConfig: SliderConfig = {
31
32
  * @param {SliderConfig} config - User provided configuration
32
33
  * @returns {SliderConfig} Complete configuration with defaults applied
33
34
  */
34
- export const createBaseConfig = (config: SliderConfig = {}): SliderConfig =>
35
- createComponentConfig(defaultConfig, config, 'slider') as SliderConfig;
35
+ export const createBaseConfig = (config: SliderConfig = {}): SliderConfig => {
36
+ // Create the base config with defaults applied
37
+ const baseConfig = createComponentConfig(defaultConfig, config, 'slider') as SliderConfig;
38
+
39
+ // Create a basic component object for structure generation
40
+ const baseComponent = {
41
+ componentName: 'slider',
42
+ config: baseConfig,
43
+ getClass: (className) => {
44
+ const prefix = baseConfig.prefix || 'mtrl';
45
+ return `${prefix}-${className}`;
46
+ }
47
+ };
48
+
49
+ // Add the structure definition to the config
50
+ baseConfig.schema = createSliderSchema(baseComponent, baseConfig);
51
+
52
+ return baseConfig;
53
+ };
36
54
 
37
55
  /**
38
56
  * Generates element configuration for the Slider component