tyrell-components 1.0.0-RC13 → 1.0.0-RC15

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 (358) hide show
  1. package/README.md +10 -2
  2. package/css/tyrell-theme.css +192 -180
  3. package/css/tyrell.css +23 -0
  4. package/dist/tyrell-colors-static.css +1 -316
  5. package/dist/tyrell-theme.css +1 -1454
  6. package/dist/tyrell.css +1 -1371
  7. package/dist/tyrell.js +1 -1
  8. package/lib/base/ty-component.d.ts +20 -10
  9. package/lib/base/ty-component.js +196 -319
  10. package/lib/components/button.d.ts +3 -17
  11. package/lib/components/button.js +261 -295
  12. package/lib/components/calendar-month.d.ts +4 -50
  13. package/lib/components/calendar-month.js +443 -582
  14. package/lib/components/calendar-navigation.d.ts +3 -48
  15. package/lib/components/calendar-navigation.js +239 -362
  16. package/lib/components/calendar.d.ts +8 -83
  17. package/lib/components/calendar.js +616 -829
  18. package/lib/components/checkbox.d.ts +5 -72
  19. package/lib/components/checkbox.js +273 -416
  20. package/lib/components/copy.d.ts +4 -57
  21. package/lib/components/copy.js +280 -397
  22. package/lib/components/date-picker.d.ts +21 -163
  23. package/lib/components/date-picker.js +1143 -1674
  24. package/lib/components/file-upload.d.ts +9 -15
  25. package/lib/components/file-upload.js +404 -426
  26. package/lib/components/icon.d.ts +3 -24
  27. package/lib/components/icon.js +141 -230
  28. package/lib/components/input.d.ts +8 -108
  29. package/lib/components/input.js +593 -784
  30. package/lib/components/modal.d.ts +17 -26
  31. package/lib/components/modal.js +340 -484
  32. package/lib/components/option.d.ts +2 -9
  33. package/lib/components/option.js +168 -216
  34. package/lib/components/popup.d.ts +2 -17
  35. package/lib/components/popup.js +249 -380
  36. package/lib/components/radio.d.ts +5 -25
  37. package/lib/components/radio.js +407 -461
  38. package/lib/components/resize-observer.d.ts +3 -30
  39. package/lib/components/resize-observer.js +69 -103
  40. package/lib/components/scroll-container.d.ts +2 -12
  41. package/lib/components/scroll-container.js +293 -338
  42. package/lib/components/select.d.ts +87 -159
  43. package/lib/components/select.js +1609 -2090
  44. package/lib/components/selected-tags.d.ts +5 -48
  45. package/lib/components/selected-tags.js +188 -276
  46. package/lib/components/step.d.ts +1 -6
  47. package/lib/components/step.js +62 -68
  48. package/lib/components/switch.d.ts +1 -12
  49. package/lib/components/switch.js +214 -247
  50. package/lib/components/tab.d.ts +1 -6
  51. package/lib/components/tab.js +62 -69
  52. package/lib/components/tabs.d.ts +6 -63
  53. package/lib/components/tabs.js +545 -777
  54. package/lib/components/tag.d.ts +3 -37
  55. package/lib/components/tag.js +236 -335
  56. package/lib/components/textarea.d.ts +7 -87
  57. package/lib/components/textarea.js +457 -627
  58. package/lib/components/tooltip.d.ts +3 -11
  59. package/lib/components/tooltip.js +307 -443
  60. package/lib/components/wizard.d.ts +6 -54
  61. package/lib/components/wizard.js +405 -618
  62. package/lib/icons/fontawesome/brands.d.ts +0 -1
  63. package/lib/icons/fontawesome/brands.js +0 -8
  64. package/lib/icons/fontawesome/regular.d.ts +0 -1
  65. package/lib/icons/fontawesome/regular.js +0 -8
  66. package/lib/icons/fontawesome/solid.d.ts +0 -1
  67. package/lib/icons/fontawesome/solid.js +0 -8
  68. package/lib/icons/heroicons/micro.d.ts +0 -1
  69. package/lib/icons/heroicons/micro.js +392 -400
  70. package/lib/icons/heroicons/mini.d.ts +0 -1
  71. package/lib/icons/heroicons/mini.js +382 -390
  72. package/lib/icons/heroicons/outline.d.ts +0 -1
  73. package/lib/icons/heroicons/outline.js +337 -345
  74. package/lib/icons/heroicons/solid.d.ts +0 -1
  75. package/lib/icons/heroicons/solid.js +407 -415
  76. package/lib/icons/lucide.d.ts +0 -1
  77. package/lib/icons/lucide.js +24479 -26351
  78. package/lib/icons/material/filled.d.ts +0 -1
  79. package/lib/icons/material/filled.js +9653 -9663
  80. package/lib/icons/material/outlined.d.ts +0 -1
  81. package/lib/icons/material/outlined.js +10271 -10281
  82. package/lib/icons/material/round.d.ts +0 -1
  83. package/lib/icons/material/round.js +10495 -10505
  84. package/lib/icons/material/sharp.d.ts +0 -1
  85. package/lib/icons/material/sharp.js +9905 -9915
  86. package/lib/icons/material/two-tone.d.ts +0 -1
  87. package/lib/icons/material/two-tone.js +12792 -12802
  88. package/lib/index.d.ts +0 -1
  89. package/lib/index.js +21 -41
  90. package/lib/styles/button.d.ts +2 -20
  91. package/lib/styles/button.js +202 -404
  92. package/lib/styles/calendar-month.d.ts +1 -5
  93. package/lib/styles/calendar-month.js +127 -244
  94. package/lib/styles/calendar-navigation.d.ts +2 -6
  95. package/lib/styles/calendar-navigation.js +64 -104
  96. package/lib/styles/calendar.d.ts +1 -2
  97. package/lib/styles/calendar.js +9 -22
  98. package/lib/styles/checkbox.d.ts +0 -1
  99. package/lib/styles/checkbox.js +45 -94
  100. package/lib/styles/copy.d.ts +0 -1
  101. package/lib/styles/copy.js +67 -106
  102. package/lib/styles/custom-scrollbar.d.ts +1 -2
  103. package/lib/styles/custom-scrollbar.js +80 -115
  104. package/lib/styles/date-picker.d.ts +1 -5
  105. package/lib/styles/date-picker.js +261 -335
  106. package/lib/styles/field-size.d.ts +6 -0
  107. package/lib/styles/field-size.js +91 -0
  108. package/lib/styles/file-upload.d.ts +1 -2
  109. package/lib/styles/file-upload.js +143 -188
  110. package/lib/styles/icon.d.ts +2 -6
  111. package/lib/styles/icon.js +92 -170
  112. package/lib/styles/input.d.ts +1 -6
  113. package/lib/styles/input.js +125 -290
  114. package/lib/styles/modal.d.ts +1 -2
  115. package/lib/styles/modal.js +71 -108
  116. package/lib/styles/option.d.ts +2 -6
  117. package/lib/styles/option.js +49 -64
  118. package/lib/styles/popup.d.ts +1 -2
  119. package/lib/styles/popup.js +42 -77
  120. package/lib/styles/radio.d.ts +0 -1
  121. package/lib/styles/radio.js +69 -110
  122. package/lib/styles/resize-observer.d.ts +1 -2
  123. package/lib/styles/resize-observer.js +2 -12
  124. package/lib/styles/scroll-container.d.ts +1 -2
  125. package/lib/styles/scroll-container.js +100 -149
  126. package/lib/styles/select-base.d.ts +0 -1
  127. package/lib/styles/select-base.js +597 -785
  128. package/lib/styles/select.d.ts +1 -2
  129. package/lib/styles/select.js +140 -236
  130. package/lib/styles/step.d.ts +1 -2
  131. package/lib/styles/step.js +22 -33
  132. package/lib/styles/switch.d.ts +0 -1
  133. package/lib/styles/switch.js +34 -73
  134. package/lib/styles/tab.d.ts +1 -2
  135. package/lib/styles/tab.js +22 -34
  136. package/lib/styles/tabs.d.ts +3 -11
  137. package/lib/styles/tabs.js +190 -222
  138. package/lib/styles/tag.d.ts +1 -5
  139. package/lib/styles/tag.js +136 -218
  140. package/lib/styles/textarea.d.ts +1 -2
  141. package/lib/styles/textarea.js +210 -319
  142. package/lib/styles/tooltip.d.ts +0 -1
  143. package/lib/styles/tooltip.js +3 -13
  144. package/lib/styles/wizard.d.ts +5 -21
  145. package/lib/styles/wizard.js +170 -306
  146. package/lib/types/common.d.ts +2 -2
  147. package/lib/types/common.js +6 -17
  148. package/lib/utils/calendar-utils.d.ts +4 -21
  149. package/lib/utils/calendar-utils.js +100 -273
  150. package/lib/utils/custom-scrollbar.d.ts +6 -20
  151. package/lib/utils/custom-scrollbar.js +273 -317
  152. package/lib/utils/flavor-sheet.d.ts +0 -1
  153. package/lib/utils/flavor-sheet.js +14 -37
  154. package/lib/utils/icon-registry.d.ts +0 -2
  155. package/lib/utils/icon-registry.js +137 -243
  156. package/lib/utils/icons.d.ts +0 -1
  157. package/lib/utils/icons.js +0 -9
  158. package/lib/utils/loader-registry.d.ts +0 -1
  159. package/lib/utils/loader-registry.js +3 -35
  160. package/lib/utils/locale.d.ts +2 -23
  161. package/lib/utils/locale.js +34 -120
  162. package/lib/utils/mobile.d.ts +0 -1
  163. package/lib/utils/mobile.js +1 -18
  164. package/lib/utils/number-format.d.ts +6 -3
  165. package/lib/utils/number-format.js +54 -110
  166. package/lib/utils/positioning.d.ts +50 -7
  167. package/lib/utils/positioning.js +224 -234
  168. package/lib/utils/property-capture.d.ts +5 -27
  169. package/lib/utils/property-capture.js +36 -144
  170. package/lib/utils/property-manager.d.ts +0 -1
  171. package/lib/utils/property-manager.js +126 -196
  172. package/lib/utils/resize-observer.d.ts +0 -1
  173. package/lib/utils/resize-observer.js +23 -59
  174. package/lib/utils/scroll-lock.d.ts +4 -11
  175. package/lib/utils/scroll-lock.js +65 -172
  176. package/lib/utils/styles.d.ts +0 -1
  177. package/lib/utils/styles.js +17 -41
  178. package/lib/version.d.ts +1 -2
  179. package/lib/version.js +1 -11
  180. package/package.json +4 -4
  181. package/lib/base/ty-component.d.ts.map +0 -1
  182. package/lib/base/ty-component.js.map +0 -1
  183. package/lib/components/button.d.ts.map +0 -1
  184. package/lib/components/button.js.map +0 -1
  185. package/lib/components/calendar-month.d.ts.map +0 -1
  186. package/lib/components/calendar-month.js.map +0 -1
  187. package/lib/components/calendar-navigation.d.ts.map +0 -1
  188. package/lib/components/calendar-navigation.js.map +0 -1
  189. package/lib/components/calendar.d.ts.map +0 -1
  190. package/lib/components/calendar.js.map +0 -1
  191. package/lib/components/checkbox.d.ts.map +0 -1
  192. package/lib/components/checkbox.js.map +0 -1
  193. package/lib/components/copy.d.ts.map +0 -1
  194. package/lib/components/copy.js.map +0 -1
  195. package/lib/components/date-picker.d.ts.map +0 -1
  196. package/lib/components/date-picker.js.map +0 -1
  197. package/lib/components/file-upload.d.ts.map +0 -1
  198. package/lib/components/file-upload.js.map +0 -1
  199. package/lib/components/icon.d.ts.map +0 -1
  200. package/lib/components/icon.js.map +0 -1
  201. package/lib/components/input.d.ts.map +0 -1
  202. package/lib/components/input.js.map +0 -1
  203. package/lib/components/modal.d.ts.map +0 -1
  204. package/lib/components/modal.js.map +0 -1
  205. package/lib/components/option.d.ts.map +0 -1
  206. package/lib/components/option.js.map +0 -1
  207. package/lib/components/popup.d.ts.map +0 -1
  208. package/lib/components/popup.js.map +0 -1
  209. package/lib/components/radio.d.ts.map +0 -1
  210. package/lib/components/radio.js.map +0 -1
  211. package/lib/components/resize-observer.d.ts.map +0 -1
  212. package/lib/components/resize-observer.js.map +0 -1
  213. package/lib/components/scroll-container.d.ts.map +0 -1
  214. package/lib/components/scroll-container.js.map +0 -1
  215. package/lib/components/select.d.ts.map +0 -1
  216. package/lib/components/select.js.map +0 -1
  217. package/lib/components/selected-tags.d.ts.map +0 -1
  218. package/lib/components/selected-tags.js.map +0 -1
  219. package/lib/components/step.d.ts.map +0 -1
  220. package/lib/components/step.js.map +0 -1
  221. package/lib/components/switch.d.ts.map +0 -1
  222. package/lib/components/switch.js.map +0 -1
  223. package/lib/components/tab.d.ts.map +0 -1
  224. package/lib/components/tab.js.map +0 -1
  225. package/lib/components/tabs.d.ts.map +0 -1
  226. package/lib/components/tabs.js.map +0 -1
  227. package/lib/components/tag.d.ts.map +0 -1
  228. package/lib/components/tag.js.map +0 -1
  229. package/lib/components/textarea.d.ts.map +0 -1
  230. package/lib/components/textarea.js.map +0 -1
  231. package/lib/components/tooltip.d.ts.map +0 -1
  232. package/lib/components/tooltip.js.map +0 -1
  233. package/lib/components/wizard.d.ts.map +0 -1
  234. package/lib/components/wizard.js.map +0 -1
  235. package/lib/icons/fontawesome/brands.d.ts.map +0 -1
  236. package/lib/icons/fontawesome/brands.js.map +0 -1
  237. package/lib/icons/fontawesome/regular.d.ts.map +0 -1
  238. package/lib/icons/fontawesome/regular.js.map +0 -1
  239. package/lib/icons/fontawesome/solid.d.ts.map +0 -1
  240. package/lib/icons/fontawesome/solid.js.map +0 -1
  241. package/lib/icons/heroicons/micro.d.ts.map +0 -1
  242. package/lib/icons/heroicons/micro.js.map +0 -1
  243. package/lib/icons/heroicons/mini.d.ts.map +0 -1
  244. package/lib/icons/heroicons/mini.js.map +0 -1
  245. package/lib/icons/heroicons/outline.d.ts.map +0 -1
  246. package/lib/icons/heroicons/outline.js.map +0 -1
  247. package/lib/icons/heroicons/solid.d.ts.map +0 -1
  248. package/lib/icons/heroicons/solid.js.map +0 -1
  249. package/lib/icons/lucide.d.ts.map +0 -1
  250. package/lib/icons/lucide.js.map +0 -1
  251. package/lib/icons/material/filled.d.ts.map +0 -1
  252. package/lib/icons/material/filled.js.map +0 -1
  253. package/lib/icons/material/outlined.d.ts.map +0 -1
  254. package/lib/icons/material/outlined.js.map +0 -1
  255. package/lib/icons/material/round.d.ts.map +0 -1
  256. package/lib/icons/material/round.js.map +0 -1
  257. package/lib/icons/material/sharp.d.ts.map +0 -1
  258. package/lib/icons/material/sharp.js.map +0 -1
  259. package/lib/icons/material/two-tone.d.ts.map +0 -1
  260. package/lib/icons/material/two-tone.js.map +0 -1
  261. package/lib/index.d.ts.map +0 -1
  262. package/lib/index.js.map +0 -1
  263. package/lib/styles/button.d.ts.map +0 -1
  264. package/lib/styles/button.js.map +0 -1
  265. package/lib/styles/calendar-month.d.ts.map +0 -1
  266. package/lib/styles/calendar-month.js.map +0 -1
  267. package/lib/styles/calendar-navigation.d.ts.map +0 -1
  268. package/lib/styles/calendar-navigation.js.map +0 -1
  269. package/lib/styles/calendar.d.ts.map +0 -1
  270. package/lib/styles/calendar.js.map +0 -1
  271. package/lib/styles/checkbox.d.ts.map +0 -1
  272. package/lib/styles/checkbox.js.map +0 -1
  273. package/lib/styles/copy.d.ts.map +0 -1
  274. package/lib/styles/copy.js.map +0 -1
  275. package/lib/styles/custom-scrollbar.d.ts.map +0 -1
  276. package/lib/styles/custom-scrollbar.js.map +0 -1
  277. package/lib/styles/date-picker.d.ts.map +0 -1
  278. package/lib/styles/date-picker.js.map +0 -1
  279. package/lib/styles/file-upload.d.ts.map +0 -1
  280. package/lib/styles/file-upload.js.map +0 -1
  281. package/lib/styles/icon.d.ts.map +0 -1
  282. package/lib/styles/icon.js.map +0 -1
  283. package/lib/styles/input.d.ts.map +0 -1
  284. package/lib/styles/input.js.map +0 -1
  285. package/lib/styles/modal.d.ts.map +0 -1
  286. package/lib/styles/modal.js.map +0 -1
  287. package/lib/styles/multiselect.d.ts +0 -8
  288. package/lib/styles/multiselect.d.ts.map +0 -1
  289. package/lib/styles/multiselect.js +0 -849
  290. package/lib/styles/multiselect.js.map +0 -1
  291. package/lib/styles/option.d.ts.map +0 -1
  292. package/lib/styles/option.js.map +0 -1
  293. package/lib/styles/popup.d.ts.map +0 -1
  294. package/lib/styles/popup.js.map +0 -1
  295. package/lib/styles/radio.d.ts.map +0 -1
  296. package/lib/styles/radio.js.map +0 -1
  297. package/lib/styles/resize-observer.d.ts.map +0 -1
  298. package/lib/styles/resize-observer.js.map +0 -1
  299. package/lib/styles/scroll-container.d.ts.map +0 -1
  300. package/lib/styles/scroll-container.js.map +0 -1
  301. package/lib/styles/select-base.d.ts.map +0 -1
  302. package/lib/styles/select-base.js.map +0 -1
  303. package/lib/styles/select.d.ts.map +0 -1
  304. package/lib/styles/select.js.map +0 -1
  305. package/lib/styles/step.d.ts.map +0 -1
  306. package/lib/styles/step.js.map +0 -1
  307. package/lib/styles/switch.d.ts.map +0 -1
  308. package/lib/styles/switch.js.map +0 -1
  309. package/lib/styles/tab.d.ts.map +0 -1
  310. package/lib/styles/tab.js.map +0 -1
  311. package/lib/styles/tabs.d.ts.map +0 -1
  312. package/lib/styles/tabs.js.map +0 -1
  313. package/lib/styles/tag.d.ts.map +0 -1
  314. package/lib/styles/tag.js.map +0 -1
  315. package/lib/styles/textarea.d.ts.map +0 -1
  316. package/lib/styles/textarea.js.map +0 -1
  317. package/lib/styles/tooltip.d.ts.map +0 -1
  318. package/lib/styles/tooltip.js.map +0 -1
  319. package/lib/styles/wizard.d.ts.map +0 -1
  320. package/lib/styles/wizard.js.map +0 -1
  321. package/lib/types/common.d.ts.map +0 -1
  322. package/lib/types/common.js.map +0 -1
  323. package/lib/utils/calendar-utils.d.ts.map +0 -1
  324. package/lib/utils/calendar-utils.js.map +0 -1
  325. package/lib/utils/custom-scrollbar.d.ts.map +0 -1
  326. package/lib/utils/custom-scrollbar.js.map +0 -1
  327. package/lib/utils/flavor-sheet.d.ts.map +0 -1
  328. package/lib/utils/flavor-sheet.js.map +0 -1
  329. package/lib/utils/icon-registry.d.ts.map +0 -1
  330. package/lib/utils/icon-registry.js.map +0 -1
  331. package/lib/utils/icons.d.ts.map +0 -1
  332. package/lib/utils/icons.js.map +0 -1
  333. package/lib/utils/loader-registry.d.ts.map +0 -1
  334. package/lib/utils/loader-registry.js.map +0 -1
  335. package/lib/utils/locale.d.ts.map +0 -1
  336. package/lib/utils/locale.js.map +0 -1
  337. package/lib/utils/mobile.d.ts.map +0 -1
  338. package/lib/utils/mobile.js.map +0 -1
  339. package/lib/utils/number-format.d.ts.map +0 -1
  340. package/lib/utils/number-format.js.map +0 -1
  341. package/lib/utils/parse-boolean.d.ts +0 -39
  342. package/lib/utils/parse-boolean.d.ts.map +0 -1
  343. package/lib/utils/parse-boolean.js +0 -58
  344. package/lib/utils/parse-boolean.js.map +0 -1
  345. package/lib/utils/positioning.d.ts.map +0 -1
  346. package/lib/utils/positioning.js.map +0 -1
  347. package/lib/utils/property-capture.d.ts.map +0 -1
  348. package/lib/utils/property-capture.js.map +0 -1
  349. package/lib/utils/property-manager.d.ts.map +0 -1
  350. package/lib/utils/property-manager.js.map +0 -1
  351. package/lib/utils/resize-observer.d.ts.map +0 -1
  352. package/lib/utils/resize-observer.js.map +0 -1
  353. package/lib/utils/scroll-lock.d.ts.map +0 -1
  354. package/lib/utils/scroll-lock.js.map +0 -1
  355. package/lib/utils/styles.d.ts.map +0 -1
  356. package/lib/utils/styles.js.map +0 -1
  357. package/lib/version.d.ts.map +0 -1
  358. package/lib/version.js.map +0 -1
@@ -1,45 +1,8 @@
1
- /**
2
- * TyCalendarNavigation Web Component
3
- * PORTED FROM: cljs/ty/components/calendar_navigation.cljs
4
- *
5
- * A pure presentation component for calendar month/year navigation.
6
- * Stateless - all state comes from properties, changes emitted via events.
7
- *
8
- * Features:
9
- * - Year/Month navigation (prev/next month, prev/next year)
10
- * - Localized month name display
11
- * - Custom event emission on navigation
12
- * - Property-driven API (no internal state)
13
- * - Inline SVG icons
14
- * - Shadow DOM encapsulation
15
- *
16
- * @example
17
- * ```html
18
- * <!-- Basic usage -->
19
- * <ty-calendar-navigation
20
- * display-month="10"
21
- * display-year="2025"
22
- * locale="en-US">
23
- * </ty-calendar-navigation>
24
- *
25
- * <!-- Listen for changes -->
26
- * <script type="module">
27
- * const nav = document.querySelector('ty-calendar-navigation');
28
- * nav.addEventListener('change', (e) => {
29
- * console.log('New month:', e.detail.month);
30
- * console.log('New year:', e.detail.year);
31
- * });
32
- * </script>
33
- * ```
34
- */
35
1
  import { ensureStyles } from '../utils/styles.js';
36
2
  import { calendarNavigationStyles } from '../styles/calendar-navigation.js';
37
3
  import { getMonthName, parseISODate } from '../utils/calendar-utils.js';
38
4
  import { getEffectiveLocale, observeLocaleChanges } from '../utils/locale.js';
39
5
  import { TyComponent } from '../base/ty-component.js';
40
- // ============================================================================
41
- // SVG Icons (Material Design)
42
- // ============================================================================
43
6
  const CHEVRON_LEFT_SVG = `<?xml version='1.0' encoding='UTF-8'?>
44
7
  <svg width='24' viewBox='0 0 24 24' height='24' xmlns='http://www.w3.org/2000/svg' stroke-width='0' stroke='currentColor' fill='currentColor'>
45
8
  <path fill='none' d='M0 0h24v24H0V0z'/>
@@ -74,333 +37,247 @@ const CHEVRONS_RIGHT_SVG = `<?xml version='1.0' encoding='UTF-8'?>
74
37
  </g>
75
38
  </g>
76
39
  </svg>`;
77
- // ============================================================================
78
- // Component Implementation
79
- // ============================================================================
80
- /**
81
- * TyCalendarNavigation Web Component
82
- */
83
40
  export class TyCalendarNavigation extends TyComponent {
84
- constructor() {
85
- super(); // TyComponent handles attachShadow
86
- // Initialize state with current date
87
- const today = new Date();
88
- this._state = {
89
- displayMonth: today.getMonth() + 1,
90
- displayYear: today.getFullYear()
91
- };
92
- // Initialize styles in shadow root
93
- const shadow = this.shadowRoot;
94
- ensureStyles(shadow, { css: calendarNavigationStyles, id: 'ty-calendar-navigation' });
95
- }
96
- // ==========================================================================
97
- // Lifecycle Hooks (TyComponent)
98
- // ==========================================================================
99
- /**
100
- * Called when component connects to DOM
101
- */
102
- onConnect() {
103
- // Sync state from properties
104
- this._state.displayMonth = this.displayMonth;
105
- this._state.displayYear = this.displayYear;
106
- // Setup locale observer to watch for ancestor lang changes
107
- this._localeObserver = observeLocaleChanges(this, () => {
108
- this.render();
109
- });
110
- // Initial render
111
- this.render();
112
- }
113
- /**
114
- * Called when component disconnects from DOM
115
- */
116
- onDisconnect() {
117
- // Cleanup locale observer
118
- if (this._localeObserver) {
119
- this._localeObserver();
120
- this._localeObserver = undefined;
121
- }
122
- }
123
- /**
124
- * Called when properties change
125
- * Update internal state BEFORE render
126
- */
127
- onPropertiesChanged(changes) {
128
- for (const { name, newValue } of changes) {
129
- switch (name) {
130
- case 'display-month':
131
- this._state.displayMonth = newValue;
132
- break;
133
- case 'display-year':
134
- this._state.displayYear = newValue;
135
- break;
136
- case 'locale':
137
- case 'size':
138
- case 'width':
139
- // These properties just affect rendering
140
- // TyComponent will call render() automatically for visual properties
141
- break;
142
- }
143
- }
144
- }
145
- // ==========================================================================
146
- // Property Accessors - Simple wrappers using TyComponent
147
- // ==========================================================================
148
- get displayMonth() {
149
- return this.getProperty('display-month');
150
- }
151
- set displayMonth(value) {
152
- this.setProperty('display-month', value);
153
- }
154
- get displayYear() {
155
- return this.getProperty('display-year');
156
- }
157
- set displayYear(value) {
158
- this.setProperty('display-year', value);
159
- }
160
- get locale() {
161
- // Use getEffectiveLocale to check ancestor lang attributes
162
- return getEffectiveLocale(this, this.getProperty('locale'));
163
- }
164
- set locale(value) {
165
- this.setProperty('locale', value);
166
- }
167
- get size() {
168
- return this.getProperty('size');
169
- }
170
- set size(value) {
171
- this.setProperty('size', value);
172
- }
173
- get width() {
174
- return this.getProperty('width');
175
- }
176
- set width(value) {
177
- this.setProperty('width', value);
178
- }
179
- get min() {
180
- return this.getProperty('min');
181
- }
182
- set min(value) {
183
- this.setProperty('min', value ?? '');
184
- }
185
- get max() {
186
- return this.getProperty('max');
187
- }
188
- set max(value) {
189
- this.setProperty('max', value ?? '');
190
- }
191
- // ==========================================================================
192
- // Event Dispatching
193
- // ==========================================================================
194
- /**
195
- * Emit change event with new month/year
196
- */
197
- emitChangeEvent(month, year) {
198
- const detail = {
199
- month,
200
- year,
201
- };
202
- const event = new CustomEvent('change', {
203
- detail,
204
- bubbles: true,
205
- cancelable: true,
206
- });
207
- this.dispatchEvent(event);
208
- }
209
- // ==========================================================================
210
- // Navigation Logic
211
- // ==========================================================================
212
- /**
213
- * Month index (year * 12 + month - 1) — flat, comparable month math.
214
- */
215
- static monthIndex(year, month) {
216
- return year * 12 + (month - 1);
217
- }
218
- /**
219
- * min/max as month indices (null when unset/invalid)
220
- */
221
- boundIndices() {
222
- const min = parseISODate(this.min);
223
- const max = parseISODate(this.max);
224
- return {
225
- minIdx: min ? TyCalendarNavigation.monthIndex(min.year, min.month) : null,
226
- maxIdx: max ? TyCalendarNavigation.monthIndex(max.year, max.month) : null,
227
- };
228
- }
229
- /**
230
- * Clamp a target month index to [min, max]
231
- */
232
- clampIndex(idx) {
233
- const { minIdx, maxIdx } = this.boundIndices();
234
- if (minIdx !== null && idx < minIdx)
235
- return minIdx;
236
- if (maxIdx !== null && idx > maxIdx)
237
- return maxIdx;
238
- return idx;
239
- }
240
- /**
241
- * Navigate by month/year delta, clamped to bounds.
242
- * Year jumps near a bound land ON the bound month instead of overshooting.
243
- */
244
- navigateBy(deltaMonths) {
245
- const current = TyCalendarNavigation.monthIndex(this._state.displayYear, this._state.displayMonth);
246
- const target = this.clampIndex(current + deltaMonths);
247
- if (target === current)
248
- return; // Already at the bound
249
- this.emitChangeEvent((target % 12) + 1, Math.floor(target / 12));
250
- }
251
- /**
252
- * True when navigating by deltaMonths can't move the display (bound reached)
253
- */
254
- isNavDisabled(deltaMonths) {
255
- const current = TyCalendarNavigation.monthIndex(this._state.displayYear, this._state.displayMonth);
256
- return this.clampIndex(current + deltaMonths) === current;
257
- }
258
- // ==========================================================================
259
- // Rendering
260
- // ==========================================================================
261
- /**
262
- * Create navigation button
263
- */
264
- createButton(className, title, svg, onClick, disabled = false) {
265
- const button = document.createElement('button');
266
- button.className = className;
267
- button.title = title;
268
- button.innerHTML = svg;
269
- button.disabled = disabled;
270
- button.addEventListener('click', onClick);
271
- return button;
272
- }
273
- /**
274
- * Main render function
275
- */
276
- render() {
277
- const root = this.shadowRoot;
278
- if (!root)
279
- return;
280
- // Ensure styles are loaded
281
- ensureStyles(root, { css: calendarNavigationStyles, id: 'ty-calendar-navigation' });
282
- // Apply size as data attribute for CSS targeting
283
- const size = this.size;
284
- this.setAttribute('data-size', size);
285
- // Apply width property as CSS custom property
286
- const width = this.width;
287
- if (width) {
288
- this.style.setProperty('--nav-width', width);
289
- }
290
- else {
291
- this.style.removeProperty('--nav-width');
292
- }
293
- // Get localized month name using current state
294
- const monthName = getMonthName(this._state.displayMonth, this.locale, 'long');
295
- // Clear and rebuild
296
- root.innerHTML = '';
297
- // Create main header container
298
- const header = document.createElement('div');
299
- header.className = 'calendar-navigation-header';
300
- // Left group: [⟪ ‹]
301
- const leftGroup = document.createElement('div');
302
- leftGroup.className = 'nav-group nav-group-left';
303
- leftGroup.appendChild(this.createButton('nav-btn nav-year-prev', 'Previous year', CHEVRONS_LEFT_SVG, () => this.navigateBy(-12), this.isNavDisabled(-12)));
304
- leftGroup.appendChild(this.createButton('nav-btn nav-month-prev', 'Previous month', CHEVRON_LEFT_SVG, () => this.navigateBy(-1), this.isNavDisabled(-1)));
305
- // Center group: [Month Year]
306
- const centerGroup = document.createElement('div');
307
- centerGroup.className = 'nav-group nav-group-center';
308
- const monthYearDisplay = document.createElement('div');
309
- monthYearDisplay.className = 'month-year-display';
310
- monthYearDisplay.textContent = `${monthName} ${this._state.displayYear}`;
311
- centerGroup.appendChild(monthYearDisplay);
312
- // Right group: [› ⟫]
313
- const rightGroup = document.createElement('div');
314
- rightGroup.className = 'nav-group nav-group-right';
315
- rightGroup.appendChild(this.createButton('nav-btn nav-month-next', 'Next month', CHEVRON_RIGHT_SVG, () => this.navigateBy(1), this.isNavDisabled(1)));
316
- rightGroup.appendChild(this.createButton('nav-btn nav-year-next', 'Next year', CHEVRONS_RIGHT_SVG, () => this.navigateBy(12), this.isNavDisabled(12)));
317
- // Assemble header
318
- header.appendChild(leftGroup);
319
- header.appendChild(centerGroup);
320
- header.appendChild(rightGroup);
321
- root.appendChild(header);
322
- }
323
- }
324
- // ============================================================================
325
- // PROPERTY CONFIGURATION - Single source of truth
326
- // ============================================================================
41
+ constructor() {
42
+ super();
43
+ const today = new Date();
44
+ this._state = {
45
+ displayMonth: today.getMonth() + 1,
46
+ displayYear: today.getFullYear()
47
+ };
48
+ const shadow = this.shadowRoot;
49
+ ensureStyles(shadow, { css: calendarNavigationStyles, id: 'ty-calendar-navigation' });
50
+ }
51
+ onConnect() {
52
+ this._state.displayMonth = this.displayMonth;
53
+ this._state.displayYear = this.displayYear;
54
+ this._localeObserver = observeLocaleChanges(this, () => {
55
+ this.render();
56
+ });
57
+ this.render();
58
+ }
59
+ onDisconnect() {
60
+ if (this._localeObserver) {
61
+ this._localeObserver();
62
+ this._localeObserver = undefined;
63
+ }
64
+ }
65
+ onPropertiesChanged(changes) {
66
+ for (const { name, newValue } of changes) {
67
+ switch (name) {
68
+ case 'display-month':
69
+ this._state.displayMonth = newValue;
70
+ break;
71
+ case 'display-year':
72
+ this._state.displayYear = newValue;
73
+ break;
74
+ case 'locale':
75
+ case 'size':
76
+ case 'width':
77
+ break;
78
+ }
79
+ }
80
+ }
81
+ get displayMonth() {
82
+ return this.getProperty('display-month');
83
+ }
84
+ set displayMonth(value) {
85
+ this.setProperty('display-month', value);
86
+ }
87
+ get displayYear() {
88
+ return this.getProperty('display-year');
89
+ }
90
+ set displayYear(value) {
91
+ this.setProperty('display-year', value);
92
+ }
93
+ get locale() {
94
+ return getEffectiveLocale(this, this.getProperty('locale'));
95
+ }
96
+ set locale(value) {
97
+ this.setProperty('locale', value);
98
+ }
99
+ get size() {
100
+ return this.getProperty('size');
101
+ }
102
+ set size(value) {
103
+ this.setProperty('size', value);
104
+ }
105
+ get width() {
106
+ return this.getProperty('width');
107
+ }
108
+ set width(value) {
109
+ this.setProperty('width', value);
110
+ }
111
+ get min() {
112
+ return this.getProperty('min');
113
+ }
114
+ set min(value) {
115
+ this.setProperty('min', value ?? '');
116
+ }
117
+ get max() {
118
+ return this.getProperty('max');
119
+ }
120
+ set max(value) {
121
+ this.setProperty('max', value ?? '');
122
+ }
123
+ emitChangeEvent(month, year) {
124
+ const detail = {
125
+ month,
126
+ year,
127
+ };
128
+ const event = new CustomEvent('change', {
129
+ detail,
130
+ bubbles: true,
131
+ cancelable: true,
132
+ });
133
+ this.dispatchEvent(event);
134
+ }
135
+ static monthIndex(year, month) {
136
+ return year * 12 + (month - 1);
137
+ }
138
+ boundIndices() {
139
+ const min = parseISODate(this.min);
140
+ const max = parseISODate(this.max);
141
+ return {
142
+ minIdx: min ? TyCalendarNavigation.monthIndex(min.year, min.month) : null,
143
+ maxIdx: max ? TyCalendarNavigation.monthIndex(max.year, max.month) : null,
144
+ };
145
+ }
146
+ clampIndex(idx) {
147
+ const { minIdx, maxIdx } = this.boundIndices();
148
+ if (minIdx !== null && idx < minIdx)
149
+ return minIdx;
150
+ if (maxIdx !== null && idx > maxIdx)
151
+ return maxIdx;
152
+ return idx;
153
+ }
154
+ navigateBy(deltaMonths) {
155
+ const current = TyCalendarNavigation.monthIndex(this._state.displayYear, this._state.displayMonth);
156
+ const target = this.clampIndex(current + deltaMonths);
157
+ if (target === current)
158
+ return;
159
+ this.emitChangeEvent((target % 12) + 1, Math.floor(target / 12));
160
+ }
161
+ isNavDisabled(deltaMonths) {
162
+ const current = TyCalendarNavigation.monthIndex(this._state.displayYear, this._state.displayMonth);
163
+ return this.clampIndex(current + deltaMonths) === current;
164
+ }
165
+ createButton(className, title, svg, onClick, disabled = false) {
166
+ const button = document.createElement('button');
167
+ button.className = className;
168
+ button.title = title;
169
+ button.innerHTML = svg;
170
+ button.disabled = disabled;
171
+ button.addEventListener('click', onClick);
172
+ return button;
173
+ }
174
+ render() {
175
+ const root = this.shadowRoot;
176
+ if (!root)
177
+ return;
178
+ ensureStyles(root, { css: calendarNavigationStyles, id: 'ty-calendar-navigation' });
179
+ const size = this.size;
180
+ this.setAttribute('data-size', size);
181
+ const width = this.width;
182
+ if (width) {
183
+ this.style.setProperty('--nav-width', width);
184
+ }
185
+ else {
186
+ this.style.removeProperty('--nav-width');
187
+ }
188
+ const monthName = getMonthName(this._state.displayMonth, this.locale, 'long');
189
+ root.innerHTML = '';
190
+ const header = document.createElement('div');
191
+ header.className = 'calendar-navigation-header';
192
+ const leftGroup = document.createElement('div');
193
+ leftGroup.className = 'nav-group nav-group-left';
194
+ leftGroup.appendChild(this.createButton('nav-btn nav-year-prev', 'Previous year', CHEVRONS_LEFT_SVG, () => this.navigateBy(-12), this.isNavDisabled(-12)));
195
+ leftGroup.appendChild(this.createButton('nav-btn nav-month-prev', 'Previous month', CHEVRON_LEFT_SVG, () => this.navigateBy(-1), this.isNavDisabled(-1)));
196
+ const centerGroup = document.createElement('div');
197
+ centerGroup.className = 'nav-group nav-group-center';
198
+ const monthYearDisplay = document.createElement('div');
199
+ monthYearDisplay.className = 'month-year-display';
200
+ monthYearDisplay.textContent = `${monthName} ${this._state.displayYear}`;
201
+ centerGroup.appendChild(monthYearDisplay);
202
+ const rightGroup = document.createElement('div');
203
+ rightGroup.className = 'nav-group nav-group-right';
204
+ rightGroup.appendChild(this.createButton('nav-btn nav-month-next', 'Next month', CHEVRON_RIGHT_SVG, () => this.navigateBy(1), this.isNavDisabled(1)));
205
+ rightGroup.appendChild(this.createButton('nav-btn nav-year-next', 'Next year', CHEVRONS_RIGHT_SVG, () => this.navigateBy(12), this.isNavDisabled(12)));
206
+ header.appendChild(leftGroup);
207
+ header.appendChild(centerGroup);
208
+ header.appendChild(rightGroup);
209
+ root.appendChild(header);
210
+ }
211
+ }
327
212
  TyCalendarNavigation.properties = {
328
- // Display properties
329
- 'display-month': {
330
- type: 'number',
331
- visual: true,
332
- default: () => new Date().getMonth() + 1, // 1-based
333
- validate: (v) => {
334
- const num = Number(v);
335
- return Number.isInteger(num) && num >= 1 && num <= 12;
336
- },
337
- coerce: (v) => {
338
- const num = Number(v);
339
- if (isNaN(num) || num < 1 || num > 12) {
340
- console.warn(`[ty-calendar-navigation] Invalid month '${v}'. Using current month.`);
341
- return new Date().getMonth() + 1;
342
- }
343
- return num;
344
- }
345
- },
346
- 'display-year': {
347
- type: 'number',
348
- visual: true,
349
- default: () => new Date().getFullYear(),
350
- validate: (v) => {
351
- const num = Number(v);
352
- return Number.isInteger(num) && num >= 1 && num <= 9999;
353
- },
354
- coerce: (v) => {
355
- const num = Number(v);
356
- if (isNaN(num) || num < 1 || num > 9999) {
357
- console.warn(`[ty-calendar-navigation] Invalid year '${v}'. Using current year.`);
358
- return new Date().getFullYear();
359
- }
360
- return num;
361
- }
362
- },
363
- // Locale property
364
- locale: {
365
- type: 'string',
366
- visual: true,
367
- default: 'en-US'
368
- },
369
- // Size property
370
- size: {
371
- type: 'string',
372
- visual: true,
373
- default: 'md',
374
- validate: (v) => ['sm', 'md', 'lg'].includes(v),
375
- coerce: (v) => {
376
- if (!['sm', 'md', 'lg'].includes(v)) {
377
- console.warn(`[ty-calendar-navigation] Invalid size '${v}'. Using 'md'.`);
378
- return 'md';
379
- }
380
- return v;
381
- }
382
- },
383
- // Width property
384
- width: {
385
- type: 'string',
386
- visual: true,
387
- default: ''
388
- },
389
- // Navigation bounds — ISO dates. Buttons that would move the display
390
- // entirely outside [min, max] months are disabled; year jumps clamp.
391
- min: {
392
- type: 'string',
393
- visual: true,
394
- default: ''
395
- },
396
- max: {
397
- type: 'string',
398
- visual: true,
399
- default: ''
400
- }
213
+ 'display-month': {
214
+ type: 'number',
215
+ visual: true,
216
+ default: () => new Date().getMonth() + 1,
217
+ validate: (v) => {
218
+ const num = Number(v);
219
+ return Number.isInteger(num) && num >= 1 && num <= 12;
220
+ },
221
+ coerce: (v) => {
222
+ const num = Number(v);
223
+ if (isNaN(num) || num < 1 || num > 12) {
224
+ console.warn(`[ty-calendar-navigation] Invalid month '${v}'. Using current month.`);
225
+ return new Date().getMonth() + 1;
226
+ }
227
+ return num;
228
+ }
229
+ },
230
+ 'display-year': {
231
+ type: 'number',
232
+ visual: true,
233
+ default: () => new Date().getFullYear(),
234
+ validate: (v) => {
235
+ const num = Number(v);
236
+ return Number.isInteger(num) && num >= 1 && num <= 9999;
237
+ },
238
+ coerce: (v) => {
239
+ const num = Number(v);
240
+ if (isNaN(num) || num < 1 || num > 9999) {
241
+ console.warn(`[ty-calendar-navigation] Invalid year '${v}'. Using current year.`);
242
+ return new Date().getFullYear();
243
+ }
244
+ return num;
245
+ }
246
+ },
247
+ locale: {
248
+ type: 'string',
249
+ visual: true,
250
+ default: 'en-US'
251
+ },
252
+ size: {
253
+ type: 'string',
254
+ visual: true,
255
+ default: 'md',
256
+ validate: (v) => ['sm', 'md', 'lg'].includes(v),
257
+ coerce: (v) => {
258
+ if (!['sm', 'md', 'lg'].includes(v)) {
259
+ console.warn(`[ty-calendar-navigation] Invalid size '${v}'. Using 'md'.`);
260
+ return 'md';
261
+ }
262
+ return v;
263
+ }
264
+ },
265
+ width: {
266
+ type: 'string',
267
+ visual: true,
268
+ default: ''
269
+ },
270
+ min: {
271
+ type: 'string',
272
+ visual: true,
273
+ default: ''
274
+ },
275
+ max: {
276
+ type: 'string',
277
+ visual: true,
278
+ default: ''
279
+ }
401
280
  };
402
- // Register the custom element
403
281
  if (!customElements.get('ty-calendar-navigation')) {
404
- customElements.define('ty-calendar-navigation', TyCalendarNavigation);
282
+ customElements.define('ty-calendar-navigation', TyCalendarNavigation);
405
283
  }
406
- //# sourceMappingURL=calendar-navigation.js.map