@mhmo91/schmancy 0.10.19 → 0.10.21

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 (371) hide show
  1. package/custom-elements.json +0 -62
  2. package/dist/agent/{overlay.confirm-body-D3jQyXgA.js → overlay.confirm-body-DXus8d-w.js} +1 -1
  3. package/dist/agent/{overlay.confirm-body-D3jQyXgA.js.map → overlay.confirm-body-DXus8d-w.js.map} +1 -1
  4. package/dist/agent/schmancy.agent.js +2043 -2083
  5. package/dist/agent/schmancy.agent.js.map +1 -1
  6. package/dist/agent/schmancy.manifest.json +1 -48
  7. package/dist/area-Cbkt0NX4.cjs +21 -0
  8. package/dist/area-Cbkt0NX4.cjs.map +1 -0
  9. package/dist/{area-BIipuSyO.js → area-Ddk7P5wD.js} +101 -131
  10. package/dist/area-Ddk7P5wD.js.map +1 -0
  11. package/dist/area.cjs +1 -1
  12. package/dist/area.js +1 -1
  13. package/dist/{autocomplete-B8CE5vGw.cjs → autocomplete-CfBFDSc3.cjs} +1 -1
  14. package/dist/{autocomplete-B8CE5vGw.cjs.map → autocomplete-CfBFDSc3.cjs.map} +1 -1
  15. package/dist/{autocomplete-Mrb3koUN.js → autocomplete-Ds3Q2cwR.js} +2 -2
  16. package/dist/{autocomplete-Mrb3koUN.js.map → autocomplete-Ds3Q2cwR.js.map} +1 -1
  17. package/dist/autocomplete.cjs +1 -1
  18. package/dist/autocomplete.js +1 -1
  19. package/dist/avatar.cjs +1 -1
  20. package/dist/avatar.js +1 -1
  21. package/dist/badge.cjs +1 -1
  22. package/dist/badge.js +1 -1
  23. package/dist/{boat-CNWIQPA1.js → boat-BF5P6p_f.js} +1 -1
  24. package/dist/{boat-CNWIQPA1.js.map → boat-BF5P6p_f.js.map} +1 -1
  25. package/dist/{boat-OatK_MGh.cjs → boat-BPN8HLzZ.cjs} +1 -1
  26. package/dist/{boat-OatK_MGh.cjs.map → boat-BPN8HLzZ.cjs.map} +1 -1
  27. package/dist/boat.cjs +1 -1
  28. package/dist/boat.js +1 -1
  29. package/dist/breadcrumb.cjs +1 -1
  30. package/dist/breadcrumb.js +1 -1
  31. package/dist/{busy-Cetzws-m.js → busy-BuACDJy6.js} +1 -1
  32. package/dist/{busy-Cetzws-m.js.map → busy-BuACDJy6.js.map} +1 -1
  33. package/dist/{busy-CMKX4oQf.cjs → busy-C7ejPa-Q.cjs} +1 -1
  34. package/dist/{busy-CMKX4oQf.cjs.map → busy-C7ejPa-Q.cjs.map} +1 -1
  35. package/dist/busy.cjs +1 -1
  36. package/dist/busy.js +1 -1
  37. package/dist/button.cjs +15 -9
  38. package/dist/button.cjs.map +1 -1
  39. package/dist/button.js +15 -9
  40. package/dist/button.js.map +1 -1
  41. package/dist/{card-8VXoo2C_.cjs → card-BIzaLuEg.cjs} +1 -1
  42. package/dist/{card-8VXoo2C_.cjs.map → card-BIzaLuEg.cjs.map} +1 -1
  43. package/dist/{card-D2k3dRL0.js → card-CgQwXO8L.js} +1 -1
  44. package/dist/{card-D2k3dRL0.js.map → card-CgQwXO8L.js.map} +1 -1
  45. package/dist/card.cjs +1 -1
  46. package/dist/card.js +1 -1
  47. package/dist/{checkbox-Cq5wzeaY.cjs → checkbox-BAqE3sTx.cjs} +1 -1
  48. package/dist/{checkbox-Cq5wzeaY.cjs.map → checkbox-BAqE3sTx.cjs.map} +1 -1
  49. package/dist/{checkbox-8hNsBejz.js → checkbox-BNdg57Om.js} +1 -1
  50. package/dist/{checkbox-8hNsBejz.js.map → checkbox-BNdg57Om.js.map} +1 -1
  51. package/dist/checkbox.cjs +1 -1
  52. package/dist/checkbox.js +1 -1
  53. package/dist/{chips-Dx_WvOGk.cjs → chips-DS3y4Lbn.cjs} +2 -4
  54. package/dist/chips-DS3y4Lbn.cjs.map +1 -0
  55. package/dist/{chips-D1kJrbzo.js → chips-DnqLaOb1.js} +3 -5
  56. package/dist/chips-DnqLaOb1.js.map +1 -0
  57. package/dist/chips.cjs +1 -1
  58. package/dist/chips.js +2 -2
  59. package/dist/connectivity.cjs +1 -1
  60. package/dist/connectivity.js +1 -1
  61. package/dist/content-drawer.cjs +1 -1
  62. package/dist/content-drawer.js +1 -1
  63. package/dist/{date-range-H903Vt_r.cjs → date-range-CsJfjbmi.cjs} +1 -1
  64. package/dist/{date-range-H903Vt_r.cjs.map → date-range-CsJfjbmi.cjs.map} +1 -1
  65. package/dist/{date-range-Dv-DM6mB.js → date-range-aPSmSBhk.js} +2 -2
  66. package/dist/{date-range-Dv-DM6mB.js.map → date-range-aPSmSBhk.js.map} +1 -1
  67. package/dist/{date-range-inline-Bvs2ZvEY.cjs → date-range-inline-CAa0_4EI.cjs} +1 -1
  68. package/dist/{date-range-inline-Bvs2ZvEY.cjs.map → date-range-inline-CAa0_4EI.cjs.map} +1 -1
  69. package/dist/{date-range-inline-TWWnTZlw.js → date-range-inline-PeRt1iIF.js} +1 -1
  70. package/dist/{date-range-inline-TWWnTZlw.js.map → date-range-inline-PeRt1iIF.js.map} +1 -1
  71. package/dist/date-range-inline.cjs +1 -1
  72. package/dist/date-range-inline.js +1 -1
  73. package/dist/date-range.cjs +1 -1
  74. package/dist/date-range.js +1 -1
  75. package/dist/delay.cjs +1 -1
  76. package/dist/delay.js +1 -1
  77. package/dist/{details-CwSDur6j.cjs → details-BnXbDpt7.cjs} +2 -2
  78. package/dist/details-BnXbDpt7.cjs.map +1 -0
  79. package/dist/{details-Cpg8sH2F.js → details-BpFjVclg.js} +2 -2
  80. package/dist/details-BpFjVclg.js.map +1 -0
  81. package/dist/details.cjs +1 -1
  82. package/dist/details.js +1 -1
  83. package/dist/directives.cjs +3 -3
  84. package/dist/directives.cjs.map +1 -1
  85. package/dist/directives.js +290 -203
  86. package/dist/directives.js.map +1 -1
  87. package/dist/{divider-BNdVLE0H.cjs → divider-B84lt1A3.cjs} +1 -1
  88. package/dist/{divider-BNdVLE0H.cjs.map → divider-B84lt1A3.cjs.map} +1 -1
  89. package/dist/{divider-Be833gGZ.js → divider-D8cBBkdG.js} +1 -1
  90. package/dist/{divider-Be833gGZ.js.map → divider-D8cBBkdG.js.map} +1 -1
  91. package/dist/divider.cjs +1 -1
  92. package/dist/divider.js +1 -1
  93. package/dist/dropdown.cjs +1 -1
  94. package/dist/dropdown.js +1 -1
  95. package/dist/{expand-CtoffNNj.js → expand-BJiKggfg.js} +2 -2
  96. package/dist/{expand-CtoffNNj.js.map → expand-BJiKggfg.js.map} +1 -1
  97. package/dist/{expand-BP6RLzHw.cjs → expand-DK-O37-j.cjs} +1 -1
  98. package/dist/{expand-BP6RLzHw.cjs.map → expand-DK-O37-j.cjs.map} +1 -1
  99. package/dist/expand.cjs +1 -1
  100. package/dist/expand.js +1 -1
  101. package/dist/{float-KmbhaQHA.js → float-B4FDN40h.js} +1 -1
  102. package/dist/{float-KmbhaQHA.js.map → float-B4FDN40h.js.map} +1 -1
  103. package/dist/{float-CfbQM_2v.cjs → float-RWR6Q1Hh.cjs} +1 -1
  104. package/dist/{float-CfbQM_2v.cjs.map → float-RWR6Q1Hh.cjs.map} +1 -1
  105. package/dist/float.cjs +1 -1
  106. package/dist/float.js +1 -1
  107. package/dist/{form-8IcmP8uV.js → form-Bz5WamuM.js} +8 -8
  108. package/dist/{form-8IcmP8uV.js.map → form-Bz5WamuM.js.map} +1 -1
  109. package/dist/{form-CuBIrKOA.cjs → form-PioZDvzA.cjs} +1 -1
  110. package/dist/{form-CuBIrKOA.cjs.map → form-PioZDvzA.cjs.map} +1 -1
  111. package/dist/form.cjs +1 -1
  112. package/dist/form.js +6 -6
  113. package/dist/handover/agent-runtime-followups.md +1 -1
  114. package/dist/handover/agent-runtime-v1.md +3 -3
  115. package/dist/{icons-D7df1ysG.js → icons-BgUbHwy8.js} +1 -1
  116. package/dist/{icons-D7df1ysG.js.map → icons-BgUbHwy8.js.map} +1 -1
  117. package/dist/{icons-BJld4JHp.cjs → icons-morK4hHz.cjs} +1 -1
  118. package/dist/{icons-BJld4JHp.cjs.map → icons-morK4hHz.cjs.map} +1 -1
  119. package/dist/icons.cjs +1 -1
  120. package/dist/icons.js +1 -1
  121. package/dist/{iframe-GT6D8l5Z.cjs → iframe-BXe1TPx1.cjs} +1 -1
  122. package/dist/{iframe-GT6D8l5Z.cjs.map → iframe-BXe1TPx1.cjs.map} +1 -1
  123. package/dist/{iframe-DAbgW9tT.js → iframe-CByrVlZy.js} +1 -1
  124. package/dist/{iframe-DAbgW9tT.js.map → iframe-CByrVlZy.js.map} +1 -1
  125. package/dist/iframe.cjs +1 -1
  126. package/dist/iframe.js +1 -1
  127. package/dist/index.cjs +1 -1
  128. package/dist/index.js +55 -56
  129. package/dist/{input-BE9wEEw4.cjs → input-BY9OCQWr.cjs} +1 -1
  130. package/dist/{input-BE9wEEw4.cjs.map → input-BY9OCQWr.cjs.map} +1 -1
  131. package/dist/{input-DC6ap_uN.js → input-Q0fm34Co.js} +2 -2
  132. package/dist/{input-DC6ap_uN.js.map → input-Q0fm34Co.js.map} +1 -1
  133. package/dist/{input-chip-MsiMu-b5.cjs → input-chip-BwNf3GD0.cjs} +1 -1
  134. package/dist/{input-chip-MsiMu-b5.cjs.map → input-chip-BwNf3GD0.cjs.map} +1 -1
  135. package/dist/{input-chip-c5n547tg.js → input-chip-CytUirVS.js} +1 -1
  136. package/dist/{input-chip-c5n547tg.js.map → input-chip-CytUirVS.js.map} +1 -1
  137. package/dist/input.cjs +1 -1
  138. package/dist/input.js +1 -1
  139. package/dist/json.cjs +1 -1
  140. package/dist/json.js +2 -2
  141. package/dist/kbd.cjs +1 -1
  142. package/dist/kbd.js +1 -1
  143. package/dist/layout.cjs +26 -1
  144. package/dist/layout.cjs.map +1 -0
  145. package/dist/layout.js +115 -2
  146. package/dist/layout.js.map +1 -0
  147. package/dist/{lightbox-CNX9Eg3U.js → lightbox-Ckvn5YNF.js} +1 -1
  148. package/dist/{lightbox-CNX9Eg3U.js.map → lightbox-Ckvn5YNF.js.map} +1 -1
  149. package/dist/{lightbox-HqJBBjAT.cjs → lightbox-p2E0oVR0.cjs} +1 -1
  150. package/dist/{lightbox-HqJBBjAT.cjs.map → lightbox-p2E0oVR0.cjs.map} +1 -1
  151. package/dist/lightbox.cjs +1 -1
  152. package/dist/lightbox.js +1 -1
  153. package/dist/{list-C76Pb-c1.js → list-CsrPVvmm.js} +1 -1
  154. package/dist/{list-C76Pb-c1.js.map → list-CsrPVvmm.js.map} +1 -1
  155. package/dist/{list-bhyuQSyO.cjs → list-r57UFHu3.cjs} +1 -1
  156. package/dist/{list-bhyuQSyO.cjs.map → list-r57UFHu3.cjs.map} +1 -1
  157. package/dist/list.cjs +1 -1
  158. package/dist/list.js +1 -1
  159. package/dist/{menu-BqKQ-s0C.cjs → menu-BOZ2iwed.cjs} +1 -1
  160. package/dist/{menu-BqKQ-s0C.cjs.map → menu-BOZ2iwed.cjs.map} +1 -1
  161. package/dist/{menu-C5ksITpG.js → menu-CxE16xur.js} +2 -2
  162. package/dist/{menu-C5ksITpG.js.map → menu-CxE16xur.js.map} +1 -1
  163. package/dist/menu.cjs +1 -1
  164. package/dist/menu.js +1 -1
  165. package/dist/mixins-DTCHPEd4.cjs +254 -0
  166. package/dist/{mixins-Du9HMrIG.cjs.map → mixins-DTCHPEd4.cjs.map} +1 -1
  167. package/dist/mixins-pU53qf6R.js +636 -0
  168. package/dist/{mixins-DCVXqL1Q.js.map → mixins-pU53qf6R.js.map} +1 -1
  169. package/dist/mixins.cjs +1 -1
  170. package/dist/mixins.js +1 -1
  171. package/dist/nav-drawer.cjs +1 -1
  172. package/dist/nav-drawer.js +1 -1
  173. package/dist/navigation-bar.cjs +1 -1
  174. package/dist/navigation-bar.js +1 -1
  175. package/dist/navigation-rail.cjs +1 -1
  176. package/dist/navigation-rail.js +1 -1
  177. package/dist/{notification-DR3gvWt8.cjs → notification-58tkVys8.cjs} +1 -1
  178. package/dist/{notification-DR3gvWt8.cjs.map → notification-58tkVys8.cjs.map} +1 -1
  179. package/dist/{notification-eZxtr3NN.js → notification-CgTBiAdf.js} +2 -2
  180. package/dist/{notification-eZxtr3NN.js.map → notification-CgTBiAdf.js.map} +1 -1
  181. package/dist/notification.cjs +1 -1
  182. package/dist/notification.js +1 -1
  183. package/dist/{option-BDOKUqTy.cjs → option-61YE3gub.cjs} +1 -1
  184. package/dist/{option-BDOKUqTy.cjs.map → option-61YE3gub.cjs.map} +1 -1
  185. package/dist/{option-CBEHYG4U.js → option-Bicf6xpI.js} +1 -1
  186. package/dist/{option-CBEHYG4U.js.map → option-Bicf6xpI.js.map} +1 -1
  187. package/dist/option.cjs +1 -1
  188. package/dist/option.js +1 -1
  189. package/dist/{overlay-DG6EeyKt.cjs → overlay-B3gKPWhu.cjs} +2 -2
  190. package/dist/overlay-B3gKPWhu.cjs.map +1 -0
  191. package/dist/{overlay-oxM9OLXP.js → overlay-D3mdWOLS.js} +12 -11
  192. package/dist/overlay-D3mdWOLS.js.map +1 -0
  193. package/dist/overlay.cjs +1 -1
  194. package/dist/{overlay.confirm-body-D_P2e7l6.js → overlay.confirm-body-Czi6cMZq.js} +1 -1
  195. package/dist/{overlay.confirm-body-D_P2e7l6.js.map → overlay.confirm-body-Czi6cMZq.js.map} +1 -1
  196. package/dist/{overlay.confirm-body-78e1WrN9.cjs → overlay.confirm-body-yr0HzS_d.cjs} +1 -1
  197. package/dist/{overlay.confirm-body-78e1WrN9.cjs.map → overlay.confirm-body-yr0HzS_d.cjs.map} +1 -1
  198. package/dist/overlay.js +3 -3
  199. package/dist/{overlay.service-C8NwO4Bx.js → overlay.service-BfZf3xoD.js} +2 -2
  200. package/dist/{overlay.service-C8NwO4Bx.js.map → overlay.service-BfZf3xoD.js.map} +1 -1
  201. package/dist/{overlay.service-DQkGPUY7.cjs → overlay.service-DNs3AWqp.cjs} +1 -1
  202. package/dist/{overlay.service-DQkGPUY7.cjs.map → overlay.service-DNs3AWqp.cjs.map} +1 -1
  203. package/dist/{progress-CMSst_2U.cjs → progress-D8XZJVl5.cjs} +1 -1
  204. package/dist/{progress-CMSst_2U.cjs.map → progress-D8XZJVl5.cjs.map} +1 -1
  205. package/dist/{progress-C4kDZfb7.js → progress-Zqx-S9NZ.js} +1 -1
  206. package/dist/{progress-C4kDZfb7.js.map → progress-Zqx-S9NZ.js.map} +1 -1
  207. package/dist/progress.cjs +1 -1
  208. package/dist/progress.js +1 -1
  209. package/dist/radio-group-D9MU1Mxz.js +71 -0
  210. package/dist/radio-group-D9MU1Mxz.js.map +1 -0
  211. package/dist/radio-group-bl8K4Gls.cjs +19 -0
  212. package/dist/radio-group-bl8K4Gls.cjs.map +1 -0
  213. package/dist/radio-group.cjs +1 -1
  214. package/dist/radio-group.js +1 -1
  215. package/dist/range.cjs +1 -1
  216. package/dist/range.js +1 -1
  217. package/dist/{rxjs-utils-Cs6XGwF6.js.map → rxjs-utils-BK8VMe3K.js.map} +1 -1
  218. package/dist/{rxjs-utils-Dsj75cJy.cjs.map → rxjs-utils-DhOKenkS.cjs.map} +1 -1
  219. package/dist/rxjs-utils.cjs +1 -1
  220. package/dist/rxjs-utils.js +1 -1
  221. package/dist/{select-UU2pB67h.js → select-CMwkl-D6.js} +3 -3
  222. package/dist/select-CMwkl-D6.js.map +1 -0
  223. package/dist/select-COIfVtZl.cjs +56 -0
  224. package/dist/select-COIfVtZl.cjs.map +1 -0
  225. package/dist/select.cjs +1 -1
  226. package/dist/select.js +1 -1
  227. package/dist/skeleton.cjs +1 -1
  228. package/dist/skeleton.js +1 -1
  229. package/dist/skills/SKILL.md +18 -2
  230. package/dist/skills/area.md +13 -0
  231. package/dist/skills/overlay.md +13 -0
  232. package/dist/skills/page.md +71 -29
  233. package/dist/skills/schmancy/SKILL.md +18 -2
  234. package/dist/skills/schmancy/area.md +13 -0
  235. package/dist/skills/schmancy/overlay.md +13 -0
  236. package/dist/skills/schmancy/page.md +71 -29
  237. package/dist/slider.cjs +1 -1
  238. package/dist/slider.js +1 -1
  239. package/dist/{splash-screen-BvaDkvJU.cjs → splash-screen-2hxq8Sft.cjs} +1 -1
  240. package/dist/{splash-screen-BvaDkvJU.cjs.map → splash-screen-2hxq8Sft.cjs.map} +1 -1
  241. package/dist/{splash-screen-ChMkAPLU.js → splash-screen-xrMNpzkm.js} +1 -1
  242. package/dist/{splash-screen-ChMkAPLU.js.map → splash-screen-xrMNpzkm.js.map} +1 -1
  243. package/dist/splash-screen.cjs +1 -1
  244. package/dist/splash-screen.js +1 -1
  245. package/dist/{src-DnunCC4X.js → src-CHd-U-w4.js} +34 -35
  246. package/dist/{src-DnunCC4X.js.map → src-CHd-U-w4.js.map} +1 -1
  247. package/dist/{src-BIlD63Cz.cjs → src-ggWtvpDr.cjs} +1 -1
  248. package/dist/{src-BIlD63Cz.cjs.map → src-ggWtvpDr.cjs.map} +1 -1
  249. package/dist/steps.cjs +1 -1
  250. package/dist/steps.js +1 -1
  251. package/dist/{surface-DCRy-EyT.js → surface-3nnvlxeE.js} +1 -1
  252. package/dist/{surface-DCRy-EyT.js.map → surface-3nnvlxeE.js.map} +1 -1
  253. package/dist/{surface-DWwQDX9r.cjs → surface-BkQ44Wuo.cjs} +1 -1
  254. package/dist/{surface-DWwQDX9r.cjs.map → surface-BkQ44Wuo.cjs.map} +1 -1
  255. package/dist/surface.cjs +1 -1
  256. package/dist/surface.js +1 -1
  257. package/dist/switch.cjs +1 -1
  258. package/dist/switch.js +1 -1
  259. package/dist/table.cjs +1 -1
  260. package/dist/table.js +1 -1
  261. package/dist/{tabs-CkDNLbiS.js → tabs-CnLIe8nE.js} +1 -1
  262. package/dist/{tabs-CkDNLbiS.js.map → tabs-CnLIe8nE.js.map} +1 -1
  263. package/dist/{tabs-lxQHWEb7.cjs → tabs-Dql0rcqZ.cjs} +1 -1
  264. package/dist/{tabs-lxQHWEb7.cjs.map → tabs-Dql0rcqZ.cjs.map} +1 -1
  265. package/dist/tabs.cjs +1 -1
  266. package/dist/tabs.js +1 -1
  267. package/dist/teleport.cjs +1 -1
  268. package/dist/teleport.js +1 -1
  269. package/dist/{textarea-DkfGmRSI.js → textarea-BAogS_Ff.js} +1 -1
  270. package/dist/{textarea-DkfGmRSI.js.map → textarea-BAogS_Ff.js.map} +1 -1
  271. package/dist/{textarea-CNa4dSvF.cjs → textarea-CGD6lAEe.cjs} +1 -1
  272. package/dist/{textarea-CNa4dSvF.cjs.map → textarea-CGD6lAEe.cjs.map} +1 -1
  273. package/dist/textarea.cjs +1 -1
  274. package/dist/textarea.js +1 -1
  275. package/dist/{theme-CNWRYdfn.js → theme-CUK0HrS3.js} +1 -1
  276. package/dist/{theme-CNWRYdfn.js.map → theme-CUK0HrS3.js.map} +1 -1
  277. package/dist/{theme-CMyXTDht.cjs → theme-DKrrQ-ic.cjs} +1 -1
  278. package/dist/{theme-CMyXTDht.cjs.map → theme-DKrrQ-ic.cjs.map} +1 -1
  279. package/dist/{theme-button-CixloLin.js → theme-button-Bb8qW2IH.js} +1 -1
  280. package/dist/{theme-button-CixloLin.js.map → theme-button-Bb8qW2IH.js.map} +1 -1
  281. package/dist/{theme-button-kMhsX5Oe.cjs → theme-button-CmTwFm3l.cjs} +1 -1
  282. package/dist/{theme-button-kMhsX5Oe.cjs.map → theme-button-CmTwFm3l.cjs.map} +1 -1
  283. package/dist/theme-button.cjs +1 -1
  284. package/dist/theme-button.js +1 -1
  285. package/dist/theme.cjs +1 -1
  286. package/dist/theme.js +2 -2
  287. package/dist/tree.cjs +1 -1
  288. package/dist/tree.js +1 -1
  289. package/dist/typography.cjs +1 -1
  290. package/dist/typography.js +1 -1
  291. package/dist/{utils-DXE5fBBd.js.map → utils-Cxg0Kfy5.js.map} +1 -1
  292. package/dist/{utils-C-Q8ePtG.cjs.map → utils-aCJYAGUr.cjs.map} +1 -1
  293. package/dist/utils.cjs +1 -1
  294. package/dist/utils.js +1 -1
  295. package/dist/visually-hidden.cjs +1 -1
  296. package/dist/visually-hidden.js +1 -1
  297. package/dist/{window-qaGFMn_4.cjs → window-BbWlaPZv.cjs} +1 -1
  298. package/dist/{window-qaGFMn_4.cjs.map → window-BbWlaPZv.cjs.map} +1 -1
  299. package/dist/{window-BcvDNi9D.js → window-DuDAQa6y.js} +1 -1
  300. package/dist/{window-BcvDNi9D.js.map → window-DuDAQa6y.js.map} +1 -1
  301. package/dist/window.cjs +1 -1
  302. package/dist/window.js +1 -1
  303. package/package.json +1 -1
  304. package/skills/schmancy/SKILL.md +18 -2
  305. package/skills/schmancy/area.md +13 -0
  306. package/skills/schmancy/overlay.md +13 -0
  307. package/skills/schmancy/page.md +71 -29
  308. package/src/CLAUDE.md +20 -0
  309. package/src/area/area.component.ts +168 -343
  310. package/src/button/button.ts +8 -5
  311. package/src/button/icon-button.ts +8 -5
  312. package/src/chips/filter-chip.ts +1 -3
  313. package/src/details/details.ts +1 -1
  314. package/src/directives/fill.ts +137 -0
  315. package/src/directives/index.ts +2 -0
  316. package/src/directives/overflow-within.ts +186 -0
  317. package/src/form/fields/radio-group/radio-button.ts +22 -44
  318. package/src/form/fields/radio-group/radio-group.ts +20 -75
  319. package/src/form/fields/select/select.ts +3 -2
  320. package/src/index.ts +0 -1
  321. package/src/overlay/index.ts +1 -0
  322. package/src/overlay/overlay.component.ts +38 -39
  323. package/src/overlay/overlay.positioning.ts +10 -2
  324. package/src/overlay/overlay.types.ts +10 -3
  325. package/src/state/schmancy-state.html +897 -0
  326. package/src/state/schmancy-state.md +981 -0
  327. package/types/src/area/area.component.d.ts +0 -15
  328. package/types/src/button/icon-button.d.ts +1 -1
  329. package/types/src/directives/fill.d.ts +46 -0
  330. package/types/src/directives/index.d.ts +2 -0
  331. package/types/src/directives/overflow-within.d.ts +77 -0
  332. package/types/src/form/fields/radio-group/radio-button.d.ts +2 -5
  333. package/types/src/form/fields/radio-group/radio-group.d.ts +2 -10
  334. package/types/src/index.d.ts +0 -1
  335. package/types/src/overlay/index.d.ts +1 -1
  336. package/types/src/overlay/overlay.positioning.d.ts +9 -1
  337. package/types/src/overlay/overlay.types.d.ts +9 -3
  338. package/dist/area-BIipuSyO.js.map +0 -1
  339. package/dist/area-C-EMiNEE.cjs +0 -12
  340. package/dist/area-C-EMiNEE.cjs.map +0 -1
  341. package/dist/chips-D1kJrbzo.js.map +0 -1
  342. package/dist/chips-Dx_WvOGk.cjs.map +0 -1
  343. package/dist/details-Cpg8sH2F.js.map +0 -1
  344. package/dist/details-CwSDur6j.cjs.map +0 -1
  345. package/dist/mixins-DCVXqL1Q.js +0 -636
  346. package/dist/mixins-Du9HMrIG.cjs +0 -254
  347. package/dist/overlay-DG6EeyKt.cjs.map +0 -1
  348. package/dist/overlay-oxM9OLXP.js.map +0 -1
  349. package/dist/page.cjs +0 -20
  350. package/dist/page.cjs.map +0 -1
  351. package/dist/page.js +0 -74
  352. package/dist/page.js.map +0 -1
  353. package/dist/radio-group-DB9D2ZkA.js +0 -108
  354. package/dist/radio-group-DB9D2ZkA.js.map +0 -1
  355. package/dist/radio-group-dVUvYFq7.cjs +0 -40
  356. package/dist/radio-group-dVUvYFq7.cjs.map +0 -1
  357. package/dist/scroll-C1klVgSQ.js +0 -115
  358. package/dist/scroll-C1klVgSQ.js.map +0 -1
  359. package/dist/scroll-S-bXF2u6.cjs +0 -26
  360. package/dist/scroll-S-bXF2u6.cjs.map +0 -1
  361. package/dist/select-UU2pB67h.js.map +0 -1
  362. package/dist/select-fu_-rZyn.cjs +0 -56
  363. package/dist/select-fu_-rZyn.cjs.map +0 -1
  364. package/src/page/index.ts +0 -1
  365. package/src/page/page.ts +0 -137
  366. package/types/src/page/index.d.ts +0 -1
  367. package/types/src/page/page.d.ts +0 -37
  368. /package/dist/{rxjs-utils-Cs6XGwF6.js → rxjs-utils-BK8VMe3K.js} +0 -0
  369. /package/dist/{rxjs-utils-Dsj75cJy.cjs → rxjs-utils-DhOKenkS.cjs} +0 -0
  370. /package/dist/{utils-DXE5fBBd.js → utils-Cxg0Kfy5.js} +0 -0
  371. /package/dist/{utils-C-Q8ePtG.cjs → utils-aCJYAGUr.cjs} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"rxjs-utils-Dsj75cJy.cjs","names":[],"sources":["../src/rxjs-utils/mutation-observer.ts","../node_modules/ts-is-present/lib/index.js","../src/rxjs-utils/waitForElements.ts"],"sourcesContent":["import { Observable } from 'rxjs'\n\nexport const mutationObserver = (\n\ttarget: HTMLElement,\n\tconfig: MutationObserverInit = {\n\t\tattributes: true,\n\t\tchildList: true,\n\t\tsubtree: true,\n\t},\n): Observable<MutationRecord[]> => {\n\treturn new Observable(observer => {\n\t\tconst mutation = new MutationObserver(mutations => {\n\t\t\tobserver.next(mutations)\n\t\t})\n\t\tmutation.observe(target, config)\n\t\tconst unsubscribe = () => {\n\t\t\tmutation.disconnect()\n\t\t}\n\t\treturn unsubscribe\n\t})\n}\nexport default mutationObserver\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.hasValueAtKey = exports.hasPresentKey = exports.isFilled = exports.isDefined = exports.isPresent = void 0;\nfunction isPresent(t) {\n return t !== undefined && t !== null;\n}\nexports.isPresent = isPresent;\nfunction isDefined(t) {\n return t !== undefined;\n}\nexports.isDefined = isDefined;\nfunction isFilled(t) {\n return t !== null;\n}\nexports.isFilled = isFilled;\n/**\n * Returns a function that can be used to filter down objects\n * to the ones that have a defined non-null value under the key `k`.\n *\n * @example\n * ```ts\n * const filesWithUrl = files.filter(file => file.url);\n * files[0].url // In this case, TS might still treat this as undefined/null\n *\n * const filesWithUrl = files.filter(hasPresentKey(\"url\"));\n * files[0].url // TS will know that this is present\n * ```\n *\n * See https://github.com/microsoft/TypeScript/issues/16069\n * why is that useful.\n */\nfunction hasPresentKey(k) {\n return function (a) {\n return a[k] !== undefined && a[k] !== null;\n };\n}\nexports.hasPresentKey = hasPresentKey;\n/**\n * Returns a function that can be used to filter down objects\n * to the ones that have a specific value V under a key `k`.\n *\n * @example\n * ```ts\n * type File = { type: \"image\", imageUrl: string } | { type: \"pdf\", pdfUrl: string };\n * const files: File[] = [];\n *\n * const imageFiles = files.filter(file => file.type === \"image\");\n * files[0].type // In this case, TS will still treat it as `\"image\" | \"pdf\"`\n *\n * const filesWithUrl = files.filter(hasValueKey(\"type\", \"image\" as const));\n * files[0].type // TS will now know that this is \"image\"\n * files[0].imageUrl // TS will know this is present, because already it excluded the other union members.\n *\n * Note: the cast `as const` is necessary, otherwise TS will only know that type is a string.\n * ```\n *\n * See https://github.com/microsoft/TypeScript/issues/16069\n * why is that useful.\n */\nfunction hasValueAtKey(k, v) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return function (a) {\n return a[k] === v;\n };\n}\nexports.hasValueAtKey = hasValueAtKey;\n//# sourceMappingURL=index.js.map","import { filter, map, startWith, take, tap, timeout } from 'rxjs'\nimport { isPresent } from 'ts-is-present'\nimport observeOnMutation from './mutation-observer'\n\n/**\n * @returns An observable that emits the elements when they are found\n * @description This function is useful when you want to wait for multiple elements to appear\n * @example waitForElements(['button', 'input']).subscribe(([button, input]) => button.click())\n * @returns\n */\nexport default function waitForElements(\n /**\n * @param selectors The selectors to use to find the elements\n * @type { string[] }\n * @description The order of the elements in the array is the same as the order of the elements in the emitted array\n */\n selectors: string[],\n /**\n * @param timeoutAfter How long to wait for the elements to appear before throwing an error\n * @default 5000\n * @type { number | undefined }\n * @description If you don't want to wait for the elements to appear, pass `undefined` as the second argument\n */\n timeoutAfter = 5000,\n) {\n return observeOnMutation(document.body).pipe(\n startWith(document.body),\n filter(() => selectors.every(s => !!document.querySelector(s))),\n take(1),\n map(() => selectors.map(s => document.querySelector(s)).filter(isPresent)), // why filter again? see https://github.com/Microsoft/TypeScript/issues/16069\n map(elements => {\n if (elements.length === selectors.length) {\n return elements\n } else {\n throw new Error('Not all elements were found')\n }\n }),\n timeoutAfter ? timeout(timeoutAfter) : tap(),\n )\n}\n"],"x_google_ignoreList":[1],"mappings":"8DAEA,IAAa,GACZ,EACA,EAA+B,CAC9B,WAAA,CAAY,EACZ,UAAA,CAAW,EACX,QAAA,CAAS,EAAA,GAGH,IAAI,EAAA,WAAW,GAAA,CACrB,IAAM,EAAW,IAAI,iBAAiB,GAAA,CACrC,EAAS,KAAK,EAAA,EAAA,CAMf,OAJA,EAAS,QAAQ,EAAQ,EAAA,KACnB,CACL,EAAS,YAAA,GAAA,CAAA,EAAA,EAAA,GAAA,CCfZ,OAAO,eAAe,EAAS,IAAc,CAAE,MAAA,CAAO,EAAA,CAAA,CACtD,EAAQ,cAAgB,EAAQ,cAAgB,EAAQ,SAAW,EAAQ,UAAY,EAAQ,UAAA,IAAiB,GAIhH,EAAQ,UAHR,SAAmB,EAAA,CACf,OAAO,GAAA,MAMX,EAAQ,UAHR,SAAmB,EAAA,CACf,OAAO,IAAP,IAAa,IAMjB,EAAQ,SAHR,SAAkB,EAAA,CACd,OAAO,IAAM,MAwBjB,EAAQ,cALR,SAAuB,EAAA,CACnB,OAAO,SAAU,EAAA,CACb,OAAO,EAAE,KAAT,IAAgB,IAAa,EAAE,KAAO,OAgC9C,EAAQ,cANR,SAAuB,EAAG,EAAA,CAEtB,OAAO,SAAU,EAAA,CACb,OAAO,EAAE,KAAO,KAAA,EAAA,CAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"rxjs-utils-DhOKenkS.cjs","names":[],"sources":["../src/rxjs-utils/mutation-observer.ts","../node_modules/ts-is-present/lib/index.js","../src/rxjs-utils/waitForElements.ts"],"sourcesContent":["import { Observable } from 'rxjs'\n\nexport const mutationObserver = (\n\ttarget: HTMLElement,\n\tconfig: MutationObserverInit = {\n\t\tattributes: true,\n\t\tchildList: true,\n\t\tsubtree: true,\n\t},\n): Observable<MutationRecord[]> => {\n\treturn new Observable(observer => {\n\t\tconst mutation = new MutationObserver(mutations => {\n\t\t\tobserver.next(mutations)\n\t\t})\n\t\tmutation.observe(target, config)\n\t\tconst unsubscribe = () => {\n\t\t\tmutation.disconnect()\n\t\t}\n\t\treturn unsubscribe\n\t})\n}\nexport default mutationObserver\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.hasValueAtKey = exports.hasPresentKey = exports.isFilled = exports.isDefined = exports.isPresent = void 0;\nfunction isPresent(t) {\n return t !== undefined && t !== null;\n}\nexports.isPresent = isPresent;\nfunction isDefined(t) {\n return t !== undefined;\n}\nexports.isDefined = isDefined;\nfunction isFilled(t) {\n return t !== null;\n}\nexports.isFilled = isFilled;\n/**\n * Returns a function that can be used to filter down objects\n * to the ones that have a defined non-null value under the key `k`.\n *\n * @example\n * ```ts\n * const filesWithUrl = files.filter(file => file.url);\n * files[0].url // In this case, TS might still treat this as undefined/null\n *\n * const filesWithUrl = files.filter(hasPresentKey(\"url\"));\n * files[0].url // TS will know that this is present\n * ```\n *\n * See https://github.com/microsoft/TypeScript/issues/16069\n * why is that useful.\n */\nfunction hasPresentKey(k) {\n return function (a) {\n return a[k] !== undefined && a[k] !== null;\n };\n}\nexports.hasPresentKey = hasPresentKey;\n/**\n * Returns a function that can be used to filter down objects\n * to the ones that have a specific value V under a key `k`.\n *\n * @example\n * ```ts\n * type File = { type: \"image\", imageUrl: string } | { type: \"pdf\", pdfUrl: string };\n * const files: File[] = [];\n *\n * const imageFiles = files.filter(file => file.type === \"image\");\n * files[0].type // In this case, TS will still treat it as `\"image\" | \"pdf\"`\n *\n * const filesWithUrl = files.filter(hasValueKey(\"type\", \"image\" as const));\n * files[0].type // TS will now know that this is \"image\"\n * files[0].imageUrl // TS will know this is present, because already it excluded the other union members.\n *\n * Note: the cast `as const` is necessary, otherwise TS will only know that type is a string.\n * ```\n *\n * See https://github.com/microsoft/TypeScript/issues/16069\n * why is that useful.\n */\nfunction hasValueAtKey(k, v) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return function (a) {\n return a[k] === v;\n };\n}\nexports.hasValueAtKey = hasValueAtKey;\n//# sourceMappingURL=index.js.map","import { filter, map, startWith, take, tap, timeout } from 'rxjs'\nimport { isPresent } from 'ts-is-present'\nimport observeOnMutation from './mutation-observer'\n\n/**\n * @returns An observable that emits the elements when they are found\n * @description This function is useful when you want to wait for multiple elements to appear\n * @example waitForElements(['button', 'input']).subscribe(([button, input]) => button.click())\n * @returns\n */\nexport default function waitForElements(\n /**\n * @param selectors The selectors to use to find the elements\n * @type { string[] }\n * @description The order of the elements in the array is the same as the order of the elements in the emitted array\n */\n selectors: string[],\n /**\n * @param timeoutAfter How long to wait for the elements to appear before throwing an error\n * @default 5000\n * @type { number | undefined }\n * @description If you don't want to wait for the elements to appear, pass `undefined` as the second argument\n */\n timeoutAfter = 5000,\n) {\n return observeOnMutation(document.body).pipe(\n startWith(document.body),\n filter(() => selectors.every(s => !!document.querySelector(s))),\n take(1),\n map(() => selectors.map(s => document.querySelector(s)).filter(isPresent)), // why filter again? see https://github.com/Microsoft/TypeScript/issues/16069\n map(elements => {\n if (elements.length === selectors.length) {\n return elements\n } else {\n throw new Error('Not all elements were found')\n }\n }),\n timeoutAfter ? timeout(timeoutAfter) : tap(),\n )\n}\n"],"x_google_ignoreList":[1],"mappings":"8DAEA,IAAa,GACZ,EACA,EAA+B,CAC9B,WAAA,CAAY,EACZ,UAAA,CAAW,EACX,QAAA,CAAS,EAAA,GAGH,IAAI,EAAA,WAAW,GAAA,CACrB,IAAM,EAAW,IAAI,iBAAiB,GAAA,CACrC,EAAS,KAAK,EAAA,EAAA,CAMf,OAJA,EAAS,QAAQ,EAAQ,EAAA,KACnB,CACL,EAAS,YAAA,GAAA,CAAA,EAAA,EAAA,GAAA,CCfZ,OAAO,eAAe,EAAS,IAAc,CAAE,MAAA,CAAO,EAAA,CAAA,CACtD,EAAQ,cAAgB,EAAQ,cAAgB,EAAQ,SAAW,EAAQ,UAAY,EAAQ,UAAA,IAAiB,GAIhH,EAAQ,UAHR,SAAmB,EAAA,CACf,OAAO,GAAA,MAMX,EAAQ,UAHR,SAAmB,EAAA,CACf,OAAO,IAAP,IAAa,IAMjB,EAAQ,SAHR,SAAkB,EAAA,CACd,OAAO,IAAM,MAwBjB,EAAQ,cALR,SAAuB,EAAA,CACnB,OAAO,SAAU,EAAA,CACb,OAAO,EAAE,KAAT,IAAgB,IAAa,EAAE,KAAO,OAgC9C,EAAQ,cANR,SAAuB,EAAG,EAAA,CAEtB,OAAO,SAAU,EAAA,CACb,OAAO,EAAE,KAAO,KAAA,EAAA,CAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,GAAA,CAAA"}
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./rxjs-utils-Dsj75cJy.cjs`);exports.mutationObserver=e.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./rxjs-utils-DhOKenkS.cjs`);exports.mutationObserver=e.t;
@@ -1,2 +1,2 @@
1
- import { t as e } from "./rxjs-utils-Cs6XGwF6.js";
1
+ import { t as e } from "./rxjs-utils-BK8VMe3K.js";
2
2
  export { e as mutationObserver };
@@ -1,4 +1,4 @@
1
- import { o as e } from "./mixins-DCVXqL1Q.js";
1
+ import { o as e } from "./mixins-pU53qf6R.js";
2
2
  import { a as t } from "./active-host-BP0zy_Y9.js";
3
3
  import { color as n } from "./directives.js";
4
4
  import { t as r } from "./theme.interface-C2XNgsLB.js";
@@ -60,10 +60,10 @@ var T = class extends e() {
60
60
  `];
61
61
  }
62
62
  get value() {
63
- return this.multi ? this._selectedValues$.value : this._selectedValue$.value;
63
+ return this.multi ? this._selectedValues$?.value ?? [] : this._selectedValue$?.value ?? "";
64
64
  }
65
65
  set value(e) {
66
- if (this.multi) {
66
+ if (this._selectedValue$ && this._selectedValues$) if (this.multi) {
67
67
  let t = Array.isArray(e) ? e : e ? String(e).split(",").map((e) => e.trim()).filter(Boolean) : [];
68
68
  this._selectedValues$.next(t);
69
69
  } else this._selectedValue$.next(e == null ? "" : String(e));
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-CMwkl-D6.js","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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"}
@@ -0,0 +1,56 @@
1
+ require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-DTCHPEd4.cjs`),t=require(`./active-host-jH3iloCR.cjs`),n=require(`./directives.cjs`),r=require(`./theme.interface-D4NeufQA.cjs`);let i=require(`rxjs`),a=require(`rxjs/operators`),o=require(`lit/directives/class-map.js`),s=require(`lit/decorators.js`),c=require(`lit`),l=require(`lit/directives/if-defined.js`),u=require(`@floating-ui/dom`);var d=class extends e.o(){constructor(...e){super(...e),this.placeholder=``,this.multi=!1,this.size=`md`,this.isOpen=!1,this.valueLabel=``,this.isValid=!0,this.selectDefaultValue=``,this._options$=new i.BehaviorSubject([]),this._selectedValue$=new i.BehaviorSubject(``),this._selectedValues$=new i.BehaviorSubject([]),this._optionSelect$=new i.Subject,this._userInteracted=!1,this._focusedOptionId=``,this.handleKeyDown=e=>{if(this.disabled)return;if(!this.isOpen)return void([`Enter`,` `,`ArrowDown`].includes(e.key)&&(e.preventDefault(),this.openDropdown(!1)));let t=Array.from(this.options||[]),n=t.findIndex(e=>e.id===this._focusedOptionId)??-1;switch(e.key){case`Escape`:e.preventDefault(),this.closeDropdown();break;case`ArrowDown`:e.preventDefault(),this.focusOption(t,Math.min(n+1,t.length-1));break;case`ArrowUp`:e.preventDefault(),this.focusOption(t,Math.max(n-1,0));break;case`Home`:e.preventDefault(),this.focusOption(t,0);break;case`End`:e.preventDefault(),this.focusOption(t,t.length-1);break;case`Enter`:case` `:if(e.preventDefault(),this._focusedOptionId){let e=t.find(e=>e.id===this._focusedOptionId);e&&this.handleOptionSelect(e.value)}break;case`Tab`:this.closeDropdown()}}}static{this.styles=[c.css`
2
+ :host {
3
+ display: block;
4
+ position: relative;
5
+ }
6
+
7
+ [role='listbox'] {
8
+ overflow-y: auto;
9
+ outline: none;
10
+ }
11
+ `]}get value(){return this.multi?this._selectedValues$?.value??[]:this._selectedValue$?.value??``}set value(e){if(this._selectedValue$&&this._selectedValues$)if(this.multi){let t=Array.isArray(e)?e:e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[];this._selectedValues$.next(t)}else this._selectedValue$.next(e==null?``:String(e))}get values(){return[...this._selectedValues$.value]}set values(e){this._selectedValues$.next(Array.isArray(e)?[...e]:[])}connectedCallback(){super.connectedCallback(),this.id||=`schmancy-select-${Math.random().toString(36).substring(2,9)}`,this.selectDefaultValue=this.value,(0,i.fromEvent)(this,`keydown`).pipe((0,i.takeUntil)(this.disconnecting)).subscribe(this.handleKeyDown),this._setupReactivePipelines()}disconnectedCallback(){super.disconnectedCallback(),this.cleanupPositioner?.()}firstUpdated(){this.syncSelection(),this.setupOptionsAccessibility(),this.inputRef&&(this.inputRef.error=!1)}updated(e){if(super.updated(e),e.has(`value`)){let e=this.multi?this._selectedValues$.value.join(`,`):this._selectedValue$.value;this.internals?.setFormValue(e)}e.has(`isOpen`)&&(this.isOpen?this.positionDropdown():this.cleanupPositioner?.())}syncSelection(){if(this.multi){let e=this._selectedValues$.value;this.options?.forEach(t=>t.selected=e.includes(t.value)),this.valueLabel=e.length>0&&this.options?.filter(t=>e.includes(t.value)).map(e=>e.label||e.textContent||``).join(`, `)||this.placeholder}else{let e=this._selectedValue$.value;this.options?.forEach(t=>{t.selected=t.value===e});let t=this.options?.find(t=>t.value===e);this.valueLabel=t?t.label||t.textContent||``:this.placeholder}}setupOptionsAccessibility(){this.options?.forEach((e,t)=>{e.setAttribute(`role`,`option`),e.id||=`${this.id}-option-${t}`,e.tabIndex=-1,e.setAttribute(`aria-selected`,String(this.multi?this._selectedValues$.value.includes(e.value):e.value===this._selectedValue$.value))})}async positionDropdown(){let e=this.renderRoot.querySelector(`.trigger`);e&&this.ul&&(this.cleanupPositioner=(0,u.autoUpdate)(e,this.ul,async()=>{let t=window.innerHeight,n=e.getBoundingClientRect(),r=t-n.bottom,i=n.top,a=Math.max(.75*Math.max(r,i),150),o=r<200&&i>r;this.ul.style.maxHeight=`${a}px`;let{x:s,y:c}=await(0,u.computePosition)(e,this.ul,{placement:o?`top-start`:`bottom-start`,middleware:[(0,u.offset)(5),(0,u.flip)(),(0,u.shift)({padding:5})]});Object.assign(this.ul.style,{left:`${s}px`,top:`${c}px`,position:`absolute`,width:`${e.offsetWidth}px`})}))}focusOption(e,t){let n=e[t];if(n){n.focus(),this._focusedOptionId=n.id;let e=this.renderRoot.querySelector(`.trigger`);if(e&&e.setAttribute(`aria-activedescendant`,n.id),this.ul&&n.offsetTop!==void 0){let e=n.offsetTop,t=n.offsetHeight,r=this.ul.scrollTop,i=this.ul.clientHeight;e<r?this.ul.scrollTop=e:e+t>r+i&&(this.ul.scrollTop=e+t-i)}}}async openDropdown(e=!1){if(this.disabled)return;this.isOpen=!0,await this.updateComplete;let t=Array.from(this.options||[]),n=this.multi?0:t.findIndex(e=>e.value===this._selectedValue$.value);this.focusOption(t,Math.max(n,0)),e&&this.reportValidity()}closeDropdown(){this._userInteracted&&(this.touched=!0),this.isOpen=!1,this._focusedOptionId=``;let e=this.renderRoot.querySelector(`.trigger`);e&&(e.removeAttribute(`aria-activedescendant`),e?.focus()),this._userInteracted&&this._shouldShowError()&&this.checkValidity()}_setupReactivePipelines(){(0,i.fromEvent)(this,`option-select`).pipe((0,a.tap)(e=>{e.stopPropagation();let t=this.options.find(t=>t.value===e.detail.value);t&&this._optionSelect$.next(t)}),(0,i.takeUntil)(this.disconnecting)).subscribe(),this._optionSelect$.pipe((0,a.withLatestFrom)(this._selectedValue$,this._selectedValues$),(0,a.tap)(([e,t,n])=>{if(this._userInteracted=!0,this.markTouched(),this.multi){let t=n.indexOf(e.value),r=t>-1?[...n.slice(0,t),...n.slice(t+1)]:[...n,e.value];this._selectedValues$.next(r),this.internals?.setFormValue(r.join(`,`)),this.valueLabel=r.length>0?this.options.filter(e=>r.includes(e.value)).map(e=>e.label||e.textContent||``).join(`, `):this.placeholder}else this._selectedValue$.next(e.value),this.internals?.setFormValue(e.value),this.valueLabel=e.label||e.textContent||this.placeholder,this.closeDropdown();this.setupOptionsAccessibility(),this._fireChangeEvent()}),(0,i.takeUntil)(this.disconnecting)).subscribe(),this._options$.pipe((0,a.tap)(e=>{e.forEach((e,t)=>{e.setAttribute(`role`,`option`),e.tabIndex=-1,e.id||=`${this.id}-option-${t}`,e.hasAttribute(`data-event-bound`)||((0,i.fromEvent)(e,`click`).pipe((0,a.tap)(e=>{e.stopPropagation()}),(0,i.takeUntil)(this.disconnecting)).subscribe(()=>this._optionSelect$.next(e)),e.setAttribute(`data-event-bound`,`true`))})}),(0,i.takeUntil)(this.disconnecting)).subscribe(),(0,i.combineLatest)([this._selectedValue$,this._selectedValues$,this._options$]).pipe((0,a.tap)(([e,t,n])=>{n.length!==0&&(this.multi?n.forEach(e=>{e.selected=t.includes(e.value)}):n.forEach(t=>{t.selected=t.value===e}))}),(0,i.takeUntil)(this.disconnecting)).subscribe()}handleOptionSelect(e){let t=this.options.find(t=>t.value===e);t&&this._optionSelect$.next(t)}_fireChangeEvent(){let e=this.multi?this._selectedValues$.value:this._selectedValue$.value;this.dispatchEvent(new CustomEvent(`change`,{detail:{value:e},bubbles:!0,composed:!0})),this.checkValidity()}checkValidity(){if(this.disabled)return!0;let e=this.multi?this._selectedValues$.value.length===0:!this._selectedValue$.value,t=!(this.required&&e);if(this.isValid=t,this.isValid?(this.validationMessage=``,this.internals?.setValidity({})):(this.validationMessage=`Please select an option.`,this.internals?.setValidity({valueMissing:!0},`Please select an option.`,this.inputRef)),this.inputRef&&this.hasUpdated){let e=!this.isValid&&this._shouldShowError();this.inputRef.error=e,this.inputRef.hint=e?this.validationMessage:this.hint}return this.isValid}reportValidity(){let e=this.checkValidity();return this.inputRef&&(this.inputRef.error=!e,this.inputRef.hint=e?this.hint:this.validationMessage,e||this.isOpen||this.openDropdown(!1),e||this.inputRef.reportValidity()),e}toFormEntries(){if(!this.name||this.disabled)return[];let e=this.value;return e==null||e===``?[]:Array.isArray(e)?e.map(e=>[this.name,String(e)]):[[this.name,String(e)]]}setCustomValidity(e){this.validationMessage=e,e?(this.isValid=!1,this.internals?.setValidity({customError:!0},e,this.inputRef)):(this.isValid=!0,this.internals?.setValidity({})),this.inputRef&&this._shouldShowError()&&(this.inputRef.error=!this.isValid,this.inputRef.hint=this.isValid?this.hint:this.validationMessage)}resetForm(){this.value=this.selectDefaultValue,this.valueLabel=this.placeholder,this.isValid=!0,this._userInteracted=!1,this.internals?.setValidity({}),super.resetForm(),this.inputRef&&(this.inputRef.error=!1,this.inputRef.hint=this.hint)}reset(){this.resetForm()}render(){let e=!this.isValid&&this._shouldShowError()&&!this.isOpen,t=this.isOpen?c.html`<span class="absolute right-3 top-1/2 transform -translate-y-1/2">▲</span>`:c.html`<span class="absolute right-3 top-1/2 transform -translate-y-1/2">▼</span>`;return c.html`
12
+ <div class="relative ${this.disabled?`opacity-60 cursor-not-allowed`:``}">
13
+ <sch-input
14
+ .name=${this.name??``}
15
+ tabIndex=${this.disabled?`-1`:`0`}
16
+ class="trigger"
17
+ role="combobox"
18
+ aria-haspopup="listbox"
19
+ aria-expanded=${this.isOpen}
20
+ aria-controls="options"
21
+ aria-autocomplete="none"
22
+ aria-required=${this.required}
23
+ aria-activedescendant=${(0,l.ifDefined)(this._focusedOptionId||void 0)}
24
+ aria-disabled=${this.disabled}
25
+ .label=${this.label}
26
+ .placeholder=${this.placeholder}
27
+ .value=${this.valueLabel}
28
+ .required=${this.required}
29
+ .disabled=${this.disabled}
30
+ .hint=${e?this.validationMessage:this.hint}
31
+ .error=${e}
32
+ .validateOn=${this.validateOn}
33
+ .size=${this.size}
34
+ .readonly=${!0}
35
+ clickable
36
+ @click=${e=>{if(this.disabled)return e.preventDefault(),void e.stopPropagation();this.isOpen?(this._userInteracted=!0,this.closeDropdown()):this.openDropdown(!1)}}
37
+ >
38
+ ${t}
39
+ </sch-input>
40
+
41
+ <!-- Overlay for capturing clicks outside when dropdown is open -->
42
+ ${this.isOpen?c.html` <div class="fixed inset-0 z-10" @click=${this.closeDropdown} tabindex="-1" aria-hidden="true"></div> `:``}
43
+
44
+ <ul
45
+ id="options"
46
+ role="listbox"
47
+ aria-multiselectable=${this.multi}
48
+ class=${(0,o.classMap)({"absolute min-w-full w-full z-20 mt-1 rounded-md shadow-lg":!0,hidden:!this.isOpen})}
49
+ ${n.color({bgColor:r.t.sys.color.surface.low,color:r.t.sys.color.surface.on})}
50
+ >
51
+ <slot
52
+ @slotchange=${()=>{this._options$.next(this.options),this.syncSelection()}}
53
+ ></slot>
54
+ </ul>
55
+ </div>
56
+ `}};t.a([(0,s.property)({type:String})],d.prototype,`placeholder`,void 0),t.a([(0,s.property)({type:String,reflect:!0})],d.prototype,`value`,null),t.a([(0,s.property)({type:Array})],d.prototype,`values`,null),t.a([(0,s.property)({type:Boolean})],d.prototype,`multi`,void 0),t.a([(0,s.property)({type:String})],d.prototype,`size`,void 0),t.a([(0,s.state)()],d.prototype,`isOpen`,void 0),t.a([(0,s.state)()],d.prototype,`valueLabel`,void 0),t.a([(0,s.state)()],d.prototype,`isValid`,void 0),t.a([(0,s.state)()],d.prototype,`selectDefaultValue`,void 0),t.a([(0,s.query)(`ul`)],d.prototype,`ul`,void 0),t.a([(0,s.query)(`sch-input`)],d.prototype,`inputRef`,void 0),t.a([(0,s.queryAssignedElements)({flatten:!0})],d.prototype,`options`,void 0),t.a([(0,s.state)()],d.prototype,`_userInteracted`,void 0),t.a([(0,s.state)()],d.prototype,`_focusedOptionId`,void 0),d=t.a([(0,s.customElement)(`schmancy-select`)],d),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return d}});
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-COIfVtZl.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-fu_-rZyn.cjs`);Object.defineProperty(exports,`SchmancySelect`,{enumerable:!0,get:function(){return e.t}});
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./select-COIfVtZl.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-UU2pB67h.js";
1
+ import { t as e } from "./select-CMwkl-D6.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-Du9HMrIG.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(`./mixins-DTCHPEd4.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`
2
2
  :host {
3
3
  display: block;
4
4
  width: var(--_sw, 100%);
package/dist/skeleton.js CHANGED
@@ -1,4 +1,4 @@
1
- import { c as e } from "./mixins-DCVXqL1Q.js";
1
+ import { c as e } from "./mixins-pU53qf6R.js";
2
2
  import { a as t } from "./active-host-BP0zy_Y9.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";
@@ -38,13 +38,17 @@ is chosen by the system based on viewport + anchor presence. There is no
38
38
  import { show, confirm, prompt } from '@mhmo91/schmancy/overlay'
39
39
  import { $notify, schmancyContentDrawer } from '@mhmo91/schmancy'
40
40
 
41
- show(new EditForm()) // centered fallback
42
- show(new QuickPicker(), { anchor: ev }) // anchored at click
41
+ show(MyForm) // component class — most common
42
+ show(() => html`<div class="p-4"><my-form .id=${id}></my-form></div>`, { anchor: ev })
43
+ // factory — lazy, no snapshot staleness
44
+ show(new EditForm()) // pre-instantiated element
43
45
  show(new Picker()) // narrow viewport → sheet (auto)
44
46
  $notify.success('Saved'); $notify.error('Failed') // toast
45
47
  schmancyContentDrawer.push({ component: new Detail() }) // side panel
46
48
  ```
47
49
 
50
+ When passing an inline template, always use the factory form `() => html\`...\`` — it is called at mount time so closed-over variables are read fresh. The eager form `html\`...\`` freezes values at the call site.
51
+
48
52
  References: `overlay.md`, `notification.md`, `content-drawer.md`.
49
53
 
50
54
  Use component tags (`<schmancy-menu>`, `<schmancy-dropdown>`, `<schmancy-tooltip>`, `<schmancy-lightbox>`, `<schmancy-expand>`) only when the tag is the natural fit (anchored panels, tooltips, galleries).
@@ -68,6 +72,18 @@ Use component tags (`<schmancy-menu>`, `<schmancy-dropdown>`, `<schmancy-tooltip
68
72
  - Every RxJS subscription ends with `.pipe(takeUntil(this.disconnecting))`.
69
73
  - Register the tag in `HTMLElementTagNameMap` for TypeScript.
70
74
 
75
+ **SIGNALS_ARE_THE_API**
76
+ State signals are the integration layer between co-located Schmancy view components; each view component owns its IO directly and has zero property inputs and zero custom event outputs when state signals cover the shared state.
77
+
78
+ - Detection signals: a view component with `.property=${value}` inputs from a parent; a view component dispatching `CustomEvent`s that a sibling or parent handles; an orchestrator file co-located with a view where routing complexity does not exceed schmancy's `.guard`+`@redirect` capability (i.e., the flow is a linear sequence with no branching or cross-route hand-off).
79
+ - Remediation: move shared state into schmancy state signals; have each component read/write signals directly in render() and connectedCallback(); delete the orchestrator if its only job was to pass data down and receive events up.
80
+
81
+ **EVENTS_UP_PROPS_DOWN** (cross-component communication when signals don't cover it)
82
+ When two components genuinely cannot share a signal (e.g., a generic reusable component that must not import app state), user actions travel upward via `CustomEvent` dispatch and data travels downward via Lit property bindings — not via callable property bindings (`onXxx`, `handleXxx`) set on child elements.
83
+
84
+ - Detection signals: `.onXxx=${fn}` or `.handleXxx=${fn}` callable property bindings in a parent template.
85
+ - Remediation: dispatch `new CustomEvent('xxx', { detail, bubbles: true, composed: true })` in the child; bind `@xxx=${handler}` in the parent.
86
+
71
87
  **State**
72
88
  - States live at module scope. Many small states beat one monolith. Use `state('feature/name').{memory,session,local,idb}(initial)` from `@mhmo91/schmancy/state`.
73
89
  - Reading `state.value` inside `render()` auto-tracks via the base class's `SignalWatcher` — no decorator or binding needed for the default case.
@@ -10,6 +10,16 @@ Schmancy's client-side router. Three pieces:
10
10
 
11
11
  Areas can be nested to compose shell-plus-sub-view layouts.
12
12
 
13
+ ## Layout contract
14
+
15
+ `<schmancy-area>` is the routing leaf in the layout cascade. Its shadow CSS guarantees:
16
+
17
+ 1. **Stretch the mounted component.** The routed view fills the area (`min-height: 100%; width: 100%`). The area itself is `height: 100%; width: 100%` so it consumes whatever cell its parent gave it (typically a `<schmancy-page>` slot or a grid `1fr` row / column).
18
+ 2. **Scroll by default.** The host is `overflow: auto` — when the mounted component grows past the area's box, the area scrolls. Pages that need a custom scroll strategy (virtualized lists, multi-pane scroll) declare `<schmancy-area no-scroll>` and own their scroll.
19
+ 3. **Reset scroll on route change.** The area sets `scrollTop = 0` after every route swap so a new view starts at the top.
20
+
21
+ Consumers do not write `h-full`, `w-full`, or `:host { height: 100% }` on routed components. The area's `::slotted` rule sizes them.
22
+
13
23
  ## Example
14
24
 
15
25
  ```html
@@ -47,6 +57,8 @@ Areas can be nested to compose shell-plus-sub-view layouts.
47
57
  | `guard` | `Observable<boolean>` | When emits `false`, blocks and dispatches `redirect` event |
48
58
  | `exact` | boolean | Strict-equality matching |
49
59
 
60
+ `<schmancy-area>` also accepts the `no-scroll` boolean attribute to opt out of default `overflow: auto` (for virtualized lists or custom scroll containers).
61
+
50
62
  ## `area` service
51
63
 
52
64
  ```typescript
@@ -139,3 +151,4 @@ Areas nest by rendering an inner `<schmancy-area>` inside a route component. A c
139
151
  - `when="tag-name"` must match `@customElement('tag-name')` exactly.
140
152
  - Guards emit `false` → always use `historyStrategy: 'replace'` in the `@redirect` handler.
141
153
  - Every subscription in guards / route state uses `takeUntil(this.disconnecting)`.
154
+ - A routed component never declares `:host { height: 100% }` or `class="h-full"` — the area sizes it. Marketing / long-form leaves that need natural scroll opt out at the host: `:host { height: auto; min-height: 100%; overflow: auto }`.
@@ -26,6 +26,19 @@ private handlePick = (ev: MouseEvent) => {
26
26
 
27
27
  Centered is the fallback (no anchor given). Sheet is the responsive adaptation (narrow viewport / touch / oversized content). You never pick layout — the system does.
28
28
 
29
+ ## Content forms
30
+
31
+ `show()` accepts four content forms:
32
+
33
+ | Form | When to use |
34
+ |---|---|
35
+ | `show(MyComponent)` | Component class — most common |
36
+ | `show(html\`...\`)` | Inline template (eager — values frozen at call site) |
37
+ | `show(() => html\`...\`)` | **Preferred for templates** — factory called at mount time; closed-over variables are read lazily, no snapshot staleness |
38
+ | `show(lazy(() => import('./x')))` | Async / code-split component |
39
+
40
+ Always prefer `() => html\`...\`` over `html\`...\`` when the template closes over any variable — the factory form evaluates those variables at mount time rather than baking them in at the call site.
41
+
29
42
  ## API
30
43
 
31
44
  | Export | Signature | Purpose |
@@ -1,42 +1,84 @@
1
1
  # schmancy-page
2
2
 
3
- > Native mobile-like page container. Fills remaining viewport height, prevents rubber-banding, pull-to-refresh, and double-tap zoom.
3
+ > Viewport-locked layout primitive. Provides a definite-height frame so any composition inside it has a parent to resolve against.
4
+
5
+ ## Contract
6
+
7
+ Two rules and one slot.
8
+
9
+ 1. **Outermost lock.** A `<schmancy-page>` with no `<schmancy-page>` ancestor anchors itself to the visual viewport (`position: fixed; inset: 0`) and tracks `visualViewport.height` for iOS soft-keyboard correctness. It does not rely on `html`/`body` height — the cascade above it is irrelevant.
10
+ 2. **Single-child stretch.** The slotted child fills the page box (`height: 100%; width: 100%; min-height: 0; min-width: 0`). More than one direct child produces a visible layout collision — fail-loud, not silent.
11
+
12
+ Composition shape is plain CSS grid / flex inside the slotted child. The primitive does not prescribe header / footer / sidebar conventions; consumers arrange regions in standard CSS. The contract is the locked frame.
4
13
 
5
14
  ## Usage
15
+
16
+ ### App root
6
17
  ```html
7
- <schmancy-page rows="auto_1fr_auto">
8
- <header>App bar</header>
9
- <main>Scrollable content</main>
10
- <footer>Bottom nav</footer>
18
+ <schmancy-page>
19
+ <schmancy-area name="root" .default=${landing}>
20
+ <schmancy-route when="landing-view" .component=${landing}></schmancy-route>
21
+ <schmancy-route when="app-home" .component=${appHome}></schmancy-route>
22
+ </schmancy-area>
11
23
  </schmancy-page>
12
24
  ```
13
25
 
14
- ## Properties
15
- | Property | Type | Default | Description |
16
- |----------|------|---------|-------------|
17
- | `rows` | string | `'auto_1fr_auto'` | Grid template rows — underscores become spaces (e.g. `'1fr_2fr_auto'`) |
18
- | `show-scrollbar` | boolean | `false` | Display scrollbar on scrollable area |
19
- | `no-select` | boolean | `false` | Disable text selection |
20
-
21
- ## Behavior
22
- - Listens to `visualViewport` resize/scroll + `orientationchange` + keyboard focus events to recompute height.
23
- - Accounts for theme bottom offset (iOS safe area, home indicator).
24
- - Auto-assigns semantic elements (`header`, `main`, `footer`) to slots.
25
- - Inner scroll area uses `schmancy-scroll` for momentum-preserving scroll.
26
-
27
- ## When to Use
28
- - Root of a mobile view or panel that should feel like a native page.
29
- - Any container where viewport-aware height + scroll containment matters.
30
-
31
- ## Example — 3-row app shell
26
+ ### Sidebar + sticky header + body
32
27
  ```html
33
- <schmancy-page rows="auto_1fr_auto">
34
- <schmancy-surface type="solid" rounded="none">
35
- <schmancy-typography type="title">My App</schmancy-typography>
36
- </schmancy-surface>
28
+ <schmancy-page>
29
+ <div class="grid grid-cols-[auto_1fr]">
30
+ <app-rail></app-rail>
31
+ <schmancy-page>
32
+ <div class="grid grid-rows-[auto_1fr]">
33
+ <app-top-bar></app-top-bar>
34
+ <schmancy-area name="app">...</schmancy-area>
35
+ </div>
36
+ </schmancy-page>
37
+ </div>
38
+ </schmancy-page>
39
+ ```
40
+
41
+ The inner `<schmancy-page>` detects the outer ancestor, skips the viewport lock, and fills its grid cell via `height: 100%; width: 100%`.
37
42
 
38
- <div class="p-4">…scrollable content…</div>
43
+ ### Tabs page
44
+ ```html
45
+ <div class="grid grid-rows-[auto_1fr]">
46
+ <schmancy-tabs></schmancy-tabs>
47
+ <schmancy-area name="settings">...</schmancy-area>
48
+ </div>
49
+ ```
39
50
 
40
- <schmancy-navigation-bar></schmancy-navigation-bar>
51
+ No `<schmancy-page>` here — this view is the routed body of a higher `<schmancy-page>`. The grid resolves against the area's `1fr` cell, which the area inherits from the page.
52
+
53
+ ### Admin shell (four regions)
54
+ ```html
55
+ <schmancy-page>
56
+ <div class="grid grid-rows-[auto_1fr]">
57
+ <admin-top-bar></admin-top-bar>
58
+ <div class="grid grid-cols-[240px_1fr_320px]">
59
+ <admin-sidebar></admin-sidebar>
60
+ <schmancy-area name="admin"></schmancy-area>
61
+ <admin-inspector></admin-inspector>
62
+ </div>
63
+ </div>
41
64
  </schmancy-page>
42
65
  ```
66
+
67
+ ## Properties
68
+
69
+ `<schmancy-page>` has no public properties. Composition is expressed by what you nest inside its single slot.
70
+
71
+ The `outermost` attribute is set automatically on the page that owns the viewport lock. Consumers neither set nor read it.
72
+
73
+ ## Edge cases
74
+
75
+ - **Print** — outermost page falls back to `position: static` so pagination works.
76
+ - **iOS soft keyboard** — outermost page reads `visualViewport.height` and applies it as inline `height`, so the locked box shrinks when the keyboard opens.
77
+ - **Long-form leaf (marketing, legal)** — opt out at the leaf, not at the page. The routed component declares its own `:host { height: auto; overflow: auto; min-height: 100% }`. The outer page stays locked; the leaf scrolls inside its `<schmancy-area>`.
78
+ - **Master-detail with two scroll regions** — render two `<schmancy-area>` slots inside a grid; each owns its scroll.
79
+
80
+ ## Rules
81
+
82
+ - A `<schmancy-page>` has exactly one direct child. If you need multiple regions, wrap them in a grid / flex container.
83
+ - Do not put `class="h-full"`, `class="w-full"`, or `:host { height: 100% }` anywhere in your tree. The page and the area carry sizing; consumer code never does.
84
+ - Scroll lives in `<schmancy-area>`, not in `<schmancy-page>`. Pages provide the locked frame; areas provide the scrolling region for their mounted component.
@@ -38,13 +38,17 @@ is chosen by the system based on viewport + anchor presence. There is no
38
38
  import { show, confirm, prompt } from '@mhmo91/schmancy/overlay'
39
39
  import { $notify, schmancyContentDrawer } from '@mhmo91/schmancy'
40
40
 
41
- show(new EditForm()) // centered fallback
42
- show(new QuickPicker(), { anchor: ev }) // anchored at click
41
+ show(MyForm) // component class — most common
42
+ show(() => html`<div class="p-4"><my-form .id=${id}></my-form></div>`, { anchor: ev })
43
+ // factory — lazy, no snapshot staleness
44
+ show(new EditForm()) // pre-instantiated element
43
45
  show(new Picker()) // narrow viewport → sheet (auto)
44
46
  $notify.success('Saved'); $notify.error('Failed') // toast
45
47
  schmancyContentDrawer.push({ component: new Detail() }) // side panel
46
48
  ```
47
49
 
50
+ When passing an inline template, always use the factory form `() => html\`...\`` — it is called at mount time so closed-over variables are read fresh. The eager form `html\`...\`` freezes values at the call site.
51
+
48
52
  References: `overlay.md`, `notification.md`, `content-drawer.md`.
49
53
 
50
54
  Use component tags (`<schmancy-menu>`, `<schmancy-dropdown>`, `<schmancy-tooltip>`, `<schmancy-lightbox>`, `<schmancy-expand>`) only when the tag is the natural fit (anchored panels, tooltips, galleries).
@@ -68,6 +72,18 @@ Use component tags (`<schmancy-menu>`, `<schmancy-dropdown>`, `<schmancy-tooltip
68
72
  - Every RxJS subscription ends with `.pipe(takeUntil(this.disconnecting))`.
69
73
  - Register the tag in `HTMLElementTagNameMap` for TypeScript.
70
74
 
75
+ **SIGNALS_ARE_THE_API**
76
+ State signals are the integration layer between co-located Schmancy view components; each view component owns its IO directly and has zero property inputs and zero custom event outputs when state signals cover the shared state.
77
+
78
+ - Detection signals: a view component with `.property=${value}` inputs from a parent; a view component dispatching `CustomEvent`s that a sibling or parent handles; an orchestrator file co-located with a view where routing complexity does not exceed schmancy's `.guard`+`@redirect` capability (i.e., the flow is a linear sequence with no branching or cross-route hand-off).
79
+ - Remediation: move shared state into schmancy state signals; have each component read/write signals directly in render() and connectedCallback(); delete the orchestrator if its only job was to pass data down and receive events up.
80
+
81
+ **EVENTS_UP_PROPS_DOWN** (cross-component communication when signals don't cover it)
82
+ When two components genuinely cannot share a signal (e.g., a generic reusable component that must not import app state), user actions travel upward via `CustomEvent` dispatch and data travels downward via Lit property bindings — not via callable property bindings (`onXxx`, `handleXxx`) set on child elements.
83
+
84
+ - Detection signals: `.onXxx=${fn}` or `.handleXxx=${fn}` callable property bindings in a parent template.
85
+ - Remediation: dispatch `new CustomEvent('xxx', { detail, bubbles: true, composed: true })` in the child; bind `@xxx=${handler}` in the parent.
86
+
71
87
  **State**
72
88
  - States live at module scope. Many small states beat one monolith. Use `state('feature/name').{memory,session,local,idb}(initial)` from `@mhmo91/schmancy/state`.
73
89
  - Reading `state.value` inside `render()` auto-tracks via the base class's `SignalWatcher` — no decorator or binding needed for the default case.