@mhmo91/schmancy 0.10.33 → 0.10.35

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 (334) hide show
  1. package/custom-elements.json +7 -51
  2. package/dist/SchmancyElement-CA0Wqt8m.js +284 -0
  3. package/dist/{SchmancyElement-DuzT2AMa.js.map → SchmancyElement-CA0Wqt8m.js.map} +1 -1
  4. package/dist/SchmancyElement-CYIif26I.cjs +2 -0
  5. package/dist/{SchmancyElement-D8_z9JrW.cjs.map → SchmancyElement-CYIif26I.cjs.map} +1 -1
  6. package/dist/agent/schmancy.agent.js +1198 -1313
  7. package/dist/agent/schmancy.agent.js.map +1 -1
  8. package/dist/agent/schmancy.manifest.json +5 -30
  9. package/dist/{area-WGfTrwcJ.cjs → area-CTSTgjlx.cjs} +1 -1
  10. package/dist/{area-WGfTrwcJ.cjs.map → area-CTSTgjlx.cjs.map} +1 -1
  11. package/dist/{area-0l8V7HlF.js → area-DviXdbDx.js} +2 -2
  12. package/dist/{area-0l8V7HlF.js.map → area-DviXdbDx.js.map} +1 -1
  13. package/dist/area.cjs +1 -1
  14. package/dist/area.js +1 -1
  15. package/dist/{audio-x9oLVKBH.js → audio-DFYoaw0M.js} +1 -1
  16. package/dist/{audio-x9oLVKBH.js.map → audio-DFYoaw0M.js.map} +1 -1
  17. package/dist/{audio-9QLk4pU-.cjs → audio-Q9oB_cQR.cjs} +1 -1
  18. package/dist/{audio-9QLk4pU-.cjs.map → audio-Q9oB_cQR.cjs.map} +1 -1
  19. package/dist/audio.cjs +1 -1
  20. package/dist/audio.js +2 -2
  21. package/dist/{autocomplete-sjZovPcs.js → autocomplete-BDvuma6D.js} +3 -3
  22. package/dist/{autocomplete-sjZovPcs.js.map → autocomplete-BDvuma6D.js.map} +1 -1
  23. package/dist/{autocomplete-CjjfXbJC.cjs → autocomplete-DmLXJr7C.cjs} +1 -1
  24. package/dist/{autocomplete-CjjfXbJC.cjs.map → autocomplete-DmLXJr7C.cjs.map} +1 -1
  25. package/dist/autocomplete.cjs +1 -1
  26. package/dist/autocomplete.js +1 -1
  27. package/dist/avatar.cjs +1 -1
  28. package/dist/avatar.js +3 -3
  29. package/dist/badge.cjs +1 -1
  30. package/dist/badge.js +1 -1
  31. package/dist/boat-Vqjgo10B.cjs +33 -0
  32. package/dist/boat-Vqjgo10B.cjs.map +1 -0
  33. package/dist/boat-lr7MPZ7H.js +207 -0
  34. package/dist/boat-lr7MPZ7H.js.map +1 -0
  35. package/dist/boat.cjs +1 -1
  36. package/dist/boat.js +1 -1
  37. package/dist/breadcrumb.cjs +1 -1
  38. package/dist/breadcrumb.js +2 -2
  39. package/dist/{busy-DDKXlzDA.cjs → busy-CgzZbGfx.cjs} +1 -1
  40. package/dist/{busy-DDKXlzDA.cjs.map → busy-CgzZbGfx.cjs.map} +1 -1
  41. package/dist/{busy-DwD-XHqS.js → busy-DgQ4ux5N.js} +2 -2
  42. package/dist/{busy-DwD-XHqS.js.map → busy-DgQ4ux5N.js.map} +1 -1
  43. package/dist/busy.cjs +1 -1
  44. package/dist/busy.js +1 -1
  45. package/dist/{button-nDZQe1ES.cjs → button-DFvR1iXX.cjs} +1 -1
  46. package/dist/{button-nDZQe1ES.cjs.map → button-DFvR1iXX.cjs.map} +1 -1
  47. package/dist/{button-qARUurjf.js → button-qbN1muQ0.js} +2 -2
  48. package/dist/{button-qARUurjf.js.map → button-qbN1muQ0.js.map} +1 -1
  49. package/dist/button.cjs +1 -1
  50. package/dist/button.js +3 -3
  51. package/dist/{card-D3IxxBBP.js → card-DAbr-7Vy.js} +2 -2
  52. package/dist/{card-D3IxxBBP.js.map → card-DAbr-7Vy.js.map} +1 -1
  53. package/dist/{card-DWZhZ5Ds.cjs → card-D_GlwZ5q.cjs} +1 -1
  54. package/dist/{card-DWZhZ5Ds.cjs.map → card-D_GlwZ5q.cjs.map} +1 -1
  55. package/dist/card.cjs +1 -1
  56. package/dist/card.js +1 -1
  57. package/dist/{checkbox-t__wRS-9.js → checkbox-BNORaxMF.js} +2 -2
  58. package/dist/{checkbox-t__wRS-9.js.map → checkbox-BNORaxMF.js.map} +1 -1
  59. package/dist/{checkbox-BBttnA_a.cjs → checkbox-BUY_uc_r.cjs} +1 -1
  60. package/dist/{checkbox-BBttnA_a.cjs.map → checkbox-BUY_uc_r.cjs.map} +1 -1
  61. package/dist/checkbox.cjs +1 -1
  62. package/dist/checkbox.js +1 -1
  63. package/dist/{chips-DIZFWnDZ.cjs → chips-CXZ4dJCK.cjs} +1 -1
  64. package/dist/{chips-DIZFWnDZ.cjs.map → chips-CXZ4dJCK.cjs.map} +1 -1
  65. package/dist/{chips-xaoSmwBK.js → chips-Dg6Lk6BT.js} +4 -4
  66. package/dist/{chips-xaoSmwBK.js.map → chips-Dg6Lk6BT.js.map} +1 -1
  67. package/dist/chips.cjs +1 -1
  68. package/dist/chips.js +2 -2
  69. package/dist/connectivity.cjs +1 -1
  70. package/dist/connectivity.js +3 -3
  71. package/dist/content-drawer.cjs +1 -1
  72. package/dist/content-drawer.js +1 -1
  73. package/dist/{date-range-8OkCahnR.js → date-range-BU6WX7d5.js} +3 -3
  74. package/dist/{date-range-8OkCahnR.js.map → date-range-BU6WX7d5.js.map} +1 -1
  75. package/dist/{date-range-Bbzg9aym.cjs → date-range-C-_be3_E.cjs} +1 -1
  76. package/dist/{date-range-Bbzg9aym.cjs.map → date-range-C-_be3_E.cjs.map} +1 -1
  77. package/dist/{date-range-inline-BEP-oWJZ.js → date-range-inline-7o7xtVIu.js} +2 -2
  78. package/dist/{date-range-inline-BEP-oWJZ.js.map → date-range-inline-7o7xtVIu.js.map} +1 -1
  79. package/dist/{date-range-inline-lhkwHFxY.cjs → date-range-inline-DJtUmHKF.cjs} +1 -1
  80. package/dist/{date-range-inline-lhkwHFxY.cjs.map → date-range-inline-DJtUmHKF.cjs.map} +1 -1
  81. package/dist/date-range-inline.cjs +1 -1
  82. package/dist/date-range-inline.js +1 -1
  83. package/dist/date-range.cjs +1 -1
  84. package/dist/date-range.js +1 -1
  85. package/dist/delay.cjs +1 -1
  86. package/dist/delay.js +2 -2
  87. package/dist/{details-3X9YKpuP.cjs → details-Bs0MyyvF.cjs} +1 -1
  88. package/dist/{details-3X9YKpuP.cjs.map → details-Bs0MyyvF.cjs.map} +1 -1
  89. package/dist/{details-BO_3CCNn.js → details-EfbDPVEo.js} +2 -2
  90. package/dist/{details-BO_3CCNn.js.map → details-EfbDPVEo.js.map} +1 -1
  91. package/dist/details.cjs +1 -1
  92. package/dist/details.js +1 -1
  93. package/dist/{directives-BOsvcH83.cjs → directives-fLwDj6b0.cjs} +1 -1
  94. package/dist/{directives-BOsvcH83.cjs.map → directives-fLwDj6b0.cjs.map} +1 -1
  95. package/dist/{directives-D7AoVfPK.js → directives-zi1Mm2er.js} +3 -3
  96. package/dist/{directives-D7AoVfPK.js.map → directives-zi1Mm2er.js.map} +1 -1
  97. package/dist/directives.cjs +1 -1
  98. package/dist/directives.js +2 -2
  99. package/dist/{divider-BHgrisGQ.js → divider-CEPfrIwe.js} +2 -2
  100. package/dist/{divider-BHgrisGQ.js.map → divider-CEPfrIwe.js.map} +1 -1
  101. package/dist/{divider-D21yKZNJ.cjs → divider-CdIsWZrM.cjs} +1 -1
  102. package/dist/{divider-D21yKZNJ.cjs.map → divider-CdIsWZrM.cjs.map} +1 -1
  103. package/dist/divider.cjs +1 -1
  104. package/dist/divider.js +1 -1
  105. package/dist/dropdown.cjs +1 -1
  106. package/dist/dropdown.js +2 -2
  107. package/dist/{expand-wRphbpW6.cjs → expand--at1k3qo.cjs} +1 -1
  108. package/dist/{expand-wRphbpW6.cjs.map → expand--at1k3qo.cjs.map} +1 -1
  109. package/dist/{expand-2TTbmm_z.js → expand-g1vqqUp1.js} +3 -3
  110. package/dist/{expand-2TTbmm_z.js.map → expand-g1vqqUp1.js.map} +1 -1
  111. package/dist/expand.cjs +1 -1
  112. package/dist/expand.js +1 -1
  113. package/dist/{float-dtDqRmcL.js → float-DxVzgI9o.js} +2 -2
  114. package/dist/{float-dtDqRmcL.js.map → float-DxVzgI9o.js.map} +1 -1
  115. package/dist/{float-B0L_CH4v.cjs → float-P9HukAm-.cjs} +1 -1
  116. package/dist/{float-B0L_CH4v.cjs.map → float-P9HukAm-.cjs.map} +1 -1
  117. package/dist/float.cjs +1 -1
  118. package/dist/float.js +1 -1
  119. package/dist/{form-DvqHReDF.cjs → form-ByYhXe1p.cjs} +1 -1
  120. package/dist/{form-DvqHReDF.cjs.map → form-ByYhXe1p.cjs.map} +1 -1
  121. package/dist/{form-BxY-9F6N.js → form-CqLaozHp.js} +3 -3
  122. package/dist/{form-BxY-9F6N.js.map → form-CqLaozHp.js.map} +1 -1
  123. package/dist/form.cjs +1 -1
  124. package/dist/form.js +10 -10
  125. package/dist/handover/agent-runtime-followups.md +1 -1
  126. package/dist/handover/agent-runtime-v1.md +3 -3
  127. package/dist/{icons-CO8UrTJQ.js → icons-CkphcMp6.js} +2 -2
  128. package/dist/{icons-CO8UrTJQ.js.map → icons-CkphcMp6.js.map} +1 -1
  129. package/dist/{icons-BbC4t44c.cjs → icons-DYtiRU5V.cjs} +1 -1
  130. package/dist/{icons-BbC4t44c.cjs.map → icons-DYtiRU5V.cjs.map} +1 -1
  131. package/dist/icons.cjs +1 -1
  132. package/dist/icons.js +1 -1
  133. package/dist/{iframe-BepoWz9Z.cjs → iframe-C3trkP8q.cjs} +1 -1
  134. package/dist/{iframe-BepoWz9Z.cjs.map → iframe-C3trkP8q.cjs.map} +1 -1
  135. package/dist/{iframe-t5zo89Fs.js → iframe-CjqJksl8.js} +2 -2
  136. package/dist/{iframe-t5zo89Fs.js.map → iframe-CjqJksl8.js.map} +1 -1
  137. package/dist/iframe.cjs +1 -1
  138. package/dist/iframe.js +1 -1
  139. package/dist/index.cjs +1 -1
  140. package/dist/index.js +37 -37
  141. package/dist/{input-2OR6wjfT.js → input-CG51zDVh.js} +2 -2
  142. package/dist/{input-2OR6wjfT.js.map → input-CG51zDVh.js.map} +1 -1
  143. package/dist/{input-B-wPPC5o.cjs → input-DuavpwNL.cjs} +1 -1
  144. package/dist/{input-B-wPPC5o.cjs.map → input-DuavpwNL.cjs.map} +1 -1
  145. package/dist/{input-chip-O5-pgek1.cjs → input-chip-57tgNXKT.cjs} +1 -1
  146. package/dist/{input-chip-O5-pgek1.cjs.map → input-chip-57tgNXKT.cjs.map} +1 -1
  147. package/dist/{input-chip-NBsnZkzu.js → input-chip-C6Lq1927.js} +2 -2
  148. package/dist/{input-chip-NBsnZkzu.js.map → input-chip-C6Lq1927.js.map} +1 -1
  149. package/dist/input.cjs +1 -1
  150. package/dist/input.js +1 -1
  151. package/dist/json.cjs +1 -1
  152. package/dist/json.js +3 -3
  153. package/dist/kbd.cjs +1 -1
  154. package/dist/kbd.js +2 -2
  155. package/dist/{layout-D7nKwpa5.cjs → layout-6ipbiWTl.cjs} +1 -1
  156. package/dist/{layout-D7nKwpa5.cjs.map → layout-6ipbiWTl.cjs.map} +1 -1
  157. package/dist/{layout-CJ01zE9V.js → layout-D4IOwx7p.js} +1 -1
  158. package/dist/{layout-CJ01zE9V.js.map → layout-D4IOwx7p.js.map} +1 -1
  159. package/dist/layout.cjs +1 -1
  160. package/dist/layout.js +2 -2
  161. package/dist/{lightbox-Droe9dYY.js → lightbox-CsyO2XSr.js} +2 -2
  162. package/dist/{lightbox-Droe9dYY.js.map → lightbox-CsyO2XSr.js.map} +1 -1
  163. package/dist/{lightbox-DVpvjsYb.cjs → lightbox-H8pVWGMX.cjs} +1 -1
  164. package/dist/{lightbox-DVpvjsYb.cjs.map → lightbox-H8pVWGMX.cjs.map} +1 -1
  165. package/dist/lightbox.cjs +1 -1
  166. package/dist/lightbox.js +1 -1
  167. package/dist/{list-DzAWv99q.js → list-BAwH0pQW.js} +2 -2
  168. package/dist/{list-DzAWv99q.js.map → list-BAwH0pQW.js.map} +1 -1
  169. package/dist/{list-JjUsFCP6.cjs → list-Bs9m8kw7.cjs} +1 -1
  170. package/dist/{list-JjUsFCP6.cjs.map → list-Bs9m8kw7.cjs.map} +1 -1
  171. package/dist/list.cjs +1 -1
  172. package/dist/list.js +1 -1
  173. package/dist/{menu-B5EKUeeD.cjs → menu-BMcGzj1h.cjs} +1 -1
  174. package/dist/{menu-B5EKUeeD.cjs.map → menu-BMcGzj1h.cjs.map} +1 -1
  175. package/dist/{menu-CgdXrzir.js → menu-tQVARVaC.js} +3 -3
  176. package/dist/{menu-CgdXrzir.js.map → menu-tQVARVaC.js.map} +1 -1
  177. package/dist/menu.cjs +1 -1
  178. package/dist/menu.js +1 -1
  179. package/dist/{mixins-Cevarn7V.js → mixins-Bp0wIHg2.js} +1 -1
  180. package/dist/{mixins-Cevarn7V.js.map → mixins-Bp0wIHg2.js.map} +1 -1
  181. package/dist/{mixins-JyO9GSGy.cjs → mixins-CGXSzZc7.cjs} +1 -1
  182. package/dist/{mixins-JyO9GSGy.cjs.map → mixins-CGXSzZc7.cjs.map} +1 -1
  183. package/dist/mixins.cjs +1 -1
  184. package/dist/mixins.js +2 -2
  185. package/dist/nav-drawer.cjs +1 -1
  186. package/dist/nav-drawer.js +1 -1
  187. package/dist/navigation-bar.cjs +1 -1
  188. package/dist/navigation-bar.js +1 -1
  189. package/dist/navigation-rail.cjs +1 -1
  190. package/dist/navigation-rail.js +2 -2
  191. package/dist/{notification-CaeRS5US.cjs → notification-Bz00zdpV.cjs} +1 -1
  192. package/dist/{notification-CaeRS5US.cjs.map → notification-Bz00zdpV.cjs.map} +1 -1
  193. package/dist/{notification-Dxwx0Zln.js → notification-D1tX2nx5.js} +4 -4
  194. package/dist/{notification-Dxwx0Zln.js.map → notification-D1tX2nx5.js.map} +1 -1
  195. package/dist/notification.cjs +1 -1
  196. package/dist/notification.js +1 -1
  197. package/dist/{option-C6wXFQOM.cjs → option-BnybLEDO.cjs} +1 -1
  198. package/dist/{option-C6wXFQOM.cjs.map → option-BnybLEDO.cjs.map} +1 -1
  199. package/dist/{option-BCnYutZz.js → option-BpGV8Apj.js} +2 -2
  200. package/dist/{option-BCnYutZz.js.map → option-BpGV8Apj.js.map} +1 -1
  201. package/dist/option.cjs +1 -1
  202. package/dist/option.js +1 -1
  203. package/dist/{overlay-BWcB2pRx.js → overlay-BpNhd74N.js} +24 -7
  204. package/dist/overlay-BpNhd74N.js.map +1 -0
  205. package/dist/{overlay-5PMZ75PO.cjs → overlay-UQR2Dy3u.cjs} +18 -3
  206. package/dist/overlay-UQR2Dy3u.cjs.map +1 -0
  207. package/dist/overlay.cjs +1 -1
  208. package/dist/{overlay.confirm-body-B7W0DOGS.js → overlay.confirm-body-BHcXu5Wk.js} +6 -6
  209. package/dist/{overlay.confirm-body-B7W0DOGS.js.map → overlay.confirm-body-BHcXu5Wk.js.map} +1 -1
  210. package/dist/{overlay.confirm-body-CsvwcBvG.cjs → overlay.confirm-body-CVDtVk5X.cjs} +1 -1
  211. package/dist/{overlay.confirm-body-CsvwcBvG.cjs.map → overlay.confirm-body-CVDtVk5X.cjs.map} +1 -1
  212. package/dist/overlay.js +3 -3
  213. package/dist/{overlay.service-CC4zckoV.cjs → overlay.service-C8RsQzgM.cjs} +1 -1
  214. package/dist/{overlay.service-CC4zckoV.cjs.map → overlay.service-C8RsQzgM.cjs.map} +1 -1
  215. package/dist/{overlay.service-zx465FI8.js → overlay.service-DTE6NwIM.js} +2 -2
  216. package/dist/{overlay.service-zx465FI8.js.map → overlay.service-DTE6NwIM.js.map} +1 -1
  217. package/dist/{progress-BoFm3r6h.js → progress-CAKsxp29.js} +2 -2
  218. package/dist/{progress-BoFm3r6h.js.map → progress-CAKsxp29.js.map} +1 -1
  219. package/dist/{progress-Bc_IBaNH.cjs → progress-gbIALDRs.cjs} +1 -1
  220. package/dist/{progress-Bc_IBaNH.cjs.map → progress-gbIALDRs.cjs.map} +1 -1
  221. package/dist/progress.cjs +1 -1
  222. package/dist/progress.js +1 -1
  223. package/dist/{radio-group-C34WDjrN.cjs → radio-group-CfJ5DtI4.cjs} +1 -1
  224. package/dist/{radio-group-C34WDjrN.cjs.map → radio-group-CfJ5DtI4.cjs.map} +1 -1
  225. package/dist/{radio-group-DnHhGrXp.js → radio-group-otyvZvUk.js} +2 -2
  226. package/dist/{radio-group-DnHhGrXp.js.map → radio-group-otyvZvUk.js.map} +1 -1
  227. package/dist/radio-group.cjs +1 -1
  228. package/dist/radio-group.js +1 -1
  229. package/dist/range.cjs +1 -1
  230. package/dist/range.js +2 -2
  231. package/dist/{select-D61MbhmA.cjs → select-81jniVTs.cjs} +1 -1
  232. package/dist/{select-D61MbhmA.cjs.map → select-81jniVTs.cjs.map} +1 -1
  233. package/dist/{select-C_ljy5k4.js → select-9vXx1fhr.js} +3 -3
  234. package/dist/{select-C_ljy5k4.js.map → select-9vXx1fhr.js.map} +1 -1
  235. package/dist/select.cjs +1 -1
  236. package/dist/select.js +1 -1
  237. package/dist/skeleton.cjs +1 -1
  238. package/dist/skeleton.js +2 -2
  239. package/dist/skills/boat.md +27 -18
  240. package/dist/skills/schmancy/boat.md +27 -18
  241. package/dist/slider.cjs +1 -1
  242. package/dist/slider.js +2 -2
  243. package/dist/{sound.service-Czs3gmRx.cjs → sound.service-CmIw63aM.cjs} +1 -1
  244. package/dist/{sound.service-Czs3gmRx.cjs.map → sound.service-CmIw63aM.cjs.map} +1 -1
  245. package/dist/{sound.service-Cuo4-X_-.js → sound.service-D3ZSq1Kj.js} +1 -1
  246. package/dist/{sound.service-Cuo4-X_-.js.map → sound.service-D3ZSq1Kj.js.map} +1 -1
  247. package/dist/{splash-screen-CbcYpkIx.js → splash-screen-BOjrmGLk.js} +2 -2
  248. package/dist/{splash-screen-CbcYpkIx.js.map → splash-screen-BOjrmGLk.js.map} +1 -1
  249. package/dist/{splash-screen-C0oeDPxV.cjs → splash-screen-C5KAWXvA.cjs} +1 -1
  250. package/dist/{splash-screen-C0oeDPxV.cjs.map → splash-screen-C5KAWXvA.cjs.map} +1 -1
  251. package/dist/splash-screen.cjs +1 -1
  252. package/dist/splash-screen.js +1 -1
  253. package/dist/{src-CdX0NekF.js → src-C5g3p1J5.js} +35 -35
  254. package/dist/{src-CdX0NekF.js.map → src-C5g3p1J5.js.map} +1 -1
  255. package/dist/{src-DEgL_xJv.cjs → src-qzUpLbje.cjs} +1 -1
  256. package/dist/{src-DEgL_xJv.cjs.map → src-qzUpLbje.cjs.map} +1 -1
  257. package/dist/{state-B-5H9i10.js → state-CWBRTSvE.js} +1 -1
  258. package/dist/{state-B-5H9i10.js.map → state-CWBRTSvE.js.map} +1 -1
  259. package/dist/{state-D85Se4Fx.cjs → state-Cex3rmx2.cjs} +1 -1
  260. package/dist/{state-D85Se4Fx.cjs.map → state-Cex3rmx2.cjs.map} +1 -1
  261. package/dist/state.cjs +1 -1
  262. package/dist/state.js +2 -2
  263. package/dist/steps.cjs +1 -1
  264. package/dist/steps.js +2 -2
  265. package/dist/{surface-gZpeCF6E.js → surface-9S5scTsD.js} +2 -2
  266. package/dist/{surface-gZpeCF6E.js.map → surface-9S5scTsD.js.map} +1 -1
  267. package/dist/{surface-DHPaLOTA.cjs → surface-PfiejLuw.cjs} +1 -1
  268. package/dist/{surface-DHPaLOTA.cjs.map → surface-PfiejLuw.cjs.map} +1 -1
  269. package/dist/surface.cjs +1 -1
  270. package/dist/surface.js +1 -1
  271. package/dist/switch.cjs +1 -1
  272. package/dist/switch.js +2 -2
  273. package/dist/table.cjs +1 -1
  274. package/dist/table.js +2 -2
  275. package/dist/{tabs-DJNdoE-x.js → tabs-BBOjAmgG.js} +2 -2
  276. package/dist/{tabs-DJNdoE-x.js.map → tabs-BBOjAmgG.js.map} +1 -1
  277. package/dist/{tabs-DgaVwuOo.cjs → tabs-uYvb1P06.cjs} +1 -1
  278. package/dist/{tabs-DgaVwuOo.cjs.map → tabs-uYvb1P06.cjs.map} +1 -1
  279. package/dist/tabs.cjs +1 -1
  280. package/dist/tabs.js +1 -1
  281. package/dist/teleport.cjs +1 -1
  282. package/dist/teleport.js +1 -1
  283. package/dist/{textarea-8x0prbgm.js → textarea-QzSj8Dkl.js} +2 -2
  284. package/dist/{textarea-8x0prbgm.js.map → textarea-QzSj8Dkl.js.map} +1 -1
  285. package/dist/{textarea-2QE5z6Ny.cjs → textarea-YPHX4g7Y.cjs} +1 -1
  286. package/dist/{textarea-2QE5z6Ny.cjs.map → textarea-YPHX4g7Y.cjs.map} +1 -1
  287. package/dist/textarea.cjs +1 -1
  288. package/dist/textarea.js +1 -1
  289. package/dist/{theme-DSD9Bs69.js → theme-C2Mp-VGt.js} +4 -4
  290. package/dist/{theme-DSD9Bs69.js.map → theme-C2Mp-VGt.js.map} +1 -1
  291. package/dist/{theme-button-Dpr6SGzB.cjs → theme-button-CJmhxfMe.cjs} +1 -1
  292. package/dist/{theme-button-Dpr6SGzB.cjs.map → theme-button-CJmhxfMe.cjs.map} +1 -1
  293. package/dist/{theme-button-nd6Z7plT.js → theme-button-DGWAXhzd.js} +2 -2
  294. package/dist/{theme-button-nd6Z7plT.js.map → theme-button-DGWAXhzd.js.map} +1 -1
  295. package/dist/theme-button.cjs +1 -1
  296. package/dist/theme-button.js +1 -1
  297. package/dist/{theme-D0yboni1.cjs → theme-iKUaS9JB.cjs} +1 -1
  298. package/dist/{theme-D0yboni1.cjs.map → theme-iKUaS9JB.cjs.map} +1 -1
  299. package/dist/theme.cjs +1 -1
  300. package/dist/theme.js +3 -3
  301. package/dist/{theme.service-mRlvWZVs.js → theme.service-hc4N-1Oz.js} +1 -1
  302. package/dist/{theme.service-mRlvWZVs.js.map → theme.service-hc4N-1Oz.js.map} +1 -1
  303. package/dist/{theme.service-LtQw04e6.cjs → theme.service-p61RsJBF.cjs} +1 -1
  304. package/dist/{theme.service-LtQw04e6.cjs.map → theme.service-p61RsJBF.cjs.map} +1 -1
  305. package/dist/tree.cjs +1 -1
  306. package/dist/tree.js +2 -2
  307. package/dist/{typography-CiZQpzE4.cjs → typography-Bdt8RlX2.cjs} +1 -1
  308. package/dist/{typography-CiZQpzE4.cjs.map → typography-Bdt8RlX2.cjs.map} +1 -1
  309. package/dist/{typography-DXyf-KdK.js → typography-DwV0sqht.js} +2 -2
  310. package/dist/{typography-DXyf-KdK.js.map → typography-DwV0sqht.js.map} +1 -1
  311. package/dist/typography.cjs +1 -1
  312. package/dist/typography.js +1 -1
  313. package/dist/visually-hidden.cjs +1 -1
  314. package/dist/visually-hidden.js +2 -2
  315. package/dist/{window-qKfP5c6M.cjs → window-D2WfvNng.cjs} +1 -1
  316. package/dist/{window-qKfP5c6M.cjs.map → window-D2WfvNng.cjs.map} +1 -1
  317. package/dist/{window-C_ATa3qM.js → window-n4jN60B_.js} +3 -3
  318. package/dist/{window-C_ATa3qM.js.map → window-n4jN60B_.js.map} +1 -1
  319. package/dist/window.cjs +1 -1
  320. package/dist/window.js +1 -1
  321. package/package.json +1 -1
  322. package/skills/schmancy/boat.md +27 -18
  323. package/src/boat/boat.ts +153 -414
  324. package/src/overlay/overlay.component.ts +28 -0
  325. package/types/src/boat/boat.d.ts +28 -38
  326. package/types/src/overlay/overlay.component.d.ts +1 -0
  327. package/dist/SchmancyElement-D8_z9JrW.cjs +0 -2
  328. package/dist/SchmancyElement-DuzT2AMa.js +0 -284
  329. package/dist/boat-CEaQaCmG.js +0 -339
  330. package/dist/boat-CEaQaCmG.js.map +0 -1
  331. package/dist/boat-CI5rcGS5.cjs +0 -85
  332. package/dist/boat-CI5rcGS5.cjs.map +0 -1
  333. package/dist/overlay-5PMZ75PO.cjs.map +0 -1
  334. package/dist/overlay-BWcB2pRx.js.map +0 -1
package/src/boat/boat.ts CHANGED
@@ -1,219 +1,159 @@
1
1
  import { SchmancyElement } from '@mixins/index'
2
- import { css, html } from 'lit'
3
- import { customElement, property, state } from 'lit/decorators.js'
2
+ import { css, html, type PropertyValues } from 'lit'
3
+ import { customElement, property, queryAssignedElements, state } from 'lit/decorators.js'
4
4
  import { classMap } from 'lit/directives/class-map.js'
5
5
  import { createRef, ref } from 'lit/directives/ref.js'
6
6
  import { styleMap } from 'lit/directives/style-map.js'
7
- import { when } from 'lit/directives/when.js'
8
- import { filter, finalize, fromEvent, map, merge, switchMap, takeUntil, tap } from 'rxjs'
9
- import { SPRING_SMOOTH, SPRING_SNAPPY } from '../utils/animation.js'
7
+ import { filter, finalize, fromEvent, map, merge, type Subscription, switchMap, takeUntil, tap } from 'rxjs'
10
8
  import { reducedMotion$ } from '../directives/reduced-motion'
9
+ import { show } from '../overlay/overlay.service'
11
10
  import { theme } from '../theme/theme.service.js'
11
+ import { SPRING_SMOOTH } from '../utils/animation.js'
12
12
 
13
- const FAB_HEIGHT = 36
14
13
  const DRAG_THRESHOLD = 5
15
14
  const POSITION_STORAGE_KEY_PREFIX = 'schmancy-boat-'
16
15
 
17
16
  type Corner = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'
18
- type BoatState = 'collapsed' | 'expanded'
19
17
  interface Position {
20
18
  x: number
21
19
  y: number
22
20
  }
23
21
 
22
+ /**
23
+ * Material-3 extended FAB that delegates its expanded panel to the `show()`
24
+ * overlay service. Collapsed: a draggable, corner-anchored pill (icon + label,
25
+ * circular when no label). Activated: the default-slot content blooms from the
26
+ * FAB as an overlay (backdrop / Esc / back-button / sheet-on-narrow handled by
27
+ * the overlay primitive).
28
+ */
24
29
  @customElement('schmancy-boat')
25
30
  export default class SchmancyBoat extends SchmancyElement {
26
31
  static styles = [css`
27
- :host {
28
- display: contents;
29
- position: relative;
30
- z-index: 1000;
31
- }
32
- :host([hidden]) {
33
- display: none !important;
34
- }
35
- `]
32
+ :host {
33
+ display: contents;
34
+ }
35
+ :host([hidden]) {
36
+ display: none !important;
37
+ }
38
+ `]
36
39
 
40
+ /** Identity for localStorage drag-position persistence. */
37
41
  @property({ type: String }) id: string = 'default'
38
- @property({ type: String }) icon?: string
39
- @property({ type: String }) label?: string
40
- /** Override the expanded panel width (e.g. '320px', '24rem'). Defaults to responsive sizing. */
41
- @property({ type: String }) expandedWidth?: string
42
- /** When true, uses a lower elevation shadow in the minimized (FAB) state. */
43
- @property({ type: Boolean, reflect: true }) lowered: boolean = false
44
- /** Corner the boat is anchored to. */
42
+ /** Corner the FAB is anchored to. */
45
43
  @property({ type: String }) corner: Corner = 'bottom-right'
46
- /** Whether the panel is open. */
44
+ /** Open state. Bind `?open=${…}` to drive the overlay; reflected to the attribute. */
47
45
  @property({ type: Boolean, reflect: true }) open: boolean = false
48
46
 
49
- /**
50
- * State property.
51
- * Maps 'expanded' → open=true, 'collapsed' → open=false (FAB visible).
52
- */
53
- get state(): BoatState {
54
- return this.open ? 'expanded' : 'collapsed'
55
- }
56
- set state(val: BoatState) {
57
- if (val === 'expanded') {
58
- this.expand()
59
- } else {
60
- // collapsed
61
- this.close()
62
- }
63
- }
64
-
65
- // Internal drag state (triggers re-render for cursor class)
66
47
  @state() private isDragging = false
48
+ @state() private currentCorner: Corner = 'bottom-right'
67
49
 
68
- // Internal position — plain fields, updated directly during drag (no re-render needed)
69
- private _position: Position = { x: 16, y: 16 }
70
- @state() private _currentCorner: Corner = 'bottom-right'
50
+ @queryAssignedElements() private slotted!: Element[]
71
51
 
72
- // Refs
73
- private _containerRef = createRef<HTMLElement>()
74
- private _contentRef = createRef<HTMLElement>()
75
- private _headerRef = createRef<HTMLElement>()
76
- private _currentAnimation?: Animation
52
+ private position: Position = { x: 16, y: 16 }
53
+ private containerRef = createRef<HTMLElement>()
54
+ private headerRef = createRef<HTMLElement>()
55
+ private currentAnimation?: Animation
77
56
 
78
- // ============================================
79
- // COMPUTED
80
- // ============================================
81
-
82
- private get panelWidth(): string {
83
- return this.expandedWidth ?? 'min(360px, calc(100vw - 32px))'
84
- }
85
-
86
- private get isBottomCorner(): boolean {
87
- return this._currentCorner.startsWith('bottom')
88
- }
89
-
90
- private get closedClipPath(): string {
91
- return this.isBottomCorner
92
- ? `inset(calc(100% - ${FAB_HEIGHT}px) 0px 0px 0px round 10px)`
93
- : `inset(0px 0px calc(100% - ${FAB_HEIGHT}px) 0px round 10px)`
94
- }
95
-
96
- private get openClipPath(): string {
97
- return 'inset(0px 0px 0px 0px round 4px)'
98
- }
99
-
100
- private get elevation(): 0 | 1 | 2 | 3 | 4 | 5 {
101
- if (this.open) return 4
102
- return this.lowered ? 1 : 3
103
- }
57
+ #ready = false
58
+ #sub?: Subscription
59
+ #captured: Element[] = []
104
60
 
105
61
  // ============================================
106
62
  // POSITION MANAGEMENT
107
63
  // ============================================
108
64
 
109
- private _applyContainerPosition() {
110
- const container = this._containerRef.value
65
+ private applyContainerPosition() {
66
+ const container = this.containerRef.value
111
67
  if (!container) return
112
68
  container.style.removeProperty('left')
113
69
  container.style.removeProperty('right')
114
70
  container.style.removeProperty('top')
115
71
  container.style.removeProperty('bottom')
116
- const { x, y } = this._position
117
- if (this._currentCorner.includes('right')) {
72
+ const { x, y } = this.position
73
+ if (this.currentCorner.includes('right')) {
118
74
  container.style.right = `${x}px`
119
75
  } else {
120
76
  container.style.left = `${x}px`
121
77
  }
122
- if (this._currentCorner.includes('bottom')) {
78
+ if (this.currentCorner.includes('bottom')) {
123
79
  container.style.bottom = `${y + theme.bottomOffset}px`
124
80
  } else {
125
81
  container.style.top = `${y}px`
126
82
  }
127
83
  }
128
84
 
129
- private _loadPosition() {
85
+ private loadPosition() {
130
86
  try {
131
87
  const saved = localStorage.getItem(POSITION_STORAGE_KEY_PREFIX + this.id)
132
88
  if (saved) {
133
89
  const parsed = JSON.parse(saved) as { x: number; y: number; anchor: Corner }
134
- this._position = { x: parsed.x, y: parsed.y }
135
- this._currentCorner = parsed.anchor
90
+ this.position = { x: parsed.x, y: parsed.y }
91
+ this.currentCorner = parsed.anchor
136
92
  }
137
93
  } catch {
138
94
  // ignore localStorage errors
139
95
  }
140
96
  }
141
97
 
142
- private _savePosition() {
98
+ private savePosition() {
143
99
  try {
144
100
  localStorage.setItem(
145
101
  POSITION_STORAGE_KEY_PREFIX + this.id,
146
- JSON.stringify({ ...this._position, anchor: this._currentCorner }),
102
+ JSON.stringify({ ...this.position, anchor: this.currentCorner }),
147
103
  )
148
104
  } catch {
149
105
  // ignore localStorage errors
150
106
  }
151
107
  }
152
108
 
153
- private _validateBounds() {
154
- const container = this._containerRef.value
109
+ private validateBounds() {
110
+ const container = this.containerRef.value
155
111
  if (!container) return
156
112
  const rect = container.getBoundingClientRect()
157
113
  if (rect.width === 0) return
158
114
  const vw = window.innerWidth
159
115
  const vh = window.innerHeight
160
- const isRight = this._currentCorner.includes('right')
161
- const isBottom = this._currentCorner.includes('bottom')
162
- const actualLeft = isRight ? vw - this._position.x - rect.width : this._position.x
163
- const actualTop = isBottom ? vh - this._position.y - rect.height : this._position.y
116
+ const isRight = this.currentCorner.includes('right')
117
+ const isBottom = this.currentCorner.includes('bottom')
118
+ const actualLeft = isRight ? vw - this.position.x - rect.width : this.position.x
119
+ const actualTop = isBottom ? vh - this.position.y - rect.height : this.position.y
164
120
  const newLeft = Math.max(0, Math.min(actualLeft, vw - rect.width))
165
121
  const newTop = Math.max(0, Math.min(actualTop, vh - rect.height))
166
- this._position = {
122
+ this.position = {
167
123
  x: isRight ? vw - newLeft - rect.width : newLeft,
168
124
  y: isBottom ? vh - newTop - rect.height : newTop,
169
125
  }
170
- this._applyContainerPosition()
126
+ this.applyContainerPosition()
171
127
  }
172
128
 
173
-
174
129
  // ============================================
175
- // CORNER SNAPPING
130
+ // CORNER SNAPPING (FLIP)
176
131
  // ============================================
177
132
 
178
- private _reorientToNearestCorner(skipAnimation = false): void {
179
- const container = this._containerRef.value
133
+ private reorientToNearestCorner(): void {
134
+ const container = this.containerRef.value
180
135
  if (!container) return
181
136
 
182
- // F — record current screen position before DOM mutation
183
137
  const rect = container.getBoundingClientRect()
184
-
185
- // L — calculate nearest corner using FAB visual center (container is always collapsed during drag)
186
- const currentIsBottom = this._currentCorner.includes('bottom')
187
138
  const fabCenterX = rect.left + rect.width / 2
188
- const fabCenterY = currentIsBottom
189
- ? rect.bottom - FAB_HEIGHT / 2
190
- : rect.top + FAB_HEIGHT / 2
139
+ const fabCenterY = rect.top + rect.height / 2
191
140
  const side = fabCenterX > window.innerWidth / 2 ? 'right' : 'left'
192
141
  const vert = fabCenterY > window.innerHeight / 2 ? 'bottom' : 'top'
193
- const newCorner: Corner = `${vert}-${side}` as Corner
194
-
195
- // Snap corner and reset offset to standard edge gap
196
- this._currentCorner = newCorner
197
- this._position = { x: 16, y: 16 }
198
- this._applyContainerPosition()
199
- // Sync clip-path to new corner — managed imperatively, not via styleMap
200
- if (!this.open) {
201
- container.style.clipPath = this.closedClipPath
202
- }
142
+ this.currentCorner = `${vert}-${side}` as Corner
143
+ this.position = { x: 16, y: 16 }
144
+ this.applyContainerPosition()
203
145
 
204
- if (skipAnimation || reducedMotion$.value) {
205
- this._savePosition()
146
+ if (reducedMotion$.value) {
147
+ this.savePosition()
206
148
  return
207
149
  }
208
150
 
209
- // I — invert: shift element back to its original visual position
210
151
  const newRect = container.getBoundingClientRect()
211
152
  const dx = rect.left - newRect.left
212
153
  const dy = rect.top - newRect.top
213
154
  container.style.transform = `translate(${dx}px, ${dy}px)`
214
155
 
215
- // P — play: animate from the inverse offset to natural resting position
216
- this._currentAnimation?.cancel()
156
+ this.currentAnimation?.cancel()
217
157
  const anim = container.animate(
218
158
  [{ transform: container.style.transform }, { transform: 'translate(0,0)' }],
219
159
  {
@@ -222,24 +162,22 @@ export default class SchmancyBoat extends SchmancyElement {
222
162
  fill: 'forwards',
223
163
  },
224
164
  )
225
- this._currentAnimation = anim
165
+ this.currentAnimation = anim
226
166
  anim.finished.then(() => {
227
- if (container.isConnected) {
228
- container.style.transform = ''
229
- }
167
+ if (container.isConnected) container.style.transform = ''
230
168
  return
231
169
  })
232
170
 
233
- this._savePosition()
171
+ this.savePosition()
234
172
  }
235
173
 
236
174
  // ============================================
237
175
  // DRAG PIPELINE
238
176
  // ============================================
239
177
 
240
- private _setupDrag() {
241
- const header = this._headerRef.value
242
- const container = this._containerRef.value
178
+ private setupDrag() {
179
+ const header = this.headerRef.value
180
+ const container = this.containerRef.value
243
181
  if (!header || !container) return
244
182
 
245
183
  let didDrag = false
@@ -254,8 +192,6 @@ export default class SchmancyBoat extends SchmancyElement {
254
192
  }),
255
193
  map(e => {
256
194
  const rect = container.getBoundingClientRect()
257
- const isBottom = this._currentCorner.includes('bottom')
258
- const wasOpen = this.open
259
195
  didDrag = false
260
196
  return {
261
197
  pointerId: e.pointerId,
@@ -264,11 +200,9 @@ export default class SchmancyBoat extends SchmancyElement {
264
200
  offsetX: e.clientX - rect.left,
265
201
  offsetY: e.clientY - rect.top,
266
202
  rect,
267
- isBottom,
268
- wasOpen,
269
203
  }
270
204
  }),
271
- switchMap(({ pointerId, startX, startY, offsetX, offsetY, rect, isBottom, wasOpen }) => {
205
+ switchMap(({ pointerId, startX, startY, offsetX, offsetY, rect }) => {
272
206
  const sameId = (e: PointerEvent) => e.pointerId === pointerId
273
207
  const move$ = fromEvent<PointerEvent>(window, 'pointermove').pipe(filter(sameId))
274
208
  const end$ = merge(
@@ -283,39 +217,23 @@ export default class SchmancyBoat extends SchmancyElement {
283
217
  if (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD && !didDrag) {
284
218
  didDrag = true
285
219
  this.isDragging = true
286
- // Collapse on first confirmed drag move (not on click)
287
- if (wasOpen) {
288
- this._currentAnimation?.cancel()
289
- this.open = false
290
- container.style.clipPath = this.closedClipPath
291
- container.style.overflow = 'hidden'
292
- const content = this._contentRef.value
293
- if (content) {
294
- content.inert = true
295
- content.style.visibility = 'hidden'
296
- }
297
- }
298
220
  }
299
221
  if (!didDrag) return
300
222
 
301
223
  const vw = window.innerWidth
302
224
  const vh = window.innerHeight
303
225
  const left = Math.max(0, Math.min(clientX - offsetX, vw - rect.width))
304
- // Allow container to go partially off-screen so FAB stays reachable at all edges
305
- const minTop = isBottom ? FAB_HEIGHT - rect.height : 0
306
- const maxTop = isBottom ? vh - rect.height : vh - FAB_HEIGHT
307
- const top = Math.max(minTop, Math.min(clientY - offsetY, maxTop))
308
-
309
- this._position = {
310
- x: this._currentCorner.includes('right') ? vw - left - rect.width : left,
311
- y: isBottom ? vh - top - rect.height : top,
226
+ const top = Math.max(0, Math.min(clientY - offsetY, vh - rect.height))
227
+ this.position = {
228
+ x: this.currentCorner.includes('right') ? vw - left - rect.width : left,
229
+ y: this.currentCorner.includes('bottom') ? vh - top - rect.height : top,
312
230
  }
313
- this._applyContainerPosition()
231
+ this.applyContainerPosition()
314
232
  }),
315
233
  takeUntil(end$),
316
234
  finalize(() => {
317
235
  if (didDrag) {
318
- this._reorientToNearestCorner()
236
+ this.reorientToNearestCorner()
319
237
  this.isDragging = false
320
238
  didDrag = false
321
239
  } else {
@@ -331,6 +249,40 @@ export default class SchmancyBoat extends SchmancyElement {
331
249
  .subscribe()
332
250
  }
333
251
 
252
+ // ============================================
253
+ // OVERLAY DELEGATION
254
+ // ============================================
255
+
256
+ private openOverlay() {
257
+ if (this.#sub) return
258
+ const anchor = this.containerRef.value
259
+ const wrapper = document.createElement('div')
260
+ wrapper.className = 'flex flex-col'
261
+ this.#captured = [...this.slotted]
262
+ this.#captured.forEach(node => wrapper.appendChild(node))
263
+
264
+ this.#sub = show(wrapper, {
265
+ anchor: anchor ?? undefined,
266
+ dismissable: true,
267
+ historyStrategy: 'silent',
268
+ })
269
+ .pipe(
270
+ finalize(() => this.restoreSlotted()),
271
+ takeUntil(this.disconnecting),
272
+ )
273
+ .subscribe()
274
+
275
+ this.dispatchScopedEvent('toggle', 'open')
276
+ }
277
+
278
+ private restoreSlotted() {
279
+ this.#captured.forEach(node => this.appendChild(node))
280
+ this.#captured = []
281
+ this.#sub = undefined
282
+ if (this.open) this.open = false
283
+ this.dispatchScopedEvent('toggle', 'closed')
284
+ }
285
+
334
286
  // ============================================
335
287
  // LIFECYCLE
336
288
  // ============================================
@@ -340,178 +292,43 @@ export default class SchmancyBoat extends SchmancyElement {
340
292
 
341
293
  fromEvent(window, 'resize')
342
294
  .pipe(takeUntil(this.disconnecting))
343
- .subscribe(() => this._validateBounds())
295
+ .subscribe(() => this.validateBounds())
344
296
 
345
297
  theme.bottomOffset$.pipe(
346
- tap(() => this._applyContainerPosition()),
298
+ tap(() => this.applyContainerPosition()),
347
299
  takeUntil(this.disconnecting),
348
300
  ).subscribe()
349
301
  }
350
302
 
351
303
  firstUpdated() {
352
- // Initialize corner from property
353
- this._currentCorner = this.corner
354
-
355
- // Load saved drag position from localStorage
356
- this._loadPosition()
357
-
358
- const container = this._containerRef.value
359
- const content = this._contentRef.value
360
- if (!container) return
361
-
362
- // Apply initial position
363
- this._applyContainerPosition()
364
-
365
- // Set initial open/closed visual state
366
- if (this.open) {
367
- container.style.overflow = ''
368
- if (content) {
369
- content.inert = false
370
- content.style.visibility = 'visible'
371
- }
372
- } else {
373
- container.style.clipPath = this.closedClipPath
374
- container.style.overflow = 'hidden'
375
- if (content) {
376
- content.inert = true
377
- content.style.visibility = 'hidden'
378
- }
379
- }
304
+ this.currentCorner = this.corner
305
+ this.loadPosition()
306
+ if (!this.containerRef.value) return
307
+ this.applyContainerPosition()
308
+ this.setupDrag()
309
+ this.#ready = true
310
+ if (this.open) this.openOverlay()
311
+ }
380
312
 
381
- // Set up drag
382
- this._setupDrag()
313
+ protected willUpdate(changed: PropertyValues<this>) {
314
+ if (!this.#ready || !changed.has('open')) return
315
+ if (this.open && !this.#sub) this.openOverlay()
316
+ else if (!this.open && this.#sub) this.#sub.unsubscribe()
383
317
  }
384
318
 
385
319
  disconnectedCallback() {
386
320
  super.disconnectedCallback()
387
- this._currentAnimation?.cancel()
388
- }
389
-
390
- // ============================================
391
- // ANIMATION
392
- // ============================================
393
-
394
- private async _animateOpen(): Promise<void> {
395
- const container = this._containerRef.value
396
- const content = this._contentRef.value
397
- if (!container) return
398
-
399
- if (content) {
400
- content.style.visibility = 'visible'
401
- content.inert = false
402
- }
403
-
404
- this.open = true
405
- await this.updateComplete
406
-
407
- if (reducedMotion$.value) {
408
- container.style.clipPath = ''
409
- container.style.overflow = ''
410
- this.dispatchScopedEvent('toggle', 'expanded')
411
- return
412
- }
413
-
414
- this._currentAnimation?.cancel()
415
- container.style.overflow = 'hidden'
416
-
417
- const openKeyframes: Keyframe[] = [
418
- { clipPath: this.closedClipPath, opacity: 0.85 },
419
- { clipPath: this.openClipPath, opacity: 1 },
420
- ]
421
- const anim = container.animate(openKeyframes, {
422
- duration: SPRING_SMOOTH.duration,
423
- easing: SPRING_SMOOTH.easingFallback,
424
- fill: 'forwards',
425
- })
426
- this._currentAnimation = anim
427
-
428
- // Clear clip-path so overflow/scroll work normally after animation
429
- anim.finished.then(() => {
430
- if (container.isConnected) {
431
- container.style.clipPath = ''
432
- container.style.overflow = ''
433
- }
434
- return
435
- })
436
-
437
- this.dispatchScopedEvent('toggle', 'expanded')
438
- }
439
-
440
- private async _animateClose(): Promise<void> {
441
- const container = this._containerRef.value
442
- if (!container) return
443
-
444
- if (reducedMotion$.value) {
445
- container.style.clipPath = this.closedClipPath
446
- container.style.overflow = 'hidden'
447
- this.open = false
448
- const content = this._contentRef.value
449
- if (content) {
450
- content.inert = true
451
- content.style.visibility = 'hidden'
452
- }
453
- this.dispatchScopedEvent('toggle', 'collapsed')
454
- return
455
- }
456
-
457
- this._currentAnimation?.cancel()
458
- container.style.overflow = 'hidden'
459
-
460
- const closeKeyframes: Keyframe[] = [
461
- { clipPath: this.openClipPath, opacity: 1 },
462
- { clipPath: this.closedClipPath, opacity: 0.85 },
463
- ]
464
- const anim = container.animate(closeKeyframes, {
465
- duration: Math.round(SPRING_SNAPPY.duration * 0.9),
466
- easing: 'cubic-bezier(0.4, 0, 0.8, 0.15)',
467
- fill: 'forwards',
468
- })
469
- this._currentAnimation = anim
470
-
471
- await anim.finished
472
-
473
- this.open = false
474
-
475
- const content = this._contentRef.value
476
- if (content) {
477
- content.inert = true
478
- content.style.visibility = 'hidden'
479
- }
480
-
481
- this.dispatchScopedEvent('toggle', 'collapsed')
321
+ this.currentAnimation?.cancel()
322
+ this.#sub?.unsubscribe()
482
323
  }
483
324
 
484
325
  // ============================================
485
326
  // PUBLIC API
486
327
  // ============================================
487
328
 
329
+ /** Flip open ↔ closed. */
488
330
  toggle() {
489
- if (this.open) this._animateClose()
490
- else this._animateOpen()
491
- }
492
-
493
- expand() {
494
- if (this.open) return
495
- this.removeAttribute('hidden')
496
- if (!this._containerRef.value) {
497
- this.open = true
498
- return
499
- }
500
- this._animateOpen()
501
- }
502
-
503
- /** Alias for expand() — kept for backwards compatibility. */
504
- show() {
505
- this.expand()
506
- }
507
-
508
- close() {
509
- if (!this.open) return
510
- if (!this._containerRef.value) {
511
- this.open = false
512
- return
513
- }
514
- this._animateClose()
331
+ this.open = !this.open
515
332
  }
516
333
 
517
334
  // ============================================
@@ -519,138 +336,60 @@ export default class SchmancyBoat extends SchmancyElement {
519
336
  // ============================================
520
337
 
521
338
  protected render(): unknown {
522
- const isBottom = this._currentCorner.startsWith('bottom')
523
-
524
339
  const containerClasses = classMap({
525
- flex: true,
526
- 'flex-col': isBottom,
527
- 'flex-col-reverse': !isBottom,
528
- 'will-change-[clip-path]': true,
529
- 'z-1000': true,
530
- // open: 4px radius (instrument-sharp); closed: 10px (status-bar pill)
531
- 'rounded': this.open,
532
- 'rounded-lg': !this.open,
340
+ 'inline-flex': true,
341
+ 'rounded-full': true,
533
342
  'overflow-hidden': true,
534
- // micro-scale + reduced opacity signals lift during drag
343
+ 'transition-opacity': true,
344
+ 'duration-200': true,
535
345
  'opacity-85': this.isDragging,
536
346
  'scale-95': this.isDragging,
537
347
  })
538
348
 
539
349
  const containerStyles = styleMap({
540
350
  position: 'fixed',
541
- width: this.panelWidth,
542
- 'max-height': 'calc(100vh - 32px)',
543
- 'pointer-events': 'none',
351
+ 'pointer-events': 'auto',
544
352
  })
545
353
 
546
- const contentStyles = styleMap({
547
- 'pointer-events': this.open ? 'auto' : 'none',
548
- })
549
-
550
- const headerClasses = classMap({
551
- 'h-full': true,
552
- 'px-3': true,
354
+ const fabClasses = classMap({
355
+ 'h-14': true,
356
+ 'min-w-14': true,
357
+ 'px-4': true,
358
+ 'rounded-full': true,
553
359
  flex: true,
554
360
  'items-center': true,
555
- 'gap-2': true,
361
+ 'justify-center': true,
362
+ 'gap-3': true,
556
363
  'select-none': true,
557
364
  'touch-none': true,
558
365
  'cursor-grabbing': this.isDragging,
559
- 'cursor-move': !this.isDragging,
560
- 'transition-opacity': true,
561
- 'duration-200': true,
366
+ 'cursor-pointer': !this.isDragging,
562
367
  })
563
368
 
564
369
  return html`
565
- <!-- schmancy-surface owns background color and elevation-based shadow.
566
- Position is managed imperatively via _applyContainerPosition(). -->
567
370
  <schmancy-surface
568
- ${ref(this._containerRef)}
371
+ ${ref(this.containerRef)}
569
372
  type="glass"
570
- .elevation=${this.elevation}
373
+ .elevation=${3}
571
374
  class=${containerClasses}
572
375
  style=${containerStyles}
573
376
  aria-expanded=${this.open}
574
377
  >
575
- <!-- Content section (visually above header for bottom corners) -->
576
- <section
577
- ${ref(this._contentRef)}
578
- class="flex-1 min-h-0 overflow-hidden flex flex-col"
579
- style=${contentStyles}
580
- role="dialog"
581
- aria-label="${this.label ?? 'Floating panel'}"
582
- >
583
- <schmancy-surface type="solid" class="flex flex-col flex-1 min-h-0 overflow-hidden">
584
- <schmancy-scroll hide class="flex-1">
585
- <slot></slot>
586
- </schmancy-scroll>
587
- </schmancy-surface>
588
- </section>
589
-
590
- <!-- Header / FAB section — always interactive, always visible -->
591
- <section
592
- class="shrink-0 bg-surface-containerLowest relative"
593
- style=${styleMap({ 'pointer-events': 'auto', height: `${FAB_HEIGHT}px` })}
378
+ <div
379
+ ${ref(this.headerRef)}
380
+ class=${fabClasses}
381
+ role="button"
382
+ tabindex="0"
383
+ aria-label="Open panel"
384
+ title="Drag to move · click to open"
594
385
  >
595
- <!-- 1px top inner highlight — reads as a lit edge when open, instrument-panel HUD accent -->
596
- ${when(
597
- this.open,
598
- () => html`<div
599
- class="absolute inset-x-0 top-0 h-px bg-linear-to-r from-transparent via-primary-default/40 to-transparent pointer-events-none"
600
- ></div>`,
601
- )}
602
- <div
603
- ${ref(this._headerRef)}
604
- class=${headerClasses}
605
- title="Drag to move"
606
- aria-label="Drag to reposition panel"
607
- >
608
- <!-- Grip indicator: only visible when collapsed, signals "this is a handle" -->
609
- ${when(
610
- !this.open,
611
- () => html`<div
612
- class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-6 h-0.5 rounded-full bg-on-surface/20 pointer-events-none"
613
- style="z-index:0"
614
- ></div>`,
615
- )}
616
-
617
- <!-- Summary slot rendered once — avoids DOM teardown on toggle -->
618
- <div class="flex-1 min-w-0 relative" style="z-index:1">
619
- <slot name="summary"></slot>
620
- </div>
621
-
622
- <!-- Toggle button: chevron up/down matches open/close direction per corner -->
623
- ${when(
624
- this.open,
625
- () => html`
626
- <schmancy-icon-button
627
- size="sm"
628
- variant="text"
629
- @click=${(e: Event) => {
630
- e.stopPropagation()
631
- this.close()
632
- }}
633
- title="Collapse"
634
- >
635
- ${isBottom ? 'expand_more' : 'expand_less'}
636
- </schmancy-icon-button>
637
- `,
638
- () => html`
639
- <schmancy-icon-button
640
- size="sm"
641
- variant="text"
642
- @click=${(e: Event) => {
643
- e.stopPropagation()
644
- this.expand()
645
- }}
646
- title="Expand"
647
- >
648
- ${isBottom ? 'expand_less' : 'expand_more'}
649
- </schmancy-icon-button>
650
- `,
651
- )}
652
- </div>
653
- </section>
386
+ <slot name="header"></slot>
387
+ <slot name="summary"></slot>
388
+ </div>
389
+
390
+ <!-- Default-slot content parks here (hidden) while collapsed;
391
+ relocated into the show() overlay on open. -->
392
+ <div hidden><slot></slot></div>
654
393
  </schmancy-surface>
655
394
  `
656
395
  }