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,124 +1,38 @@
1
- /**
2
- * Locale Resolution Utilities
3
- *
4
- * Provides a cascade system for resolving locale/language preferences:
5
- * 1. Component's explicit `locale` attribute (highest priority)
6
- * 2. Closest ancestor's `lang` attribute
7
- * 3. Document root's `lang` attribute
8
- * 4. Browser's language preference
9
- * 5. 'en-US' fallback (lowest priority)
10
- *
11
- * This allows developers to set locale at any level:
12
- * - Per-component: <ty-input locale="fr-FR">
13
- * - Per-section: <div lang="de-DE"><ty-input></ty-input></div>
14
- * - Per-page: <html lang="es-ES">
15
- * - Browser default: Uses navigator.language
16
- *
17
- * @example
18
- * ```typescript
19
- * // In a component
20
- * class TyInput extends HTMLElement {
21
- * get locale(): string {
22
- * return getEffectiveLocale(this, this.getAttribute('locale'));
23
- * }
24
- * }
25
- * ```
26
- */
27
- /**
28
- * Get the effective locale for an element using the resolution cascade.
29
- *
30
- * Resolution order:
31
- * 1. Explicit locale attribute on the element
32
- * 2. Closest ancestor element with a `lang` attribute
33
- * 3. Document root element's `lang` attribute
34
- * 4. Browser's navigator.language
35
- * 5. Fallback to 'en-US'
36
- *
37
- * @param element - The element to get locale for
38
- * @param explicitLocale - Optional explicit locale value (from component's locale attribute)
39
- * @returns The resolved locale string (e.g., 'en-US', 'fr-FR')
40
- *
41
- * @example
42
- * ```html
43
- * <html lang="en-US">
44
- * <div lang="fr-FR">
45
- * <ty-input></ty-input> <!-- Uses 'fr-FR' -->
46
- * <ty-input locale="de-DE"></ty-input> <!-- Uses 'de-DE' -->
47
- * </div>
48
- * <ty-input></ty-input> <!-- Uses 'en-US' -->
49
- * </html>
50
- * ```
51
- */
52
1
  export function getEffectiveLocale(element, explicitLocale) {
53
- // 1. Explicit locale attribute takes highest priority
54
- if (explicitLocale) {
55
- return explicitLocale;
56
- }
57
- // 2. Check closest ancestor with lang attribute
58
- // This allows per-section locale overrides
59
- const langElement = element.closest('[lang]');
60
- if (langElement) {
61
- const lang = langElement.getAttribute('lang');
62
- if (lang)
63
- return lang;
64
- }
65
- // 3. Check document root (html element)
66
- if (document.documentElement.lang) {
67
- return document.documentElement.lang;
68
- }
69
- // 4. Use browser's language preference
70
- if (navigator.language) {
71
- return navigator.language;
72
- }
73
- // 5. Ultimate fallback
74
- return 'en-US';
2
+ if (explicitLocale) {
3
+ return explicitLocale;
4
+ }
5
+ const langElement = element.closest('[lang]');
6
+ if (langElement) {
7
+ const lang = langElement.getAttribute('lang');
8
+ if (lang)
9
+ return lang;
10
+ }
11
+ if (document.documentElement.lang) {
12
+ return document.documentElement.lang;
13
+ }
14
+ if (navigator.language) {
15
+ return navigator.language;
16
+ }
17
+ return 'en-US';
75
18
  }
76
- /**
77
- * Create a MutationObserver to watch for lang attribute changes.
78
- * Useful for components that need to react to dynamic locale changes.
79
- *
80
- * @param element - The element to observe
81
- * @param callback - Function to call when lang changes
82
- * @returns Cleanup function to disconnect the observer
83
- *
84
- * @example
85
- * ```typescript
86
- * class TyInput extends HTMLElement {
87
- * private _localeObserver?: () => void;
88
- *
89
- * connectedCallback() {
90
- * this._localeObserver = observeLocaleChanges(this, () => {
91
- * this.render(); // Re-render when locale changes
92
- * });
93
- * }
94
- *
95
- * disconnectedCallback() {
96
- * this._localeObserver?.();
97
- * }
98
- * }
99
- * ```
100
- */
101
19
  export function observeLocaleChanges(element, callback) {
102
- let currentLocale = getEffectiveLocale(element);
103
- // Create observer for lang attribute changes on ancestors
104
- const observer = new MutationObserver((mutations) => {
105
- for (const mutation of mutations) {
106
- if (mutation.type === 'attributes' && mutation.attributeName === 'lang') {
107
- const newLocale = getEffectiveLocale(element);
108
- if (newLocale !== currentLocale) {
109
- currentLocale = newLocale;
110
- callback(newLocale);
111
- }
112
- }
113
- }
114
- });
115
- // Observe document and all ancestors
116
- observer.observe(document.documentElement, {
117
- attributes: true,
118
- attributeFilter: ['lang'],
119
- subtree: true
120
- });
121
- // Return cleanup function
122
- return () => observer.disconnect();
20
+ let currentLocale = getEffectiveLocale(element);
21
+ const observer = new MutationObserver((mutations) => {
22
+ for (const mutation of mutations) {
23
+ if (mutation.type === 'attributes' && mutation.attributeName === 'lang') {
24
+ const newLocale = getEffectiveLocale(element);
25
+ if (newLocale !== currentLocale) {
26
+ currentLocale = newLocale;
27
+ callback(newLocale);
28
+ }
29
+ }
30
+ }
31
+ });
32
+ observer.observe(document.documentElement, {
33
+ attributes: true,
34
+ attributeFilter: ['lang'],
35
+ subtree: true
36
+ });
37
+ return () => observer.disconnect();
123
38
  }
124
- //# sourceMappingURL=locale.js.map
@@ -11,4 +11,3 @@
11
11
  * Returns true when the primary pointer is coarse (touch) AND viewport is narrow.
12
12
  */
13
13
  export declare function isMobileTouch(breakpoint?: number): boolean;
14
- //# sourceMappingURL=mobile.d.ts.map
@@ -1,21 +1,4 @@
1
- /**
2
- * Mobile detection utility
3
- *
4
- * Uses CSS media query via matchMedia for reliable detection:
5
- * - `pointer: coarse` identifies touch-primary devices (not laptops with touchscreens)
6
- * - Breakpoint is evaluated by the browser, always in sync with CSS
7
- * - Called on each use (not cached), so it responds to viewport changes and rotation
8
- */
9
- /**
10
- * Default mobile breakpoint (px).
11
- * Matches phones in portrait and most phones in landscape.
12
- */
13
1
  const MOBILE_BREAKPOINT = 768;
14
- /**
15
- * Detect mobile touch devices.
16
- * Returns true when the primary pointer is coarse (touch) AND viewport is narrow.
17
- */
18
2
  export function isMobileTouch(breakpoint = MOBILE_BREAKPOINT) {
19
- return window.matchMedia(`(pointer: coarse) and (max-width: ${breakpoint}px)`).matches;
3
+ return window.matchMedia(`(pointer: coarse) and (max-width: ${breakpoint}px)`).matches;
20
4
  }
21
- //# sourceMappingURL=mobile.js.map
@@ -1,6 +1,5 @@
1
1
  /**
2
2
  * Number Formatting Utilities
3
- * PORTED FROM: clj/ty/i18n/number.cljs
4
3
  *
5
4
  * Uses native Intl.NumberFormat for locale-aware number formatting
6
5
  * Supports currency, percent, compact notation, and custom precision
@@ -34,6 +33,10 @@ export declare function formatNumber(value: number, config: FormatConfig): strin
34
33
  * Simple rule: the last occurring . or , is the decimal separator.
35
34
  * Everything else is stripped. This works for both US (1,234.56) and
36
35
  * European (1.234,56) input, and for mobile keyboards that use , as decimal.
36
+ * One grouping exception: a repeated separator ("1.234.567") can't be a
37
+ * decimal point, so it's stripped as thousands grouping. A LONE separator is
38
+ * always decimal — "$1,234" pasted from formatted text parses as 1.234; this
39
+ * known ambiguity is resolved in favor of typed input ("12,50" → 12.5).
37
40
  *
38
41
  * @example
39
42
  * ```typescript
@@ -42,7 +45,8 @@ export declare function formatNumber(value: number, config: FormatConfig): strin
42
45
  * parseNumericValue("12,50") // 12.5 (last separator is ,)
43
46
  * parseNumericValue("12.50") // 12.5 (last separator is .)
44
47
  * parseNumericValue("1234") // 1234
45
- * parseNumericValue("$1,234") // 1234
48
+ * parseNumericValue("1.234.567") // 1234567 (repeated separator = grouping)
49
+ * parseNumericValue("$1,234") // 1.234 (lone separator = decimal; known paste ambiguity)
46
50
  * parseNumericValue("15%") // 15
47
51
  * parseNumericValue("") // null
48
52
  * ```
@@ -59,4 +63,3 @@ export declare function parseNumericValue(value: string): number | null;
59
63
  * ```
60
64
  */
61
65
  export declare function shouldFormat(type: string): boolean;
62
- //# sourceMappingURL=number-format.d.ts.map
@@ -1,116 +1,60 @@
1
- /**
2
- * Number Formatting Utilities
3
- * PORTED FROM: clj/ty/i18n/number.cljs
4
- *
5
- * Uses native Intl.NumberFormat for locale-aware number formatting
6
- * Supports currency, percent, compact notation, and custom precision
7
- */
8
- /**
9
- * Format a number based on configuration
10
- *
11
- * @example
12
- * ```typescript
13
- * formatNumber(1234.56, { type: 'currency', currency: 'USD', locale: 'en-US' })
14
- * // Returns: "$1,234.56"
15
- *
16
- * formatNumber(0.15, { type: 'percent', precision: 2 })
17
- * // Returns: "15.00%"
18
- *
19
- * formatNumber(1234567, { type: 'compact' })
20
- * // Returns: "1.2M"
21
- * ```
22
- */
23
1
  export function formatNumber(value, config) {
24
- const { type, locale = 'en-US', currency = 'USD', precision } = config;
25
- const options = {};
26
- // Add precision if specified
27
- if (precision !== undefined) {
28
- options.minimumFractionDigits = precision;
29
- options.maximumFractionDigits = precision;
30
- }
31
- // Configure based on type
32
- switch (type) {
33
- case 'currency':
34
- options.style = 'currency';
35
- options.currency = currency;
36
- break;
37
- case 'percent':
38
- options.style = 'percent';
39
- // Note: Intl.NumberFormat expects decimal (0.15 for 15%)
40
- // We'll handle the division in the input component
41
- break;
42
- case 'compact':
43
- options.notation = 'compact';
44
- options.compactDisplay = 'short';
45
- break;
46
- case 'number':
47
- default:
48
- options.style = 'decimal';
49
- break;
50
- }
51
- const formatter = new Intl.NumberFormat(locale, options);
52
- const formatted = formatter.format(value);
53
- // Normalize Unicode spaces for better HTML input compatibility
54
- // Replace narrow no-break space (U+202F) and thin space (U+2009) with regular non-breaking space (U+00A0)
55
- // This ensures proper rendering in HTML input elements
56
- return formatted
57
- .replace(/\u202F/g, '\u00A0') // Narrow no-break space → non-breaking space
58
- .replace(/\u2009/g, '\u00A0'); // Thin space → non-breaking space
2
+ const { type, locale = 'en-US', currency = 'USD', precision } = config;
3
+ const options = {};
4
+ if (precision !== undefined) {
5
+ options.minimumFractionDigits = precision;
6
+ options.maximumFractionDigits = precision;
7
+ }
8
+ switch (type) {
9
+ case 'currency':
10
+ options.style = 'currency';
11
+ options.currency = currency;
12
+ break;
13
+ case 'percent':
14
+ options.style = 'percent';
15
+ break;
16
+ case 'compact':
17
+ options.notation = 'compact';
18
+ options.compactDisplay = 'short';
19
+ break;
20
+ case 'number':
21
+ default:
22
+ options.style = 'decimal';
23
+ break;
24
+ }
25
+ const formatter = new Intl.NumberFormat(locale, options);
26
+ const formatted = formatter.format(value);
27
+ return formatted
28
+ .replace(/\u202F/g, '\u00A0')
29
+ .replace(/\u2009/g, '\u00A0');
59
30
  }
60
- /**
61
- * Parse a numeric string to a number
62
- *
63
- * Simple rule: the last occurring . or , is the decimal separator.
64
- * Everything else is stripped. This works for both US (1,234.56) and
65
- * European (1.234,56) input, and for mobile keyboards that use , as decimal.
66
- *
67
- * @example
68
- * ```typescript
69
- * parseNumericValue("1,234.56") // 1234.56 (last separator is .)
70
- * parseNumericValue("1.234,56") // 1234.56 (last separator is ,)
71
- * parseNumericValue("12,50") // 12.5 (last separator is ,)
72
- * parseNumericValue("12.50") // 12.5 (last separator is .)
73
- * parseNumericValue("1234") // 1234
74
- * parseNumericValue("$1,234") // 1234
75
- * parseNumericValue("15%") // 15
76
- * parseNumericValue("") // null
77
- * ```
78
- */
79
31
  export function parseNumericValue(value) {
80
- if (!value || value.trim() === '')
81
- return null;
82
- // Strip everything except digits, dots, commas, and minus
83
- let stripped = value
84
- .replace(/[^\d.,-]/g, '')
85
- .trim();
86
- if (stripped === '' || stripped === '-')
87
- return null;
88
- // Find the last occurring . or , — that's the decimal separator
89
- const lastComma = stripped.lastIndexOf(',');
90
- const lastDot = stripped.lastIndexOf('.');
91
- const lastSep = Math.max(lastComma, lastDot);
92
- if (lastSep === -1) {
93
- // No separators — pure integer
94
- const parsed = parseFloat(stripped);
95
- return isNaN(parsed) ? null : parsed;
96
- }
97
- // Split at the last separator
98
- const intPart = stripped.slice(0, lastSep).replace(/[.,]/g, '');
99
- const decPart = stripped.slice(lastSep + 1);
100
- const parsed = parseFloat(intPart + '.' + decPart);
101
- return isNaN(parsed) ? null : parsed;
32
+ if (!value || value.trim() === '')
33
+ return null;
34
+ let stripped = value
35
+ .replace(/[^\d.,-]/g, '')
36
+ .trim();
37
+ if (stripped === '' || stripped === '-')
38
+ return null;
39
+ const lastComma = stripped.lastIndexOf(',');
40
+ const lastDot = stripped.lastIndexOf('.');
41
+ const lastSep = Math.max(lastComma, lastDot);
42
+ if (lastSep === -1) {
43
+ const parsed = parseFloat(stripped);
44
+ return isNaN(parsed) ? null : parsed;
45
+ }
46
+ const sepChar = stripped[lastSep];
47
+ const before = stripped.slice(0, lastSep);
48
+ const after = stripped.slice(lastSep + 1);
49
+ if (before.includes(sepChar)) {
50
+ const parsed = parseFloat(stripped.replace(/[.,]/g, ''));
51
+ return isNaN(parsed) ? null : parsed;
52
+ }
53
+ const intPart = before.replace(/[.,]/g, '');
54
+ const decPart = after;
55
+ const parsed = parseFloat(intPart + '.' + decPart);
56
+ return isNaN(parsed) ? null : parsed;
102
57
  }
103
- /**
104
- * Check if input type requires numeric formatting
105
- *
106
- * @example
107
- * ```typescript
108
- * shouldFormat('currency') // true
109
- * shouldFormat('percent') // true
110
- * shouldFormat('text') // false
111
- * ```
112
- */
113
58
  export function shouldFormat(type) {
114
- return ['number', 'currency', 'percent', 'compact'].includes(type);
59
+ return ['number', 'currency', 'percent', 'compact'].includes(type);
115
60
  }
116
- //# sourceMappingURL=number-format.js.map
@@ -1,6 +1,5 @@
1
1
  /**
2
2
  * Core positioning engine for floating elements
3
- * Adapted from ty.positioning ClojureScript implementation
4
3
  *
5
4
  * Handles smart positioning of tooltips, dropdowns, popups, and other
6
5
  * floating elements relative to anchor elements with automatic overflow
@@ -13,7 +12,7 @@ export type PlacementOrientation = 'horizontal' | 'vertical';
13
12
  /**
14
13
  * Vertical alignment options
15
14
  */
16
- export type VerticalAlign = 'top' | 'center' | 'bottom' | 'end';
15
+ export type VerticalAlign = 'top' | 'start' | 'center' | 'bottom' | 'end';
17
16
  /**
18
17
  * Horizontal alignment options
19
18
  */
@@ -111,6 +110,47 @@ export declare const placementPreferences: {
111
110
  tooltip: Placement[];
112
111
  dropdown: Placement[];
113
112
  };
113
+ /** The four sides a floating element can sit on. */
114
+ export type PlacementSide = 'top' | 'right' | 'bottom' | 'left';
115
+ /** Cross-axis alignment against the anchor. Omitted means centred. */
116
+ export type PlacementAlign = 'start' | 'end';
117
+ /** Split `'left-end'` into `{ side: 'left', align: 'end' }`. */
118
+ export declare function parsePlacement(placement: Placement): {
119
+ side: PlacementSide;
120
+ align?: PlacementAlign;
121
+ };
122
+ /**
123
+ * Fallback order to try for a requested placement, best-fit first.
124
+ *
125
+ * FLIP BEFORE RE-ALIGN. When a placement overflows it is almost always the
126
+ * SIDE axis that ran out of room, and re-aligning on the same side does not
127
+ * change the fit at all: `bottom-start` and `bottom-end` need identical
128
+ * vertical space. Flipping to the opposite side is the move that actually
129
+ * helps, so the requested alignment is carried across the flip first, and only
130
+ * then do we try other alignments.
131
+ *
132
+ * This also keeps the old hand-written chains intact for the four bare sides —
133
+ * `top` still degrades to `bottom` as its very next candidate, exactly as
134
+ * before aligned placements existed.
135
+ *
136
+ * Callers previously hand-wrote a 4-entry chain per side, which silently
137
+ * dropped every aligned placement onto the default chain.
138
+ */
139
+ export declare function preferenceChain(placement: Placement): Placement[];
140
+ /**
141
+ * Map a `Placement` onto `computeAnchoredPosition`'s inputs, so dropdown-style
142
+ * components (ty-select, ty-date-picker) accept the same `placement` vocabulary
143
+ * as ty-popup / ty-tooltip.
144
+ *
145
+ * Dropdowns only ever live above or below their trigger, so a left/right
146
+ * placement degrades to "auto" side while keeping its alignment. Bare sides
147
+ * default to start-aligned, matching a native <select> and the behaviour these
148
+ * components had before `placement` existed.
149
+ */
150
+ export declare function placementToAnchored(placement?: Placement | '' | null): {
151
+ side: 'top' | 'bottom' | 'auto';
152
+ align: 'start' | 'center' | 'end';
153
+ };
114
154
  /**
115
155
  * Find the best position for the floating element
116
156
  * Tries all preference placements and returns the one that fits best
@@ -132,10 +172,14 @@ export interface AnchoredPopupOptions {
132
172
  gap?: number;
133
173
  /** Minimum distance from viewport edges (px, default 8) */
134
174
  padding?: number;
135
- /** Horizontal anchor edge: trigger's left edge ("start", default) or
136
- * right edge ("end"). Either way the result is clamped into the
137
- * viewport, same as before. */
138
- align?: "start" | "end";
175
+ /** Horizontal anchor edge: trigger's left edge ("start", default), its
176
+ * right edge ("end"), or centred on it. Either way the result is clamped
177
+ * into the viewport, same as before. */
178
+ align?: "start" | "center" | "end";
179
+ /** Preferred vertical side. "auto" (default) keeps the historic behaviour:
180
+ * below when it fits, otherwise whichever side has more room. Naming a
181
+ * side honours it when it fits and still flips rather than clipping. */
182
+ side?: "top" | "bottom" | "auto";
139
183
  }
140
184
  export interface AnchoredPopupPosition {
141
185
  /** Popup left edge, viewport coords, clamped into view */
@@ -147,4 +191,3 @@ export interface AnchoredPopupPosition {
147
191
  below: boolean;
148
192
  }
149
193
  export declare function computeAnchoredPosition(o: AnchoredPopupOptions): AnchoredPopupPosition;
150
- //# sourceMappingURL=positioning.d.ts.map