tyrell-components 1.0.0-RC13 → 1.0.0-RC14

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 (355) hide show
  1. package/README.md +1 -1
  2. package/css/tyrell-theme.css +167 -178
  3. package/css/tyrell.css +19 -0
  4. package/dist/tyrell-theme.css +167 -178
  5. package/dist/tyrell.css +19 -0
  6. package/dist/tyrell.js +1 -1
  7. package/lib/base/ty-component.d.ts +20 -10
  8. package/lib/base/ty-component.js +21 -144
  9. package/lib/components/button.d.ts +2 -16
  10. package/lib/components/button.js +0 -36
  11. package/lib/components/calendar-month.d.ts +2 -48
  12. package/lib/components/calendar-month.js +4 -166
  13. package/lib/components/calendar-navigation.d.ts +3 -48
  14. package/lib/components/calendar-navigation.js +3 -126
  15. package/lib/components/calendar.d.ts +3 -80
  16. package/lib/components/calendar.js +8 -230
  17. package/lib/components/checkbox.d.ts +4 -71
  18. package/lib/components/checkbox.js +7 -151
  19. package/lib/components/copy.d.ts +3 -56
  20. package/lib/components/copy.js +1 -120
  21. package/lib/components/date-picker.d.ts +13 -162
  22. package/lib/components/date-picker.js +41 -592
  23. package/lib/components/file-upload.d.ts +9 -15
  24. package/lib/components/file-upload.js +19 -41
  25. package/lib/components/icon.d.ts +3 -24
  26. package/lib/components/icon.js +1 -90
  27. package/lib/components/input.d.ts +7 -107
  28. package/lib/components/input.js +5 -193
  29. package/lib/components/modal.d.ts +17 -26
  30. package/lib/components/modal.js +57 -201
  31. package/lib/components/option.d.ts +2 -9
  32. package/lib/components/option.js +0 -48
  33. package/lib/components/popup.d.ts +2 -17
  34. package/lib/components/popup.js +8 -139
  35. package/lib/components/radio.d.ts +3 -23
  36. package/lib/components/radio.js +10 -65
  37. package/lib/components/resize-observer.d.ts +3 -30
  38. package/lib/components/resize-observer.js +12 -46
  39. package/lib/components/scroll-container.d.ts +2 -12
  40. package/lib/components/scroll-container.js +3 -46
  41. package/lib/components/select.d.ts +22 -153
  42. package/lib/components/select.js +33 -590
  43. package/lib/components/selected-tags.d.ts +4 -47
  44. package/lib/components/selected-tags.js +1 -95
  45. package/lib/components/step.d.ts +1 -6
  46. package/lib/components/step.js +0 -6
  47. package/lib/components/switch.d.ts +0 -11
  48. package/lib/components/switch.js +2 -36
  49. package/lib/components/tab.d.ts +1 -6
  50. package/lib/components/tab.js +0 -7
  51. package/lib/components/tabs.d.ts +5 -63
  52. package/lib/components/tabs.js +20 -283
  53. package/lib/components/tag.d.ts +2 -36
  54. package/lib/components/tag.js +5 -105
  55. package/lib/components/textarea.d.ts +6 -86
  56. package/lib/components/textarea.js +2 -173
  57. package/lib/components/tooltip.d.ts +3 -11
  58. package/lib/components/tooltip.js +24 -160
  59. package/lib/components/wizard.d.ts +6 -54
  60. package/lib/components/wizard.js +15 -228
  61. package/lib/icons/fontawesome/brands.d.ts +0 -1
  62. package/lib/icons/fontawesome/brands.js +0 -8
  63. package/lib/icons/fontawesome/regular.d.ts +0 -1
  64. package/lib/icons/fontawesome/regular.js +0 -8
  65. package/lib/icons/fontawesome/solid.d.ts +0 -1
  66. package/lib/icons/fontawesome/solid.js +0 -8
  67. package/lib/icons/heroicons/micro.d.ts +0 -1
  68. package/lib/icons/heroicons/micro.js +0 -8
  69. package/lib/icons/heroicons/mini.d.ts +0 -1
  70. package/lib/icons/heroicons/mini.js +0 -8
  71. package/lib/icons/heroicons/outline.d.ts +0 -1
  72. package/lib/icons/heroicons/outline.js +0 -8
  73. package/lib/icons/heroicons/solid.d.ts +0 -1
  74. package/lib/icons/heroicons/solid.js +0 -8
  75. package/lib/icons/lucide.d.ts +0 -1
  76. package/lib/icons/lucide.js +0 -1872
  77. package/lib/icons/material/filled.d.ts +0 -1
  78. package/lib/icons/material/filled.js +0 -10
  79. package/lib/icons/material/outlined.d.ts +0 -1
  80. package/lib/icons/material/outlined.js +0 -10
  81. package/lib/icons/material/round.d.ts +0 -1
  82. package/lib/icons/material/round.js +0 -10
  83. package/lib/icons/material/sharp.d.ts +0 -1
  84. package/lib/icons/material/sharp.js +0 -10
  85. package/lib/icons/material/two-tone.d.ts +0 -1
  86. package/lib/icons/material/two-tone.js +0 -10
  87. package/lib/index.d.ts +0 -1
  88. package/lib/index.js +0 -20
  89. package/lib/styles/button.d.ts +2 -20
  90. package/lib/styles/button.js +22 -122
  91. package/lib/styles/calendar-month.d.ts +1 -5
  92. package/lib/styles/calendar-month.js +4 -61
  93. package/lib/styles/calendar-navigation.d.ts +2 -6
  94. package/lib/styles/calendar-navigation.js +2 -27
  95. package/lib/styles/calendar.d.ts +1 -2
  96. package/lib/styles/calendar.js +1 -14
  97. package/lib/styles/checkbox.d.ts +0 -1
  98. package/lib/styles/checkbox.js +1 -23
  99. package/lib/styles/copy.d.ts +0 -1
  100. package/lib/styles/copy.js +2 -17
  101. package/lib/styles/custom-scrollbar.d.ts +1 -2
  102. package/lib/styles/custom-scrollbar.js +3 -18
  103. package/lib/styles/date-picker.d.ts +1 -5
  104. package/lib/styles/date-picker.js +35 -39
  105. package/lib/styles/file-upload.d.ts +1 -2
  106. package/lib/styles/file-upload.js +1 -16
  107. package/lib/styles/icon.d.ts +2 -6
  108. package/lib/styles/icon.js +7 -21
  109. package/lib/styles/input.d.ts +1 -6
  110. package/lib/styles/input.js +5 -54
  111. package/lib/styles/modal.d.ts +1 -2
  112. package/lib/styles/modal.js +21 -23
  113. package/lib/styles/option.d.ts +2 -6
  114. package/lib/styles/option.js +17 -12
  115. package/lib/styles/popup.d.ts +1 -2
  116. package/lib/styles/popup.js +26 -30
  117. package/lib/styles/radio.d.ts +0 -1
  118. package/lib/styles/radio.js +2 -16
  119. package/lib/styles/resize-observer.d.ts +1 -2
  120. package/lib/styles/resize-observer.js +0 -7
  121. package/lib/styles/scroll-container.d.ts +1 -2
  122. package/lib/styles/scroll-container.js +0 -19
  123. package/lib/styles/select-base.d.ts +0 -1
  124. package/lib/styles/select-base.js +68 -79
  125. package/lib/styles/select.d.ts +1 -2
  126. package/lib/styles/select.js +7 -15
  127. package/lib/styles/step.d.ts +1 -2
  128. package/lib/styles/step.js +0 -4
  129. package/lib/styles/switch.d.ts +0 -1
  130. package/lib/styles/switch.js +2 -20
  131. package/lib/styles/tab.d.ts +1 -2
  132. package/lib/styles/tab.js +0 -5
  133. package/lib/styles/tabs.d.ts +3 -11
  134. package/lib/styles/tabs.js +10 -48
  135. package/lib/styles/tag.d.ts +1 -5
  136. package/lib/styles/tag.js +2 -31
  137. package/lib/styles/textarea.d.ts +1 -2
  138. package/lib/styles/textarea.js +2 -45
  139. package/lib/styles/tooltip.d.ts +0 -1
  140. package/lib/styles/tooltip.js +0 -10
  141. package/lib/styles/wizard.d.ts +5 -21
  142. package/lib/styles/wizard.js +8 -88
  143. package/lib/types/common.d.ts +0 -2
  144. package/lib/types/common.js +0 -12
  145. package/lib/utils/calendar-utils.d.ts +4 -21
  146. package/lib/utils/calendar-utils.js +4 -177
  147. package/lib/utils/custom-scrollbar.d.ts +6 -20
  148. package/lib/utils/custom-scrollbar.js +1 -45
  149. package/lib/utils/flavor-sheet.d.ts +0 -1
  150. package/lib/utils/flavor-sheet.js +0 -23
  151. package/lib/utils/icon-registry.d.ts +0 -2
  152. package/lib/utils/icon-registry.js +1 -107
  153. package/lib/utils/icons.d.ts +0 -1
  154. package/lib/utils/icons.js +0 -9
  155. package/lib/utils/loader-registry.d.ts +0 -1
  156. package/lib/utils/loader-registry.js +0 -32
  157. package/lib/utils/locale.d.ts +2 -23
  158. package/lib/utils/locale.js +0 -86
  159. package/lib/utils/mobile.d.ts +0 -1
  160. package/lib/utils/mobile.js +0 -17
  161. package/lib/utils/number-format.d.ts +6 -3
  162. package/lib/utils/number-format.js +11 -67
  163. package/lib/utils/positioning.d.ts +50 -7
  164. package/lib/utils/positioning.js +52 -62
  165. package/lib/utils/property-capture.d.ts +5 -27
  166. package/lib/utils/property-capture.js +0 -108
  167. package/lib/utils/property-manager.d.ts +0 -1
  168. package/lib/utils/property-manager.js +0 -70
  169. package/lib/utils/resize-observer.d.ts +0 -1
  170. package/lib/utils/resize-observer.js +0 -36
  171. package/lib/utils/scroll-lock.d.ts +4 -11
  172. package/lib/utils/scroll-lock.js +0 -107
  173. package/lib/utils/styles.d.ts +0 -1
  174. package/lib/utils/styles.js +0 -24
  175. package/lib/version.d.ts +1 -2
  176. package/lib/version.js +1 -11
  177. package/package.json +2 -2
  178. package/lib/base/ty-component.d.ts.map +0 -1
  179. package/lib/base/ty-component.js.map +0 -1
  180. package/lib/components/button.d.ts.map +0 -1
  181. package/lib/components/button.js.map +0 -1
  182. package/lib/components/calendar-month.d.ts.map +0 -1
  183. package/lib/components/calendar-month.js.map +0 -1
  184. package/lib/components/calendar-navigation.d.ts.map +0 -1
  185. package/lib/components/calendar-navigation.js.map +0 -1
  186. package/lib/components/calendar.d.ts.map +0 -1
  187. package/lib/components/calendar.js.map +0 -1
  188. package/lib/components/checkbox.d.ts.map +0 -1
  189. package/lib/components/checkbox.js.map +0 -1
  190. package/lib/components/copy.d.ts.map +0 -1
  191. package/lib/components/copy.js.map +0 -1
  192. package/lib/components/date-picker.d.ts.map +0 -1
  193. package/lib/components/date-picker.js.map +0 -1
  194. package/lib/components/file-upload.d.ts.map +0 -1
  195. package/lib/components/file-upload.js.map +0 -1
  196. package/lib/components/icon.d.ts.map +0 -1
  197. package/lib/components/icon.js.map +0 -1
  198. package/lib/components/input.d.ts.map +0 -1
  199. package/lib/components/input.js.map +0 -1
  200. package/lib/components/modal.d.ts.map +0 -1
  201. package/lib/components/modal.js.map +0 -1
  202. package/lib/components/option.d.ts.map +0 -1
  203. package/lib/components/option.js.map +0 -1
  204. package/lib/components/popup.d.ts.map +0 -1
  205. package/lib/components/popup.js.map +0 -1
  206. package/lib/components/radio.d.ts.map +0 -1
  207. package/lib/components/radio.js.map +0 -1
  208. package/lib/components/resize-observer.d.ts.map +0 -1
  209. package/lib/components/resize-observer.js.map +0 -1
  210. package/lib/components/scroll-container.d.ts.map +0 -1
  211. package/lib/components/scroll-container.js.map +0 -1
  212. package/lib/components/select.d.ts.map +0 -1
  213. package/lib/components/select.js.map +0 -1
  214. package/lib/components/selected-tags.d.ts.map +0 -1
  215. package/lib/components/selected-tags.js.map +0 -1
  216. package/lib/components/step.d.ts.map +0 -1
  217. package/lib/components/step.js.map +0 -1
  218. package/lib/components/switch.d.ts.map +0 -1
  219. package/lib/components/switch.js.map +0 -1
  220. package/lib/components/tab.d.ts.map +0 -1
  221. package/lib/components/tab.js.map +0 -1
  222. package/lib/components/tabs.d.ts.map +0 -1
  223. package/lib/components/tabs.js.map +0 -1
  224. package/lib/components/tag.d.ts.map +0 -1
  225. package/lib/components/tag.js.map +0 -1
  226. package/lib/components/textarea.d.ts.map +0 -1
  227. package/lib/components/textarea.js.map +0 -1
  228. package/lib/components/tooltip.d.ts.map +0 -1
  229. package/lib/components/tooltip.js.map +0 -1
  230. package/lib/components/wizard.d.ts.map +0 -1
  231. package/lib/components/wizard.js.map +0 -1
  232. package/lib/icons/fontawesome/brands.d.ts.map +0 -1
  233. package/lib/icons/fontawesome/brands.js.map +0 -1
  234. package/lib/icons/fontawesome/regular.d.ts.map +0 -1
  235. package/lib/icons/fontawesome/regular.js.map +0 -1
  236. package/lib/icons/fontawesome/solid.d.ts.map +0 -1
  237. package/lib/icons/fontawesome/solid.js.map +0 -1
  238. package/lib/icons/heroicons/micro.d.ts.map +0 -1
  239. package/lib/icons/heroicons/micro.js.map +0 -1
  240. package/lib/icons/heroicons/mini.d.ts.map +0 -1
  241. package/lib/icons/heroicons/mini.js.map +0 -1
  242. package/lib/icons/heroicons/outline.d.ts.map +0 -1
  243. package/lib/icons/heroicons/outline.js.map +0 -1
  244. package/lib/icons/heroicons/solid.d.ts.map +0 -1
  245. package/lib/icons/heroicons/solid.js.map +0 -1
  246. package/lib/icons/lucide.d.ts.map +0 -1
  247. package/lib/icons/lucide.js.map +0 -1
  248. package/lib/icons/material/filled.d.ts.map +0 -1
  249. package/lib/icons/material/filled.js.map +0 -1
  250. package/lib/icons/material/outlined.d.ts.map +0 -1
  251. package/lib/icons/material/outlined.js.map +0 -1
  252. package/lib/icons/material/round.d.ts.map +0 -1
  253. package/lib/icons/material/round.js.map +0 -1
  254. package/lib/icons/material/sharp.d.ts.map +0 -1
  255. package/lib/icons/material/sharp.js.map +0 -1
  256. package/lib/icons/material/two-tone.d.ts.map +0 -1
  257. package/lib/icons/material/two-tone.js.map +0 -1
  258. package/lib/index.d.ts.map +0 -1
  259. package/lib/index.js.map +0 -1
  260. package/lib/styles/button.d.ts.map +0 -1
  261. package/lib/styles/button.js.map +0 -1
  262. package/lib/styles/calendar-month.d.ts.map +0 -1
  263. package/lib/styles/calendar-month.js.map +0 -1
  264. package/lib/styles/calendar-navigation.d.ts.map +0 -1
  265. package/lib/styles/calendar-navigation.js.map +0 -1
  266. package/lib/styles/calendar.d.ts.map +0 -1
  267. package/lib/styles/calendar.js.map +0 -1
  268. package/lib/styles/checkbox.d.ts.map +0 -1
  269. package/lib/styles/checkbox.js.map +0 -1
  270. package/lib/styles/copy.d.ts.map +0 -1
  271. package/lib/styles/copy.js.map +0 -1
  272. package/lib/styles/custom-scrollbar.d.ts.map +0 -1
  273. package/lib/styles/custom-scrollbar.js.map +0 -1
  274. package/lib/styles/date-picker.d.ts.map +0 -1
  275. package/lib/styles/date-picker.js.map +0 -1
  276. package/lib/styles/file-upload.d.ts.map +0 -1
  277. package/lib/styles/file-upload.js.map +0 -1
  278. package/lib/styles/icon.d.ts.map +0 -1
  279. package/lib/styles/icon.js.map +0 -1
  280. package/lib/styles/input.d.ts.map +0 -1
  281. package/lib/styles/input.js.map +0 -1
  282. package/lib/styles/modal.d.ts.map +0 -1
  283. package/lib/styles/modal.js.map +0 -1
  284. package/lib/styles/multiselect.d.ts +0 -8
  285. package/lib/styles/multiselect.d.ts.map +0 -1
  286. package/lib/styles/multiselect.js +0 -849
  287. package/lib/styles/multiselect.js.map +0 -1
  288. package/lib/styles/option.d.ts.map +0 -1
  289. package/lib/styles/option.js.map +0 -1
  290. package/lib/styles/popup.d.ts.map +0 -1
  291. package/lib/styles/popup.js.map +0 -1
  292. package/lib/styles/radio.d.ts.map +0 -1
  293. package/lib/styles/radio.js.map +0 -1
  294. package/lib/styles/resize-observer.d.ts.map +0 -1
  295. package/lib/styles/resize-observer.js.map +0 -1
  296. package/lib/styles/scroll-container.d.ts.map +0 -1
  297. package/lib/styles/scroll-container.js.map +0 -1
  298. package/lib/styles/select-base.d.ts.map +0 -1
  299. package/lib/styles/select-base.js.map +0 -1
  300. package/lib/styles/select.d.ts.map +0 -1
  301. package/lib/styles/select.js.map +0 -1
  302. package/lib/styles/step.d.ts.map +0 -1
  303. package/lib/styles/step.js.map +0 -1
  304. package/lib/styles/switch.d.ts.map +0 -1
  305. package/lib/styles/switch.js.map +0 -1
  306. package/lib/styles/tab.d.ts.map +0 -1
  307. package/lib/styles/tab.js.map +0 -1
  308. package/lib/styles/tabs.d.ts.map +0 -1
  309. package/lib/styles/tabs.js.map +0 -1
  310. package/lib/styles/tag.d.ts.map +0 -1
  311. package/lib/styles/tag.js.map +0 -1
  312. package/lib/styles/textarea.d.ts.map +0 -1
  313. package/lib/styles/textarea.js.map +0 -1
  314. package/lib/styles/tooltip.d.ts.map +0 -1
  315. package/lib/styles/tooltip.js.map +0 -1
  316. package/lib/styles/wizard.d.ts.map +0 -1
  317. package/lib/styles/wizard.js.map +0 -1
  318. package/lib/types/common.d.ts.map +0 -1
  319. package/lib/types/common.js.map +0 -1
  320. package/lib/utils/calendar-utils.d.ts.map +0 -1
  321. package/lib/utils/calendar-utils.js.map +0 -1
  322. package/lib/utils/custom-scrollbar.d.ts.map +0 -1
  323. package/lib/utils/custom-scrollbar.js.map +0 -1
  324. package/lib/utils/flavor-sheet.d.ts.map +0 -1
  325. package/lib/utils/flavor-sheet.js.map +0 -1
  326. package/lib/utils/icon-registry.d.ts.map +0 -1
  327. package/lib/utils/icon-registry.js.map +0 -1
  328. package/lib/utils/icons.d.ts.map +0 -1
  329. package/lib/utils/icons.js.map +0 -1
  330. package/lib/utils/loader-registry.d.ts.map +0 -1
  331. package/lib/utils/loader-registry.js.map +0 -1
  332. package/lib/utils/locale.d.ts.map +0 -1
  333. package/lib/utils/locale.js.map +0 -1
  334. package/lib/utils/mobile.d.ts.map +0 -1
  335. package/lib/utils/mobile.js.map +0 -1
  336. package/lib/utils/number-format.d.ts.map +0 -1
  337. package/lib/utils/number-format.js.map +0 -1
  338. package/lib/utils/parse-boolean.d.ts +0 -39
  339. package/lib/utils/parse-boolean.d.ts.map +0 -1
  340. package/lib/utils/parse-boolean.js +0 -58
  341. package/lib/utils/parse-boolean.js.map +0 -1
  342. package/lib/utils/positioning.d.ts.map +0 -1
  343. package/lib/utils/positioning.js.map +0 -1
  344. package/lib/utils/property-capture.d.ts.map +0 -1
  345. package/lib/utils/property-capture.js.map +0 -1
  346. package/lib/utils/property-manager.d.ts.map +0 -1
  347. package/lib/utils/property-manager.js.map +0 -1
  348. package/lib/utils/resize-observer.d.ts.map +0 -1
  349. package/lib/utils/resize-observer.js.map +0 -1
  350. package/lib/utils/scroll-lock.d.ts.map +0 -1
  351. package/lib/utils/scroll-lock.js.map +0 -1
  352. package/lib/utils/styles.d.ts.map +0 -1
  353. package/lib/utils/styles.js.map +0 -1
  354. package/lib/version.d.ts.map +0 -1
  355. package/lib/version.js.map +0 -1
@@ -1,121 +1,41 @@
1
- /**
2
- * TyCalendar Web Component
3
- * PORTED FROM: cljs/ty/components/calendar.cljs
4
- *
5
- * A complete calendar orchestration component that combines navigation and month display.
6
- * Manages selection state, form participation, and event coordination.
7
- *
8
- * Architecture:
9
- * - year/month/day HTML attributes for intuitive API
10
- * - Internal state management (private properties)
11
- * - Distributes properties to child components (navigation + month)
12
- * - Single 'change' event with complete day context
13
- * - Form participation via ElementInternals
14
- *
15
- * Features:
16
- * - Combines ty-calendar-navigation + ty-calendar-month
17
- * - Date selection with visual feedback
18
- * - Form integration (works with FormData)
19
- * - Custom render functions (dayContentFn)
20
- * - Custom CSS injection
21
- * - Automatic date validation
22
- * - Event coordination between components
23
- *
24
- * @example
25
- * ```html
26
- * <!-- Basic usage -->
27
- * <ty-calendar
28
- * year="2025"
29
- * month="10"
30
- * day="15">
31
- * </ty-calendar>
32
- *
33
- * <!-- Form integration -->
34
- * <form>
35
- * <ty-calendar name="booking-date"></ty-calendar>
36
- * <button type="submit">Submit</button>
37
- * </form>
38
- *
39
- * <!-- With custom rendering -->
40
- * <ty-calendar id="custom"></ty-calendar>
41
- * <script type="module">
42
- * const cal = document.getElementById('custom');
43
- * cal.dayContentFn = (ctx) => {
44
- * const el = document.createElement('div');
45
- * el.textContent = ctx.dayInMonth;
46
- * if (ctx.today) el.style.fontWeight = 'bold';
47
- * return el;
48
- * };
49
- * </script>
50
- * ```
51
- */
52
1
  import { ensureStyles } from '../utils/styles.js';
53
2
  import { calendarStyles } from '../styles/calendar.js';
54
- // Side-effect imports: register the child elements this component createElements
55
3
  import './calendar-month.js';
56
4
  import './calendar-navigation.js';
57
5
  import { parseISODate } from '../utils/calendar-utils.js';
58
6
  import { getEffectiveLocale, observeLocaleChanges } from '../utils/locale.js';
59
- // ============================================================================
60
- // Helper Functions
61
- // ============================================================================
62
- /**
63
- * Get current date for defaults
64
- */
65
7
  function getCurrentDate() {
66
8
  const now = new Date();
67
9
  return {
68
10
  year: now.getFullYear(),
69
- month: now.getMonth() + 1, // 1-based
11
+ month: now.getMonth() + 1,
70
12
  day: now.getDate(),
71
13
  };
72
14
  }
73
- /**
74
- * Validate and parse year from string
75
- */
76
15
  function parseYear(yearStr) {
77
16
  if (!yearStr || !/^\d{4}$/.test(yearStr))
78
17
  return null;
79
18
  return parseInt(yearStr, 10);
80
19
  }
81
- /**
82
- * Validate and parse month from string (1-12)
83
- */
84
20
  function parseMonth(monthStr) {
85
21
  if (!monthStr || !/^\d{1,2}$/.test(monthStr))
86
22
  return null;
87
23
  const month = parseInt(monthStr, 10);
88
24
  return month >= 1 && month <= 12 ? month : null;
89
25
  }
90
- /**
91
- * Validate and parse day from string (1-31, validated against month)
92
- */
93
26
  function parseDay(dayStr, year, month) {
94
27
  if (!dayStr || !/^\d{1,2}$/.test(dayStr))
95
28
  return null;
96
29
  const day = parseInt(dayStr, 10);
97
- // Get days in month for validation
98
30
  const daysInMonth = new Date(year, month, 0).getDate();
99
31
  return day >= 1 && day <= daysInMonth ? day : null;
100
32
  }
101
- /**
102
- * Format date as ISO string (YYYY-MM-DD) for form submission
103
- */
104
33
  function formatDateISO(year, month, day) {
105
34
  const monthStr = month.toString().padStart(2, '0');
106
35
  const dayStr = day.toString().padStart(2, '0');
107
36
  return `${year}-${monthStr}-${dayStr}`;
108
37
  }
109
- // ============================================================================
110
- // Component Implementation
111
- // ============================================================================
112
- /**
113
- * TyCalendar Web Component
114
- */
115
38
  export class TyCalendar extends HTMLElement {
116
- /**
117
- * Observed attributes
118
- */
119
39
  static get observedAttributes() {
120
40
  return ['year', 'month', 'day', 'show-navigation', 'stateless', 'locale', 'name', 'size', 'width', 'min', 'max', 'flavor'];
121
41
  }
@@ -124,44 +44,31 @@ export class TyCalendar extends HTMLElement {
124
44
  this._showNavigation = true;
125
45
  this._stateless = false;
126
46
  this._size = 'md';
127
- this._flavor = 'primary'; // passed to month display only (nav stays neutral chrome)
128
- // Initialize state with current date
47
+ this._flavor = 'primary';
129
48
  const current = getCurrentDate();
130
49
  this._state = {
131
50
  displayYear: current.year,
132
51
  displayMonth: current.month,
133
52
  };
134
53
  this.attachShadow({ mode: 'open' });
135
- // Attach ElementInternals for form participation
136
54
  if ('attachInternals' in this) {
137
55
  this._internals = this.attachInternals();
138
56
  }
139
57
  }
140
- // ==========================================================================
141
- // Lifecycle Methods
142
- // ==========================================================================
143
58
  connectedCallback() {
144
- // Parse initial attributes
145
59
  this.initializeFromAttributes();
146
- // ✅ CHECK: Properties set before custom element upgrade
147
- // When scripts run before element is fully upgraded, properties are set as plain properties
148
- // without triggering setters. We need to migrate them to private fields.
149
- // Check for dayContentFn set before upgrade
150
60
  const plainDayContentFn = this.dayContentFn;
151
61
  if (plainDayContentFn && !this._dayContentFn) {
152
62
  this._dayContentFn = plainDayContentFn;
153
- delete this.dayContentFn; // Clean up plain property
63
+ delete this.dayContentFn;
154
64
  }
155
- // Check for customCSS set before upgrade
156
65
  const plainCustomCSS = this.customCSS;
157
66
  if (plainCustomCSS && !this._customCSS) {
158
67
  this._customCSS = plainCustomCSS;
159
- delete this.customCSS; // Clean up plain property
68
+ delete this.customCSS;
160
69
  }
161
- // Check for value set before upgrade
162
70
  const plainValue = this.value;
163
71
  if (plainValue && typeof plainValue === 'string' && plainValue !== this.value) {
164
- // Parse and set the value properly
165
72
  const match = plainValue.match(/^(\d{4})-(\d{2})-(\d{2})$/);
166
73
  if (match) {
167
74
  const year = parseInt(match[1], 10);
@@ -172,31 +79,25 @@ export class TyCalendar extends HTMLElement {
172
79
  this._state.selectedDay = day;
173
80
  this._state.displayYear = year;
174
81
  this._state.displayMonth = month;
175
- // Update attributes if not in stateless mode
176
82
  if (!this._stateless) {
177
83
  this.setAttribute('year', year.toString());
178
84
  this.setAttribute('month', month.toString());
179
85
  this.setAttribute('day', day.toString());
180
86
  }
181
87
  }
182
- delete this.value; // Clean up plain property
88
+ delete this.value;
183
89
  }
184
- // Render the calendar
185
90
  this.render();
186
- // Set initial form value if date is selected
187
91
  this.updateFormValue();
188
- // Setup locale observer to watch for ancestor lang changes
189
92
  this._localeObserver = observeLocaleChanges(this, () => {
190
93
  this.render();
191
94
  });
192
95
  }
193
96
  disconnectedCallback() {
194
- // Cleanup locale observer
195
97
  if (this._localeObserver) {
196
98
  this._localeObserver();
197
99
  this._localeObserver = undefined;
198
100
  }
199
- // Cleanup references
200
101
  this._navigation = undefined;
201
102
  this._monthDisplay = undefined;
202
103
  }
@@ -217,17 +118,13 @@ export class TyCalendar extends HTMLElement {
217
118
  break;
218
119
  case 'stateless':
219
120
  this._stateless = newValue !== null && newValue !== 'false';
220
- // No re-render needed, just changes behavior
221
121
  break;
222
122
  case 'locale':
223
- // Attribute is the source of truth — `get locale` resolves it via
224
- // getEffectiveLocale; children just need a re-sync.
225
123
  this.syncChildComponents();
226
124
  break;
227
125
  case 'size':
228
126
  if (newValue === 'sm' || newValue === 'md' || newValue === 'lg') {
229
127
  this._size = newValue;
230
- // Clear width when size is set (mutually exclusive)
231
128
  this._width = undefined;
232
129
  this.removeAttribute('width');
233
130
  this.syncChildComponents();
@@ -235,22 +132,20 @@ export class TyCalendar extends HTMLElement {
235
132
  break;
236
133
  case 'width':
237
134
  this._width = newValue || undefined;
238
- // Clear size when width is set (mutually exclusive)
239
135
  if (newValue) {
240
- this._size = 'md'; // Reset to default
136
+ this._size = 'md';
241
137
  this.removeAttribute('size');
242
138
  }
243
139
  this.syncChildComponents();
244
140
  break;
245
141
  case 'name':
246
- // Name change triggers form value update
247
142
  this.updateFormValue();
248
143
  break;
249
144
  case 'min':
250
145
  case 'max':
251
146
  this[name === 'min' ? '_min' : '_max'] = newValue || undefined;
252
147
  this.syncChildComponents();
253
- this.updateValidity(); // bounds change can (in)validate current selection
148
+ this.updateValidity();
254
149
  break;
255
150
  case 'flavor':
256
151
  this._flavor = newValue || 'primary';
@@ -258,14 +153,10 @@ export class TyCalendar extends HTMLElement {
258
153
  break;
259
154
  }
260
155
  }
261
- // ==========================================================================
262
- // Property Getters/Setters
263
- // ==========================================================================
264
156
  get min() {
265
157
  return this._min;
266
158
  }
267
159
  set min(value) {
268
- // Reflect to attribute; attributeChangedCallback syncs children
269
160
  if (value)
270
161
  this.setAttribute('min', value);
271
162
  else
@@ -294,13 +185,11 @@ export class TyCalendar extends HTMLElement {
294
185
  }
295
186
  set year(value) {
296
187
  if (value !== undefined) {
297
- // In stateless mode, only update display
298
188
  if (this._stateless) {
299
189
  this._state.displayYear = value;
300
190
  this.setAttribute('year', value.toString());
301
191
  }
302
192
  else {
303
- // In stateful mode, update both selection and display
304
193
  this._state.selectedYear = value;
305
194
  this._state.displayYear = value;
306
195
  this.setAttribute('year', value.toString());
@@ -322,13 +211,11 @@ export class TyCalendar extends HTMLElement {
322
211
  }
323
212
  set month(value) {
324
213
  if (value !== undefined) {
325
- // In stateless mode, only update display
326
214
  if (this._stateless) {
327
215
  this._state.displayMonth = value;
328
216
  this.setAttribute('month', value.toString());
329
217
  }
330
218
  else {
331
- // In stateful mode, update both selection and display
332
219
  this._state.selectedMonth = value;
333
220
  this._state.displayMonth = value;
334
221
  this.setAttribute('month', value.toString());
@@ -391,7 +278,6 @@ export class TyCalendar extends HTMLElement {
391
278
  set size(value) {
392
279
  if (this._size !== value) {
393
280
  this._size = value;
394
- // Clear width when size is set (mutually exclusive)
395
281
  this._width = undefined;
396
282
  this.removeAttribute('width');
397
283
  this.setAttribute('size', value);
@@ -405,8 +291,7 @@ export class TyCalendar extends HTMLElement {
405
291
  if (this._width !== value) {
406
292
  this._width = value;
407
293
  if (value) {
408
- // Clear size when width is set (mutually exclusive)
409
- this._size = 'md'; // Reset to default
294
+ this._size = 'md';
410
295
  this.removeAttribute('size');
411
296
  this.setAttribute('width', value);
412
297
  }
@@ -439,11 +324,9 @@ export class TyCalendar extends HTMLElement {
439
324
  }
440
325
  set value(isoDate) {
441
326
  if (!isoDate) {
442
- // Clear selection
443
327
  delete this._state.selectedYear;
444
328
  delete this._state.selectedMonth;
445
329
  delete this._state.selectedDay;
446
- // In normal mode, also clear attributes
447
330
  if (!this._stateless) {
448
331
  this.removeAttribute('year');
449
332
  this.removeAttribute('month');
@@ -451,21 +334,16 @@ export class TyCalendar extends HTMLElement {
451
334
  }
452
335
  }
453
336
  else {
454
- // Parse ISO date (YYYY-MM-DD)
455
337
  const match = isoDate.match(/^(\d{4})-(\d{2})-(\d{2})$/);
456
338
  if (match) {
457
339
  const year = parseInt(match[1], 10);
458
340
  const month = parseInt(match[2], 10);
459
341
  const day = parseInt(match[3], 10);
460
- // Update internal selection state
461
342
  this._state.selectedYear = year;
462
343
  this._state.selectedMonth = month;
463
344
  this._state.selectedDay = day;
464
- // Update display to show this month
465
345
  this._state.displayYear = year;
466
346
  this._state.displayMonth = month;
467
- // In normal mode, update attributes
468
- // In stateless mode, skip attribute updates (parent controls attributes)
469
347
  if (!this._stateless) {
470
348
  this.setAttribute('year', year.toString());
471
349
  this.setAttribute('month', month.toString());
@@ -474,17 +352,10 @@ export class TyCalendar extends HTMLElement {
474
352
  }
475
353
  }
476
354
  this.syncChildComponents();
477
- // In normal mode, update form value
478
355
  if (!this._stateless) {
479
356
  this.updateFormValue();
480
357
  }
481
358
  }
482
- // ==========================================================================
483
- // State Management
484
- // ==========================================================================
485
- /**
486
- * Initialize state from HTML attributes on first load
487
- */
488
359
  initializeFromAttributes() {
489
360
  const yearStr = this.getAttribute('year');
490
361
  const monthStr = this.getAttribute('month');
@@ -493,20 +364,16 @@ export class TyCalendar extends HTMLElement {
493
364
  const statelessStr = this.getAttribute('stateless');
494
365
  const sizeStr = this.getAttribute('size');
495
366
  const widthStr = this.getAttribute('width');
496
- // Date bounds
497
367
  this._min = this.getAttribute('min') || undefined;
498
368
  this._max = this.getAttribute('max') || undefined;
499
- // Parse year
500
369
  const year = parseYear(yearStr);
501
370
  if (year) {
502
371
  this._state.displayYear = year;
503
372
  }
504
- // Parse month
505
373
  const month = parseMonth(monthStr);
506
374
  if (month) {
507
375
  this._state.displayMonth = month;
508
376
  }
509
- // Parse day (only if year and month are valid)
510
377
  if (year && month) {
511
378
  const day = parseDay(dayStr, year, month);
512
379
  if (day) {
@@ -515,38 +382,29 @@ export class TyCalendar extends HTMLElement {
515
382
  this._state.selectedDay = day;
516
383
  }
517
384
  }
518
- // Show navigation
519
385
  if (showNavStr) {
520
386
  this._showNavigation = showNavStr !== 'false';
521
387
  }
522
- // Stateless mode
523
388
  if (statelessStr !== null) {
524
389
  this._stateless = statelessStr !== 'false';
525
390
  }
526
- // Size
527
391
  if (sizeStr && (sizeStr === 'sm' || sizeStr === 'md' || sizeStr === 'lg')) {
528
392
  this._size = sizeStr;
529
393
  }
530
- // Width
531
394
  if (widthStr) {
532
395
  this._width = widthStr;
533
396
  }
534
397
  }
535
- /**
536
- * Sync state from changed attributes
537
- */
538
398
  syncStateFromAttributes() {
539
399
  const yearStr = this.getAttribute('year');
540
400
  const monthStr = this.getAttribute('month');
541
401
  const dayStr = this.getAttribute('day');
542
402
  const year = parseYear(yearStr);
543
403
  const month = parseMonth(monthStr);
544
- // Update display year/month
545
404
  if (year)
546
405
  this._state.displayYear = year;
547
406
  if (month)
548
407
  this._state.displayMonth = month;
549
- // Update selection (only if all three are valid)
550
408
  if (year && month) {
551
409
  const day = parseDay(dayStr, year, month);
552
410
  if (day) {
@@ -555,24 +413,18 @@ export class TyCalendar extends HTMLElement {
555
413
  this._state.selectedDay = day;
556
414
  }
557
415
  else {
558
- // Clear selection if day is invalid
559
416
  delete this._state.selectedYear;
560
417
  delete this._state.selectedMonth;
561
418
  delete this._state.selectedDay;
562
419
  }
563
420
  }
564
421
  else {
565
- // Clear selection if year or month is invalid
566
422
  delete this._state.selectedYear;
567
423
  delete this._state.selectedMonth;
568
424
  delete this._state.selectedDay;
569
425
  }
570
426
  }
571
- /**
572
- * Update child components with current state
573
- */
574
427
  syncChildComponents() {
575
- // Update navigation
576
428
  if (this._navigation) {
577
429
  this._navigation.displayMonth = this._state.displayMonth;
578
430
  this._navigation.displayYear = this._state.displayYear;
@@ -580,10 +432,8 @@ export class TyCalendar extends HTMLElement {
580
432
  this._navigation.size = this._size;
581
433
  this._navigation.min = this._min ?? '';
582
434
  this._navigation.max = this._max ?? '';
583
- // Always sync width (set or clear)
584
435
  this._navigation.width = this._width;
585
436
  }
586
- // Update month display
587
437
  if (this._monthDisplay) {
588
438
  this._monthDisplay.displayMonth = this._state.displayMonth;
589
439
  this._monthDisplay.displayYear = this._state.displayYear;
@@ -592,17 +442,13 @@ export class TyCalendar extends HTMLElement {
592
442
  this._monthDisplay.min = this._min;
593
443
  this._monthDisplay.max = this._max;
594
444
  this._monthDisplay.flavor = this._flavor;
595
- // Always sync width (set or clear)
596
445
  this._monthDisplay.width = this._width;
597
- // Pass render functions
598
446
  if (this._dayContentFn) {
599
447
  this._monthDisplay.dayContentFn = this._dayContentFn;
600
448
  }
601
- // Pass custom CSS
602
449
  if (this._customCSS) {
603
450
  this._monthDisplay.customCSS = this._customCSS;
604
451
  }
605
- // Update selection value (convert to Date timestamp)
606
452
  const { selectedYear, selectedMonth, selectedDay } = this._state;
607
453
  if (selectedYear && selectedMonth && selectedDay) {
608
454
  const date = new Date(selectedYear, selectedMonth - 1, selectedDay);
@@ -613,11 +459,7 @@ export class TyCalendar extends HTMLElement {
613
459
  }
614
460
  }
615
461
  }
616
- /**
617
- * Update form value using ElementInternals
618
- */
619
462
  updateFormValue() {
620
- // Skip form participation in stateless mode
621
463
  if (this._stateless)
622
464
  return;
623
465
  if (!this._internals)
@@ -633,10 +475,6 @@ export class TyCalendar extends HTMLElement {
633
475
  }
634
476
  this.updateValidity();
635
477
  }
636
- /**
637
- * Selection outside [min, max] => rangeUnderflow/rangeOverflow.
638
- * UI can't produce this (days are disabled), but programmatic values can.
639
- */
640
478
  updateValidity() {
641
479
  if (!this._internals)
642
480
  return;
@@ -656,22 +494,13 @@ export class TyCalendar extends HTMLElement {
656
494
  }
657
495
  this._internals.setValidity({});
658
496
  }
659
- // ==========================================================================
660
- // Event Handlers
661
- // ==========================================================================
662
- /**
663
- * Handle navigation change (month/year navigation)
664
- */
665
497
  handleNavigationChange(event) {
666
498
  event.preventDefault();
667
499
  event.stopPropagation();
668
500
  const { month, year } = event.detail;
669
- // Update display state
670
501
  this._state.displayMonth = month;
671
502
  this._state.displayYear = year;
672
- // Sync child components
673
503
  this.syncChildComponents();
674
- // Emit navigate event
675
504
  const navigateDetail = {
676
505
  month,
677
506
  year,
@@ -685,16 +514,11 @@ export class TyCalendar extends HTMLElement {
685
514
  cancelable: false,
686
515
  }));
687
516
  }
688
- /**
689
- * Handle day click (day selection)
690
- */
691
517
  handleDayClick(event) {
692
518
  event.preventDefault();
693
519
  event.stopPropagation();
694
520
  const { dayContext, year, month, day } = event.detail;
695
- // In stateless mode, just re-dispatch the event without updating internal state
696
521
  if (this._stateless) {
697
- // Re-dispatch day-click event for parent to handle
698
522
  this.dispatchEvent(new CustomEvent('day-click', {
699
523
  detail: event.detail,
700
524
  bubbles: true,
@@ -703,21 +527,16 @@ export class TyCalendar extends HTMLElement {
703
527
  }));
704
528
  return;
705
529
  }
706
- // Normal mode: update selection state
707
530
  this._state.selectedYear = year;
708
531
  this._state.selectedMonth = month;
709
532
  this._state.selectedDay = day;
710
533
  this._state.displayYear = year;
711
534
  this._state.displayMonth = month;
712
- // Update HTML attributes
713
535
  this.setAttribute('year', year.toString());
714
536
  this.setAttribute('month', month.toString());
715
537
  this.setAttribute('day', day.toString());
716
- // Update form value
717
538
  this.updateFormValue();
718
- // Sync child components
719
539
  this.syncChildComponents();
720
- // Emit change event
721
540
  const changeDetail = {
722
541
  year,
723
542
  month,
@@ -733,51 +552,29 @@ export class TyCalendar extends HTMLElement {
733
552
  cancelable: false,
734
553
  }));
735
554
  }
736
- // ==========================================================================
737
- // Public Methods
738
- // ==========================================================================
739
- /**
740
- * Force re-render of the calendar
741
- * Useful after updating dayContentFn or other dynamic properties
742
- */
743
555
  refresh() {
744
556
  this.syncChildComponents();
745
- // Force month display to re-render (for async data updates)
746
557
  if (this._monthDisplay && typeof this._monthDisplay.refresh === 'function') {
747
558
  this._monthDisplay.refresh();
748
559
  }
749
560
  }
750
- // ==========================================================================
751
- // Rendering
752
- // ==========================================================================
753
- /**
754
- * Create navigation element
755
- */
756
561
  createNavigation() {
757
562
  const nav = document.createElement('ty-calendar-navigation');
758
- // Set properties
759
563
  nav.displayMonth = this._state.displayMonth;
760
564
  nav.displayYear = this._state.displayYear;
761
565
  nav.locale = this.locale;
762
566
  nav.size = this._size;
763
567
  nav.min = this._min ?? '';
764
568
  nav.max = this._max ?? '';
765
- // Only set width if explicitly provided
766
569
  if (this._width) {
767
570
  nav.width = this._width;
768
571
  }
769
- // Listen for change events
770
572
  nav.addEventListener('change', (e) => this.handleNavigationChange(e));
771
- // Store reference
772
573
  this._navigation = nav;
773
574
  return nav;
774
575
  }
775
- /**
776
- * Create month display element
777
- */
778
576
  createMonthDisplay() {
779
577
  const month = document.createElement('ty-calendar-month');
780
- // Set properties
781
578
  month.displayMonth = this._state.displayMonth;
782
579
  month.displayYear = this._state.displayYear;
783
580
  month.locale = this.locale;
@@ -785,61 +582,42 @@ export class TyCalendar extends HTMLElement {
785
582
  month.min = this._min;
786
583
  month.max = this._max;
787
584
  month.flavor = this._flavor;
788
- // Only set width if explicitly provided
789
585
  if (this._width) {
790
586
  month.width = this._width;
791
587
  }
792
- // Set selection value if exists
793
588
  const { selectedYear, selectedMonth, selectedDay } = this._state;
794
589
  if (selectedYear && selectedMonth && selectedDay) {
795
590
  const date = new Date(selectedYear, selectedMonth - 1, selectedDay);
796
591
  month.value = date.getTime();
797
592
  }
798
- // Pass render functions
799
593
  if (this._dayContentFn) {
800
594
  month.dayContentFn = this._dayContentFn;
801
595
  }
802
- // Pass custom CSS
803
596
  if (this._customCSS) {
804
597
  month.customCSS = this._customCSS;
805
598
  }
806
- // Listen for day-click events
807
599
  month.addEventListener('day-click', (e) => this.handleDayClick(e));
808
- // Store reference
809
600
  this._monthDisplay = month;
810
601
  return month;
811
602
  }
812
- /**
813
- * Main render function
814
- */
815
603
  render() {
816
604
  const root = this.shadowRoot;
817
605
  if (!root)
818
606
  return;
819
- // Ensure styles are loaded
820
607
  ensureStyles(root, { css: calendarStyles, id: 'ty-calendar' });
821
- // Clear and rebuild
822
608
  root.innerHTML = '';
823
- // Create main container
824
609
  const container = document.createElement('div');
825
610
  container.className = 'calendar-container';
826
- // Add navigation if requested
827
611
  if (this._showNavigation) {
828
612
  const nav = this.createNavigation();
829
613
  container.appendChild(nav);
830
614
  }
831
- // Add month display
832
615
  const month = this.createMonthDisplay();
833
616
  container.appendChild(month);
834
617
  root.appendChild(container);
835
618
  }
836
619
  }
837
- /**
838
- * Form-associated custom element
839
- */
840
620
  TyCalendar.formAssociated = true;
841
- // Register the custom element
842
621
  if (!customElements.get('ty-calendar')) {
843
622
  customElements.define('ty-calendar', TyCalendar);
844
623
  }
845
- //# sourceMappingURL=calendar.js.map