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,106 +1,23 @@
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
2
  if (explicitLocale) {
55
3
  return explicitLocale;
56
4
  }
57
- // 2. Check closest ancestor with lang attribute
58
- // This allows per-section locale overrides
59
5
  const langElement = element.closest('[lang]');
60
6
  if (langElement) {
61
7
  const lang = langElement.getAttribute('lang');
62
8
  if (lang)
63
9
  return lang;
64
10
  }
65
- // 3. Check document root (html element)
66
11
  if (document.documentElement.lang) {
67
12
  return document.documentElement.lang;
68
13
  }
69
- // 4. Use browser's language preference
70
14
  if (navigator.language) {
71
15
  return navigator.language;
72
16
  }
73
- // 5. Ultimate fallback
74
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
20
  let currentLocale = getEffectiveLocale(element);
103
- // Create observer for lang attribute changes on ancestors
104
21
  const observer = new MutationObserver((mutations) => {
105
22
  for (const mutation of mutations) {
106
23
  if (mutation.type === 'attributes' && mutation.attributeName === 'lang') {
@@ -112,13 +29,10 @@ export function observeLocaleChanges(element, callback) {
112
29
  }
113
30
  }
114
31
  });
115
- // Observe document and all ancestors
116
32
  observer.observe(document.documentElement, {
117
33
  attributes: true,
118
34
  attributeFilter: ['lang'],
119
35
  subtree: true
120
36
  });
121
- // Return cleanup function
122
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
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,34 +1,10 @@
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
2
  const { type, locale = 'en-US', currency = 'USD', precision } = config;
25
3
  const options = {};
26
- // Add precision if specified
27
4
  if (precision !== undefined) {
28
5
  options.minimumFractionDigits = precision;
29
6
  options.maximumFractionDigits = precision;
30
7
  }
31
- // Configure based on type
32
8
  switch (type) {
33
9
  case 'currency':
34
10
  options.style = 'currency';
@@ -36,8 +12,6 @@ export function formatNumber(value, config) {
36
12
  break;
37
13
  case 'percent':
38
14
  options.style = 'percent';
39
- // Note: Intl.NumberFormat expects decimal (0.15 for 15%)
40
- // We'll handle the division in the input component
41
15
  break;
42
16
  case 'compact':
43
17
  options.notation = 'compact';
@@ -50,67 +24,37 @@ export function formatNumber(value, config) {
50
24
  }
51
25
  const formatter = new Intl.NumberFormat(locale, options);
52
26
  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
27
  return formatted
57
- .replace(/\u202F/g, '\u00A0') // Narrow no-break space → non-breaking space
58
- .replace(/\u2009/g, '\u00A0'); // Thin space → non-breaking space
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
32
  if (!value || value.trim() === '')
81
33
  return null;
82
- // Strip everything except digits, dots, commas, and minus
83
34
  let stripped = value
84
35
  .replace(/[^\d.,-]/g, '')
85
36
  .trim();
86
37
  if (stripped === '' || stripped === '-')
87
38
  return null;
88
- // Find the last occurring . or , — that's the decimal separator
89
39
  const lastComma = stripped.lastIndexOf(',');
90
40
  const lastDot = stripped.lastIndexOf('.');
91
41
  const lastSep = Math.max(lastComma, lastDot);
92
42
  if (lastSep === -1) {
93
- // No separators — pure integer
94
43
  const parsed = parseFloat(stripped);
95
44
  return isNaN(parsed) ? null : parsed;
96
45
  }
97
- // Split at the last separator
98
- const intPart = stripped.slice(0, lastSep).replace(/[.,]/g, '');
99
- const decPart = stripped.slice(lastSep + 1);
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;
100
55
  const parsed = parseFloat(intPart + '.' + decPart);
101
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
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
@@ -1,17 +1,3 @@
1
- /**
2
- * Core positioning engine for floating elements
3
- * Adapted from ty.positioning ClojureScript implementation
4
- *
5
- * Handles smart positioning of tooltips, dropdowns, popups, and other
6
- * floating elements relative to anchor elements with automatic overflow
7
- * detection and placement fallback.
8
- */
9
- // ============================================================================
10
- // Placement Definitions
11
- // ============================================================================
12
- /**
13
- * Map of all placement configurations
14
- */
15
1
  export const placements = {
16
2
  'top-start': {
17
3
  vertical: 'top',
@@ -26,7 +12,7 @@ export const placements = {
26
12
  horizontal: 'end',
27
13
  },
28
14
  'right-start': {
29
- vertical: 'center',
15
+ vertical: 'start',
30
16
  horizontal: 'end',
31
17
  orientation: 'vertical',
32
18
  },
@@ -53,7 +39,7 @@ export const placements = {
53
39
  horizontal: 'end',
54
40
  },
55
41
  'left-start': {
56
- vertical: 'center',
42
+ vertical: 'start',
57
43
  horizontal: 'start',
58
44
  orientation: 'vertical',
59
45
  },
@@ -68,9 +54,6 @@ export const placements = {
68
54
  orientation: 'vertical',
69
55
  },
70
56
  };
71
- /**
72
- * Default placement preference lists for different use cases
73
- */
74
57
  export const placementPreferences = {
75
58
  default: [
76
59
  'bottom-start', 'bottom-end', 'top-start', 'top-end',
@@ -85,12 +68,41 @@ export const placementPreferences = {
85
68
  'bottom', 'top', 'right', 'left'
86
69
  ],
87
70
  };
88
- // ============================================================================
89
- // DOM Measurement Helpers
90
- // ============================================================================
91
- /**
92
- * Get element dimensions relative to viewport with calculated center points
93
- */
71
+ const OPPOSITE_SIDE = {
72
+ top: 'bottom',
73
+ bottom: 'top',
74
+ left: 'right',
75
+ right: 'left',
76
+ };
77
+ export function parsePlacement(placement) {
78
+ const [side, align] = placement.split('-');
79
+ return { side, align };
80
+ }
81
+ export function preferenceChain(placement) {
82
+ const { side, align } = parsePlacement(placement);
83
+ const opposite = OPPOSITE_SIDE[side];
84
+ const perpendicular = side === 'top' || side === 'bottom' ? ['right', 'left'] : ['bottom', 'top'];
85
+ const exact = (s) => (align ? `${s}-${align}` : s);
86
+ const rest = (s) => (align
87
+ ? [s, `${s}-${align === 'start' ? 'end' : 'start'}`]
88
+ : [`${s}-start`, `${s}-end`]);
89
+ return [
90
+ exact(side),
91
+ exact(opposite),
92
+ ...rest(side),
93
+ ...rest(opposite),
94
+ ...perpendicular.flatMap((s) => [exact(s), ...rest(s)]),
95
+ ];
96
+ }
97
+ export function placementToAnchored(placement) {
98
+ if (!placement)
99
+ return { side: 'auto', align: 'start' };
100
+ const { side, align } = parsePlacement(placement);
101
+ return {
102
+ side: side === 'top' || side === 'bottom' ? side : 'auto',
103
+ align: align ?? 'start',
104
+ };
105
+ }
94
106
  function getElementRect(el) {
95
107
  const rect = el.getBoundingClientRect();
96
108
  return {
@@ -104,9 +116,6 @@ function getElementRect(el) {
104
116
  centerY: rect.top + rect.height / 2,
105
117
  };
106
118
  }
107
- /**
108
- * Get viewport dimensions and scroll position
109
- */
110
119
  function getViewportRect() {
111
120
  return {
112
121
  width: window.innerWidth,
@@ -115,22 +124,13 @@ function getViewportRect() {
115
124
  scrollY: window.scrollY,
116
125
  };
117
126
  }
118
- // ============================================================================
119
- // Position Calculation
120
- // ============================================================================
121
- /**
122
- * Calculate position for a specific placement
123
- * Returns x, y coordinates and overflow information
124
- */
125
127
  function calculatePlacement(options) {
126
128
  const { targetRect, floatingRect, placement, offset, padding, scrollbarWidth, containerPadding, } = options;
127
129
  const config = placements[placement];
128
130
  const { vertical, horizontal, orientation } = config;
129
131
  const viewport = getViewportRect();
130
- // Calculate X position
131
132
  let x;
132
133
  if (orientation === 'vertical') {
133
- // Left/right placements
134
134
  if (horizontal === 'start') {
135
135
  x = targetRect.left - floatingRect.width - offset + containerPadding;
136
136
  }
@@ -139,33 +139,29 @@ function calculatePlacement(options) {
139
139
  }
140
140
  }
141
141
  else {
142
- // Top/bottom placements
143
142
  if (horizontal === 'start') {
144
- x = targetRect.left;
143
+ x = targetRect.left - containerPadding;
145
144
  }
146
145
  else if (horizontal === 'center') {
147
146
  x = targetRect.centerX - floatingRect.width / 2;
148
147
  }
149
148
  else {
150
- x = targetRect.right - floatingRect.width;
149
+ x = targetRect.right - floatingRect.width + containerPadding;
151
150
  }
152
151
  }
153
- // Calculate Y position
154
152
  let y;
155
153
  if (orientation === 'vertical') {
156
- // Left/right placements
157
154
  if (vertical === 'center') {
158
155
  y = targetRect.centerY - floatingRect.height / 2;
159
156
  }
160
157
  else if (vertical === 'end') {
161
- y = targetRect.bottom - floatingRect.height - containerPadding;
158
+ y = targetRect.bottom - floatingRect.height + containerPadding;
162
159
  }
163
160
  else {
164
- y = targetRect.top;
161
+ y = targetRect.top - containerPadding;
165
162
  }
166
163
  }
167
164
  else {
168
- // Top/bottom placements
169
165
  if (vertical === 'top') {
170
166
  y = targetRect.top - floatingRect.height - offset + containerPadding;
171
167
  }
@@ -173,14 +169,12 @@ function calculatePlacement(options) {
173
169
  y = targetRect.bottom + offset - containerPadding;
174
170
  }
175
171
  }
176
- // Calculate overflow for each edge
177
172
  const overflow = {
178
173
  top: Math.min(0, y - padding),
179
174
  left: Math.min(0, x - padding),
180
175
  bottom: Math.min(0, viewport.height - (y + floatingRect.height + padding)),
181
176
  right: Math.min(0, viewport.width - (x + floatingRect.width + padding + scrollbarWidth)),
182
177
  };
183
- // Sum of absolute overflow values
184
178
  const overflowAmount = Object.values(overflow).reduce((sum, val) => sum + Math.abs(val), 0);
185
179
  return {
186
180
  x: Math.round(x),
@@ -191,16 +185,11 @@ function calculatePlacement(options) {
191
185
  fits: overflowAmount === 0,
192
186
  };
193
187
  }
194
- /**
195
- * Find the best position for the floating element
196
- * Tries all preference placements and returns the one that fits best
197
- */
198
188
  export function findBestPosition(options) {
199
189
  const { targetEl, floatingEl, preferences = placementPreferences.default, offset = 8, padding = 8, containerPadding = 0, } = options;
200
190
  const targetRect = getElementRect(targetEl);
201
191
  const floatingRect = getElementRect(floatingEl);
202
192
  const scrollbarWidth = 15;
203
- // Calculate all candidate positions
204
193
  const candidates = preferences.map(placement => calculatePlacement({
205
194
  targetRect,
206
195
  floatingRect,
@@ -210,10 +199,8 @@ export function findBestPosition(options) {
210
199
  containerPadding,
211
200
  scrollbarWidth,
212
201
  }));
213
- // Find first that fits, or one with least overflow
214
202
  const bestPosition = candidates.find(c => c.fits) ||
215
203
  candidates.reduce((best, current) => current.overflowAmount < best.overflowAmount ? current : best);
216
- // Adjust for scrollbar if needed
217
204
  if (bestPosition.overflow.right < 0) {
218
205
  bestPosition.x += bestPosition.overflow.right;
219
206
  }
@@ -226,13 +213,17 @@ export function computeAnchoredPosition(o) {
226
213
  const vh = window.innerHeight;
227
214
  const spaceBelow = vh - o.anchorRect.bottom;
228
215
  const spaceAbove = o.anchorRect.top;
229
- // Below when it fits — and when neither side fits, the side with MORE room
230
- // instead of blindly flipping up (a trigger near the viewport top used to
231
- // clip the popup off-screen).
232
- const below = spaceBelow >= o.popupHeight + gap + padding || spaceBelow >= spaceAbove;
233
- // Anchor to the trigger's left edge ("start") or right edge ("end"),
234
- // clamped into the viewport either way.
235
- const rawX = o.align === "end" ? o.anchorRect.right - o.popupWidth : o.anchorRect.left;
216
+ const needed = o.popupHeight + gap + padding;
217
+ const fitsBelow = spaceBelow >= needed;
218
+ const fitsAbove = spaceAbove >= needed;
219
+ const side = o.side ?? "auto";
220
+ const below = side === "bottom" ? (fitsBelow || !fitsAbove ? true : false)
221
+ : side === "top" ? (fitsAbove || !fitsBelow ? false : true)
222
+ : fitsBelow || spaceBelow >= spaceAbove;
223
+ const rawX = o.align === "end" ? o.anchorRect.right - o.popupWidth
224
+ : o.align === "center"
225
+ ? o.anchorRect.left + (o.anchorRect.width - o.popupWidth) / 2
226
+ : o.anchorRect.left;
236
227
  const x = Math.max(padding, Math.min(rawX, vw - o.popupWidth - padding));
237
228
  return {
238
229
  x,
@@ -241,4 +232,3 @@ export function computeAnchoredPosition(o) {
241
232
  below,
242
233
  };
243
234
  }
244
- //# sourceMappingURL=positioning.js.map
@@ -1,32 +1,11 @@
1
1
  /**
2
2
  * Property Capture Utility
3
3
  *
4
- * Solves the problem of frameworks (React, Reagent, etc.) setting properties
5
- * on custom elements BEFORE connectedCallback runs.
6
- *
7
- * PROBLEM:
8
- * 1. Framework creates element: document.createElement('ty-dropdown')
9
- * 2. Framework sets properties: element.value = "foo"
10
- * 3. Constructor runs and defines getters/setters
11
- * 4. BUT properties were already set, creating instance properties
12
- * 5. Instance properties shadow the class getters/setters
13
- * 6. connectedCallback runs - too late!
14
- *
15
- * SOLUTION:
16
- * In connectedCallback, capture any pre-set properties and apply them properly.
17
- *
18
- * @example
19
- * ```typescript
20
- * connectedCallback(): void {
21
- * const preSetProps = capturePreSetProperties(this, [
22
- * 'value', 'clearable', 'disabled'
23
- * ])
24
- *
25
- * if (preSetProps.value !== undefined) {
26
- * this._value = preSetProps.value
27
- * }
28
- * }
29
- * ```
4
+ * Frameworks (React, Reagent, ...) set properties on a custom element before
5
+ * the constructor defines its getters/setters, so those assignments become
6
+ * *instance* properties that permanently shadow the class accessors — by the
7
+ * time connectedCallback runs, the setters have never been called.
8
+ * Fix: in connectedCallback, capture the pre-set values and re-apply them.
30
9
  */
31
10
  /**
32
11
  * Captured property data
@@ -129,4 +108,3 @@ export declare function applyPreSetProperties(element: any, propertyNames: strin
129
108
  * ```
130
109
  */
131
110
  export declare function captureAndApplyProperties(element: any, propertyNames: string[], transformer?: (name: string, value: any) => any, options?: PropertyCaptureOptions): void;
132
- //# sourceMappingURL=property-capture.d.ts.map