@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":"autocomplete-Mrb3koUN.js","names":[],"sources":["../src/form/fields/autocomplete/autocomplete.scss?inline","../src/form/fields/autocomplete/autocomplete.ts"],"sourcesContent":[":host {\n\tdisplay: block;\n\tborder: unset !important;\n\tline-height: unset !important;\n\tbackground: unset !important;\n\tpadding: unset !important;\n\tfont-size: unset !important;\n\tbox-shadow: unset !important;\n}\n\n:host:focus {\n\tbox-shadow: unset !important;\n}\n\n@keyframes onAutoFillStart {\n\tfrom {/**/}\n\tto {/**/}\n}\n\nsch-input::part(input):-webkit-autofill,\nsch-input input:-webkit-autofill {\n\tanimation-name: onAutoFillStart;\n\tanimation-duration: 1ms;\n}\n","import { SchmancyFormField } from '@mixins/index'\nimport { InputSize, SchmancyInput } from '@schmancy/input'\nimport SchmancyOption from '@schmancy/option/option'\nimport { html, nothing, unsafeCSS } 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 { createRef, ref } from 'lit/directives/ref.js'\nimport { repeat } from 'lit/directives/repeat.js'\nimport { when } from 'lit/directives/when.js'\nimport {\n BehaviorSubject,\n combineLatest,\n fromEvent,\n timer\n} from 'rxjs'\nimport {\n debounceTime,\n distinctUntilChanged,\n takeUntil,\n tap\n} from 'rxjs/operators'\nimport style from './autocomplete.scss?inline'\n\n// Import the similarity function (or include it inline)\nimport { similarity } from '../../../utils/search'\n// Import chip component for multi-select display\nimport '../../../chips/input-chip'\n\nexport type SchmancyAutocompleteChangeEvent = CustomEvent<{\n value: string | string[]\n values?: string[]\n}>\n\ninterface FilteredOption {\n option: SchmancyOption\n score: number\n}\n\n/**\n * Autocomplete input component with filtering and multi-select support.\n *\n * @prop {string} name - Name attribute for form submission\n * @prop {string} label - Label text displayed above the input\n * @prop {string} placeholder - Placeholder text for the input\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-autocomplete')\nexport default class SchmancyAutocomplete extends SchmancyFormField(unsafeCSS(style)) {\n\n // `formAssociated`, `internals`, `attachInternals`, `name`, `label`,\n // `required`, `disabled`, `error`, `validationMessage`, `hint`, `id`,\n // `validateOn`, `touched/dirty/submitted`, `markTouched/markSubmitted`,\n // `setCustomValidity`, `formDisabledCallback`, FIELD_CONNECT_EVENT dispatch\n // — all from the mixin.\n\n /** Override mixin's resetForm with autocomplete-specific subject reset. */\n override resetForm(): void {\n if (this.multi) {\n this._selectedValues$.next([])\n } else {\n this._selectedValue$.next('')\n }\n this._inputValue = ''\n this._inputValue$.next('')\n super.resetForm()\n }\n\n // Track whether value/values have been explicitly set\n _valueSet: boolean = false\n _valuesSet: boolean = false\n\n // Autocomplete-specific properties only — `name`, `label`, `required`,\n // `error`, `validationMessage` come from the mixin.\n @property({ type: String }) placeholder = ''\n @property({ type: String }) maxHeight = '300px'\n @property({ type: Boolean }) multi = false\n @property({ type: String }) description = ''\n @property({ type: String, reflect: true }) size: InputSize = 'md'\n @property({ type: String }) autocomplete = 'off'\n @property({ type: Number }) debounceMs = 200\n @property({ type: Number }) similarityThreshold = 0.3 // Minimum similarity score to show option\n\n private readonly _a11yId = `schmancy-autocomplete-${Math.random().toString(36).slice(2, 10)}`\n\n // Values property for multi-select mode\n @property({ type: Array })\n get values() {\n return [...this._selectedValues$.value]\n }\n set values(vals: string[]) {\n this._valuesSet = true\n this._selectedValues$.next(Array.isArray(vals) ? [...vals] : [])\n }\n\n // Value property — narrowed override of the mixin's wide value union.\n @property({ type: String, reflect: true })\n override get value(): string {\n return this.multi\n ? this._selectedValues$.value.join(',')\n : this._selectedValue$.value\n }\n override set value(val: string) {\n this._valueSet = true\n if (this.multi) {\n const newValues = val ? val.split(',').map(v => v.trim()).filter(Boolean) : []\n const currentValues = this._selectedValues$.value\n // Only update if values actually changed\n if (JSON.stringify(newValues) !== JSON.stringify(currentValues)) {\n this._selectedValues$.next(newValues)\n }\n } else {\n // Only update if value actually changed\n if (val !== this._selectedValue$.value) {\n this._selectedValue$.next(val)\n // Update the input display when value is set\n this._updateInputDisplay()\n }\n }\n }\n\n // State\n @state() private _open = false\n @state() private _inputValue = ''\n @state() private _visibleOptionsCount = 0\n @state() private _hasResults = true\n\n // DOM references\n @query('#options') _listbox!: HTMLUListElement\n @query('sch-input') _input!: SchmancyInput\n @queryAssignedElements({ flatten: true }) private _options!: SchmancyOption[]\n private _inputElementRef = createRef<HTMLInputElement>()\n\n // RxJS Subjects - only what we actually need\n private _selectedValue$ = new BehaviorSubject<string>('')\n private _selectedValues$ = new BehaviorSubject<string[]>([])\n private _inputValue$ = new BehaviorSubject<string>('')\n\n override connectedCallback() {\n // FIELD_CONNECT_EVENT is dispatched by the mixin's connectedCallback.\n super.connectedCallback()\n this._setupAutocompleteLogic()\n this._setupDocumentClickHandler()\n }\n\n private _setupAutocompleteLogic() {\n // Sync selection state\n combineLatest([\n this._selectedValue$,\n this._selectedValues$\n ]).pipe(\n tap(([selectedValue, selectedValues]) => {\n this._updateOptionSelection(selectedValue, selectedValues)\n // Keep ElementInternals form value in sync with selection (single and multi).\n const formValue = this.multi ? selectedValues.join(',') : selectedValue\n this.internals?.setFormValue(formValue || null)\n if (this.required) {\n const missing = this.multi ? selectedValues.length === 0 : !selectedValue\n this.internals?.setValidity(\n missing ? { valueMissing: true } : {},\n missing ? this.validationMessage || 'Please select an option.' : undefined,\n )\n }\n }),\n takeUntil(this.disconnecting)\n ).subscribe()\n\n // Filter options based on input\n this._inputValue$.pipe(\n distinctUntilChanged(),\n debounceTime(this.debounceMs),\n tap(searchTerm => {\n if (this._open) {\n this._filterOptions(searchTerm)\n }\n }),\n takeUntil(this.disconnecting)\n ).subscribe()\n }\n\n private _setupOptionHandlers() {\n this._options.forEach((option, index) => {\n option.setAttribute('role', 'option')\n option.tabIndex = -1\n if (!option.id) {\n option.id = `${this.id}-option-${index}`\n }\n // Idempotent: slotchange may fire repeatedly for the same option nodes,\n // and addEventListener doesn't replace prior handlers like onfoo= did.\n if (option.dataset.schmancyAutocompleteHandlers === 'attached') return\n option.dataset.schmancyAutocompleteHandlers = 'attached'\n\n // Prevent blur handler from interfering with option selection\n fromEvent<MouseEvent>(option, 'mousedown')\n .pipe(takeUntil(this.disconnecting))\n .subscribe(e => e.preventDefault())\n\n // Handle the actual selection\n fromEvent<MouseEvent>(option, 'click')\n .pipe(takeUntil(this.disconnecting))\n .subscribe(e => {\n e.stopPropagation()\n this._selectOption(option)\n })\n })\n }\n\n private _updateOptionSelection(selectedValue: string, selectedValues: string[]) {\n this._options.forEach(option => {\n option.selected = this.multi\n ? selectedValues.includes(option.value)\n : option.value === selectedValue\n option.setAttribute('aria-selected', String(option.selected))\n })\n }\n\n private _filterOptions(searchTerm: string) {\n const term = searchTerm.trim()\n\n if (!term) {\n // Show all options if no search term\n this._options.forEach(option => {\n option.hidden = false\n option.style.order = '0'\n })\n this._visibleOptionsCount = this._options.length\n this._hasResults = true\n } else {\n // Calculate similarity scores for all options\n const scoredOptions: FilteredOption[] = this._options.map(option => {\n const optionLabel = option.label || option.textContent || ''\n const optionValue = option.value\n\n const labelScore = similarity(term, optionLabel)\n const valueScore = similarity(term, optionValue)\n const score = Math.max(labelScore * 1.1, valueScore)\n\n return { option, score }\n })\n\n // Sort by score (highest first)\n scoredOptions.sort((a, b) => b.score - a.score)\n\n // Apply visibility and ordering\n let visibleCount = 0\n scoredOptions.forEach((item, index) => {\n const { option, score } = item\n\n if (score < this.similarityThreshold) {\n option.hidden = true\n } else {\n option.hidden = false\n visibleCount++\n option.style.order = String(index)\n }\n })\n\n this._visibleOptionsCount = visibleCount\n this._hasResults = visibleCount > 0\n }\n\n this._announceToScreenReader(\n this._visibleOptionsCount > 0\n ? `${this._visibleOptionsCount} option${this._visibleOptionsCount === 1 ? '' : 's'} available.`\n : 'No results found.'\n )\n }\n\n private _openDropdown() {\n this._open = true\n // Reset filters based on current input value when dropdown opens\n this._filterOptions(this._inputValue)\n }\n\n private _selectOption(option: SchmancyOption) {\n if (this.multi) {\n const currentValues = this._selectedValues$.value\n const index = currentValues.indexOf(option.value)\n const newValues = index > -1\n ? currentValues.filter(v => v !== option.value)\n : [...currentValues, option.value]\n\n this._selectedValues$.next(newValues)\n this._announceToScreenReader(\n newValues.length > 0\n ? `Selected: ${this._getSelectedLabels().join(', ')}`\n : 'No options selected'\n )\n this._fireChangeEvent()\n } else {\n // Update value first\n this._selectedValue$.next(option.value)\n\n // Close dropdown IMMEDIATELY to prevent blur handler from firing\n this._open = false\n\n // Now fire event with the NEW value\n this._fireChangeEvent()\n\n // Update UI\n this._inputValue = option.label || option.textContent || ''\n this._inputValue$.next(this._inputValue)\n\n this._announceToScreenReader(`Selected: ${option.label || option.textContent}`)\n }\n }\n\n private _setupDocumentClickHandler() {\n fromEvent<MouseEvent>(document, 'click')\n .pipe(takeUntil(this.disconnecting))\n .subscribe(e => {\n if (!this._open) return\n const path = e.composedPath()\n if (!path.includes(this) && !this._options.some(opt => path.includes(opt))) {\n this._open = false\n this._updateInputDisplay()\n }\n })\n }\n\n\n private _updateInputDisplay() {\n // For multi-select, we don't update input display since chips show the selections\n if (this.multi) return\n\n const selectedValue = this._selectedValue$.value\n const option = this._options.find(opt => opt.value === selectedValue)\n this._inputValue = option ? option.label || option.textContent || '' : ''\n this._inputValue$.next(this._inputValue)\n\n if (this._inputElementRef.value) {\n this._inputElementRef.value.value = this._inputValue\n }\n }\n\n private _getSelectedLabels(): string[] {\n return this._options\n .filter(option => \n this.multi \n ? this._selectedValues$.value.includes(option.value)\n : option.value === this._selectedValue$.value\n )\n .map(option => option.label || option.textContent || '')\n }\n\n private _announceToScreenReader(message: string) {\n const liveRegion = this.shadowRoot?.querySelector('#live-status')\n if (liveRegion) {\n liveRegion.textContent = message\n }\n }\n\n private _fireChangeEvent() {\n const detail: SchmancyAutocompleteChangeEvent['detail'] = {\n value: this.value,\n }\n\n if (this.multi) {\n detail.values = [...this._selectedValues$.value]\n }\n\n this.dispatchEvent(\n new CustomEvent<SchmancyAutocompleteChangeEvent['detail']>('change', {\n detail,\n bubbles: true,\n composed: true,\n })\n )\n }\n\n public checkValidity(): boolean {\n if (!this.required) return true\n return this.multi \n ? this._selectedValues$.value.length > 0 \n : Boolean(this._selectedValue$.value)\n }\n\n public reportValidity(): boolean {\n if (this._inputElementRef.value) {\n return this._inputElementRef.value.reportValidity()\n }\n return this.checkValidity()\n }\n\n firstUpdated() {\n this._setupOptionHandlers()\n\n // Sync initial value with display after options are available\n this._updateInputDisplay()\n\n // Update options when slot changes\n const slot = this.shadowRoot?.querySelector('slot')\n slot?.addEventListener('slotchange', () => {\n this._setupOptionHandlers()\n this._updateOptionSelection(this._selectedValue$.value, this._selectedValues$.value)\n })\n }\n\n private handleChipRemove(value: string) {\n const currentValues = this._selectedValues$.value\n const newValues = currentValues.filter(v => v !== value)\n this._selectedValues$.next(newValues)\n this._fireChangeEvent()\n this._announceToScreenReader(`Removed: ${this._getChipLabel(value)}`)\n }\n\n private _getChipLabel(value: string): string {\n const option = this._options.find(opt => opt.value === value)\n return option ? option.label || option.textContent || value : value\n }\n\n private _focusTextInput() {\n if (this._inputElementRef.value) {\n this._inputElementRef.value.focus()\n }\n }\n\n render() {\n const descriptionId = `${this.id}-desc`\n\n // Get size-based styling to match Schmancy input\n const getSizeStyles = () => {\n switch (this.size) {\n case 'sm':\n return {\n height: 'min-h-[40px]',\n padding: 'px-2',\n fontSize: 'text-sm', // 14px\n labelSize: 'text-sm'\n }\n case 'lg':\n return {\n height: 'min-h-[60px]',\n padding: 'px-5',\n fontSize: 'text-lg', // 18px\n labelSize: 'text-lg'\n }\n case 'md':\n default:\n return {\n height: 'min-h-[50px]',\n padding: 'px-4',\n fontSize: 'text-base', // 16px\n labelSize: 'text-base'\n }\n }\n }\n\n const { height, padding, fontSize, labelSize } = getSizeStyles()\n\n return html`\n <div class=\"relative\">\n <!-- Screen reader live region -->\n <div id=\"live-status\" role=\"status\" aria-live=\"polite\" class=\"sr-only\"></div>\n\n <!-- Description -->\n ${this.description ? html`<div id=\"${descriptionId}\" class=\"sr-only\">${this.description}</div>` : ''}\n\n <!-- Custom input wrapper for Gmail-style chip input -->\n <slot name=\"trigger\">\n ${when(this.multi,\n () => html`\n <!-- Custom multi-select input with inline chips -->\n <div class=\"relative\">\n ${when(this.label, () => html`\n <label class=\"${classMap({\n 'block mb-1 font-medium': true,\n 'text-primary-default': !this.error,\n 'text-error-default': this.error,\n [labelSize]: true\n })}\">\n ${this.label}${this.required ? html`<span class=\"text-error-default ml-1\">*</span>` : ''}\n </label>\n `)}\n <div\n class=\"${classMap({\n 'flex flex-wrap items-center gap-1': true,\n [height]: true,\n [padding]: true,\n 'block w-full min-w-0 rounded-[8px] border-0': true,\n 'bg-surface-highest text-surface-on': true,\n 'ring-0 ring-inset focus-within:ring-1 focus-within:ring-inset': true,\n 'ring-secondary-default focus-within:ring-secondary-default': !this.error,\n 'ring-error-default focus-within:ring-error-default': this.error,\n 'cursor-text transition-colors duration-200': true\n })}\"\n @click=${() => this._focusTextInput()}\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n aria-controls=\"options\"\n aria-expanded=${this._open}\n >\n <!-- Render chips inline -->\n ${repeat(\n this._selectedValues$.value,\n value => value,\n value => html`\n <schmancy-input-chip\n .value=${value}\n @remove=${(e: CustomEvent) => this.handleChipRemove(e.detail.value)}\n class=\"shrink-0 my-0.5\"\n >\n ${this._getChipLabel(value)}\n </schmancy-input-chip>\n `\n )}\n\n <!-- Text input for typing -->\n <input\n ${ref(this._inputElementRef)}\n id=\"autocomplete-input\"\n type=\"text\"\n class=\"flex-1 min-w-[120px] py-1 bg-transparent border-none outline-none ${fontSize} font-medium text-surface-on placeholder:text-muted\"\n name=${this.name || this.label?.toLowerCase().replace(/\\s+/g, '-') || ''}\n .placeholder=${this._selectedValues$.value.length > 0 ? 'Add more...' : this.placeholder}\n .value=${this._inputValue}\n .autocomplete=${this.autocomplete}\n aria-invalid=${this.error ? 'true' : 'false'}\n aria-required=${this.required ? 'true' : 'false'}\n aria-describedby=${this.error && this.validationMessage ? `${this._a11yId}-err` : nothing}\n aria-label=${!this.label && this.placeholder ? this.placeholder : nothing}\n @input=${(e: Event) => {\n const value = (e.target as HTMLInputElement).value\n this._inputValue = value\n this._inputValue$.next(value)\n }}\n @focus=${(e: FocusEvent) => {\n e.stopPropagation()\n // Clear input on focus for new searches\n this._inputValue = ''\n this._inputValue$.next('')\n this._openDropdown()\n }}\n @keydown=${(e: KeyboardEvent) => {\n this._handleKeyDown(e)\n }}\n @blur=${() => {\n this._handleAutoSelectOnBlur()\n }}\n />\n </div>\n\n <!-- Validation message -->\n ${when(this.error && this.validationMessage, () => html`\n <div id=\"${this._a11yId}-err\" class=\"mt-1 text-sm text-error-default\" role=\"alert\">\n ${this.validationMessage}\n </div>\n `)}\n </div>\n `,\n () => html`\n <!-- Regular single-select input -->\n <schmancy-input\n .size=${this.size}\n ${ref(this._inputElementRef)}\n id=\"autocomplete-input\"\n class=\"w-full\"\n .name=${this.name || this.label?.toLowerCase().replace(/\\s+/g, '-') || ''}\n .label=${this.label}\n .placeholder=${this.placeholder}\n .required=${this.required}\n .value=${this._inputValue}\n type=\"text\"\n autocomplete=${this.autocomplete}\n clickable\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n aria-controls=\"options\"\n aria-expanded=${this._open}\n aria-describedby=${ifDefined(this.description ? descriptionId : undefined)}\n @input=${(e: Event) => {\n const value = (e.target as HTMLInputElement).value\n this._inputValue = value\n this._inputValue$.next(value)\n }}\n @focus=${(e: FocusEvent) => {\n e.stopPropagation()\n this._openDropdown()\n }}\n @click=${(e: MouseEvent) => {\n e.stopPropagation()\n this._openDropdown()\n }}\n @keydown=${(e: KeyboardEvent) => {\n this._handleKeyDown(e)\n }}\n @blur=${() => {\n this._handleAutoSelectOnBlur()\n }}\n >\n </schmancy-input>\n `\n )}\n </slot>\n\n <!-- Options dropdown -->\n <ul\n id=\"options\"\n class=${classMap({\n 'absolute': true,\n 'z-[1000]': true,\n 'mt-1': true,\n 'w-full': true,\n 'rounded-md': true,\n 'shadow-md': true,\n 'overflow-auto': true,\n 'min-w-full': true,\n 'bg-surface-low': true,\n 'flex': true,\n 'flex-col': true, // Enable flexbox for ordering\n })}\n role=\"listbox\"\n aria-multiselectable=${this.multi ? 'true' : 'false'}\n aria-label=${`${this.label || 'Options'} dropdown`}\n ?hidden=${!this._open}\n style=\"max-height: ${this.maxHeight}; display: ${this._open ? 'flex' : 'none'};\"\n @slotchange=${() => {\n this._setupOptionHandlers()\n }}\n >\n <slot></slot>\n ${!this._hasResults ? html`\n <li class=\"px-3 py-2 text-sm text-muted\">No results found</li>\n ` : ''}\n </ul>\n </div>\n `\n }\n\n private _handleAutoSelectOnBlur() {\n // Only auto-select in single-select mode and when dropdown is open with a search term\n if (this.multi || !this._open || !this._inputValue.trim()) {\n return\n }\n \n const searchTerm = this._inputValue.trim()\n \n // Find the best matching option using the same similarity logic as filtering\n let bestMatch: SchmancyOption | null = null\n let bestScore = 0\n \n this._options.forEach(option => {\n // Skip hidden options\n if (option.hidden) return\n \n // Get text to search in (prioritize label, then textContent, then value)\n const optionLabel = option.label || option.textContent || ''\n const optionValue = option.value\n \n // Calculate similarity scores for both label and value\n const labelScore = similarity(searchTerm, optionLabel)\n const valueScore = similarity(searchTerm, optionValue)\n \n // Use the higher score (prioritizing label matches)\n const score = Math.max(labelScore * 1.1, valueScore) // Slight boost for label matches\n \n // Keep track of best match that meets threshold\n if (score > bestScore && score >= this.similarityThreshold) {\n bestScore = score\n bestMatch = option\n }\n })\n \n // Auto-select the best match if found\n if (bestMatch) {\n // Silently update the selected value without firing change event\n this._selectedValue$.next(bestMatch.value)\n this._inputValue = bestMatch.label || bestMatch.textContent || ''\n this._inputValue$.next(this._inputValue)\n this._open = false\n }\n }\n\n private _handleKeyDown(event: KeyboardEvent) {\n const isOpen = this._open\n const selectedValues = this._selectedValues$.value\n\n // Handle backspace to remove last chip in multi-select when input is empty\n if (this.multi && event.key === 'Backspace' && !this._inputValue && selectedValues.length > 0 && !isOpen) {\n event.preventDefault()\n const lastValue = selectedValues[selectedValues.length - 1]\n this.handleChipRemove(lastValue)\n return\n }\n\n if (!isOpen && (event.key === 'ArrowDown' || event.key === 'Enter')) {\n event.preventDefault()\n this._openDropdown()\n\n timer(10)\n .pipe(takeUntil(this.disconnecting))\n .subscribe(() => {\n const firstVisible = this._options.find(opt => !opt.hidden)\n firstVisible?.focus()\n })\n return\n }\n\n if (!isOpen) return\n\n const visibleOptions = this._options.filter(opt => !opt.hidden)\n .toSorted((a, b) => parseInt(a.style.order || '0') - parseInt(b.style.order || '0'))\n\n const focusedOption = visibleOptions.find(opt => opt === document.activeElement)\n const currentIndex = focusedOption ? visibleOptions.indexOf(focusedOption) : -1\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault()\n this._open = false\n this._updateInputDisplay()\n this._inputElementRef.value?.focus()\n break\n\n case 'Tab':\n this._open = false\n this._updateInputDisplay()\n break\n\n case 'ArrowDown':\n event.preventDefault()\n const nextIndex = currentIndex < visibleOptions.length - 1 ? currentIndex + 1 : 0\n visibleOptions[nextIndex]?.focus()\n break\n\n case 'ArrowUp':\n event.preventDefault()\n const prevIndex = currentIndex > 0 ? currentIndex - 1 : visibleOptions.length - 1\n visibleOptions[prevIndex]?.focus()\n break\n\n case 'Home':\n event.preventDefault()\n visibleOptions[0]?.focus()\n break\n\n case 'End':\n event.preventDefault()\n visibleOptions[visibleOptions.length - 1]?.focus()\n break\n\n case 'Enter':\n case ' ':\n if (focusedOption) {\n event.preventDefault()\n this._selectOption(focusedOption)\n }\n break\n }\n }\n}\n\n\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'schmancy-autocomplete': SchmancyAutocomplete\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"autocomplete-Ds3Q2cwR.js","names":[],"sources":["../src/form/fields/autocomplete/autocomplete.scss?inline","../src/form/fields/autocomplete/autocomplete.ts"],"sourcesContent":[":host {\n\tdisplay: block;\n\tborder: unset !important;\n\tline-height: unset !important;\n\tbackground: unset !important;\n\tpadding: unset !important;\n\tfont-size: unset !important;\n\tbox-shadow: unset !important;\n}\n\n:host:focus {\n\tbox-shadow: unset !important;\n}\n\n@keyframes onAutoFillStart {\n\tfrom {/**/}\n\tto {/**/}\n}\n\nsch-input::part(input):-webkit-autofill,\nsch-input input:-webkit-autofill {\n\tanimation-name: onAutoFillStart;\n\tanimation-duration: 1ms;\n}\n","import { SchmancyFormField } from '@mixins/index'\nimport { InputSize, SchmancyInput } from '@schmancy/input'\nimport SchmancyOption from '@schmancy/option/option'\nimport { html, nothing, unsafeCSS } 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 { createRef, ref } from 'lit/directives/ref.js'\nimport { repeat } from 'lit/directives/repeat.js'\nimport { when } from 'lit/directives/when.js'\nimport {\n BehaviorSubject,\n combineLatest,\n fromEvent,\n timer\n} from 'rxjs'\nimport {\n debounceTime,\n distinctUntilChanged,\n takeUntil,\n tap\n} from 'rxjs/operators'\nimport style from './autocomplete.scss?inline'\n\n// Import the similarity function (or include it inline)\nimport { similarity } from '../../../utils/search'\n// Import chip component for multi-select display\nimport '../../../chips/input-chip'\n\nexport type SchmancyAutocompleteChangeEvent = CustomEvent<{\n value: string | string[]\n values?: string[]\n}>\n\ninterface FilteredOption {\n option: SchmancyOption\n score: number\n}\n\n/**\n * Autocomplete input component with filtering and multi-select support.\n *\n * @prop {string} name - Name attribute for form submission\n * @prop {string} label - Label text displayed above the input\n * @prop {string} placeholder - Placeholder text for the input\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-autocomplete')\nexport default class SchmancyAutocomplete extends SchmancyFormField(unsafeCSS(style)) {\n\n // `formAssociated`, `internals`, `attachInternals`, `name`, `label`,\n // `required`, `disabled`, `error`, `validationMessage`, `hint`, `id`,\n // `validateOn`, `touched/dirty/submitted`, `markTouched/markSubmitted`,\n // `setCustomValidity`, `formDisabledCallback`, FIELD_CONNECT_EVENT dispatch\n // — all from the mixin.\n\n /** Override mixin's resetForm with autocomplete-specific subject reset. */\n override resetForm(): void {\n if (this.multi) {\n this._selectedValues$.next([])\n } else {\n this._selectedValue$.next('')\n }\n this._inputValue = ''\n this._inputValue$.next('')\n super.resetForm()\n }\n\n // Track whether value/values have been explicitly set\n _valueSet: boolean = false\n _valuesSet: boolean = false\n\n // Autocomplete-specific properties only — `name`, `label`, `required`,\n // `error`, `validationMessage` come from the mixin.\n @property({ type: String }) placeholder = ''\n @property({ type: String }) maxHeight = '300px'\n @property({ type: Boolean }) multi = false\n @property({ type: String }) description = ''\n @property({ type: String, reflect: true }) size: InputSize = 'md'\n @property({ type: String }) autocomplete = 'off'\n @property({ type: Number }) debounceMs = 200\n @property({ type: Number }) similarityThreshold = 0.3 // Minimum similarity score to show option\n\n private readonly _a11yId = `schmancy-autocomplete-${Math.random().toString(36).slice(2, 10)}`\n\n // Values property for multi-select mode\n @property({ type: Array })\n get values() {\n return [...this._selectedValues$.value]\n }\n set values(vals: string[]) {\n this._valuesSet = true\n this._selectedValues$.next(Array.isArray(vals) ? [...vals] : [])\n }\n\n // Value property — narrowed override of the mixin's wide value union.\n @property({ type: String, reflect: true })\n override get value(): string {\n return this.multi\n ? this._selectedValues$.value.join(',')\n : this._selectedValue$.value\n }\n override set value(val: string) {\n this._valueSet = true\n if (this.multi) {\n const newValues = val ? val.split(',').map(v => v.trim()).filter(Boolean) : []\n const currentValues = this._selectedValues$.value\n // Only update if values actually changed\n if (JSON.stringify(newValues) !== JSON.stringify(currentValues)) {\n this._selectedValues$.next(newValues)\n }\n } else {\n // Only update if value actually changed\n if (val !== this._selectedValue$.value) {\n this._selectedValue$.next(val)\n // Update the input display when value is set\n this._updateInputDisplay()\n }\n }\n }\n\n // State\n @state() private _open = false\n @state() private _inputValue = ''\n @state() private _visibleOptionsCount = 0\n @state() private _hasResults = true\n\n // DOM references\n @query('#options') _listbox!: HTMLUListElement\n @query('sch-input') _input!: SchmancyInput\n @queryAssignedElements({ flatten: true }) private _options!: SchmancyOption[]\n private _inputElementRef = createRef<HTMLInputElement>()\n\n // RxJS Subjects - only what we actually need\n private _selectedValue$ = new BehaviorSubject<string>('')\n private _selectedValues$ = new BehaviorSubject<string[]>([])\n private _inputValue$ = new BehaviorSubject<string>('')\n\n override connectedCallback() {\n // FIELD_CONNECT_EVENT is dispatched by the mixin's connectedCallback.\n super.connectedCallback()\n this._setupAutocompleteLogic()\n this._setupDocumentClickHandler()\n }\n\n private _setupAutocompleteLogic() {\n // Sync selection state\n combineLatest([\n this._selectedValue$,\n this._selectedValues$\n ]).pipe(\n tap(([selectedValue, selectedValues]) => {\n this._updateOptionSelection(selectedValue, selectedValues)\n // Keep ElementInternals form value in sync with selection (single and multi).\n const formValue = this.multi ? selectedValues.join(',') : selectedValue\n this.internals?.setFormValue(formValue || null)\n if (this.required) {\n const missing = this.multi ? selectedValues.length === 0 : !selectedValue\n this.internals?.setValidity(\n missing ? { valueMissing: true } : {},\n missing ? this.validationMessage || 'Please select an option.' : undefined,\n )\n }\n }),\n takeUntil(this.disconnecting)\n ).subscribe()\n\n // Filter options based on input\n this._inputValue$.pipe(\n distinctUntilChanged(),\n debounceTime(this.debounceMs),\n tap(searchTerm => {\n if (this._open) {\n this._filterOptions(searchTerm)\n }\n }),\n takeUntil(this.disconnecting)\n ).subscribe()\n }\n\n private _setupOptionHandlers() {\n this._options.forEach((option, index) => {\n option.setAttribute('role', 'option')\n option.tabIndex = -1\n if (!option.id) {\n option.id = `${this.id}-option-${index}`\n }\n // Idempotent: slotchange may fire repeatedly for the same option nodes,\n // and addEventListener doesn't replace prior handlers like onfoo= did.\n if (option.dataset.schmancyAutocompleteHandlers === 'attached') return\n option.dataset.schmancyAutocompleteHandlers = 'attached'\n\n // Prevent blur handler from interfering with option selection\n fromEvent<MouseEvent>(option, 'mousedown')\n .pipe(takeUntil(this.disconnecting))\n .subscribe(e => e.preventDefault())\n\n // Handle the actual selection\n fromEvent<MouseEvent>(option, 'click')\n .pipe(takeUntil(this.disconnecting))\n .subscribe(e => {\n e.stopPropagation()\n this._selectOption(option)\n })\n })\n }\n\n private _updateOptionSelection(selectedValue: string, selectedValues: string[]) {\n this._options.forEach(option => {\n option.selected = this.multi\n ? selectedValues.includes(option.value)\n : option.value === selectedValue\n option.setAttribute('aria-selected', String(option.selected))\n })\n }\n\n private _filterOptions(searchTerm: string) {\n const term = searchTerm.trim()\n\n if (!term) {\n // Show all options if no search term\n this._options.forEach(option => {\n option.hidden = false\n option.style.order = '0'\n })\n this._visibleOptionsCount = this._options.length\n this._hasResults = true\n } else {\n // Calculate similarity scores for all options\n const scoredOptions: FilteredOption[] = this._options.map(option => {\n const optionLabel = option.label || option.textContent || ''\n const optionValue = option.value\n\n const labelScore = similarity(term, optionLabel)\n const valueScore = similarity(term, optionValue)\n const score = Math.max(labelScore * 1.1, valueScore)\n\n return { option, score }\n })\n\n // Sort by score (highest first)\n scoredOptions.sort((a, b) => b.score - a.score)\n\n // Apply visibility and ordering\n let visibleCount = 0\n scoredOptions.forEach((item, index) => {\n const { option, score } = item\n\n if (score < this.similarityThreshold) {\n option.hidden = true\n } else {\n option.hidden = false\n visibleCount++\n option.style.order = String(index)\n }\n })\n\n this._visibleOptionsCount = visibleCount\n this._hasResults = visibleCount > 0\n }\n\n this._announceToScreenReader(\n this._visibleOptionsCount > 0\n ? `${this._visibleOptionsCount} option${this._visibleOptionsCount === 1 ? '' : 's'} available.`\n : 'No results found.'\n )\n }\n\n private _openDropdown() {\n this._open = true\n // Reset filters based on current input value when dropdown opens\n this._filterOptions(this._inputValue)\n }\n\n private _selectOption(option: SchmancyOption) {\n if (this.multi) {\n const currentValues = this._selectedValues$.value\n const index = currentValues.indexOf(option.value)\n const newValues = index > -1\n ? currentValues.filter(v => v !== option.value)\n : [...currentValues, option.value]\n\n this._selectedValues$.next(newValues)\n this._announceToScreenReader(\n newValues.length > 0\n ? `Selected: ${this._getSelectedLabels().join(', ')}`\n : 'No options selected'\n )\n this._fireChangeEvent()\n } else {\n // Update value first\n this._selectedValue$.next(option.value)\n\n // Close dropdown IMMEDIATELY to prevent blur handler from firing\n this._open = false\n\n // Now fire event with the NEW value\n this._fireChangeEvent()\n\n // Update UI\n this._inputValue = option.label || option.textContent || ''\n this._inputValue$.next(this._inputValue)\n\n this._announceToScreenReader(`Selected: ${option.label || option.textContent}`)\n }\n }\n\n private _setupDocumentClickHandler() {\n fromEvent<MouseEvent>(document, 'click')\n .pipe(takeUntil(this.disconnecting))\n .subscribe(e => {\n if (!this._open) return\n const path = e.composedPath()\n if (!path.includes(this) && !this._options.some(opt => path.includes(opt))) {\n this._open = false\n this._updateInputDisplay()\n }\n })\n }\n\n\n private _updateInputDisplay() {\n // For multi-select, we don't update input display since chips show the selections\n if (this.multi) return\n\n const selectedValue = this._selectedValue$.value\n const option = this._options.find(opt => opt.value === selectedValue)\n this._inputValue = option ? option.label || option.textContent || '' : ''\n this._inputValue$.next(this._inputValue)\n\n if (this._inputElementRef.value) {\n this._inputElementRef.value.value = this._inputValue\n }\n }\n\n private _getSelectedLabels(): string[] {\n return this._options\n .filter(option => \n this.multi \n ? this._selectedValues$.value.includes(option.value)\n : option.value === this._selectedValue$.value\n )\n .map(option => option.label || option.textContent || '')\n }\n\n private _announceToScreenReader(message: string) {\n const liveRegion = this.shadowRoot?.querySelector('#live-status')\n if (liveRegion) {\n liveRegion.textContent = message\n }\n }\n\n private _fireChangeEvent() {\n const detail: SchmancyAutocompleteChangeEvent['detail'] = {\n value: this.value,\n }\n\n if (this.multi) {\n detail.values = [...this._selectedValues$.value]\n }\n\n this.dispatchEvent(\n new CustomEvent<SchmancyAutocompleteChangeEvent['detail']>('change', {\n detail,\n bubbles: true,\n composed: true,\n })\n )\n }\n\n public checkValidity(): boolean {\n if (!this.required) return true\n return this.multi \n ? this._selectedValues$.value.length > 0 \n : Boolean(this._selectedValue$.value)\n }\n\n public reportValidity(): boolean {\n if (this._inputElementRef.value) {\n return this._inputElementRef.value.reportValidity()\n }\n return this.checkValidity()\n }\n\n firstUpdated() {\n this._setupOptionHandlers()\n\n // Sync initial value with display after options are available\n this._updateInputDisplay()\n\n // Update options when slot changes\n const slot = this.shadowRoot?.querySelector('slot')\n slot?.addEventListener('slotchange', () => {\n this._setupOptionHandlers()\n this._updateOptionSelection(this._selectedValue$.value, this._selectedValues$.value)\n })\n }\n\n private handleChipRemove(value: string) {\n const currentValues = this._selectedValues$.value\n const newValues = currentValues.filter(v => v !== value)\n this._selectedValues$.next(newValues)\n this._fireChangeEvent()\n this._announceToScreenReader(`Removed: ${this._getChipLabel(value)}`)\n }\n\n private _getChipLabel(value: string): string {\n const option = this._options.find(opt => opt.value === value)\n return option ? option.label || option.textContent || value : value\n }\n\n private _focusTextInput() {\n if (this._inputElementRef.value) {\n this._inputElementRef.value.focus()\n }\n }\n\n render() {\n const descriptionId = `${this.id}-desc`\n\n // Get size-based styling to match Schmancy input\n const getSizeStyles = () => {\n switch (this.size) {\n case 'sm':\n return {\n height: 'min-h-[40px]',\n padding: 'px-2',\n fontSize: 'text-sm', // 14px\n labelSize: 'text-sm'\n }\n case 'lg':\n return {\n height: 'min-h-[60px]',\n padding: 'px-5',\n fontSize: 'text-lg', // 18px\n labelSize: 'text-lg'\n }\n case 'md':\n default:\n return {\n height: 'min-h-[50px]',\n padding: 'px-4',\n fontSize: 'text-base', // 16px\n labelSize: 'text-base'\n }\n }\n }\n\n const { height, padding, fontSize, labelSize } = getSizeStyles()\n\n return html`\n <div class=\"relative\">\n <!-- Screen reader live region -->\n <div id=\"live-status\" role=\"status\" aria-live=\"polite\" class=\"sr-only\"></div>\n\n <!-- Description -->\n ${this.description ? html`<div id=\"${descriptionId}\" class=\"sr-only\">${this.description}</div>` : ''}\n\n <!-- Custom input wrapper for Gmail-style chip input -->\n <slot name=\"trigger\">\n ${when(this.multi,\n () => html`\n <!-- Custom multi-select input with inline chips -->\n <div class=\"relative\">\n ${when(this.label, () => html`\n <label class=\"${classMap({\n 'block mb-1 font-medium': true,\n 'text-primary-default': !this.error,\n 'text-error-default': this.error,\n [labelSize]: true\n })}\">\n ${this.label}${this.required ? html`<span class=\"text-error-default ml-1\">*</span>` : ''}\n </label>\n `)}\n <div\n class=\"${classMap({\n 'flex flex-wrap items-center gap-1': true,\n [height]: true,\n [padding]: true,\n 'block w-full min-w-0 rounded-[8px] border-0': true,\n 'bg-surface-highest text-surface-on': true,\n 'ring-0 ring-inset focus-within:ring-1 focus-within:ring-inset': true,\n 'ring-secondary-default focus-within:ring-secondary-default': !this.error,\n 'ring-error-default focus-within:ring-error-default': this.error,\n 'cursor-text transition-colors duration-200': true\n })}\"\n @click=${() => this._focusTextInput()}\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n aria-controls=\"options\"\n aria-expanded=${this._open}\n >\n <!-- Render chips inline -->\n ${repeat(\n this._selectedValues$.value,\n value => value,\n value => html`\n <schmancy-input-chip\n .value=${value}\n @remove=${(e: CustomEvent) => this.handleChipRemove(e.detail.value)}\n class=\"shrink-0 my-0.5\"\n >\n ${this._getChipLabel(value)}\n </schmancy-input-chip>\n `\n )}\n\n <!-- Text input for typing -->\n <input\n ${ref(this._inputElementRef)}\n id=\"autocomplete-input\"\n type=\"text\"\n class=\"flex-1 min-w-[120px] py-1 bg-transparent border-none outline-none ${fontSize} font-medium text-surface-on placeholder:text-muted\"\n name=${this.name || this.label?.toLowerCase().replace(/\\s+/g, '-') || ''}\n .placeholder=${this._selectedValues$.value.length > 0 ? 'Add more...' : this.placeholder}\n .value=${this._inputValue}\n .autocomplete=${this.autocomplete}\n aria-invalid=${this.error ? 'true' : 'false'}\n aria-required=${this.required ? 'true' : 'false'}\n aria-describedby=${this.error && this.validationMessage ? `${this._a11yId}-err` : nothing}\n aria-label=${!this.label && this.placeholder ? this.placeholder : nothing}\n @input=${(e: Event) => {\n const value = (e.target as HTMLInputElement).value\n this._inputValue = value\n this._inputValue$.next(value)\n }}\n @focus=${(e: FocusEvent) => {\n e.stopPropagation()\n // Clear input on focus for new searches\n this._inputValue = ''\n this._inputValue$.next('')\n this._openDropdown()\n }}\n @keydown=${(e: KeyboardEvent) => {\n this._handleKeyDown(e)\n }}\n @blur=${() => {\n this._handleAutoSelectOnBlur()\n }}\n />\n </div>\n\n <!-- Validation message -->\n ${when(this.error && this.validationMessage, () => html`\n <div id=\"${this._a11yId}-err\" class=\"mt-1 text-sm text-error-default\" role=\"alert\">\n ${this.validationMessage}\n </div>\n `)}\n </div>\n `,\n () => html`\n <!-- Regular single-select input -->\n <schmancy-input\n .size=${this.size}\n ${ref(this._inputElementRef)}\n id=\"autocomplete-input\"\n class=\"w-full\"\n .name=${this.name || this.label?.toLowerCase().replace(/\\s+/g, '-') || ''}\n .label=${this.label}\n .placeholder=${this.placeholder}\n .required=${this.required}\n .value=${this._inputValue}\n type=\"text\"\n autocomplete=${this.autocomplete}\n clickable\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n aria-controls=\"options\"\n aria-expanded=${this._open}\n aria-describedby=${ifDefined(this.description ? descriptionId : undefined)}\n @input=${(e: Event) => {\n const value = (e.target as HTMLInputElement).value\n this._inputValue = value\n this._inputValue$.next(value)\n }}\n @focus=${(e: FocusEvent) => {\n e.stopPropagation()\n this._openDropdown()\n }}\n @click=${(e: MouseEvent) => {\n e.stopPropagation()\n this._openDropdown()\n }}\n @keydown=${(e: KeyboardEvent) => {\n this._handleKeyDown(e)\n }}\n @blur=${() => {\n this._handleAutoSelectOnBlur()\n }}\n >\n </schmancy-input>\n `\n )}\n </slot>\n\n <!-- Options dropdown -->\n <ul\n id=\"options\"\n class=${classMap({\n 'absolute': true,\n 'z-[1000]': true,\n 'mt-1': true,\n 'w-full': true,\n 'rounded-md': true,\n 'shadow-md': true,\n 'overflow-auto': true,\n 'min-w-full': true,\n 'bg-surface-low': true,\n 'flex': true,\n 'flex-col': true, // Enable flexbox for ordering\n })}\n role=\"listbox\"\n aria-multiselectable=${this.multi ? 'true' : 'false'}\n aria-label=${`${this.label || 'Options'} dropdown`}\n ?hidden=${!this._open}\n style=\"max-height: ${this.maxHeight}; display: ${this._open ? 'flex' : 'none'};\"\n @slotchange=${() => {\n this._setupOptionHandlers()\n }}\n >\n <slot></slot>\n ${!this._hasResults ? html`\n <li class=\"px-3 py-2 text-sm text-muted\">No results found</li>\n ` : ''}\n </ul>\n </div>\n `\n }\n\n private _handleAutoSelectOnBlur() {\n // Only auto-select in single-select mode and when dropdown is open with a search term\n if (this.multi || !this._open || !this._inputValue.trim()) {\n return\n }\n \n const searchTerm = this._inputValue.trim()\n \n // Find the best matching option using the same similarity logic as filtering\n let bestMatch: SchmancyOption | null = null\n let bestScore = 0\n \n this._options.forEach(option => {\n // Skip hidden options\n if (option.hidden) return\n \n // Get text to search in (prioritize label, then textContent, then value)\n const optionLabel = option.label || option.textContent || ''\n const optionValue = option.value\n \n // Calculate similarity scores for both label and value\n const labelScore = similarity(searchTerm, optionLabel)\n const valueScore = similarity(searchTerm, optionValue)\n \n // Use the higher score (prioritizing label matches)\n const score = Math.max(labelScore * 1.1, valueScore) // Slight boost for label matches\n \n // Keep track of best match that meets threshold\n if (score > bestScore && score >= this.similarityThreshold) {\n bestScore = score\n bestMatch = option\n }\n })\n \n // Auto-select the best match if found\n if (bestMatch) {\n // Silently update the selected value without firing change event\n this._selectedValue$.next(bestMatch.value)\n this._inputValue = bestMatch.label || bestMatch.textContent || ''\n this._inputValue$.next(this._inputValue)\n this._open = false\n }\n }\n\n private _handleKeyDown(event: KeyboardEvent) {\n const isOpen = this._open\n const selectedValues = this._selectedValues$.value\n\n // Handle backspace to remove last chip in multi-select when input is empty\n if (this.multi && event.key === 'Backspace' && !this._inputValue && selectedValues.length > 0 && !isOpen) {\n event.preventDefault()\n const lastValue = selectedValues[selectedValues.length - 1]\n this.handleChipRemove(lastValue)\n return\n }\n\n if (!isOpen && (event.key === 'ArrowDown' || event.key === 'Enter')) {\n event.preventDefault()\n this._openDropdown()\n\n timer(10)\n .pipe(takeUntil(this.disconnecting))\n .subscribe(() => {\n const firstVisible = this._options.find(opt => !opt.hidden)\n firstVisible?.focus()\n })\n return\n }\n\n if (!isOpen) return\n\n const visibleOptions = this._options.filter(opt => !opt.hidden)\n .toSorted((a, b) => parseInt(a.style.order || '0') - parseInt(b.style.order || '0'))\n\n const focusedOption = visibleOptions.find(opt => opt === document.activeElement)\n const currentIndex = focusedOption ? visibleOptions.indexOf(focusedOption) : -1\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault()\n this._open = false\n this._updateInputDisplay()\n this._inputElementRef.value?.focus()\n break\n\n case 'Tab':\n this._open = false\n this._updateInputDisplay()\n break\n\n case 'ArrowDown':\n event.preventDefault()\n const nextIndex = currentIndex < visibleOptions.length - 1 ? currentIndex + 1 : 0\n visibleOptions[nextIndex]?.focus()\n break\n\n case 'ArrowUp':\n event.preventDefault()\n const prevIndex = currentIndex > 0 ? currentIndex - 1 : visibleOptions.length - 1\n visibleOptions[prevIndex]?.focus()\n break\n\n case 'Home':\n event.preventDefault()\n visibleOptions[0]?.focus()\n break\n\n case 'End':\n event.preventDefault()\n visibleOptions[visibleOptions.length - 1]?.focus()\n break\n\n case 'Enter':\n case ' ':\n if (focusedOption) {\n event.preventDefault()\n this._selectOption(focusedOption)\n }\n break\n }\n }\n}\n\n\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'schmancy-autocomplete': SchmancyAutocomplete\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- require(`./autocomplete-B8CE5vGw.cjs`);
1
+ require(`./autocomplete-CfBFDSc3.cjs`);
@@ -1 +1 @@
1
- import "./autocomplete-Mrb3koUN.js";
1
+ import "./autocomplete-Ds3Q2cwR.js";
package/dist/avatar.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`),n=require(`./directives.cjs`),r=require(`./theme.interface-D4NeufQA.cjs`);let i=require(`lit/decorators.js`),a=require(`lit`);var o=class extends e.c{constructor(...e){super(...e),this.initials=``,this.src=``,this.icon=``,this.size=`md`,this.color=`primary`,this.shape=`circle`,this.bordered=!1,this.status=`none`}render(){let e;e=this.src?a.html`<img class="w-full h-full object-cover" src="${this.src}" alt="Avatar" />`:this.initials?a.html`<span class="text-center font-medium">${this.initials.substring(0,2).toUpperCase()}</span>`:this.icon?a.html`<schmancy-icon>${this.icon}</schmancy-icon>`:a.html`<schmancy-icon>person</schmancy-icon>`;let t={"relative flex items-center justify-center overflow-hidden":!0,[{xxs:`w-5 h-5 text-[8px]`,xs:`w-6 h-6 text-xs`,sm:`w-8 h-8 text-sm`,md:`w-10 h-10 text-base`,lg:`w-12 h-12 text-lg`,xl:`w-16 h-16 text-xl`}[this.size]]:!0,[{circle:`rounded-full`,square:`rounded-md`}[this.shape]]:!0,"border-2 border-surface-container":this.bordered},n=this.getColorAttributes();return a.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),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(`lit/decorators.js`),a=require(`lit`);var o=class extends e.c{constructor(...e){super(...e),this.initials=``,this.src=``,this.icon=``,this.size=`md`,this.color=`primary`,this.shape=`circle`,this.bordered=!1,this.status=`none`}render(){let e;e=this.src?a.html`<img class="w-full h-full object-cover" src="${this.src}" alt="Avatar" />`:this.initials?a.html`<span class="text-center font-medium">${this.initials.substring(0,2).toUpperCase()}</span>`:this.icon?a.html`<schmancy-icon>${this.icon}</schmancy-icon>`:a.html`<schmancy-icon>person</schmancy-icon>`;let t={"relative flex items-center justify-center overflow-hidden":!0,[{xxs:`w-5 h-5 text-[8px]`,xs:`w-6 h-6 text-xs`,sm:`w-8 h-8 text-sm`,md:`w-10 h-10 text-base`,lg:`w-12 h-12 text-lg`,xl:`w-16 h-16 text-xl`}[this.size]]:!0,[{circle:`rounded-full`,square:`rounded-md`}[this.shape]]:!0,"border-2 border-surface-container":this.bordered},n=this.getColorAttributes();return a.html`
2
2
  <div class="${this.classMap(t)}" ${n}>
3
3
  ${e} ${this.status===`none`?``:this.renderStatusIndicator()}
4
4
  </div>
package/dist/avatar.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 { color as n } from "./directives.js";
4
4
  import { t as r } from "./theme.interface-C2XNgsLB.js";
package/dist/badge.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./src-BIlD63Cz.cjs`);Object.defineProperty(exports,`ScBadgeV2`,{enumerable:!0,get:function(){return e.w}}),Object.defineProperty(exports,`SchmancyBadgeV2`,{enumerable:!0,get:function(){return e.T}});
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./src-ggWtvpDr.cjs`);Object.defineProperty(exports,`ScBadgeV2`,{enumerable:!0,get:function(){return e.w}}),Object.defineProperty(exports,`SchmancyBadgeV2`,{enumerable:!0,get:function(){return e.T}});
package/dist/badge.js CHANGED
@@ -1,2 +1,2 @@
1
- import { T as e, w as t } from "./src-DnunCC4X.js";
1
+ import { T as e, w as t } from "./src-CHd-U-w4.js";
2
2
  export { t as ScBadgeV2, e as SchmancyBadgeV2 };
@@ -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 { d as n, f as r } from "./animation-DCznELuT.js";
4
4
  import { t as i } from "./reduced-motion-D7LqTUMn.js";
@@ -1 +1 @@
1
- {"version":3,"file":"boat-CNWIQPA1.js","names":[],"sources":["../src/boat/boat.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { when } from 'lit/directives/when.js'\nimport { filter, finalize, fromEvent, map, merge, switchMap, takeUntil, tap } from 'rxjs'\nimport { SPRING_SMOOTH, SPRING_SNAPPY } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport { theme } from '../theme/theme.service.js'\n\nconst FAB_HEIGHT = 44\nconst DRAG_THRESHOLD = 5\nconst POSITION_STORAGE_KEY_PREFIX = 'schmancy-boat-'\n\ntype Corner = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'\ntype BoatState = 'collapsed' | 'expanded'\ninterface Position {\n\tx: number\n\ty: number\n}\n\n@customElement('schmancy-boat')\nexport default class SchmancyBoat extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: contents;\n\t\tposition: relative;\n\t\tz-index: 1000;\n\t}\n\t:host([hidden]) {\n\t\tdisplay: none !important;\n\t}\n`]\n\n\t@property({ type: String }) id: string = 'default'\n\t@property({ type: String }) icon?: string\n\t@property({ type: String }) label?: string\n\t/** Override the expanded panel width (e.g. '320px', '24rem'). Defaults to responsive sizing. */\n\t@property({ type: String }) expandedWidth?: string\n\t/** When true, uses a lower elevation shadow in the minimized (FAB) state. */\n\t@property({ type: Boolean, reflect: true }) lowered: boolean = false\n\t/** Corner the boat is anchored to. */\n\t@property({ type: String }) corner: Corner = 'bottom-right'\n\t/** Whether the panel is open. */\n\t@property({ type: Boolean, reflect: true }) open: boolean = false\n\n\t/**\n\t * State property.\n\t * Maps 'expanded' → open=true, 'collapsed' → open=false (FAB visible).\n\t */\n\tget state(): BoatState {\n\t\treturn this.open ? 'expanded' : 'collapsed'\n\t}\n\tset state(val: BoatState) {\n\t\tif (val === 'expanded') {\n\t\t\tthis.expand()\n\t\t} else {\n\t\t\t// collapsed\n\t\t\tthis.close()\n\t\t}\n\t}\n\n\t// Internal drag state (triggers re-render for cursor class)\n\t@state() private isDragging = false\n\n\t// Internal position — plain fields, updated directly during drag (no re-render needed)\n\tprivate _position: Position = { x: 16, y: 16 }\n\t@state() private _currentCorner: Corner = 'bottom-right'\n\n\t// Refs\n\tprivate _containerRef = createRef<HTMLElement>()\n\tprivate _contentRef = createRef<HTMLElement>()\n\tprivate _headerRef = createRef<HTMLElement>()\n\tprivate _currentAnimation?: Animation\n\n\t// ============================================\n\t// COMPUTED\n\t// ============================================\n\n\tprivate get panelWidth(): string {\n\t\treturn this.expandedWidth ?? 'min(360px, calc(100vw - 32px))'\n\t}\n\n\tprivate get isBottomCorner(): boolean {\n\t\treturn this._currentCorner.startsWith('bottom')\n\t}\n\n\tprivate get closedClipPath(): string {\n\t\treturn this.isBottomCorner\n\t\t\t? `inset(calc(100% - ${FAB_HEIGHT}px) 0px 0px 0px round 22px)`\n\t\t\t: `inset(0px 0px calc(100% - ${FAB_HEIGHT}px) 0px round 22px)`\n\t}\n\n\tprivate get openClipPath(): string {\n\t\treturn 'inset(0px 0px 0px 0px round 12px)'\n\t}\n\n\tprivate get elevation(): 0 | 1 | 2 | 3 | 4 | 5 {\n\t\tif (this.open) return 4\n\t\treturn this.lowered ? 1 : 3\n\t}\n\n\t// ============================================\n\t// POSITION MANAGEMENT\n\t// ============================================\n\n\tprivate _applyContainerPosition() {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\t\tcontainer.style.removeProperty('left')\n\t\tcontainer.style.removeProperty('right')\n\t\tcontainer.style.removeProperty('top')\n\t\tcontainer.style.removeProperty('bottom')\n\t\tconst { x, y } = this._position\n\t\tif (this._currentCorner.includes('right')) {\n\t\t\tcontainer.style.right = `${x}px`\n\t\t} else {\n\t\t\tcontainer.style.left = `${x}px`\n\t\t}\n\t\tif (this._currentCorner.includes('bottom')) {\n\t\t\tcontainer.style.bottom = `${y + theme.bottomOffset}px`\n\t\t} else {\n\t\t\tcontainer.style.top = `${y}px`\n\t\t}\n\t}\n\n\tprivate _loadPosition() {\n\t\ttry {\n\t\t\tconst saved = localStorage.getItem(POSITION_STORAGE_KEY_PREFIX + this.id)\n\t\t\tif (saved) {\n\t\t\t\tconst parsed = JSON.parse(saved) as { x: number; y: number; anchor: Corner }\n\t\t\t\tthis._position = { x: parsed.x, y: parsed.y }\n\t\t\t\tthis._currentCorner = parsed.anchor\n\t\t\t}\n\t\t} catch {\n\t\t\t// ignore localStorage errors\n\t\t}\n\t}\n\n\tprivate _savePosition() {\n\t\ttry {\n\t\t\tlocalStorage.setItem(\n\t\t\t\tPOSITION_STORAGE_KEY_PREFIX + this.id,\n\t\t\t\tJSON.stringify({ ...this._position, anchor: this._currentCorner }),\n\t\t\t)\n\t\t} catch {\n\t\t\t// ignore localStorage errors\n\t\t}\n\t}\n\n\tprivate _validateBounds() {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\t\tconst rect = container.getBoundingClientRect()\n\t\tif (rect.width === 0) return\n\t\tconst vw = window.innerWidth\n\t\tconst vh = window.innerHeight\n\t\tconst isRight = this._currentCorner.includes('right')\n\t\tconst isBottom = this._currentCorner.includes('bottom')\n\t\tconst actualLeft = isRight ? vw - this._position.x - rect.width : this._position.x\n\t\tconst actualTop = isBottom ? vh - this._position.y - rect.height : this._position.y\n\t\tconst newLeft = Math.max(0, Math.min(actualLeft, vw - rect.width))\n\t\tconst newTop = Math.max(0, Math.min(actualTop, vh - rect.height))\n\t\tthis._position = {\n\t\t\tx: isRight ? vw - newLeft - rect.width : newLeft,\n\t\t\ty: isBottom ? vh - newTop - rect.height : newTop,\n\t\t}\n\t\tthis._applyContainerPosition()\n\t}\n\n\n\t// ============================================\n\t// CORNER SNAPPING\n\t// ============================================\n\n\tprivate _reorientToNearestCorner(skipAnimation = false): void {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\n\t\t// F — record current screen position before DOM mutation\n\t\tconst rect = container.getBoundingClientRect()\n\n\t\t// L — calculate nearest corner using FAB visual center (container is always collapsed during drag)\n\t\tconst currentIsBottom = this._currentCorner.includes('bottom')\n\t\tconst fabCenterX = rect.left + rect.width / 2\n\t\tconst fabCenterY = currentIsBottom\n\t\t\t? rect.bottom - FAB_HEIGHT / 2\n\t\t\t: rect.top + FAB_HEIGHT / 2\n\t\tconst side = fabCenterX > window.innerWidth / 2 ? 'right' : 'left'\n\t\tconst vert = fabCenterY > window.innerHeight / 2 ? 'bottom' : 'top'\n\t\tconst newCorner: Corner = `${vert}-${side}` as Corner\n\n\t\t// Snap corner and reset offset to standard edge gap\n\t\tthis._currentCorner = newCorner\n\t\tthis._position = { x: 16, y: 16 }\n\t\tthis._applyContainerPosition()\n\t\t// Sync clip-path to new corner — managed imperatively, not via styleMap\n\t\tif (!this.open) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t}\n\n\t\tif (skipAnimation || reducedMotion$.value) {\n\t\t\tthis._savePosition()\n\t\t\treturn\n\t\t}\n\n\t\t// I — invert: shift element back to its original visual position\n\t\tconst newRect = container.getBoundingClientRect()\n\t\tconst dx = rect.left - newRect.left\n\t\tconst dy = rect.top - newRect.top\n\t\tcontainer.style.transform = `translate(${dx}px, ${dy}px)`\n\n\t\t// P — play: animate from the inverse offset to natural resting position\n\t\tthis._currentAnimation?.cancel()\n\t\tconst anim = container.animate(\n\t\t\t[{ transform: container.style.transform }, { transform: 'translate(0,0)' }],\n\t\t\t{\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\t\tthis._currentAnimation = anim\n\t\tanim.finished.then(() => {\n\t\t\tif (container.isConnected) {\n\t\t\t\tcontainer.style.transform = ''\n\t\t\t}\n\t\t\treturn\n\t\t})\n\n\t\tthis._savePosition()\n\t}\n\n\t// ============================================\n\t// DRAG PIPELINE\n\t// ============================================\n\n\tprivate _setupDrag() {\n\t\tconst header = this._headerRef.value\n\t\tconst container = this._containerRef.value\n\t\tif (!header || !container) return\n\n\t\tlet didDrag = false\n\n\t\tfromEvent<PointerEvent>(header, 'pointerdown')\n\t\t\t.pipe(\n\t\t\t\tfilter(e => e.button === 0),\n\t\t\t\ttap(e => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t\theader.setPointerCapture(e.pointerId)\n\t\t\t\t}),\n\t\t\t\tmap(e => {\n\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\tconst isBottom = this._currentCorner.includes('bottom')\n\t\t\t\t\tconst wasOpen = this.open\n\t\t\t\t\tdidDrag = false\n\t\t\t\t\treturn {\n\t\t\t\t\t\tpointerId: e.pointerId,\n\t\t\t\t\t\tstartX: e.clientX,\n\t\t\t\t\t\tstartY: e.clientY,\n\t\t\t\t\t\toffsetX: e.clientX - rect.left,\n\t\t\t\t\t\toffsetY: e.clientY - rect.top,\n\t\t\t\t\t\trect,\n\t\t\t\t\t\tisBottom,\n\t\t\t\t\t\twasOpen,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\tswitchMap(({ pointerId, startX, startY, offsetX, offsetY, rect, isBottom, wasOpen }) => {\n\t\t\t\t\tconst sameId = (e: PointerEvent) => e.pointerId === pointerId\n\t\t\t\t\tconst move$ = fromEvent<PointerEvent>(window, 'pointermove').pipe(filter(sameId))\n\t\t\t\t\tconst end$ = merge(\n\t\t\t\t\t\tfromEvent<PointerEvent>(window, 'pointerup'),\n\t\t\t\t\t\tfromEvent<PointerEvent>(window, 'pointercancel'),\n\t\t\t\t\t).pipe(filter(sameId))\n\n\t\t\t\t\treturn move$.pipe(\n\t\t\t\t\t\ttap(({ clientX, clientY }) => {\n\t\t\t\t\t\t\tconst dx = clientX - startX\n\t\t\t\t\t\t\tconst dy = clientY - startY\n\t\t\t\t\t\t\tif (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD && !didDrag) {\n\t\t\t\t\t\t\t\tdidDrag = true\n\t\t\t\t\t\t\t\tthis.isDragging = true\n\t\t\t\t\t\t\t\t// Collapse on first confirmed drag move (not on click)\n\t\t\t\t\t\t\t\tif (wasOpen) {\n\t\t\t\t\t\t\t\t\tthis._currentAnimation?.cancel()\n\t\t\t\t\t\t\t\t\tthis.open = false\n\t\t\t\t\t\t\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\t\t\t\t\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\t\t\t\t\t\t\tconst content = this._contentRef.value\n\t\t\t\t\t\t\t\t\tif (content) {\n\t\t\t\t\t\t\t\t\t\tcontent.inert = true\n\t\t\t\t\t\t\t\t\t\tcontent.style.visibility = 'hidden'\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!didDrag) return\n\n\t\t\t\t\t\t\tconst vw = window.innerWidth\n\t\t\t\t\t\t\tconst vh = window.innerHeight\n\t\t\t\t\t\t\tconst left = Math.max(0, Math.min(clientX - offsetX, vw - rect.width))\n\t\t\t\t\t\t\t// Allow container to go partially off-screen so FAB stays reachable at all edges\n\t\t\t\t\t\t\tconst minTop = isBottom ? FAB_HEIGHT - rect.height : 0\n\t\t\t\t\t\t\tconst maxTop = isBottom ? vh - rect.height : vh - FAB_HEIGHT\n\t\t\t\t\t\t\tconst top = Math.max(minTop, Math.min(clientY - offsetY, maxTop))\n\n\t\t\t\t\t\t\tthis._position = {\n\t\t\t\t\t\t\t\tx: this._currentCorner.includes('right') ? vw - left - rect.width : left,\n\t\t\t\t\t\t\t\ty: isBottom ? vh - top - rect.height : top,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis._applyContainerPosition()\n\t\t\t\t\t\t}),\n\t\t\t\t\t\ttakeUntil(end$),\n\t\t\t\t\t\tfinalize(() => {\n\t\t\t\t\t\t\tif (didDrag) {\n\t\t\t\t\t\t\t\tthis._reorientToNearestCorner()\n\t\t\t\t\t\t\t\tthis.isDragging = false\n\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.isDragging = false\n\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t\tthis.toggle()\n\t\t\t\t\t\t\t}\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\t// ============================================\n\t// LIFECYCLE\n\t// ============================================\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\tfromEvent(window, 'resize')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(() => this._validateBounds())\n\n\t\ttheme.bottomOffset$.pipe(\n\t\t\ttap(() => this._applyContainerPosition()),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\t}\n\n\tfirstUpdated() {\n\t\t// Initialize corner from property\n\t\tthis._currentCorner = this.corner\n\n\t\t// Load saved drag position from localStorage\n\t\tthis._loadPosition()\n\n\t\tconst container = this._containerRef.value\n\t\tconst content = this._contentRef.value\n\t\tif (!container) return\n\n\t\t// Apply initial position\n\t\tthis._applyContainerPosition()\n\n\t\t// Set initial open/closed visual state\n\t\tif (this.open) {\n\t\t\tcontainer.style.overflow = ''\n\t\t\tif (content) {\n\t\t\t\tcontent.inert = false\n\t\t\t\tcontent.style.visibility = 'visible'\n\t\t\t}\n\t\t} else {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tif (content) {\n\t\t\t\tcontent.inert = true\n\t\t\t\tcontent.style.visibility = 'hidden'\n\t\t\t}\n\t\t}\n\n\t\t// Set up drag\n\t\tthis._setupDrag()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis._currentAnimation?.cancel()\n\t}\n\n\t// ============================================\n\t// ANIMATION\n\t// ============================================\n\n\tprivate async _animateOpen(): Promise<void> {\n\t\tconst container = this._containerRef.value\n\t\tconst content = this._contentRef.value\n\t\tif (!container) return\n\n\t\tif (content) {\n\t\t\tcontent.style.visibility = 'visible'\n\t\t\tcontent.inert = false\n\t\t}\n\n\t\tthis.open = true\n\t\tawait this.updateComplete\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = ''\n\t\t\tcontainer.style.overflow = ''\n\t\t\tthis.dispatchScopedEvent('toggle', 'expanded')\n\t\t\treturn\n\t\t}\n\n\t\tthis._currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\n\t\tconst openKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t]\n\t\tconst anim = container.animate(openKeyframes, {\n\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis._currentAnimation = anim\n\n\t\t// Clear clip-path so overflow/scroll work normally after animation\n\t\tanim.finished.then(() => {\n\t\t\tif (container.isConnected) {\n\t\t\t\tcontainer.style.clipPath = ''\n\t\t\t\tcontainer.style.overflow = ''\n\t\t\t}\n\t\t\treturn\n\t\t})\n\n\t\tthis.dispatchScopedEvent('toggle', 'expanded')\n\t}\n\n\tprivate async _animateClose(): Promise<void> {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tthis.open = false\n\t\t\tconst content = this._contentRef.value\n\t\t\tif (content) {\n\t\t\t\tcontent.inert = true\n\t\t\t\tcontent.style.visibility = 'hidden'\n\t\t\t}\n\t\t\tthis.dispatchScopedEvent('toggle', 'collapsed')\n\t\t\treturn\n\t\t}\n\n\t\tthis._currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\n\t\tconst closeKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t]\n\t\tconst anim = container.animate(closeKeyframes, {\n\t\t\tduration: Math.round(SPRING_SNAPPY.duration * 0.9),\n\t\t\teasing: 'cubic-bezier(0.4, 0, 0.8, 0.15)',\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis._currentAnimation = anim\n\n\t\tawait anim.finished\n\n\t\tthis.open = false\n\n\t\tconst content = this._contentRef.value\n\t\tif (content) {\n\t\t\tcontent.inert = true\n\t\t\tcontent.style.visibility = 'hidden'\n\t\t}\n\n\t\tthis.dispatchScopedEvent('toggle', 'collapsed')\n\t}\n\n\t// ============================================\n\t// PUBLIC API\n\t// ============================================\n\n\ttoggle() {\n\t\tif (this.open) this._animateClose()\n\t\telse this._animateOpen()\n\t}\n\n\texpand() {\n\t\tif (this.open) return\n\t\tthis.removeAttribute('hidden')\n\t\tif (!this._containerRef.value) {\n\t\t\tthis.open = true\n\t\t\treturn\n\t\t}\n\t\tthis._animateOpen()\n\t}\n\n\t/** Alias for expand() — kept for backwards compatibility. */\n\tshow() {\n\t\tthis.expand()\n\t}\n\n\tclose() {\n\t\tif (!this.open) return\n\t\tif (!this._containerRef.value) {\n\t\t\tthis.open = false\n\t\t\treturn\n\t\t}\n\t\tthis._animateClose()\n\t}\n\n\t// ============================================\n\t// RENDER\n\t// ============================================\n\n\tprotected render(): unknown {\n\t\tconst isBottom = this._currentCorner.startsWith('bottom')\n\n\t\tconst containerClasses = classMap({\n\t\t\tflex: true,\n\t\t\t'flex-col': isBottom,\n\t\t\t'flex-col-reverse': !isBottom,\n\t\t\t'will-change-[clip-path]': true,\n\t\t\t'z-1000': true,\n\t\t\t'rounded-2xl': this.open,\n\t\t\t'rounded-[22px]': !this.open,\n\t\t\t'overflow-hidden': true,\n\t\t\t'opacity-95': this.isDragging,\n\t\t})\n\n\t\tconst containerStyles = styleMap({\n\t\t\tposition: 'fixed',\n\t\t\twidth: this.panelWidth,\n\t\t\t'max-height': 'calc(100vh - 32px)',\n\t\t\t'pointer-events': 'none',\n\t\t})\n\n\t\tconst contentStyles = styleMap({\n\t\t\t'pointer-events': this.open ? 'auto' : 'none',\n\t\t})\n\n\t\tconst headerClasses = classMap({\n\t\t\t'h-full': true,\n\t\t\t'px-3': true,\n\t\t\tflex: true,\n\t\t\t'items-center': true,\n\t\t\t'gap-2': true,\n\t\t\t'select-none': true,\n\t\t\t'touch-none': true,\n\t\t\t'cursor-grabbing': this.isDragging,\n\t\t\t'cursor-move': !this.isDragging,\n\t\t\t'transition-opacity': true,\n\t\t\t'duration-200': true,\n\t\t})\n\n\t\treturn html`\n\t\t\t<!-- schmancy-surface owns background color and elevation-based shadow.\n\t\t\t Position is managed imperatively via _applyContainerPosition(). -->\n\t\t\t<schmancy-surface\n\t\t\t\t${ref(this._containerRef)}\n\t\t\t\ttype=\"glass\"\n\t\t\t\t.elevation=${this.elevation}\n\t\t\t\tclass=${containerClasses}\n\t\t\t\tstyle=${containerStyles}\n\t\t\t\taria-expanded=${this.open}\n\t\t\t>\n\t\t\t\t<!-- Content section (visually above header for bottom corners) -->\n\t\t\t\t<section\n\t\t\t\t\t${ref(this._contentRef)}\n\t\t\t\t\tclass=\"flex-1 min-h-0 overflow-hidden flex flex-col\"\n\t\t\t\t\tstyle=${contentStyles}\n\t\t\t\t\trole=\"dialog\"\n\t\t\t\t\taria-label=\"${this.label ?? 'Floating panel'}\"\n\t\t\t\t>\n\t\t\t\t\t<schmancy-surface type=\"solid\" class=\"flex flex-col flex-1 min-h-0 overflow-hidden\">\n\t\t\t\t\t\t<schmancy-scroll hide class=\"flex-1\">\n\t\t\t\t\t\t\t<slot></slot>\n\t\t\t\t\t\t</schmancy-scroll>\n\t\t\t\t\t</schmancy-surface>\n\t\t\t\t</section>\n\n\t\t\t\t<!-- Gradient separator between header and content — only when open -->\n\t\t\t\t${when(\n\t\t\t\t\tthis.open,\n\t\t\t\t\t() =>\n\t\t\t\t\t\thtml`<div\n\t\t\t\t\t\t\tclass=\"h-px shrink-0 bg-linear-to-r from-transparent via-primary-default/30 to-transparent\"\n\t\t\t\t\t\t></div>`,\n\t\t\t\t)}\n\n\t\t\t\t<!-- Header / FAB section — always interactive, always visible -->\n\t\t\t\t<section\n\t\t\t\t\tclass=\"shrink-0 bg-surface-containerLowest\"\n\t\t\t\t\tstyle=${styleMap({ 'pointer-events': 'auto', height: `${FAB_HEIGHT}px` })}\n\t\t\t\t>\n\t\t\t\t\t<div\n\t\t\t\t\t\t${ref(this._headerRef)}\n\t\t\t\t\t\tclass=${headerClasses}\n\t\t\t\t\t\ttitle=\"Drag to move\"\n\t\t\t\t\t\taria-label=\"Drag to reposition panel\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<!-- Summary slot rendered once — avoids DOM teardown on toggle -->\n\t\t\t\t\t\t<div class=\"flex-1 min-w-0\">\n\t\t\t\t\t\t\t<slot name=\"summary\"></slot>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<!-- Toggle button: collapse when open, expand when closed -->\n\t\t\t\t\t\t${when(\n\t\t\t\t\t\t\tthis.open,\n\t\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tvariant=\"text\"\n\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\tthis.close()\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\ttitle=\"Collapse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tclose_fullscreen\n\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t`,\n\t\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tvariant=\"text\"\n\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\tthis.expand()\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\ttitle=\"Expand\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tfullscreen\n\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t`,\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-boat': SchmancyBoat\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"boat-BF5P6p_f.js","names":[],"sources":["../src/boat/boat.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { when } from 'lit/directives/when.js'\nimport { filter, finalize, fromEvent, map, merge, switchMap, takeUntil, tap } from 'rxjs'\nimport { SPRING_SMOOTH, SPRING_SNAPPY } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport { theme } from '../theme/theme.service.js'\n\nconst FAB_HEIGHT = 44\nconst DRAG_THRESHOLD = 5\nconst POSITION_STORAGE_KEY_PREFIX = 'schmancy-boat-'\n\ntype Corner = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'\ntype BoatState = 'collapsed' | 'expanded'\ninterface Position {\n\tx: number\n\ty: number\n}\n\n@customElement('schmancy-boat')\nexport default class SchmancyBoat extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: contents;\n\t\tposition: relative;\n\t\tz-index: 1000;\n\t}\n\t:host([hidden]) {\n\t\tdisplay: none !important;\n\t}\n`]\n\n\t@property({ type: String }) id: string = 'default'\n\t@property({ type: String }) icon?: string\n\t@property({ type: String }) label?: string\n\t/** Override the expanded panel width (e.g. '320px', '24rem'). Defaults to responsive sizing. */\n\t@property({ type: String }) expandedWidth?: string\n\t/** When true, uses a lower elevation shadow in the minimized (FAB) state. */\n\t@property({ type: Boolean, reflect: true }) lowered: boolean = false\n\t/** Corner the boat is anchored to. */\n\t@property({ type: String }) corner: Corner = 'bottom-right'\n\t/** Whether the panel is open. */\n\t@property({ type: Boolean, reflect: true }) open: boolean = false\n\n\t/**\n\t * State property.\n\t * Maps 'expanded' → open=true, 'collapsed' → open=false (FAB visible).\n\t */\n\tget state(): BoatState {\n\t\treturn this.open ? 'expanded' : 'collapsed'\n\t}\n\tset state(val: BoatState) {\n\t\tif (val === 'expanded') {\n\t\t\tthis.expand()\n\t\t} else {\n\t\t\t// collapsed\n\t\t\tthis.close()\n\t\t}\n\t}\n\n\t// Internal drag state (triggers re-render for cursor class)\n\t@state() private isDragging = false\n\n\t// Internal position — plain fields, updated directly during drag (no re-render needed)\n\tprivate _position: Position = { x: 16, y: 16 }\n\t@state() private _currentCorner: Corner = 'bottom-right'\n\n\t// Refs\n\tprivate _containerRef = createRef<HTMLElement>()\n\tprivate _contentRef = createRef<HTMLElement>()\n\tprivate _headerRef = createRef<HTMLElement>()\n\tprivate _currentAnimation?: Animation\n\n\t// ============================================\n\t// COMPUTED\n\t// ============================================\n\n\tprivate get panelWidth(): string {\n\t\treturn this.expandedWidth ?? 'min(360px, calc(100vw - 32px))'\n\t}\n\n\tprivate get isBottomCorner(): boolean {\n\t\treturn this._currentCorner.startsWith('bottom')\n\t}\n\n\tprivate get closedClipPath(): string {\n\t\treturn this.isBottomCorner\n\t\t\t? `inset(calc(100% - ${FAB_HEIGHT}px) 0px 0px 0px round 22px)`\n\t\t\t: `inset(0px 0px calc(100% - ${FAB_HEIGHT}px) 0px round 22px)`\n\t}\n\n\tprivate get openClipPath(): string {\n\t\treturn 'inset(0px 0px 0px 0px round 12px)'\n\t}\n\n\tprivate get elevation(): 0 | 1 | 2 | 3 | 4 | 5 {\n\t\tif (this.open) return 4\n\t\treturn this.lowered ? 1 : 3\n\t}\n\n\t// ============================================\n\t// POSITION MANAGEMENT\n\t// ============================================\n\n\tprivate _applyContainerPosition() {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\t\tcontainer.style.removeProperty('left')\n\t\tcontainer.style.removeProperty('right')\n\t\tcontainer.style.removeProperty('top')\n\t\tcontainer.style.removeProperty('bottom')\n\t\tconst { x, y } = this._position\n\t\tif (this._currentCorner.includes('right')) {\n\t\t\tcontainer.style.right = `${x}px`\n\t\t} else {\n\t\t\tcontainer.style.left = `${x}px`\n\t\t}\n\t\tif (this._currentCorner.includes('bottom')) {\n\t\t\tcontainer.style.bottom = `${y + theme.bottomOffset}px`\n\t\t} else {\n\t\t\tcontainer.style.top = `${y}px`\n\t\t}\n\t}\n\n\tprivate _loadPosition() {\n\t\ttry {\n\t\t\tconst saved = localStorage.getItem(POSITION_STORAGE_KEY_PREFIX + this.id)\n\t\t\tif (saved) {\n\t\t\t\tconst parsed = JSON.parse(saved) as { x: number; y: number; anchor: Corner }\n\t\t\t\tthis._position = { x: parsed.x, y: parsed.y }\n\t\t\t\tthis._currentCorner = parsed.anchor\n\t\t\t}\n\t\t} catch {\n\t\t\t// ignore localStorage errors\n\t\t}\n\t}\n\n\tprivate _savePosition() {\n\t\ttry {\n\t\t\tlocalStorage.setItem(\n\t\t\t\tPOSITION_STORAGE_KEY_PREFIX + this.id,\n\t\t\t\tJSON.stringify({ ...this._position, anchor: this._currentCorner }),\n\t\t\t)\n\t\t} catch {\n\t\t\t// ignore localStorage errors\n\t\t}\n\t}\n\n\tprivate _validateBounds() {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\t\tconst rect = container.getBoundingClientRect()\n\t\tif (rect.width === 0) return\n\t\tconst vw = window.innerWidth\n\t\tconst vh = window.innerHeight\n\t\tconst isRight = this._currentCorner.includes('right')\n\t\tconst isBottom = this._currentCorner.includes('bottom')\n\t\tconst actualLeft = isRight ? vw - this._position.x - rect.width : this._position.x\n\t\tconst actualTop = isBottom ? vh - this._position.y - rect.height : this._position.y\n\t\tconst newLeft = Math.max(0, Math.min(actualLeft, vw - rect.width))\n\t\tconst newTop = Math.max(0, Math.min(actualTop, vh - rect.height))\n\t\tthis._position = {\n\t\t\tx: isRight ? vw - newLeft - rect.width : newLeft,\n\t\t\ty: isBottom ? vh - newTop - rect.height : newTop,\n\t\t}\n\t\tthis._applyContainerPosition()\n\t}\n\n\n\t// ============================================\n\t// CORNER SNAPPING\n\t// ============================================\n\n\tprivate _reorientToNearestCorner(skipAnimation = false): void {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\n\t\t// F — record current screen position before DOM mutation\n\t\tconst rect = container.getBoundingClientRect()\n\n\t\t// L — calculate nearest corner using FAB visual center (container is always collapsed during drag)\n\t\tconst currentIsBottom = this._currentCorner.includes('bottom')\n\t\tconst fabCenterX = rect.left + rect.width / 2\n\t\tconst fabCenterY = currentIsBottom\n\t\t\t? rect.bottom - FAB_HEIGHT / 2\n\t\t\t: rect.top + FAB_HEIGHT / 2\n\t\tconst side = fabCenterX > window.innerWidth / 2 ? 'right' : 'left'\n\t\tconst vert = fabCenterY > window.innerHeight / 2 ? 'bottom' : 'top'\n\t\tconst newCorner: Corner = `${vert}-${side}` as Corner\n\n\t\t// Snap corner and reset offset to standard edge gap\n\t\tthis._currentCorner = newCorner\n\t\tthis._position = { x: 16, y: 16 }\n\t\tthis._applyContainerPosition()\n\t\t// Sync clip-path to new corner — managed imperatively, not via styleMap\n\t\tif (!this.open) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t}\n\n\t\tif (skipAnimation || reducedMotion$.value) {\n\t\t\tthis._savePosition()\n\t\t\treturn\n\t\t}\n\n\t\t// I — invert: shift element back to its original visual position\n\t\tconst newRect = container.getBoundingClientRect()\n\t\tconst dx = rect.left - newRect.left\n\t\tconst dy = rect.top - newRect.top\n\t\tcontainer.style.transform = `translate(${dx}px, ${dy}px)`\n\n\t\t// P — play: animate from the inverse offset to natural resting position\n\t\tthis._currentAnimation?.cancel()\n\t\tconst anim = container.animate(\n\t\t\t[{ transform: container.style.transform }, { transform: 'translate(0,0)' }],\n\t\t\t{\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\t\tthis._currentAnimation = anim\n\t\tanim.finished.then(() => {\n\t\t\tif (container.isConnected) {\n\t\t\t\tcontainer.style.transform = ''\n\t\t\t}\n\t\t\treturn\n\t\t})\n\n\t\tthis._savePosition()\n\t}\n\n\t// ============================================\n\t// DRAG PIPELINE\n\t// ============================================\n\n\tprivate _setupDrag() {\n\t\tconst header = this._headerRef.value\n\t\tconst container = this._containerRef.value\n\t\tif (!header || !container) return\n\n\t\tlet didDrag = false\n\n\t\tfromEvent<PointerEvent>(header, 'pointerdown')\n\t\t\t.pipe(\n\t\t\t\tfilter(e => e.button === 0),\n\t\t\t\ttap(e => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t\theader.setPointerCapture(e.pointerId)\n\t\t\t\t}),\n\t\t\t\tmap(e => {\n\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\tconst isBottom = this._currentCorner.includes('bottom')\n\t\t\t\t\tconst wasOpen = this.open\n\t\t\t\t\tdidDrag = false\n\t\t\t\t\treturn {\n\t\t\t\t\t\tpointerId: e.pointerId,\n\t\t\t\t\t\tstartX: e.clientX,\n\t\t\t\t\t\tstartY: e.clientY,\n\t\t\t\t\t\toffsetX: e.clientX - rect.left,\n\t\t\t\t\t\toffsetY: e.clientY - rect.top,\n\t\t\t\t\t\trect,\n\t\t\t\t\t\tisBottom,\n\t\t\t\t\t\twasOpen,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\tswitchMap(({ pointerId, startX, startY, offsetX, offsetY, rect, isBottom, wasOpen }) => {\n\t\t\t\t\tconst sameId = (e: PointerEvent) => e.pointerId === pointerId\n\t\t\t\t\tconst move$ = fromEvent<PointerEvent>(window, 'pointermove').pipe(filter(sameId))\n\t\t\t\t\tconst end$ = merge(\n\t\t\t\t\t\tfromEvent<PointerEvent>(window, 'pointerup'),\n\t\t\t\t\t\tfromEvent<PointerEvent>(window, 'pointercancel'),\n\t\t\t\t\t).pipe(filter(sameId))\n\n\t\t\t\t\treturn move$.pipe(\n\t\t\t\t\t\ttap(({ clientX, clientY }) => {\n\t\t\t\t\t\t\tconst dx = clientX - startX\n\t\t\t\t\t\t\tconst dy = clientY - startY\n\t\t\t\t\t\t\tif (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD && !didDrag) {\n\t\t\t\t\t\t\t\tdidDrag = true\n\t\t\t\t\t\t\t\tthis.isDragging = true\n\t\t\t\t\t\t\t\t// Collapse on first confirmed drag move (not on click)\n\t\t\t\t\t\t\t\tif (wasOpen) {\n\t\t\t\t\t\t\t\t\tthis._currentAnimation?.cancel()\n\t\t\t\t\t\t\t\t\tthis.open = false\n\t\t\t\t\t\t\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\t\t\t\t\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\t\t\t\t\t\t\tconst content = this._contentRef.value\n\t\t\t\t\t\t\t\t\tif (content) {\n\t\t\t\t\t\t\t\t\t\tcontent.inert = true\n\t\t\t\t\t\t\t\t\t\tcontent.style.visibility = 'hidden'\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!didDrag) return\n\n\t\t\t\t\t\t\tconst vw = window.innerWidth\n\t\t\t\t\t\t\tconst vh = window.innerHeight\n\t\t\t\t\t\t\tconst left = Math.max(0, Math.min(clientX - offsetX, vw - rect.width))\n\t\t\t\t\t\t\t// Allow container to go partially off-screen so FAB stays reachable at all edges\n\t\t\t\t\t\t\tconst minTop = isBottom ? FAB_HEIGHT - rect.height : 0\n\t\t\t\t\t\t\tconst maxTop = isBottom ? vh - rect.height : vh - FAB_HEIGHT\n\t\t\t\t\t\t\tconst top = Math.max(minTop, Math.min(clientY - offsetY, maxTop))\n\n\t\t\t\t\t\t\tthis._position = {\n\t\t\t\t\t\t\t\tx: this._currentCorner.includes('right') ? vw - left - rect.width : left,\n\t\t\t\t\t\t\t\ty: isBottom ? vh - top - rect.height : top,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis._applyContainerPosition()\n\t\t\t\t\t\t}),\n\t\t\t\t\t\ttakeUntil(end$),\n\t\t\t\t\t\tfinalize(() => {\n\t\t\t\t\t\t\tif (didDrag) {\n\t\t\t\t\t\t\t\tthis._reorientToNearestCorner()\n\t\t\t\t\t\t\t\tthis.isDragging = false\n\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.isDragging = false\n\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t\tthis.toggle()\n\t\t\t\t\t\t\t}\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\t// ============================================\n\t// LIFECYCLE\n\t// ============================================\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\tfromEvent(window, 'resize')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(() => this._validateBounds())\n\n\t\ttheme.bottomOffset$.pipe(\n\t\t\ttap(() => this._applyContainerPosition()),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\t}\n\n\tfirstUpdated() {\n\t\t// Initialize corner from property\n\t\tthis._currentCorner = this.corner\n\n\t\t// Load saved drag position from localStorage\n\t\tthis._loadPosition()\n\n\t\tconst container = this._containerRef.value\n\t\tconst content = this._contentRef.value\n\t\tif (!container) return\n\n\t\t// Apply initial position\n\t\tthis._applyContainerPosition()\n\n\t\t// Set initial open/closed visual state\n\t\tif (this.open) {\n\t\t\tcontainer.style.overflow = ''\n\t\t\tif (content) {\n\t\t\t\tcontent.inert = false\n\t\t\t\tcontent.style.visibility = 'visible'\n\t\t\t}\n\t\t} else {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tif (content) {\n\t\t\t\tcontent.inert = true\n\t\t\t\tcontent.style.visibility = 'hidden'\n\t\t\t}\n\t\t}\n\n\t\t// Set up drag\n\t\tthis._setupDrag()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis._currentAnimation?.cancel()\n\t}\n\n\t// ============================================\n\t// ANIMATION\n\t// ============================================\n\n\tprivate async _animateOpen(): Promise<void> {\n\t\tconst container = this._containerRef.value\n\t\tconst content = this._contentRef.value\n\t\tif (!container) return\n\n\t\tif (content) {\n\t\t\tcontent.style.visibility = 'visible'\n\t\t\tcontent.inert = false\n\t\t}\n\n\t\tthis.open = true\n\t\tawait this.updateComplete\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = ''\n\t\t\tcontainer.style.overflow = ''\n\t\t\tthis.dispatchScopedEvent('toggle', 'expanded')\n\t\t\treturn\n\t\t}\n\n\t\tthis._currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\n\t\tconst openKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t]\n\t\tconst anim = container.animate(openKeyframes, {\n\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis._currentAnimation = anim\n\n\t\t// Clear clip-path so overflow/scroll work normally after animation\n\t\tanim.finished.then(() => {\n\t\t\tif (container.isConnected) {\n\t\t\t\tcontainer.style.clipPath = ''\n\t\t\t\tcontainer.style.overflow = ''\n\t\t\t}\n\t\t\treturn\n\t\t})\n\n\t\tthis.dispatchScopedEvent('toggle', 'expanded')\n\t}\n\n\tprivate async _animateClose(): Promise<void> {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tthis.open = false\n\t\t\tconst content = this._contentRef.value\n\t\t\tif (content) {\n\t\t\t\tcontent.inert = true\n\t\t\t\tcontent.style.visibility = 'hidden'\n\t\t\t}\n\t\t\tthis.dispatchScopedEvent('toggle', 'collapsed')\n\t\t\treturn\n\t\t}\n\n\t\tthis._currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\n\t\tconst closeKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t]\n\t\tconst anim = container.animate(closeKeyframes, {\n\t\t\tduration: Math.round(SPRING_SNAPPY.duration * 0.9),\n\t\t\teasing: 'cubic-bezier(0.4, 0, 0.8, 0.15)',\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis._currentAnimation = anim\n\n\t\tawait anim.finished\n\n\t\tthis.open = false\n\n\t\tconst content = this._contentRef.value\n\t\tif (content) {\n\t\t\tcontent.inert = true\n\t\t\tcontent.style.visibility = 'hidden'\n\t\t}\n\n\t\tthis.dispatchScopedEvent('toggle', 'collapsed')\n\t}\n\n\t// ============================================\n\t// PUBLIC API\n\t// ============================================\n\n\ttoggle() {\n\t\tif (this.open) this._animateClose()\n\t\telse this._animateOpen()\n\t}\n\n\texpand() {\n\t\tif (this.open) return\n\t\tthis.removeAttribute('hidden')\n\t\tif (!this._containerRef.value) {\n\t\t\tthis.open = true\n\t\t\treturn\n\t\t}\n\t\tthis._animateOpen()\n\t}\n\n\t/** Alias for expand() — kept for backwards compatibility. */\n\tshow() {\n\t\tthis.expand()\n\t}\n\n\tclose() {\n\t\tif (!this.open) return\n\t\tif (!this._containerRef.value) {\n\t\t\tthis.open = false\n\t\t\treturn\n\t\t}\n\t\tthis._animateClose()\n\t}\n\n\t// ============================================\n\t// RENDER\n\t// ============================================\n\n\tprotected render(): unknown {\n\t\tconst isBottom = this._currentCorner.startsWith('bottom')\n\n\t\tconst containerClasses = classMap({\n\t\t\tflex: true,\n\t\t\t'flex-col': isBottom,\n\t\t\t'flex-col-reverse': !isBottom,\n\t\t\t'will-change-[clip-path]': true,\n\t\t\t'z-1000': true,\n\t\t\t'rounded-2xl': this.open,\n\t\t\t'rounded-[22px]': !this.open,\n\t\t\t'overflow-hidden': true,\n\t\t\t'opacity-95': this.isDragging,\n\t\t})\n\n\t\tconst containerStyles = styleMap({\n\t\t\tposition: 'fixed',\n\t\t\twidth: this.panelWidth,\n\t\t\t'max-height': 'calc(100vh - 32px)',\n\t\t\t'pointer-events': 'none',\n\t\t})\n\n\t\tconst contentStyles = styleMap({\n\t\t\t'pointer-events': this.open ? 'auto' : 'none',\n\t\t})\n\n\t\tconst headerClasses = classMap({\n\t\t\t'h-full': true,\n\t\t\t'px-3': true,\n\t\t\tflex: true,\n\t\t\t'items-center': true,\n\t\t\t'gap-2': true,\n\t\t\t'select-none': true,\n\t\t\t'touch-none': true,\n\t\t\t'cursor-grabbing': this.isDragging,\n\t\t\t'cursor-move': !this.isDragging,\n\t\t\t'transition-opacity': true,\n\t\t\t'duration-200': true,\n\t\t})\n\n\t\treturn html`\n\t\t\t<!-- schmancy-surface owns background color and elevation-based shadow.\n\t\t\t Position is managed imperatively via _applyContainerPosition(). -->\n\t\t\t<schmancy-surface\n\t\t\t\t${ref(this._containerRef)}\n\t\t\t\ttype=\"glass\"\n\t\t\t\t.elevation=${this.elevation}\n\t\t\t\tclass=${containerClasses}\n\t\t\t\tstyle=${containerStyles}\n\t\t\t\taria-expanded=${this.open}\n\t\t\t>\n\t\t\t\t<!-- Content section (visually above header for bottom corners) -->\n\t\t\t\t<section\n\t\t\t\t\t${ref(this._contentRef)}\n\t\t\t\t\tclass=\"flex-1 min-h-0 overflow-hidden flex flex-col\"\n\t\t\t\t\tstyle=${contentStyles}\n\t\t\t\t\trole=\"dialog\"\n\t\t\t\t\taria-label=\"${this.label ?? 'Floating panel'}\"\n\t\t\t\t>\n\t\t\t\t\t<schmancy-surface type=\"solid\" class=\"flex flex-col flex-1 min-h-0 overflow-hidden\">\n\t\t\t\t\t\t<schmancy-scroll hide class=\"flex-1\">\n\t\t\t\t\t\t\t<slot></slot>\n\t\t\t\t\t\t</schmancy-scroll>\n\t\t\t\t\t</schmancy-surface>\n\t\t\t\t</section>\n\n\t\t\t\t<!-- Gradient separator between header and content — only when open -->\n\t\t\t\t${when(\n\t\t\t\t\tthis.open,\n\t\t\t\t\t() =>\n\t\t\t\t\t\thtml`<div\n\t\t\t\t\t\t\tclass=\"h-px shrink-0 bg-linear-to-r from-transparent via-primary-default/30 to-transparent\"\n\t\t\t\t\t\t></div>`,\n\t\t\t\t)}\n\n\t\t\t\t<!-- Header / FAB section — always interactive, always visible -->\n\t\t\t\t<section\n\t\t\t\t\tclass=\"shrink-0 bg-surface-containerLowest\"\n\t\t\t\t\tstyle=${styleMap({ 'pointer-events': 'auto', height: `${FAB_HEIGHT}px` })}\n\t\t\t\t>\n\t\t\t\t\t<div\n\t\t\t\t\t\t${ref(this._headerRef)}\n\t\t\t\t\t\tclass=${headerClasses}\n\t\t\t\t\t\ttitle=\"Drag to move\"\n\t\t\t\t\t\taria-label=\"Drag to reposition panel\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<!-- Summary slot rendered once — avoids DOM teardown on toggle -->\n\t\t\t\t\t\t<div class=\"flex-1 min-w-0\">\n\t\t\t\t\t\t\t<slot name=\"summary\"></slot>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<!-- Toggle button: collapse when open, expand when closed -->\n\t\t\t\t\t\t${when(\n\t\t\t\t\t\t\tthis.open,\n\t\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tvariant=\"text\"\n\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\tthis.close()\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\ttitle=\"Collapse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tclose_fullscreen\n\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t`,\n\t\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tvariant=\"text\"\n\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\tthis.expand()\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\ttitle=\"Expand\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tfullscreen\n\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t`,\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-boat': SchmancyBoat\n\t}\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-Du9HMrIG.cjs`),t=require(`./active-host-jH3iloCR.cjs`),n=require(`./animation-CCOIW4wJ.cjs`),r=require(`./reduced-motion-Dzfp_w5x.cjs`),i=require(`./theme.service-CnFUmUpc.cjs`);let a=require(`rxjs`),o=require(`lit/directives/class-map.js`),s=require(`lit/directives/style-map.js`),c=require(`lit/decorators.js`),l=require(`lit`),u=require(`lit/directives/ref.js`),d=require(`lit/directives/when.js`);var f=44,p=`schmancy-boat-`,m=class extends e.c{constructor(...e){super(...e),this.id=`default`,this.lowered=!1,this.corner=`bottom-right`,this.open=!1,this.isDragging=!1,this._position={x:16,y:16},this._currentCorner=`bottom-right`,this._containerRef=(0,u.createRef)(),this._contentRef=(0,u.createRef)(),this._headerRef=(0,u.createRef)()}static{this.styles=[l.css`
1
+ require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-DTCHPEd4.cjs`),t=require(`./active-host-jH3iloCR.cjs`),n=require(`./animation-CCOIW4wJ.cjs`),r=require(`./reduced-motion-Dzfp_w5x.cjs`),i=require(`./theme.service-CnFUmUpc.cjs`);let a=require(`rxjs`),o=require(`lit/directives/class-map.js`),s=require(`lit/directives/style-map.js`),c=require(`lit/decorators.js`),l=require(`lit`),u=require(`lit/directives/ref.js`),d=require(`lit/directives/when.js`);var f=44,p=`schmancy-boat-`,m=class extends e.c{constructor(...e){super(...e),this.id=`default`,this.lowered=!1,this.corner=`bottom-right`,this.open=!1,this.isDragging=!1,this._position={x:16,y:16},this._currentCorner=`bottom-right`,this._containerRef=(0,u.createRef)(),this._contentRef=(0,u.createRef)(),this._headerRef=(0,u.createRef)()}static{this.styles=[l.css`
2
2
  :host {
3
3
  display: contents;
4
4
  position: relative;
@@ -1 +1 @@
1
- {"version":3,"file":"boat-OatK_MGh.cjs","names":[],"sources":["../src/boat/boat.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { when } from 'lit/directives/when.js'\nimport { filter, finalize, fromEvent, map, merge, switchMap, takeUntil, tap } from 'rxjs'\nimport { SPRING_SMOOTH, SPRING_SNAPPY } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport { theme } from '../theme/theme.service.js'\n\nconst FAB_HEIGHT = 44\nconst DRAG_THRESHOLD = 5\nconst POSITION_STORAGE_KEY_PREFIX = 'schmancy-boat-'\n\ntype Corner = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'\ntype BoatState = 'collapsed' | 'expanded'\ninterface Position {\n\tx: number\n\ty: number\n}\n\n@customElement('schmancy-boat')\nexport default class SchmancyBoat extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: contents;\n\t\tposition: relative;\n\t\tz-index: 1000;\n\t}\n\t:host([hidden]) {\n\t\tdisplay: none !important;\n\t}\n`]\n\n\t@property({ type: String }) id: string = 'default'\n\t@property({ type: String }) icon?: string\n\t@property({ type: String }) label?: string\n\t/** Override the expanded panel width (e.g. '320px', '24rem'). Defaults to responsive sizing. */\n\t@property({ type: String }) expandedWidth?: string\n\t/** When true, uses a lower elevation shadow in the minimized (FAB) state. */\n\t@property({ type: Boolean, reflect: true }) lowered: boolean = false\n\t/** Corner the boat is anchored to. */\n\t@property({ type: String }) corner: Corner = 'bottom-right'\n\t/** Whether the panel is open. */\n\t@property({ type: Boolean, reflect: true }) open: boolean = false\n\n\t/**\n\t * State property.\n\t * Maps 'expanded' → open=true, 'collapsed' → open=false (FAB visible).\n\t */\n\tget state(): BoatState {\n\t\treturn this.open ? 'expanded' : 'collapsed'\n\t}\n\tset state(val: BoatState) {\n\t\tif (val === 'expanded') {\n\t\t\tthis.expand()\n\t\t} else {\n\t\t\t// collapsed\n\t\t\tthis.close()\n\t\t}\n\t}\n\n\t// Internal drag state (triggers re-render for cursor class)\n\t@state() private isDragging = false\n\n\t// Internal position — plain fields, updated directly during drag (no re-render needed)\n\tprivate _position: Position = { x: 16, y: 16 }\n\t@state() private _currentCorner: Corner = 'bottom-right'\n\n\t// Refs\n\tprivate _containerRef = createRef<HTMLElement>()\n\tprivate _contentRef = createRef<HTMLElement>()\n\tprivate _headerRef = createRef<HTMLElement>()\n\tprivate _currentAnimation?: Animation\n\n\t// ============================================\n\t// COMPUTED\n\t// ============================================\n\n\tprivate get panelWidth(): string {\n\t\treturn this.expandedWidth ?? 'min(360px, calc(100vw - 32px))'\n\t}\n\n\tprivate get isBottomCorner(): boolean {\n\t\treturn this._currentCorner.startsWith('bottom')\n\t}\n\n\tprivate get closedClipPath(): string {\n\t\treturn this.isBottomCorner\n\t\t\t? `inset(calc(100% - ${FAB_HEIGHT}px) 0px 0px 0px round 22px)`\n\t\t\t: `inset(0px 0px calc(100% - ${FAB_HEIGHT}px) 0px round 22px)`\n\t}\n\n\tprivate get openClipPath(): string {\n\t\treturn 'inset(0px 0px 0px 0px round 12px)'\n\t}\n\n\tprivate get elevation(): 0 | 1 | 2 | 3 | 4 | 5 {\n\t\tif (this.open) return 4\n\t\treturn this.lowered ? 1 : 3\n\t}\n\n\t// ============================================\n\t// POSITION MANAGEMENT\n\t// ============================================\n\n\tprivate _applyContainerPosition() {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\t\tcontainer.style.removeProperty('left')\n\t\tcontainer.style.removeProperty('right')\n\t\tcontainer.style.removeProperty('top')\n\t\tcontainer.style.removeProperty('bottom')\n\t\tconst { x, y } = this._position\n\t\tif (this._currentCorner.includes('right')) {\n\t\t\tcontainer.style.right = `${x}px`\n\t\t} else {\n\t\t\tcontainer.style.left = `${x}px`\n\t\t}\n\t\tif (this._currentCorner.includes('bottom')) {\n\t\t\tcontainer.style.bottom = `${y + theme.bottomOffset}px`\n\t\t} else {\n\t\t\tcontainer.style.top = `${y}px`\n\t\t}\n\t}\n\n\tprivate _loadPosition() {\n\t\ttry {\n\t\t\tconst saved = localStorage.getItem(POSITION_STORAGE_KEY_PREFIX + this.id)\n\t\t\tif (saved) {\n\t\t\t\tconst parsed = JSON.parse(saved) as { x: number; y: number; anchor: Corner }\n\t\t\t\tthis._position = { x: parsed.x, y: parsed.y }\n\t\t\t\tthis._currentCorner = parsed.anchor\n\t\t\t}\n\t\t} catch {\n\t\t\t// ignore localStorage errors\n\t\t}\n\t}\n\n\tprivate _savePosition() {\n\t\ttry {\n\t\t\tlocalStorage.setItem(\n\t\t\t\tPOSITION_STORAGE_KEY_PREFIX + this.id,\n\t\t\t\tJSON.stringify({ ...this._position, anchor: this._currentCorner }),\n\t\t\t)\n\t\t} catch {\n\t\t\t// ignore localStorage errors\n\t\t}\n\t}\n\n\tprivate _validateBounds() {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\t\tconst rect = container.getBoundingClientRect()\n\t\tif (rect.width === 0) return\n\t\tconst vw = window.innerWidth\n\t\tconst vh = window.innerHeight\n\t\tconst isRight = this._currentCorner.includes('right')\n\t\tconst isBottom = this._currentCorner.includes('bottom')\n\t\tconst actualLeft = isRight ? vw - this._position.x - rect.width : this._position.x\n\t\tconst actualTop = isBottom ? vh - this._position.y - rect.height : this._position.y\n\t\tconst newLeft = Math.max(0, Math.min(actualLeft, vw - rect.width))\n\t\tconst newTop = Math.max(0, Math.min(actualTop, vh - rect.height))\n\t\tthis._position = {\n\t\t\tx: isRight ? vw - newLeft - rect.width : newLeft,\n\t\t\ty: isBottom ? vh - newTop - rect.height : newTop,\n\t\t}\n\t\tthis._applyContainerPosition()\n\t}\n\n\n\t// ============================================\n\t// CORNER SNAPPING\n\t// ============================================\n\n\tprivate _reorientToNearestCorner(skipAnimation = false): void {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\n\t\t// F — record current screen position before DOM mutation\n\t\tconst rect = container.getBoundingClientRect()\n\n\t\t// L — calculate nearest corner using FAB visual center (container is always collapsed during drag)\n\t\tconst currentIsBottom = this._currentCorner.includes('bottom')\n\t\tconst fabCenterX = rect.left + rect.width / 2\n\t\tconst fabCenterY = currentIsBottom\n\t\t\t? rect.bottom - FAB_HEIGHT / 2\n\t\t\t: rect.top + FAB_HEIGHT / 2\n\t\tconst side = fabCenterX > window.innerWidth / 2 ? 'right' : 'left'\n\t\tconst vert = fabCenterY > window.innerHeight / 2 ? 'bottom' : 'top'\n\t\tconst newCorner: Corner = `${vert}-${side}` as Corner\n\n\t\t// Snap corner and reset offset to standard edge gap\n\t\tthis._currentCorner = newCorner\n\t\tthis._position = { x: 16, y: 16 }\n\t\tthis._applyContainerPosition()\n\t\t// Sync clip-path to new corner — managed imperatively, not via styleMap\n\t\tif (!this.open) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t}\n\n\t\tif (skipAnimation || reducedMotion$.value) {\n\t\t\tthis._savePosition()\n\t\t\treturn\n\t\t}\n\n\t\t// I — invert: shift element back to its original visual position\n\t\tconst newRect = container.getBoundingClientRect()\n\t\tconst dx = rect.left - newRect.left\n\t\tconst dy = rect.top - newRect.top\n\t\tcontainer.style.transform = `translate(${dx}px, ${dy}px)`\n\n\t\t// P — play: animate from the inverse offset to natural resting position\n\t\tthis._currentAnimation?.cancel()\n\t\tconst anim = container.animate(\n\t\t\t[{ transform: container.style.transform }, { transform: 'translate(0,0)' }],\n\t\t\t{\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\t\tthis._currentAnimation = anim\n\t\tanim.finished.then(() => {\n\t\t\tif (container.isConnected) {\n\t\t\t\tcontainer.style.transform = ''\n\t\t\t}\n\t\t\treturn\n\t\t})\n\n\t\tthis._savePosition()\n\t}\n\n\t// ============================================\n\t// DRAG PIPELINE\n\t// ============================================\n\n\tprivate _setupDrag() {\n\t\tconst header = this._headerRef.value\n\t\tconst container = this._containerRef.value\n\t\tif (!header || !container) return\n\n\t\tlet didDrag = false\n\n\t\tfromEvent<PointerEvent>(header, 'pointerdown')\n\t\t\t.pipe(\n\t\t\t\tfilter(e => e.button === 0),\n\t\t\t\ttap(e => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t\theader.setPointerCapture(e.pointerId)\n\t\t\t\t}),\n\t\t\t\tmap(e => {\n\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\tconst isBottom = this._currentCorner.includes('bottom')\n\t\t\t\t\tconst wasOpen = this.open\n\t\t\t\t\tdidDrag = false\n\t\t\t\t\treturn {\n\t\t\t\t\t\tpointerId: e.pointerId,\n\t\t\t\t\t\tstartX: e.clientX,\n\t\t\t\t\t\tstartY: e.clientY,\n\t\t\t\t\t\toffsetX: e.clientX - rect.left,\n\t\t\t\t\t\toffsetY: e.clientY - rect.top,\n\t\t\t\t\t\trect,\n\t\t\t\t\t\tisBottom,\n\t\t\t\t\t\twasOpen,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\tswitchMap(({ pointerId, startX, startY, offsetX, offsetY, rect, isBottom, wasOpen }) => {\n\t\t\t\t\tconst sameId = (e: PointerEvent) => e.pointerId === pointerId\n\t\t\t\t\tconst move$ = fromEvent<PointerEvent>(window, 'pointermove').pipe(filter(sameId))\n\t\t\t\t\tconst end$ = merge(\n\t\t\t\t\t\tfromEvent<PointerEvent>(window, 'pointerup'),\n\t\t\t\t\t\tfromEvent<PointerEvent>(window, 'pointercancel'),\n\t\t\t\t\t).pipe(filter(sameId))\n\n\t\t\t\t\treturn move$.pipe(\n\t\t\t\t\t\ttap(({ clientX, clientY }) => {\n\t\t\t\t\t\t\tconst dx = clientX - startX\n\t\t\t\t\t\t\tconst dy = clientY - startY\n\t\t\t\t\t\t\tif (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD && !didDrag) {\n\t\t\t\t\t\t\t\tdidDrag = true\n\t\t\t\t\t\t\t\tthis.isDragging = true\n\t\t\t\t\t\t\t\t// Collapse on first confirmed drag move (not on click)\n\t\t\t\t\t\t\t\tif (wasOpen) {\n\t\t\t\t\t\t\t\t\tthis._currentAnimation?.cancel()\n\t\t\t\t\t\t\t\t\tthis.open = false\n\t\t\t\t\t\t\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\t\t\t\t\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\t\t\t\t\t\t\tconst content = this._contentRef.value\n\t\t\t\t\t\t\t\t\tif (content) {\n\t\t\t\t\t\t\t\t\t\tcontent.inert = true\n\t\t\t\t\t\t\t\t\t\tcontent.style.visibility = 'hidden'\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!didDrag) return\n\n\t\t\t\t\t\t\tconst vw = window.innerWidth\n\t\t\t\t\t\t\tconst vh = window.innerHeight\n\t\t\t\t\t\t\tconst left = Math.max(0, Math.min(clientX - offsetX, vw - rect.width))\n\t\t\t\t\t\t\t// Allow container to go partially off-screen so FAB stays reachable at all edges\n\t\t\t\t\t\t\tconst minTop = isBottom ? FAB_HEIGHT - rect.height : 0\n\t\t\t\t\t\t\tconst maxTop = isBottom ? vh - rect.height : vh - FAB_HEIGHT\n\t\t\t\t\t\t\tconst top = Math.max(minTop, Math.min(clientY - offsetY, maxTop))\n\n\t\t\t\t\t\t\tthis._position = {\n\t\t\t\t\t\t\t\tx: this._currentCorner.includes('right') ? vw - left - rect.width : left,\n\t\t\t\t\t\t\t\ty: isBottom ? vh - top - rect.height : top,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis._applyContainerPosition()\n\t\t\t\t\t\t}),\n\t\t\t\t\t\ttakeUntil(end$),\n\t\t\t\t\t\tfinalize(() => {\n\t\t\t\t\t\t\tif (didDrag) {\n\t\t\t\t\t\t\t\tthis._reorientToNearestCorner()\n\t\t\t\t\t\t\t\tthis.isDragging = false\n\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.isDragging = false\n\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t\tthis.toggle()\n\t\t\t\t\t\t\t}\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\t// ============================================\n\t// LIFECYCLE\n\t// ============================================\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\tfromEvent(window, 'resize')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(() => this._validateBounds())\n\n\t\ttheme.bottomOffset$.pipe(\n\t\t\ttap(() => this._applyContainerPosition()),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\t}\n\n\tfirstUpdated() {\n\t\t// Initialize corner from property\n\t\tthis._currentCorner = this.corner\n\n\t\t// Load saved drag position from localStorage\n\t\tthis._loadPosition()\n\n\t\tconst container = this._containerRef.value\n\t\tconst content = this._contentRef.value\n\t\tif (!container) return\n\n\t\t// Apply initial position\n\t\tthis._applyContainerPosition()\n\n\t\t// Set initial open/closed visual state\n\t\tif (this.open) {\n\t\t\tcontainer.style.overflow = ''\n\t\t\tif (content) {\n\t\t\t\tcontent.inert = false\n\t\t\t\tcontent.style.visibility = 'visible'\n\t\t\t}\n\t\t} else {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tif (content) {\n\t\t\t\tcontent.inert = true\n\t\t\t\tcontent.style.visibility = 'hidden'\n\t\t\t}\n\t\t}\n\n\t\t// Set up drag\n\t\tthis._setupDrag()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis._currentAnimation?.cancel()\n\t}\n\n\t// ============================================\n\t// ANIMATION\n\t// ============================================\n\n\tprivate async _animateOpen(): Promise<void> {\n\t\tconst container = this._containerRef.value\n\t\tconst content = this._contentRef.value\n\t\tif (!container) return\n\n\t\tif (content) {\n\t\t\tcontent.style.visibility = 'visible'\n\t\t\tcontent.inert = false\n\t\t}\n\n\t\tthis.open = true\n\t\tawait this.updateComplete\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = ''\n\t\t\tcontainer.style.overflow = ''\n\t\t\tthis.dispatchScopedEvent('toggle', 'expanded')\n\t\t\treturn\n\t\t}\n\n\t\tthis._currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\n\t\tconst openKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t]\n\t\tconst anim = container.animate(openKeyframes, {\n\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis._currentAnimation = anim\n\n\t\t// Clear clip-path so overflow/scroll work normally after animation\n\t\tanim.finished.then(() => {\n\t\t\tif (container.isConnected) {\n\t\t\t\tcontainer.style.clipPath = ''\n\t\t\t\tcontainer.style.overflow = ''\n\t\t\t}\n\t\t\treturn\n\t\t})\n\n\t\tthis.dispatchScopedEvent('toggle', 'expanded')\n\t}\n\n\tprivate async _animateClose(): Promise<void> {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tthis.open = false\n\t\t\tconst content = this._contentRef.value\n\t\t\tif (content) {\n\t\t\t\tcontent.inert = true\n\t\t\t\tcontent.style.visibility = 'hidden'\n\t\t\t}\n\t\t\tthis.dispatchScopedEvent('toggle', 'collapsed')\n\t\t\treturn\n\t\t}\n\n\t\tthis._currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\n\t\tconst closeKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t]\n\t\tconst anim = container.animate(closeKeyframes, {\n\t\t\tduration: Math.round(SPRING_SNAPPY.duration * 0.9),\n\t\t\teasing: 'cubic-bezier(0.4, 0, 0.8, 0.15)',\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis._currentAnimation = anim\n\n\t\tawait anim.finished\n\n\t\tthis.open = false\n\n\t\tconst content = this._contentRef.value\n\t\tif (content) {\n\t\t\tcontent.inert = true\n\t\t\tcontent.style.visibility = 'hidden'\n\t\t}\n\n\t\tthis.dispatchScopedEvent('toggle', 'collapsed')\n\t}\n\n\t// ============================================\n\t// PUBLIC API\n\t// ============================================\n\n\ttoggle() {\n\t\tif (this.open) this._animateClose()\n\t\telse this._animateOpen()\n\t}\n\n\texpand() {\n\t\tif (this.open) return\n\t\tthis.removeAttribute('hidden')\n\t\tif (!this._containerRef.value) {\n\t\t\tthis.open = true\n\t\t\treturn\n\t\t}\n\t\tthis._animateOpen()\n\t}\n\n\t/** Alias for expand() — kept for backwards compatibility. */\n\tshow() {\n\t\tthis.expand()\n\t}\n\n\tclose() {\n\t\tif (!this.open) return\n\t\tif (!this._containerRef.value) {\n\t\t\tthis.open = false\n\t\t\treturn\n\t\t}\n\t\tthis._animateClose()\n\t}\n\n\t// ============================================\n\t// RENDER\n\t// ============================================\n\n\tprotected render(): unknown {\n\t\tconst isBottom = this._currentCorner.startsWith('bottom')\n\n\t\tconst containerClasses = classMap({\n\t\t\tflex: true,\n\t\t\t'flex-col': isBottom,\n\t\t\t'flex-col-reverse': !isBottom,\n\t\t\t'will-change-[clip-path]': true,\n\t\t\t'z-1000': true,\n\t\t\t'rounded-2xl': this.open,\n\t\t\t'rounded-[22px]': !this.open,\n\t\t\t'overflow-hidden': true,\n\t\t\t'opacity-95': this.isDragging,\n\t\t})\n\n\t\tconst containerStyles = styleMap({\n\t\t\tposition: 'fixed',\n\t\t\twidth: this.panelWidth,\n\t\t\t'max-height': 'calc(100vh - 32px)',\n\t\t\t'pointer-events': 'none',\n\t\t})\n\n\t\tconst contentStyles = styleMap({\n\t\t\t'pointer-events': this.open ? 'auto' : 'none',\n\t\t})\n\n\t\tconst headerClasses = classMap({\n\t\t\t'h-full': true,\n\t\t\t'px-3': true,\n\t\t\tflex: true,\n\t\t\t'items-center': true,\n\t\t\t'gap-2': true,\n\t\t\t'select-none': true,\n\t\t\t'touch-none': true,\n\t\t\t'cursor-grabbing': this.isDragging,\n\t\t\t'cursor-move': !this.isDragging,\n\t\t\t'transition-opacity': true,\n\t\t\t'duration-200': true,\n\t\t})\n\n\t\treturn html`\n\t\t\t<!-- schmancy-surface owns background color and elevation-based shadow.\n\t\t\t Position is managed imperatively via _applyContainerPosition(). -->\n\t\t\t<schmancy-surface\n\t\t\t\t${ref(this._containerRef)}\n\t\t\t\ttype=\"glass\"\n\t\t\t\t.elevation=${this.elevation}\n\t\t\t\tclass=${containerClasses}\n\t\t\t\tstyle=${containerStyles}\n\t\t\t\taria-expanded=${this.open}\n\t\t\t>\n\t\t\t\t<!-- Content section (visually above header for bottom corners) -->\n\t\t\t\t<section\n\t\t\t\t\t${ref(this._contentRef)}\n\t\t\t\t\tclass=\"flex-1 min-h-0 overflow-hidden flex flex-col\"\n\t\t\t\t\tstyle=${contentStyles}\n\t\t\t\t\trole=\"dialog\"\n\t\t\t\t\taria-label=\"${this.label ?? 'Floating panel'}\"\n\t\t\t\t>\n\t\t\t\t\t<schmancy-surface type=\"solid\" class=\"flex flex-col flex-1 min-h-0 overflow-hidden\">\n\t\t\t\t\t\t<schmancy-scroll hide class=\"flex-1\">\n\t\t\t\t\t\t\t<slot></slot>\n\t\t\t\t\t\t</schmancy-scroll>\n\t\t\t\t\t</schmancy-surface>\n\t\t\t\t</section>\n\n\t\t\t\t<!-- Gradient separator between header and content — only when open -->\n\t\t\t\t${when(\n\t\t\t\t\tthis.open,\n\t\t\t\t\t() =>\n\t\t\t\t\t\thtml`<div\n\t\t\t\t\t\t\tclass=\"h-px shrink-0 bg-linear-to-r from-transparent via-primary-default/30 to-transparent\"\n\t\t\t\t\t\t></div>`,\n\t\t\t\t)}\n\n\t\t\t\t<!-- Header / FAB section — always interactive, always visible -->\n\t\t\t\t<section\n\t\t\t\t\tclass=\"shrink-0 bg-surface-containerLowest\"\n\t\t\t\t\tstyle=${styleMap({ 'pointer-events': 'auto', height: `${FAB_HEIGHT}px` })}\n\t\t\t\t>\n\t\t\t\t\t<div\n\t\t\t\t\t\t${ref(this._headerRef)}\n\t\t\t\t\t\tclass=${headerClasses}\n\t\t\t\t\t\ttitle=\"Drag to move\"\n\t\t\t\t\t\taria-label=\"Drag to reposition panel\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<!-- Summary slot rendered once — avoids DOM teardown on toggle -->\n\t\t\t\t\t\t<div class=\"flex-1 min-w-0\">\n\t\t\t\t\t\t\t<slot name=\"summary\"></slot>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<!-- Toggle button: collapse when open, expand when closed -->\n\t\t\t\t\t\t${when(\n\t\t\t\t\t\t\tthis.open,\n\t\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tvariant=\"text\"\n\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\tthis.close()\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\ttitle=\"Collapse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tclose_fullscreen\n\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t`,\n\t\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tvariant=\"text\"\n\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\tthis.expand()\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\ttitle=\"Expand\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tfullscreen\n\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t`,\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-boat': SchmancyBoat\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"boat-BPN8HLzZ.cjs","names":[],"sources":["../src/boat/boat.ts"],"sourcesContent":["import { SchmancyElement } from '@mixins/index'\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { when } from 'lit/directives/when.js'\nimport { filter, finalize, fromEvent, map, merge, switchMap, takeUntil, tap } from 'rxjs'\nimport { SPRING_SMOOTH, SPRING_SNAPPY } from '../utils/animation.js'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport { theme } from '../theme/theme.service.js'\n\nconst FAB_HEIGHT = 44\nconst DRAG_THRESHOLD = 5\nconst POSITION_STORAGE_KEY_PREFIX = 'schmancy-boat-'\n\ntype Corner = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'\ntype BoatState = 'collapsed' | 'expanded'\ninterface Position {\n\tx: number\n\ty: number\n}\n\n@customElement('schmancy-boat')\nexport default class SchmancyBoat extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: contents;\n\t\tposition: relative;\n\t\tz-index: 1000;\n\t}\n\t:host([hidden]) {\n\t\tdisplay: none !important;\n\t}\n`]\n\n\t@property({ type: String }) id: string = 'default'\n\t@property({ type: String }) icon?: string\n\t@property({ type: String }) label?: string\n\t/** Override the expanded panel width (e.g. '320px', '24rem'). Defaults to responsive sizing. */\n\t@property({ type: String }) expandedWidth?: string\n\t/** When true, uses a lower elevation shadow in the minimized (FAB) state. */\n\t@property({ type: Boolean, reflect: true }) lowered: boolean = false\n\t/** Corner the boat is anchored to. */\n\t@property({ type: String }) corner: Corner = 'bottom-right'\n\t/** Whether the panel is open. */\n\t@property({ type: Boolean, reflect: true }) open: boolean = false\n\n\t/**\n\t * State property.\n\t * Maps 'expanded' → open=true, 'collapsed' → open=false (FAB visible).\n\t */\n\tget state(): BoatState {\n\t\treturn this.open ? 'expanded' : 'collapsed'\n\t}\n\tset state(val: BoatState) {\n\t\tif (val === 'expanded') {\n\t\t\tthis.expand()\n\t\t} else {\n\t\t\t// collapsed\n\t\t\tthis.close()\n\t\t}\n\t}\n\n\t// Internal drag state (triggers re-render for cursor class)\n\t@state() private isDragging = false\n\n\t// Internal position — plain fields, updated directly during drag (no re-render needed)\n\tprivate _position: Position = { x: 16, y: 16 }\n\t@state() private _currentCorner: Corner = 'bottom-right'\n\n\t// Refs\n\tprivate _containerRef = createRef<HTMLElement>()\n\tprivate _contentRef = createRef<HTMLElement>()\n\tprivate _headerRef = createRef<HTMLElement>()\n\tprivate _currentAnimation?: Animation\n\n\t// ============================================\n\t// COMPUTED\n\t// ============================================\n\n\tprivate get panelWidth(): string {\n\t\treturn this.expandedWidth ?? 'min(360px, calc(100vw - 32px))'\n\t}\n\n\tprivate get isBottomCorner(): boolean {\n\t\treturn this._currentCorner.startsWith('bottom')\n\t}\n\n\tprivate get closedClipPath(): string {\n\t\treturn this.isBottomCorner\n\t\t\t? `inset(calc(100% - ${FAB_HEIGHT}px) 0px 0px 0px round 22px)`\n\t\t\t: `inset(0px 0px calc(100% - ${FAB_HEIGHT}px) 0px round 22px)`\n\t}\n\n\tprivate get openClipPath(): string {\n\t\treturn 'inset(0px 0px 0px 0px round 12px)'\n\t}\n\n\tprivate get elevation(): 0 | 1 | 2 | 3 | 4 | 5 {\n\t\tif (this.open) return 4\n\t\treturn this.lowered ? 1 : 3\n\t}\n\n\t// ============================================\n\t// POSITION MANAGEMENT\n\t// ============================================\n\n\tprivate _applyContainerPosition() {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\t\tcontainer.style.removeProperty('left')\n\t\tcontainer.style.removeProperty('right')\n\t\tcontainer.style.removeProperty('top')\n\t\tcontainer.style.removeProperty('bottom')\n\t\tconst { x, y } = this._position\n\t\tif (this._currentCorner.includes('right')) {\n\t\t\tcontainer.style.right = `${x}px`\n\t\t} else {\n\t\t\tcontainer.style.left = `${x}px`\n\t\t}\n\t\tif (this._currentCorner.includes('bottom')) {\n\t\t\tcontainer.style.bottom = `${y + theme.bottomOffset}px`\n\t\t} else {\n\t\t\tcontainer.style.top = `${y}px`\n\t\t}\n\t}\n\n\tprivate _loadPosition() {\n\t\ttry {\n\t\t\tconst saved = localStorage.getItem(POSITION_STORAGE_KEY_PREFIX + this.id)\n\t\t\tif (saved) {\n\t\t\t\tconst parsed = JSON.parse(saved) as { x: number; y: number; anchor: Corner }\n\t\t\t\tthis._position = { x: parsed.x, y: parsed.y }\n\t\t\t\tthis._currentCorner = parsed.anchor\n\t\t\t}\n\t\t} catch {\n\t\t\t// ignore localStorage errors\n\t\t}\n\t}\n\n\tprivate _savePosition() {\n\t\ttry {\n\t\t\tlocalStorage.setItem(\n\t\t\t\tPOSITION_STORAGE_KEY_PREFIX + this.id,\n\t\t\t\tJSON.stringify({ ...this._position, anchor: this._currentCorner }),\n\t\t\t)\n\t\t} catch {\n\t\t\t// ignore localStorage errors\n\t\t}\n\t}\n\n\tprivate _validateBounds() {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\t\tconst rect = container.getBoundingClientRect()\n\t\tif (rect.width === 0) return\n\t\tconst vw = window.innerWidth\n\t\tconst vh = window.innerHeight\n\t\tconst isRight = this._currentCorner.includes('right')\n\t\tconst isBottom = this._currentCorner.includes('bottom')\n\t\tconst actualLeft = isRight ? vw - this._position.x - rect.width : this._position.x\n\t\tconst actualTop = isBottom ? vh - this._position.y - rect.height : this._position.y\n\t\tconst newLeft = Math.max(0, Math.min(actualLeft, vw - rect.width))\n\t\tconst newTop = Math.max(0, Math.min(actualTop, vh - rect.height))\n\t\tthis._position = {\n\t\t\tx: isRight ? vw - newLeft - rect.width : newLeft,\n\t\t\ty: isBottom ? vh - newTop - rect.height : newTop,\n\t\t}\n\t\tthis._applyContainerPosition()\n\t}\n\n\n\t// ============================================\n\t// CORNER SNAPPING\n\t// ============================================\n\n\tprivate _reorientToNearestCorner(skipAnimation = false): void {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\n\t\t// F — record current screen position before DOM mutation\n\t\tconst rect = container.getBoundingClientRect()\n\n\t\t// L — calculate nearest corner using FAB visual center (container is always collapsed during drag)\n\t\tconst currentIsBottom = this._currentCorner.includes('bottom')\n\t\tconst fabCenterX = rect.left + rect.width / 2\n\t\tconst fabCenterY = currentIsBottom\n\t\t\t? rect.bottom - FAB_HEIGHT / 2\n\t\t\t: rect.top + FAB_HEIGHT / 2\n\t\tconst side = fabCenterX > window.innerWidth / 2 ? 'right' : 'left'\n\t\tconst vert = fabCenterY > window.innerHeight / 2 ? 'bottom' : 'top'\n\t\tconst newCorner: Corner = `${vert}-${side}` as Corner\n\n\t\t// Snap corner and reset offset to standard edge gap\n\t\tthis._currentCorner = newCorner\n\t\tthis._position = { x: 16, y: 16 }\n\t\tthis._applyContainerPosition()\n\t\t// Sync clip-path to new corner — managed imperatively, not via styleMap\n\t\tif (!this.open) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t}\n\n\t\tif (skipAnimation || reducedMotion$.value) {\n\t\t\tthis._savePosition()\n\t\t\treturn\n\t\t}\n\n\t\t// I — invert: shift element back to its original visual position\n\t\tconst newRect = container.getBoundingClientRect()\n\t\tconst dx = rect.left - newRect.left\n\t\tconst dy = rect.top - newRect.top\n\t\tcontainer.style.transform = `translate(${dx}px, ${dy}px)`\n\n\t\t// P — play: animate from the inverse offset to natural resting position\n\t\tthis._currentAnimation?.cancel()\n\t\tconst anim = container.animate(\n\t\t\t[{ transform: container.style.transform }, { transform: 'translate(0,0)' }],\n\t\t\t{\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\t\tthis._currentAnimation = anim\n\t\tanim.finished.then(() => {\n\t\t\tif (container.isConnected) {\n\t\t\t\tcontainer.style.transform = ''\n\t\t\t}\n\t\t\treturn\n\t\t})\n\n\t\tthis._savePosition()\n\t}\n\n\t// ============================================\n\t// DRAG PIPELINE\n\t// ============================================\n\n\tprivate _setupDrag() {\n\t\tconst header = this._headerRef.value\n\t\tconst container = this._containerRef.value\n\t\tif (!header || !container) return\n\n\t\tlet didDrag = false\n\n\t\tfromEvent<PointerEvent>(header, 'pointerdown')\n\t\t\t.pipe(\n\t\t\t\tfilter(e => e.button === 0),\n\t\t\t\ttap(e => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t\theader.setPointerCapture(e.pointerId)\n\t\t\t\t}),\n\t\t\t\tmap(e => {\n\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\tconst isBottom = this._currentCorner.includes('bottom')\n\t\t\t\t\tconst wasOpen = this.open\n\t\t\t\t\tdidDrag = false\n\t\t\t\t\treturn {\n\t\t\t\t\t\tpointerId: e.pointerId,\n\t\t\t\t\t\tstartX: e.clientX,\n\t\t\t\t\t\tstartY: e.clientY,\n\t\t\t\t\t\toffsetX: e.clientX - rect.left,\n\t\t\t\t\t\toffsetY: e.clientY - rect.top,\n\t\t\t\t\t\trect,\n\t\t\t\t\t\tisBottom,\n\t\t\t\t\t\twasOpen,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\tswitchMap(({ pointerId, startX, startY, offsetX, offsetY, rect, isBottom, wasOpen }) => {\n\t\t\t\t\tconst sameId = (e: PointerEvent) => e.pointerId === pointerId\n\t\t\t\t\tconst move$ = fromEvent<PointerEvent>(window, 'pointermove').pipe(filter(sameId))\n\t\t\t\t\tconst end$ = merge(\n\t\t\t\t\t\tfromEvent<PointerEvent>(window, 'pointerup'),\n\t\t\t\t\t\tfromEvent<PointerEvent>(window, 'pointercancel'),\n\t\t\t\t\t).pipe(filter(sameId))\n\n\t\t\t\t\treturn move$.pipe(\n\t\t\t\t\t\ttap(({ clientX, clientY }) => {\n\t\t\t\t\t\t\tconst dx = clientX - startX\n\t\t\t\t\t\t\tconst dy = clientY - startY\n\t\t\t\t\t\t\tif (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD && !didDrag) {\n\t\t\t\t\t\t\t\tdidDrag = true\n\t\t\t\t\t\t\t\tthis.isDragging = true\n\t\t\t\t\t\t\t\t// Collapse on first confirmed drag move (not on click)\n\t\t\t\t\t\t\t\tif (wasOpen) {\n\t\t\t\t\t\t\t\t\tthis._currentAnimation?.cancel()\n\t\t\t\t\t\t\t\t\tthis.open = false\n\t\t\t\t\t\t\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\t\t\t\t\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\t\t\t\t\t\t\tconst content = this._contentRef.value\n\t\t\t\t\t\t\t\t\tif (content) {\n\t\t\t\t\t\t\t\t\t\tcontent.inert = true\n\t\t\t\t\t\t\t\t\t\tcontent.style.visibility = 'hidden'\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!didDrag) return\n\n\t\t\t\t\t\t\tconst vw = window.innerWidth\n\t\t\t\t\t\t\tconst vh = window.innerHeight\n\t\t\t\t\t\t\tconst left = Math.max(0, Math.min(clientX - offsetX, vw - rect.width))\n\t\t\t\t\t\t\t// Allow container to go partially off-screen so FAB stays reachable at all edges\n\t\t\t\t\t\t\tconst minTop = isBottom ? FAB_HEIGHT - rect.height : 0\n\t\t\t\t\t\t\tconst maxTop = isBottom ? vh - rect.height : vh - FAB_HEIGHT\n\t\t\t\t\t\t\tconst top = Math.max(minTop, Math.min(clientY - offsetY, maxTop))\n\n\t\t\t\t\t\t\tthis._position = {\n\t\t\t\t\t\t\t\tx: this._currentCorner.includes('right') ? vw - left - rect.width : left,\n\t\t\t\t\t\t\t\ty: isBottom ? vh - top - rect.height : top,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis._applyContainerPosition()\n\t\t\t\t\t\t}),\n\t\t\t\t\t\ttakeUntil(end$),\n\t\t\t\t\t\tfinalize(() => {\n\t\t\t\t\t\t\tif (didDrag) {\n\t\t\t\t\t\t\t\tthis._reorientToNearestCorner()\n\t\t\t\t\t\t\t\tthis.isDragging = false\n\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.isDragging = false\n\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t\tthis.toggle()\n\t\t\t\t\t\t\t}\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\t// ============================================\n\t// LIFECYCLE\n\t// ============================================\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\tfromEvent(window, 'resize')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(() => this._validateBounds())\n\n\t\ttheme.bottomOffset$.pipe(\n\t\t\ttap(() => this._applyContainerPosition()),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\t}\n\n\tfirstUpdated() {\n\t\t// Initialize corner from property\n\t\tthis._currentCorner = this.corner\n\n\t\t// Load saved drag position from localStorage\n\t\tthis._loadPosition()\n\n\t\tconst container = this._containerRef.value\n\t\tconst content = this._contentRef.value\n\t\tif (!container) return\n\n\t\t// Apply initial position\n\t\tthis._applyContainerPosition()\n\n\t\t// Set initial open/closed visual state\n\t\tif (this.open) {\n\t\t\tcontainer.style.overflow = ''\n\t\t\tif (content) {\n\t\t\t\tcontent.inert = false\n\t\t\t\tcontent.style.visibility = 'visible'\n\t\t\t}\n\t\t} else {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tif (content) {\n\t\t\t\tcontent.inert = true\n\t\t\t\tcontent.style.visibility = 'hidden'\n\t\t\t}\n\t\t}\n\n\t\t// Set up drag\n\t\tthis._setupDrag()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\tthis._currentAnimation?.cancel()\n\t}\n\n\t// ============================================\n\t// ANIMATION\n\t// ============================================\n\n\tprivate async _animateOpen(): Promise<void> {\n\t\tconst container = this._containerRef.value\n\t\tconst content = this._contentRef.value\n\t\tif (!container) return\n\n\t\tif (content) {\n\t\t\tcontent.style.visibility = 'visible'\n\t\t\tcontent.inert = false\n\t\t}\n\n\t\tthis.open = true\n\t\tawait this.updateComplete\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = ''\n\t\t\tcontainer.style.overflow = ''\n\t\t\tthis.dispatchScopedEvent('toggle', 'expanded')\n\t\t\treturn\n\t\t}\n\n\t\tthis._currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\n\t\tconst openKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t]\n\t\tconst anim = container.animate(openKeyframes, {\n\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis._currentAnimation = anim\n\n\t\t// Clear clip-path so overflow/scroll work normally after animation\n\t\tanim.finished.then(() => {\n\t\t\tif (container.isConnected) {\n\t\t\t\tcontainer.style.clipPath = ''\n\t\t\t\tcontainer.style.overflow = ''\n\t\t\t}\n\t\t\treturn\n\t\t})\n\n\t\tthis.dispatchScopedEvent('toggle', 'expanded')\n\t}\n\n\tprivate async _animateClose(): Promise<void> {\n\t\tconst container = this._containerRef.value\n\t\tif (!container) return\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tthis.open = false\n\t\t\tconst content = this._contentRef.value\n\t\t\tif (content) {\n\t\t\t\tcontent.inert = true\n\t\t\t\tcontent.style.visibility = 'hidden'\n\t\t\t}\n\t\t\tthis.dispatchScopedEvent('toggle', 'collapsed')\n\t\t\treturn\n\t\t}\n\n\t\tthis._currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\n\t\tconst closeKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t]\n\t\tconst anim = container.animate(closeKeyframes, {\n\t\t\tduration: Math.round(SPRING_SNAPPY.duration * 0.9),\n\t\t\teasing: 'cubic-bezier(0.4, 0, 0.8, 0.15)',\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis._currentAnimation = anim\n\n\t\tawait anim.finished\n\n\t\tthis.open = false\n\n\t\tconst content = this._contentRef.value\n\t\tif (content) {\n\t\t\tcontent.inert = true\n\t\t\tcontent.style.visibility = 'hidden'\n\t\t}\n\n\t\tthis.dispatchScopedEvent('toggle', 'collapsed')\n\t}\n\n\t// ============================================\n\t// PUBLIC API\n\t// ============================================\n\n\ttoggle() {\n\t\tif (this.open) this._animateClose()\n\t\telse this._animateOpen()\n\t}\n\n\texpand() {\n\t\tif (this.open) return\n\t\tthis.removeAttribute('hidden')\n\t\tif (!this._containerRef.value) {\n\t\t\tthis.open = true\n\t\t\treturn\n\t\t}\n\t\tthis._animateOpen()\n\t}\n\n\t/** Alias for expand() — kept for backwards compatibility. */\n\tshow() {\n\t\tthis.expand()\n\t}\n\n\tclose() {\n\t\tif (!this.open) return\n\t\tif (!this._containerRef.value) {\n\t\t\tthis.open = false\n\t\t\treturn\n\t\t}\n\t\tthis._animateClose()\n\t}\n\n\t// ============================================\n\t// RENDER\n\t// ============================================\n\n\tprotected render(): unknown {\n\t\tconst isBottom = this._currentCorner.startsWith('bottom')\n\n\t\tconst containerClasses = classMap({\n\t\t\tflex: true,\n\t\t\t'flex-col': isBottom,\n\t\t\t'flex-col-reverse': !isBottom,\n\t\t\t'will-change-[clip-path]': true,\n\t\t\t'z-1000': true,\n\t\t\t'rounded-2xl': this.open,\n\t\t\t'rounded-[22px]': !this.open,\n\t\t\t'overflow-hidden': true,\n\t\t\t'opacity-95': this.isDragging,\n\t\t})\n\n\t\tconst containerStyles = styleMap({\n\t\t\tposition: 'fixed',\n\t\t\twidth: this.panelWidth,\n\t\t\t'max-height': 'calc(100vh - 32px)',\n\t\t\t'pointer-events': 'none',\n\t\t})\n\n\t\tconst contentStyles = styleMap({\n\t\t\t'pointer-events': this.open ? 'auto' : 'none',\n\t\t})\n\n\t\tconst headerClasses = classMap({\n\t\t\t'h-full': true,\n\t\t\t'px-3': true,\n\t\t\tflex: true,\n\t\t\t'items-center': true,\n\t\t\t'gap-2': true,\n\t\t\t'select-none': true,\n\t\t\t'touch-none': true,\n\t\t\t'cursor-grabbing': this.isDragging,\n\t\t\t'cursor-move': !this.isDragging,\n\t\t\t'transition-opacity': true,\n\t\t\t'duration-200': true,\n\t\t})\n\n\t\treturn html`\n\t\t\t<!-- schmancy-surface owns background color and elevation-based shadow.\n\t\t\t Position is managed imperatively via _applyContainerPosition(). -->\n\t\t\t<schmancy-surface\n\t\t\t\t${ref(this._containerRef)}\n\t\t\t\ttype=\"glass\"\n\t\t\t\t.elevation=${this.elevation}\n\t\t\t\tclass=${containerClasses}\n\t\t\t\tstyle=${containerStyles}\n\t\t\t\taria-expanded=${this.open}\n\t\t\t>\n\t\t\t\t<!-- Content section (visually above header for bottom corners) -->\n\t\t\t\t<section\n\t\t\t\t\t${ref(this._contentRef)}\n\t\t\t\t\tclass=\"flex-1 min-h-0 overflow-hidden flex flex-col\"\n\t\t\t\t\tstyle=${contentStyles}\n\t\t\t\t\trole=\"dialog\"\n\t\t\t\t\taria-label=\"${this.label ?? 'Floating panel'}\"\n\t\t\t\t>\n\t\t\t\t\t<schmancy-surface type=\"solid\" class=\"flex flex-col flex-1 min-h-0 overflow-hidden\">\n\t\t\t\t\t\t<schmancy-scroll hide class=\"flex-1\">\n\t\t\t\t\t\t\t<slot></slot>\n\t\t\t\t\t\t</schmancy-scroll>\n\t\t\t\t\t</schmancy-surface>\n\t\t\t\t</section>\n\n\t\t\t\t<!-- Gradient separator between header and content — only when open -->\n\t\t\t\t${when(\n\t\t\t\t\tthis.open,\n\t\t\t\t\t() =>\n\t\t\t\t\t\thtml`<div\n\t\t\t\t\t\t\tclass=\"h-px shrink-0 bg-linear-to-r from-transparent via-primary-default/30 to-transparent\"\n\t\t\t\t\t\t></div>`,\n\t\t\t\t)}\n\n\t\t\t\t<!-- Header / FAB section — always interactive, always visible -->\n\t\t\t\t<section\n\t\t\t\t\tclass=\"shrink-0 bg-surface-containerLowest\"\n\t\t\t\t\tstyle=${styleMap({ 'pointer-events': 'auto', height: `${FAB_HEIGHT}px` })}\n\t\t\t\t>\n\t\t\t\t\t<div\n\t\t\t\t\t\t${ref(this._headerRef)}\n\t\t\t\t\t\tclass=${headerClasses}\n\t\t\t\t\t\ttitle=\"Drag to move\"\n\t\t\t\t\t\taria-label=\"Drag to reposition panel\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<!-- Summary slot rendered once — avoids DOM teardown on toggle -->\n\t\t\t\t\t\t<div class=\"flex-1 min-w-0\">\n\t\t\t\t\t\t\t<slot name=\"summary\"></slot>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<!-- Toggle button: collapse when open, expand when closed -->\n\t\t\t\t\t\t${when(\n\t\t\t\t\t\t\tthis.open,\n\t\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tvariant=\"text\"\n\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\tthis.close()\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\ttitle=\"Collapse\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tclose_fullscreen\n\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t`,\n\t\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t\t<schmancy-icon-button\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tvariant=\"text\"\n\t\t\t\t\t\t\t\t\t@click=${(e: Event) => {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t\tthis.expand()\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\ttitle=\"Expand\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tfullscreen\n\t\t\t\t\t\t\t\t</schmancy-icon-button>\n\t\t\t\t\t\t\t`,\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-boat': SchmancyBoat\n\t}\n}\n"],"mappings":"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"}
package/dist/boat.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./boat-OatK_MGh.cjs`);exports.SchmancyBoat=e.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./boat-BPN8HLzZ.cjs`);exports.SchmancyBoat=e.t;
package/dist/boat.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as e } from "./boat-CNWIQPA1.js";
1
+ import { t as e } from "./boat-BF5P6p_f.js";
2
2
  export { e as SchmancyBoat };
@@ -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.separator=`/`}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.separator=`/`}static{this.styles=[r.css`
2
2
  :host {
3
3
  display: block;
4
4
  }