mtrl 0.2.6 → 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 (147) hide show
  1. package/index.ts +18 -0
  2. package/package.json +1 -1
  3. package/src/components/badge/_styles.scss +117 -109
  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 -10
  16. package/src/components/button/api.ts +5 -0
  17. package/src/components/button/config.ts +5 -0
  18. package/src/components/button/types.ts +6 -0
  19. package/src/components/card/card.ts +13 -25
  20. package/src/components/card/config.ts +67 -22
  21. package/src/components/card/features.ts +3 -0
  22. package/src/components/card/types.ts +28 -0
  23. package/src/components/checkbox/_styles.scss +0 -2
  24. package/src/components/datepicker/_styles.scss +358 -0
  25. package/src/components/datepicker/api.ts +272 -0
  26. package/src/components/datepicker/config.ts +144 -0
  27. package/src/components/datepicker/constants.ts +98 -0
  28. package/src/components/datepicker/datepicker.ts +346 -0
  29. package/src/components/datepicker/index.ts +9 -0
  30. package/src/components/datepicker/render.ts +452 -0
  31. package/src/components/datepicker/types.ts +268 -0
  32. package/src/components/datepicker/utils.ts +290 -0
  33. package/src/components/dialog/_styles.scss +174 -128
  34. package/src/components/dialog/api.ts +48 -13
  35. package/src/components/dialog/config.ts +9 -5
  36. package/src/components/dialog/dialog.ts +6 -3
  37. package/src/components/dialog/features.ts +290 -130
  38. package/src/components/dialog/types.ts +7 -4
  39. package/src/components/divider/_styles.scss +57 -0
  40. package/src/components/divider/config.ts +81 -0
  41. package/src/components/divider/divider.ts +37 -0
  42. package/src/components/divider/features.ts +207 -0
  43. package/src/components/divider/index.ts +5 -0
  44. package/src/components/divider/types.ts +55 -0
  45. package/src/components/extended-fab/_styles.scss +267 -0
  46. package/src/components/extended-fab/api.ts +141 -0
  47. package/src/components/extended-fab/config.ts +108 -0
  48. package/src/components/extended-fab/constants.ts +36 -0
  49. package/src/components/extended-fab/extended-fab.ts +125 -0
  50. package/src/components/extended-fab/index.ts +4 -0
  51. package/src/components/extended-fab/types.ts +287 -0
  52. package/src/components/fab/_styles.scss +225 -0
  53. package/src/components/fab/api.ts +97 -0
  54. package/src/components/fab/config.ts +94 -0
  55. package/src/components/fab/constants.ts +41 -0
  56. package/src/components/fab/fab.ts +67 -0
  57. package/src/components/fab/index.ts +4 -0
  58. package/src/components/fab/types.ts +234 -0
  59. package/src/components/navigation/_styles.scss +1 -0
  60. package/src/components/navigation/api.ts +78 -50
  61. package/src/components/navigation/features/items.ts +280 -0
  62. package/src/components/navigation/nav-item.ts +72 -23
  63. package/src/components/navigation/navigation.ts +54 -2
  64. package/src/components/navigation/types.ts +210 -188
  65. package/src/components/search/_styles.scss +306 -0
  66. package/src/components/search/api.ts +203 -0
  67. package/src/components/search/config.ts +87 -0
  68. package/src/components/search/constants.ts +21 -0
  69. package/src/components/search/features/index.ts +4 -0
  70. package/src/components/search/features/search.ts +718 -0
  71. package/src/components/search/features/states.ts +165 -0
  72. package/src/components/search/features/structure.ts +198 -0
  73. package/src/components/search/index.ts +10 -0
  74. package/src/components/search/search.ts +52 -0
  75. package/src/components/search/types.ts +163 -0
  76. package/src/components/segmented-button/_styles.scss +117 -0
  77. package/src/components/segmented-button/config.ts +67 -0
  78. package/src/components/segmented-button/constants.ts +42 -0
  79. package/src/components/segmented-button/index.ts +4 -0
  80. package/src/components/segmented-button/segment.ts +155 -0
  81. package/src/components/segmented-button/segmented-button.ts +250 -0
  82. package/src/components/segmented-button/types.ts +219 -0
  83. package/src/components/slider/_styles.scss +83 -24
  84. package/src/components/slider/accessibility.md +5 -5
  85. package/src/components/slider/api.ts +41 -120
  86. package/src/components/slider/config.ts +51 -47
  87. package/src/components/slider/features/handlers.ts +495 -0
  88. package/src/components/slider/features/index.ts +1 -2
  89. package/src/components/slider/features/slider.ts +66 -84
  90. package/src/components/slider/features/states.ts +195 -0
  91. package/src/components/slider/features/structure.ts +136 -206
  92. package/src/components/slider/features/ui.ts +145 -206
  93. package/src/components/slider/index.ts +2 -11
  94. package/src/components/slider/slider.ts +9 -12
  95. package/src/components/slider/types.ts +39 -24
  96. package/src/components/switch/_styles.scss +0 -2
  97. package/src/components/tabs/_styles.scss +94 -32
  98. package/src/components/tabs/features.ts +4 -2
  99. package/src/components/tabs/indicator.ts +73 -13
  100. package/src/components/tabs/types.ts +10 -2
  101. package/src/components/timepicker/README.md +277 -0
  102. package/src/components/timepicker/_styles.scss +451 -0
  103. package/src/components/timepicker/api.ts +632 -0
  104. package/src/components/timepicker/clockdial.ts +482 -0
  105. package/src/components/timepicker/config.ts +130 -0
  106. package/src/components/timepicker/constants.ts +138 -0
  107. package/src/components/timepicker/index.ts +8 -0
  108. package/src/components/timepicker/render.ts +613 -0
  109. package/src/components/timepicker/timepicker.ts +117 -0
  110. package/src/components/timepicker/types.ts +336 -0
  111. package/src/components/timepicker/utils.ts +241 -0
  112. package/src/components/top-app-bar/_styles.scss +225 -0
  113. package/src/components/top-app-bar/config.ts +83 -0
  114. package/src/components/top-app-bar/index.ts +11 -0
  115. package/src/components/top-app-bar/top-app-bar.ts +316 -0
  116. package/src/components/top-app-bar/types.ts +140 -0
  117. package/src/core/build/_ripple.scss +6 -6
  118. package/src/core/build/ripple.ts +72 -95
  119. package/src/core/compose/features/icon.ts +3 -1
  120. package/src/core/compose/features/ripple.ts +4 -1
  121. package/src/core/compose/features/textlabel.ts +26 -2
  122. package/src/core/dom/create.ts +5 -0
  123. package/src/index.ts +9 -0
  124. package/src/styles/abstract/_theme.scss +9 -1
  125. package/src/styles/themes/_autumn.scss +21 -0
  126. package/src/styles/themes/_base-theme.scss +61 -0
  127. package/src/styles/themes/_baseline.scss +58 -0
  128. package/src/styles/themes/_bluekhaki.scss +125 -0
  129. package/src/styles/themes/_brownbeige.scss +125 -0
  130. package/src/styles/themes/_browngreen.scss +125 -0
  131. package/src/styles/themes/_forest.scss +6 -0
  132. package/src/styles/themes/_greenbeige.scss +125 -0
  133. package/src/styles/themes/_material.scss +125 -0
  134. package/src/styles/themes/_ocean.scss +6 -0
  135. package/src/styles/themes/_sageivory.scss +125 -0
  136. package/src/styles/themes/_spring.scss +6 -0
  137. package/src/styles/themes/_summer.scss +5 -0
  138. package/src/styles/themes/_sunset.scss +5 -0
  139. package/src/styles/themes/_tealcaramel.scss +125 -0
  140. package/src/styles/themes/_winter.scss +6 -0
  141. package/src/components/navigation/features/items.js +0 -192
  142. package/src/components/slider/features/appearance.ts +0 -94
  143. package/src/components/slider/features/disabled.ts +0 -68
  144. package/src/components/slider/features/events.ts +0 -164
  145. package/src/components/slider/features/interactions.ts +0 -396
  146. package/src/components/slider/features/keyboard.ts +0 -233
  147. package/src/core/collection/adapters/mongodb.js +0 -232
@@ -27,6 +27,21 @@ export enum CardElevation {
27
27
  LEVEL4 = 4
28
28
  }
29
29
 
30
+ /**
31
+ * Button configuration interface for buttons shorthand
32
+ * @interface ButtonConfig
33
+ */
34
+ export interface ButtonConfig {
35
+ /** Button text */
36
+ text?: string;
37
+ /** Button variant */
38
+ variant?: string;
39
+ /** Button icon */
40
+ icon?: string;
41
+ /** Additional button properties */
42
+ [key: string]: any;
43
+ }
44
+
30
45
  /**
31
46
  * Card configuration interface
32
47
  * @interface CardSchema
@@ -54,6 +69,19 @@ export interface CardSchema {
54
69
  mediaConfig?: CardMediaConfig;
55
70
  /** ARIA attributes for accessibility */
56
71
  aria?: CardAriaAttributes;
72
+
73
+ // New inline configuration options
74
+ /** Inline header configuration (alternative to headerConfig) */
75
+ header?: CardHeaderConfig;
76
+ /** Inline content configuration (alternative to contentConfig) */
77
+ content?: CardContentConfig;
78
+ /** Inline media configuration (alternative to mediaConfig) */
79
+ media?: CardMediaConfig;
80
+ /** Inline actions configuration (alternative to actionsConfig) */
81
+ actions?: CardActionsConfig;
82
+ /** Simple buttons array for actions (will be converted to actionsConfig) */
83
+ buttons?: ButtonConfig[];
84
+
57
85
  /** Internal component name */
58
86
  componentName?: string;
59
87
  /** CSS class prefix */
@@ -70,8 +70,6 @@ $component: '#{base.$prefix}-checkbox';
70
70
 
71
71
  // Label position variants
72
72
  &--label-start {
73
- flex-direction: row-reverse;
74
-
75
73
  .#{$component}-label {
76
74
  margin-left: 0;
77
75
  margin-right: 12px;
@@ -0,0 +1,358 @@
1
+ // src/components/datepicker/_styles.scss
2
+ @use '../../styles/abstract/base' as base;
3
+ @use '../../styles/abstract/variables' as v;
4
+ @use '../../styles/abstract/functions' as f;
5
+ @use '../../styles/abstract/mixins' as m;
6
+ @use '../../styles/abstract/theme' as t;
7
+
8
+ $component: '#{base.$prefix}-datepicker';
9
+
10
+ .#{$component} {
11
+ &-container {
12
+ position: relative;
13
+ display: inline-flex;
14
+ flex-direction: column;
15
+ width: 100%;
16
+ min-width: 280px;
17
+ max-width: 360px;
18
+ }
19
+
20
+ &-input {
21
+ display: flex;
22
+ height: 40px;
23
+ width: 100%;
24
+ padding: 0 12px;
25
+ border: 1px solid t.color('outline');
26
+ border-radius: 4px;
27
+ background-color: t.color('surface');
28
+ color: t.color('on-surface');
29
+ font-family: inherit;
30
+ font-size: 16px;
31
+ line-height: 24px;
32
+ transition: border-color 0.2s ease;
33
+ cursor: pointer;
34
+
35
+ &:hover {
36
+ border-color: t.color('on-surface-variant');
37
+ }
38
+
39
+ &:focus {
40
+ outline: none;
41
+ border-color: t.color('primary');
42
+ border-width: 2px;
43
+ padding: 0 11px; // Adjust for increased border width
44
+ }
45
+
46
+ &:disabled {
47
+ opacity: 0.38;
48
+ cursor: not-allowed;
49
+ border-color: t.color('outline');
50
+ background-color: t.alpha('on-surface', 0.04);
51
+ }
52
+ }
53
+
54
+ &-calendar {
55
+ position: absolute;
56
+ top: 100%;
57
+ left: 0;
58
+ z-index: 10;
59
+ margin-top: 8px;
60
+ background-color: t.color('surface-container-high');
61
+ border-radius: v.shape('large');
62
+ box-shadow: v.elevation('level3');
63
+ overflow: hidden;
64
+
65
+ &-content {
66
+ display: flex;
67
+ flex-direction: column;
68
+ padding: 16px;
69
+ }
70
+ }
71
+
72
+ &-header {
73
+ display: flex;
74
+ align-items: center;
75
+ justify-content: space-between;
76
+ margin-bottom: 16px;
77
+ }
78
+
79
+ &-month-selector,
80
+ &-year-selector {
81
+ padding: 8px 12px;
82
+ border: none;
83
+ background: none;
84
+ color: t.color('on-surface-variant');
85
+ @include m.typography('title-small');
86
+ cursor: pointer;
87
+ border-radius: v.shape('full');
88
+
89
+ &:hover {
90
+ background-color: t.alpha('on-surface', 0.08);
91
+ }
92
+
93
+ &:focus {
94
+ outline: none;
95
+ background-color: t.alpha('on-surface', 0.12);
96
+ }
97
+ }
98
+
99
+ &-nav-controls {
100
+ display: flex;
101
+ align-items: center;
102
+ }
103
+
104
+ &-prev-btn,
105
+ &-next-btn {
106
+ display: flex;
107
+ align-items: center;
108
+ justify-content: center;
109
+ width: 40px;
110
+ height: 40px;
111
+ border: none;
112
+ background: none;
113
+ border-radius: 50%;
114
+ color: t.color('on-surface-variant');
115
+ cursor: pointer;
116
+
117
+ &:hover {
118
+ background-color: t.alpha('on-surface', 0.08);
119
+ }
120
+
121
+ &:focus {
122
+ outline: none;
123
+ background-color: t.alpha('on-surface', 0.12);
124
+ }
125
+
126
+ svg {
127
+ width: 24px;
128
+ height: 24px;
129
+ }
130
+ }
131
+
132
+ &-weekdays {
133
+ display: grid;
134
+ grid-template-columns: repeat(7, 1fr);
135
+ margin-bottom: 8px;
136
+ }
137
+
138
+ &-weekday {
139
+ display: flex;
140
+ align-items: center;
141
+ justify-content: center;
142
+ height: 40px;
143
+ @include m.typography('body-small');
144
+ color: t.color('on-surface-variant');
145
+ font-weight: 500;
146
+ }
147
+
148
+ &-days {
149
+ display: grid;
150
+ grid-template-columns: repeat(7, 1fr);
151
+ gap: 0;
152
+ }
153
+
154
+ &-day {
155
+ display: flex;
156
+ align-items: center;
157
+ justify-content: center;
158
+ width: 40px;
159
+ height: 40px;
160
+ border: none;
161
+ background: none;
162
+ border-radius: 50%;
163
+ @include m.typography('body-medium');
164
+ color: t.color('on-surface');
165
+ cursor: pointer;
166
+
167
+ // &:hover:not(:disabled) {
168
+ // background-color: t.alpha('on-surface', 0.08);
169
+ // }
170
+
171
+ &:focus {
172
+ outline: none;
173
+ background-color: t.alpha('on-surface', 0.12);
174
+ }
175
+
176
+ &.outside-month {
177
+ color: t.color('on-surface-variant');
178
+ opacity: 0.6;
179
+ }
180
+
181
+ &.today {
182
+ position: relative;
183
+ &::before {
184
+ position: absolute;
185
+ border-radius: 50%;
186
+ height: 100%;
187
+ width: 100%;
188
+ content: '';
189
+ border: 1px solid t.color('primary');
190
+ }
191
+
192
+ }
193
+
194
+ &.selected {
195
+ background-color: t.color('primary');
196
+ color: t.color('on-primary');
197
+ }
198
+
199
+ &:disabled {
200
+ color: t.color('on-surface-variant');
201
+ opacity: 0.38;
202
+ cursor: not-allowed;
203
+ }
204
+
205
+ &.range-start,
206
+ &.range-end {
207
+ background-color: t.color('primary');
208
+ color: t.color('on-primary');
209
+ }
210
+
211
+ &.range-middle {
212
+ background-color: t.alpha('primary-container', 0.18);
213
+ color: t.color('on-primary-container');
214
+ border-radius: 0;
215
+ }
216
+ }
217
+
218
+ &-months,
219
+ &-years {
220
+ display: grid;
221
+ grid-template-columns: repeat(3, 1fr);
222
+ gap: 8px;
223
+ padding: 16px 0;
224
+ }
225
+
226
+ &-month,
227
+ &-year {
228
+ display: flex;
229
+ align-items: center;
230
+ justify-content: center;
231
+ height: 36px;
232
+ border: none;
233
+ background: none;
234
+ border-radius: v.shape('medium');
235
+ @include m.typography('body-medium');
236
+ color: t.color('on-surface');
237
+ cursor: pointer;
238
+
239
+ &:hover {
240
+ background-color: t.alpha('on-surface', 0.08);
241
+ }
242
+
243
+ &:focus {
244
+ outline: none;
245
+ background-color: t.alpha('on-surface', 0.12);
246
+ }
247
+
248
+ &.selected {
249
+ background-color: t.color('primary');
250
+ color: t.color('on-primary');
251
+ }
252
+ }
253
+
254
+ &-footer {
255
+ display: flex;
256
+ justify-content: flex-end;
257
+ padding: 8px 16px 8px 0;
258
+ margin-top: 16px;
259
+
260
+ button {
261
+ margin-left: 8px;
262
+ }
263
+ }
264
+
265
+ // Modal-specific styles
266
+ &-modal {
267
+ position: fixed;
268
+ top: 50%;
269
+ left: 50%;
270
+ transform: translate(-50%, -50%);
271
+ z-index: v.z-index('modal');
272
+ width: 328px;
273
+ max-width: 90vw;
274
+
275
+ &-overlay {
276
+ position: fixed;
277
+ top: 0;
278
+ left: 0;
279
+ right: 0;
280
+ bottom: 0;
281
+ background-color: rgba(0, 0, 0, 0.5);
282
+ z-index: v.z-index('modal') - 1;
283
+ }
284
+ }
285
+
286
+ // Full-screen modal for mobile
287
+ @media (max-width: 600px) {
288
+ &-modal {
289
+ width: 100%;
290
+ height: 100%;
291
+ max-width: none;
292
+ top: 0;
293
+ left: 0;
294
+ transform: none;
295
+ border-radius: 0;
296
+
297
+ &-header {
298
+ height: 56px;
299
+ padding: 0 16px;
300
+ border-bottom: 1px solid t.color('outline-variant');
301
+ }
302
+ }
303
+ }
304
+
305
+ // Range selection styles
306
+ &-range {
307
+ .#{$component}-days {
308
+ .#{$component}-day {
309
+ &.range-start {
310
+ position: relative;
311
+ // border-top-right-radius: 0;
312
+ // border-bottom-right-radius: 0;
313
+ &::before {
314
+ position: absolute;
315
+ content: '';
316
+ right: 0;
317
+ width: 50%;
318
+ height: 100%;
319
+ background-color: t.alpha('primary', 0.1);
320
+ }
321
+ }
322
+
323
+ &.range-end {
324
+ position: relative;
325
+ // border-top-left-radius: 0;
326
+ // border-bottom-left-radius: 0;
327
+ &::before {
328
+ position: absolute;
329
+ content: '';
330
+ left: 0;
331
+ width: 50%;
332
+ height: 100%;
333
+ background-color: t.alpha('primary', 0.1);
334
+ }
335
+ }
336
+ }
337
+ }
338
+ }
339
+
340
+ // Animation
341
+ &-animate {
342
+ .#{$component}-calendar {
343
+ animation: datepicker-fade-in 0.2s ease;
344
+ }
345
+ }
346
+ }
347
+
348
+ // Animations
349
+ @keyframes datepicker-fade-in {
350
+ from {
351
+ opacity: 0;
352
+ transform: translateY(-10px);
353
+ }
354
+ to {
355
+ opacity: 1;
356
+ transform: translateY(0);
357
+ }
358
+ }
@@ -0,0 +1,272 @@
1
+ // src/components/datepicker/api.ts
2
+ import { DatePickerComponent } from './types';
3
+ import {
4
+ formatDate,
5
+ parseDate,
6
+ isSameDay,
7
+ generateCalendarDates,
8
+ addMonths,
9
+ addYears
10
+ } from './utils';
11
+ import { DATEPICKER_VIEWS, DATEPICKER_SELECTION_MODES } from './constants';
12
+
13
+ interface ApiOptions {
14
+ disabled: {
15
+ enable: () => void;
16
+ disable: () => void;
17
+ };
18
+ lifecycle: {
19
+ destroy: () => void;
20
+ };
21
+ events: {
22
+ on: (event: string, handler: Function) => any;
23
+ off: (event: string, handler: Function) => any;
24
+ emit: (event: string, data: any) => any;
25
+ };
26
+ }
27
+
28
+ /**
29
+ * Enhances a datepicker component with API methods
30
+ * @param {object} state - Current state of the datepicker
31
+ * @param {ApiOptions} options - API configuration options
32
+ * @returns {Function} Higher-order function that adds API methods to component
33
+ * @internal This is an internal utility for the DatePicker component
34
+ */
35
+ export const withAPI = (state: any, { disabled, lifecycle, events }: ApiOptions) =>
36
+ (component: any): DatePickerComponent => {
37
+ // Calendar navigation API
38
+ const calendar = {
39
+ goToDate(date: Date): void {
40
+ const validDate = parseDate(date);
41
+ if (!validDate) return;
42
+
43
+ state.currentMonth = validDate.getMonth();
44
+ state.currentYear = validDate.getFullYear();
45
+
46
+ // Update calendar view
47
+ state.updateCalendar();
48
+ },
49
+
50
+ nextMonth(): void {
51
+ const newDate = addMonths(new Date(state.currentYear, state.currentMonth, 1), 1);
52
+ state.currentMonth = newDate.getMonth();
53
+ state.currentYear = newDate.getFullYear();
54
+
55
+ // Update calendar view
56
+ state.updateCalendar();
57
+ },
58
+
59
+ prevMonth(): void {
60
+ const newDate = addMonths(new Date(state.currentYear, state.currentMonth, 1), -1);
61
+ state.currentMonth = newDate.getMonth();
62
+ state.currentYear = newDate.getFullYear();
63
+
64
+ // Update calendar view
65
+ state.updateCalendar();
66
+ },
67
+
68
+ nextYear(): void {
69
+ state.currentYear += 1;
70
+
71
+ // Update calendar view
72
+ state.updateCalendar();
73
+ },
74
+
75
+ prevYear(): void {
76
+ state.currentYear -= 1;
77
+
78
+ // Update calendar view
79
+ state.updateCalendar();
80
+ },
81
+
82
+ showDayView(): void {
83
+ state.currentView = DATEPICKER_VIEWS.DAY;
84
+ state.updateCalendar();
85
+ },
86
+
87
+ showMonthView(): void {
88
+ state.currentView = DATEPICKER_VIEWS.MONTH;
89
+ state.updateCalendar();
90
+ },
91
+
92
+ showYearView(): void {
93
+ state.currentView = DATEPICKER_VIEWS.YEAR;
94
+ state.updateCalendar();
95
+ },
96
+
97
+ getCurrentView(): string {
98
+ return state.currentView;
99
+ }
100
+ };
101
+
102
+ return {
103
+ ...component as any,
104
+ element: component.element,
105
+ input: state.input,
106
+ calendar,
107
+
108
+ open(): DatePickerComponent {
109
+ state.isOpen = true;
110
+ state.render();
111
+ events.emit('open', { value: this.getValue() });
112
+ return this;
113
+ },
114
+
115
+ close(): DatePickerComponent {
116
+ state.isOpen = false;
117
+ state.render();
118
+ events.emit('close', { value: this.getValue() });
119
+ return this;
120
+ },
121
+
122
+ getValue(): Date | [Date, Date] | null {
123
+ if (!state.selectedDate) return null;
124
+
125
+ // Range selection
126
+ if (state.selectionMode === DATEPICKER_SELECTION_MODES.RANGE && state.rangeEndDate) {
127
+ return [new Date(state.selectedDate), new Date(state.rangeEndDate)];
128
+ }
129
+
130
+ // Single selection
131
+ return new Date(state.selectedDate);
132
+ },
133
+
134
+ setValue(value: Date | string | [Date | string, Date | string]): DatePickerComponent {
135
+ // Handle range selection
136
+ if (Array.isArray(value) && state.selectionMode === DATEPICKER_SELECTION_MODES.RANGE) {
137
+ const start = parseDate(value[0]);
138
+ const end = parseDate(value[1]);
139
+
140
+ if (start && end) {
141
+ state.selectedDate = start;
142
+ state.rangeEndDate = end;
143
+
144
+ // Ensure start date is before end date
145
+ if (start > end) {
146
+ state.selectedDate = end;
147
+ state.rangeEndDate = start;
148
+ }
149
+
150
+ // Update input value
151
+ state.updateInputValue();
152
+
153
+ // Update calendar if it's open
154
+ if (state.isOpen) {
155
+ // Set current month/year to the start date's month/year
156
+ state.currentMonth = state.selectedDate.getMonth();
157
+ state.currentYear = state.selectedDate.getFullYear();
158
+ state.updateCalendar();
159
+ }
160
+
161
+ events.emit('change', {
162
+ value: this.getValue(),
163
+ formattedValue: this.getFormattedValue()
164
+ });
165
+ }
166
+
167
+ return this;
168
+ }
169
+
170
+ // Handle single date selection
171
+ const parsedDate = parseDate(value as Date | string);
172
+ if (parsedDate) {
173
+ state.selectedDate = parsedDate;
174
+ state.rangeEndDate = null;
175
+
176
+ // Update input value
177
+ state.updateInputValue();
178
+
179
+ // Update calendar if it's open
180
+ if (state.isOpen) {
181
+ state.currentMonth = parsedDate.getMonth();
182
+ state.currentYear = parsedDate.getFullYear();
183
+ state.updateCalendar();
184
+ }
185
+
186
+ events.emit('change', {
187
+ value: this.getValue(),
188
+ formattedValue: this.getFormattedValue()
189
+ });
190
+ }
191
+
192
+ return this;
193
+ },
194
+
195
+ getFormattedValue(): string {
196
+ if (!state.selectedDate) return '';
197
+
198
+ // Range selection
199
+ if (state.selectionMode === DATEPICKER_SELECTION_MODES.RANGE && state.rangeEndDate) {
200
+ const startStr = formatDate(state.selectedDate, state.dateFormat);
201
+ const endStr = formatDate(state.rangeEndDate, state.dateFormat);
202
+ return `${startStr} - ${endStr}`;
203
+ }
204
+
205
+ // Single selection
206
+ return formatDate(state.selectedDate, state.dateFormat);
207
+ },
208
+
209
+ clear(): DatePickerComponent {
210
+ state.selectedDate = null;
211
+ state.rangeEndDate = null;
212
+ state.updateInputValue();
213
+
214
+ if (state.isOpen) {
215
+ state.updateCalendar();
216
+ }
217
+
218
+ events.emit('change', { value: null, formattedValue: '' });
219
+ return this;
220
+ },
221
+
222
+ enable(): DatePickerComponent {
223
+ disabled.enable();
224
+ return this;
225
+ },
226
+
227
+ disable(): DatePickerComponent {
228
+ disabled.disable();
229
+ return this;
230
+ },
231
+
232
+ setMinDate(date: Date | string): DatePickerComponent {
233
+ const parsedDate = parseDate(date);
234
+ if (parsedDate) {
235
+ state.minDate = parsedDate;
236
+
237
+ // Update calendar if it's open
238
+ if (state.isOpen) {
239
+ state.updateCalendar();
240
+ }
241
+ }
242
+ return this;
243
+ },
244
+
245
+ setMaxDate(date: Date | string): DatePickerComponent {
246
+ const parsedDate = parseDate(date);
247
+ if (parsedDate) {
248
+ state.maxDate = parsedDate;
249
+
250
+ // Update calendar if it's open
251
+ if (state.isOpen) {
252
+ state.updateCalendar();
253
+ }
254
+ }
255
+ return this;
256
+ },
257
+
258
+ destroy(): void {
259
+ lifecycle.destroy();
260
+ },
261
+
262
+ on(event: string, handler: Function): DatePickerComponent {
263
+ events.on(event, handler);
264
+ return this;
265
+ },
266
+
267
+ off(event: string, handler: Function): DatePickerComponent {
268
+ events.off(event, handler);
269
+ return this;
270
+ }
271
+ };
272
+ };