mtrl 0.2.6 → 0.2.8

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 (226) hide show
  1. package/demo/build.ts +349 -0
  2. package/demo/index.html +110 -0
  3. package/demo/main.js +448 -0
  4. package/demo/styles.css +239 -0
  5. package/index.ts +18 -0
  6. package/package.json +14 -3
  7. package/server.ts +86 -0
  8. package/src/components/badge/api.ts +70 -63
  9. package/src/components/badge/badge.ts +16 -2
  10. package/src/components/badge/config.ts +66 -13
  11. package/src/components/badge/features.ts +51 -42
  12. package/src/components/badge/index.ts +27 -2
  13. package/src/components/badge/types.ts +62 -30
  14. package/src/components/bottom-app-bar/bottom-app-bar.ts +154 -0
  15. package/src/components/bottom-app-bar/config.ts +29 -0
  16. package/src/components/bottom-app-bar/index.ts +17 -0
  17. package/src/components/bottom-app-bar/types.ts +114 -0
  18. package/src/components/button/api.ts +5 -0
  19. package/src/components/button/button.ts +0 -1
  20. package/src/components/button/config.ts +6 -2
  21. package/src/components/button/index.ts +10 -2
  22. package/src/components/button/types.ts +20 -2
  23. package/src/components/card/card.ts +13 -25
  24. package/src/components/card/config.ts +83 -30
  25. package/src/components/card/content.ts +8 -10
  26. package/src/components/card/features.ts +4 -3
  27. package/src/components/card/index.ts +29 -2
  28. package/src/components/card/types.ts +33 -22
  29. package/src/components/checkbox/config.ts +3 -4
  30. package/src/components/checkbox/index.ts +1 -2
  31. package/src/components/checkbox/types.ts +12 -3
  32. package/src/components/chip/api.ts +170 -221
  33. package/src/components/chip/chip.ts +34 -302
  34. package/src/components/chip/config.ts +1 -2
  35. package/src/components/chip/index.ts +10 -2
  36. package/src/components/chip/types.ts +224 -35
  37. package/src/components/datepicker/api.ts +265 -0
  38. package/src/components/datepicker/config.ts +141 -0
  39. package/src/components/datepicker/datepicker.ts +341 -0
  40. package/src/components/datepicker/index.ts +12 -0
  41. package/src/components/datepicker/render.ts +450 -0
  42. package/src/components/datepicker/types.ts +397 -0
  43. package/src/components/datepicker/utils.ts +289 -0
  44. package/src/components/dialog/api.ts +55 -21
  45. package/src/components/dialog/config.ts +12 -9
  46. package/src/components/dialog/dialog.ts +6 -3
  47. package/src/components/dialog/features.ts +345 -151
  48. package/src/components/dialog/index.ts +38 -8
  49. package/src/components/dialog/types.ts +40 -14
  50. package/src/components/divider/config.ts +81 -0
  51. package/src/components/divider/divider.ts +37 -0
  52. package/src/components/divider/features.ts +207 -0
  53. package/src/components/divider/index.ts +9 -0
  54. package/src/components/divider/types.ts +55 -0
  55. package/src/components/extended-fab/api.ts +141 -0
  56. package/src/components/extended-fab/config.ts +112 -0
  57. package/src/components/extended-fab/extended-fab.ts +125 -0
  58. package/src/components/extended-fab/index.ts +9 -0
  59. package/src/components/extended-fab/types.ts +304 -0
  60. package/src/components/fab/api.ts +97 -0
  61. package/src/components/fab/config.ts +93 -0
  62. package/src/components/fab/fab.ts +67 -0
  63. package/src/components/fab/index.ts +9 -0
  64. package/src/components/fab/types.ts +251 -0
  65. package/src/components/list/config.ts +4 -5
  66. package/src/components/list/features.ts +6 -7
  67. package/src/components/list/index.ts +7 -9
  68. package/src/components/list/list-item.ts +12 -13
  69. package/src/components/list/types.ts +50 -5
  70. package/src/components/list/utils.ts +30 -3
  71. package/src/components/menu/features/items-manager.ts +9 -9
  72. package/src/components/menu/features/positioning.ts +7 -7
  73. package/src/components/menu/features/visibility.ts +7 -7
  74. package/src/components/menu/index.ts +7 -9
  75. package/src/components/menu/menu-item.ts +6 -6
  76. package/src/components/menu/menu.ts +22 -0
  77. package/src/components/menu/types.ts +29 -10
  78. package/src/components/menu/utils.ts +67 -0
  79. package/src/components/navigation/api.ts +78 -50
  80. package/src/components/navigation/config.ts +22 -10
  81. package/src/components/navigation/features/items.ts +284 -0
  82. package/src/components/navigation/index.ts +0 -6
  83. package/src/components/navigation/nav-item.ts +70 -33
  84. package/src/components/navigation/navigation.ts +53 -3
  85. package/src/components/navigation/types.ts +117 -70
  86. package/src/components/progress/api.ts +2 -3
  87. package/src/components/progress/config.ts +2 -3
  88. package/src/components/progress/index.ts +0 -1
  89. package/src/components/progress/progress.ts +1 -2
  90. package/src/components/progress/types.ts +186 -33
  91. package/src/components/radios/config.ts +1 -1
  92. package/src/components/radios/index.ts +0 -1
  93. package/src/components/radios/types.ts +0 -7
  94. package/src/components/search/api.ts +203 -0
  95. package/src/components/search/config.ts +86 -0
  96. package/src/components/search/features/index.ts +4 -0
  97. package/src/components/search/features/search.ts +717 -0
  98. package/src/components/search/features/states.ts +169 -0
  99. package/src/components/search/features/structure.ts +197 -0
  100. package/src/components/search/index.ts +7 -0
  101. package/src/components/search/search.ts +52 -0
  102. package/src/components/search/types.ts +175 -0
  103. package/src/components/segmented-button/config.ts +80 -0
  104. package/src/components/segmented-button/index.ts +4 -0
  105. package/src/components/segmented-button/segment.ts +154 -0
  106. package/src/components/segmented-button/segmented-button.ts +249 -0
  107. package/src/components/segmented-button/types.ts +254 -0
  108. package/src/components/slider/accessibility.md +5 -5
  109. package/src/components/slider/api.ts +41 -120
  110. package/src/components/slider/config.ts +51 -47
  111. package/src/components/slider/features/handlers.ts +495 -0
  112. package/src/components/slider/features/index.ts +1 -2
  113. package/src/components/slider/features/slider.ts +66 -84
  114. package/src/components/slider/features/states.ts +195 -0
  115. package/src/components/slider/features/structure.ts +136 -206
  116. package/src/components/slider/features/ui.ts +145 -206
  117. package/src/components/slider/index.ts +2 -11
  118. package/src/components/slider/slider.ts +9 -12
  119. package/src/components/slider/types.ts +67 -26
  120. package/src/components/snackbar/config.ts +2 -3
  121. package/src/components/snackbar/constants.ts +0 -32
  122. package/src/components/snackbar/index.ts +0 -1
  123. package/src/components/snackbar/position.ts +9 -1
  124. package/src/components/snackbar/types.ts +122 -46
  125. package/src/components/switch/config.ts +2 -3
  126. package/src/components/switch/index.ts +0 -1
  127. package/src/components/switch/types.ts +3 -2
  128. package/src/components/tabs/config.ts +3 -4
  129. package/src/components/tabs/features.ts +4 -2
  130. package/src/components/tabs/index.ts +0 -15
  131. package/src/components/tabs/indicator.ts +73 -13
  132. package/src/components/tabs/tab-api.ts +12 -4
  133. package/src/components/tabs/tab.ts +18 -6
  134. package/src/components/tabs/types.ts +23 -5
  135. package/src/components/textfield/config.ts +2 -3
  136. package/src/components/textfield/index.ts +0 -1
  137. package/src/components/textfield/types.ts +17 -3
  138. package/src/components/timepicker/README.md +277 -0
  139. package/src/components/timepicker/api.ts +632 -0
  140. package/src/components/timepicker/clockdial.ts +482 -0
  141. package/src/components/timepicker/config.ts +228 -0
  142. package/src/components/timepicker/index.ts +3 -0
  143. package/src/components/timepicker/render.ts +613 -0
  144. package/src/components/timepicker/timepicker.ts +117 -0
  145. package/src/components/timepicker/types.ts +336 -0
  146. package/src/components/timepicker/utils.ts +241 -0
  147. package/src/components/tooltip/api.ts +1 -1
  148. package/src/components/tooltip/config.ts +27 -6
  149. package/src/components/tooltip/index.ts +0 -1
  150. package/src/components/tooltip/types.ts +13 -3
  151. package/src/components/top-app-bar/config.ts +83 -0
  152. package/src/components/top-app-bar/index.ts +11 -0
  153. package/src/components/top-app-bar/top-app-bar.ts +316 -0
  154. package/src/components/top-app-bar/types.ts +140 -0
  155. package/src/core/build/_ripple.scss +6 -6
  156. package/src/core/build/ripple.ts +72 -95
  157. package/src/core/compose/features/icon.ts +3 -1
  158. package/src/core/compose/features/ripple.ts +4 -1
  159. package/src/core/compose/features/textlabel.ts +23 -2
  160. package/src/core/dom/create.ts +5 -0
  161. package/src/index.ts +9 -0
  162. package/src/styles/abstract/_theme.scss +9 -1
  163. package/src/styles/components/_badge.scss +182 -0
  164. package/src/styles/components/_bottom-app-bar.scss +103 -0
  165. package/src/{components/button/_styles.scss → styles/components/_button.scss} +0 -10
  166. package/src/{components/checkbox/_styles.scss → styles/components/_checkbox.scss} +0 -2
  167. package/src/styles/components/_datepicker.scss +358 -0
  168. package/src/styles/components/_dialog.scss +259 -0
  169. package/src/styles/components/_divider.scss +57 -0
  170. package/src/styles/components/_extended-fab.scss +267 -0
  171. package/src/styles/components/_fab.scss +225 -0
  172. package/src/{components/navigation/_styles.scss → styles/components/_navigation.scss} +1 -0
  173. package/src/styles/components/_search.scss +306 -0
  174. package/src/styles/components/_segmented-button.scss +117 -0
  175. package/src/{components/slider/_styles.scss → styles/components/_slider.scss} +83 -24
  176. package/src/{components/switch/_styles.scss → styles/components/_switch.scss} +0 -2
  177. package/src/{components/tabs/_styles.scss → styles/components/_tabs.scss} +95 -33
  178. package/src/{components/textfield/_styles.scss → styles/components/_textfield.scss} +70 -67
  179. package/src/styles/components/_timepicker.scss +451 -0
  180. package/src/styles/components/_top-app-bar.scss +225 -0
  181. package/src/styles/main.scss +98 -49
  182. package/src/styles/themes/_autumn.scss +21 -0
  183. package/src/styles/themes/_base-theme.scss +61 -0
  184. package/src/styles/themes/_baseline.scss +58 -0
  185. package/src/styles/themes/_bluekhaki.scss +125 -0
  186. package/src/styles/themes/_brownbeige.scss +125 -0
  187. package/src/styles/themes/_browngreen.scss +125 -0
  188. package/src/styles/themes/_forest.scss +6 -0
  189. package/src/styles/themes/_greenbeige.scss +125 -0
  190. package/src/styles/themes/_material.scss +125 -0
  191. package/src/styles/themes/_ocean.scss +6 -0
  192. package/src/styles/themes/_sageivory.scss +125 -0
  193. package/src/styles/themes/_spring.scss +6 -0
  194. package/src/styles/themes/_summer.scss +5 -0
  195. package/src/styles/themes/_sunset.scss +5 -0
  196. package/src/styles/themes/_tealcaramel.scss +125 -0
  197. package/src/styles/themes/_winter.scss +6 -0
  198. package/src/components/badge/_styles.scss +0 -174
  199. package/src/components/badge/constants.ts +0 -30
  200. package/src/components/button/constants.ts +0 -11
  201. package/src/components/card/constants.ts +0 -84
  202. package/src/components/dialog/_styles.scss +0 -213
  203. package/src/components/dialog/constants.ts +0 -32
  204. package/src/components/menu/constants.ts +0 -154
  205. package/src/components/navigation/constants.ts +0 -200
  206. package/src/components/navigation/features/items.js +0 -192
  207. package/src/components/progress/constants.ts +0 -29
  208. package/src/components/slider/features/appearance.ts +0 -94
  209. package/src/components/slider/features/disabled.ts +0 -68
  210. package/src/components/slider/features/events.ts +0 -164
  211. package/src/components/slider/features/interactions.ts +0 -396
  212. package/src/components/slider/features/keyboard.ts +0 -233
  213. package/src/components/switch/constants.ts +0 -80
  214. package/src/components/tabs/constants.ts +0 -89
  215. package/src/core/collection/adapters/mongodb.js +0 -232
  216. /package/src/{components/card/_styles.scss → styles/components/_card.scss} +0 -0
  217. /package/src/{components/carousel/_styles.scss → styles/components/_carousel.scss} +0 -0
  218. /package/src/{components/chip/_styles.scss → styles/components/_chip.scss} +0 -0
  219. /package/src/{components/list/_styles.scss → styles/components/_list.scss} +0 -0
  220. /package/src/{components/menu/_styles.scss → styles/components/_menu.scss} +0 -0
  221. /package/src/{components/progress/_styles.scss → styles/components/_progress.scss} +0 -0
  222. /package/src/{components/radios/_styles.scss → styles/components/_radios.scss} +0 -0
  223. /package/src/{components/sheet/_styles.scss → styles/components/_sheet.scss} +0 -0
  224. /package/src/{components/snackbar/_styles.scss → styles/components/_snackbar.scss} +0 -0
  225. /package/src/{components/tooltip/_styles.scss → styles/components/_tooltip.scss} +0 -0
  226. /package/src/styles/utilities/{_color.scss → _colors.scss} +0 -0
@@ -0,0 +1,450 @@
1
+ // src/components/datepicker/render.ts
2
+ import {
3
+ MONTH_NAMES,
4
+ MONTH_NAMES_SHORT,
5
+ DAY_NAMES,
6
+ TODAY_CLASS,
7
+ SELECTED_CLASS,
8
+ OUTSIDE_MONTH_CLASS,
9
+ RANGE_START_CLASS,
10
+ RANGE_END_CLASS,
11
+ RANGE_MIDDLE_CLASS
12
+ } from './types';
13
+ import { CalendarDate } from './types';
14
+ import {
15
+ generateCalendarDates,
16
+ generateYearRange
17
+ } from './utils';
18
+ import { createElement } from '../../core/dom/create';
19
+
20
+ /**
21
+ * Renders the calendar header with navigation controls
22
+ * @param {Object} params - Rendering parameters
23
+ * @returns {HTMLElement} Calendar header element
24
+ */
25
+ export const renderHeader = ({
26
+ currentMonth,
27
+ currentYear,
28
+ currentView,
29
+ prefix,
30
+ emit
31
+ }: any): HTMLElement => {
32
+ const header = createElement({
33
+ tag: 'div',
34
+ className: `${prefix}-datepicker-header`
35
+ });
36
+
37
+ // Month selector
38
+ const monthButton = createElement({
39
+ tag: 'button',
40
+ className: `${prefix}-datepicker-month-selector`,
41
+ text: MONTH_NAMES[currentMonth],
42
+ attrs: {
43
+ type: 'button',
44
+ 'aria-label': 'Select month'
45
+ }
46
+ });
47
+
48
+ // Year selector
49
+ const yearButton = createElement({
50
+ tag: 'button',
51
+ className: `${prefix}-datepicker-year-selector`,
52
+ text: currentYear.toString(),
53
+ attrs: {
54
+ type: 'button',
55
+ 'aria-label': 'Select year'
56
+ }
57
+ });
58
+
59
+ // Navigation controls container
60
+ const navControls = createElement({
61
+ tag: 'div',
62
+ className: `${prefix}-datepicker-nav-controls`
63
+ });
64
+
65
+ // Previous button
66
+ const prevButton = createElement({
67
+ tag: 'button',
68
+ className: `${prefix}-datepicker-prev-btn`,
69
+ html: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg>',
70
+ attrs: {
71
+ type: 'button',
72
+ 'aria-label': currentView === 'day' ? 'Previous month' :
73
+ currentView === 'month' ? 'Previous year' : 'Previous year range'
74
+ }
75
+ });
76
+
77
+ // Next button
78
+ const nextButton = createElement({
79
+ tag: 'button',
80
+ className: `${prefix}-datepicker-next-btn`,
81
+ html: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>',
82
+ attrs: {
83
+ type: 'button',
84
+ 'aria-label': currentView === 'day' ? 'Next month' :
85
+ currentView === 'month' ? 'Next year' : 'Next year range'
86
+ }
87
+ });
88
+
89
+ // Event listeners
90
+ monthButton.addEventListener('click', (event) => {
91
+ // Prevent event from bubbling up
92
+ event.stopPropagation();
93
+ emit('viewChange', { view: 'month' });
94
+ });
95
+
96
+ yearButton.addEventListener('click', (event) => {
97
+ // Prevent event from bubbling up
98
+ event.stopPropagation();
99
+ emit('viewChange', { view: 'year' });
100
+ });
101
+
102
+ prevButton.addEventListener('click', (event) => {
103
+ // Prevent event from bubbling up
104
+ event.stopPropagation();
105
+
106
+ if (currentView === 'day') {
107
+ emit('prevMonth');
108
+ } else if (currentView === 'month') {
109
+ emit('prevYear');
110
+ } else {
111
+ emit('prevYearRange');
112
+ }
113
+ });
114
+
115
+ nextButton.addEventListener('click', (event) => {
116
+ // Prevent event from bubbling up
117
+ event.stopPropagation();
118
+
119
+ if (currentView === 'day') {
120
+ emit('nextMonth');
121
+ } else if (currentView === 'month') {
122
+ emit('nextYear');
123
+ } else {
124
+ emit('nextYearRange');
125
+ }
126
+ });
127
+
128
+ // Add buttons to container
129
+ header.appendChild(monthButton);
130
+ header.appendChild(yearButton);
131
+
132
+ navControls.appendChild(prevButton);
133
+ navControls.appendChild(nextButton);
134
+ header.appendChild(navControls);
135
+
136
+ return header;
137
+ };
138
+
139
+ /**
140
+ * Renders the days of the week (S, M, T, etc.)
141
+ * @param {string} prefix - CSS class prefix
142
+ * @returns {HTMLElement} Weekdays element
143
+ */
144
+ export const renderWeekdays = (prefix: string): HTMLElement => {
145
+ const weekdaysRow = createElement({
146
+ tag: 'div',
147
+ className: `${prefix}-datepicker-weekdays`
148
+ });
149
+
150
+ DAY_NAMES.forEach(day => {
151
+ const dayElement = createElement({
152
+ tag: 'span',
153
+ className: `${prefix}-datepicker-weekday`,
154
+ text: day
155
+ });
156
+ weekdaysRow.appendChild(dayElement);
157
+ });
158
+
159
+ return weekdaysRow;
160
+ };
161
+
162
+ /**
163
+ * Renders the calendar days
164
+ * @param {Object} params - Rendering parameters
165
+ * @returns {HTMLElement} Calendar days element
166
+ */
167
+ export const renderDays = ({
168
+ currentYear,
169
+ currentMonth,
170
+ selectedDate,
171
+ rangeEndDate,
172
+ minDate,
173
+ maxDate,
174
+ prefix,
175
+ emit
176
+ }: any): HTMLElement => {
177
+ const daysGrid = createElement({
178
+ tag: 'div',
179
+ className: `${prefix}-datepicker-days`
180
+ });
181
+
182
+ const calendarDates = generateCalendarDates(
183
+ currentYear,
184
+ currentMonth,
185
+ selectedDate,
186
+ rangeEndDate,
187
+ minDate,
188
+ maxDate
189
+ );
190
+
191
+ calendarDates.forEach((calendarDate: CalendarDate) => {
192
+ const classNames = [
193
+ `${prefix}-datepicker-day`,
194
+ calendarDate.isCurrentMonth ? '' : OUTSIDE_MONTH_CLASS,
195
+ calendarDate.isToday ? TODAY_CLASS : '',
196
+ calendarDate.isSelected ? SELECTED_CLASS : '',
197
+ calendarDate.isDisabled ? 'disabled' : '',
198
+ calendarDate.isRangeStart ? RANGE_START_CLASS : '',
199
+ calendarDate.isRangeEnd ? RANGE_END_CLASS : '',
200
+ calendarDate.isRangeMiddle ? RANGE_MIDDLE_CLASS : ''
201
+ ].filter(Boolean).join(' ');
202
+
203
+ const dayElement = createElement({
204
+ tag: 'button',
205
+ className: classNames,
206
+ text: calendarDate.day.toString(),
207
+ attrs: {
208
+ type: 'button',
209
+ 'aria-label': calendarDate.date.toLocaleDateString(),
210
+ 'aria-selected': calendarDate.isSelected ? 'true' : 'false',
211
+ 'aria-disabled': calendarDate.isDisabled ? 'true' : 'false',
212
+ 'data-date': calendarDate.date.toISOString(),
213
+ disabled: calendarDate.isDisabled
214
+ }
215
+ });
216
+
217
+ // Event listener
218
+ dayElement.addEventListener('click', (event) => {
219
+ // Prevent event from bubbling up
220
+ event.stopPropagation();
221
+
222
+ if (!calendarDate.isDisabled) {
223
+ emit('dateSelected', { date: calendarDate.date });
224
+ }
225
+ });
226
+
227
+ daysGrid.appendChild(dayElement);
228
+ });
229
+
230
+ return daysGrid;
231
+ };
232
+
233
+ /**
234
+ * Renders the month selection view
235
+ * @param {Object} params - Rendering parameters
236
+ * @returns {HTMLElement} Month selection element
237
+ */
238
+ export const renderMonthSelection = ({
239
+ currentYear,
240
+ currentMonth,
241
+ prefix,
242
+ emit
243
+ }: any): HTMLElement => {
244
+ const monthsGrid = createElement({
245
+ tag: 'div',
246
+ className: `${prefix}-datepicker-months`
247
+ });
248
+
249
+ MONTH_NAMES_SHORT.forEach((month, index) => {
250
+ const isSelected = index === currentMonth;
251
+
252
+ const monthElement = createElement({
253
+ tag: 'button',
254
+ className: `${prefix}-datepicker-month ${isSelected ? SELECTED_CLASS : ''}`,
255
+ text: month,
256
+ attrs: {
257
+ type: 'button',
258
+ 'aria-selected': isSelected ? 'true' : 'false',
259
+ 'data-month': index.toString()
260
+ }
261
+ });
262
+
263
+ monthElement.addEventListener('click', (event) => {
264
+ // Prevent event from bubbling up
265
+ event.stopPropagation();
266
+ emit('monthSelected', { month: index });
267
+ });
268
+
269
+ monthsGrid.appendChild(monthElement);
270
+ });
271
+
272
+ return monthsGrid;
273
+ };
274
+
275
+ /**
276
+ * Renders the year selection view
277
+ * @param {Object} params - Rendering parameters
278
+ * @returns {HTMLElement} Year selection element
279
+ */
280
+ export const renderYearSelection = ({
281
+ currentYear,
282
+ prefix,
283
+ emit
284
+ }: any): HTMLElement => {
285
+ const yearsGrid = createElement({
286
+ tag: 'div',
287
+ className: `${prefix}-datepicker-years`
288
+ });
289
+
290
+ const yearRange = generateYearRange(currentYear, 10);
291
+
292
+ yearRange.forEach(year => {
293
+ const isSelected = year === currentYear;
294
+
295
+ const yearElement = createElement({
296
+ tag: 'button',
297
+ className: `${prefix}-datepicker-year ${isSelected ? SELECTED_CLASS : ''}`,
298
+ text: year.toString(),
299
+ attrs: {
300
+ type: 'button',
301
+ 'aria-selected': isSelected ? 'true' : 'false',
302
+ 'data-year': year.toString()
303
+ }
304
+ });
305
+
306
+ yearElement.addEventListener('click', (event) => {
307
+ // Prevent event from bubbling up
308
+ event.stopPropagation();
309
+ emit('yearSelected', { year });
310
+ });
311
+
312
+ yearsGrid.appendChild(yearElement);
313
+ });
314
+
315
+ return yearsGrid;
316
+ };
317
+
318
+ /**
319
+ * Renders the footer with action buttons
320
+ * @param {Object} params - Rendering parameters
321
+ * @returns {HTMLElement} Footer element
322
+ */
323
+ export const renderFooter = ({
324
+ variant,
325
+ prefix,
326
+ emit
327
+ }: any): HTMLElement => {
328
+ const footer = createElement({
329
+ tag: 'div',
330
+ className: `${prefix}-datepicker-footer`
331
+ });
332
+
333
+ // Cancel button
334
+ const cancelButton = createElement({
335
+ tag: 'button',
336
+ className: `${prefix}-datepicker-cancel ${prefix}-button ${prefix}-button--text`,
337
+ text: 'Cancel',
338
+ attrs: {
339
+ type: 'button'
340
+ }
341
+ });
342
+
343
+ // OK button
344
+ const okButton = createElement({
345
+ tag: 'button',
346
+ className: `${prefix}-datepicker-ok ${prefix}-button ${prefix}-button--text`,
347
+ text: 'OK',
348
+ attrs: {
349
+ type: 'button'
350
+ }
351
+ });
352
+
353
+ cancelButton.addEventListener('click', (event) => {
354
+ // Prevent event from bubbling up
355
+ event.stopPropagation();
356
+ emit('cancel');
357
+ });
358
+
359
+ okButton.addEventListener('click', (event) => {
360
+ // Prevent event from bubbling up
361
+ event.stopPropagation();
362
+ emit('confirm');
363
+ });
364
+
365
+ footer.appendChild(cancelButton);
366
+ footer.appendChild(okButton);
367
+
368
+ return footer;
369
+ };
370
+
371
+ /**
372
+ * Renders a complete calendar view
373
+ * @param {Object} state - Current datepicker state
374
+ * @param {Function} emit - Event emission function
375
+ * @returns {HTMLElement} Rendered calendar
376
+ */
377
+ export const renderCalendar = (state: any, emit: Function): HTMLElement => {
378
+ const {
379
+ prefix,
380
+ currentView,
381
+ currentMonth,
382
+ currentYear,
383
+ selectedDate,
384
+ rangeEndDate,
385
+ minDate,
386
+ maxDate,
387
+ variant
388
+ } = state;
389
+
390
+ // Create calendar container
391
+ const calendar = createElement({
392
+ tag: 'div',
393
+ className: `${prefix}-datepicker-calendar-content`
394
+ });
395
+
396
+ // Render header
397
+ const header = renderHeader({
398
+ currentMonth,
399
+ currentYear,
400
+ currentView,
401
+ prefix,
402
+ emit
403
+ });
404
+ calendar.appendChild(header);
405
+
406
+ // Render content based on current view
407
+ if (currentView === 'day') {
408
+ const weekdays = renderWeekdays(prefix);
409
+ calendar.appendChild(weekdays);
410
+
411
+ const days = renderDays({
412
+ currentYear,
413
+ currentMonth,
414
+ selectedDate,
415
+ rangeEndDate,
416
+ minDate,
417
+ maxDate,
418
+ prefix,
419
+ emit
420
+ });
421
+ calendar.appendChild(days);
422
+ } else if (currentView === 'month') {
423
+ const months = renderMonthSelection({
424
+ currentYear,
425
+ currentMonth,
426
+ prefix,
427
+ emit
428
+ });
429
+ calendar.appendChild(months);
430
+ } else if (currentView === 'year') {
431
+ const years = renderYearSelection({
432
+ currentYear,
433
+ prefix,
434
+ emit
435
+ });
436
+ calendar.appendChild(years);
437
+ }
438
+
439
+ // Only add footer for modal variants
440
+ if (variant !== 'docked') {
441
+ const footer = renderFooter({
442
+ variant,
443
+ prefix,
444
+ emit
445
+ });
446
+ calendar.appendChild(footer);
447
+ }
448
+
449
+ return calendar;
450
+ };