tyrell-components 1.0.0-TC45 → 1.0.0-TC47

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 (353) hide show
  1. package/README.md +1 -1
  2. package/css/tyrell-theme.css +93 -100
  3. package/dist/tyrell-theme.css +93 -100
  4. package/dist/tyrell.js +1 -1
  5. package/lib/base/ty-component.d.ts +12 -7
  6. package/lib/base/ty-component.js +8 -139
  7. package/lib/components/button.d.ts +2 -16
  8. package/lib/components/button.js +0 -36
  9. package/lib/components/calendar-month.d.ts +2 -48
  10. package/lib/components/calendar-month.js +4 -166
  11. package/lib/components/calendar-navigation.d.ts +3 -48
  12. package/lib/components/calendar-navigation.js +3 -126
  13. package/lib/components/calendar.d.ts +3 -80
  14. package/lib/components/calendar.js +8 -230
  15. package/lib/components/checkbox.d.ts +4 -71
  16. package/lib/components/checkbox.js +7 -151
  17. package/lib/components/copy.d.ts +3 -56
  18. package/lib/components/copy.js +1 -120
  19. package/lib/components/date-picker.d.ts +13 -162
  20. package/lib/components/date-picker.js +39 -584
  21. package/lib/components/file-upload.d.ts +3 -15
  22. package/lib/components/file-upload.js +0 -37
  23. package/lib/components/icon.d.ts +3 -24
  24. package/lib/components/icon.js +1 -90
  25. package/lib/components/input.d.ts +7 -107
  26. package/lib/components/input.js +4 -193
  27. package/lib/components/modal.d.ts +3 -26
  28. package/lib/components/modal.js +1 -188
  29. package/lib/components/option.d.ts +2 -9
  30. package/lib/components/option.js +0 -48
  31. package/lib/components/popup.d.ts +2 -17
  32. package/lib/components/popup.js +4 -135
  33. package/lib/components/radio.d.ts +3 -23
  34. package/lib/components/radio.js +0 -63
  35. package/lib/components/resize-observer.d.ts +2 -30
  36. package/lib/components/resize-observer.js +0 -45
  37. package/lib/components/scroll-container.d.ts +2 -12
  38. package/lib/components/scroll-container.js +3 -46
  39. package/lib/components/select.d.ts +22 -153
  40. package/lib/components/select.js +30 -585
  41. package/lib/components/selected-tags.d.ts +4 -47
  42. package/lib/components/selected-tags.js +0 -94
  43. package/lib/components/step.d.ts +1 -6
  44. package/lib/components/step.js +0 -6
  45. package/lib/components/switch.d.ts +0 -11
  46. package/lib/components/switch.js +2 -36
  47. package/lib/components/tab.d.ts +1 -6
  48. package/lib/components/tab.js +0 -7
  49. package/lib/components/tabs.d.ts +3 -63
  50. package/lib/components/tabs.js +5 -283
  51. package/lib/components/tag.d.ts +2 -36
  52. package/lib/components/tag.js +5 -105
  53. package/lib/components/textarea.d.ts +6 -86
  54. package/lib/components/textarea.js +2 -173
  55. package/lib/components/tooltip.d.ts +3 -11
  56. package/lib/components/tooltip.js +2 -160
  57. package/lib/components/wizard.d.ts +4 -54
  58. package/lib/components/wizard.js +0 -228
  59. package/lib/icons/fontawesome/brands.d.ts +0 -1
  60. package/lib/icons/fontawesome/brands.js +0 -8
  61. package/lib/icons/fontawesome/regular.d.ts +0 -1
  62. package/lib/icons/fontawesome/regular.js +0 -8
  63. package/lib/icons/fontawesome/solid.d.ts +0 -1
  64. package/lib/icons/fontawesome/solid.js +0 -8
  65. package/lib/icons/heroicons/micro.d.ts +0 -1
  66. package/lib/icons/heroicons/micro.js +0 -8
  67. package/lib/icons/heroicons/mini.d.ts +0 -1
  68. package/lib/icons/heroicons/mini.js +0 -8
  69. package/lib/icons/heroicons/outline.d.ts +0 -1
  70. package/lib/icons/heroicons/outline.js +0 -8
  71. package/lib/icons/heroicons/solid.d.ts +0 -1
  72. package/lib/icons/heroicons/solid.js +0 -8
  73. package/lib/icons/lucide.d.ts +0 -1
  74. package/lib/icons/lucide.js +0 -1872
  75. package/lib/icons/material/filled.d.ts +0 -1
  76. package/lib/icons/material/filled.js +0 -10
  77. package/lib/icons/material/outlined.d.ts +0 -1
  78. package/lib/icons/material/outlined.js +0 -10
  79. package/lib/icons/material/round.d.ts +0 -1
  80. package/lib/icons/material/round.js +0 -10
  81. package/lib/icons/material/sharp.d.ts +0 -1
  82. package/lib/icons/material/sharp.js +0 -10
  83. package/lib/icons/material/two-tone.d.ts +0 -1
  84. package/lib/icons/material/two-tone.js +0 -10
  85. package/lib/index.d.ts +0 -1
  86. package/lib/index.js +0 -20
  87. package/lib/styles/button.d.ts +2 -20
  88. package/lib/styles/button.js +18 -121
  89. package/lib/styles/calendar-month.d.ts +1 -5
  90. package/lib/styles/calendar-month.js +4 -61
  91. package/lib/styles/calendar-navigation.d.ts +2 -6
  92. package/lib/styles/calendar-navigation.js +2 -27
  93. package/lib/styles/calendar.d.ts +1 -2
  94. package/lib/styles/calendar.js +1 -14
  95. package/lib/styles/checkbox.d.ts +0 -1
  96. package/lib/styles/checkbox.js +1 -23
  97. package/lib/styles/copy.d.ts +0 -1
  98. package/lib/styles/copy.js +2 -17
  99. package/lib/styles/custom-scrollbar.d.ts +1 -2
  100. package/lib/styles/custom-scrollbar.js +3 -18
  101. package/lib/styles/date-picker.d.ts +1 -5
  102. package/lib/styles/date-picker.js +8 -38
  103. package/lib/styles/file-upload.d.ts +1 -2
  104. package/lib/styles/file-upload.js +1 -16
  105. package/lib/styles/icon.d.ts +2 -6
  106. package/lib/styles/icon.js +7 -21
  107. package/lib/styles/input.d.ts +1 -6
  108. package/lib/styles/input.js +5 -54
  109. package/lib/styles/modal.d.ts +1 -2
  110. package/lib/styles/modal.js +3 -23
  111. package/lib/styles/option.d.ts +2 -6
  112. package/lib/styles/option.js +2 -12
  113. package/lib/styles/popup.d.ts +1 -2
  114. package/lib/styles/popup.js +4 -25
  115. package/lib/styles/radio.d.ts +0 -1
  116. package/lib/styles/radio.js +2 -16
  117. package/lib/styles/resize-observer.d.ts +1 -2
  118. package/lib/styles/resize-observer.js +0 -7
  119. package/lib/styles/scroll-container.d.ts +1 -2
  120. package/lib/styles/scroll-container.js +0 -19
  121. package/lib/styles/select-base.d.ts +0 -1
  122. package/lib/styles/select-base.js +15 -74
  123. package/lib/styles/select.d.ts +1 -2
  124. package/lib/styles/select.js +2 -14
  125. package/lib/styles/step.d.ts +1 -2
  126. package/lib/styles/step.js +0 -4
  127. package/lib/styles/switch.d.ts +0 -1
  128. package/lib/styles/switch.js +2 -20
  129. package/lib/styles/tab.d.ts +1 -2
  130. package/lib/styles/tab.js +0 -5
  131. package/lib/styles/tabs.d.ts +3 -11
  132. package/lib/styles/tabs.js +10 -48
  133. package/lib/styles/tag.d.ts +1 -5
  134. package/lib/styles/tag.js +2 -31
  135. package/lib/styles/textarea.d.ts +1 -2
  136. package/lib/styles/textarea.js +2 -45
  137. package/lib/styles/tooltip.d.ts +0 -1
  138. package/lib/styles/tooltip.js +0 -10
  139. package/lib/styles/wizard.d.ts +5 -21
  140. package/lib/styles/wizard.js +8 -88
  141. package/lib/types/common.d.ts +0 -2
  142. package/lib/types/common.js +0 -12
  143. package/lib/utils/calendar-utils.d.ts +4 -21
  144. package/lib/utils/calendar-utils.js +4 -177
  145. package/lib/utils/custom-scrollbar.d.ts +6 -20
  146. package/lib/utils/custom-scrollbar.js +1 -45
  147. package/lib/utils/flavor-sheet.d.ts +0 -1
  148. package/lib/utils/flavor-sheet.js +0 -23
  149. package/lib/utils/icon-registry.d.ts +0 -2
  150. package/lib/utils/icon-registry.js +1 -107
  151. package/lib/utils/icons.d.ts +0 -1
  152. package/lib/utils/icons.js +0 -9
  153. package/lib/utils/loader-registry.d.ts +0 -1
  154. package/lib/utils/loader-registry.js +0 -32
  155. package/lib/utils/locale.d.ts +2 -23
  156. package/lib/utils/locale.js +0 -86
  157. package/lib/utils/mobile.d.ts +0 -1
  158. package/lib/utils/mobile.js +0 -17
  159. package/lib/utils/number-format.d.ts +0 -2
  160. package/lib/utils/number-format.js +2 -65
  161. package/lib/utils/positioning.d.ts +50 -7
  162. package/lib/utils/positioning.js +49 -59
  163. package/lib/utils/property-capture.d.ts +5 -27
  164. package/lib/utils/property-capture.js +0 -108
  165. package/lib/utils/property-manager.d.ts +0 -1
  166. package/lib/utils/property-manager.js +0 -70
  167. package/lib/utils/resize-observer.d.ts +0 -1
  168. package/lib/utils/resize-observer.js +0 -36
  169. package/lib/utils/scroll-lock.d.ts +4 -11
  170. package/lib/utils/scroll-lock.js +0 -107
  171. package/lib/utils/styles.d.ts +0 -1
  172. package/lib/utils/styles.js +0 -24
  173. package/lib/version.d.ts +1 -2
  174. package/lib/version.js +1 -11
  175. package/package.json +2 -2
  176. package/lib/base/ty-component.d.ts.map +0 -1
  177. package/lib/base/ty-component.js.map +0 -1
  178. package/lib/components/button.d.ts.map +0 -1
  179. package/lib/components/button.js.map +0 -1
  180. package/lib/components/calendar-month.d.ts.map +0 -1
  181. package/lib/components/calendar-month.js.map +0 -1
  182. package/lib/components/calendar-navigation.d.ts.map +0 -1
  183. package/lib/components/calendar-navigation.js.map +0 -1
  184. package/lib/components/calendar.d.ts.map +0 -1
  185. package/lib/components/calendar.js.map +0 -1
  186. package/lib/components/checkbox.d.ts.map +0 -1
  187. package/lib/components/checkbox.js.map +0 -1
  188. package/lib/components/copy.d.ts.map +0 -1
  189. package/lib/components/copy.js.map +0 -1
  190. package/lib/components/date-picker.d.ts.map +0 -1
  191. package/lib/components/date-picker.js.map +0 -1
  192. package/lib/components/file-upload.d.ts.map +0 -1
  193. package/lib/components/file-upload.js.map +0 -1
  194. package/lib/components/icon.d.ts.map +0 -1
  195. package/lib/components/icon.js.map +0 -1
  196. package/lib/components/input.d.ts.map +0 -1
  197. package/lib/components/input.js.map +0 -1
  198. package/lib/components/modal.d.ts.map +0 -1
  199. package/lib/components/modal.js.map +0 -1
  200. package/lib/components/option.d.ts.map +0 -1
  201. package/lib/components/option.js.map +0 -1
  202. package/lib/components/popup.d.ts.map +0 -1
  203. package/lib/components/popup.js.map +0 -1
  204. package/lib/components/radio.d.ts.map +0 -1
  205. package/lib/components/radio.js.map +0 -1
  206. package/lib/components/resize-observer.d.ts.map +0 -1
  207. package/lib/components/resize-observer.js.map +0 -1
  208. package/lib/components/scroll-container.d.ts.map +0 -1
  209. package/lib/components/scroll-container.js.map +0 -1
  210. package/lib/components/select.d.ts.map +0 -1
  211. package/lib/components/select.js.map +0 -1
  212. package/lib/components/selected-tags.d.ts.map +0 -1
  213. package/lib/components/selected-tags.js.map +0 -1
  214. package/lib/components/step.d.ts.map +0 -1
  215. package/lib/components/step.js.map +0 -1
  216. package/lib/components/switch.d.ts.map +0 -1
  217. package/lib/components/switch.js.map +0 -1
  218. package/lib/components/tab.d.ts.map +0 -1
  219. package/lib/components/tab.js.map +0 -1
  220. package/lib/components/tabs.d.ts.map +0 -1
  221. package/lib/components/tabs.js.map +0 -1
  222. package/lib/components/tag.d.ts.map +0 -1
  223. package/lib/components/tag.js.map +0 -1
  224. package/lib/components/textarea.d.ts.map +0 -1
  225. package/lib/components/textarea.js.map +0 -1
  226. package/lib/components/tooltip.d.ts.map +0 -1
  227. package/lib/components/tooltip.js.map +0 -1
  228. package/lib/components/wizard.d.ts.map +0 -1
  229. package/lib/components/wizard.js.map +0 -1
  230. package/lib/icons/fontawesome/brands.d.ts.map +0 -1
  231. package/lib/icons/fontawesome/brands.js.map +0 -1
  232. package/lib/icons/fontawesome/regular.d.ts.map +0 -1
  233. package/lib/icons/fontawesome/regular.js.map +0 -1
  234. package/lib/icons/fontawesome/solid.d.ts.map +0 -1
  235. package/lib/icons/fontawesome/solid.js.map +0 -1
  236. package/lib/icons/heroicons/micro.d.ts.map +0 -1
  237. package/lib/icons/heroicons/micro.js.map +0 -1
  238. package/lib/icons/heroicons/mini.d.ts.map +0 -1
  239. package/lib/icons/heroicons/mini.js.map +0 -1
  240. package/lib/icons/heroicons/outline.d.ts.map +0 -1
  241. package/lib/icons/heroicons/outline.js.map +0 -1
  242. package/lib/icons/heroicons/solid.d.ts.map +0 -1
  243. package/lib/icons/heroicons/solid.js.map +0 -1
  244. package/lib/icons/lucide.d.ts.map +0 -1
  245. package/lib/icons/lucide.js.map +0 -1
  246. package/lib/icons/material/filled.d.ts.map +0 -1
  247. package/lib/icons/material/filled.js.map +0 -1
  248. package/lib/icons/material/outlined.d.ts.map +0 -1
  249. package/lib/icons/material/outlined.js.map +0 -1
  250. package/lib/icons/material/round.d.ts.map +0 -1
  251. package/lib/icons/material/round.js.map +0 -1
  252. package/lib/icons/material/sharp.d.ts.map +0 -1
  253. package/lib/icons/material/sharp.js.map +0 -1
  254. package/lib/icons/material/two-tone.d.ts.map +0 -1
  255. package/lib/icons/material/two-tone.js.map +0 -1
  256. package/lib/index.d.ts.map +0 -1
  257. package/lib/index.js.map +0 -1
  258. package/lib/styles/button.d.ts.map +0 -1
  259. package/lib/styles/button.js.map +0 -1
  260. package/lib/styles/calendar-month.d.ts.map +0 -1
  261. package/lib/styles/calendar-month.js.map +0 -1
  262. package/lib/styles/calendar-navigation.d.ts.map +0 -1
  263. package/lib/styles/calendar-navigation.js.map +0 -1
  264. package/lib/styles/calendar.d.ts.map +0 -1
  265. package/lib/styles/calendar.js.map +0 -1
  266. package/lib/styles/checkbox.d.ts.map +0 -1
  267. package/lib/styles/checkbox.js.map +0 -1
  268. package/lib/styles/copy.d.ts.map +0 -1
  269. package/lib/styles/copy.js.map +0 -1
  270. package/lib/styles/custom-scrollbar.d.ts.map +0 -1
  271. package/lib/styles/custom-scrollbar.js.map +0 -1
  272. package/lib/styles/date-picker.d.ts.map +0 -1
  273. package/lib/styles/date-picker.js.map +0 -1
  274. package/lib/styles/file-upload.d.ts.map +0 -1
  275. package/lib/styles/file-upload.js.map +0 -1
  276. package/lib/styles/icon.d.ts.map +0 -1
  277. package/lib/styles/icon.js.map +0 -1
  278. package/lib/styles/input.d.ts.map +0 -1
  279. package/lib/styles/input.js.map +0 -1
  280. package/lib/styles/modal.d.ts.map +0 -1
  281. package/lib/styles/modal.js.map +0 -1
  282. package/lib/styles/multiselect.d.ts +0 -8
  283. package/lib/styles/multiselect.d.ts.map +0 -1
  284. package/lib/styles/multiselect.js +0 -849
  285. package/lib/styles/multiselect.js.map +0 -1
  286. package/lib/styles/option.d.ts.map +0 -1
  287. package/lib/styles/option.js.map +0 -1
  288. package/lib/styles/popup.d.ts.map +0 -1
  289. package/lib/styles/popup.js.map +0 -1
  290. package/lib/styles/radio.d.ts.map +0 -1
  291. package/lib/styles/radio.js.map +0 -1
  292. package/lib/styles/resize-observer.d.ts.map +0 -1
  293. package/lib/styles/resize-observer.js.map +0 -1
  294. package/lib/styles/scroll-container.d.ts.map +0 -1
  295. package/lib/styles/scroll-container.js.map +0 -1
  296. package/lib/styles/select-base.d.ts.map +0 -1
  297. package/lib/styles/select-base.js.map +0 -1
  298. package/lib/styles/select.d.ts.map +0 -1
  299. package/lib/styles/select.js.map +0 -1
  300. package/lib/styles/step.d.ts.map +0 -1
  301. package/lib/styles/step.js.map +0 -1
  302. package/lib/styles/switch.d.ts.map +0 -1
  303. package/lib/styles/switch.js.map +0 -1
  304. package/lib/styles/tab.d.ts.map +0 -1
  305. package/lib/styles/tab.js.map +0 -1
  306. package/lib/styles/tabs.d.ts.map +0 -1
  307. package/lib/styles/tabs.js.map +0 -1
  308. package/lib/styles/tag.d.ts.map +0 -1
  309. package/lib/styles/tag.js.map +0 -1
  310. package/lib/styles/textarea.d.ts.map +0 -1
  311. package/lib/styles/textarea.js.map +0 -1
  312. package/lib/styles/tooltip.d.ts.map +0 -1
  313. package/lib/styles/tooltip.js.map +0 -1
  314. package/lib/styles/wizard.d.ts.map +0 -1
  315. package/lib/styles/wizard.js.map +0 -1
  316. package/lib/types/common.d.ts.map +0 -1
  317. package/lib/types/common.js.map +0 -1
  318. package/lib/utils/calendar-utils.d.ts.map +0 -1
  319. package/lib/utils/calendar-utils.js.map +0 -1
  320. package/lib/utils/custom-scrollbar.d.ts.map +0 -1
  321. package/lib/utils/custom-scrollbar.js.map +0 -1
  322. package/lib/utils/flavor-sheet.d.ts.map +0 -1
  323. package/lib/utils/flavor-sheet.js.map +0 -1
  324. package/lib/utils/icon-registry.d.ts.map +0 -1
  325. package/lib/utils/icon-registry.js.map +0 -1
  326. package/lib/utils/icons.d.ts.map +0 -1
  327. package/lib/utils/icons.js.map +0 -1
  328. package/lib/utils/loader-registry.d.ts.map +0 -1
  329. package/lib/utils/loader-registry.js.map +0 -1
  330. package/lib/utils/locale.d.ts.map +0 -1
  331. package/lib/utils/locale.js.map +0 -1
  332. package/lib/utils/mobile.d.ts.map +0 -1
  333. package/lib/utils/mobile.js.map +0 -1
  334. package/lib/utils/number-format.d.ts.map +0 -1
  335. package/lib/utils/number-format.js.map +0 -1
  336. package/lib/utils/parse-boolean.d.ts +0 -39
  337. package/lib/utils/parse-boolean.d.ts.map +0 -1
  338. package/lib/utils/parse-boolean.js +0 -58
  339. package/lib/utils/parse-boolean.js.map +0 -1
  340. package/lib/utils/positioning.d.ts.map +0 -1
  341. package/lib/utils/positioning.js.map +0 -1
  342. package/lib/utils/property-capture.d.ts.map +0 -1
  343. package/lib/utils/property-capture.js.map +0 -1
  344. package/lib/utils/property-manager.d.ts.map +0 -1
  345. package/lib/utils/property-manager.js.map +0 -1
  346. package/lib/utils/resize-observer.d.ts.map +0 -1
  347. package/lib/utils/resize-observer.js.map +0 -1
  348. package/lib/utils/scroll-lock.d.ts.map +0 -1
  349. package/lib/utils/scroll-lock.js.map +0 -1
  350. package/lib/utils/styles.d.ts.map +0 -1
  351. package/lib/utils/styles.js.map +0 -1
  352. package/lib/version.d.ts.map +0 -1
  353. package/lib/version.js.map +0 -1
@@ -1,71 +1,23 @@
1
- /**
2
- * Modal Component
3
- *
4
- * Pure wrapper for modal dialogs using the native <dialog> element.
5
- * Provides backdrop, focus management, scroll locking, and keyboard interaction
6
- * without imposing any styling on content.
7
- *
8
- * Features:
9
- * - Native dialog element wrapper
10
- * - Dual API: declarative (open attribute) and imperative (show/hide methods)
11
- * - Cancellable `beforeclose` lifecycle event for unsaved-state flows
12
- * - Auto-hiding close button on hover (desktop only)
13
- * - Scroll locking with unique modal IDs
14
- * - Customizable backdrop via CSS variables
15
- *
16
- * @example
17
- * <ty-modal id="my-modal">
18
- * <div class="ty-elevated p-6 rounded-lg max-w-md">
19
- * <h3 class="text-lg font-semibold mb-4">Modal Title</h3>
20
- * <p class="ty-text- mb-4">Modal content here</p>
21
- * <ty-button onclick="this.closest('ty-modal').hide()">
22
- * Close
23
- * </ty-button>
24
- * </div>
25
- * </ty-modal>
26
- */
27
1
  import { lockScroll, unlockScroll } from '../utils/scroll-lock.js';
28
2
  import { ensureStyles } from '../utils/styles.js';
29
3
  import { modalStyles } from '../styles/modal.js';
30
- // ============================================================================
31
- // WeakMaps for State Management
32
- // ============================================================================
33
4
  const backdropClickHandlers = new WeakMap();
34
5
  const escapeKeyHandlers = new WeakMap();
35
6
  const closeButtonHandlers = new WeakMap();
36
7
  const hoverEnterHandlers = new WeakMap();
37
8
  const hoverLeaveHandlers = new WeakMap();
38
- const modalIds = new WeakMap(); // Store unique modal ID for scroll locking
39
- // ============================================================================
40
- // Constants
41
- // ============================================================================
42
- /**
43
- * SVG icon for the close button (Lucide X icon)
44
- */
9
+ const modalIds = new WeakMap();
45
10
  const CLOSE_ICON = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x-icon lucide-x"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>`;
46
- // ============================================================================
47
- // Helper Functions
48
- // ============================================================================
49
- /**
50
- * Parse boolean attribute
51
- * Boolean attribute semantics: presence -> true, explicit 'false' -> false
52
- * Matches ClojureScript implementation
53
- */
54
11
  function parseBoolAttr(el, name) {
55
12
  if (!el.hasAttribute(name)) {
56
13
  return false;
57
14
  }
58
15
  const value = el.getAttribute(name);
59
- // Explicit "false" string means false
60
16
  if (value !== null && value.toLowerCase() === 'false') {
61
17
  return false;
62
18
  }
63
- // Attribute present (even empty) means true
64
19
  return true;
65
20
  }
66
- /**
67
- * Read modal attributes with defaults
68
- */
69
21
  function getModalAttributes(el) {
70
22
  return {
71
23
  open: parseBoolAttr(el, 'open'),
@@ -78,15 +30,9 @@ function getModalAttributes(el) {
78
30
  : true,
79
31
  };
80
32
  }
81
- /**
82
- * Get the modal dialog element from shadow root
83
- */
84
33
  function getModalDialog(shadowRoot) {
85
34
  return shadowRoot.querySelector('.ty-modal-dialog');
86
35
  }
87
- /**
88
- * Get or create a unique modal ID for scroll locking
89
- */
90
36
  function getModalId(el) {
91
37
  let id = modalIds.get(el);
92
38
  if (!id) {
@@ -95,15 +41,9 @@ function getModalId(el) {
95
41
  }
96
42
  return id;
97
43
  }
98
- /**
99
- * Check if device is mobile (for hover behavior)
100
- */
101
44
  function isMobile() {
102
45
  return window.innerWidth < 768 || navigator.maxTouchPoints > 0;
103
46
  }
104
- /**
105
- * Dispatch custom modal event
106
- */
107
47
  function dispatchModalEvent(el, eventType, detail) {
108
48
  const event = new CustomEvent(eventType, {
109
49
  detail,
@@ -112,12 +52,6 @@ function dispatchModalEvent(el, eventType, detail) {
112
52
  });
113
53
  el.dispatchEvent(event);
114
54
  }
115
- // ============================================================================
116
- // Dialog Structure Creation
117
- // ============================================================================
118
- /**
119
- * Ensure the internal dialog structure exists in shadow DOM
120
- */
121
55
  function ensureInternalDialog(shadowRoot) {
122
56
  let dialog = getModalDialog(shadowRoot);
123
57
  if (!dialog) {
@@ -125,45 +59,24 @@ function ensureInternalDialog(shadowRoot) {
125
59
  const closeButton = document.createElement('button');
126
60
  const contentDiv = document.createElement('div');
127
61
  const slot = document.createElement('slot');
128
- // Setup dialog structure
129
62
  dialog.className = 'ty-modal-dialog';
130
- // Setup close button with SVG icon
131
63
  closeButton.className = 'close-button';
132
64
  closeButton.type = 'button';
133
65
  closeButton.setAttribute('aria-label', 'Close modal');
134
66
  closeButton.innerHTML = CLOSE_ICON;
135
- // Setup content container
136
67
  contentDiv.className = 'modal-content';
137
68
  contentDiv.appendChild(slot);
138
- // Assemble: dialog > [close-button, content-div]
139
69
  dialog.appendChild(closeButton);
140
70
  dialog.appendChild(contentDiv);
141
71
  shadowRoot.appendChild(dialog);
142
72
  }
143
73
  return dialog;
144
74
  }
145
- // ============================================================================
146
- // Event Handlers
147
- // ============================================================================
148
- /**
149
- * Close modal with cancellable beforeclose lifecycle.
150
- *
151
- * 1. Emit `beforeclose` (cancellable, bubbles, composed). Consumers can
152
- * `event.preventDefault()` to abort the close — render your own UI for
153
- * unsaved-state flows.
154
- * 2. Remove the `open` attribute, which triggers the actual close.
155
- *
156
- * Callers pass `reason` so consumers can decide differently based on intent
157
- * (e.g. "OK to discard via ESC, but not via .hide() during a save").
158
- */
159
75
  function closeModal(el, reason = 'programmatic', opts) {
160
76
  const shadowRoot = el.shadowRoot;
161
77
  const dialog = shadowRoot ? getModalDialog(shadowRoot) : null;
162
78
  if (!dialog || !dialog.open)
163
79
  return;
164
- // `force: true` bypasses the cancellable event. Used by consumers AFTER
165
- // they've shown their own confirm UI and the user said "yes, close" —
166
- // calling `.hide()` again without force would re-trigger their intercept.
167
80
  if (!opts?.force) {
168
81
  const beforeClose = new CustomEvent('beforeclose', {
169
82
  detail: { reason },
@@ -175,31 +88,20 @@ function closeModal(el, reason = 'programmatic', opts) {
175
88
  if (beforeClose.defaultPrevented)
176
89
  return;
177
90
  }
178
- // Remove open attribute (triggers actual close).
179
91
  el.removeAttribute('open');
180
92
  }
181
- /**
182
- * Open modal programmatically
183
- */
184
93
  function openModal(el) {
185
94
  el.setAttribute('open', 'true');
186
95
  }
187
- /**
188
- * Handle backdrop click
189
- */
190
96
  function handleBackdropClick(el, event) {
191
97
  event.stopPropagation();
192
98
  const shadowRoot = el.shadowRoot;
193
99
  const dialog = shadowRoot ? getModalDialog(shadowRoot) : null;
194
- // Only close if clicking on dialog backdrop (not content)
195
100
  if (dialog && event.target === dialog) {
196
101
  event.preventDefault();
197
102
  closeModal(el, 'backdrop');
198
103
  }
199
104
  }
200
- /**
201
- * Handle escape key press
202
- */
203
105
  function handleEscapeKey(el, event) {
204
106
  event.stopPropagation();
205
107
  if (event.key === 'Escape') {
@@ -207,17 +109,11 @@ function handleEscapeKey(el, event) {
207
109
  closeModal(el, 'escape');
208
110
  }
209
111
  }
210
- /**
211
- * Handle close button click
212
- */
213
112
  function handleCloseButtonClick(el, event) {
214
113
  event.preventDefault();
215
114
  event.stopPropagation();
216
115
  closeModal(el, 'close-button');
217
116
  }
218
- /**
219
- * Handle hover enter on modal content (hide close button)
220
- */
221
117
  function handleHoverEnter(_el, event) {
222
118
  const content = event.currentTarget;
223
119
  const dialog = content.closest('.ty-modal-dialog');
@@ -228,9 +124,6 @@ function handleHoverEnter(_el, event) {
228
124
  }
229
125
  }
230
126
  }
231
- /**
232
- * Handle hover leave on modal content (show close button)
233
- */
234
127
  function handleHoverLeave(_el, event) {
235
128
  const content = event.currentTarget;
236
129
  const dialog = content.closest('.ty-modal-dialog');
@@ -241,75 +134,55 @@ function handleHoverLeave(_el, event) {
241
134
  }
242
135
  }
243
136
  }
244
- /**
245
- * Setup backdrop click handling
246
- */
247
137
  function setupBackdropClick(el, dialog, enabled) {
248
- // Remove existing listener
249
138
  const existingHandler = backdropClickHandlers.get(el);
250
139
  if (existingHandler) {
251
140
  dialog.removeEventListener('click', existingHandler);
252
141
  backdropClickHandlers.delete(el);
253
142
  }
254
- // Add new listener if enabled
255
143
  if (enabled) {
256
144
  const handler = (e) => handleBackdropClick(el, e);
257
145
  backdropClickHandlers.set(el, handler);
258
146
  dialog.addEventListener('click', handler);
259
147
  }
260
148
  }
261
- /**
262
- * Setup escape key handling
263
- */
264
149
  function setupEscapeKey(el, dialog, enabled) {
265
- // Remove existing listener
266
150
  const existingHandler = escapeKeyHandlers.get(el);
267
151
  if (existingHandler) {
268
152
  dialog.removeEventListener('keydown', existingHandler);
269
153
  escapeKeyHandlers.delete(el);
270
154
  }
271
- // Add new listener if enabled
272
155
  if (enabled) {
273
156
  const handler = (e) => handleEscapeKey(el, e);
274
157
  escapeKeyHandlers.set(el, handler);
275
158
  dialog.addEventListener('keydown', handler);
276
159
  }
277
160
  }
278
- /**
279
- * Setup close button click handling and visibility
280
- */
281
161
  function setupCloseButton(el, dialog, showButton) {
282
162
  const closeButton = dialog.querySelector('.close-button');
283
163
  if (!closeButton)
284
164
  return;
285
- // Show or hide close button based on close-on-outside-click setting
286
165
  if (showButton) {
287
166
  closeButton.style.display = '';
288
167
  }
289
168
  else {
290
169
  closeButton.style.display = 'none';
291
170
  }
292
- // Remove existing listener
293
171
  const existingHandler = closeButtonHandlers.get(el);
294
172
  if (existingHandler) {
295
173
  closeButton.removeEventListener('click', existingHandler);
296
174
  closeButtonHandlers.delete(el);
297
175
  }
298
- // Add click listener only if button is visible
299
176
  if (showButton) {
300
177
  const handler = (e) => handleCloseButtonClick(el, e);
301
178
  closeButtonHandlers.set(el, handler);
302
179
  closeButton.addEventListener('click', handler);
303
180
  }
304
181
  }
305
- /**
306
- * Setup close button hover handlers (desktop only)
307
- */
308
182
  function setupCloseButtonHover(el, dialog) {
309
183
  const modalContent = dialog.querySelector('.modal-content');
310
184
  if (!modalContent)
311
185
  return;
312
- // Remove existing listeners
313
186
  const existingEnterHandler = hoverEnterHandlers.get(el);
314
187
  const existingLeaveHandler = hoverLeaveHandlers.get(el);
315
188
  if (existingEnterHandler) {
@@ -320,7 +193,6 @@ function setupCloseButtonHover(el, dialog) {
320
193
  modalContent.removeEventListener('mouseleave', existingLeaveHandler);
321
194
  hoverLeaveHandlers.delete(el);
322
195
  }
323
- // Add hover listeners only on desktop
324
196
  if (!isMobile()) {
325
197
  const enterHandler = (e) => handleHoverEnter(el, e);
326
198
  const leaveHandler = (e) => handleHoverLeave(el, e);
@@ -330,12 +202,6 @@ function setupCloseButtonHover(el, dialog) {
330
202
  modalContent.addEventListener('mouseleave', leaveHandler);
331
203
  }
332
204
  }
333
- // ============================================================================
334
- // Core Render Function
335
- // ============================================================================
336
- /**
337
- * Render the modal structure and sync state
338
- */
339
205
  function render(el) {
340
206
  const shadowRoot = el.shadowRoot;
341
207
  if (!shadowRoot)
@@ -343,22 +209,14 @@ function render(el) {
343
209
  const attributes = getModalAttributes(el);
344
210
  const dialog = ensureInternalDialog(shadowRoot);
345
211
  const modalId = getModalId(el);
346
- // Ensure styles are loaded
347
212
  ensureStyles(shadowRoot, { css: modalStyles, id: 'ty-modal' });
348
- // Apply dialog class
349
213
  dialog.className = 'ty-modal-dialog';
350
- // Apply backdrop attribute
351
214
  if (attributes.backdrop) {
352
215
  dialog.setAttribute('data-backdrop', 'true');
353
216
  }
354
217
  else {
355
218
  dialog.removeAttribute('data-backdrop');
356
219
  }
357
- // Accessible name: <dialog> has an implicit role="dialog" for free, but
358
- // nothing gives it a NAME unless the consumer's own slotted heading
359
- // happens to get wired up manually. Opt-in `label` attribute (same
360
- // pattern as ty-select/ty-date-picker's `label` prop) — unset stays
361
- // exactly as before (no regression, just no fix without opting in).
362
220
  const label = el.getAttribute('label');
363
221
  if (label) {
364
222
  dialog.setAttribute('aria-label', label);
@@ -366,54 +224,35 @@ function render(el) {
366
224
  else {
367
225
  dialog.removeAttribute('aria-label');
368
226
  }
369
- // Setup event handlers
370
227
  setupBackdropClick(el, dialog, attributes.closeOnOutsideClick);
371
228
  setupEscapeKey(el, dialog, attributes.closeOnEscape);
372
229
  setupCloseButton(el, dialog, attributes.closeOnOutsideClick);
373
230
  setupCloseButtonHover(el, dialog);
374
- // Sync open state with native dialog
375
231
  if (attributes.open) {
376
232
  if (!dialog.open) {
377
- // Lock scroll
378
233
  lockScroll(modalId);
379
- // Show dialog
380
234
  if (attributes.backdrop) {
381
235
  dialog.showModal();
382
236
  }
383
237
  else {
384
238
  dialog.show();
385
239
  }
386
- // Dispatch open event
387
240
  dispatchModalEvent(el, 'open', {});
388
241
  }
389
242
  }
390
243
  else {
391
244
  if (dialog.open) {
392
- // Unlock scroll
393
245
  unlockScroll(modalId);
394
- // Close dialog
395
246
  dialog.close();
396
- // Dispatch close event
397
247
  dispatchModalEvent(el, 'close', {
398
248
  reason: 'programmatic'
399
249
  });
400
250
  }
401
251
  }
402
- // Handle dialog's native close event.
403
- //
404
- // Child components (ty-select, ty-date-picker) dispatch a
405
- // bubbling+composed `close` custom event when their popups close. Those
406
- // events bubble up to *this* dialog and trigger `onclose` too — without this
407
- // guard, opening a dropdown inside a modal and closing the dropdown would
408
- // close the whole modal. The native dialog `close` event is not composed
409
- // and targets the dialog itself, so we only react when `event.target` is
410
- // the dialog.
411
252
  dialog.onclose = (event) => {
412
253
  if (event.target !== dialog)
413
254
  return;
414
- // Ensure scroll is unlocked
415
255
  unlockScroll(modalId);
416
- // Sync the open attribute
417
256
  if (el.hasAttribute('open')) {
418
257
  el.removeAttribute('open');
419
258
  dispatchModalEvent(el, 'close', {
@@ -423,33 +262,26 @@ function render(el) {
423
262
  }
424
263
  };
425
264
  }
426
- /**
427
- * Cleanup all resources when component disconnects
428
- */
429
265
  function cleanup(el) {
430
266
  const modalId = modalIds.get(el);
431
267
  const shadowRoot = el.shadowRoot;
432
268
  const dialog = shadowRoot ? getModalDialog(shadowRoot) : null;
433
- // Force unlock scroll if modal removed while open
434
269
  if (modalId) {
435
270
  unlockScroll(modalId);
436
271
  modalIds.delete(el);
437
272
  }
438
273
  if (!dialog)
439
274
  return;
440
- // Cleanup backdrop click handler
441
275
  const backdropHandler = backdropClickHandlers.get(el);
442
276
  if (backdropHandler) {
443
277
  dialog.removeEventListener('click', backdropHandler);
444
278
  backdropClickHandlers.delete(el);
445
279
  }
446
- // Cleanup escape key handler
447
280
  const escapeHandler = escapeKeyHandlers.get(el);
448
281
  if (escapeHandler) {
449
282
  dialog.removeEventListener('keydown', escapeHandler);
450
283
  escapeKeyHandlers.delete(el);
451
284
  }
452
- // Cleanup close button handler
453
285
  const closeButton = dialog.querySelector('.close-button');
454
286
  if (closeButton) {
455
287
  const closeHandler = closeButtonHandlers.get(el);
@@ -458,7 +290,6 @@ function cleanup(el) {
458
290
  closeButtonHandlers.delete(el);
459
291
  }
460
292
  }
461
- // Cleanup hover handlers
462
293
  const modalContent = dialog.querySelector('.modal-content');
463
294
  if (modalContent) {
464
295
  const enterHandler = hoverEnterHandlers.get(el);
@@ -473,14 +304,7 @@ function cleanup(el) {
473
304
  }
474
305
  }
475
306
  }
476
- // ============================================================================
477
- // Component Definition
478
- // ============================================================================
479
- /**
480
- * TyModal Web Component
481
- */
482
307
  export class TyModal extends HTMLElement {
483
- /** Observed attributes */
484
308
  static get observedAttributes() {
485
309
  return ['open', 'backdrop', 'close-on-outside-click', 'close-on-escape', 'label'];
486
310
  }
@@ -490,7 +314,6 @@ export class TyModal extends HTMLElement {
490
314
  }
491
315
  connectedCallback() {
492
316
  render(this);
493
- // Add public API methods
494
317
  this.show = () => openModal(this);
495
318
  this.hide = (opts) => closeModal(this, 'programmatic', opts);
496
319
  }
@@ -498,25 +321,15 @@ export class TyModal extends HTMLElement {
498
321
  cleanup(this);
499
322
  }
500
323
  attributeChangedCallback(_name, _oldValue, _newValue) {
501
- // React (and any framework that conditionally mounts an already-open
502
- // modal) sets initial attributes BEFORE inserting the element into the
503
- // document, and showModal() on a disconnected <dialog> throws
504
- // InvalidStateError. Defer — connectedCallback render()s on insertion
505
- // and applies `open` then.
506
324
  if (!this.isConnected)
507
325
  return;
508
- // Re-render on attribute changes
509
326
  render(this);
510
327
  }
511
328
  }
512
- // Register the custom element
513
329
  if (!customElements.get('ty-modal')) {
514
330
  customElements.define('ty-modal', TyModal);
515
331
  }
516
- // Also exposed as ty-dialog — the platform/ARIA name (wraps native <dialog>).
517
- // A constructor can only register once, hence the subclass.
518
332
  if (!customElements.get('ty-dialog')) {
519
333
  customElements.define('ty-dialog', class TyDialog extends TyModal {
520
334
  });
521
335
  }
522
- //# sourceMappingURL=modal.js.map
@@ -1,9 +1,6 @@
1
1
  /**
2
- * TyOption Web Component
3
- * PORTED FROM: clj/ty/components/option.cljs
4
- *
5
- * Ty Option Web Component - Rich HTML alternative to native <option>
6
- * Enhanced with robust property-attribute synchronization for framework compatibility.
2
+ * TyOption Web Component - rich HTML alternative to native <option>.
3
+ * Property-attribute synchronization keeps it compatible with frameworks.
7
4
  */
8
5
  import type { TyOptionElement } from '../types/common.js';
9
6
  export declare class TyOption extends HTMLElement implements TyOptionElement {
@@ -31,9 +28,5 @@ export declare class TyOption extends HTMLElement implements TyOptionElement {
31
28
  set highlighted(value: boolean);
32
29
  get hidden(): boolean;
33
30
  set hidden(value: boolean);
34
- /**
35
- * Render the option component with rich HTML content and property sync
36
- */
37
31
  private render;
38
32
  }
39
- //# sourceMappingURL=option.d.ts.map
@@ -1,29 +1,5 @@
1
- /**
2
- * TyOption Web Component
3
- * PORTED FROM: clj/ty/components/option.cljs
4
- *
5
- * Ty Option Web Component - Rich HTML alternative to native <option>
6
- * Enhanced with robust property-attribute synchronization for framework compatibility.
7
- */
8
1
  import { ensureStyles } from '../utils/styles.js';
9
2
  import { optionStyles } from '../styles/option.js';
10
- /**
11
- * Ty Option Component
12
- *
13
- * Rich HTML alternative to native <option> element.
14
- * Supports HTML content, styling, and framework property binding.
15
- *
16
- * @example
17
- * ```html
18
- * <ty-option value="1">Simple Option</ty-option>
19
- * <ty-option value="2" selected>Selected Option</ty-option>
20
- * <ty-option value="3" disabled>Disabled Option</ty-option>
21
- * <ty-option value="4">
22
- * <strong>Rich</strong> <em>HTML</em> Content
23
- * </ty-option>
24
- * ```
25
- */
26
- /** Lucide `check` — shown on selected options (kept inline: shadow DOM can't rely on the icon registry) */
27
3
  const CHECK_SVG = `
28
4
  <svg class="option-check" viewBox="0 0 24 24" fill="none" stroke="currentColor"
29
5
  stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
@@ -46,12 +22,9 @@ export class TyOption extends HTMLElement {
46
22
  return ['value', 'disabled', 'selected', 'highlighted', 'hidden'];
47
23
  }
48
24
  connectedCallback() {
49
- // CRITICAL: Reagent/React may set properties BEFORE the element is constructed
50
- // Check if value was set directly on the instance before our getter/setter was available
51
25
  const instanceValue = Object.getOwnPropertyDescriptor(this, 'value');
52
26
  if (instanceValue && instanceValue.value !== undefined) {
53
27
  this._value = instanceValue.value;
54
- // Clean up the instance property so our getter/setter works
55
28
  delete this.value;
56
29
  }
57
30
  this.render();
@@ -78,13 +51,7 @@ export class TyOption extends HTMLElement {
78
51
  }
79
52
  this.render();
80
53
  }
81
- /**
82
- * Get value from either property or attribute, with textContent fallback.
83
- * Property takes precedence (for framework compatibility).
84
- */
85
54
  getOptionValue() {
86
- // Explicit priority: property > attribute > textContent
87
- // This correctly handles empty strings
88
55
  if (this._value !== undefined) {
89
56
  return this._value;
90
57
  }
@@ -94,8 +61,6 @@ export class TyOption extends HTMLElement {
94
61
  }
95
62
  return this.textContent?.trim() || '';
96
63
  }
97
- // Public API - Getters/Setters
98
- // NOTE: All setters trigger re-render to support property changes from frameworks like React
99
64
  get value() {
100
65
  return this.getOptionValue();
101
66
  }
@@ -171,42 +136,31 @@ export class TyOption extends HTMLElement {
171
136
  this.render();
172
137
  }
173
138
  }
174
- /**
175
- * Render the option component with rich HTML content and property sync
176
- */
177
139
  render() {
178
140
  const shadow = this.shadowRoot;
179
- // Create wrapper once — the check icon alone communicates selection;
180
- // clicking a selected option again deselects it (see select.ts), so no
181
- // separate clear affordance is needed on mobile.
182
141
  if (!shadow.querySelector('.option-content')) {
183
142
  shadow.innerHTML = `<div class="option-content"><slot></slot>${CHECK_SVG}</div>`;
184
143
  }
185
- // Update content wrapper attributes
186
144
  const content = shadow.querySelector('.option-content');
187
145
  if (content) {
188
- // Disabled state
189
146
  if (this._disabled) {
190
147
  content.setAttribute('disabled', '');
191
148
  }
192
149
  else {
193
150
  content.removeAttribute('disabled');
194
151
  }
195
- // Selected state
196
152
  if (this._selected) {
197
153
  content.setAttribute('selected', '');
198
154
  }
199
155
  else {
200
156
  content.removeAttribute('selected');
201
157
  }
202
- // Highlighted state
203
158
  if (this._highlighted) {
204
159
  content.setAttribute('highlighted', '');
205
160
  }
206
161
  else {
207
162
  content.removeAttribute('highlighted');
208
163
  }
209
- // Hidden state
210
164
  if (this._hidden) {
211
165
  content.setAttribute('hidden', '');
212
166
  }
@@ -216,8 +170,6 @@ export class TyOption extends HTMLElement {
216
170
  }
217
171
  }
218
172
  }
219
- // Register the custom element
220
173
  if (!customElements.get('ty-option')) {
221
174
  customElements.define('ty-option', TyOption);
222
175
  }
223
- //# sourceMappingURL=option.js.map
@@ -1,19 +1,6 @@
1
1
  /**
2
- * Popup Component
3
- *
4
- * Interactive popup component with dropdown-like behavior and tooltip positioning.
5
- * Uses parent-child relationship - popup opens on click, stays open for interaction,
6
- * closes on outside click or ESC key.
7
- *
8
- * @example
9
- * <button>
10
- * Click me
11
- * <ty-popup placement="bottom" offset="8">
12
- * <div class="ty-elevated p-4 rounded-lg">
13
- * Popup content here
14
- * </div>
15
- * </ty-popup>
16
- * </button>
2
+ * Popup Component - click-triggered popup positioned against its PARENT element
3
+ * (the anchor). Stays open for interaction; closes on outside click or ESC.
17
4
  */
18
5
  import { type Placement } from '../utils/positioning.js';
19
6
  /**
@@ -33,11 +20,9 @@ export declare class TyPopup extends HTMLElement {
33
20
  closePopup?: () => void;
34
21
  openPopup?: () => void;
35
22
  togglePopup?: () => void;
36
- /** Observed attributes */
37
23
  static get observedAttributes(): string[];
38
24
  constructor();
39
25
  connectedCallback(): void;
40
26
  disconnectedCallback(): void;
41
27
  attributeChangedCallback(name: string, _oldValue: string | null, _newValue: string | null): void;
42
28
  }
43
- //# sourceMappingURL=popup.d.ts.map