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
@@ -25,14 +25,4 @@ export const CHIP_VARIANTS = {
25
25
 
26
26
  /** Suggestion chip for presenting options */
27
27
  SUGGESTION: 'suggestion'
28
- };
29
-
30
- /**
31
- * Available sizes for the Chip component
32
- * @enum {string}
33
- */
34
- export const CHIP_SIZES = {
35
- SMALL: 'small',
36
- MEDIUM: 'medium',
37
- LARGE: 'large'
38
28
  };
@@ -1,4 +1,4 @@
1
1
  // src/components/chip/index.js
2
2
  export { default } from './chip'
3
3
  export { default as createChipSet } from './chip-set'
4
- export { CHIP_VARIANTS, CHIP_SIZES } from './constants'
4
+ export { CHIP_VARIANTS } from './constants'
@@ -1,5 +1,5 @@
1
1
  // src/components/chip/types.ts
2
- import { CHIP_VARIANTS, CHIP_SIZES } from './constants';
2
+ import { CHIP_VARIANTS } from './constants';
3
3
 
4
4
  /**
5
5
  * Configuration interface for the Chip component
@@ -8,9 +8,6 @@ export interface ChipConfig {
8
8
  /** Chip variant (filled, outlined, elevated, assist, filter, input, suggestion) */
9
9
  variant?: keyof typeof CHIP_VARIANTS | string;
10
10
 
11
- /** Chip size (small, medium, large) */
12
- size?: keyof typeof CHIP_SIZES | string;
13
-
14
11
  /** Whether the chip is initially disabled */
15
12
  disabled?: boolean;
16
13
 
@@ -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
+ };