@mhmo91/schmancy 0.10.34 → 0.10.36
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.
- package/custom-elements.json +1144 -1101
- package/dist/SchmancyElement-BBzRWB1w.cjs +2 -0
- package/dist/SchmancyElement-BBzRWB1w.cjs.map +1 -0
- package/dist/SchmancyElement-C3CpdNsi.js +284 -0
- package/dist/SchmancyElement-C3CpdNsi.js.map +1 -0
- package/dist/agent/schmancy.agent.js +3414 -3263
- package/dist/agent/schmancy.agent.js.map +1 -1
- package/dist/agent/schmancy.manifest.json +335 -276
- package/dist/{area-DviXdbDx.js → area-BA96mwFY.js} +2 -2
- package/dist/{area-DviXdbDx.js.map → area-BA96mwFY.js.map} +1 -1
- package/dist/{area-CTSTgjlx.cjs → area-DtyQDdOF.cjs} +1 -1
- package/dist/{area-CTSTgjlx.cjs.map → area-DtyQDdOF.cjs.map} +1 -1
- package/dist/area.cjs +1 -1
- package/dist/area.js +1 -1
- package/dist/{audio-Q9oB_cQR.cjs → audio-B_jT9Xr7.cjs} +1 -1
- package/dist/{audio-Q9oB_cQR.cjs.map → audio-B_jT9Xr7.cjs.map} +1 -1
- package/dist/{audio-DFYoaw0M.js → audio-D52h1jAT.js} +1 -1
- package/dist/{audio-DFYoaw0M.js.map → audio-D52h1jAT.js.map} +1 -1
- package/dist/audio.cjs +1 -1
- package/dist/audio.js +2 -2
- package/dist/{autocomplete-DmLXJr7C.cjs → autocomplete-Bts5Jwwr.cjs} +1 -1
- package/dist/{autocomplete-DmLXJr7C.cjs.map → autocomplete-Bts5Jwwr.cjs.map} +1 -1
- package/dist/{autocomplete-BDvuma6D.js → autocomplete-CI4QJXAN.js} +3 -3
- package/dist/{autocomplete-BDvuma6D.js.map → autocomplete-CI4QJXAN.js.map} +1 -1
- package/dist/autocomplete.cjs +1 -1
- package/dist/autocomplete.js +1 -1
- package/dist/avatar.cjs +1 -1
- package/dist/avatar.js +3 -3
- package/dist/badge.cjs +1 -1
- package/dist/badge.js +1 -1
- package/dist/boat-I4B1UNMc.cjs +34 -0
- package/dist/boat-I4B1UNMc.cjs.map +1 -0
- package/dist/boat-_N1x5U_3.js +191 -0
- package/dist/boat-_N1x5U_3.js.map +1 -0
- package/dist/boat.cjs +1 -1
- package/dist/boat.js +1 -1
- package/dist/breadcrumb.cjs +1 -1
- package/dist/breadcrumb.js +2 -2
- package/dist/{busy-CgzZbGfx.cjs → busy-BIUonyPk.cjs} +1 -1
- package/dist/{busy-CgzZbGfx.cjs.map → busy-BIUonyPk.cjs.map} +1 -1
- package/dist/{busy-DgQ4ux5N.js → busy-CCB3qKnh.js} +2 -2
- package/dist/{busy-DgQ4ux5N.js.map → busy-CCB3qKnh.js.map} +1 -1
- package/dist/busy.cjs +1 -1
- package/dist/busy.js +1 -1
- package/dist/{button-qbN1muQ0.js → button-C89bPnHt.js} +2 -2
- package/dist/{button-qbN1muQ0.js.map → button-C89bPnHt.js.map} +1 -1
- package/dist/{button-DFvR1iXX.cjs → button-CkwQH-g3.cjs} +1 -1
- package/dist/{button-DFvR1iXX.cjs.map → button-CkwQH-g3.cjs.map} +1 -1
- package/dist/button.cjs +4 -4
- package/dist/button.cjs.map +1 -1
- package/dist/button.js +16 -22
- package/dist/button.js.map +1 -1
- package/dist/{card-D_GlwZ5q.cjs → card-BO93_oxQ.cjs} +1 -1
- package/dist/{card-D_GlwZ5q.cjs.map → card-BO93_oxQ.cjs.map} +1 -1
- package/dist/{card-DAbr-7Vy.js → card-CFsCgJKZ.js} +2 -2
- package/dist/{card-DAbr-7Vy.js.map → card-CFsCgJKZ.js.map} +1 -1
- package/dist/card.cjs +1 -1
- package/dist/card.js +1 -1
- package/dist/{checkbox-BNORaxMF.js → checkbox-Bh7q0djq.js} +2 -2
- package/dist/{checkbox-BNORaxMF.js.map → checkbox-Bh7q0djq.js.map} +1 -1
- package/dist/{checkbox-BUY_uc_r.cjs → checkbox-CFUBUFtW.cjs} +1 -1
- package/dist/{checkbox-BUY_uc_r.cjs.map → checkbox-CFUBUFtW.cjs.map} +1 -1
- package/dist/checkbox.cjs +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/{chips-Dg6Lk6BT.js → chips-6YaoRmeG.js} +145 -122
- package/dist/chips-6YaoRmeG.js.map +1 -0
- package/dist/{chips-CXZ4dJCK.cjs → chips-BfzpsyV1.cjs} +44 -33
- package/dist/chips-BfzpsyV1.cjs.map +1 -0
- package/dist/chips.cjs +1 -1
- package/dist/chips.js +2 -2
- package/dist/connectivity.cjs +1 -1
- package/dist/connectivity.js +3 -3
- package/dist/content-drawer.cjs +1 -1
- package/dist/content-drawer.js +1 -1
- package/dist/{date-range-BU6WX7d5.js → date-range-CEo_Kjqw.js} +129 -137
- package/dist/date-range-CEo_Kjqw.js.map +1 -0
- package/dist/{date-range-C-_be3_E.cjs → date-range-N-A249O9.cjs} +25 -19
- package/dist/date-range-N-A249O9.cjs.map +1 -0
- package/dist/{date-range-inline-7o7xtVIu.js → date-range-inline-BwialV9j.js} +2 -2
- package/dist/{date-range-inline-7o7xtVIu.js.map → date-range-inline-BwialV9j.js.map} +1 -1
- package/dist/{date-range-inline-DJtUmHKF.cjs → date-range-inline-DFopysWF.cjs} +1 -1
- package/dist/{date-range-inline-DJtUmHKF.cjs.map → date-range-inline-DFopysWF.cjs.map} +1 -1
- package/dist/date-range-inline.cjs +1 -1
- package/dist/date-range-inline.js +1 -1
- package/dist/date-range.cjs +1 -1
- package/dist/date-range.js +1 -1
- package/dist/delay.cjs +1 -1
- package/dist/delay.js +2 -2
- package/dist/{details-Bs0MyyvF.cjs → details-BLRPV8sY.cjs} +1 -1
- package/dist/{details-Bs0MyyvF.cjs.map → details-BLRPV8sY.cjs.map} +1 -1
- package/dist/{details-EfbDPVEo.js → details-GtpfI2hA.js} +2 -2
- package/dist/{details-EfbDPVEo.js.map → details-GtpfI2hA.js.map} +1 -1
- package/dist/details.cjs +1 -1
- package/dist/details.js +1 -1
- package/dist/{directives-zi1Mm2er.js → directives-C2dXgpCY.js} +13 -6
- package/dist/directives-C2dXgpCY.js.map +1 -0
- package/dist/{directives-fLwDj6b0.cjs → directives-CvYGSW_a.cjs} +2 -2
- package/dist/directives-CvYGSW_a.cjs.map +1 -0
- package/dist/directives.cjs +1 -1
- package/dist/directives.js +2 -2
- package/dist/{divider-CEPfrIwe.js → divider-D0pGX2VB.js} +2 -2
- package/dist/{divider-CEPfrIwe.js.map → divider-D0pGX2VB.js.map} +1 -1
- package/dist/{divider-CdIsWZrM.cjs → divider-rNsWCvMi.cjs} +1 -1
- package/dist/{divider-CdIsWZrM.cjs.map → divider-rNsWCvMi.cjs.map} +1 -1
- package/dist/divider.cjs +1 -1
- package/dist/divider.js +1 -1
- package/dist/dropdown.cjs +1 -1
- package/dist/dropdown.js +2 -2
- package/dist/{expand-g1vqqUp1.js → expand-FcKAzJta.js} +3 -3
- package/dist/{expand-g1vqqUp1.js.map → expand-FcKAzJta.js.map} +1 -1
- package/dist/{expand--at1k3qo.cjs → expand-tffQHGbZ.cjs} +1 -1
- package/dist/{expand--at1k3qo.cjs.map → expand-tffQHGbZ.cjs.map} +1 -1
- package/dist/expand.cjs +1 -1
- package/dist/expand.js +1 -1
- package/dist/fab.cjs +77 -0
- package/dist/fab.cjs.map +1 -0
- package/dist/fab.js +151 -0
- package/dist/fab.js.map +1 -0
- package/dist/{float-P9HukAm-.cjs → float-CDjgxWyy.cjs} +1 -1
- package/dist/{float-P9HukAm-.cjs.map → float-CDjgxWyy.cjs.map} +1 -1
- package/dist/{float-DxVzgI9o.js → float-CQ1WEp3M.js} +2 -2
- package/dist/{float-DxVzgI9o.js.map → float-CQ1WEp3M.js.map} +1 -1
- package/dist/float.cjs +1 -1
- package/dist/float.js +1 -1
- package/dist/{form-CqLaozHp.js → form-H24puioV.js} +3 -3
- package/dist/{form-CqLaozHp.js.map → form-H24puioV.js.map} +1 -1
- package/dist/{form-ByYhXe1p.cjs → form-VYhbbir3.cjs} +1 -1
- package/dist/{form-ByYhXe1p.cjs.map → form-VYhbbir3.cjs.map} +1 -1
- package/dist/form.cjs +6 -6
- package/dist/form.cjs.map +1 -1
- package/dist/form.js +25 -23
- package/dist/form.js.map +1 -1
- package/dist/handover/agent-runtime-followups.md +1 -1
- package/dist/handover/agent-runtime-v1.md +3 -3
- package/dist/{icons-DYtiRU5V.cjs → icons-B_a1HStW.cjs} +1 -1
- package/dist/{icons-DYtiRU5V.cjs.map → icons-B_a1HStW.cjs.map} +1 -1
- package/dist/{icons-CkphcMp6.js → icons-DBxfN91B.js} +2 -2
- package/dist/{icons-CkphcMp6.js.map → icons-DBxfN91B.js.map} +1 -1
- package/dist/icons.cjs +1 -1
- package/dist/icons.js +1 -1
- package/dist/{iframe-CjqJksl8.js → iframe-BDVElN8z.js} +2 -2
- package/dist/{iframe-CjqJksl8.js.map → iframe-BDVElN8z.js.map} +1 -1
- package/dist/{iframe-C3trkP8q.cjs → iframe-CG-z9qev.cjs} +1 -1
- package/dist/{iframe-C3trkP8q.cjs.map → iframe-CG-z9qev.cjs.map} +1 -1
- package/dist/iframe.cjs +1 -1
- package/dist/iframe.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +57 -56
- package/dist/{input-DuavpwNL.cjs → input-B14Nn6xD.cjs} +1 -1
- package/dist/{input-DuavpwNL.cjs.map → input-B14Nn6xD.cjs.map} +1 -1
- package/dist/{input-CG51zDVh.js → input-Bt_o4sYo.js} +2 -2
- package/dist/{input-CG51zDVh.js.map → input-Bt_o4sYo.js.map} +1 -1
- package/dist/{input-chip-C6Lq1927.js → input-chip-DEqO0DXc.js} +2 -2
- package/dist/input-chip-DEqO0DXc.js.map +1 -0
- package/dist/{input-chip-57tgNXKT.cjs → input-chip-ugYu9Fn9.cjs} +1 -1
- package/dist/input-chip-ugYu9Fn9.cjs.map +1 -0
- package/dist/input.cjs +1 -1
- package/dist/input.js +1 -1
- package/dist/json.cjs +1 -1
- package/dist/json.js +3 -3
- package/dist/kbd.cjs +1 -1
- package/dist/kbd.js +2 -2
- package/dist/{layout-D4IOwx7p.js → layout-BJ_43VrH.js} +1 -1
- package/dist/{layout-D4IOwx7p.js.map → layout-BJ_43VrH.js.map} +1 -1
- package/dist/{layout-6ipbiWTl.cjs → layout-DF9ZaQ-b.cjs} +1 -1
- package/dist/{layout-6ipbiWTl.cjs.map → layout-DF9ZaQ-b.cjs.map} +1 -1
- package/dist/layout.cjs +1 -1
- package/dist/layout.js +2 -2
- package/dist/{lightbox-H8pVWGMX.cjs → lightbox-B47Zoqv-.cjs} +1 -1
- package/dist/{lightbox-H8pVWGMX.cjs.map → lightbox-B47Zoqv-.cjs.map} +1 -1
- package/dist/{lightbox-CsyO2XSr.js → lightbox-ZmuoBBFT.js} +2 -2
- package/dist/{lightbox-CsyO2XSr.js.map → lightbox-ZmuoBBFT.js.map} +1 -1
- package/dist/lightbox.cjs +1 -1
- package/dist/lightbox.js +1 -1
- package/dist/{list-BAwH0pQW.js → list-C47xzld_.js} +2 -2
- package/dist/{list-BAwH0pQW.js.map → list-C47xzld_.js.map} +1 -1
- package/dist/{list-Bs9m8kw7.cjs → list-CaSWrlG2.cjs} +1 -1
- package/dist/{list-Bs9m8kw7.cjs.map → list-CaSWrlG2.cjs.map} +1 -1
- package/dist/list.cjs +1 -1
- package/dist/list.js +1 -1
- package/dist/{menu-tQVARVaC.js → menu-8RObM6Ie.js} +3 -3
- package/dist/{menu-tQVARVaC.js.map → menu-8RObM6Ie.js.map} +1 -1
- package/dist/{menu-BMcGzj1h.cjs → menu-Jpsy85SX.cjs} +1 -1
- package/dist/{menu-BMcGzj1h.cjs.map → menu-Jpsy85SX.cjs.map} +1 -1
- package/dist/menu.cjs +1 -1
- package/dist/menu.js +1 -1
- package/dist/{mixins-CGXSzZc7.cjs → mixins-DPdzC9ZH.cjs} +1 -1
- package/dist/{mixins-CGXSzZc7.cjs.map → mixins-DPdzC9ZH.cjs.map} +1 -1
- package/dist/{mixins-Bp0wIHg2.js → mixins-DTzfFVyv.js} +1 -1
- package/dist/{mixins-Bp0wIHg2.js.map → mixins-DTzfFVyv.js.map} +1 -1
- package/dist/mixins.cjs +1 -1
- package/dist/mixins.js +2 -2
- package/dist/nav-drawer.cjs +1 -1
- package/dist/nav-drawer.js +1 -1
- package/dist/navigation-bar.cjs +1 -1
- package/dist/navigation-bar.js +1 -1
- package/dist/navigation-rail.cjs +1 -1
- package/dist/navigation-rail.js +2 -2
- package/dist/{notification-D1tX2nx5.js → notification-Ccktcj9H.js} +4 -4
- package/dist/{notification-D1tX2nx5.js.map → notification-Ccktcj9H.js.map} +1 -1
- package/dist/{notification-Bz00zdpV.cjs → notification-DSkB-sn0.cjs} +1 -1
- package/dist/{notification-Bz00zdpV.cjs.map → notification-DSkB-sn0.cjs.map} +1 -1
- package/dist/notification.cjs +1 -1
- package/dist/notification.js +1 -1
- package/dist/{option-BnybLEDO.cjs → option-0aNiVB3Q.cjs} +1 -1
- package/dist/{option-BnybLEDO.cjs.map → option-0aNiVB3Q.cjs.map} +1 -1
- package/dist/{option-BpGV8Apj.js → option-CkMxwBqU.js} +2 -2
- package/dist/{option-BpGV8Apj.js.map → option-CkMxwBqU.js.map} +1 -1
- package/dist/option.cjs +1 -1
- package/dist/option.js +1 -1
- package/dist/{overlay-UQR2Dy3u.cjs → overlay-BS-ta-zq.cjs} +5 -5
- package/dist/overlay-BS-ta-zq.cjs.map +1 -0
- package/dist/{overlay-BpNhd74N.js → overlay-H3Wt_dgQ.js} +108 -108
- package/dist/overlay-H3Wt_dgQ.js.map +1 -0
- package/dist/overlay.cjs +1 -1
- package/dist/{overlay.confirm-body-CVDtVk5X.cjs → overlay.confirm-body-CR9xaqOE.cjs} +1 -1
- package/dist/{overlay.confirm-body-CVDtVk5X.cjs.map → overlay.confirm-body-CR9xaqOE.cjs.map} +1 -1
- package/dist/{overlay.confirm-body-BHcXu5Wk.js → overlay.confirm-body-Dxn_wNm3.js} +6 -6
- package/dist/{overlay.confirm-body-BHcXu5Wk.js.map → overlay.confirm-body-Dxn_wNm3.js.map} +1 -1
- package/dist/overlay.js +3 -3
- package/dist/{overlay.service-DTE6NwIM.js → overlay.service-C46kOtUi.js} +2 -2
- package/dist/{overlay.service-DTE6NwIM.js.map → overlay.service-C46kOtUi.js.map} +1 -1
- package/dist/{overlay.service-C8RsQzgM.cjs → overlay.service-DEj3rfRr.cjs} +1 -1
- package/dist/{overlay.service-C8RsQzgM.cjs.map → overlay.service-DEj3rfRr.cjs.map} +1 -1
- package/dist/{progress-CAKsxp29.js → progress-BK7gSq8j.js} +2 -2
- package/dist/{progress-CAKsxp29.js.map → progress-BK7gSq8j.js.map} +1 -1
- package/dist/{progress-gbIALDRs.cjs → progress-zs18GR6C.cjs} +1 -1
- package/dist/{progress-gbIALDRs.cjs.map → progress-zs18GR6C.cjs.map} +1 -1
- package/dist/progress.cjs +1 -1
- package/dist/progress.js +1 -1
- package/dist/{radio-group-otyvZvUk.js → radio-group-1HCpzRUB.js} +2 -2
- package/dist/{radio-group-otyvZvUk.js.map → radio-group-1HCpzRUB.js.map} +1 -1
- package/dist/{radio-group-CfJ5DtI4.cjs → radio-group-DbYlyPc-.cjs} +1 -1
- package/dist/{radio-group-CfJ5DtI4.cjs.map → radio-group-DbYlyPc-.cjs.map} +1 -1
- package/dist/radio-group.cjs +1 -1
- package/dist/radio-group.js +1 -1
- package/dist/range.cjs +1 -1
- package/dist/range.js +2 -2
- package/dist/{select-81jniVTs.cjs → select-B-SSmUDe.cjs} +1 -1
- package/dist/{select-81jniVTs.cjs.map → select-B-SSmUDe.cjs.map} +1 -1
- package/dist/{select-9vXx1fhr.js → select-CEyhNtZ2.js} +3 -3
- package/dist/{select-9vXx1fhr.js.map → select-CEyhNtZ2.js.map} +1 -1
- package/dist/select.cjs +1 -1
- package/dist/select.js +1 -1
- package/dist/skeleton.cjs +1 -1
- package/dist/skeleton.js +2 -2
- package/dist/skills/INDEX.md +1 -1
- package/dist/skills/SKILL.md +6 -7
- package/dist/skills/boat.md +21 -15
- package/dist/skills/fab.md +75 -0
- package/dist/skills/schmancy/INDEX.md +1 -1
- package/dist/skills/schmancy/SKILL.md +6 -7
- package/dist/skills/schmancy/boat.md +21 -15
- package/dist/skills/schmancy/fab.md +75 -0
- package/dist/skills/schmancy/theme.md +1 -1
- package/dist/skills/theme.md +1 -1
- package/dist/slider.cjs +1 -1
- package/dist/slider.js +2 -2
- package/dist/{sound.service-D3ZSq1Kj.js → sound.service-DO4SmUUT.js} +1 -1
- package/dist/{sound.service-D3ZSq1Kj.js.map → sound.service-DO4SmUUT.js.map} +1 -1
- package/dist/{sound.service-CmIw63aM.cjs → sound.service-G_8GV_6L.cjs} +1 -1
- package/dist/{sound.service-CmIw63aM.cjs.map → sound.service-G_8GV_6L.cjs.map} +1 -1
- package/dist/{splash-screen-BOjrmGLk.js → splash-screen-B1mM4_xz.js} +2 -2
- package/dist/{splash-screen-BOjrmGLk.js.map → splash-screen-B1mM4_xz.js.map} +1 -1
- package/dist/{splash-screen-C5KAWXvA.cjs → splash-screen-cbz4bxjB.cjs} +1 -1
- package/dist/{splash-screen-C5KAWXvA.cjs.map → splash-screen-cbz4bxjB.cjs.map} +1 -1
- package/dist/splash-screen.cjs +1 -1
- package/dist/splash-screen.js +1 -1
- package/dist/{src-Bm1vop0l.cjs → src-czeiuT1m.cjs} +1 -1
- package/dist/{src-Bm1vop0l.cjs.map → src-czeiuT1m.cjs.map} +1 -1
- package/dist/{src-DoOhMBtI.js → src-tncsWsTY.js} +36 -35
- package/dist/{src-DoOhMBtI.js.map → src-tncsWsTY.js.map} +1 -1
- package/dist/{state-Cex3rmx2.cjs → state-Cx0aoL5e.cjs} +1 -1
- package/dist/{state-Cex3rmx2.cjs.map → state-Cx0aoL5e.cjs.map} +1 -1
- package/dist/{state-CWBRTSvE.js → state-DJDp3N7J.js} +1 -1
- package/dist/{state-CWBRTSvE.js.map → state-DJDp3N7J.js.map} +1 -1
- package/dist/state.cjs +1 -1
- package/dist/state.js +2 -2
- package/dist/steps.cjs +1 -1
- package/dist/steps.js +2 -2
- package/dist/{surface-PfiejLuw.cjs → surface-C3cxTcJD.cjs} +1 -1
- package/dist/{surface-PfiejLuw.cjs.map → surface-C3cxTcJD.cjs.map} +1 -1
- package/dist/{surface-9S5scTsD.js → surface-CYBl8_a3.js} +2 -2
- package/dist/{surface-9S5scTsD.js.map → surface-CYBl8_a3.js.map} +1 -1
- package/dist/surface.cjs +1 -1
- package/dist/surface.js +1 -1
- package/dist/switch.cjs +1 -1
- package/dist/switch.js +2 -2
- package/dist/table.cjs +1 -1
- package/dist/table.js +2 -2
- package/dist/{tabs-BBOjAmgG.js → tabs-DHy93Q3N.js} +2 -2
- package/dist/{tabs-BBOjAmgG.js.map → tabs-DHy93Q3N.js.map} +1 -1
- package/dist/{tabs-uYvb1P06.cjs → tabs-ORQ_Zd43.cjs} +1 -1
- package/dist/{tabs-uYvb1P06.cjs.map → tabs-ORQ_Zd43.cjs.map} +1 -1
- package/dist/tabs.cjs +1 -1
- package/dist/tabs.js +1 -1
- package/dist/teleport.cjs +1 -1
- package/dist/teleport.js +1 -1
- package/dist/{textarea-YPHX4g7Y.cjs → textarea-CEUaDURR.cjs} +1 -1
- package/dist/{textarea-YPHX4g7Y.cjs.map → textarea-CEUaDURR.cjs.map} +1 -1
- package/dist/{textarea-QzSj8Dkl.js → textarea-DHIMt-ly.js} +2 -2
- package/dist/{textarea-QzSj8Dkl.js.map → textarea-DHIMt-ly.js.map} +1 -1
- package/dist/textarea.cjs +1 -1
- package/dist/textarea.js +1 -1
- package/dist/theme-CJpjkqHr.cjs +181 -0
- package/dist/{theme-iKUaS9JB.cjs.map → theme-CJpjkqHr.cjs.map} +1 -1
- package/dist/{theme-C2Mp-VGt.js → theme-CgI9PRco.js} +6 -5
- package/dist/{theme-C2Mp-VGt.js.map → theme-CgI9PRco.js.map} +1 -1
- package/dist/{theme-button-CJmhxfMe.cjs → theme-button--FuBkuVr.cjs} +1 -1
- package/dist/{theme-button-CJmhxfMe.cjs.map → theme-button--FuBkuVr.cjs.map} +1 -1
- package/dist/{theme-button-DGWAXhzd.js → theme-button-D-FXb3oO.js} +2 -2
- package/dist/{theme-button-DGWAXhzd.js.map → theme-button-D-FXb3oO.js.map} +1 -1
- package/dist/theme-button.cjs +1 -1
- package/dist/theme-button.js +1 -1
- package/dist/theme.cjs +1 -1
- package/dist/theme.js +3 -3
- package/dist/{theme.service-hc4N-1Oz.js → theme.service-BfTK1Wtl.js} +1 -1
- package/dist/{theme.service-hc4N-1Oz.js.map → theme.service-BfTK1Wtl.js.map} +1 -1
- package/dist/{theme.service-p61RsJBF.cjs → theme.service-Dg7LO0Qz.cjs} +1 -1
- package/dist/{theme.service-p61RsJBF.cjs.map → theme.service-Dg7LO0Qz.cjs.map} +1 -1
- package/dist/tree.cjs +1 -1
- package/dist/tree.js +2 -2
- package/dist/{typography-DwV0sqht.js → typography-BEGLfHwz.js} +2 -2
- package/dist/{typography-DwV0sqht.js.map → typography-BEGLfHwz.js.map} +1 -1
- package/dist/{typography-Bdt8RlX2.cjs → typography-CxA3sx9B.cjs} +1 -1
- package/dist/{typography-Bdt8RlX2.cjs.map → typography-CxA3sx9B.cjs.map} +1 -1
- package/dist/typography.cjs +1 -1
- package/dist/typography.js +1 -1
- package/dist/visually-hidden.cjs +1 -1
- package/dist/visually-hidden.js +2 -2
- package/dist/{window-n4jN60B_.js → window-B_n4P9az.js} +3 -3
- package/dist/{window-n4jN60B_.js.map → window-B_n4P9az.js.map} +1 -1
- package/dist/{window-D2WfvNng.cjs → window-Vl1u1-EG.cjs} +1 -1
- package/dist/{window-D2WfvNng.cjs.map → window-Vl1u1-EG.cjs.map} +1 -1
- package/dist/window.cjs +1 -1
- package/dist/window.js +1 -1
- package/package.json +1 -1
- package/skills/schmancy/INDEX.md +1 -1
- package/skills/schmancy/SKILL.md +6 -7
- package/skills/schmancy/boat.md +21 -15
- package/skills/schmancy/fab.md +75 -0
- package/skills/schmancy/theme.md +1 -1
- package/src/CLAUDE.md +22 -16
- package/src/boat/boat.test.ts +130 -0
- package/src/boat/boat.ts +192 -186
- package/src/button/icon-button.ts +18 -30
- package/src/chips/assist-chip.ts +2 -263
- package/src/chips/chips.ts +2 -259
- package/src/chips/filter-chip.ts +2 -255
- package/src/chips/index.ts +2 -5
- package/src/chips/input-chip.ts +2 -413
- package/src/chips/suggestion-chip.ts +2 -266
- package/src/directives/fill.ts +28 -5
- package/src/fab/fab.test.ts +101 -0
- package/src/fab/fab.ts +226 -0
- package/src/fab/index.ts +1 -0
- package/src/form/fields/chips/assist-chip.ts +263 -0
- package/src/form/fields/chips/chips.ts +234 -0
- package/src/form/fields/chips/filter-chip.ts +255 -0
- package/src/form/fields/chips/index.ts +5 -0
- package/src/form/fields/chips/input-chip.ts +413 -0
- package/src/form/fields/chips/suggestion-chip.ts +266 -0
- package/src/form/fields/date-range/date-range.test.ts +44 -0
- package/src/form/fields/date-range/date-range.ts +103 -97
- package/src/form/fields/index.ts +1 -0
- package/src/index.ts +2 -1
- package/src/overlay/overlay.animations.ts +2 -3
- package/src/overlay/overlay.component.ts +8 -4
- package/src/overlay/overlay.types.ts +14 -2
- package/src/theme/theme.component.ts +1 -0
- package/src/theme/theme.style.css +3 -0
- package/types/src/boat/boat.d.ts +40 -25
- package/types/src/boat/boat.test.d.ts +2 -0
- package/types/src/button/icon-button.d.ts +3 -2
- package/types/src/chips/assist-chip.d.ts +1 -47
- package/types/src/chips/chips.d.ts +1 -43
- package/types/src/chips/filter-chip.d.ts +1 -67
- package/types/src/chips/index.d.ts +1 -5
- package/types/src/chips/input-chip.d.ts +1 -82
- package/types/src/chips/suggestion-chip.d.ts +1 -52
- package/types/src/fab/fab.d.ts +80 -0
- package/types/src/fab/fab.test.d.ts +2 -0
- package/types/src/fab/index.d.ts +1 -0
- package/types/src/form/fields/chips/assist-chip.d.ts +47 -0
- package/types/src/form/fields/chips/chips.d.ts +35 -0
- package/types/src/form/fields/chips/filter-chip.d.ts +67 -0
- package/types/src/form/fields/chips/index.d.ts +5 -0
- package/types/src/form/fields/chips/input-chip.d.ts +82 -0
- package/types/src/form/fields/chips/suggestion-chip.d.ts +52 -0
- package/types/src/form/fields/date-range/date-range.d.ts +5 -10
- package/types/src/form/fields/index.d.ts +1 -0
- package/types/src/index.d.ts +2 -1
- package/types/src/overlay/overlay.component.d.ts +1 -0
- package/types/src/overlay/overlay.types.d.ts +12 -2
- package/types/src/theme/theme.component.d.ts +1 -0
- package/dist/SchmancyElement-CA0Wqt8m.js +0 -284
- package/dist/SchmancyElement-CA0Wqt8m.js.map +0 -1
- package/dist/SchmancyElement-CYIif26I.cjs +0 -2
- package/dist/SchmancyElement-CYIif26I.cjs.map +0 -1
- package/dist/boat-BgpWcLnV.cjs +0 -38
- package/dist/boat-BgpWcLnV.cjs.map +0 -1
- package/dist/boat-Y5UMiJCV.js +0 -216
- package/dist/boat-Y5UMiJCV.js.map +0 -1
- package/dist/chips-CXZ4dJCK.cjs.map +0 -1
- package/dist/chips-Dg6Lk6BT.js.map +0 -1
- package/dist/date-range-BU6WX7d5.js.map +0 -1
- package/dist/date-range-C-_be3_E.cjs.map +0 -1
- package/dist/directives-fLwDj6b0.cjs.map +0 -1
- package/dist/directives-zi1Mm2er.js.map +0 -1
- package/dist/input-chip-57tgNXKT.cjs.map +0 -1
- package/dist/input-chip-C6Lq1927.js.map +0 -1
- package/dist/overlay-BpNhd74N.js.map +0 -1
- package/dist/overlay-UQR2Dy3u.cjs.map +0 -1
- package/dist/theme-iKUaS9JB.cjs +0 -181
package/skills/schmancy/SKILL.md
CHANGED
|
@@ -56,9 +56,9 @@ Use component tags (`<schmancy-menu>`, `<schmancy-dropdown>`, `<schmancy-tooltip
|
|
|
56
56
|
|
|
57
57
|
## Composition
|
|
58
58
|
|
|
59
|
-
- **Audit by grep** (`AUDIT_BY_GREP`). An agent's compliance report on a file under a rule is the list of file:line citations of the rule's forbidden patterns; an empty list is compliance. The rule applies to every other rule in this skill (`PRIMITIVE_FIRST`, `
|
|
60
|
-
Sources: each rule above names its forbidden patterns explicitly — `
|
|
61
|
-
Remediation: before reporting any file compliant, run a grep against each forbidden pattern named by the rule under audit (e.g. `grep -nE '
|
|
59
|
+
- **Audit by grep** (`AUDIT_BY_GREP`). An agent's compliance report on a file under a rule is the list of file:line citations of the rule's forbidden patterns; an empty list is compliance. The rule applies to every other rule in this skill (`PRIMITIVE_FIRST`, `ARBITRARY_VALUE_CANONICAL_TOKEN_ON_REUSE`, `NO_LOCAL_CLASS_CSS`, `NO_TERNARY_NOTHING_DISPATCH`): a claim that a file complies is a claim about what the file does NOT contain, and that claim is verified by enumerating the rule's forbidden patterns and grepping each one.
|
|
60
|
+
Sources: each rule above names its forbidden patterns explicitly — `ARBITRARY_VALUE_CANONICAL_TOKEN_ON_REUSE` forbids a single-value `--<namespace>-x` `@theme` alias (the portable `[...]` arbitrary value is canonical, not forbidden); `PRIMITIVE_FIRST` forbids raw HTML elements whose class attribute carries design-system styling (typography/color/surface/spacing-as-design); `NO_LOCAL_CLASS_CSS` forbids class/id/attribute selectors inside the `css` template; `NO_TERNARY_NOTHING_DISPATCH` forbids `${cond ? html\`...\` : nothing}` and `${cond && html\`...\`}` patterns.
|
|
61
|
+
Remediation: before reporting any file compliant, run a grep against each forbidden pattern named by the rule under audit (e.g. `grep -nE '^\s*--[a-z-]+:' web/src/styles.css owl/src/**/styles.css` for single-value `@theme` aliases under `ARBITRARY_VALUE_CANONICAL_TOKEN_ON_REUSE`; `grep -nE 'class="[^"]*\b(text-|bg-|border-|rounded-|shadow-|tracking-|leading-|p[xy]?-)' <file>` plus a manual scan for raw `<div>`/`<span>` carrying those classes for `PRIMITIVE_FIRST`). The compliance report's body is the concatenation of those grep outputs annotated with their rule name; an empty body across every pattern under every rule is the only form of "compliant". A claim of compliance unaccompanied by the grep evidence is not a compliance report and is treated as an unverified assertion that the audit loop rejects.
|
|
62
62
|
- **Schmancy primitive first** (`PRIMITIVE_FIRST`). Within `web/**`, every visible UI element is a custom element exported from `packages/schmancy/src/**`, and an element absent from that export set is added there before being imported into `web/**`. The rule sits above the styling rules: a `<div class="text-xs text-surface-on-variant">…</div>` whose role is typography is a violation even when every utility resolves to a registered token, because `<schmancy-typography>` already covers that role; the styling rules apply only to whatever class strings remain after the right primitive has been selected.
|
|
63
63
|
Sources: [packages/schmancy/skills/schmancy/INDEX.md](../INDEX.md) catalogues the export set by job (foundations / atoms / forms / navigation / overlays / interaction / feedback / display); each role's reference file (`typography.md`, `surface.md`, `button.md`, `overlay.md`, …) names the props, slots, and events that displace the equivalent `<div>` + utility-class pattern. The export set is the single source — a primitive that is not exported from `packages/schmancy/src/**` does not satisfy this rule even if it lives in a private file inside the schmancy tree.
|
|
64
64
|
Remediation: walk every `.ts` and `.html` file under `web/**` and list every raw HTML element whose class string carries design-system styling (typography, color, spacing-as-design-decision, surface, layout-as-design-decision, motion, overlay) — those are the violations. For each, look up the matching schmancy primitive in `INDEX.md` and rewrite the element through that primitive (`<schmancy-typography type=… token=…>` for type-scale text, `<schmancy-surface type=…>` for elevated/bounded surfaces (size with Tailwind utilities), `<schmancy-grid>`/`<schmancy-flex>` for layout primitives with design intent, the imperative `show`/`$notify`/`schmancyContentDrawer.push` services for overlays, `<schmancy-scroll>` for scroll containers). When a needed primitive is absent from the export set, design and implement it as a new component under `packages/schmancy/src/<role>/` — extending `SchmancyElement` with `static styles = [css\`...\`]`, registered in `HTMLElementTagNameMap`, exported through the package barrel, and documented with a sibling `.md` in the skill's reference set — and only then introduce the first call site in `web/**`. The audit subagent iterates the whole `web/**` tree, surfaces the violation list, applies the rewrites, runs `yarn workspace @momo/web tsc --noEmit` plus the colocated `*-view.test.ts` suites, and reports pre-existing violations that require a new schmancy primitive as a separate punch list for designer/architect approval before the implementation lands. The loop exits when every `web/**` file's visible UI elements are schmancy primitives and the typecheck plus the test suites pass.
|
|
@@ -113,10 +113,9 @@ When two components genuinely cannot share a signal (e.g., a generic reusable co
|
|
|
113
113
|
**Styling**
|
|
114
114
|
- Styling uses Tailwind and schmancy tokens. The `css` block in `static styles` contains only `:host` rules, `@keyframes`, and selectors targeting vendor pseudo-elements (`::-webkit-*`, `::-moz-*`). Other styling is set through Tailwind utility classes and schmancy theme tokens on the `class=` attribute. The `style=` attribute holds per-instance dynamic values only (e.g. `style="--tide: ${value}"`).
|
|
115
115
|
Remediation: move declarations to Tailwind on the `class=` attribute (`backdrop-filter: blur(20px)` → `backdrop-blur-xl`; `color-mix(in oklch, Canvas 72%, transparent)` → `bg-surface/70`; `border-radius: 14px` → `rounded-2xl`; `transition: opacity 80ms linear` → `transition-opacity duration-75 ease-linear`). When a visual pattern seems to want its own class (like `.glass`), check `INDEX.md` — schmancy likely ships the component.
|
|
116
|
-
-
|
|
117
|
-
- **
|
|
118
|
-
|
|
119
|
-
Remediation: list every `[...]` arbitrary-value utility in the changeset; for each whose value matches a `--<namespace>-*` variable, replace with the named utility (`bg-[#faf7f2]` → `bg-surface-containerLowest`, `max-w-[720px]` → `max-w-3xl`); for each whose value has no matching variable, register the variable in `packages/schmancy/src/theme/theme.style.css` first, then mirror the same `--<namespace>-x: …` declaration inside an `@theme {}` block in the consumer's stylesheet (e.g. `web/src/styles.css`) — schmancy ships the variable to its own shadow-DOM TailwindMixin, the consumer mirror lets Tailwind v4 generate the named utility for document-scope code. When the variable lives in both places but the utility class still does not apply inside a shadow-DOM component (the mixin's utility subset is frozen at schmancy build time, so consumer-introduced class names can't be added), bind the registered variable through an inline `style="<property>: var(--<namespace>-x);"` attribute on the element — the bracket-syntax rule is satisfied because no Tailwind arbitrary-value utility appears in the markup, and the `style=` attribute consuming a registered CSS custom property fits the per-instance dynamic-value clause of `NO_LOCAL_CLASS_CSS`. When the value's design rationale is one-off (a vendor-dictated pixel width, a single-use marketing graphic) the rule still requires a registered token — the alternative is to drop the value as a design violation.
|
|
116
|
+
- **Color is a theme token** (`COLOR_IS_A_THEME_TOKEN`). Every color a `web/src/**` element renders is the schmancy theme namespace surfaced as a Tailwind utility on `class=` (`text-error-default`, `bg-surface-container`, `border-outline-variant` — every `--schmancy-sys-color-*` auto-aliases to `--color-*`, which Tailwind v4 lifts into the full `bg-/text-/border-/ring-/fill-/stroke-` namespace) or a schmancy component that already carries the token (`<schmancy-surface type=…>`, `<schmancy-typography>`). A raw `#hex` / `rgb()` / `rgba()` / `hsl()` literal and an inline `var(--schmancy-sys-color-*)` inside a `style=` attribute name a color the theme already names — including inside `@keyframes` and animated backgrounds, where the animated property still references the token utility, not a hand-written value. Raw `var(--schmancy-sys-color-*)` lives only inside a component's own `static styles` `css` template (where Tailwind does not reach); a color literal in markup is admissible only with a written rationale for why no token in `theme.md` can express it. `theme.md` is the authoritative token catalog.
|
|
117
|
+
- **Arbitrary value is canonical; a token is earned by semantic reuse** (`ARBITRARY_VALUE_CANONICAL_TOKEN_ON_REUSE`). Within `web/src/**`, `owl/src/**`, and `packages/schmancy/src/**`, a trivial or one-off layout/size value is its portable Tailwind arbitrary utility (`grid-rows-[auto_1fr]`, `max-w-[720px]`) and stays there; a `--<namespace>-x` `@theme` alias of a single such value is the violation and is reverted to the portable form. A `--<namespace>-*` token earns existence only as a named design concept reused across call sites — the schmancy semantic color, type-scale, spacing, and motion namespaces (`COLOR_IS_A_THEME_TOKEN` owns the color half) — never as a one-value alias. An `@theme` token is visible only to the Tailwind build that compiles its stylesheet, so a `web/src/styles.css` token emits zero CSS in `owl/`; a `suggestCanonicalClasses`-style arbitrary-value→named-utility rewrite not backed by an `@theme` declaration in the edited workspace's own build is dead CSS, and the portable arbitrary form is kept.
|
|
118
|
+
- **Schmancy elements need no import in `web/src/**`** (`SCHMANCY_PLUGIN_REGISTERS`). The Vite plugin globally registers every schmancy custom element for the `web/` app; side-effect imports of individual subpaths (`import "@mhmo91/schmancy/badge"`, `import "@mhmo91/schmancy/icon"`, etc.) inside `web/src/**` are redundant and fail with TS2882. Use the tag directly in templates.
|
|
120
119
|
- No `setTimeout` / `setInterval` / `addEventListener` — use RxJS (`timer`, `interval`, `fromEvent`).
|
|
121
120
|
|
|
122
121
|
**Accessibility (combobox forms)**
|
package/skills/schmancy/boat.md
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
# schmancy-boat
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Corner-anchored launcher that opens its panel via the `show()` overlay service. Three slots, three non-overlapping intents — **no element-type sniffing**. The collapsed launcher's size, padding, radius and spacing are the consumer's; the boat owns drag, corner-snapping, position persistence and the glass surface.
|
|
4
4
|
|
|
5
|
-
> **Note:** `schmancy-window` is the evolved successor with more capabilities (resize, maximize, multi-window registry). Prefer `schmancy-window` for new code unless you want the simpler
|
|
5
|
+
> **Note:** `schmancy-window` is the evolved successor with more capabilities (resize, maximize, multi-window registry). Prefer `schmancy-window` for new code unless you want the simpler launcher-to-overlay model.
|
|
6
6
|
|
|
7
7
|
## Usage
|
|
8
8
|
```html
|
|
9
|
-
<schmancy-boat id="assistant"
|
|
10
|
-
|
|
11
|
-
<
|
|
9
|
+
<schmancy-boat id="assistant" ?open=${isOpen}>
|
|
10
|
+
<!-- optional: slot a handle to make the boat draggable -->
|
|
11
|
+
<schmancy-icon slot="drag-handle">drag_indicator</schmancy-icon>
|
|
12
12
|
|
|
13
|
-
<!--
|
|
13
|
+
<!-- trigger slot: the collapsed launcher — a plain click opens the panel -->
|
|
14
|
+
<div slot="trigger" class="px-4 py-2 rounded-full">Assistant · 3</div>
|
|
15
|
+
|
|
16
|
+
<!-- default slot: blooms into the show() overlay on open -->
|
|
14
17
|
<div class="p-4">Panel body content</div>
|
|
15
18
|
</schmancy-boat>
|
|
16
19
|
```
|
|
@@ -19,11 +22,8 @@
|
|
|
19
22
|
| Property | Type | Default | Description |
|
|
20
23
|
|----------|------|---------|-------------|
|
|
21
24
|
| `id` | string | `'default'` | Unique identifier (persists drag position in localStorage) |
|
|
22
|
-
| `icon` | string | — | Material icon for the FAB (overridden by the `header` slot) |
|
|
23
|
-
| `label` | string | — | FAB label text. **Omit → circular icon-only FAB** |
|
|
24
25
|
| `open` | boolean | `false` | Open state, reflected. Bind `?open=${…}` to drive it |
|
|
25
26
|
| `corner` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | `'bottom-right'` | Initial anchor corner |
|
|
26
|
-
| `lowered` | boolean | `false` | Lower the FAB elevation |
|
|
27
27
|
|
|
28
28
|
## Methods & event
|
|
29
29
|
```typescript
|
|
@@ -36,19 +36,25 @@ boat.addEventListener('toggle', e => e.detail) // 'open' | 'closed'
|
|
|
36
36
|
## Slots
|
|
37
37
|
| Slot | Renders | Behavior |
|
|
38
38
|
|------|---------|----------|
|
|
39
|
+
| `trigger` | the collapsed launcher — everything visible while closed | A native **click** (or Enter/Space) anywhere on it opens the panel. The boat does **not** `preventDefault` / `stopPropagation` / `setPointerCapture` here, so any interactive child (button, FAB, input) works natively. A child that should *not* also open the boat calls `stopPropagation()` on its own handler. |
|
|
40
|
+
| `drag-handle` | the drag affordance (a grip icon, a title bar — your choice) | **Opt-in.** Pointer-drag is wired only to this slot's boat-owned wrapper. Slot something here → draggable; omit it → the boat is static at its corner. A no-move tap on the handle also opens, so the grip doubles as a launcher. |
|
|
39
41
|
| _(default)_ | the expanded panel body | relocated into the `show()` overlay on open, restored on close |
|
|
40
|
-
| `summary` | trailing content on the FAB pill | live count / badge — stays on the FAB |
|
|
41
|
-
| `header` | leading icon on the FAB pill | overrides the `icon` property |
|
|
42
42
|
|
|
43
43
|
## Behavior
|
|
44
|
-
- Drag
|
|
45
|
-
-
|
|
46
|
-
-
|
|
44
|
+
- **Drag is opt-in and unambiguous.** No `<schmancy-boat>` is draggable unless the consumer slots `drag-handle`. Drag listens on a dedicated boat-owned region wrapping only that slot — every pointerdown there is a drag intent, so there is no interactive-element denylist and new interactive components never need registering.
|
|
45
|
+
- **The trigger is pure content.** Opening is a normal click that bubbles; nesting a `<schmancy-button>`, `<schmancy-fab>`, etc. in the trigger Just Works — the long-standing "interactive control swallowed by the drag/tap heuristic" bug class is gone (see ADR 0031).
|
|
46
|
+
- The collapsed shape is **not** imposed by the boat: no fixed height, padding, radius or gap. Style the `trigger` slot content for any shape.
|
|
47
|
+
- Drag to reposition (from the handle). Releases snap to the nearest corner (FLIP + `SPRING_SMOOTH`). Position persists in `localStorage` under `schmancy-boat-{id}`.
|
|
48
|
+
- Activation delegates to `show()`: blooms from the launcher, backdrop / Esc / back-button / sheet-on-narrow handled by the overlay primitive.
|
|
47
49
|
- Respects `prefers-reduced-motion`.
|
|
48
50
|
|
|
49
51
|
## Example
|
|
50
52
|
```html
|
|
51
|
-
<schmancy-boat id="chat"
|
|
53
|
+
<schmancy-boat id="chat" corner="bottom-right">
|
|
54
|
+
<schmancy-icon slot="drag-handle" class="px-1 opacity-40">drag_indicator</schmancy-icon>
|
|
55
|
+
<schmancy-fab slot="trigger" variant="tertiary" .label=${`Chat · ${count}`}>
|
|
56
|
+
<schmancy-icon>chat</schmancy-icon>
|
|
57
|
+
</schmancy-fab>
|
|
52
58
|
<schmancy-list class="p-2">
|
|
53
59
|
<!-- messages -->
|
|
54
60
|
</schmancy-list>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# schmancy-fab
|
|
2
|
+
|
|
3
|
+
> Material 3 Floating Action Button. Faithful to the M3 spec
|
|
4
|
+
> (m3.material.io/components/floating-action-button) and the `md-fab`
|
|
5
|
+
> reference implementation (github.com/material-components/material-web):
|
|
6
|
+
> four colour variants, three sizes, an extended form, and a lowered
|
|
7
|
+
> elevation register. Adds schmancy's house `magnetic` pull + spring press.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
```html
|
|
11
|
+
<!-- Regular FAB (icon-only) -->
|
|
12
|
+
<schmancy-fab aria-label="Compose"><schmancy-icon>edit</schmancy-icon></schmancy-fab>
|
|
13
|
+
|
|
14
|
+
<!-- Extended FAB -->
|
|
15
|
+
<schmancy-fab label="Compose" variant="primary">
|
|
16
|
+
<schmancy-icon>edit</schmancy-icon>
|
|
17
|
+
</schmancy-fab>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Properties
|
|
21
|
+
| Property | Type | Default | Description |
|
|
22
|
+
|----------|------|---------|-------------|
|
|
23
|
+
| `variant` | `'surface' \| 'primary' \| 'secondary' \| 'tertiary'` | `'surface'` | M3 colour role. `surface` = `surface-containerHigh` container + `primary` icon; the others use the matching `*-container` / `*-onContainer` pair |
|
|
24
|
+
| `size` | `'small' \| 'medium' \| 'large'` | `'medium'` | Container size: 40 / 56 / 96 dp. Ignored while extended |
|
|
25
|
+
| `label` | `string` | `''` | A non-empty value switches the FAB to its **extended** form (icon + text), exactly as `md-fab` derives extended from a truthy label |
|
|
26
|
+
| `extended` | `boolean` | `false` | Reflected mirror of "`label` is non-empty"; drives the extended geometry. Set automatically from `label` — read it, don't set it |
|
|
27
|
+
| `lowered` | `boolean` | `false` | M3 lowered FAB: elevation drops to level 1 (resting) / level 2 (hover) |
|
|
28
|
+
|
|
29
|
+
Per M3 guidance a FAB is **never disabled** — there is no `disabled`
|
|
30
|
+
property, matching `md-fab`.
|
|
31
|
+
|
|
32
|
+
## Slots
|
|
33
|
+
| Slot | Description |
|
|
34
|
+
|------|-------------|
|
|
35
|
+
| (default) | The icon, typically `<schmancy-icon>`. Auto-sized per FAB size (24dp; 36dp for `large`) and given `aria-hidden` when an accessible name is present |
|
|
36
|
+
|
|
37
|
+
## M3 tokens (exact)
|
|
38
|
+
| | small | medium | large | extended |
|
|
39
|
+
|--|--|--|--|--|
|
|
40
|
+
| container | 40×40 | 56×56 | 96×96 | 56 tall, content wide |
|
|
41
|
+
| shape (radius) | 12dp | 16dp | 28dp | 16dp |
|
|
42
|
+
| icon | 24dp | 24dp | 36dp | 24dp |
|
|
43
|
+
|
|
44
|
+
Extended paddings: `padding-inline-start: 16px`, `padding-inline-end: 20px`,
|
|
45
|
+
icon-to-label gap `12px` — verbatim from `md-fab`'s shared styles. Label is
|
|
46
|
+
the `label-large` type scale.
|
|
47
|
+
|
|
48
|
+
Elevation maps to schmancy's M3 elevation tokens
|
|
49
|
+
(`--schmancy-sys-elevation-*`): resting **level 3**, hover **level 4**;
|
|
50
|
+
lowered → resting **level 1**, hover **level 2**. Pressed elevation equals
|
|
51
|
+
resting per M3 (the press read is the state layer + spring scale).
|
|
52
|
+
|
|
53
|
+
State layer: hover `0.08`, focus/pressed `0.10`, tinted with the variant's
|
|
54
|
+
on-colour.
|
|
55
|
+
|
|
56
|
+
## Physics (schmancy house style)
|
|
57
|
+
- **magnetic** directive embedded (strength 3, radius 60px) — same pull as `schmancy-button`.
|
|
58
|
+
- Hover raises elevation per M3; active applies a spring `scale(0.96)`.
|
|
59
|
+
- `prefers-reduced-motion` removes the transition and the press scale.
|
|
60
|
+
|
|
61
|
+
## Examples
|
|
62
|
+
```html
|
|
63
|
+
<!-- Small surface FAB -->
|
|
64
|
+
<schmancy-fab size="small" aria-label="Add"><schmancy-icon>add</schmancy-icon></schmancy-fab>
|
|
65
|
+
|
|
66
|
+
<!-- Large tertiary FAB -->
|
|
67
|
+
<schmancy-fab size="large" variant="tertiary" aria-label="Create">
|
|
68
|
+
<schmancy-icon>add</schmancy-icon>
|
|
69
|
+
</schmancy-fab>
|
|
70
|
+
|
|
71
|
+
<!-- Lowered extended secondary FAB -->
|
|
72
|
+
<schmancy-fab lowered label="New message" variant="secondary">
|
|
73
|
+
<schmancy-icon>edit</schmancy-icon>
|
|
74
|
+
</schmancy-fab>
|
|
75
|
+
```
|
package/skills/schmancy/theme.md
CHANGED
|
@@ -75,7 +75,7 @@ Every `--schmancy-sys-color-*` token is aliased as `--color-*` in the theme styl
|
|
|
75
75
|
--schmancy-sys-color-{token} → --color-{token} → bg-{token} · text-{token} · border-{token}
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
**
|
|
78
|
+
**The shortcut utility is the readable form of a token that exists for genuine semantic reuse and is registered in the workspace being edited.** `border-outline-variant` reads better than `border-[var(--schmancy-sys-color-outlineVariant)]` because `outlineVariant` is a reused semantic color aliased into every consuming workspace. A trivial or one-off layout value (`grid-rows-[auto_1fr]`, `max-w-[720px]`) stays in its portable arbitrary form — aliasing it behind a workspace-local `@theme` token adds a name no second call site uses and a build dependency a sibling workspace's Tailwind does not resolve.
|
|
79
79
|
|
|
80
80
|
Multi-word tokens are registered in **both** camelCase and kebab-case — both forms work. Use whichever reads better:
|
|
81
81
|
|
package/src/CLAUDE.md
CHANGED
|
@@ -116,10 +116,12 @@ connectedCallback() {
|
|
|
116
116
|
```
|
|
117
117
|
|
|
118
118
|
- Every subscription ends with `.pipe(takeUntil(this.disconnecting))`.
|
|
119
|
-
- Form components (`select`, `autocomplete`, `chips`)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
119
|
+
- Form components (`select`, `autocomplete`, `chips`) carry an explicit
|
|
120
|
+
`multi: boolean` mode flag and route `value` through two
|
|
121
|
+
BehaviorSubjects (`_value$`, `_values$`). They never infer mode from
|
|
122
|
+
which setter was called. Before writing a new field, read
|
|
123
|
+
`mixins/formField.mixin.ts` and mirror
|
|
124
|
+
`src/form/fields/select/select.ts` (the canonical single/multi field).
|
|
123
125
|
|
|
124
126
|
### Custom events
|
|
125
127
|
|
|
@@ -137,6 +139,13 @@ this.dispatchEvent(
|
|
|
137
139
|
)
|
|
138
140
|
```
|
|
139
141
|
|
|
142
|
+
For a **form field** (a control `<schmancy-form>` collects), emit `change`
|
|
143
|
+
through the mixin's `emitChange({ value })` instead of hand-rolling
|
|
144
|
+
`dispatchEvent`. It guarantees `composed: true` so the event crosses the
|
|
145
|
+
shadow boundary the form listens across — the recurring field bug is a
|
|
146
|
+
hand-rolled dispatch that forgets that flag. See `emitChange` in
|
|
147
|
+
`mixins/formField.mixin.ts`.
|
|
148
|
+
|
|
140
149
|
### Accessibility
|
|
141
150
|
|
|
142
151
|
Form components carry the ARIA combobox pattern (`role="combobox"`,
|
|
@@ -183,18 +192,15 @@ the Tailwind shortcut utilities (`bg-surface-default`,
|
|
|
183
192
|
|
|
184
193
|
## Validation patterns (form components)
|
|
185
194
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
return this._inputElementRef.value?.reportValidity() ?? this.checkValidity()
|
|
196
|
-
}
|
|
197
|
-
```
|
|
195
|
+
`checkValidity()`, `reportValidity()`, `setCustomValidity()`, the
|
|
196
|
+
`validateOn` truth table, and `internals.setValidity` wiring all come from
|
|
197
|
+
`FormFieldMixin` (`mixins/formField.mixin.ts`). A new field adopts them by
|
|
198
|
+
extending `SchmancyFormField(styles)` — it does not hand-roll its own
|
|
199
|
+
validity. The two cases that *do* require an override are array-typed
|
|
200
|
+
values: empty-array `required` (the mixin's `value === ''` test passes for
|
|
201
|
+
`[]`) and `setFormValue` for arrays (the platform API rejects arrays).
|
|
202
|
+
`src/form/fields/select/select.ts` shows both — read it before authoring a
|
|
203
|
+
field's validity.
|
|
198
204
|
|
|
199
205
|
## Pointers
|
|
200
206
|
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
2
|
+
import './boat'
|
|
3
|
+
import '../surface/surface'
|
|
4
|
+
import type SchmancyBoat from './boat'
|
|
5
|
+
|
|
6
|
+
const nextUpdate = () => new Promise(r => requestAnimationFrame(() => r(null)))
|
|
7
|
+
|
|
8
|
+
// The overlay service aborts its own AbortController when an opened overlay
|
|
9
|
+
// is dismissed/unmounted; that rejection is overlay-internal and out of the
|
|
10
|
+
// boat's scope. Swallow ONLY AbortError so the suite stays clean without
|
|
11
|
+
// masking any other unhandled rejection.
|
|
12
|
+
const swallowAbort = (e: PromiseRejectionEvent) => {
|
|
13
|
+
if ((e.reason as { name?: string } | null)?.name === 'AbortError') e.preventDefault()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const handleWrapper = (boat: SchmancyBoat) =>
|
|
17
|
+
boat.shadowRoot!.querySelector('[aria-label="Drag to move"]') as HTMLElement
|
|
18
|
+
const triggerWrapper = (boat: SchmancyBoat) =>
|
|
19
|
+
boat.shadowRoot!.querySelector('[aria-label="Open panel"]') as HTMLElement
|
|
20
|
+
const container = (boat: SchmancyBoat) =>
|
|
21
|
+
boat.shadowRoot!.querySelector('schmancy-surface') as HTMLElement
|
|
22
|
+
|
|
23
|
+
describe('schmancy-boat — gesture/slot contract', () => {
|
|
24
|
+
let host: HTMLDivElement
|
|
25
|
+
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
host = document.createElement('div')
|
|
28
|
+
document.body.appendChild(host)
|
|
29
|
+
localStorage.clear()
|
|
30
|
+
window.addEventListener('unhandledrejection', swallowAbort)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
afterEach(async () => {
|
|
34
|
+
// Close any open overlay gracefully so show()'s teardown runs its
|
|
35
|
+
// normal finalize path instead of aborting on an abrupt DOM removal.
|
|
36
|
+
const boat = host.querySelector('schmancy-boat') as SchmancyBoat | null
|
|
37
|
+
if (boat?.open) {
|
|
38
|
+
boat.open = false
|
|
39
|
+
await nextUpdate()
|
|
40
|
+
await nextUpdate()
|
|
41
|
+
}
|
|
42
|
+
window.removeEventListener('unhandledrejection', swallowAbort)
|
|
43
|
+
host.remove()
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('is static when no drag-handle is slotted (handle region hidden)', async () => {
|
|
47
|
+
host.innerHTML = `<schmancy-boat id="a"><div slot="trigger">Open</div><div>panel</div></schmancy-boat>`
|
|
48
|
+
const boat = host.querySelector('schmancy-boat') as SchmancyBoat
|
|
49
|
+
await nextUpdate()
|
|
50
|
+
await nextUpdate()
|
|
51
|
+
expect(handleWrapper(boat).classList.contains('hidden')).toBe(true)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('becomes draggable only when a drag-handle is slotted', async () => {
|
|
55
|
+
host.innerHTML = `<schmancy-boat id="b"><span slot="drag-handle">⠿</span><div slot="trigger">Open</div><div>panel</div></schmancy-boat>`
|
|
56
|
+
const boat = host.querySelector('schmancy-boat') as SchmancyBoat
|
|
57
|
+
await nextUpdate()
|
|
58
|
+
await nextUpdate()
|
|
59
|
+
expect(handleWrapper(boat).classList.contains('hidden')).toBe(false)
|
|
60
|
+
expect(handleWrapper(boat).classList.contains('cursor-grab')).toBe(true)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('opens on a plain click anywhere on the trigger', async () => {
|
|
64
|
+
host.innerHTML = `<schmancy-boat id="c"><div slot="trigger">Open me</div><div>panel</div></schmancy-boat>`
|
|
65
|
+
const boat = host.querySelector('schmancy-boat') as SchmancyBoat
|
|
66
|
+
await nextUpdate()
|
|
67
|
+
expect(boat.open).toBe(false)
|
|
68
|
+
triggerWrapper(boat).click()
|
|
69
|
+
await nextUpdate()
|
|
70
|
+
expect(boat.open).toBe(true)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('does NOT suppress a slotted interactive control (the bug class)', async () => {
|
|
74
|
+
host.innerHTML = `<schmancy-boat id="d"><button slot="trigger" id="inner">Act</button><div>panel</div></schmancy-boat>`
|
|
75
|
+
const boat = host.querySelector('schmancy-boat') as SchmancyBoat
|
|
76
|
+
const innerBtn = host.querySelector('#inner') as HTMLButtonElement
|
|
77
|
+
let innerFired = false
|
|
78
|
+
let prevented = false
|
|
79
|
+
innerBtn.addEventListener('click', e => {
|
|
80
|
+
innerFired = true
|
|
81
|
+
prevented = e.defaultPrevented
|
|
82
|
+
})
|
|
83
|
+
await nextUpdate()
|
|
84
|
+
|
|
85
|
+
innerBtn.click()
|
|
86
|
+
await nextUpdate()
|
|
87
|
+
|
|
88
|
+
// The slotted button's own handler ran, the boat did not preventDefault
|
|
89
|
+
// it, and the click still bubbled to "open" the boat.
|
|
90
|
+
expect(innerFired).toBe(true)
|
|
91
|
+
expect(prevented).toBe(false)
|
|
92
|
+
expect(boat.open).toBe(true)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('drags from the handle and snaps (a moved gesture is not a tap-open)', async () => {
|
|
96
|
+
host.innerHTML = `<schmancy-boat id="e"><span slot="drag-handle">⠿</span><div slot="trigger">Open</div><div>panel</div></schmancy-boat>`
|
|
97
|
+
const boat = host.querySelector('schmancy-boat') as SchmancyBoat
|
|
98
|
+
await nextUpdate()
|
|
99
|
+
await nextUpdate()
|
|
100
|
+
const grip = handleWrapper(boat)
|
|
101
|
+
|
|
102
|
+
grip.dispatchEvent(
|
|
103
|
+
new PointerEvent('pointerdown', { button: 0, pointerId: 1, clientX: 100, clientY: 100, bubbles: true }),
|
|
104
|
+
)
|
|
105
|
+
window.dispatchEvent(new PointerEvent('pointermove', { pointerId: 1, clientX: 100, clientY: 100 }))
|
|
106
|
+
window.dispatchEvent(new PointerEvent('pointermove', { pointerId: 1, clientX: 220, clientY: 240 }))
|
|
107
|
+
await nextUpdate()
|
|
108
|
+
expect(container(boat).classList.contains('scale-95')).toBe(true)
|
|
109
|
+
|
|
110
|
+
window.dispatchEvent(new PointerEvent('pointerup', { pointerId: 1, clientX: 220, clientY: 240 }))
|
|
111
|
+
await nextUpdate()
|
|
112
|
+
expect(boat.open).toBe(false)
|
|
113
|
+
expect(localStorage.getItem('schmancy-boat-e')).not.toBeNull()
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('treats a no-move press on the handle as a tap that opens', async () => {
|
|
117
|
+
host.innerHTML = `<schmancy-boat id="f"><span slot="drag-handle">⠿</span><div slot="trigger">Open</div><div>panel</div></schmancy-boat>`
|
|
118
|
+
const boat = host.querySelector('schmancy-boat') as SchmancyBoat
|
|
119
|
+
await nextUpdate()
|
|
120
|
+
await nextUpdate()
|
|
121
|
+
const grip = handleWrapper(boat)
|
|
122
|
+
|
|
123
|
+
grip.dispatchEvent(
|
|
124
|
+
new PointerEvent('pointerdown', { button: 0, pointerId: 2, clientX: 50, clientY: 50, bubbles: true }),
|
|
125
|
+
)
|
|
126
|
+
window.dispatchEvent(new PointerEvent('pointerup', { pointerId: 2, clientX: 50, clientY: 50 }))
|
|
127
|
+
await nextUpdate()
|
|
128
|
+
expect(boat.open).toBe(true)
|
|
129
|
+
})
|
|
130
|
+
})
|