@mhmo91/schmancy 0.10.28 → 0.10.30

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 (451) hide show
  1. package/custom-elements.json +7 -2
  2. package/dist/SchmancyElement-BQ4DFufc.js +300 -0
  3. package/dist/SchmancyElement-BQ4DFufc.js.map +1 -0
  4. package/dist/SchmancyElement-DhSiMp6Y.cjs +2 -0
  5. package/dist/SchmancyElement-DhSiMp6Y.cjs.map +1 -0
  6. package/dist/agent/{flow-3RrZM-e7.js.map → flow-CvG1fLW5.js.map} +1 -1
  7. package/dist/agent/schmancy.agent.js +7843 -3334
  8. package/dist/agent/schmancy.agent.js.map +1 -1
  9. package/dist/agent/schmancy.manifest.json +1 -2
  10. package/dist/agent/{vendor-material-color-33Mj762T.js.map → vendor-material-color-DcL7ZPxx.js.map} +1 -1
  11. package/dist/animation-CCOIW4wJ.cjs.map +1 -1
  12. package/dist/animation-DCznELuT.js.map +1 -1
  13. package/dist/{area-C_Yvjmad.js → area-BjpUWvzE.js} +7 -7
  14. package/dist/{area-C_Yvjmad.js.map → area-BjpUWvzE.js.map} +1 -1
  15. package/dist/area-CgTzkxah.cjs +21 -0
  16. package/dist/{area-BSVOYQDA.cjs.map → area-CgTzkxah.cjs.map} +1 -1
  17. package/dist/area.cjs +1 -1
  18. package/dist/area.js +1 -1
  19. package/dist/{audio-CxO5a2HL.js → audio-CwBJntnB.js} +1 -1
  20. package/dist/{audio-CxO5a2HL.js.map → audio-CwBJntnB.js.map} +1 -1
  21. package/dist/{audio-Cvmemu84.cjs → audio-DISBFOaR.cjs} +1 -1
  22. package/dist/{audio-Cvmemu84.cjs.map → audio-DISBFOaR.cjs.map} +1 -1
  23. package/dist/audio.cjs +1 -1
  24. package/dist/audio.js +2 -2
  25. package/dist/{autocomplete-B50VXUzw.cjs → autocomplete-DbCUOgWU.cjs} +2 -2
  26. package/dist/{autocomplete-B50VXUzw.cjs.map → autocomplete-DbCUOgWU.cjs.map} +1 -1
  27. package/dist/{autocomplete-C6I1mfOT.js → autocomplete-Dy708jem.js} +7 -7
  28. package/dist/{autocomplete-C6I1mfOT.js.map → autocomplete-Dy708jem.js.map} +1 -1
  29. package/dist/autocomplete.cjs +1 -1
  30. package/dist/autocomplete.js +1 -1
  31. package/dist/avatar.cjs +3 -3
  32. package/dist/avatar.cjs.map +1 -1
  33. package/dist/avatar.js +5 -5
  34. package/dist/avatar.js.map +1 -1
  35. package/dist/badge.cjs +1 -1
  36. package/dist/badge.js +1 -1
  37. package/dist/{boat-DVQBNkk5.cjs → boat-BzZN_iwp.cjs} +11 -11
  38. package/dist/{boat-DVQBNkk5.cjs.map → boat-BzZN_iwp.cjs.map} +1 -1
  39. package/dist/{boat-C94QZ4Zt.js → boat-Z4Lzl3ai.js} +8 -8
  40. package/dist/{boat-C94QZ4Zt.js.map → boat-Z4Lzl3ai.js.map} +1 -1
  41. package/dist/boat.cjs +1 -1
  42. package/dist/boat.js +1 -1
  43. package/dist/breadcrumb.cjs +4 -4
  44. package/dist/breadcrumb.cjs.map +1 -1
  45. package/dist/breadcrumb.js +7 -7
  46. package/dist/breadcrumb.js.map +1 -1
  47. package/dist/{busy--bNb42rM.js → busy-CRFGPkcP.js} +7 -7
  48. package/dist/{busy--bNb42rM.js.map → busy-CRFGPkcP.js.map} +1 -1
  49. package/dist/{busy-DuxFvEkY.cjs → busy-Cu-47DfN.cjs} +8 -8
  50. package/dist/{busy-DuxFvEkY.cjs.map → busy-Cu-47DfN.cjs.map} +1 -1
  51. package/dist/busy.cjs +1 -1
  52. package/dist/busy.js +1 -1
  53. package/dist/{button-DAFZ5A4O.cjs → button-CN_JTjRd.cjs} +15 -15
  54. package/dist/{button-DAFZ5A4O.cjs.map → button-CN_JTjRd.cjs.map} +1 -1
  55. package/dist/{button-B7b9L_h5.js → button-D_USF3tt.js} +10 -10
  56. package/dist/{button-B7b9L_h5.js.map → button-D_USF3tt.js.map} +1 -1
  57. package/dist/button.cjs +19 -19
  58. package/dist/button.cjs.map +1 -1
  59. package/dist/button.js +9 -9
  60. package/dist/button.js.map +1 -1
  61. package/dist/{card-DZPd24Sn.cjs → card-D4P5_gg9.cjs} +10 -10
  62. package/dist/{card-DZPd24Sn.cjs.map → card-D4P5_gg9.cjs.map} +1 -1
  63. package/dist/{card-ixzxOW-Q.js → card-DpN5KIYc.js} +15 -15
  64. package/dist/{card-ixzxOW-Q.js.map → card-DpN5KIYc.js.map} +1 -1
  65. package/dist/card.cjs +1 -1
  66. package/dist/card.js +1 -1
  67. package/dist/{checkbox-DdGpepTh.js → checkbox-C8ChypKf.js} +5 -5
  68. package/dist/{checkbox-DdGpepTh.js.map → checkbox-C8ChypKf.js.map} +1 -1
  69. package/dist/{checkbox-Bi_Fm2mf.cjs → checkbox-hhXVXDV1.cjs} +3 -3
  70. package/dist/{checkbox-Bi_Fm2mf.cjs.map → checkbox-hhXVXDV1.cjs.map} +1 -1
  71. package/dist/checkbox.cjs +1 -1
  72. package/dist/checkbox.js +1 -1
  73. package/dist/{chips-DLTynyVB.js → chips-B8R9q4yl.js} +27 -27
  74. package/dist/{chips-DLTynyVB.js.map → chips-B8R9q4yl.js.map} +1 -1
  75. package/dist/{chips-DWQMZErr.cjs → chips-BTLlO_Ow.cjs} +18 -18
  76. package/dist/{chips-DWQMZErr.cjs.map → chips-BTLlO_Ow.cjs.map} +1 -1
  77. package/dist/chips.cjs +1 -1
  78. package/dist/chips.js +2 -2
  79. package/dist/connectivity.cjs +7 -7
  80. package/dist/connectivity.cjs.map +1 -1
  81. package/dist/connectivity.js +5 -5
  82. package/dist/connectivity.js.map +1 -1
  83. package/dist/content-drawer.cjs +1 -1
  84. package/dist/content-drawer.js +1 -1
  85. package/dist/cursor-glow-Ah7VXSj7.js.map +1 -1
  86. package/dist/cursor-glow-Bulq-38P.cjs.map +1 -1
  87. package/dist/{date-range-DQpmMJH-.cjs → date-range-9h6ZSkZb.cjs} +3 -3
  88. package/dist/{date-range-DQpmMJH-.cjs.map → date-range-9h6ZSkZb.cjs.map} +1 -1
  89. package/dist/{date-range-CJ6MiTpF.js → date-range-CS96dWMh.js} +7 -7
  90. package/dist/{date-range-CJ6MiTpF.js.map → date-range-CS96dWMh.js.map} +1 -1
  91. package/dist/date-range-inline-CAxnHA-l.cjs +43 -0
  92. package/dist/{date-range-inline-nPWIs-3C.cjs.map → date-range-inline-CAxnHA-l.cjs.map} +1 -1
  93. package/dist/{date-range-inline-Ho3CENTh.js → date-range-inline-DCXdGeRv.js} +5 -5
  94. package/dist/{date-range-inline-Ho3CENTh.js.map → date-range-inline-DCXdGeRv.js.map} +1 -1
  95. package/dist/date-range-inline.cjs +1 -1
  96. package/dist/date-range-inline.js +1 -1
  97. package/dist/date-range.cjs +1 -1
  98. package/dist/date-range.js +1 -1
  99. package/dist/delay.cjs +4 -4
  100. package/dist/delay.cjs.map +1 -1
  101. package/dist/delay.js +6 -6
  102. package/dist/delay.js.map +1 -1
  103. package/dist/{details-BnRWMZdt.cjs → details-BC0IObBd.cjs} +2 -2
  104. package/dist/{details-BnRWMZdt.cjs.map → details-BC0IObBd.cjs.map} +1 -1
  105. package/dist/{details-CcMTvYo7.js → details-Pgd0slKn.js} +11 -11
  106. package/dist/{details-CcMTvYo7.js.map → details-Pgd0slKn.js.map} +1 -1
  107. package/dist/details.cjs +1 -1
  108. package/dist/details.js +1 -1
  109. package/dist/{directives-DgPbz0lQ.js → directives-B-RT9R2u.js} +3 -3
  110. package/dist/{directives-DgPbz0lQ.js.map → directives-B-RT9R2u.js.map} +1 -1
  111. package/dist/{directives-BkSqmLBV.cjs → directives-CFWacnWU.cjs} +1 -1
  112. package/dist/{directives-BkSqmLBV.cjs.map → directives-CFWacnWU.cjs.map} +1 -1
  113. package/dist/directives.cjs +1 -1
  114. package/dist/directives.js +2 -2
  115. package/dist/discovery.service-CIa3Eeuk.cjs.map +1 -1
  116. package/dist/discovery.service-DZFxtRwW.js.map +1 -1
  117. package/dist/{divider-CZCj0ioH.js → divider-BMzm0lOz.js} +5 -5
  118. package/dist/{divider-CZCj0ioH.js.map → divider-BMzm0lOz.js.map} +1 -1
  119. package/dist/{divider-C6yJSL1c.cjs → divider-D1OzaRAQ.cjs} +3 -3
  120. package/dist/{divider-C6yJSL1c.cjs.map → divider-D1OzaRAQ.cjs.map} +1 -1
  121. package/dist/divider.cjs +1 -1
  122. package/dist/divider.js +1 -1
  123. package/dist/dropdown.cjs +4 -4
  124. package/dist/dropdown.cjs.map +1 -1
  125. package/dist/dropdown.js +8 -8
  126. package/dist/dropdown.js.map +1 -1
  127. package/dist/{expand-Cc6ogXsR.js → expand-C0Uqxfv0.js} +10 -10
  128. package/dist/{expand-Cc6ogXsR.js.map → expand-C0Uqxfv0.js.map} +1 -1
  129. package/dist/{expand-D4EhwOYh.cjs → expand-CiQkzth9.cjs} +3 -3
  130. package/dist/{expand-D4EhwOYh.cjs.map → expand-CiQkzth9.cjs.map} +1 -1
  131. package/dist/expand.cjs +1 -1
  132. package/dist/expand.js +1 -1
  133. package/dist/float-Bu_IfKRd.cjs +1 -0
  134. package/dist/{float-B8EPc_OG.cjs.map → float-Bu_IfKRd.cjs.map} +1 -1
  135. package/dist/{float-BvI3HTtB.js → float-DwBMXhek.js} +2 -2
  136. package/dist/{float-BvI3HTtB.js.map → float-DwBMXhek.js.map} +1 -1
  137. package/dist/float.cjs +1 -1
  138. package/dist/float.js +1 -1
  139. package/dist/{form-FtYtZScl.js → form-B9Je2W_m.js} +15 -95
  140. package/dist/form-B9Je2W_m.js.map +1 -0
  141. package/dist/{form-SHg5FLsd.cjs → form-BnbAVZyf.cjs} +4 -19
  142. package/dist/form-BnbAVZyf.cjs.map +1 -0
  143. package/dist/form.cjs +18 -1
  144. package/dist/form.cjs.map +1 -0
  145. package/dist/form.js +93 -9
  146. package/dist/form.js.map +1 -0
  147. package/dist/gravity-6pL6CfIr.cjs.map +1 -1
  148. package/dist/gravity-sVK3zGBF.js.map +1 -1
  149. package/dist/handover/agent-runtime-followups.md +1 -1
  150. package/dist/handover/agent-runtime-v1.md +3 -3
  151. package/dist/hashContent-BqU6v1Xr.js.map +1 -1
  152. package/dist/hashContent-iRZJJWtE.cjs.map +1 -1
  153. package/dist/{icon-CgIXAvKI.cjs → icons-BfWQl5k5.cjs} +6 -6
  154. package/dist/icons-BfWQl5k5.cjs.map +1 -0
  155. package/dist/{icon-B1eZr2ZL.js → icons-DJHPXKgR.js} +4 -4
  156. package/dist/{icon-CgIXAvKI.cjs.map → icons-DJHPXKgR.js.map} +1 -1
  157. package/dist/icons.cjs +1 -1
  158. package/dist/icons.js +1 -1
  159. package/dist/{iframe-CmpAZc61.js → iframe-DLz8ll0s.js} +5 -5
  160. package/dist/{iframe-CmpAZc61.js.map → iframe-DLz8ll0s.js.map} +1 -1
  161. package/dist/{iframe-BO3BpRLH.cjs → iframe-UtczJypj.cjs} +5 -5
  162. package/dist/{iframe-BO3BpRLH.cjs.map → iframe-UtczJypj.cjs.map} +1 -1
  163. package/dist/iframe.cjs +1 -1
  164. package/dist/iframe.js +1 -1
  165. package/dist/index.cjs +1 -1
  166. package/dist/index.js +69 -69
  167. package/dist/{input-_Hft9vov.js → input-AQbBEj2f.js} +15 -15
  168. package/dist/{input-_Hft9vov.js.map → input-AQbBEj2f.js.map} +1 -1
  169. package/dist/{input-5YL2oUBr.cjs → input-Pp6A1m3s.cjs} +2 -2
  170. package/dist/{input-5YL2oUBr.cjs.map → input-Pp6A1m3s.cjs.map} +1 -1
  171. package/dist/{input-chip-DKMNpcED.cjs → input-chip-B5vYNuEm.cjs} +9 -9
  172. package/dist/{input-chip-DKMNpcED.cjs.map → input-chip-B5vYNuEm.cjs.map} +1 -1
  173. package/dist/{input-chip-BNTojQT6.js → input-chip-Bbs_gXOB.js} +10 -10
  174. package/dist/{input-chip-BNTojQT6.js.map → input-chip-Bbs_gXOB.js.map} +1 -1
  175. package/dist/input.cjs +1 -1
  176. package/dist/input.js +1 -1
  177. package/dist/json.cjs +3 -3
  178. package/dist/json.cjs.map +1 -1
  179. package/dist/json.js +5 -5
  180. package/dist/json.js.map +1 -1
  181. package/dist/kbd.cjs +2 -2
  182. package/dist/kbd.cjs.map +1 -1
  183. package/dist/kbd.js +5 -5
  184. package/dist/kbd.js.map +1 -1
  185. package/dist/{layout-DSAjo92m.js → layout-9K1zxhZn.js} +1 -1
  186. package/dist/{layout-DSAjo92m.js.map → layout-9K1zxhZn.js.map} +1 -1
  187. package/dist/{layout-eXb9wjDh.cjs → layout-B0dct--7.cjs} +1 -1
  188. package/dist/{layout-eXb9wjDh.cjs.map → layout-B0dct--7.cjs.map} +1 -1
  189. package/dist/layout.cjs +2 -2
  190. package/dist/layout.cjs.map +1 -1
  191. package/dist/layout.js +7 -7
  192. package/dist/layout.js.map +1 -1
  193. package/dist/lazy-CayEFyC3.cjs.map +1 -1
  194. package/dist/lazy-D-bO2r4m.js.map +1 -1
  195. package/dist/{lightbox-t4dvb8_A.cjs → lightbox-D_EizrG3.cjs} +21 -21
  196. package/dist/{lightbox-t4dvb8_A.cjs.map → lightbox-D_EizrG3.cjs.map} +1 -1
  197. package/dist/{lightbox-CKlYcnHV.js → lightbox-DmJTs2My.js} +9 -9
  198. package/dist/{lightbox-CKlYcnHV.js.map → lightbox-DmJTs2My.js.map} +1 -1
  199. package/dist/lightbox.cjs +1 -1
  200. package/dist/lightbox.js +1 -1
  201. package/dist/{list-21mWtDKg.cjs → list-BSn8czyO.cjs} +5 -5
  202. package/dist/{list-21mWtDKg.cjs.map → list-BSn8czyO.cjs.map} +1 -1
  203. package/dist/{list-B6QhxgRJ.js → list-DjSSRZxF.js} +12 -12
  204. package/dist/{list-B6QhxgRJ.js.map → list-DjSSRZxF.js.map} +1 -1
  205. package/dist/list.cjs +1 -1
  206. package/dist/list.js +1 -1
  207. package/dist/magnetic-B2VKNfDu.js.map +1 -1
  208. package/dist/magnetic-MQ3HMHJi.cjs.map +1 -1
  209. package/dist/{menu-C5qcgMnw.js → menu-CCVEde6u.js} +7 -7
  210. package/dist/{menu-C5qcgMnw.js.map → menu-CCVEde6u.js.map} +1 -1
  211. package/dist/menu-DTNnq7j_.cjs +23 -0
  212. package/dist/{menu-Cuxt5K4Y.cjs.map → menu-DTNnq7j_.cjs.map} +1 -1
  213. package/dist/menu.cjs +1 -1
  214. package/dist/menu.js +1 -1
  215. package/dist/mixins-BYfSDvbP.js +412 -0
  216. package/dist/mixins-BYfSDvbP.js.map +1 -0
  217. package/dist/mixins-YQI9JogS.cjs +245 -0
  218. package/dist/mixins-YQI9JogS.cjs.map +1 -0
  219. package/dist/mixins.cjs +1 -1
  220. package/dist/mixins.js +3 -2
  221. package/dist/nav-drawer.cjs +1 -1
  222. package/dist/nav-drawer.js +1 -1
  223. package/dist/navigation-bar.cjs +1 -1
  224. package/dist/navigation-bar.js +1 -1
  225. package/dist/navigation-rail.cjs +10 -10
  226. package/dist/navigation-rail.cjs.map +1 -1
  227. package/dist/navigation-rail.js +15 -15
  228. package/dist/navigation-rail.js.map +1 -1
  229. package/dist/{notification-CDKBKh63.js → notification-BNEuu3Q2.js} +7 -7
  230. package/dist/{notification-CDKBKh63.js.map → notification-BNEuu3Q2.js.map} +1 -1
  231. package/dist/notification-RhaYvA1I.cjs +24 -0
  232. package/dist/{notification-CcNoBFEJ.cjs.map → notification-RhaYvA1I.cjs.map} +1 -1
  233. package/dist/notification.cjs +1 -1
  234. package/dist/notification.js +1 -1
  235. package/dist/{option-BWfmDJvm.js → option-BLMYRy5C.js} +6 -6
  236. package/dist/{option-BWfmDJvm.js.map → option-BLMYRy5C.js.map} +1 -1
  237. package/dist/{option-DejeqOad.cjs → option-Dk7UFFlr.cjs} +5 -5
  238. package/dist/{option-DejeqOad.cjs.map → option-Dk7UFFlr.cjs.map} +1 -1
  239. package/dist/option.cjs +1 -1
  240. package/dist/option.js +1 -1
  241. package/dist/overlay-BbntqsVm.cjs +43 -0
  242. package/dist/overlay-BbntqsVm.cjs.map +1 -0
  243. package/dist/{overlay-D3c_NY18.js → overlay-CujzmLxg.js} +93 -144
  244. package/dist/overlay-CujzmLxg.js.map +1 -0
  245. package/dist/overlay-stack-Bdr9lOqi.cjs.map +1 -1
  246. package/dist/overlay-stack-D2rgxQLh.js.map +1 -1
  247. package/dist/overlay.cjs +1 -1
  248. package/dist/overlay.confirm-body-CMge0LP5.cjs +70 -0
  249. package/dist/overlay.confirm-body-CMge0LP5.cjs.map +1 -0
  250. package/dist/{overlay.confirm-body-B_v0ivkn.js → overlay.confirm-body-CRk4MvKh.js} +15 -27
  251. package/dist/overlay.confirm-body-CRk4MvKh.js.map +1 -0
  252. package/dist/overlay.js +3 -3
  253. package/dist/{overlay.service-B3FjXCqc.js → overlay.service-DnT4SBlJ.js} +31 -27
  254. package/dist/{overlay.service-B3FjXCqc.js.map → overlay.service-DnT4SBlJ.js.map} +1 -1
  255. package/dist/overlay.service-Dq5XtSEL.cjs +1 -0
  256. package/dist/{overlay.service-BkSeqXIv.cjs.map → overlay.service-Dq5XtSEL.cjs.map} +1 -1
  257. package/dist/{progress-6_rb3Ah9.cjs → progress-Bqd4DdOQ.cjs} +7 -7
  258. package/dist/{progress-6_rb3Ah9.cjs.map → progress-Bqd4DdOQ.cjs.map} +1 -1
  259. package/dist/{progress-CFcmO0wv.js → progress-Cu_wh6Sl.js} +10 -10
  260. package/dist/{progress-CFcmO0wv.js.map → progress-Cu_wh6Sl.js.map} +1 -1
  261. package/dist/progress.cjs +1 -1
  262. package/dist/progress.js +1 -1
  263. package/dist/radio-group-C8rUbYL6.cjs +19 -0
  264. package/dist/{radio-group-_WZg8EKM.cjs.map → radio-group-C8rUbYL6.cjs.map} +1 -1
  265. package/dist/{radio-group-Bd8y9QpX.js → radio-group-Duzgx17I.js} +7 -7
  266. package/dist/{radio-group-Bd8y9QpX.js.map → radio-group-Duzgx17I.js.map} +1 -1
  267. package/dist/radio-group.cjs +1 -1
  268. package/dist/radio-group.js +1 -1
  269. package/dist/range.cjs +2 -2
  270. package/dist/range.cjs.map +1 -1
  271. package/dist/range.js +5 -5
  272. package/dist/range.js.map +1 -1
  273. package/dist/reduced-motion-D-L12p7G.js.map +1 -1
  274. package/dist/reduced-motion-Ds-HjMzn.cjs.map +1 -1
  275. package/dist/rxjs-utils-Csnks202.cjs.map +1 -1
  276. package/dist/rxjs-utils-d-ivVN84.js.map +1 -1
  277. package/dist/search-DPKoC-dT.cjs.map +1 -1
  278. package/dist/search-MvIBA93K.js.map +1 -1
  279. package/dist/{select-Czpl1ztD.js → select-CzCv1f1c.js} +6 -6
  280. package/dist/{select-Czpl1ztD.js.map → select-CzCv1f1c.js.map} +1 -1
  281. package/dist/{select-BaioT3yY.cjs → select-DdqEsfnG.cjs} +2 -2
  282. package/dist/{select-BaioT3yY.cjs.map → select-DdqEsfnG.cjs.map} +1 -1
  283. package/dist/select.cjs +1 -1
  284. package/dist/select.js +1 -1
  285. package/dist/skeleton.cjs +2 -2
  286. package/dist/skeleton.cjs.map +1 -1
  287. package/dist/skeleton.js +5 -5
  288. package/dist/skeleton.js.map +1 -1
  289. package/dist/skills/form.md +34 -0
  290. package/dist/skills/schmancy/form.md +34 -0
  291. package/dist/slider.cjs +7 -7
  292. package/dist/slider.cjs.map +1 -1
  293. package/dist/slider.js +6 -6
  294. package/dist/slider.js.map +1 -1
  295. package/dist/{sound.service-v_jqCkos.js → sound.service-BOWTBG16.js} +1 -1
  296. package/dist/{sound.service-v_jqCkos.js.map → sound.service-BOWTBG16.js.map} +1 -1
  297. package/dist/{sound.service-DVJZb9ox.cjs → sound.service-BwIzAFQx.cjs} +1 -1
  298. package/dist/{sound.service-DVJZb9ox.cjs.map → sound.service-BwIzAFQx.cjs.map} +1 -1
  299. package/dist/{splash-screen-YtTVkJg8.js → splash-screen-Dj-zuGuB.js} +6 -6
  300. package/dist/{splash-screen-YtTVkJg8.js.map → splash-screen-Dj-zuGuB.js.map} +1 -1
  301. package/dist/splash-screen-_KhxgneW.cjs +41 -0
  302. package/dist/{splash-screen-3FtgdVy3.cjs.map → splash-screen-_KhxgneW.cjs.map} +1 -1
  303. package/dist/splash-screen.cjs +1 -1
  304. package/dist/splash-screen.js +1 -1
  305. package/dist/src-BSjgxN07.cjs +263 -0
  306. package/dist/{src-AYRNg63f.cjs.map → src-BSjgxN07.cjs.map} +1 -1
  307. package/dist/{src-DKMEgT2z.js → src-Curgs4Yp.js} +83 -83
  308. package/dist/{src-DKMEgT2z.js.map → src-Curgs4Yp.js.map} +1 -1
  309. package/dist/state-BthYuA3T.cjs +1 -0
  310. package/dist/state-BthYuA3T.cjs.map +1 -0
  311. package/dist/{state-CHbIt2Dw.js → state-E0bVrZ7q.js} +293 -279
  312. package/dist/state-E0bVrZ7q.js.map +1 -0
  313. package/dist/state.cjs +1 -1
  314. package/dist/state.js +3 -3
  315. package/dist/steps.cjs +10 -10
  316. package/dist/steps.cjs.map +1 -1
  317. package/dist/steps.js +9 -9
  318. package/dist/steps.js.map +1 -1
  319. package/dist/{surface-CVxyQPln.js → surface-C2TIedTq.js} +4 -4
  320. package/dist/{surface-CVxyQPln.js.map → surface-C2TIedTq.js.map} +1 -1
  321. package/dist/surface-D-GqzyLn.cjs +7 -0
  322. package/dist/{surface-BNvxLEDN.cjs.map → surface-D-GqzyLn.cjs.map} +1 -1
  323. package/dist/surface.cjs +1 -1
  324. package/dist/surface.js +1 -1
  325. package/dist/switch.cjs +2 -2
  326. package/dist/switch.cjs.map +1 -1
  327. package/dist/switch.js +6 -6
  328. package/dist/switch.js.map +1 -1
  329. package/dist/table.cjs +11 -11
  330. package/dist/table.cjs.map +1 -1
  331. package/dist/table.js +10 -10
  332. package/dist/table.js.map +1 -1
  333. package/dist/{tabs-CnPXvZuZ.js → tabs-CLRVe23a.js} +11 -11
  334. package/dist/{tabs-CnPXvZuZ.js.map → tabs-CLRVe23a.js.map} +1 -1
  335. package/dist/{tabs-DTU7748z.cjs → tabs-C_493iod.cjs} +4 -4
  336. package/dist/{tabs-DTU7748z.cjs.map → tabs-C_493iod.cjs.map} +1 -1
  337. package/dist/tabs.cjs +1 -1
  338. package/dist/tabs.js +1 -1
  339. package/dist/teleport.cjs +1 -1
  340. package/dist/teleport.js +1 -1
  341. package/dist/{textarea-mQPsppmd.js → textarea-BWEyOtPy.js} +9 -9
  342. package/dist/{textarea-mQPsppmd.js.map → textarea-BWEyOtPy.js.map} +1 -1
  343. package/dist/textarea-CICgd2oP.cjs +43 -0
  344. package/dist/{textarea-Bqth6Q8P.cjs.map → textarea-CICgd2oP.cjs.map} +1 -1
  345. package/dist/textarea.cjs +1 -1
  346. package/dist/textarea.js +1 -1
  347. package/dist/{theme-BJqpv4cG.js → theme-Bfg_H2AF.js} +12 -12
  348. package/dist/{theme-BJqpv4cG.js.map → theme-Bfg_H2AF.js.map} +1 -1
  349. package/dist/theme-D7zOJiyg.cjs +181 -0
  350. package/dist/{theme-D4HGKt7N.cjs.map → theme-D7zOJiyg.cjs.map} +1 -1
  351. package/dist/{theme-button-Jap7G_IH.js → theme-button-C53GdQER.js} +4 -4
  352. package/dist/{theme-button-Jap7G_IH.js.map → theme-button-C53GdQER.js.map} +1 -1
  353. package/dist/theme-button-DgeBcqFm.cjs +8 -0
  354. package/dist/{theme-button-LP-Dgr17.cjs.map → theme-button-DgeBcqFm.cjs.map} +1 -1
  355. package/dist/theme-button.cjs +1 -1
  356. package/dist/theme-button.js +1 -1
  357. package/dist/theme.cjs +1 -1
  358. package/dist/theme.interface-CSt7JUBD.cjs.map +1 -1
  359. package/dist/theme.interface-odQEpZZH.js.map +1 -1
  360. package/dist/theme.js +3 -3
  361. package/dist/{theme.service-Bh08uOSJ.js → theme.service-BqDuioYc.js} +1 -1
  362. package/dist/{theme.service-Bh08uOSJ.js.map → theme.service-BqDuioYc.js.map} +1 -1
  363. package/dist/{theme.service-Y-e8b331.cjs → theme.service-C3PoISGd.cjs} +1 -1
  364. package/dist/{theme.service-Y-e8b331.cjs.map → theme.service-C3PoISGd.cjs.map} +1 -1
  365. package/dist/tooltip.cjs.map +1 -1
  366. package/dist/tooltip.js.map +1 -1
  367. package/dist/tree.cjs +3 -3
  368. package/dist/tree.cjs.map +1 -1
  369. package/dist/tree.js +4 -4
  370. package/dist/tree.js.map +1 -1
  371. package/dist/types.cjs.map +1 -1
  372. package/dist/types.js.map +1 -1
  373. package/dist/typewriter.cjs.map +1 -1
  374. package/dist/typewriter.js.map +1 -1
  375. package/dist/{typography-Bc4MmSal.cjs → typography-B19fJ5YT.cjs} +4 -4
  376. package/dist/{typography-Bc4MmSal.cjs.map → typography-B19fJ5YT.cjs.map} +1 -1
  377. package/dist/{typography-BJMm6b0b.js → typography-CzbQv-X0.js} +10 -10
  378. package/dist/{typography-BJMm6b0b.js.map → typography-CzbQv-X0.js.map} +1 -1
  379. package/dist/typography.cjs +1 -1
  380. package/dist/typography.js +1 -1
  381. package/dist/utils-DTa3QHxk.cjs.map +1 -1
  382. package/dist/utils-H8wNknWC.js.map +1 -1
  383. package/dist/visually-hidden.cjs +2 -2
  384. package/dist/visually-hidden.cjs.map +1 -1
  385. package/dist/visually-hidden.js +4 -4
  386. package/dist/visually-hidden.js.map +1 -1
  387. package/dist/window-DXB53PuA.cjs +59 -0
  388. package/dist/{window-CNu_WnsY.cjs.map → window-DXB53PuA.cjs.map} +1 -1
  389. package/dist/{window-DZTjkE24.js → window-DpctMXiy.js} +9 -9
  390. package/dist/{window-DZTjkE24.js.map → window-DpctMXiy.js.map} +1 -1
  391. package/dist/window.cjs +1 -1
  392. package/dist/window.js +1 -1
  393. package/package.json +1 -1
  394. package/skills/schmancy/form.md +34 -0
  395. package/src/form/form.ts +5 -1
  396. package/src/overlay/overlay.animations.ts +0 -29
  397. package/src/overlay/overlay.component.ts +30 -38
  398. package/src/overlay/overlay.confirm-body.ts +3 -15
  399. package/src/overlay/overlay.layout.ts +11 -53
  400. package/src/overlay/overlay.stack.test.ts +113 -0
  401. package/src/overlay/overlay.types.ts +17 -11
  402. package/src/state/active-host.ts +50 -1
  403. package/src/state/index.ts +50 -11
  404. package/src/state/schmancy-context.ts +97 -88
  405. package/src/surface/surface.styles.ts +14 -10
  406. package/types/src/form/form.d.ts +1 -0
  407. package/types/src/overlay/overlay.confirm-body.d.ts +1 -1
  408. package/types/src/overlay/overlay.layout.d.ts +10 -30
  409. package/types/src/overlay/overlay.stack.test.d.ts +1 -0
  410. package/types/src/overlay/overlay.types.d.ts +17 -11
  411. package/types/src/state/active-host.d.ts +3 -0
  412. package/types/src/state/index.d.ts +16 -2
  413. package/types/src/state/schmancy-context.d.ts +2 -2
  414. package/dist/active-host-BP0zy_Y9.js +0 -63
  415. package/dist/active-host-BP0zy_Y9.js.map +0 -1
  416. package/dist/active-host-jH3iloCR.cjs +0 -1
  417. package/dist/active-host-jH3iloCR.cjs.map +0 -1
  418. package/dist/agent/overlay.confirm-body-BZoUgkdK.js +0 -4574
  419. package/dist/agent/overlay.confirm-body-BZoUgkdK.js.map +0 -1
  420. package/dist/area-BSVOYQDA.cjs +0 -21
  421. package/dist/date-range-inline-nPWIs-3C.cjs +0 -43
  422. package/dist/float-B8EPc_OG.cjs +0 -1
  423. package/dist/form-FtYtZScl.js.map +0 -1
  424. package/dist/form-SHg5FLsd.cjs.map +0 -1
  425. package/dist/icon-B1eZr2ZL.js.map +0 -1
  426. package/dist/menu-Cuxt5K4Y.cjs +0 -23
  427. package/dist/mixins-8dT5j6CS.js +0 -627
  428. package/dist/mixins-8dT5j6CS.js.map +0 -1
  429. package/dist/mixins-BF3Vj8_c.cjs +0 -242
  430. package/dist/mixins-BF3Vj8_c.cjs.map +0 -1
  431. package/dist/notification-CcNoBFEJ.cjs +0 -24
  432. package/dist/overlay-D3c_NY18.js.map +0 -1
  433. package/dist/overlay-Dv2utO4C.cjs +0 -43
  434. package/dist/overlay-Dv2utO4C.cjs.map +0 -1
  435. package/dist/overlay.confirm-body-B2ntyquG.cjs +0 -79
  436. package/dist/overlay.confirm-body-B2ntyquG.cjs.map +0 -1
  437. package/dist/overlay.confirm-body-B_v0ivkn.js.map +0 -1
  438. package/dist/overlay.service-BkSeqXIv.cjs +0 -1
  439. package/dist/radio-group-_WZg8EKM.cjs +0 -19
  440. package/dist/splash-screen-3FtgdVy3.cjs +0 -41
  441. package/dist/src-AYRNg63f.cjs +0 -263
  442. package/dist/state-CHbIt2Dw.js.map +0 -1
  443. package/dist/state-DcGj-pJJ.cjs +0 -1
  444. package/dist/state-DcGj-pJJ.cjs.map +0 -1
  445. package/dist/surface-BNvxLEDN.cjs +0 -7
  446. package/dist/textarea-Bqth6Q8P.cjs +0 -43
  447. package/dist/theme-D4HGKt7N.cjs +0 -181
  448. package/dist/theme-button-LP-Dgr17.cjs +0 -8
  449. package/dist/window-CNu_WnsY.cjs +0 -59
  450. /package/dist/agent/{flow-3RrZM-e7.js → flow-CvG1fLW5.js} +0 -0
  451. /package/dist/agent/{vendor-material-color-33Mj762T.js → vendor-material-color-DcL7ZPxx.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"select-BaioT3yY.cjs","names":[],"sources":["../src/form/fields/select/select.ts"],"sourcesContent":["import { autoUpdate, computePosition, flip, offset, shift } from '@floating-ui/dom'\nimport { SchmancyFormField } from '@mixins/index'\nimport { color } from '@schmancy/directives'\nimport SchmancyInput from '@schmancy/input/input'\nimport SchmancyOption from '@schmancy/option/option'\nimport { SchmancyTheme } from '@schmancy/theme/theme.interface'\nimport { css, html, PropertyValues, TemplateResult } from 'lit'\nimport { customElement, property, query, queryAssignedElements, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { BehaviorSubject, combineLatest, fromEvent, Subject, takeUntil } from 'rxjs'\nimport { tap, withLatestFrom } from 'rxjs/operators'\n\nexport type SchmancySelectChangeEvent = CustomEvent<{\n\tvalue: string | string[]\n}>\n\n/**\n * Select dropdown component with single and multi-select support.\n *\n * @prop {string} name - Name attribute for form submission\n * @prop {string} label - Label text displayed above the select\n * @prop {string} placeholder - Placeholder text when no value is selected\n * @prop {boolean} required - Whether the field is required\n * @prop {boolean} multi - Enable multi-select mode\n * @prop {string} value - Selected value (single select mode)\n * @prop {string[]} values - Selected values (multi-select mode)\n */\n@customElement('schmancy-select')\nexport class SchmancySelect extends SchmancyFormField() {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: block;\n\t\tposition: relative;\n\t}\n\n\t[role='listbox'] {\n\t\toverflow-y: auto;\n\t\toutline: none;\n\t}\n`]\n\n\t// FACE wiring (formAssociated, internals, attachInternals) comes from\n\t// SchmancyFormField. Same for: name, required, disabled, validationMessage,\n\t// validateOn, touched/dirty/pristine/submitted, markTouched/markSubmitted,\n\t// formResetCallback, formDisabledCallback, FIELD_CONNECT_EVENT dispatch.\n\n\t@property({ type: String }) placeholder = ''\n\n\t// Override `value` with the narrowed select-specific type and a custom\n\t// getter/setter pair backed by reactive subjects.\n\t@property({ type: String, reflect: true })\n\toverride get value(): string | string[] {\n\t\treturn this.multi\n\t\t\t? (this._selectedValues$?.value ?? [])\n\t\t\t: (this._selectedValue$?.value ?? '')\n\t}\n\toverride set value(val: string | string[]) {\n\t\tif (!this._selectedValue$ || !this._selectedValues$) return\n\t\tif (this.multi) {\n\t\t\tconst values = Array.isArray(val)\n\t\t\t\t? val\n\t\t\t\t: val ? String(val).split(',').map(v => v.trim()).filter(Boolean) : []\n\t\t\tthis._selectedValues$.next(values)\n\t\t} else {\n\t\t\tthis._selectedValue$.next(val == null ? '' : String(val))\n\t\t}\n\t}\n\n\t// Values property for multi-select mode\n\t@property({ type: Array })\n\tget values() {\n\t\treturn [...this._selectedValues$.value]\n\t}\n\tset values(vals: string[]) {\n\t\tthis._selectedValues$.next(Array.isArray(vals) ? [...vals] : [])\n\t}\n\n\t@property({ type: Boolean }) multi = false\n\t// `label` and `hint` come from the mixin.\n\t// M3 aligned sizes: 24dp (xxs) → 32dp (xs) → 40dp (sm) → 48dp (md) → 56dp (lg)\n\t@property({ type: String }) size: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' = 'md'\n\n\t// Internal states\n\t@state() private isOpen = false\n\t@state() private valueLabel = ''\n\t@state() private isValid = true\n\n\t// Store the initial/default value for reset behavior. Distinct from the\n\t// mixin's `_defaultValue` (which is `string` only); select needs the wider\n\t// shape so resetForm can restore arrays for multi-select.\n\t@state() private selectDefaultValue: string | string[] = ''\n\n\t@query('ul') private ul!: HTMLUListElement\n\t@query('sch-input') private inputRef!: SchmancyInput\n\t@queryAssignedElements({ flatten: true }) private options!: SchmancyOption[]\n\tprivate cleanupPositioner?: () => void\n\n\t// Reactive state management\n\tprivate _options$ = new BehaviorSubject<SchmancyOption[]>([])\n\tprivate _selectedValue$ = new BehaviorSubject<string>('')\n\tprivate _selectedValues$ = new BehaviorSubject<string[]>([])\n\tprivate _optionSelect$ = new Subject<SchmancyOption>()\n\n\t/**\n\t * Tracks whether the user has actively interacted (clicked/typed/keyed\n\t * inside the dropdown). Distinct from the mixin's `touched` (which fires on\n\t * blur). Used to gate dropdown-positioning side-effects on user-driven\n\t * actions versus programmatic state changes.\n\t */\n\t@state() _userInteracted = false\n\n\t// Reference to current focused option (for keyboard navigation)\n\t@state() private _focusedOptionId = ''\n\n\toverride connectedCallback() {\n\t\tsuper.connectedCallback()\n\t\tif (!this.id) {\n\t\t\tthis.id = `schmancy-select-${Math.random().toString(36).substring(2, 9)}`\n\t\t}\n\n\t\t// Store initial value for reset\n\t\tthis.selectDefaultValue = this.value\n\n\t\t// Add keyboard handling to host element\n\t\tfromEvent<KeyboardEvent>(this, 'keydown').pipe(takeUntil(this.disconnecting)).subscribe(this.handleKeyDown)\n\n\t\t// Setup reactive pipelines\n\t\tthis._setupReactivePipelines()\n\t}\n\n\toverride disconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis.cleanupPositioner?.()\n\t\t// Form event listeners are automatically cleaned up via takeUntil(this.disconnecting)\n\t}\n\n\tfirstUpdated() {\n\t\tthis.syncSelection()\n\t\tthis.setupOptionsAccessibility()\n\n\t\t// Initially hide any validation errors until user interacts\n\t\tif (this.inputRef) {\n\t\t\tthis.inputRef.error = false\n\t\t}\n\t}\n\n\toverride updated(changedProps: PropertyValues) {\n\t\tsuper.updated(changedProps)\n\n\t\tif (changedProps.has('value')) {\n\t\t\t// Multi-select serializes to a comma-joined scalar on FormData; the\n\t\t\t// mixin's willUpdate already called setFormValue with the raw\n\t\t\t// value, override here for the joined-string shape.\n\t\t\tconst formValue = this.multi\n\t\t\t\t? this._selectedValues$.value.join(',')\n\t\t\t\t: this._selectedValue$.value\n\t\t\tthis.internals?.setFormValue(formValue)\n\n\t\t\t// `dirty` is a mixin getter (value !== _defaultValue); no manual flag.\n\t\t\t// Mixin's willUpdate already calls checkValidity when _shouldShowError().\n\t\t}\n\n\t\t// When open state changes, setup or cleanup the dropdown positioner\n\t\tif (changedProps.has('isOpen')) {\n\t\t\tif (this.isOpen) {\n\t\t\t\tthis.positionDropdown()\n\t\t\t} else {\n\t\t\t\tthis.cleanupPositioner?.()\n\t\t\t}\n\t\t}\n\t}\n\n\t// `shouldShowValidation` removed — replaced by mixin's `_shouldShowError()`.\n\n\tprivate syncSelection() {\n\t\tif (this.multi) {\n\t\t\t// Read directly from the BehaviorSubject to avoid string conversion issues\n\t\t\tconst selectedValues = this._selectedValues$.value\n\t\t\tthis.options?.forEach(o => (o.selected = selectedValues.includes(o.value))) // Update option selected state\n\t\t\tthis.valueLabel =\n\t\t\t\tselectedValues.length > 0\n\t\t\t\t\t? this.options\n\t\t\t\t\t\t\t?.filter(o => selectedValues.includes(o.value))\n\t\t\t\t\t\t\t.map(o => o.label || o.textContent || '')\n\t\t\t\t\t\t\t.join(', ') || this.placeholder\n\t\t\t\t\t: this.placeholder\n\t\t} else {\n\t\t\t// Single select - read from BehaviorSubject\n\t\t\tconst currentValue = this._selectedValue$.value\n\t\t\tthis.options?.forEach(o => {\n\t\t\t\t// Set selected property on each option based on matching value\n\t\t\t\to.selected = o.value === currentValue\n\t\t\t})\n\t\t\tconst selectedOption = this.options?.find(o => o.value === currentValue)\n\t\t\tthis.valueLabel = selectedOption ? (selectedOption.label || selectedOption.textContent || '') : this.placeholder\n\t\t}\n\t}\n\n\tprivate setupOptionsAccessibility() {\n\t\tthis.options?.forEach((option, index) => {\n\t\t\toption.setAttribute('role', 'option')\n\t\t\tif (!option.id) {\n\t\t\t\toption.id = `${this.id}-option-${index}`\n\t\t\t}\n\n\t\t\t// Set tabindex to -1 so they're focusable programmatically but not in the tab order\n\t\t\toption.tabIndex = -1\n\n\t\t\toption.setAttribute(\n\t\t\t\t'aria-selected',\n\t\t\t\tString(this.multi ? this._selectedValues$.value.includes(option.value) : option.value === this._selectedValue$.value),\n\t\t\t)\n\t\t})\n\t}\n\n\tprivate async positionDropdown() {\n\t\tconst reference = this.renderRoot.querySelector('.trigger') as HTMLElement\n\t\tif (!reference || !this.ul) return\n\n\t\tthis.cleanupPositioner = autoUpdate(reference, this.ul, async () => {\n\t\t\t// Get viewport dimensions\n\t\t\tconst viewportHeight = window.innerHeight\n\t\t\tconst triggerRect = reference.getBoundingClientRect()\n\n\t\t\t// Calculate available space below and above\n\t\t\tconst spaceBelow = viewportHeight - triggerRect.bottom\n\t\t\tconst spaceAbove = triggerRect.top\n\n\t\t\t// Calculate max height - use 75% of the largest available space, but at least 150px\n\t\t\tconst maxHeight = Math.max(Math.max(spaceBelow, spaceAbove) * 0.75, 150)\n\n\t\t\t// Determine if we should flip\n\t\t\tconst shouldFlip = spaceBelow < 200 && spaceAbove > spaceBelow\n\n\t\t\t// Apply max height\n\t\t\tthis.ul.style.maxHeight = `${maxHeight}px`\n\n\t\t\tconst { x, y } = await computePosition(reference, this.ul, {\n\t\t\t\tplacement: shouldFlip ? 'top-start' : 'bottom-start',\n\t\t\t\tmiddleware: [offset(5), flip(), shift({ padding: 5 })],\n\t\t\t})\n\n\t\t\tObject.assign(this.ul.style, {\n\t\t\t\tleft: `${x}px`,\n\t\t\t\ttop: `${y}px`,\n\t\t\t\tposition: 'absolute',\n\t\t\t\twidth: `${reference.offsetWidth}px`, // Match the width of the trigger\n\t\t\t})\n\t\t})\n\t}\n\n\tprivate handleKeyDown = (e: KeyboardEvent) => {\n\t\t// Don't handle keyboard events when disabled\n\t\tif (this.disabled) {\n\t\t\treturn\n\t\t}\n\n\t\tif (!this.isOpen) {\n\t\t\tif (['Enter', ' ', 'ArrowDown'].includes(e.key)) {\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.openDropdown(false)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\t// Find current focused option\n\t\tconst options = Array.from(this.options || [])\n\t\tconst current = options.findIndex(o => o.id === this._focusedOptionId) ?? -1\n\n\t\tswitch (e.key) {\n\t\t\tcase 'Escape':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.closeDropdown()\n\t\t\t\tbreak\n\t\t\tcase 'ArrowDown':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.focusOption(options, Math.min(current + 1, options.length - 1))\n\t\t\t\tbreak\n\t\t\tcase 'ArrowUp':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.focusOption(options, Math.max(current - 1, 0))\n\t\t\t\tbreak\n\t\t\tcase 'Home':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.focusOption(options, 0)\n\t\t\t\tbreak\n\t\t\tcase 'End':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.focusOption(options, options.length - 1)\n\t\t\t\tbreak\n\t\t\tcase 'Enter':\n\t\t\tcase ' ':\n\t\t\t\te.preventDefault()\n\t\t\t\tif (this._focusedOptionId) {\n\t\t\t\t\tconst focusedOption = options.find(opt => opt.id === this._focusedOptionId)\n\t\t\t\t\tif (focusedOption) {\n\t\t\t\t\t\tthis.handleOptionSelect(focusedOption.value)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'Tab':\n\t\t\t\tthis.closeDropdown()\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tprivate focusOption(options: SchmancyOption[], index: number) {\n\t\tconst option = options[index]\n\t\tif (option) {\n\t\t\toption.focus()\n\t\t\tthis._focusedOptionId = option.id\n\n\t\t\t// Update aria-activedescendant on the combobox\n\t\t\tconst combobox = this.renderRoot.querySelector('.trigger')\n\t\t\tif (combobox) {\n\t\t\t\tcombobox.setAttribute('aria-activedescendant', option.id)\n\t\t\t}\n\n\t\t\t// Ensure option is visible in the scrollable area\n\t\t\tif (this.ul && option.offsetTop !== undefined) {\n\t\t\t\t// Get position info\n\t\t\t\tconst optionTop = option.offsetTop\n\t\t\t\tconst optionHeight = option.offsetHeight\n\t\t\t\tconst scrollTop = this.ul.scrollTop\n\t\t\t\tconst ulHeight = this.ul.clientHeight\n\n\t\t\t\t// Scroll into view if needed\n\t\t\t\tif (optionTop < scrollTop) {\n\t\t\t\t\tthis.ul.scrollTop = optionTop\n\t\t\t\t} else if (optionTop + optionHeight > scrollTop + ulHeight) {\n\t\t\t\t\tthis.ul.scrollTop = optionTop + optionHeight - ulHeight\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async openDropdown(report = false) {\n\t\t// Don't open if disabled\n\t\tif (this.disabled) {\n\t\t\treturn\n\t\t}\n\n\t\t// Don't mark as touched on opening - we'll do that on closing\n\t\t// so errors only show after interaction is complete\n\n\t\tthis.isOpen = true\n\t\tawait this.updateComplete\n\n\t\t// Focus first or selected option\n\t\tconst options = Array.from(this.options || [])\n\t\tconst selectedIndex = this.multi ? 0 : options.findIndex(o => o.value === this._selectedValue$.value)\n\n\t\tthis.focusOption(options, Math.max(selectedIndex, 0))\n\n\t\t// Don't automatically validate when opening\n\t\t// Only validate if explicitly requested (like from a form submission)\n\t\tif (report) this.reportValidity()\n\t}\n\n\tprivate closeDropdown() {\n\t\t// Only mark as touched if the user actually interacted with the component\n\t\t// and made a selection or explicitly closed it without selecting\n\t\tif (this._userInteracted) {\n\t\t\tthis.touched = true\n\t\t}\n\n\t\tthis.isOpen = false\n\t\tthis._focusedOptionId = ''\n\n\t\t// Update combobox to remove aria-activedescendant\n\t\tconst combobox = this.renderRoot.querySelector<HTMLElement>('.trigger')\n\t\tif (combobox) {\n\t\t\tcombobox.removeAttribute('aria-activedescendant')\n\t\t\tcombobox?.focus()\n\t\t}\n\n\t\t// Only check validity when closing if the user has actually interacted\n\t\t// with the component and validation should be shown\n\t\tif (this._userInteracted && this._shouldShowError()) {\n\t\t\tthis.checkValidity()\n\t\t}\n\t}\n\n\tprivate _setupReactivePipelines() {\n\t\t// Listen for option-select events from child options\n\t\tfromEvent<CustomEvent>(this, 'option-select')\n\t\t\t.pipe(\n\t\t\t\ttap((e) => {\n\t\t\t\t\te.stopPropagation() // Prevent event from bubbling further\n\t\t\t\t\tconst option = this.options.find(o => o.value === e.detail.value)\n\t\t\t\t\tif (option) {\n\t\t\t\t\t\tthis._optionSelect$.next(option)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Handle option selection through reactive pipeline\n\t\tthis._optionSelect$\n\t\t\t.pipe(\n\t\t\t\twithLatestFrom(this._selectedValue$, this._selectedValues$),\n\t\t\t\ttap(([option, _, currentValues]) => {\n\t\t\t\t\tthis._userInteracted = true\n\t\t\t\t\tthis.markTouched()\n\t\t\t\t\t// `dirty` is a mixin getter; setting `value` below triggers it\n\n\t\t\t\t\tif (this.multi) {\n\t\t\t\t\t\tconst index = currentValues.indexOf(option.value)\n\t\t\t\t\t\tconst newValues = index > -1\n\t\t\t\t\t\t\t? [...currentValues.slice(0, index), ...currentValues.slice(index + 1)]\n\t\t\t\t\t\t\t: [...currentValues, option.value]\n\t\t\t\t\t\tthis._selectedValues$.next(newValues)\n\n\t\t\t\t\t\t// Update form value\n\t\t\t\t\t\tthis.internals?.setFormValue(newValues.join(','))\n\n\t\t\t\t\t\t// Update display label\n\t\t\t\t\t\tthis.valueLabel = newValues.length > 0\n\t\t\t\t\t\t\t? this.options\n\t\t\t\t\t\t\t\t\t.filter(o => newValues.includes(o.value))\n\t\t\t\t\t\t\t\t\t.map(o => o.label || o.textContent || '')\n\t\t\t\t\t\t\t\t\t.join(', ')\n\t\t\t\t\t\t\t: this.placeholder\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Single select\n\t\t\t\t\t\tthis._selectedValue$.next(option.value)\n\n\t\t\t\t\t\t// Update form value\n\t\t\t\t\t\tthis.internals?.setFormValue(option.value)\n\n\t\t\t\t\t\tthis.valueLabel = option.label || option.textContent || this.placeholder\n\t\t\t\t\t\tthis.closeDropdown()\n\t\t\t\t\t}\n\n\t\t\t\t\t// Update the option's accessibility state\n\t\t\t\t\tthis.setupOptionsAccessibility()\n\n\t\t\t\t\t// Dispatch change event\n\t\t\t\t\tthis._fireChangeEvent()\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Options management pipeline - bind pointerdown events exactly like autocomplete\n\t\tthis._options$\n\t\t\t.pipe(\n\t\t\t\ttap((options) => {\n\t\t\t\t\toptions.forEach((option, index) => {\n\t\t\t\t\t\toption.setAttribute('role', 'option')\n\t\t\t\t\t\toption.tabIndex = -1\n\t\t\t\t\t\tif (!option.id) {\n\t\t\t\t\t\t\toption.id = `${this.id}-option-${index}`\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Use data-event-bound to prevent duplicate bindings\n\t\t\t\t\t\tif (!option.hasAttribute('data-event-bound')) {\n\t\t\t\t\t\t\t// Use click event instead of pointerdown for better mobile UX\n\t\t\t\t\t\t\t// This allows users to scroll through options without immediately selecting\n\t\t\t\t\t\t\tfromEvent(option, 'click').pipe(\n\t\t\t\t\t\t\t\ttap(e => {\n\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t\t\t\t\t).subscribe(() => this._optionSelect$.next(option))\n\t\t\t\t\t\t\toption.setAttribute('data-event-bound', 'true')\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Selection sync pipeline - sync selected states with value changes\n\t\tcombineLatest([this._selectedValue$, this._selectedValues$, this._options$])\n\t\t\t.pipe(\n\t\t\t\ttap(([singleValue, multiValues, options]) => {\n\t\t\t\t\tif (options.length === 0) return\n\n\t\t\t\t\tif (this.multi) {\n\t\t\t\t\t\toptions.forEach(option => {\n\t\t\t\t\t\t\toption.selected = multiValues.includes(option.value)\n\t\t\t\t\t\t})\n\t\t\t\t\t} else {\n\t\t\t\t\t\toptions.forEach(option => {\n\t\t\t\t\t\t\toption.selected = option.value === singleValue\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\tprivate handleOptionSelect(value: string) {\n\t\t// This method is now called from keyboard navigation only\n\t\tconst option = this.options.find(o => o.value === value)\n\t\tif (option) {\n\t\t\tthis._optionSelect$.next(option)\n\t\t}\n\t}\n\n\tprivate _fireChangeEvent() {\n\t\t// Get the current value based on multi/single mode\n\t\tconst value = this.multi ? this._selectedValues$.value : this._selectedValue$.value\n\n\t\t// Dispatch only one change event with the value in detail\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent<SchmancySelectChangeEvent['detail']>('change', {\n\t\t\t\tdetail: { value },\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t}),\n\t\t)\n\n\t\t// Then check validity (only show error if validation should be shown)\n\t\tthis.checkValidity()\n\t}\n\n\tpublic checkValidity(): boolean {\n\t\t// Disabled fields are always valid\n\t\tif (this.disabled) {\n\t\t\treturn true\n\t\t}\n\n\t\t// Determine if the select is empty based on whether it's multi-select or single-select\n\t\tconst isEmpty = this.multi\n\t\t\t? this._selectedValues$.value.length === 0\n\t\t\t: !this._selectedValue$.value\n\n\t\t// Check if the value is valid (not empty when required)\n\t\tconst isValid = !(this.required && isEmpty)\n\n\t\t// Set the validity state\n\t\tthis.isValid = isValid\n\n\t\tif (!this.isValid) {\n\t\t\tthis.validationMessage = 'Please select an option.'\n\t\t\tthis.internals?.setValidity({ valueMissing: true }, 'Please select an option.', this.inputRef)\n\t\t} else {\n\t\t\t// Clear validation message\n\t\t\tthis.validationMessage = ''\n\t\t\tthis.internals?.setValidity({})\n\t\t}\n\n\t\t// Update the input component to reflect our validation state\n\t\tif (this.inputRef && this.hasUpdated) {\n\t\t\tconst showError = !this.isValid && this._shouldShowError()\n\t\t\tthis.inputRef.error = showError\n\t\t\tthis.inputRef.hint = showError ? this.validationMessage : this.hint\n\t\t}\n\n\t\treturn this.isValid\n\t}\n\n\tpublic reportValidity(): boolean {\n\t\t// Force validation display regardless of validation strategy\n\t\tconst valid = this.checkValidity()\n\n\t\t// Force the input to show validation errors\n\t\tif (this.inputRef) {\n\t\t\t// Set the input's error state\n\t\t\tthis.inputRef.error = !valid\n\t\t\tthis.inputRef.hint = !valid ? this.validationMessage : this.hint\n\n\t\t\t// If invalid and not already open, automatically open the dropdown to show options\n\t\t\tif (!valid && !this.isOpen) {\n\t\t\t\t// Open the dropdown but don't mark as user interaction yet\n\t\t\t\t// This helps users immediately see available options when validation fails\n\t\t\t\tthis.openDropdown(false)\n\t\t\t}\n\n\t\t\t// Only call reportValidity on the input if invalid to show the native popup\n\t\t\tif (!valid) {\n\t\t\t\tthis.inputRef.reportValidity()\n\t\t\t}\n\t\t}\n\n\t\treturn valid\n\t}\n\n\t// `markTouched`, `markSubmitted`, `touched`, `dirty`, `pristine`, `submitted`,\n\t// `error` (storage) — all from the mixin. Select's `error` semantics\n\t// (errors-while-open suppression) live in render() via _shouldShowError() +\n\t// !isOpen, not as a separate getter.\n\n\t/**\n\t * Multi-value-aware `toFormEntries`. Single-select emits one `[name,value]`;\n\t * multi-select emits N entries with the same name (canonical FormData shape\n\t * for repeated fields).\n\t */\n\toverride toFormEntries(): Array<[string, FormDataEntryValue]> {\n\t\tif (!this.name || this.disabled) return []\n\t\tconst v = this.value\n\t\tif (v === undefined || v === null || v === '') return []\n\t\tif (Array.isArray(v))\n\t\t\treturn v.map(item => [this.name, String(item)] as [string, FormDataEntryValue])\n\t\treturn [[this.name, String(v)]]\n\t}\n\n\toverride setCustomValidity(message: string) {\n\t\tthis.validationMessage = message\n\t\tif (message) {\n\t\t\tthis.isValid = false\n\t\t\tthis.internals?.setValidity({ customError: true }, message, this.inputRef)\n\t\t} else {\n\t\t\tthis.isValid = true\n\t\t\tthis.internals?.setValidity({})\n\t\t}\n\n\t\t// Update input if needed\n\t\tif (this.inputRef && this._shouldShowError()) {\n\t\t\tthis.inputRef.error = !this.isValid\n\t\t\tthis.inputRef.hint = !this.isValid ? this.validationMessage : this.hint\n\t\t}\n\t}\n\n\t/**\n\t * Reset to the snapshot captured at connect time. Mixin's `resetForm`\n\t * handles touched/submitted/error/validationMessage; the override layers on\n\t * select-specific cleanup (value subjects, label, validity).\n\t */\n\toverride resetForm(): void {\n\t\t// Restore value (multi-aware) before super so the mixin's _defaultValue\n\t\t// reset doesn't clobber the array-shape we need.\n\t\tthis.value = this.selectDefaultValue\n\t\tthis.valueLabel = this.placeholder\n\t\tthis.isValid = true\n\t\tthis._userInteracted = false\n\t\tthis.internals?.setValidity({})\n\t\tsuper.resetForm()\n\t\tif (this.inputRef) {\n\t\t\tthis.inputRef.error = false\n\t\t\tthis.inputRef.hint = this.hint\n\t\t}\n\t}\n\n\t/** Back-compat alias for callers that used the previous public API. */\n\tpublic reset(): void {\n\t\tthis.resetForm()\n\t}\n\n\trender(): TemplateResult {\n\t\t// Determine if we should show errors based on the validation strategy and interaction\n\t\t// Never show errors on initial render or if the dropdown is open\n\t\tconst showErrors = !this.isValid && this._shouldShowError() && !this.isOpen\n\n\t\t// Add caret icon based on open state\n\t\tconst caretIcon = this.isOpen\n\t\t\t? html`<span class=\"absolute right-3 top-1/2 transform -translate-y-1/2\">▲</span>`\n\t\t\t: html`<span class=\"absolute right-3 top-1/2 transform -translate-y-1/2\">▼</span>`\n\n\t\treturn html`\n\t\t\t<div class=\"relative ${this.disabled ? 'opacity-60 cursor-not-allowed' : ''}\">\n\t\t\t\t<sch-input\n\t\t\t\t\t.name=${this.name ?? ''}\n\t\t\t\t\ttabIndex=${this.disabled ? '-1' : '0'}\n\t\t\t\t\tclass=\"trigger\"\n\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\taria-haspopup=\"listbox\"\n\t\t\t\t\taria-expanded=${this.isOpen}\n\t\t\t\t\taria-controls=\"options\"\n\t\t\t\t\taria-autocomplete=\"none\"\n\t\t\t\t\taria-required=${this.required}\n\t\t\t\t\taria-activedescendant=${ifDefined(this._focusedOptionId || undefined)}\n\t\t\t\t\taria-disabled=${this.disabled}\n\t\t\t\t\t.label=${this.label}\n\t\t\t\t\t.placeholder=${this.placeholder}\n\t\t\t\t\t.value=${this.valueLabel}\n\t\t\t\t\t.required=${this.required}\n\t\t\t\t\t.disabled=${this.disabled}\n\t\t\t\t\t.hint=${showErrors ? this.validationMessage : this.hint}\n\t\t\t\t\t.error=${showErrors}\n\t\t\t\t\t.validateOn=${this.validateOn}\n\t\t\t\t\t.size=${this.size}\n\t\t\t\t\t.readonly=${true}\n\t\t\t\t\tclickable\n\t\t\t\t\t@click=${(e: MouseEvent) => {\n\t\t\t\t\t\t// Don't process clicks if disabled\n\t\t\t\t\t\tif (this.disabled) {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// On first click, don't count this as user interaction yet\n\t\t\t\t\t\tif (!this.isOpen) {\n\t\t\t\t\t\t\t// Open without triggering validation - we'll validate when they close\n\t\t\t\t\t\t\tthis.openDropdown(false)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Mark as interacted when they close the dropdown\n\t\t\t\t\t\t\tthis._userInteracted = true\n\t\t\t\t\t\t\tthis.closeDropdown()\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t${caretIcon}\n\t\t\t\t</sch-input>\n\n\t\t\t\t<!-- Overlay for capturing clicks outside when dropdown is open -->\n\t\t\t\t${this.isOpen\n\t\t\t\t\t? html` <div class=\"fixed inset-0 z-10\" @click=${this.closeDropdown} tabindex=\"-1\" aria-hidden=\"true\"></div> `\n\t\t\t\t\t: ''}\n\n\t\t\t\t<ul\n\t\t\t\t\tid=\"options\"\n\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\taria-multiselectable=${this.multi}\n\t\t\t\t\tclass=${classMap({\n\t\t\t\t\t\t'absolute min-w-full w-full z-20 mt-1 rounded-md shadow-lg': true,\n\t\t\t\t\t\thidden: !this.isOpen,\n\t\t\t\t\t})}\n\t\t\t\t\t${color({\n\t\t\t\t\t\tbgColor: SchmancyTheme.sys.color.surface.low,\n\t\t\t\t\t\tcolor: SchmancyTheme.sys.color.surface.on,\n\t\t\t\t\t})}\n\t\t\t\t>\n\t\t\t\t\t<slot\n\t\t\t\t\t\t@slotchange=${() => {\n\t\t\t\t\t\t\tthis._options$.next(this.options)\n\t\t\t\t\t\t\t// Sync selection state when options re-render\n\t\t\t\t\t\t\tthis.syncSelection()\n\t\t\t\t\t\t}}\n\t\t\t\t\t></slot>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\n// Don't export 'select' here as it conflicts with the store's select decorator\n// export const select = SchmancySelect\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-select': SchmancySelect\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"select-DdqEsfnG.cjs","names":[],"sources":["../src/form/fields/select/select.ts"],"sourcesContent":["import { autoUpdate, computePosition, flip, offset, shift } from '@floating-ui/dom'\nimport { SchmancyFormField } from '@mixins/index'\nimport { color } from '@schmancy/directives'\nimport SchmancyInput from '@schmancy/input/input'\nimport SchmancyOption from '@schmancy/option/option'\nimport { SchmancyTheme } from '@schmancy/theme/theme.interface'\nimport { css, html, PropertyValues, TemplateResult } from 'lit'\nimport { customElement, property, query, queryAssignedElements, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { BehaviorSubject, combineLatest, fromEvent, Subject, takeUntil } from 'rxjs'\nimport { tap, withLatestFrom } from 'rxjs/operators'\n\nexport type SchmancySelectChangeEvent = CustomEvent<{\n\tvalue: string | string[]\n}>\n\n/**\n * Select dropdown component with single and multi-select support.\n *\n * @prop {string} name - Name attribute for form submission\n * @prop {string} label - Label text displayed above the select\n * @prop {string} placeholder - Placeholder text when no value is selected\n * @prop {boolean} required - Whether the field is required\n * @prop {boolean} multi - Enable multi-select mode\n * @prop {string} value - Selected value (single select mode)\n * @prop {string[]} values - Selected values (multi-select mode)\n */\n@customElement('schmancy-select')\nexport class SchmancySelect extends SchmancyFormField() {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: block;\n\t\tposition: relative;\n\t}\n\n\t[role='listbox'] {\n\t\toverflow-y: auto;\n\t\toutline: none;\n\t}\n`]\n\n\t// FACE wiring (formAssociated, internals, attachInternals) comes from\n\t// SchmancyFormField. Same for: name, required, disabled, validationMessage,\n\t// validateOn, touched/dirty/pristine/submitted, markTouched/markSubmitted,\n\t// formResetCallback, formDisabledCallback, FIELD_CONNECT_EVENT dispatch.\n\n\t@property({ type: String }) placeholder = ''\n\n\t// Override `value` with the narrowed select-specific type and a custom\n\t// getter/setter pair backed by reactive subjects.\n\t@property({ type: String, reflect: true })\n\toverride get value(): string | string[] {\n\t\treturn this.multi\n\t\t\t? (this._selectedValues$?.value ?? [])\n\t\t\t: (this._selectedValue$?.value ?? '')\n\t}\n\toverride set value(val: string | string[]) {\n\t\tif (!this._selectedValue$ || !this._selectedValues$) return\n\t\tif (this.multi) {\n\t\t\tconst values = Array.isArray(val)\n\t\t\t\t? val\n\t\t\t\t: val ? String(val).split(',').map(v => v.trim()).filter(Boolean) : []\n\t\t\tthis._selectedValues$.next(values)\n\t\t} else {\n\t\t\tthis._selectedValue$.next(val == null ? '' : String(val))\n\t\t}\n\t}\n\n\t// Values property for multi-select mode\n\t@property({ type: Array })\n\tget values() {\n\t\treturn [...this._selectedValues$.value]\n\t}\n\tset values(vals: string[]) {\n\t\tthis._selectedValues$.next(Array.isArray(vals) ? [...vals] : [])\n\t}\n\n\t@property({ type: Boolean }) multi = false\n\t// `label` and `hint` come from the mixin.\n\t// M3 aligned sizes: 24dp (xxs) → 32dp (xs) → 40dp (sm) → 48dp (md) → 56dp (lg)\n\t@property({ type: String }) size: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' = 'md'\n\n\t// Internal states\n\t@state() private isOpen = false\n\t@state() private valueLabel = ''\n\t@state() private isValid = true\n\n\t// Store the initial/default value for reset behavior. Distinct from the\n\t// mixin's `_defaultValue` (which is `string` only); select needs the wider\n\t// shape so resetForm can restore arrays for multi-select.\n\t@state() private selectDefaultValue: string | string[] = ''\n\n\t@query('ul') private ul!: HTMLUListElement\n\t@query('sch-input') private inputRef!: SchmancyInput\n\t@queryAssignedElements({ flatten: true }) private options!: SchmancyOption[]\n\tprivate cleanupPositioner?: () => void\n\n\t// Reactive state management\n\tprivate _options$ = new BehaviorSubject<SchmancyOption[]>([])\n\tprivate _selectedValue$ = new BehaviorSubject<string>('')\n\tprivate _selectedValues$ = new BehaviorSubject<string[]>([])\n\tprivate _optionSelect$ = new Subject<SchmancyOption>()\n\n\t/**\n\t * Tracks whether the user has actively interacted (clicked/typed/keyed\n\t * inside the dropdown). Distinct from the mixin's `touched` (which fires on\n\t * blur). Used to gate dropdown-positioning side-effects on user-driven\n\t * actions versus programmatic state changes.\n\t */\n\t@state() _userInteracted = false\n\n\t// Reference to current focused option (for keyboard navigation)\n\t@state() private _focusedOptionId = ''\n\n\toverride connectedCallback() {\n\t\tsuper.connectedCallback()\n\t\tif (!this.id) {\n\t\t\tthis.id = `schmancy-select-${Math.random().toString(36).substring(2, 9)}`\n\t\t}\n\n\t\t// Store initial value for reset\n\t\tthis.selectDefaultValue = this.value\n\n\t\t// Add keyboard handling to host element\n\t\tfromEvent<KeyboardEvent>(this, 'keydown').pipe(takeUntil(this.disconnecting)).subscribe(this.handleKeyDown)\n\n\t\t// Setup reactive pipelines\n\t\tthis._setupReactivePipelines()\n\t}\n\n\toverride disconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis.cleanupPositioner?.()\n\t\t// Form event listeners are automatically cleaned up via takeUntil(this.disconnecting)\n\t}\n\n\tfirstUpdated() {\n\t\tthis.syncSelection()\n\t\tthis.setupOptionsAccessibility()\n\n\t\t// Initially hide any validation errors until user interacts\n\t\tif (this.inputRef) {\n\t\t\tthis.inputRef.error = false\n\t\t}\n\t}\n\n\toverride updated(changedProps: PropertyValues) {\n\t\tsuper.updated(changedProps)\n\n\t\tif (changedProps.has('value')) {\n\t\t\t// Multi-select serializes to a comma-joined scalar on FormData; the\n\t\t\t// mixin's willUpdate already called setFormValue with the raw\n\t\t\t// value, override here for the joined-string shape.\n\t\t\tconst formValue = this.multi\n\t\t\t\t? this._selectedValues$.value.join(',')\n\t\t\t\t: this._selectedValue$.value\n\t\t\tthis.internals?.setFormValue(formValue)\n\n\t\t\t// `dirty` is a mixin getter (value !== _defaultValue); no manual flag.\n\t\t\t// Mixin's willUpdate already calls checkValidity when _shouldShowError().\n\t\t}\n\n\t\t// When open state changes, setup or cleanup the dropdown positioner\n\t\tif (changedProps.has('isOpen')) {\n\t\t\tif (this.isOpen) {\n\t\t\t\tthis.positionDropdown()\n\t\t\t} else {\n\t\t\t\tthis.cleanupPositioner?.()\n\t\t\t}\n\t\t}\n\t}\n\n\t// `shouldShowValidation` removed — replaced by mixin's `_shouldShowError()`.\n\n\tprivate syncSelection() {\n\t\tif (this.multi) {\n\t\t\t// Read directly from the BehaviorSubject to avoid string conversion issues\n\t\t\tconst selectedValues = this._selectedValues$.value\n\t\t\tthis.options?.forEach(o => (o.selected = selectedValues.includes(o.value))) // Update option selected state\n\t\t\tthis.valueLabel =\n\t\t\t\tselectedValues.length > 0\n\t\t\t\t\t? this.options\n\t\t\t\t\t\t\t?.filter(o => selectedValues.includes(o.value))\n\t\t\t\t\t\t\t.map(o => o.label || o.textContent || '')\n\t\t\t\t\t\t\t.join(', ') || this.placeholder\n\t\t\t\t\t: this.placeholder\n\t\t} else {\n\t\t\t// Single select - read from BehaviorSubject\n\t\t\tconst currentValue = this._selectedValue$.value\n\t\t\tthis.options?.forEach(o => {\n\t\t\t\t// Set selected property on each option based on matching value\n\t\t\t\to.selected = o.value === currentValue\n\t\t\t})\n\t\t\tconst selectedOption = this.options?.find(o => o.value === currentValue)\n\t\t\tthis.valueLabel = selectedOption ? (selectedOption.label || selectedOption.textContent || '') : this.placeholder\n\t\t}\n\t}\n\n\tprivate setupOptionsAccessibility() {\n\t\tthis.options?.forEach((option, index) => {\n\t\t\toption.setAttribute('role', 'option')\n\t\t\tif (!option.id) {\n\t\t\t\toption.id = `${this.id}-option-${index}`\n\t\t\t}\n\n\t\t\t// Set tabindex to -1 so they're focusable programmatically but not in the tab order\n\t\t\toption.tabIndex = -1\n\n\t\t\toption.setAttribute(\n\t\t\t\t'aria-selected',\n\t\t\t\tString(this.multi ? this._selectedValues$.value.includes(option.value) : option.value === this._selectedValue$.value),\n\t\t\t)\n\t\t})\n\t}\n\n\tprivate async positionDropdown() {\n\t\tconst reference = this.renderRoot.querySelector('.trigger') as HTMLElement\n\t\tif (!reference || !this.ul) return\n\n\t\tthis.cleanupPositioner = autoUpdate(reference, this.ul, async () => {\n\t\t\t// Get viewport dimensions\n\t\t\tconst viewportHeight = window.innerHeight\n\t\t\tconst triggerRect = reference.getBoundingClientRect()\n\n\t\t\t// Calculate available space below and above\n\t\t\tconst spaceBelow = viewportHeight - triggerRect.bottom\n\t\t\tconst spaceAbove = triggerRect.top\n\n\t\t\t// Calculate max height - use 75% of the largest available space, but at least 150px\n\t\t\tconst maxHeight = Math.max(Math.max(spaceBelow, spaceAbove) * 0.75, 150)\n\n\t\t\t// Determine if we should flip\n\t\t\tconst shouldFlip = spaceBelow < 200 && spaceAbove > spaceBelow\n\n\t\t\t// Apply max height\n\t\t\tthis.ul.style.maxHeight = `${maxHeight}px`\n\n\t\t\tconst { x, y } = await computePosition(reference, this.ul, {\n\t\t\t\tplacement: shouldFlip ? 'top-start' : 'bottom-start',\n\t\t\t\tmiddleware: [offset(5), flip(), shift({ padding: 5 })],\n\t\t\t})\n\n\t\t\tObject.assign(this.ul.style, {\n\t\t\t\tleft: `${x}px`,\n\t\t\t\ttop: `${y}px`,\n\t\t\t\tposition: 'absolute',\n\t\t\t\twidth: `${reference.offsetWidth}px`, // Match the width of the trigger\n\t\t\t})\n\t\t})\n\t}\n\n\tprivate handleKeyDown = (e: KeyboardEvent) => {\n\t\t// Don't handle keyboard events when disabled\n\t\tif (this.disabled) {\n\t\t\treturn\n\t\t}\n\n\t\tif (!this.isOpen) {\n\t\t\tif (['Enter', ' ', 'ArrowDown'].includes(e.key)) {\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.openDropdown(false)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\t// Find current focused option\n\t\tconst options = Array.from(this.options || [])\n\t\tconst current = options.findIndex(o => o.id === this._focusedOptionId) ?? -1\n\n\t\tswitch (e.key) {\n\t\t\tcase 'Escape':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.closeDropdown()\n\t\t\t\tbreak\n\t\t\tcase 'ArrowDown':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.focusOption(options, Math.min(current + 1, options.length - 1))\n\t\t\t\tbreak\n\t\t\tcase 'ArrowUp':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.focusOption(options, Math.max(current - 1, 0))\n\t\t\t\tbreak\n\t\t\tcase 'Home':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.focusOption(options, 0)\n\t\t\t\tbreak\n\t\t\tcase 'End':\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.focusOption(options, options.length - 1)\n\t\t\t\tbreak\n\t\t\tcase 'Enter':\n\t\t\tcase ' ':\n\t\t\t\te.preventDefault()\n\t\t\t\tif (this._focusedOptionId) {\n\t\t\t\t\tconst focusedOption = options.find(opt => opt.id === this._focusedOptionId)\n\t\t\t\t\tif (focusedOption) {\n\t\t\t\t\t\tthis.handleOptionSelect(focusedOption.value)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase 'Tab':\n\t\t\t\tthis.closeDropdown()\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tprivate focusOption(options: SchmancyOption[], index: number) {\n\t\tconst option = options[index]\n\t\tif (option) {\n\t\t\toption.focus()\n\t\t\tthis._focusedOptionId = option.id\n\n\t\t\t// Update aria-activedescendant on the combobox\n\t\t\tconst combobox = this.renderRoot.querySelector('.trigger')\n\t\t\tif (combobox) {\n\t\t\t\tcombobox.setAttribute('aria-activedescendant', option.id)\n\t\t\t}\n\n\t\t\t// Ensure option is visible in the scrollable area\n\t\t\tif (this.ul && option.offsetTop !== undefined) {\n\t\t\t\t// Get position info\n\t\t\t\tconst optionTop = option.offsetTop\n\t\t\t\tconst optionHeight = option.offsetHeight\n\t\t\t\tconst scrollTop = this.ul.scrollTop\n\t\t\t\tconst ulHeight = this.ul.clientHeight\n\n\t\t\t\t// Scroll into view if needed\n\t\t\t\tif (optionTop < scrollTop) {\n\t\t\t\t\tthis.ul.scrollTop = optionTop\n\t\t\t\t} else if (optionTop + optionHeight > scrollTop + ulHeight) {\n\t\t\t\t\tthis.ul.scrollTop = optionTop + optionHeight - ulHeight\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async openDropdown(report = false) {\n\t\t// Don't open if disabled\n\t\tif (this.disabled) {\n\t\t\treturn\n\t\t}\n\n\t\t// Don't mark as touched on opening - we'll do that on closing\n\t\t// so errors only show after interaction is complete\n\n\t\tthis.isOpen = true\n\t\tawait this.updateComplete\n\n\t\t// Focus first or selected option\n\t\tconst options = Array.from(this.options || [])\n\t\tconst selectedIndex = this.multi ? 0 : options.findIndex(o => o.value === this._selectedValue$.value)\n\n\t\tthis.focusOption(options, Math.max(selectedIndex, 0))\n\n\t\t// Don't automatically validate when opening\n\t\t// Only validate if explicitly requested (like from a form submission)\n\t\tif (report) this.reportValidity()\n\t}\n\n\tprivate closeDropdown() {\n\t\t// Only mark as touched if the user actually interacted with the component\n\t\t// and made a selection or explicitly closed it without selecting\n\t\tif (this._userInteracted) {\n\t\t\tthis.touched = true\n\t\t}\n\n\t\tthis.isOpen = false\n\t\tthis._focusedOptionId = ''\n\n\t\t// Update combobox to remove aria-activedescendant\n\t\tconst combobox = this.renderRoot.querySelector<HTMLElement>('.trigger')\n\t\tif (combobox) {\n\t\t\tcombobox.removeAttribute('aria-activedescendant')\n\t\t\tcombobox?.focus()\n\t\t}\n\n\t\t// Only check validity when closing if the user has actually interacted\n\t\t// with the component and validation should be shown\n\t\tif (this._userInteracted && this._shouldShowError()) {\n\t\t\tthis.checkValidity()\n\t\t}\n\t}\n\n\tprivate _setupReactivePipelines() {\n\t\t// Listen for option-select events from child options\n\t\tfromEvent<CustomEvent>(this, 'option-select')\n\t\t\t.pipe(\n\t\t\t\ttap((e) => {\n\t\t\t\t\te.stopPropagation() // Prevent event from bubbling further\n\t\t\t\t\tconst option = this.options.find(o => o.value === e.detail.value)\n\t\t\t\t\tif (option) {\n\t\t\t\t\t\tthis._optionSelect$.next(option)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Handle option selection through reactive pipeline\n\t\tthis._optionSelect$\n\t\t\t.pipe(\n\t\t\t\twithLatestFrom(this._selectedValue$, this._selectedValues$),\n\t\t\t\ttap(([option, _, currentValues]) => {\n\t\t\t\t\tthis._userInteracted = true\n\t\t\t\t\tthis.markTouched()\n\t\t\t\t\t// `dirty` is a mixin getter; setting `value` below triggers it\n\n\t\t\t\t\tif (this.multi) {\n\t\t\t\t\t\tconst index = currentValues.indexOf(option.value)\n\t\t\t\t\t\tconst newValues = index > -1\n\t\t\t\t\t\t\t? [...currentValues.slice(0, index), ...currentValues.slice(index + 1)]\n\t\t\t\t\t\t\t: [...currentValues, option.value]\n\t\t\t\t\t\tthis._selectedValues$.next(newValues)\n\n\t\t\t\t\t\t// Update form value\n\t\t\t\t\t\tthis.internals?.setFormValue(newValues.join(','))\n\n\t\t\t\t\t\t// Update display label\n\t\t\t\t\t\tthis.valueLabel = newValues.length > 0\n\t\t\t\t\t\t\t? this.options\n\t\t\t\t\t\t\t\t\t.filter(o => newValues.includes(o.value))\n\t\t\t\t\t\t\t\t\t.map(o => o.label || o.textContent || '')\n\t\t\t\t\t\t\t\t\t.join(', ')\n\t\t\t\t\t\t\t: this.placeholder\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Single select\n\t\t\t\t\t\tthis._selectedValue$.next(option.value)\n\n\t\t\t\t\t\t// Update form value\n\t\t\t\t\t\tthis.internals?.setFormValue(option.value)\n\n\t\t\t\t\t\tthis.valueLabel = option.label || option.textContent || this.placeholder\n\t\t\t\t\t\tthis.closeDropdown()\n\t\t\t\t\t}\n\n\t\t\t\t\t// Update the option's accessibility state\n\t\t\t\t\tthis.setupOptionsAccessibility()\n\n\t\t\t\t\t// Dispatch change event\n\t\t\t\t\tthis._fireChangeEvent()\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Options management pipeline - bind pointerdown events exactly like autocomplete\n\t\tthis._options$\n\t\t\t.pipe(\n\t\t\t\ttap((options) => {\n\t\t\t\t\toptions.forEach((option, index) => {\n\t\t\t\t\t\toption.setAttribute('role', 'option')\n\t\t\t\t\t\toption.tabIndex = -1\n\t\t\t\t\t\tif (!option.id) {\n\t\t\t\t\t\t\toption.id = `${this.id}-option-${index}`\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Use data-event-bound to prevent duplicate bindings\n\t\t\t\t\t\tif (!option.hasAttribute('data-event-bound')) {\n\t\t\t\t\t\t\t// Use click event instead of pointerdown for better mobile UX\n\t\t\t\t\t\t\t// This allows users to scroll through options without immediately selecting\n\t\t\t\t\t\t\tfromEvent(option, 'click').pipe(\n\t\t\t\t\t\t\t\ttap(e => {\n\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t\t\t\t\t).subscribe(() => this._optionSelect$.next(option))\n\t\t\t\t\t\t\toption.setAttribute('data-event-bound', 'true')\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Selection sync pipeline - sync selected states with value changes\n\t\tcombineLatest([this._selectedValue$, this._selectedValues$, this._options$])\n\t\t\t.pipe(\n\t\t\t\ttap(([singleValue, multiValues, options]) => {\n\t\t\t\t\tif (options.length === 0) return\n\n\t\t\t\t\tif (this.multi) {\n\t\t\t\t\t\toptions.forEach(option => {\n\t\t\t\t\t\t\toption.selected = multiValues.includes(option.value)\n\t\t\t\t\t\t})\n\t\t\t\t\t} else {\n\t\t\t\t\t\toptions.forEach(option => {\n\t\t\t\t\t\t\toption.selected = option.value === singleValue\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting)\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\tprivate handleOptionSelect(value: string) {\n\t\t// This method is now called from keyboard navigation only\n\t\tconst option = this.options.find(o => o.value === value)\n\t\tif (option) {\n\t\t\tthis._optionSelect$.next(option)\n\t\t}\n\t}\n\n\tprivate _fireChangeEvent() {\n\t\t// Get the current value based on multi/single mode\n\t\tconst value = this.multi ? this._selectedValues$.value : this._selectedValue$.value\n\n\t\t// Dispatch only one change event with the value in detail\n\t\tthis.dispatchEvent(\n\t\t\tnew CustomEvent<SchmancySelectChangeEvent['detail']>('change', {\n\t\t\t\tdetail: { value },\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t}),\n\t\t)\n\n\t\t// Then check validity (only show error if validation should be shown)\n\t\tthis.checkValidity()\n\t}\n\n\tpublic checkValidity(): boolean {\n\t\t// Disabled fields are always valid\n\t\tif (this.disabled) {\n\t\t\treturn true\n\t\t}\n\n\t\t// Determine if the select is empty based on whether it's multi-select or single-select\n\t\tconst isEmpty = this.multi\n\t\t\t? this._selectedValues$.value.length === 0\n\t\t\t: !this._selectedValue$.value\n\n\t\t// Check if the value is valid (not empty when required)\n\t\tconst isValid = !(this.required && isEmpty)\n\n\t\t// Set the validity state\n\t\tthis.isValid = isValid\n\n\t\tif (!this.isValid) {\n\t\t\tthis.validationMessage = 'Please select an option.'\n\t\t\tthis.internals?.setValidity({ valueMissing: true }, 'Please select an option.', this.inputRef)\n\t\t} else {\n\t\t\t// Clear validation message\n\t\t\tthis.validationMessage = ''\n\t\t\tthis.internals?.setValidity({})\n\t\t}\n\n\t\t// Update the input component to reflect our validation state\n\t\tif (this.inputRef && this.hasUpdated) {\n\t\t\tconst showError = !this.isValid && this._shouldShowError()\n\t\t\tthis.inputRef.error = showError\n\t\t\tthis.inputRef.hint = showError ? this.validationMessage : this.hint\n\t\t}\n\n\t\treturn this.isValid\n\t}\n\n\tpublic reportValidity(): boolean {\n\t\t// Force validation display regardless of validation strategy\n\t\tconst valid = this.checkValidity()\n\n\t\t// Force the input to show validation errors\n\t\tif (this.inputRef) {\n\t\t\t// Set the input's error state\n\t\t\tthis.inputRef.error = !valid\n\t\t\tthis.inputRef.hint = !valid ? this.validationMessage : this.hint\n\n\t\t\t// If invalid and not already open, automatically open the dropdown to show options\n\t\t\tif (!valid && !this.isOpen) {\n\t\t\t\t// Open the dropdown but don't mark as user interaction yet\n\t\t\t\t// This helps users immediately see available options when validation fails\n\t\t\t\tthis.openDropdown(false)\n\t\t\t}\n\n\t\t\t// Only call reportValidity on the input if invalid to show the native popup\n\t\t\tif (!valid) {\n\t\t\t\tthis.inputRef.reportValidity()\n\t\t\t}\n\t\t}\n\n\t\treturn valid\n\t}\n\n\t// `markTouched`, `markSubmitted`, `touched`, `dirty`, `pristine`, `submitted`,\n\t// `error` (storage) — all from the mixin. Select's `error` semantics\n\t// (errors-while-open suppression) live in render() via _shouldShowError() +\n\t// !isOpen, not as a separate getter.\n\n\t/**\n\t * Multi-value-aware `toFormEntries`. Single-select emits one `[name,value]`;\n\t * multi-select emits N entries with the same name (canonical FormData shape\n\t * for repeated fields).\n\t */\n\toverride toFormEntries(): Array<[string, FormDataEntryValue]> {\n\t\tif (!this.name || this.disabled) return []\n\t\tconst v = this.value\n\t\tif (v === undefined || v === null || v === '') return []\n\t\tif (Array.isArray(v))\n\t\t\treturn v.map(item => [this.name, String(item)] as [string, FormDataEntryValue])\n\t\treturn [[this.name, String(v)]]\n\t}\n\n\toverride setCustomValidity(message: string) {\n\t\tthis.validationMessage = message\n\t\tif (message) {\n\t\t\tthis.isValid = false\n\t\t\tthis.internals?.setValidity({ customError: true }, message, this.inputRef)\n\t\t} else {\n\t\t\tthis.isValid = true\n\t\t\tthis.internals?.setValidity({})\n\t\t}\n\n\t\t// Update input if needed\n\t\tif (this.inputRef && this._shouldShowError()) {\n\t\t\tthis.inputRef.error = !this.isValid\n\t\t\tthis.inputRef.hint = !this.isValid ? this.validationMessage : this.hint\n\t\t}\n\t}\n\n\t/**\n\t * Reset to the snapshot captured at connect time. Mixin's `resetForm`\n\t * handles touched/submitted/error/validationMessage; the override layers on\n\t * select-specific cleanup (value subjects, label, validity).\n\t */\n\toverride resetForm(): void {\n\t\t// Restore value (multi-aware) before super so the mixin's _defaultValue\n\t\t// reset doesn't clobber the array-shape we need.\n\t\tthis.value = this.selectDefaultValue\n\t\tthis.valueLabel = this.placeholder\n\t\tthis.isValid = true\n\t\tthis._userInteracted = false\n\t\tthis.internals?.setValidity({})\n\t\tsuper.resetForm()\n\t\tif (this.inputRef) {\n\t\t\tthis.inputRef.error = false\n\t\t\tthis.inputRef.hint = this.hint\n\t\t}\n\t}\n\n\t/** Back-compat alias for callers that used the previous public API. */\n\tpublic reset(): void {\n\t\tthis.resetForm()\n\t}\n\n\trender(): TemplateResult {\n\t\t// Determine if we should show errors based on the validation strategy and interaction\n\t\t// Never show errors on initial render or if the dropdown is open\n\t\tconst showErrors = !this.isValid && this._shouldShowError() && !this.isOpen\n\n\t\t// Add caret icon based on open state\n\t\tconst caretIcon = this.isOpen\n\t\t\t? html`<span class=\"absolute right-3 top-1/2 transform -translate-y-1/2\">▲</span>`\n\t\t\t: html`<span class=\"absolute right-3 top-1/2 transform -translate-y-1/2\">▼</span>`\n\n\t\treturn html`\n\t\t\t<div class=\"relative ${this.disabled ? 'opacity-60 cursor-not-allowed' : ''}\">\n\t\t\t\t<sch-input\n\t\t\t\t\t.name=${this.name ?? ''}\n\t\t\t\t\ttabIndex=${this.disabled ? '-1' : '0'}\n\t\t\t\t\tclass=\"trigger\"\n\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\taria-haspopup=\"listbox\"\n\t\t\t\t\taria-expanded=${this.isOpen}\n\t\t\t\t\taria-controls=\"options\"\n\t\t\t\t\taria-autocomplete=\"none\"\n\t\t\t\t\taria-required=${this.required}\n\t\t\t\t\taria-activedescendant=${ifDefined(this._focusedOptionId || undefined)}\n\t\t\t\t\taria-disabled=${this.disabled}\n\t\t\t\t\t.label=${this.label}\n\t\t\t\t\t.placeholder=${this.placeholder}\n\t\t\t\t\t.value=${this.valueLabel}\n\t\t\t\t\t.required=${this.required}\n\t\t\t\t\t.disabled=${this.disabled}\n\t\t\t\t\t.hint=${showErrors ? this.validationMessage : this.hint}\n\t\t\t\t\t.error=${showErrors}\n\t\t\t\t\t.validateOn=${this.validateOn}\n\t\t\t\t\t.size=${this.size}\n\t\t\t\t\t.readonly=${true}\n\t\t\t\t\tclickable\n\t\t\t\t\t@click=${(e: MouseEvent) => {\n\t\t\t\t\t\t// Don't process clicks if disabled\n\t\t\t\t\t\tif (this.disabled) {\n\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// On first click, don't count this as user interaction yet\n\t\t\t\t\t\tif (!this.isOpen) {\n\t\t\t\t\t\t\t// Open without triggering validation - we'll validate when they close\n\t\t\t\t\t\t\tthis.openDropdown(false)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Mark as interacted when they close the dropdown\n\t\t\t\t\t\t\tthis._userInteracted = true\n\t\t\t\t\t\t\tthis.closeDropdown()\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t${caretIcon}\n\t\t\t\t</sch-input>\n\n\t\t\t\t<!-- Overlay for capturing clicks outside when dropdown is open -->\n\t\t\t\t${this.isOpen\n\t\t\t\t\t? html` <div class=\"fixed inset-0 z-10\" @click=${this.closeDropdown} tabindex=\"-1\" aria-hidden=\"true\"></div> `\n\t\t\t\t\t: ''}\n\n\t\t\t\t<ul\n\t\t\t\t\tid=\"options\"\n\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\taria-multiselectable=${this.multi}\n\t\t\t\t\tclass=${classMap({\n\t\t\t\t\t\t'absolute min-w-full w-full z-20 mt-1 rounded-md shadow-lg': true,\n\t\t\t\t\t\thidden: !this.isOpen,\n\t\t\t\t\t})}\n\t\t\t\t\t${color({\n\t\t\t\t\t\tbgColor: SchmancyTheme.sys.color.surface.low,\n\t\t\t\t\t\tcolor: SchmancyTheme.sys.color.surface.on,\n\t\t\t\t\t})}\n\t\t\t\t>\n\t\t\t\t\t<slot\n\t\t\t\t\t\t@slotchange=${() => {\n\t\t\t\t\t\t\tthis._options$.next(this.options)\n\t\t\t\t\t\t\t// Sync selection state when options re-render\n\t\t\t\t\t\t\tthis.syncSelection()\n\t\t\t\t\t\t}}\n\t\t\t\t\t></slot>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\n// Don't export 'select' here as it conflicts with the store's select decorator\n// export const select = SchmancySelect\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-select': SchmancySelect\n\t}\n}\n"],"mappings":"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"}
package/dist/select.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./select-BaioT3yY.cjs`);Object.defineProperty(exports,`SchmancySelect`,{enumerable:!0,get:function(){return e.t}});
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./select-DdqEsfnG.cjs`);Object.defineProperty(exports,`SchmancySelect`,{enumerable:!0,get:function(){return e.t}});
package/dist/select.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as e } from "./select-Czpl1ztD.js";
1
+ import { t as e } from "./select-CzCv1f1c.js";
2
2
  export { e as SchmancySelect };
package/dist/skeleton.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-BF3Vj8_c.cjs`),t=require(`./active-host-jH3iloCR.cjs`);let n=require(`lit/decorators.js`),r=require(`lit`);var i=class extends e.c{constructor(...e){super(...e),this.shape=`rect`,this.width=``,this.height=``,this.radius=``}static{this.styles=[r.css`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./SchmancyElement-DhSiMp6Y.cjs`);require(`./mixins-YQI9JogS.cjs`);let t=require(`lit/decorators.js`),n=require(`lit`);var r=class extends e.t{constructor(...e){super(...e),this.shape=`rect`,this.width=``,this.height=``,this.radius=``}static{this.styles=[n.css`
2
2
  :host {
3
3
  display: block;
4
4
  width: var(--_sw, 100%);
@@ -30,4 +30,4 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./ch
30
30
  background: var(--schmancy-sys-color-surface-containerHighest, #e6e6e6);
31
31
  }
32
32
  }
33
- `]}connectedCallback(){super.connectedCallback(),this.setAttribute(`role`,`status`),this.setAttribute(`aria-busy`,`true`),this.setAttribute(`aria-label`,`Loading`)}updated(){this.width&&this.style.setProperty(`--_sw`,this.width);let e=this.shape===`text`?`1em`:`1rem`;this.style.setProperty(`--_sh`,this.height||e),this.radius&&this.style.setProperty(`--_sr`,this.radius)}render(){return r.html`<div part="surface" class="surface"></div>`}};t.a([(0,n.property)({type:String,reflect:!0})],i.prototype,`shape`,void 0),t.a([(0,n.property)({type:String})],i.prototype,`width`,void 0),t.a([(0,n.property)({type:String})],i.prototype,`height`,void 0),t.a([(0,n.property)({type:String})],i.prototype,`radius`,void 0),i=t.a([(0,n.customElement)(`schmancy-skeleton`)],i),Object.defineProperty(exports,`SchmancySkeleton`,{enumerable:!0,get:function(){return i}});
33
+ `]}connectedCallback(){super.connectedCallback(),this.setAttribute(`role`,`status`),this.setAttribute(`aria-busy`,`true`),this.setAttribute(`aria-label`,`Loading`)}updated(){this.width&&this.style.setProperty(`--_sw`,this.width);let e=this.shape===`text`?`1em`:`1rem`;this.style.setProperty(`--_sh`,this.height||e),this.radius&&this.style.setProperty(`--_sr`,this.radius)}render(){return n.html`<div part="surface" class="surface"></div>`}};e.p([(0,t.property)({type:String,reflect:!0})],r.prototype,`shape`,void 0),e.p([(0,t.property)({type:String})],r.prototype,`width`,void 0),e.p([(0,t.property)({type:String})],r.prototype,`height`,void 0),e.p([(0,t.property)({type:String})],r.prototype,`radius`,void 0),r=e.p([(0,t.customElement)(`schmancy-skeleton`)],r),Object.defineProperty(exports,`SchmancySkeleton`,{enumerable:!0,get:function(){return r}});
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton.cjs","names":[],"sources":["../src/skeleton/skeleton.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n/**\n * Placeholder shimmer surface shown while content loads. Renders a\n * shape-configurable rectangle with a reduced-motion-aware shimmer.\n *\n * @element schmancy-skeleton\n * @attr shape - 'rect' | 'circle' | 'text'. Default 'rect'.\n * @attr width - CSS length (e.g. `100%`, `12rem`).\n * @attr height - CSS length; for `shape=text` defaults to 1em.\n * @attr radius - CSS length for corner radius; ignored for `shape=circle`.\n * @csspart surface - The shimmering surface element.\n */\n@customElement('schmancy-skeleton')\nexport class SchmancySkeleton extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: block;\n\t\twidth: var(--_sw, 100%);\n\t\theight: var(--_sh, 1rem);\n\t}\n\t.surface {\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tborder-radius: var(--_sr, 0.25rem);\n\t\tbackground: linear-gradient(\n\t\t\t90deg,\n\t\t\tvar(--schmancy-sys-color-surface-containerHighest, #e6e6e6) 25%,\n\t\t\tvar(--schmancy-sys-color-surface-container, #f2f2f2) 37%,\n\t\t\tvar(--schmancy-sys-color-surface-containerHighest, #e6e6e6) 63%\n\t\t);\n\t\tbackground-size: 400% 100%;\n\t\tanimation: schmancy-skeleton-shimmer 1.4s ease infinite;\n\t}\n\t:host([shape='circle']) .surface {\n\t\tborder-radius: 50%;\n\t}\n\t@keyframes schmancy-skeleton-shimmer {\n\t\t0% { background-position: 100% 50%; }\n\t\t100% { background-position: 0 50%; }\n\t}\n\t@media (prefers-reduced-motion: reduce) {\n\t\t.surface {\n\t\t\tanimation: none;\n\t\t\tbackground: var(--schmancy-sys-color-surface-containerHighest, #e6e6e6);\n\t\t}\n\t}\n`];\n\t@property({ type: String, reflect: true }) shape: 'rect' | 'circle' | 'text' = 'rect'\n\t@property({ type: String }) width = ''\n\t@property({ type: String }) height = ''\n\t@property({ type: String }) radius = ''\n\n\tconnectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.setAttribute('role', 'status')\n\t\tthis.setAttribute('aria-busy', 'true')\n\t\tthis.setAttribute('aria-label', 'Loading')\n\t}\n\n\tprotected updated(): void {\n\t\tif (this.width) this.style.setProperty('--_sw', this.width)\n\t\tconst defaultHeight = this.shape === 'text' ? '1em' : '1rem'\n\t\tthis.style.setProperty('--_sh', this.height || defaultHeight)\n\t\tif (this.radius) this.style.setProperty('--_sr', this.radius)\n\t}\n\n\trender() {\n\t\treturn html`<div part=\"surface\" class=\"surface\"></div>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-skeleton': SchmancySkeleton\n\t}\n}\n"],"mappings":"wOAgBO,IAAA,EAAA,cAA+B,EAAA,CAAA,CAAA,YAAA,GAAA,EAAA,CAAA,MAAA,GAAA,EAAA,CAAA,KAAA,MAkC0C,OAAA,KAAA,MAC3C,GAAA,KAAA,OACC,GAAA,KAAA,OACA,GAAA,OAAA,KAAA,OApCrB,CAAC,EAAA,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCpB,mBAAA,CACC,MAAM,mBAAA,CACN,KAAK,aAAa,OAAQ,SAAA,CAC1B,KAAK,aAAa,YAAa,OAAA,CAC/B,KAAK,aAAa,aAAc,UAAA,CAGjC,SAAA,CACK,KAAK,OAAO,KAAK,MAAM,YAAY,QAAS,KAAK,MAAA,CACrD,IAAM,EAAgB,KAAK,QAAU,OAAS,MAAQ,OACtD,KAAK,MAAM,YAAY,QAAS,KAAK,QAAU,EAAA,CAC3C,KAAK,QAAQ,KAAK,MAAM,YAAY,QAAS,KAAK,OAAA,CAGvD,QAAA,CACC,MAAO,GAAA,IAAI,+CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UApBF,CAAE,KAAM,OAAQ,QAAA,CAAS,EAAA,CAAA,CAAA,CAAO,EAAA,UAAA,QAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAChC,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,QAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UACjB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,SAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UACjB,CAAE,KAAM,OAAA,CAAA,CAAA,CAAS,EAAA,UAAA,SAAA,IAAA,GAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eAtCb,oBAAA,CAAA,CAAoB,EAAA,CAAA,OAAA,eAAA,QAAA,mBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"skeleton.cjs","names":[],"sources":["../src/skeleton/skeleton.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n/**\n * Placeholder shimmer surface shown while content loads. Renders a\n * shape-configurable rectangle with a reduced-motion-aware shimmer.\n *\n * @element schmancy-skeleton\n * @attr shape - 'rect' | 'circle' | 'text'. Default 'rect'.\n * @attr width - CSS length (e.g. `100%`, `12rem`).\n * @attr height - CSS length; for `shape=text` defaults to 1em.\n * @attr radius - CSS length for corner radius; ignored for `shape=circle`.\n * @csspart surface - The shimmering surface element.\n */\n@customElement('schmancy-skeleton')\nexport class SchmancySkeleton extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: block;\n\t\twidth: var(--_sw, 100%);\n\t\theight: var(--_sh, 1rem);\n\t}\n\t.surface {\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tborder-radius: var(--_sr, 0.25rem);\n\t\tbackground: linear-gradient(\n\t\t\t90deg,\n\t\t\tvar(--schmancy-sys-color-surface-containerHighest, #e6e6e6) 25%,\n\t\t\tvar(--schmancy-sys-color-surface-container, #f2f2f2) 37%,\n\t\t\tvar(--schmancy-sys-color-surface-containerHighest, #e6e6e6) 63%\n\t\t);\n\t\tbackground-size: 400% 100%;\n\t\tanimation: schmancy-skeleton-shimmer 1.4s ease infinite;\n\t}\n\t:host([shape='circle']) .surface {\n\t\tborder-radius: 50%;\n\t}\n\t@keyframes schmancy-skeleton-shimmer {\n\t\t0% { background-position: 100% 50%; }\n\t\t100% { background-position: 0 50%; }\n\t}\n\t@media (prefers-reduced-motion: reduce) {\n\t\t.surface {\n\t\t\tanimation: none;\n\t\t\tbackground: var(--schmancy-sys-color-surface-containerHighest, #e6e6e6);\n\t\t}\n\t}\n`];\n\t@property({ type: String, reflect: true }) shape: 'rect' | 'circle' | 'text' = 'rect'\n\t@property({ type: String }) width = ''\n\t@property({ type: String }) height = ''\n\t@property({ type: String }) radius = ''\n\n\tconnectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.setAttribute('role', 'status')\n\t\tthis.setAttribute('aria-busy', 'true')\n\t\tthis.setAttribute('aria-label', 'Loading')\n\t}\n\n\tprotected updated(): void {\n\t\tif (this.width) this.style.setProperty('--_sw', this.width)\n\t\tconst defaultHeight = this.shape === 'text' ? '1em' : '1rem'\n\t\tthis.style.setProperty('--_sh', this.height || defaultHeight)\n\t\tif (this.radius) this.style.setProperty('--_sr', this.radius)\n\t}\n\n\trender() {\n\t\treturn html`<div part=\"surface\" class=\"surface\"></div>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-skeleton': SchmancySkeleton\n\t}\n}\n"],"mappings":"0OAgBO,IAAA,EAAA,cAA+B,EAAA,CAAA,CAAA,YAAA,GAAA,EAAA,CAAA,MAAA,GAAA,CAAA,EAAA,KAAA,MAkC0C,OAAA,KAAA,MAC3C,GAAA,KAAA,OACC,GAAA,KAAA,OACA,EAAA,CAAA,OAAA,KAAA,OApCrB,CAAC,EAAA,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCpB,mBAAA,CACC,MAAM,kBAAA,EACN,KAAK,aAAa,OAAQ,QAAA,EAC1B,KAAK,aAAa,YAAa,MAAA,EAC/B,KAAK,aAAa,aAAc,SAAA,CACjC,CAEA,SAAA,CACK,KAAK,OAAO,KAAK,MAAM,YAAY,QAAS,KAAK,KAAA,EACrD,IAAM,EAAgB,KAAK,QAAU,OAAS,MAAQ,OACtD,KAAK,MAAM,YAAY,QAAS,KAAK,QAAU,CAAA,EAC3C,KAAK,QAAQ,KAAK,MAAM,YAAY,QAAS,KAAK,MAAA,CACvD,CAEA,QAAA,CACC,MAAO,GAAA,IAAI,4CACZ,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UArBU,CAAE,KAAM,OAAQ,QAAA,CAAS,CAAA,CAAA,CAAA,EAAM,EAAA,UAAA,QAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAC/B,CAAE,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,QAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAChB,CAAE,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,SAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAChB,CAAE,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,SAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eAtCZ,mBAAA,CAAA,EAAmB,CAAA,EAAA,OAAA,eAAA,QAAA,mBAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,CAAA,CAAA,CAAA"}
package/dist/skeleton.js CHANGED
@@ -1,8 +1,8 @@
1
- import { c as e } from "./mixins-8dT5j6CS.js";
2
- import { a as t } from "./active-host-BP0zy_Y9.js";
1
+ import { p as e, t } from "./SchmancyElement-BQ4DFufc.js";
2
+ import "./mixins-BYfSDvbP.js";
3
3
  import { customElement as n, property as r } from "lit/decorators.js";
4
4
  import { css as i, html as a } from "lit";
5
- var o = class extends e {
5
+ var o = class extends t {
6
6
  constructor(...e) {
7
7
  super(...e), this.shape = "rect", this.width = "", this.height = "", this.radius = "";
8
8
  }
@@ -53,8 +53,8 @@ var o = class extends e {
53
53
  return a`<div part="surface" class="surface"></div>`;
54
54
  }
55
55
  };
56
- t([r({
56
+ e([r({
57
57
  type: String,
58
58
  reflect: !0
59
- })], o.prototype, "shape", void 0), t([r({ type: String })], o.prototype, "width", void 0), t([r({ type: String })], o.prototype, "height", void 0), t([r({ type: String })], o.prototype, "radius", void 0), o = t([n("schmancy-skeleton")], o);
59
+ })], o.prototype, "shape", void 0), e([r({ type: String })], o.prototype, "width", void 0), e([r({ type: String })], o.prototype, "height", void 0), e([r({ type: String })], o.prototype, "radius", void 0), o = e([n("schmancy-skeleton")], o);
60
60
  export { o as SchmancySkeleton };
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton.js","names":[],"sources":["../src/skeleton/skeleton.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n/**\n * Placeholder shimmer surface shown while content loads. Renders a\n * shape-configurable rectangle with a reduced-motion-aware shimmer.\n *\n * @element schmancy-skeleton\n * @attr shape - 'rect' | 'circle' | 'text'. Default 'rect'.\n * @attr width - CSS length (e.g. `100%`, `12rem`).\n * @attr height - CSS length; for `shape=text` defaults to 1em.\n * @attr radius - CSS length for corner radius; ignored for `shape=circle`.\n * @csspart surface - The shimmering surface element.\n */\n@customElement('schmancy-skeleton')\nexport class SchmancySkeleton extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: block;\n\t\twidth: var(--_sw, 100%);\n\t\theight: var(--_sh, 1rem);\n\t}\n\t.surface {\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tborder-radius: var(--_sr, 0.25rem);\n\t\tbackground: linear-gradient(\n\t\t\t90deg,\n\t\t\tvar(--schmancy-sys-color-surface-containerHighest, #e6e6e6) 25%,\n\t\t\tvar(--schmancy-sys-color-surface-container, #f2f2f2) 37%,\n\t\t\tvar(--schmancy-sys-color-surface-containerHighest, #e6e6e6) 63%\n\t\t);\n\t\tbackground-size: 400% 100%;\n\t\tanimation: schmancy-skeleton-shimmer 1.4s ease infinite;\n\t}\n\t:host([shape='circle']) .surface {\n\t\tborder-radius: 50%;\n\t}\n\t@keyframes schmancy-skeleton-shimmer {\n\t\t0% { background-position: 100% 50%; }\n\t\t100% { background-position: 0 50%; }\n\t}\n\t@media (prefers-reduced-motion: reduce) {\n\t\t.surface {\n\t\t\tanimation: none;\n\t\t\tbackground: var(--schmancy-sys-color-surface-containerHighest, #e6e6e6);\n\t\t}\n\t}\n`];\n\t@property({ type: String, reflect: true }) shape: 'rect' | 'circle' | 'text' = 'rect'\n\t@property({ type: String }) width = ''\n\t@property({ type: String }) height = ''\n\t@property({ type: String }) radius = ''\n\n\tconnectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.setAttribute('role', 'status')\n\t\tthis.setAttribute('aria-busy', 'true')\n\t\tthis.setAttribute('aria-label', 'Loading')\n\t}\n\n\tprotected updated(): void {\n\t\tif (this.width) this.style.setProperty('--_sw', this.width)\n\t\tconst defaultHeight = this.shape === 'text' ? '1em' : '1rem'\n\t\tthis.style.setProperty('--_sh', this.height || defaultHeight)\n\t\tif (this.radius) this.style.setProperty('--_sr', this.radius)\n\t}\n\n\trender() {\n\t\treturn html`<div part=\"surface\" class=\"surface\"></div>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-skeleton': SchmancySkeleton\n\t}\n}\n"],"mappings":";;;;AAgBO,IAAA,IAAA,cAA+B,EAAA;CAAA,YAAA,GAAA,GAAA;EAAA,MAAA,GAAA,EAAA,EAAA,KAAA,QAkC0C,QAAA,KAAA,QAC3C,IAAA,KAAA,SACC,IAAA,KAAA,SACA;;CAAA;EAAA,KAAA,SApCrB,CAAC,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCpB,oBAAA;EACC,MAAM,mBAAA,EACN,KAAK,aAAa,QAAQ,SAAA,EAC1B,KAAK,aAAa,aAAa,OAAA,EAC/B,KAAK,aAAa,cAAc,UAAA;;CAGjC,UAAA;EACK,KAAK,SAAO,KAAK,MAAM,YAAY,SAAS,KAAK,MAAA;EACrD,IAAM,IAAgB,KAAK,UAAU,SAAS,QAAQ;EACtD,KAAK,MAAM,YAAY,SAAS,KAAK,UAAU,EAAA,EAC3C,KAAK,UAAQ,KAAK,MAAM,YAAY,SAAS,KAAK,OAAA;;CAGvD,SAAA;EACC,OAAO,CAAI;;;AAAA,EAAA,CApBX,EAAS;CAAE,MAAM;CAAQ,SAAA,CAAS;CAAA,CAAA,CAAA,EAAO,EAAA,WAAA,SAAA,KAAA,EAAA,EAAA,EAAA,CACzC,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,EAAS,EAAA,WAAA,SAAA,KAAA,EAAA,EAAA,EAAA,CAC1B,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,EAAS,EAAA,WAAA,UAAA,KAAA,EAAA,EAAA,EAAA,CAC1B,EAAS,EAAE,MAAM,QAAA,CAAA,CAAA,EAAS,EAAA,WAAA,UAAA,KAAA,EAAA,EAAA,IAAA,EAAA,CAtC3B,EAAc,oBAAA,CAAA,EAAoB,EAAA;AAAA,SAAA,KAAA"}
1
+ {"version":3,"file":"skeleton.js","names":[],"sources":["../src/skeleton/skeleton.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n/**\n * Placeholder shimmer surface shown while content loads. Renders a\n * shape-configurable rectangle with a reduced-motion-aware shimmer.\n *\n * @element schmancy-skeleton\n * @attr shape - 'rect' | 'circle' | 'text'. Default 'rect'.\n * @attr width - CSS length (e.g. `100%`, `12rem`).\n * @attr height - CSS length; for `shape=text` defaults to 1em.\n * @attr radius - CSS length for corner radius; ignored for `shape=circle`.\n * @csspart surface - The shimmering surface element.\n */\n@customElement('schmancy-skeleton')\nexport class SchmancySkeleton extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: block;\n\t\twidth: var(--_sw, 100%);\n\t\theight: var(--_sh, 1rem);\n\t}\n\t.surface {\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tborder-radius: var(--_sr, 0.25rem);\n\t\tbackground: linear-gradient(\n\t\t\t90deg,\n\t\t\tvar(--schmancy-sys-color-surface-containerHighest, #e6e6e6) 25%,\n\t\t\tvar(--schmancy-sys-color-surface-container, #f2f2f2) 37%,\n\t\t\tvar(--schmancy-sys-color-surface-containerHighest, #e6e6e6) 63%\n\t\t);\n\t\tbackground-size: 400% 100%;\n\t\tanimation: schmancy-skeleton-shimmer 1.4s ease infinite;\n\t}\n\t:host([shape='circle']) .surface {\n\t\tborder-radius: 50%;\n\t}\n\t@keyframes schmancy-skeleton-shimmer {\n\t\t0% { background-position: 100% 50%; }\n\t\t100% { background-position: 0 50%; }\n\t}\n\t@media (prefers-reduced-motion: reduce) {\n\t\t.surface {\n\t\t\tanimation: none;\n\t\t\tbackground: var(--schmancy-sys-color-surface-containerHighest, #e6e6e6);\n\t\t}\n\t}\n`];\n\t@property({ type: String, reflect: true }) shape: 'rect' | 'circle' | 'text' = 'rect'\n\t@property({ type: String }) width = ''\n\t@property({ type: String }) height = ''\n\t@property({ type: String }) radius = ''\n\n\tconnectedCallback(): void {\n\t\tsuper.connectedCallback()\n\t\tthis.setAttribute('role', 'status')\n\t\tthis.setAttribute('aria-busy', 'true')\n\t\tthis.setAttribute('aria-label', 'Loading')\n\t}\n\n\tprotected updated(): void {\n\t\tif (this.width) this.style.setProperty('--_sw', this.width)\n\t\tconst defaultHeight = this.shape === 'text' ? '1em' : '1rem'\n\t\tthis.style.setProperty('--_sh', this.height || defaultHeight)\n\t\tif (this.radius) this.style.setProperty('--_sr', this.radius)\n\t}\n\n\trender() {\n\t\treturn html`<div part=\"surface\" class=\"surface\"></div>`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-skeleton': SchmancySkeleton\n\t}\n}\n"],"mappings":";;;;AAgBO,IAAA,IAAA,cAA+B,EAAA;CAAA,YAAA,GAAA,GAAA;EAAA,MAAA,GAAA,CAAA,GAAA,KAAA,QAkC0C,QAAA,KAAA,QAC3C,IAAA,KAAA,SACC,IAAA,KAAA,SACA;CAAA;CAAA;EAAA,KAAA,SApCrB,CAAC,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCpB,oBAAA;EACC,MAAM,kBAAA,GACN,KAAK,aAAa,QAAQ,QAAA,GAC1B,KAAK,aAAa,aAAa,MAAA,GAC/B,KAAK,aAAa,cAAc,SAAA;CACjC;CAEA,UAAA;EACK,KAAK,SAAO,KAAK,MAAM,YAAY,SAAS,KAAK,KAAA;EACrD,IAAM,IAAgB,KAAK,UAAU,SAAS,QAAQ;EACtD,KAAK,MAAM,YAAY,SAAS,KAAK,UAAU,CAAA,GAC3C,KAAK,UAAQ,KAAK,MAAM,YAAY,SAAS,KAAK,MAAA;CACvD;CAEA,SAAA;EACC,OAAO,CAAI;CACZ;AAAA;AAAA,EAAA,CArBC,EAAS;CAAE,MAAM;CAAQ,SAAA,CAAS;AAAA,CAAA,CAAA,GAAM,EAAA,WAAA,SAAA,KAAA,CAAA,GAAA,EAAA,CACxC,EAAS,EAAE,MAAM,OAAA,CAAA,CAAA,GAAQ,EAAA,WAAA,SAAA,KAAA,CAAA,GAAA,EAAA,CACzB,EAAS,EAAE,MAAM,OAAA,CAAA,CAAA,GAAQ,EAAA,WAAA,UAAA,KAAA,CAAA,GAAA,EAAA,CACzB,EAAS,EAAE,MAAM,OAAA,CAAA,CAAA,GAAQ,EAAA,WAAA,UAAA,KAAA,CAAA,GAAA,IAAA,EAAA,CAtC1B,EAAc,mBAAA,CAAA,GAAmB,CAAA;AAAA,SAAA,KAAA"}
@@ -85,6 +85,40 @@ async _onSubmit(e: CustomEvent<SchmancyFormSubmitDetail>) {
85
85
  }
86
86
  ```
87
87
 
88
+ ## Submit-handler discipline
89
+
90
+ A `@submit` handler narrows the draft type, then passes the persist promise to `ev.detail.until(...)` in one expression. The form already enforces field-level `required` and renders a rejected `until` promise inline via `formError` state — anything the handler adds on top is duplication.
91
+
92
+ Anti-patterns:
93
+
94
+ - Wrapping a single `await api(...)` call in an `(async () => { ... })()` IIFE solely to use `await`. `until(api(...))` accepts a promise directly; the IIFE adds nothing.
95
+ - `if (!draft.name.trim()) throw new Error('Fill in the name.')` when the field is `<schmancy-input required>`. Required-field violations never reach the handler — schmancy-form blocks the submit dispatch before they would.
96
+ - `throw new Error(...)` on a kind-narrowing branch (`if (draft?.kind !== 'organization')`). The other branch is impossible by construction (the form's `<schmancy-context>` isolates that kind's draft). Narrowing branches use `return`, not `throw`.
97
+
98
+ The remaining legitimate throws are cross-component invariants the form can't see — e.g., "Pick a legal entity first" when a sibling picker writes to a different state singleton. Express them by passing `Promise.reject(new Error(...))` to `until`, not by re-introducing an IIFE.
99
+
100
+ ```ts
101
+ // ❌ wrong
102
+ ev.detail.until((async () => {
103
+ if (!draft.name.trim()) throw new Error('Fill in the name.');
104
+ if (auth.currentUser === null) throw new Error('Sign in.');
105
+ await updateWorkspace(draft.id, { name: draft.name.trim() });
106
+ })());
107
+
108
+ // ✓ right
109
+ const draft = state.value;
110
+ if (draft?.kind !== 'organization' || !draft.id) return;
111
+ ev.detail.until(updateWorkspace(draft.id, { name: draft.name.trim() }));
112
+
113
+ // ✓ cross-component invariant: reject inline
114
+ const parent = ws.legalEntity.value;
115
+ if (parent?.kind !== 'legalEntity') {
116
+ ev.detail.until(Promise.reject(new Error('Pick a legal entity first.')));
117
+ return;
118
+ }
119
+ ev.detail.until(createWorkspace(/* ...assembled with parent.id... */));
120
+ ```
121
+
88
122
  ## CSS state hooks (free)
89
123
 
90
124
  Every field broadcasts these via `:state(...)`:
@@ -85,6 +85,40 @@ async _onSubmit(e: CustomEvent<SchmancyFormSubmitDetail>) {
85
85
  }
86
86
  ```
87
87
 
88
+ ## Submit-handler discipline
89
+
90
+ A `@submit` handler narrows the draft type, then passes the persist promise to `ev.detail.until(...)` in one expression. The form already enforces field-level `required` and renders a rejected `until` promise inline via `formError` state — anything the handler adds on top is duplication.
91
+
92
+ Anti-patterns:
93
+
94
+ - Wrapping a single `await api(...)` call in an `(async () => { ... })()` IIFE solely to use `await`. `until(api(...))` accepts a promise directly; the IIFE adds nothing.
95
+ - `if (!draft.name.trim()) throw new Error('Fill in the name.')` when the field is `<schmancy-input required>`. Required-field violations never reach the handler — schmancy-form blocks the submit dispatch before they would.
96
+ - `throw new Error(...)` on a kind-narrowing branch (`if (draft?.kind !== 'organization')`). The other branch is impossible by construction (the form's `<schmancy-context>` isolates that kind's draft). Narrowing branches use `return`, not `throw`.
97
+
98
+ The remaining legitimate throws are cross-component invariants the form can't see — e.g., "Pick a legal entity first" when a sibling picker writes to a different state singleton. Express them by passing `Promise.reject(new Error(...))` to `until`, not by re-introducing an IIFE.
99
+
100
+ ```ts
101
+ // ❌ wrong
102
+ ev.detail.until((async () => {
103
+ if (!draft.name.trim()) throw new Error('Fill in the name.');
104
+ if (auth.currentUser === null) throw new Error('Sign in.');
105
+ await updateWorkspace(draft.id, { name: draft.name.trim() });
106
+ })());
107
+
108
+ // ✓ right
109
+ const draft = state.value;
110
+ if (draft?.kind !== 'organization' || !draft.id) return;
111
+ ev.detail.until(updateWorkspace(draft.id, { name: draft.name.trim() }));
112
+
113
+ // ✓ cross-component invariant: reject inline
114
+ const parent = ws.legalEntity.value;
115
+ if (parent?.kind !== 'legalEntity') {
116
+ ev.detail.until(Promise.reject(new Error('Pick a legal entity first.')));
117
+ return;
118
+ }
119
+ ev.detail.until(createWorkspace(/* ...assembled with parent.id... */));
120
+ ```
121
+
88
122
  ## CSS state hooks (free)
89
123
 
90
124
  Every field broadcasts these via `:state(...)`:
package/dist/slider.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-BF3Vj8_c.cjs`),t=require(`./active-host-jH3iloCR.cjs`);let n=require(`rxjs`),r=require(`rxjs/operators`),i=require(`lit/decorators.js`),a=require(`lit`),o=require(`lit/directives/cache.js`);var s=class extends e.c{constructor(...e){super(...e),this.type=`content`,this.src=``,this.alt=``,this.controls=!0,this.autoplay=!1,this.loop=!1,this.muted=!1,this.fit=`cover`}static{this.styles=[a.css`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./SchmancyElement-DhSiMp6Y.cjs`);require(`./mixins-YQI9JogS.cjs`);let t=require(`rxjs`),n=require(`rxjs/operators`),r=require(`lit/decorators.js`),i=require(`lit`),a=require(`lit/directives/cache.js`);var o=class extends e.t{constructor(...e){super(...e),this.type=`content`,this.src=``,this.alt=``,this.controls=!0,this.autoplay=!1,this.loop=!1,this.muted=!1,this.fit=`cover`}static{this.styles=[i.css`
2
2
  :host {
3
3
  display: block;
4
4
  scroll-snap-align: center; /* If your slider uses scroll-snap */
@@ -10,7 +10,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./ch
10
10
  height: auto;
11
11
  object-fit: var(--object-fit, cover);
12
12
  }
13
- `]}render(){return a.html` <div style="--object-fit: ${this.fit}">${(0,o.cache)(this.renderSlide())}</div> `}renderSlide(){switch(this.type){case`image`:return a.html` <img class="slide" src="${this.src}" alt="${this.alt}" loading="lazy" /> `;case`video`:return a.html`
13
+ `]}render(){return i.html` <div style="--object-fit: ${this.fit}">${(0,a.cache)(this.renderSlide())}</div> `}renderSlide(){switch(this.type){case`image`:return i.html` <img class="slide" src="${this.src}" alt="${this.alt}" loading="lazy" /> `;case`video`:return i.html`
14
14
  <video
15
15
  class="slide"
16
16
  src="${this.src}"
@@ -21,7 +21,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./ch
21
21
  >
22
22
  Your browser does not support HTML video.
23
23
  </video>
24
- `;default:return a.html`<slot></slot>`}}};t.a([(0,i.property)({type:String})],s.prototype,`type`,void 0),t.a([(0,i.property)({type:String})],s.prototype,`src`,void 0),t.a([(0,i.property)({type:String})],s.prototype,`alt`,void 0),t.a([(0,i.property)({type:Boolean})],s.prototype,`controls`,void 0),t.a([(0,i.property)({type:Boolean})],s.prototype,`autoplay`,void 0),t.a([(0,i.property)({type:Boolean})],s.prototype,`loop`,void 0),t.a([(0,i.property)({type:Boolean})],s.prototype,`muted`,void 0),t.a([(0,i.property)({type:String})],s.prototype,`fit`,void 0),s=t.a([(0,i.customElement)(`schmancy-slide`)],s);var c=class extends e.c{constructor(...e){super(...e),this.selectedIndex=0,this.showArrows=!0}static{this.styles=[a.css`
24
+ `;default:return i.html`<slot></slot>`}}};e.p([(0,r.property)({type:String})],o.prototype,`type`,void 0),e.p([(0,r.property)({type:String})],o.prototype,`src`,void 0),e.p([(0,r.property)({type:String})],o.prototype,`alt`,void 0),e.p([(0,r.property)({type:Boolean})],o.prototype,`controls`,void 0),e.p([(0,r.property)({type:Boolean})],o.prototype,`autoplay`,void 0),e.p([(0,r.property)({type:Boolean})],o.prototype,`loop`,void 0),e.p([(0,r.property)({type:Boolean})],o.prototype,`muted`,void 0),e.p([(0,r.property)({type:String})],o.prototype,`fit`,void 0),o=e.p([(0,r.customElement)(`schmancy-slide`)],o);var s=class extends e.t{constructor(...e){super(...e),this.selectedIndex=0,this.showArrows=!0}static{this.styles=[i.css`
25
25
  .slider {
26
26
  /* Lay out slides horizontally, one after another */
27
27
  display: flex;
@@ -46,7 +46,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./ch
46
46
  flex: 0 0 100%;
47
47
  box-sizing: border-box;
48
48
  }
49
- `]}firstUpdated(){this.slider.scrollLeft=0,(0,n.fromEvent)(this.slider,`scroll`).pipe((0,r.throttleTime)(100,void 0,{trailing:!0})).subscribe(()=>{this.updateSelectedIndexOnScroll()})}updateSelectedIndexOnScroll(){let e=this.defaultSlot?.assignedElements({flatten:!0})??[];if(!e.length)return;let t=this.selectedIndex,n=this.slider.scrollLeft+this.slider.clientWidth/2,r=0,i=1/0;e.forEach((e,t)=>{let a=e.offsetLeft+e.clientWidth/2,o=Math.abs(n-a);o<i&&(i=o,r=t)}),this.selectedIndex=r,this.selectedIndex!==t&&this.dispatchEvent(new CustomEvent(`slide-changed`,{detail:{index:this.selectedIndex}}))}goToSlide(e){let t=this.defaultSlot?.assignedElements({flatten:!0})??[];t[e]&&this.slider.scrollTo({left:t[e].offsetLeft,behavior:`smooth`})}onPrevClick(){this.goToSlide(this.selectedIndex-1)}onNextClick(){let e=this.defaultSlot?.assignedElements({flatten:!0})??[];this.selectedIndex<e.length-1&&this.goToSlide(this.selectedIndex+1)}render(){let e=this.defaultSlot?.assignedElements({flatten:!0})??[];return a.html`
49
+ `]}firstUpdated(){this.slider.scrollLeft=0,(0,t.fromEvent)(this.slider,`scroll`).pipe((0,n.throttleTime)(100,void 0,{trailing:!0})).subscribe(()=>{this.updateSelectedIndexOnScroll()})}updateSelectedIndexOnScroll(){let e=this.defaultSlot?.assignedElements({flatten:!0})??[];if(!e.length)return;let t=this.selectedIndex,n=this.slider.scrollLeft+this.slider.clientWidth/2,r=0,i=1/0;e.forEach((e,t)=>{let a=e.offsetLeft+e.clientWidth/2,o=Math.abs(n-a);o<i&&(i=o,r=t)}),this.selectedIndex=r,this.selectedIndex!==t&&this.dispatchEvent(new CustomEvent(`slide-changed`,{detail:{index:this.selectedIndex}}))}goToSlide(e){let t=this.defaultSlot?.assignedElements({flatten:!0})??[];t[e]&&this.slider.scrollTo({left:t[e].offsetLeft,behavior:`smooth`})}onPrevClick(){this.goToSlide(this.selectedIndex-1)}onNextClick(){let e=this.defaultSlot?.assignedElements({flatten:!0})??[];this.selectedIndex<e.length-1&&this.goToSlide(this.selectedIndex+1)}render(){let e=this.defaultSlot?.assignedElements({flatten:!0})??[];return i.html`
50
50
  <div class="relative inset-0">
51
51
  <!-- The scrollable track -->
52
52
  <div class="slider" id="slider">
@@ -54,7 +54,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./ch
54
54
  </div>
55
55
 
56
56
  <!-- Next/Prev Buttons (Optional) -->
57
- ${this.showArrows?a.html`
57
+ ${this.showArrows?i.html`
58
58
  <schmancy-icon-button
59
59
  class="absolute left-2 top-1/2 -translate-y-1/2"
60
60
  @click=${this.onPrevClick}
@@ -73,10 +73,10 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./ch
73
73
 
74
74
  <!-- Dots / indicators -->
75
75
  <div class="absolute bottom-4 left-1/2 -translate-x-1/2 flex space-x-2">
76
- ${e.map((e,t)=>a.html`
76
+ ${e.map((e,t)=>i.html`
77
77
  <schmancy-button .variant=${t===this.selectedIndex?`filled tonal`:`outlined`} class="rounded-full ">
78
78
  </schmancy-button>
79
79
  `)}
80
80
  </div>
81
81
  </div>
82
- `}};t.a([(0,i.state)()],c.prototype,`selectedIndex`,void 0),t.a([(0,i.property)({type:Boolean})],c.prototype,`showArrows`,void 0),t.a([(0,i.query)(`#slider`)],c.prototype,`slider`,void 0),t.a([(0,i.query)(`slot`)],c.prototype,`defaultSlot`,void 0),c=t.a([(0,i.customElement)(`schmancy-slider`)],c),Object.defineProperty(exports,`SchmancySlide`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`SchmancySlider`,{enumerable:!0,get:function(){return c}});
82
+ `}};e.p([(0,r.state)()],s.prototype,`selectedIndex`,void 0),e.p([(0,r.property)({type:Boolean})],s.prototype,`showArrows`,void 0),e.p([(0,r.query)(`#slider`)],s.prototype,`slider`,void 0),e.p([(0,r.query)(`slot`)],s.prototype,`defaultSlot`,void 0),s=e.p([(0,r.customElement)(`schmancy-slider`)],s),Object.defineProperty(exports,`SchmancySlide`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`SchmancySlider`,{enumerable:!0,get:function(){return s}});
@@ -1 +1 @@
1
- {"version":3,"file":"slider.cjs","names":[],"sources":["../src/slider/slide.ts","../src/slider/slider.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { cache } from 'lit/directives/cache.js'\n\n/**\n * Supported slide \"types.\"\n * - 'image': Renders an <img>\n * - 'video': Renders a <video>\n * - 'content': Renders a <slot> (the default)\n */\ntype SlideType = 'image' | 'video' | 'content'\n\n/**\n * Allowed values for the 'fit' property,\n * which maps to CSS object-fit.\n */\ntype ObjectFit = 'cover' | 'contain' | 'fill' | 'scale-down' | 'none'\n\n@customElement('schmancy-slide')\nexport class SchmancySlide extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: block;\n\t\tscroll-snap-align: center; /* If your slider uses scroll-snap */\n\t}\n\n\t.slide {\n\t\tdisplay: block;\n\t\twidth: 100%;\n\t\theight: auto;\n\t\tobject-fit: var(--object-fit, cover);\n\t}\n`]\n\n\t/**\n\t * Determines how this slide should be rendered.\n\t * Defaults to 'content' if not provided.\n\t */\n\t@property({ type: String }) type: SlideType = 'content'\n\n\t/**\n\t * Source for images or videos (if `type` is 'image' or 'video').\n\t */\n\t@property({ type: String }) src: string = ''\n\n\t/**\n\t * Alternate text for images.\n\t */\n\t@property({ type: String }) alt: string = ''\n\n\t/**\n\t * Whether to show default video controls (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) controls = true\n\n\t/**\n\t * Whether the video should autoplay (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) autoplay = false\n\n\t/**\n\t * Whether the video should loop (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) loop = false\n\n\t/**\n\t * Whether the video is muted (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) muted = false\n\n\t/**\n\t * CSS `object-fit` property, applied to images/videos.\n\t */\n\t@property({ type: String }) fit: ObjectFit = 'cover'\n\n\trender() {\n\t\treturn html` <div style=\"--object-fit: ${this.fit}\">${cache(this.renderSlide())}</div> `\n\t}\n\n\tprivate renderSlide() {\n\t\tswitch (this.type) {\n\t\t\tcase 'image':\n\t\t\t\treturn html` <img class=\"slide\" src=\"${this.src}\" alt=\"${this.alt}\" loading=\"lazy\" /> `\n\t\t\tcase 'video':\n\t\t\t\treturn html`\n\t\t\t\t\t<video\n\t\t\t\t\t\tclass=\"slide\"\n\t\t\t\t\t\tsrc=\"${this.src}\"\n\t\t\t\t\t\t?controls=\"${this.controls}\"\n\t\t\t\t\t\t?autoplay=\"${this.autoplay}\"\n\t\t\t\t\t\t?loop=\"${this.loop}\"\n\t\t\t\t\t\t?muted=\"${this.muted}\"\n\t\t\t\t\t>\n\t\t\t\t\t\tYour browser does not support HTML video.\n\t\t\t\t\t</video>\n\t\t\t\t`\n\t\t\tcase 'content':\n\t\t\tdefault:\n\t\t\t\treturn html`<slot></slot>`\n\t\t}\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-slide': SchmancySlide\n\t}\n}\n","import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { fromEvent } from 'rxjs'\nimport { throttleTime } from 'rxjs/operators'\n\n@customElement('schmancy-slider')\nexport class SchmancySlider extends SchmancyElement {\n\tstatic styles = [css`\n\t.slider {\n\t\t/* Lay out slides horizontally, one after another */\n\t\tdisplay: flex;\n\t\toverflow-x: auto;\n\n\t\t/* Optional: scroll snapping */\n\t\tscroll-snap-type: x mandatory;\n\n\t\t/* Hide scrollbars */\n\t\t-ms-overflow-style: none; /* IE and Edge */\n\t\tscrollbar-width: none; /* Firefox */\n\t}\n\t.slider::-webkit-scrollbar {\n\t\tdisplay: none; /* Chrome, Safari, Opera */\n\t}\n\n\t/* \n Ensure each slide takes up the full slider width.\n \"schmancy-slide\" is the child custom element.\n */\n\t::slotted(schmancy-slide) {\n\t\tflex: 0 0 100%;\n\t\tbox-sizing: border-box;\n\t}\n`]\n\n\t/**\n\t * Currently centered slide index\n\t */\n\t@state() private selectedIndex: number = 0\n\n\t/**\n\t * If true, renders next/prev buttons\n\t */\n\t@property({ type: Boolean }) showArrows: boolean = true\n\n\t@query('#slider') private slider!: HTMLDivElement\n\t@query('slot') private defaultSlot!: HTMLSlotElement\n\n\tprotected firstUpdated() {\n\t\t// Start at leftmost position\n\t\tthis.slider.scrollLeft = 0\n\n\t\t// Throttle scroll events to update selected index\n\t\tfromEvent(this.slider, 'scroll')\n\t\t\t.pipe(throttleTime(100, undefined, { trailing: true }))\n\t\t\t.subscribe(() => {\n\t\t\t\tthis.updateSelectedIndexOnScroll()\n\t\t\t})\n\t}\n\n\tprivate updateSelectedIndexOnScroll() {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\t\tif (!slides.length) return\n\n\t\tconst oldIndex = this.selectedIndex\n\n\t\t// Center of the slider’s visible area\n\t\tconst sliderCenter = this.slider.scrollLeft + this.slider.clientWidth / 2\n\n\t\tlet closestIndex = 0\n\t\tlet closestDistance = Infinity\n\n\t\tslides.forEach((slide, index) => {\n\t\t\tconst itemStart = (slide as HTMLElement).offsetLeft\n\t\t\tconst itemCenter = itemStart + slide.clientWidth / 2\n\t\t\tconst distance = Math.abs(sliderCenter - itemCenter)\n\n\t\t\tif (distance < closestDistance) {\n\t\t\t\tclosestDistance = distance\n\t\t\t\tclosestIndex = index\n\t\t\t}\n\t\t})\n\n\t\tthis.selectedIndex = closestIndex\n\n\t\t// If the index changed, dispatch event\n\t\tif (this.selectedIndex !== oldIndex) {\n\t\t\tthis.dispatchEvent(\n\t\t\t\tnew CustomEvent('slide-changed', {\n\t\t\t\t\tdetail: { index: this.selectedIndex },\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate goToSlide(newIndex: number) {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\t\tif (!slides[newIndex]) return\n\n\t\tthis.slider.scrollTo({\n\t\t\tleft: (slides[newIndex] as HTMLElement).offsetLeft,\n\t\t\tbehavior: 'smooth',\n\t\t})\n\t}\n\n\tprivate onPrevClick() {\n\t\tthis.goToSlide(this.selectedIndex - 1)\n\t}\n\n\tprivate onNextClick() {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\t\tif (this.selectedIndex < slides.length - 1) {\n\t\t\tthis.goToSlide(this.selectedIndex + 1)\n\t\t}\n\t}\n\n\trender() {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\n\t\treturn html`\n\t\t\t<div class=\"relative inset-0\">\n\t\t\t\t<!-- The scrollable track -->\n\t\t\t\t<div class=\"slider\" id=\"slider\">\n\t\t\t\t\t<slot></slot>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Next/Prev Buttons (Optional) -->\n\t\t\t\t${this.showArrows\n\t\t\t\t\t? html`\n\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\tclass=\"absolute left-2 top-1/2 -translate-y-1/2\"\n\t\t\t\t\t\t\t\t@click=${this.onPrevClick}\n\t\t\t\t\t\t\t\t?disabled=${this.selectedIndex === 0}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tchevron_left\n\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\tclass=\"absolute right-2 top-1/2 -translate-y-1/2\"\n\t\t\t\t\t\t\t\t@click=${this.onNextClick}\n\t\t\t\t\t\t\t\t?disabled=${this.selectedIndex === slides.length - 1}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tchevron_right\n\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t`\n\t\t\t\t\t: null}\n\n\t\t\t\t<!-- Dots / indicators -->\n\t\t\t\t<div class=\"absolute bottom-4 left-1/2 -translate-x-1/2 flex space-x-2\">\n\t\t\t\t\t${slides.map((_, index) => {\n\t\t\t\t\t\tconst isSelected = index === this.selectedIndex\n\t\t\t\t\t\treturn html`\n\t\t\t\t\t\t\t<schmancy-button .variant=${isSelected ? 'filled tonal' : 'outlined'} class=\"rounded-full \">\n\t\t\t\t\t\t\t</schmancy-button>\n\t\t\t\t\t\t`\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-slider': SchmancySlider\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"slider.cjs","names":[],"sources":["../src/slider/slide.ts","../src/slider/slider.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { cache } from 'lit/directives/cache.js'\n\n/**\n * Supported slide \"types.\"\n * - 'image': Renders an <img>\n * - 'video': Renders a <video>\n * - 'content': Renders a <slot> (the default)\n */\ntype SlideType = 'image' | 'video' | 'content'\n\n/**\n * Allowed values for the 'fit' property,\n * which maps to CSS object-fit.\n */\ntype ObjectFit = 'cover' | 'contain' | 'fill' | 'scale-down' | 'none'\n\n@customElement('schmancy-slide')\nexport class SchmancySlide extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: block;\n\t\tscroll-snap-align: center; /* If your slider uses scroll-snap */\n\t}\n\n\t.slide {\n\t\tdisplay: block;\n\t\twidth: 100%;\n\t\theight: auto;\n\t\tobject-fit: var(--object-fit, cover);\n\t}\n`]\n\n\t/**\n\t * Determines how this slide should be rendered.\n\t * Defaults to 'content' if not provided.\n\t */\n\t@property({ type: String }) type: SlideType = 'content'\n\n\t/**\n\t * Source for images or videos (if `type` is 'image' or 'video').\n\t */\n\t@property({ type: String }) src: string = ''\n\n\t/**\n\t * Alternate text for images.\n\t */\n\t@property({ type: String }) alt: string = ''\n\n\t/**\n\t * Whether to show default video controls (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) controls = true\n\n\t/**\n\t * Whether the video should autoplay (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) autoplay = false\n\n\t/**\n\t * Whether the video should loop (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) loop = false\n\n\t/**\n\t * Whether the video is muted (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) muted = false\n\n\t/**\n\t * CSS `object-fit` property, applied to images/videos.\n\t */\n\t@property({ type: String }) fit: ObjectFit = 'cover'\n\n\trender() {\n\t\treturn html` <div style=\"--object-fit: ${this.fit}\">${cache(this.renderSlide())}</div> `\n\t}\n\n\tprivate renderSlide() {\n\t\tswitch (this.type) {\n\t\t\tcase 'image':\n\t\t\t\treturn html` <img class=\"slide\" src=\"${this.src}\" alt=\"${this.alt}\" loading=\"lazy\" /> `\n\t\t\tcase 'video':\n\t\t\t\treturn html`\n\t\t\t\t\t<video\n\t\t\t\t\t\tclass=\"slide\"\n\t\t\t\t\t\tsrc=\"${this.src}\"\n\t\t\t\t\t\t?controls=\"${this.controls}\"\n\t\t\t\t\t\t?autoplay=\"${this.autoplay}\"\n\t\t\t\t\t\t?loop=\"${this.loop}\"\n\t\t\t\t\t\t?muted=\"${this.muted}\"\n\t\t\t\t\t>\n\t\t\t\t\t\tYour browser does not support HTML video.\n\t\t\t\t\t</video>\n\t\t\t\t`\n\t\t\tcase 'content':\n\t\t\tdefault:\n\t\t\t\treturn html`<slot></slot>`\n\t\t}\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-slide': SchmancySlide\n\t}\n}\n","import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { fromEvent } from 'rxjs'\nimport { throttleTime } from 'rxjs/operators'\n\n@customElement('schmancy-slider')\nexport class SchmancySlider extends SchmancyElement {\n\tstatic styles = [css`\n\t.slider {\n\t\t/* Lay out slides horizontally, one after another */\n\t\tdisplay: flex;\n\t\toverflow-x: auto;\n\n\t\t/* Optional: scroll snapping */\n\t\tscroll-snap-type: x mandatory;\n\n\t\t/* Hide scrollbars */\n\t\t-ms-overflow-style: none; /* IE and Edge */\n\t\tscrollbar-width: none; /* Firefox */\n\t}\n\t.slider::-webkit-scrollbar {\n\t\tdisplay: none; /* Chrome, Safari, Opera */\n\t}\n\n\t/* \n Ensure each slide takes up the full slider width.\n \"schmancy-slide\" is the child custom element.\n */\n\t::slotted(schmancy-slide) {\n\t\tflex: 0 0 100%;\n\t\tbox-sizing: border-box;\n\t}\n`]\n\n\t/**\n\t * Currently centered slide index\n\t */\n\t@state() private selectedIndex: number = 0\n\n\t/**\n\t * If true, renders next/prev buttons\n\t */\n\t@property({ type: Boolean }) showArrows: boolean = true\n\n\t@query('#slider') private slider!: HTMLDivElement\n\t@query('slot') private defaultSlot!: HTMLSlotElement\n\n\tprotected firstUpdated() {\n\t\t// Start at leftmost position\n\t\tthis.slider.scrollLeft = 0\n\n\t\t// Throttle scroll events to update selected index\n\t\tfromEvent(this.slider, 'scroll')\n\t\t\t.pipe(throttleTime(100, undefined, { trailing: true }))\n\t\t\t.subscribe(() => {\n\t\t\t\tthis.updateSelectedIndexOnScroll()\n\t\t\t})\n\t}\n\n\tprivate updateSelectedIndexOnScroll() {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\t\tif (!slides.length) return\n\n\t\tconst oldIndex = this.selectedIndex\n\n\t\t// Center of the slider’s visible area\n\t\tconst sliderCenter = this.slider.scrollLeft + this.slider.clientWidth / 2\n\n\t\tlet closestIndex = 0\n\t\tlet closestDistance = Infinity\n\n\t\tslides.forEach((slide, index) => {\n\t\t\tconst itemStart = (slide as HTMLElement).offsetLeft\n\t\t\tconst itemCenter = itemStart + slide.clientWidth / 2\n\t\t\tconst distance = Math.abs(sliderCenter - itemCenter)\n\n\t\t\tif (distance < closestDistance) {\n\t\t\t\tclosestDistance = distance\n\t\t\t\tclosestIndex = index\n\t\t\t}\n\t\t})\n\n\t\tthis.selectedIndex = closestIndex\n\n\t\t// If the index changed, dispatch event\n\t\tif (this.selectedIndex !== oldIndex) {\n\t\t\tthis.dispatchEvent(\n\t\t\t\tnew CustomEvent('slide-changed', {\n\t\t\t\t\tdetail: { index: this.selectedIndex },\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate goToSlide(newIndex: number) {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\t\tif (!slides[newIndex]) return\n\n\t\tthis.slider.scrollTo({\n\t\t\tleft: (slides[newIndex] as HTMLElement).offsetLeft,\n\t\t\tbehavior: 'smooth',\n\t\t})\n\t}\n\n\tprivate onPrevClick() {\n\t\tthis.goToSlide(this.selectedIndex - 1)\n\t}\n\n\tprivate onNextClick() {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\t\tif (this.selectedIndex < slides.length - 1) {\n\t\t\tthis.goToSlide(this.selectedIndex + 1)\n\t\t}\n\t}\n\n\trender() {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\n\t\treturn html`\n\t\t\t<div class=\"relative inset-0\">\n\t\t\t\t<!-- The scrollable track -->\n\t\t\t\t<div class=\"slider\" id=\"slider\">\n\t\t\t\t\t<slot></slot>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Next/Prev Buttons (Optional) -->\n\t\t\t\t${this.showArrows\n\t\t\t\t\t? html`\n\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\tclass=\"absolute left-2 top-1/2 -translate-y-1/2\"\n\t\t\t\t\t\t\t\t@click=${this.onPrevClick}\n\t\t\t\t\t\t\t\t?disabled=${this.selectedIndex === 0}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tchevron_left\n\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\tclass=\"absolute right-2 top-1/2 -translate-y-1/2\"\n\t\t\t\t\t\t\t\t@click=${this.onNextClick}\n\t\t\t\t\t\t\t\t?disabled=${this.selectedIndex === slides.length - 1}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tchevron_right\n\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t`\n\t\t\t\t\t: null}\n\n\t\t\t\t<!-- Dots / indicators -->\n\t\t\t\t<div class=\"absolute bottom-4 left-1/2 -translate-x-1/2 flex space-x-2\">\n\t\t\t\t\t${slides.map((_, index) => {\n\t\t\t\t\t\tconst isSelected = index === this.selectedIndex\n\t\t\t\t\t\treturn html`\n\t\t\t\t\t\t\t<schmancy-button .variant=${isSelected ? 'filled tonal' : 'outlined'} class=\"rounded-full \">\n\t\t\t\t\t\t\t</schmancy-button>\n\t\t\t\t\t\t`\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-slider': SchmancySlider\n\t}\n}\n"],"mappings":"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"}
package/dist/slider.js CHANGED
@@ -1,11 +1,11 @@
1
- import { c as e } from "./mixins-8dT5j6CS.js";
2
- import { a as t } from "./active-host-BP0zy_Y9.js";
1
+ import { p as e, t } from "./SchmancyElement-BQ4DFufc.js";
2
+ import "./mixins-BYfSDvbP.js";
3
3
  import { fromEvent as n } from "rxjs";
4
4
  import { throttleTime as r } from "rxjs/operators";
5
5
  import { customElement as i, property as a, query as o, state as s } from "lit/decorators.js";
6
6
  import { css as c, html as l } from "lit";
7
7
  import { cache as u } from "lit/directives/cache.js";
8
- var d = class extends e {
8
+ var d = class extends t {
9
9
  constructor(...e) {
10
10
  super(...e), this.type = "content", this.src = "", this.alt = "", this.controls = !0, this.autoplay = !1, this.loop = !1, this.muted = !1, this.fit = "cover";
11
11
  }
@@ -46,8 +46,8 @@ var d = class extends e {
46
46
  }
47
47
  }
48
48
  };
49
- t([a({ type: String })], d.prototype, "type", void 0), t([a({ type: String })], d.prototype, "src", void 0), t([a({ type: String })], d.prototype, "alt", void 0), t([a({ type: Boolean })], d.prototype, "controls", void 0), t([a({ type: Boolean })], d.prototype, "autoplay", void 0), t([a({ type: Boolean })], d.prototype, "loop", void 0), t([a({ type: Boolean })], d.prototype, "muted", void 0), t([a({ type: String })], d.prototype, "fit", void 0), d = t([i("schmancy-slide")], d);
50
- var f = class extends e {
49
+ e([a({ type: String })], d.prototype, "type", void 0), e([a({ type: String })], d.prototype, "src", void 0), e([a({ type: String })], d.prototype, "alt", void 0), e([a({ type: Boolean })], d.prototype, "controls", void 0), e([a({ type: Boolean })], d.prototype, "autoplay", void 0), e([a({ type: Boolean })], d.prototype, "loop", void 0), e([a({ type: Boolean })], d.prototype, "muted", void 0), e([a({ type: String })], d.prototype, "fit", void 0), d = e([i("schmancy-slide")], d);
50
+ var f = class extends t {
51
51
  constructor(...e) {
52
52
  super(...e), this.selectedIndex = 0, this.showArrows = !0;
53
53
  }
@@ -145,5 +145,5 @@ var f = class extends e {
145
145
  `;
146
146
  }
147
147
  };
148
- t([s()], f.prototype, "selectedIndex", void 0), t([a({ type: Boolean })], f.prototype, "showArrows", void 0), t([o("#slider")], f.prototype, "slider", void 0), t([o("slot")], f.prototype, "defaultSlot", void 0), f = t([i("schmancy-slider")], f);
148
+ e([s()], f.prototype, "selectedIndex", void 0), e([a({ type: Boolean })], f.prototype, "showArrows", void 0), e([o("#slider")], f.prototype, "slider", void 0), e([o("slot")], f.prototype, "defaultSlot", void 0), f = e([i("schmancy-slider")], f);
149
149
  export { d as SchmancySlide, f as SchmancySlider };
@@ -1 +1 @@
1
- {"version":3,"file":"slider.js","names":[],"sources":["../src/slider/slide.ts","../src/slider/slider.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { cache } from 'lit/directives/cache.js'\n\n/**\n * Supported slide \"types.\"\n * - 'image': Renders an <img>\n * - 'video': Renders a <video>\n * - 'content': Renders a <slot> (the default)\n */\ntype SlideType = 'image' | 'video' | 'content'\n\n/**\n * Allowed values for the 'fit' property,\n * which maps to CSS object-fit.\n */\ntype ObjectFit = 'cover' | 'contain' | 'fill' | 'scale-down' | 'none'\n\n@customElement('schmancy-slide')\nexport class SchmancySlide extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: block;\n\t\tscroll-snap-align: center; /* If your slider uses scroll-snap */\n\t}\n\n\t.slide {\n\t\tdisplay: block;\n\t\twidth: 100%;\n\t\theight: auto;\n\t\tobject-fit: var(--object-fit, cover);\n\t}\n`]\n\n\t/**\n\t * Determines how this slide should be rendered.\n\t * Defaults to 'content' if not provided.\n\t */\n\t@property({ type: String }) type: SlideType = 'content'\n\n\t/**\n\t * Source for images or videos (if `type` is 'image' or 'video').\n\t */\n\t@property({ type: String }) src: string = ''\n\n\t/**\n\t * Alternate text for images.\n\t */\n\t@property({ type: String }) alt: string = ''\n\n\t/**\n\t * Whether to show default video controls (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) controls = true\n\n\t/**\n\t * Whether the video should autoplay (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) autoplay = false\n\n\t/**\n\t * Whether the video should loop (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) loop = false\n\n\t/**\n\t * Whether the video is muted (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) muted = false\n\n\t/**\n\t * CSS `object-fit` property, applied to images/videos.\n\t */\n\t@property({ type: String }) fit: ObjectFit = 'cover'\n\n\trender() {\n\t\treturn html` <div style=\"--object-fit: ${this.fit}\">${cache(this.renderSlide())}</div> `\n\t}\n\n\tprivate renderSlide() {\n\t\tswitch (this.type) {\n\t\t\tcase 'image':\n\t\t\t\treturn html` <img class=\"slide\" src=\"${this.src}\" alt=\"${this.alt}\" loading=\"lazy\" /> `\n\t\t\tcase 'video':\n\t\t\t\treturn html`\n\t\t\t\t\t<video\n\t\t\t\t\t\tclass=\"slide\"\n\t\t\t\t\t\tsrc=\"${this.src}\"\n\t\t\t\t\t\t?controls=\"${this.controls}\"\n\t\t\t\t\t\t?autoplay=\"${this.autoplay}\"\n\t\t\t\t\t\t?loop=\"${this.loop}\"\n\t\t\t\t\t\t?muted=\"${this.muted}\"\n\t\t\t\t\t>\n\t\t\t\t\t\tYour browser does not support HTML video.\n\t\t\t\t\t</video>\n\t\t\t\t`\n\t\t\tcase 'content':\n\t\t\tdefault:\n\t\t\t\treturn html`<slot></slot>`\n\t\t}\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-slide': SchmancySlide\n\t}\n}\n","import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { fromEvent } from 'rxjs'\nimport { throttleTime } from 'rxjs/operators'\n\n@customElement('schmancy-slider')\nexport class SchmancySlider extends SchmancyElement {\n\tstatic styles = [css`\n\t.slider {\n\t\t/* Lay out slides horizontally, one after another */\n\t\tdisplay: flex;\n\t\toverflow-x: auto;\n\n\t\t/* Optional: scroll snapping */\n\t\tscroll-snap-type: x mandatory;\n\n\t\t/* Hide scrollbars */\n\t\t-ms-overflow-style: none; /* IE and Edge */\n\t\tscrollbar-width: none; /* Firefox */\n\t}\n\t.slider::-webkit-scrollbar {\n\t\tdisplay: none; /* Chrome, Safari, Opera */\n\t}\n\n\t/* \n Ensure each slide takes up the full slider width.\n \"schmancy-slide\" is the child custom element.\n */\n\t::slotted(schmancy-slide) {\n\t\tflex: 0 0 100%;\n\t\tbox-sizing: border-box;\n\t}\n`]\n\n\t/**\n\t * Currently centered slide index\n\t */\n\t@state() private selectedIndex: number = 0\n\n\t/**\n\t * If true, renders next/prev buttons\n\t */\n\t@property({ type: Boolean }) showArrows: boolean = true\n\n\t@query('#slider') private slider!: HTMLDivElement\n\t@query('slot') private defaultSlot!: HTMLSlotElement\n\n\tprotected firstUpdated() {\n\t\t// Start at leftmost position\n\t\tthis.slider.scrollLeft = 0\n\n\t\t// Throttle scroll events to update selected index\n\t\tfromEvent(this.slider, 'scroll')\n\t\t\t.pipe(throttleTime(100, undefined, { trailing: true }))\n\t\t\t.subscribe(() => {\n\t\t\t\tthis.updateSelectedIndexOnScroll()\n\t\t\t})\n\t}\n\n\tprivate updateSelectedIndexOnScroll() {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\t\tif (!slides.length) return\n\n\t\tconst oldIndex = this.selectedIndex\n\n\t\t// Center of the slider’s visible area\n\t\tconst sliderCenter = this.slider.scrollLeft + this.slider.clientWidth / 2\n\n\t\tlet closestIndex = 0\n\t\tlet closestDistance = Infinity\n\n\t\tslides.forEach((slide, index) => {\n\t\t\tconst itemStart = (slide as HTMLElement).offsetLeft\n\t\t\tconst itemCenter = itemStart + slide.clientWidth / 2\n\t\t\tconst distance = Math.abs(sliderCenter - itemCenter)\n\n\t\t\tif (distance < closestDistance) {\n\t\t\t\tclosestDistance = distance\n\t\t\t\tclosestIndex = index\n\t\t\t}\n\t\t})\n\n\t\tthis.selectedIndex = closestIndex\n\n\t\t// If the index changed, dispatch event\n\t\tif (this.selectedIndex !== oldIndex) {\n\t\t\tthis.dispatchEvent(\n\t\t\t\tnew CustomEvent('slide-changed', {\n\t\t\t\t\tdetail: { index: this.selectedIndex },\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate goToSlide(newIndex: number) {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\t\tif (!slides[newIndex]) return\n\n\t\tthis.slider.scrollTo({\n\t\t\tleft: (slides[newIndex] as HTMLElement).offsetLeft,\n\t\t\tbehavior: 'smooth',\n\t\t})\n\t}\n\n\tprivate onPrevClick() {\n\t\tthis.goToSlide(this.selectedIndex - 1)\n\t}\n\n\tprivate onNextClick() {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\t\tif (this.selectedIndex < slides.length - 1) {\n\t\t\tthis.goToSlide(this.selectedIndex + 1)\n\t\t}\n\t}\n\n\trender() {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\n\t\treturn html`\n\t\t\t<div class=\"relative inset-0\">\n\t\t\t\t<!-- The scrollable track -->\n\t\t\t\t<div class=\"slider\" id=\"slider\">\n\t\t\t\t\t<slot></slot>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Next/Prev Buttons (Optional) -->\n\t\t\t\t${this.showArrows\n\t\t\t\t\t? html`\n\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\tclass=\"absolute left-2 top-1/2 -translate-y-1/2\"\n\t\t\t\t\t\t\t\t@click=${this.onPrevClick}\n\t\t\t\t\t\t\t\t?disabled=${this.selectedIndex === 0}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tchevron_left\n\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\tclass=\"absolute right-2 top-1/2 -translate-y-1/2\"\n\t\t\t\t\t\t\t\t@click=${this.onNextClick}\n\t\t\t\t\t\t\t\t?disabled=${this.selectedIndex === slides.length - 1}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tchevron_right\n\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t`\n\t\t\t\t\t: null}\n\n\t\t\t\t<!-- Dots / indicators -->\n\t\t\t\t<div class=\"absolute bottom-4 left-1/2 -translate-x-1/2 flex space-x-2\">\n\t\t\t\t\t${slides.map((_, index) => {\n\t\t\t\t\t\tconst isSelected = index === this.selectedIndex\n\t\t\t\t\t\treturn html`\n\t\t\t\t\t\t\t<schmancy-button .variant=${isSelected ? 'filled tonal' : 'outlined'} class=\"rounded-full \">\n\t\t\t\t\t\t\t</schmancy-button>\n\t\t\t\t\t\t`\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-slider': SchmancySlider\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"slider.js","names":[],"sources":["../src/slider/slide.ts","../src/slider/slider.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { cache } from 'lit/directives/cache.js'\n\n/**\n * Supported slide \"types.\"\n * - 'image': Renders an <img>\n * - 'video': Renders a <video>\n * - 'content': Renders a <slot> (the default)\n */\ntype SlideType = 'image' | 'video' | 'content'\n\n/**\n * Allowed values for the 'fit' property,\n * which maps to CSS object-fit.\n */\ntype ObjectFit = 'cover' | 'contain' | 'fill' | 'scale-down' | 'none'\n\n@customElement('schmancy-slide')\nexport class SchmancySlide extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: block;\n\t\tscroll-snap-align: center; /* If your slider uses scroll-snap */\n\t}\n\n\t.slide {\n\t\tdisplay: block;\n\t\twidth: 100%;\n\t\theight: auto;\n\t\tobject-fit: var(--object-fit, cover);\n\t}\n`]\n\n\t/**\n\t * Determines how this slide should be rendered.\n\t * Defaults to 'content' if not provided.\n\t */\n\t@property({ type: String }) type: SlideType = 'content'\n\n\t/**\n\t * Source for images or videos (if `type` is 'image' or 'video').\n\t */\n\t@property({ type: String }) src: string = ''\n\n\t/**\n\t * Alternate text for images.\n\t */\n\t@property({ type: String }) alt: string = ''\n\n\t/**\n\t * Whether to show default video controls (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) controls = true\n\n\t/**\n\t * Whether the video should autoplay (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) autoplay = false\n\n\t/**\n\t * Whether the video should loop (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) loop = false\n\n\t/**\n\t * Whether the video is muted (if `type` is 'video').\n\t */\n\t@property({ type: Boolean }) muted = false\n\n\t/**\n\t * CSS `object-fit` property, applied to images/videos.\n\t */\n\t@property({ type: String }) fit: ObjectFit = 'cover'\n\n\trender() {\n\t\treturn html` <div style=\"--object-fit: ${this.fit}\">${cache(this.renderSlide())}</div> `\n\t}\n\n\tprivate renderSlide() {\n\t\tswitch (this.type) {\n\t\t\tcase 'image':\n\t\t\t\treturn html` <img class=\"slide\" src=\"${this.src}\" alt=\"${this.alt}\" loading=\"lazy\" /> `\n\t\t\tcase 'video':\n\t\t\t\treturn html`\n\t\t\t\t\t<video\n\t\t\t\t\t\tclass=\"slide\"\n\t\t\t\t\t\tsrc=\"${this.src}\"\n\t\t\t\t\t\t?controls=\"${this.controls}\"\n\t\t\t\t\t\t?autoplay=\"${this.autoplay}\"\n\t\t\t\t\t\t?loop=\"${this.loop}\"\n\t\t\t\t\t\t?muted=\"${this.muted}\"\n\t\t\t\t\t>\n\t\t\t\t\t\tYour browser does not support HTML video.\n\t\t\t\t\t</video>\n\t\t\t\t`\n\t\t\tcase 'content':\n\t\t\tdefault:\n\t\t\t\treturn html`<slot></slot>`\n\t\t}\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-slide': SchmancySlide\n\t}\n}\n","import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { fromEvent } from 'rxjs'\nimport { throttleTime } from 'rxjs/operators'\n\n@customElement('schmancy-slider')\nexport class SchmancySlider extends SchmancyElement {\n\tstatic styles = [css`\n\t.slider {\n\t\t/* Lay out slides horizontally, one after another */\n\t\tdisplay: flex;\n\t\toverflow-x: auto;\n\n\t\t/* Optional: scroll snapping */\n\t\tscroll-snap-type: x mandatory;\n\n\t\t/* Hide scrollbars */\n\t\t-ms-overflow-style: none; /* IE and Edge */\n\t\tscrollbar-width: none; /* Firefox */\n\t}\n\t.slider::-webkit-scrollbar {\n\t\tdisplay: none; /* Chrome, Safari, Opera */\n\t}\n\n\t/* \n Ensure each slide takes up the full slider width.\n \"schmancy-slide\" is the child custom element.\n */\n\t::slotted(schmancy-slide) {\n\t\tflex: 0 0 100%;\n\t\tbox-sizing: border-box;\n\t}\n`]\n\n\t/**\n\t * Currently centered slide index\n\t */\n\t@state() private selectedIndex: number = 0\n\n\t/**\n\t * If true, renders next/prev buttons\n\t */\n\t@property({ type: Boolean }) showArrows: boolean = true\n\n\t@query('#slider') private slider!: HTMLDivElement\n\t@query('slot') private defaultSlot!: HTMLSlotElement\n\n\tprotected firstUpdated() {\n\t\t// Start at leftmost position\n\t\tthis.slider.scrollLeft = 0\n\n\t\t// Throttle scroll events to update selected index\n\t\tfromEvent(this.slider, 'scroll')\n\t\t\t.pipe(throttleTime(100, undefined, { trailing: true }))\n\t\t\t.subscribe(() => {\n\t\t\t\tthis.updateSelectedIndexOnScroll()\n\t\t\t})\n\t}\n\n\tprivate updateSelectedIndexOnScroll() {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\t\tif (!slides.length) return\n\n\t\tconst oldIndex = this.selectedIndex\n\n\t\t// Center of the slider’s visible area\n\t\tconst sliderCenter = this.slider.scrollLeft + this.slider.clientWidth / 2\n\n\t\tlet closestIndex = 0\n\t\tlet closestDistance = Infinity\n\n\t\tslides.forEach((slide, index) => {\n\t\t\tconst itemStart = (slide as HTMLElement).offsetLeft\n\t\t\tconst itemCenter = itemStart + slide.clientWidth / 2\n\t\t\tconst distance = Math.abs(sliderCenter - itemCenter)\n\n\t\t\tif (distance < closestDistance) {\n\t\t\t\tclosestDistance = distance\n\t\t\t\tclosestIndex = index\n\t\t\t}\n\t\t})\n\n\t\tthis.selectedIndex = closestIndex\n\n\t\t// If the index changed, dispatch event\n\t\tif (this.selectedIndex !== oldIndex) {\n\t\t\tthis.dispatchEvent(\n\t\t\t\tnew CustomEvent('slide-changed', {\n\t\t\t\t\tdetail: { index: this.selectedIndex },\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate goToSlide(newIndex: number) {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\t\tif (!slides[newIndex]) return\n\n\t\tthis.slider.scrollTo({\n\t\t\tleft: (slides[newIndex] as HTMLElement).offsetLeft,\n\t\t\tbehavior: 'smooth',\n\t\t})\n\t}\n\n\tprivate onPrevClick() {\n\t\tthis.goToSlide(this.selectedIndex - 1)\n\t}\n\n\tprivate onNextClick() {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\t\tif (this.selectedIndex < slides.length - 1) {\n\t\t\tthis.goToSlide(this.selectedIndex + 1)\n\t\t}\n\t}\n\n\trender() {\n\t\tconst slides = this.defaultSlot?.assignedElements({ flatten: true }) ?? []\n\n\t\treturn html`\n\t\t\t<div class=\"relative inset-0\">\n\t\t\t\t<!-- The scrollable track -->\n\t\t\t\t<div class=\"slider\" id=\"slider\">\n\t\t\t\t\t<slot></slot>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Next/Prev Buttons (Optional) -->\n\t\t\t\t${this.showArrows\n\t\t\t\t\t? html`\n\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\tclass=\"absolute left-2 top-1/2 -translate-y-1/2\"\n\t\t\t\t\t\t\t\t@click=${this.onPrevClick}\n\t\t\t\t\t\t\t\t?disabled=${this.selectedIndex === 0}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tchevron_left\n\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\tclass=\"absolute right-2 top-1/2 -translate-y-1/2\"\n\t\t\t\t\t\t\t\t@click=${this.onNextClick}\n\t\t\t\t\t\t\t\t?disabled=${this.selectedIndex === slides.length - 1}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tchevron_right\n\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t`\n\t\t\t\t\t: null}\n\n\t\t\t\t<!-- Dots / indicators -->\n\t\t\t\t<div class=\"absolute bottom-4 left-1/2 -translate-x-1/2 flex space-x-2\">\n\t\t\t\t\t${slides.map((_, index) => {\n\t\t\t\t\t\tconst isSelected = index === this.selectedIndex\n\t\t\t\t\t\treturn html`\n\t\t\t\t\t\t\t<schmancy-button .variant=${isSelected ? 'filled tonal' : 'outlined'} class=\"rounded-full \">\n\t\t\t\t\t\t\t</schmancy-button>\n\t\t\t\t\t\t`\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-slider': SchmancySlider\n\t}\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { o as e } from "./state-CHbIt2Dw.js";
1
+ import { s as e } from "./state-E0bVrZ7q.js";
2
2
  import { BehaviorSubject as t, distinctUntilChanged as n, map as r, shareReplay as i } from "rxjs";
3
3
  var a = e("schmancy/sound").local({
4
4
  theme: null,