@mhmo91/schmancy 0.10.5 → 0.10.7

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 (445) hide show
  1. package/README.md +11 -0
  2. package/custom-elements.json +235 -1807
  3. package/dist/agent/{flow-CaPi2G8y.js.map → flow-CvG1fLW5.js.map} +1 -1
  4. package/dist/agent/schmancy.agent.js +5347 -12408
  5. package/dist/agent/schmancy.agent.js.map +1 -1
  6. package/dist/agent/schmancy.manifest.json +70 -1068
  7. package/dist/agent/{vendor-material-color-Be96dpGE.js.map → vendor-material-color-DcL7ZPxx.js.map} +1 -1
  8. package/dist/{area-CSQdhCBF.cjs → area-8IBAXzbC.cjs} +1 -1
  9. package/dist/{area-CSQdhCBF.cjs.map → area-8IBAXzbC.cjs.map} +1 -1
  10. package/dist/{area-D5haQE-J.js → area-DSW_LYXQ.js} +1 -1
  11. package/dist/{area-D5haQE-J.js.map → area-DSW_LYXQ.js.map} +1 -1
  12. package/dist/area.cjs +1 -1
  13. package/dist/area.js +1 -1
  14. package/dist/{autocomplete-B_bJXUjm.cjs → autocomplete-9PLjlFYt.cjs} +1 -1
  15. package/dist/{autocomplete-B_bJXUjm.cjs.map → autocomplete-9PLjlFYt.cjs.map} +1 -1
  16. package/dist/{autocomplete-DtyjZJ1E.js → autocomplete-CXwwmUbC.js} +2 -2
  17. package/dist/{autocomplete-DtyjZJ1E.js.map → autocomplete-CXwwmUbC.js.map} +1 -1
  18. package/dist/autocomplete.cjs +1 -1
  19. package/dist/autocomplete.js +1 -1
  20. package/dist/avatar.cjs +1 -1
  21. package/dist/avatar.js +2 -2
  22. package/dist/badge.cjs +1 -1
  23. package/dist/badge.js +1 -1
  24. package/dist/{boat-BJLCp-Hv.cjs → boat-CpGNeWav.cjs} +1 -1
  25. package/dist/{boat-BJLCp-Hv.cjs.map → boat-CpGNeWav.cjs.map} +1 -1
  26. package/dist/{boat-MT8bRT8u.js → boat-Dwn5oXd8.js} +1 -1
  27. package/dist/{boat-MT8bRT8u.js.map → boat-Dwn5oXd8.js.map} +1 -1
  28. package/dist/boat.cjs +1 -1
  29. package/dist/boat.js +1 -1
  30. package/dist/breadcrumb.cjs +1 -1
  31. package/dist/breadcrumb.js +1 -1
  32. package/dist/{busy-DSF2E-zy.cjs → busy-CUUgvimY.cjs} +1 -1
  33. package/dist/{busy-DSF2E-zy.cjs.map → busy-CUUgvimY.cjs.map} +1 -1
  34. package/dist/{busy-6BqWGryX.js → busy-Cjm1BYVC.js} +1 -1
  35. package/dist/{busy-6BqWGryX.js.map → busy-Cjm1BYVC.js.map} +1 -1
  36. package/dist/busy.cjs +1 -1
  37. package/dist/busy.js +1 -1
  38. package/dist/button.cjs +1 -1
  39. package/dist/button.js +1 -1
  40. package/dist/{card-CvuVha-W.js → card-BR22oYCL.js} +1 -1
  41. package/dist/{card-CvuVha-W.js.map → card-BR22oYCL.js.map} +1 -1
  42. package/dist/{card-DnKnaHzf.cjs → card-BjZ_WRr3.cjs} +1 -1
  43. package/dist/{card-DnKnaHzf.cjs.map → card-BjZ_WRr3.cjs.map} +1 -1
  44. package/dist/card.cjs +1 -1
  45. package/dist/card.js +1 -1
  46. package/dist/{checkbox-D3u8Wm9r.cjs → checkbox-2e8v7CNg.cjs} +1 -1
  47. package/dist/{checkbox-D3u8Wm9r.cjs.map → checkbox-2e8v7CNg.cjs.map} +1 -1
  48. package/dist/{checkbox-QDRsE8cp.js → checkbox-CsADwyfu.js} +1 -1
  49. package/dist/{checkbox-QDRsE8cp.js.map → checkbox-CsADwyfu.js.map} +1 -1
  50. package/dist/checkbox.cjs +1 -1
  51. package/dist/checkbox.js +1 -1
  52. package/dist/{chips-Dy9vx8JS.js → chips-C9HwVbGT.js} +2 -2
  53. package/dist/{chips-Dy9vx8JS.js.map → chips-C9HwVbGT.js.map} +1 -1
  54. package/dist/{chips-CMoQzop1.cjs → chips-DPCcO55o.cjs} +1 -1
  55. package/dist/{chips-CMoQzop1.cjs.map → chips-DPCcO55o.cjs.map} +1 -1
  56. package/dist/chips.cjs +1 -1
  57. package/dist/chips.js +2 -2
  58. package/dist/connectivity.cjs +1 -1
  59. package/dist/connectivity.js +1 -1
  60. package/dist/content-drawer.cjs +1 -1
  61. package/dist/content-drawer.js +1 -1
  62. package/dist/{date-range-B2NuihKA.cjs → date-range-63-FC7gD.cjs} +1 -1
  63. package/dist/{date-range-B2NuihKA.cjs.map → date-range-63-FC7gD.cjs.map} +1 -1
  64. package/dist/{date-range-Boesjlic.js → date-range-CFaP-8Os.js} +2 -2
  65. package/dist/{date-range-Boesjlic.js.map → date-range-CFaP-8Os.js.map} +1 -1
  66. package/dist/{date-range-inline-DBuND2pc.js → date-range-inline-BCuK_XCv.js} +1 -1
  67. package/dist/{date-range-inline-DBuND2pc.js.map → date-range-inline-BCuK_XCv.js.map} +1 -1
  68. package/dist/{date-range-inline-BI6_4Ahl.cjs → date-range-inline-Cpdqd-8B.cjs} +1 -1
  69. package/dist/{date-range-inline-BI6_4Ahl.cjs.map → date-range-inline-Cpdqd-8B.cjs.map} +1 -1
  70. package/dist/date-range-inline.cjs +1 -1
  71. package/dist/date-range-inline.js +1 -1
  72. package/dist/date-range.cjs +1 -1
  73. package/dist/date-range.js +1 -1
  74. package/dist/delay.cjs +1 -1
  75. package/dist/delay.js +2 -2
  76. package/dist/{details-BrGrUTGC.js → details-0dOlqHHL.js} +1 -1
  77. package/dist/{details-BrGrUTGC.js.map → details-0dOlqHHL.js.map} +1 -1
  78. package/dist/{details-BRs_z5-k.cjs → details-qKikJIyH.cjs} +1 -1
  79. package/dist/{details-BRs_z5-k.cjs.map → details-qKikJIyH.cjs.map} +1 -1
  80. package/dist/details.cjs +1 -1
  81. package/dist/details.js +1 -1
  82. package/dist/{divider-W3TiDasp.js → divider-BxkIl0H1.js} +1 -1
  83. package/dist/{divider-W3TiDasp.js.map → divider-BxkIl0H1.js.map} +1 -1
  84. package/dist/{divider-BOxQ2T9h.cjs → divider-CX9mmWZ8.cjs} +1 -1
  85. package/dist/{divider-BOxQ2T9h.cjs.map → divider-CX9mmWZ8.cjs.map} +1 -1
  86. package/dist/divider.cjs +1 -1
  87. package/dist/divider.js +1 -1
  88. package/dist/dropdown.cjs +1 -1
  89. package/dist/dropdown.js +1 -1
  90. package/dist/{expand-CnccBF91.cjs → expand-891JuQuN.cjs} +1 -1
  91. package/dist/{expand-CnccBF91.cjs.map → expand-891JuQuN.cjs.map} +1 -1
  92. package/dist/{expand-Pu8fZ0jZ.js → expand-BeAx94MP.js} +2 -2
  93. package/dist/{expand-Pu8fZ0jZ.js.map → expand-BeAx94MP.js.map} +1 -1
  94. package/dist/expand.cjs +1 -1
  95. package/dist/expand.js +1 -1
  96. package/dist/{float-WCVdp3um.js → float-BPF2WO4L.js} +1 -1
  97. package/dist/{float-WCVdp3um.js.map → float-BPF2WO4L.js.map} +1 -1
  98. package/dist/{float-BRKa-P6Z.cjs → float-D7vvODxx.cjs} +1 -1
  99. package/dist/{float-BRKa-P6Z.cjs.map → float-D7vvODxx.cjs.map} +1 -1
  100. package/dist/float.cjs +1 -1
  101. package/dist/float.js +1 -1
  102. package/dist/{form-CI59gad4.js.map → form-CFvwnfuJ.js.map} +1 -1
  103. package/dist/{form-B2qudx_q.cjs.map → form-Ceijw1aA.cjs.map} +1 -1
  104. package/dist/form.cjs +1 -1
  105. package/dist/form.js +1 -1
  106. package/dist/handover/agent-runtime-followups.md +1 -1
  107. package/dist/handover/agent-runtime-v1.md +3 -3
  108. package/dist/{hashContent-a8uVr3xs.js.map → hashContent-BU6jl5ih.js.map} +1 -1
  109. package/dist/{hashContent-ejkBgDnN.cjs.map → hashContent-Bobsobip.cjs.map} +1 -1
  110. package/dist/{icons-C0ufCcdp.js → icons-BKxW_7QR.js} +1 -1
  111. package/dist/{icons-C0ufCcdp.js.map → icons-BKxW_7QR.js.map} +1 -1
  112. package/dist/{icons-DXEbmg-O.cjs → icons-QSdo-8h9.cjs} +1 -1
  113. package/dist/{icons-DXEbmg-O.cjs.map → icons-QSdo-8h9.cjs.map} +1 -1
  114. package/dist/icons.cjs +1 -1
  115. package/dist/icons.js +1 -1
  116. package/dist/{iframe-c9lGxw7x.js → iframe-BxvbhyTS.js} +1 -1
  117. package/dist/{iframe-c9lGxw7x.js.map → iframe-BxvbhyTS.js.map} +1 -1
  118. package/dist/{iframe-C6RVODkW.cjs → iframe-CMKV-bm8.cjs} +1 -1
  119. package/dist/{iframe-C6RVODkW.cjs.map → iframe-CMKV-bm8.cjs.map} +1 -1
  120. package/dist/iframe.cjs +1 -1
  121. package/dist/iframe.js +1 -1
  122. package/dist/index.cjs +1 -1
  123. package/dist/index.js +64 -72
  124. package/dist/{input-B4HM-9-H.cjs → input-BFhJU74_.cjs} +1 -1
  125. package/dist/{input-B4HM-9-H.cjs.map → input-BFhJU74_.cjs.map} +1 -1
  126. package/dist/{input-Pmj_bH37.js → input-DIqaR8Mr.js} +1 -1
  127. package/dist/{input-Pmj_bH37.js.map → input-DIqaR8Mr.js.map} +1 -1
  128. package/dist/{input-chip-BIGgd_7w.js → input-chip-D9tlSk_2.js} +1 -1
  129. package/dist/{input-chip-BIGgd_7w.js.map → input-chip-D9tlSk_2.js.map} +1 -1
  130. package/dist/{input-chip-BoDisY6c.cjs → input-chip-w09qTt7J.cjs} +1 -1
  131. package/dist/{input-chip-BoDisY6c.cjs.map → input-chip-w09qTt7J.cjs.map} +1 -1
  132. package/dist/input.cjs +1 -1
  133. package/dist/input.js +1 -1
  134. package/dist/json.cjs +1 -1
  135. package/dist/json.js +2 -2
  136. package/dist/kbd.cjs +1 -1
  137. package/dist/kbd.js +1 -1
  138. package/dist/layout.cjs +1 -1
  139. package/dist/layout.js +1 -1
  140. package/dist/{lightbox-DK1vDKm3.cjs → lightbox-CK035jsx.cjs} +1 -1
  141. package/dist/{lightbox-DK1vDKm3.cjs.map → lightbox-CK035jsx.cjs.map} +1 -1
  142. package/dist/{lightbox-K1eJTYXP.js → lightbox-GChmL3Ff.js} +2 -2
  143. package/dist/{lightbox-K1eJTYXP.js.map → lightbox-GChmL3Ff.js.map} +1 -1
  144. package/dist/lightbox.cjs +1 -1
  145. package/dist/lightbox.js +1 -1
  146. package/dist/{list-CEuVqAxN.cjs → list-B3P37zlH.cjs} +1 -1
  147. package/dist/{list-CEuVqAxN.cjs.map → list-B3P37zlH.cjs.map} +1 -1
  148. package/dist/{list-Ds0Nv1y5.js → list-J-Fz24Z1.js} +1 -1
  149. package/dist/{list-Ds0Nv1y5.js.map → list-J-Fz24Z1.js.map} +1 -1
  150. package/dist/list.cjs +1 -1
  151. package/dist/list.js +1 -1
  152. package/dist/{menu-Bly30Nje.cjs → menu-BnFd8CwU.cjs} +1 -1
  153. package/dist/{menu-Bly30Nje.cjs.map → menu-BnFd8CwU.cjs.map} +1 -1
  154. package/dist/{menu-L8MK1ma5.js → menu-DHTlUwXS.js} +2 -2
  155. package/dist/{menu-L8MK1ma5.js.map → menu-DHTlUwXS.js.map} +1 -1
  156. package/dist/menu.cjs +1 -1
  157. package/dist/menu.js +1 -1
  158. package/dist/mixins-47_CZk7q.cjs +298 -0
  159. package/dist/{mixins-CAb0b03r.cjs.map → mixins-47_CZk7q.cjs.map} +1 -1
  160. package/dist/mixins-PBJJGiiP.js +627 -0
  161. package/dist/{mixins-B34UxxCe.js.map → mixins-PBJJGiiP.js.map} +1 -1
  162. package/dist/mixins.cjs +1 -1
  163. package/dist/mixins.js +1 -1
  164. package/dist/nav-drawer.cjs +1 -1
  165. package/dist/nav-drawer.js +1 -1
  166. package/dist/navigation-bar.cjs +1 -1
  167. package/dist/navigation-bar.js +1 -1
  168. package/dist/navigation-rail.cjs +1 -1
  169. package/dist/navigation-rail.js +1 -1
  170. package/dist/{notification-7fSbk8hm.cjs → notification-B6YBL0hx.cjs} +1 -1
  171. package/dist/{notification-7fSbk8hm.cjs.map → notification-B6YBL0hx.cjs.map} +1 -1
  172. package/dist/{notification-DB25M-qo.js → notification-C-5Bv3vj.js} +2 -2
  173. package/dist/{notification-DB25M-qo.js.map → notification-C-5Bv3vj.js.map} +1 -1
  174. package/dist/notification.cjs +1 -1
  175. package/dist/notification.js +1 -1
  176. package/dist/{option-DDHa25k5.js → option-B7q6VXCu.js} +1 -1
  177. package/dist/{option-DDHa25k5.js.map → option-B7q6VXCu.js.map} +1 -1
  178. package/dist/{option-HF9Xqbuq.cjs → option-DVQRa3nr.cjs} +1 -1
  179. package/dist/{option-HF9Xqbuq.cjs.map → option-DVQRa3nr.cjs.map} +1 -1
  180. package/dist/option.cjs +1 -1
  181. package/dist/option.js +1 -1
  182. package/dist/{overlay-stack-CCiTaf_C.js.map → overlay-stack-DCDS17uj.js.map} +1 -1
  183. package/dist/{overlay-stack-CFGiYf34.cjs.map → overlay-stack-DPIe_aYv.cjs.map} +1 -1
  184. package/dist/overlay.cjs +1 -1
  185. package/dist/{overlay.confirm-body-BDG94R0x.js → overlay.confirm-body-CAY5xK1n.js} +1 -1
  186. package/dist/{overlay.confirm-body-BDG94R0x.js.map → overlay.confirm-body-CAY5xK1n.js.map} +1 -1
  187. package/dist/{overlay.confirm-body-b4Nx_OVf.cjs → overlay.confirm-body-XZtErofy.cjs} +1 -1
  188. package/dist/{overlay.confirm-body-b4Nx_OVf.cjs.map → overlay.confirm-body-XZtErofy.cjs.map} +1 -1
  189. package/dist/overlay.js +3 -3
  190. package/dist/{overlay.service-BUCuZa6V.js → overlay.service-BZE_lwKO.js} +2 -2
  191. package/dist/{overlay.service-BUCuZa6V.js.map → overlay.service-BZE_lwKO.js.map} +1 -1
  192. package/dist/{overlay.service-CRHZZY9F.cjs → overlay.service-Oyjrw831.cjs} +1 -1
  193. package/dist/{overlay.service-CRHZZY9F.cjs.map → overlay.service-Oyjrw831.cjs.map} +1 -1
  194. package/dist/page.cjs +1 -1
  195. package/dist/page.js +2 -2
  196. package/dist/{progress-CqOyMM4i.js → progress-BHXLYs9i.js} +1 -1
  197. package/dist/{progress-CqOyMM4i.js.map → progress-BHXLYs9i.js.map} +1 -1
  198. package/dist/{progress-54R4QRgW.cjs → progress-D99bumkC.cjs} +1 -1
  199. package/dist/{progress-54R4QRgW.cjs.map → progress-D99bumkC.cjs.map} +1 -1
  200. package/dist/progress.cjs +1 -1
  201. package/dist/progress.js +1 -1
  202. package/dist/{radio-group-B4zbBIZF.js → radio-group-BYra5_q1.js} +1 -1
  203. package/dist/{radio-group-B4zbBIZF.js.map → radio-group-BYra5_q1.js.map} +1 -1
  204. package/dist/{radio-group-BJqZpYVy.cjs → radio-group-DYsycLmD.cjs} +1 -1
  205. package/dist/{radio-group-BJqZpYVy.cjs.map → radio-group-DYsycLmD.cjs.map} +1 -1
  206. package/dist/radio-group.cjs +1 -1
  207. package/dist/radio-group.js +1 -1
  208. package/dist/range.cjs +1 -1
  209. package/dist/range.js +1 -1
  210. package/dist/{rxjs-utils-BXpvHN4-.js.map → rxjs-utils-CVeJQ9KG.js.map} +1 -1
  211. package/dist/{rxjs-utils-CaC-tdot.cjs.map → rxjs-utils-DCUHg_Ml.cjs.map} +1 -1
  212. package/dist/rxjs-utils.cjs +1 -1
  213. package/dist/rxjs-utils.js +1 -1
  214. package/dist/{scroll-CYm6Krus.js → scroll-TqNWZ0lo.js} +1 -1
  215. package/dist/{scroll-CYm6Krus.js.map → scroll-TqNWZ0lo.js.map} +1 -1
  216. package/dist/{scroll-iSRovYYt.cjs → scroll-cayCBOrq.cjs} +1 -1
  217. package/dist/{scroll-iSRovYYt.cjs.map → scroll-cayCBOrq.cjs.map} +1 -1
  218. package/dist/{select-DiQHtQJN.cjs → select-CRdSmlLq.cjs} +1 -1
  219. package/dist/{select-DiQHtQJN.cjs.map → select-CRdSmlLq.cjs.map} +1 -1
  220. package/dist/{select-1WHseXP6.js → select-nzq0qFlF.js} +2 -2
  221. package/dist/{select-1WHseXP6.js.map → select-nzq0qFlF.js.map} +1 -1
  222. package/dist/select.cjs +1 -1
  223. package/dist/select.js +1 -1
  224. package/dist/skeleton.cjs +1 -1
  225. package/dist/skeleton.js +1 -1
  226. package/dist/skills/INDEX.md +9 -6
  227. package/dist/skills/schmancy/INDEX.md +9 -6
  228. package/dist/slider.cjs +1 -1
  229. package/dist/slider.js +1 -1
  230. package/dist/{splash-screen-BwvtKMdN.js → splash-screen-BJeIiJ_e.js} +1 -1
  231. package/dist/{splash-screen-BwvtKMdN.js.map → splash-screen-BJeIiJ_e.js.map} +1 -1
  232. package/dist/{splash-screen-CJL8DGDe.cjs → splash-screen-BMLQXzDq.cjs} +1 -1
  233. package/dist/{splash-screen-CJL8DGDe.cjs.map → splash-screen-BMLQXzDq.cjs.map} +1 -1
  234. package/dist/splash-screen.cjs +1 -1
  235. package/dist/splash-screen.js +1 -1
  236. package/dist/{src-Bwr2NR0A.cjs → src-DE11tq2Q.cjs} +1 -1
  237. package/dist/{src-Bwr2NR0A.cjs.map → src-DE11tq2Q.cjs.map} +1 -1
  238. package/dist/{src-UaZeROcW.js → src-qvWlNoMO.js} +34 -42
  239. package/dist/{src-UaZeROcW.js.map → src-qvWlNoMO.js.map} +1 -1
  240. package/dist/steps.cjs +1 -1
  241. package/dist/steps.js +1 -1
  242. package/dist/{surface-DE5iuI8e.cjs → surface-D426MFLR.cjs} +1 -1
  243. package/dist/{surface-DE5iuI8e.cjs.map → surface-D426MFLR.cjs.map} +1 -1
  244. package/dist/{surface-DPUkQ3OL.js → surface-DG7Cmm9V.js} +1 -1
  245. package/dist/{surface-DPUkQ3OL.js.map → surface-DG7Cmm9V.js.map} +1 -1
  246. package/dist/surface.cjs +1 -1
  247. package/dist/surface.js +1 -1
  248. package/dist/switch.cjs +1 -1
  249. package/dist/switch.js +1 -1
  250. package/dist/table.cjs +1 -1
  251. package/dist/table.js +1 -1
  252. package/dist/{tabs-B2XEQPQl.js → tabs-B7siJkM5.js} +1 -1
  253. package/dist/{tabs-B2XEQPQl.js.map → tabs-B7siJkM5.js.map} +1 -1
  254. package/dist/{tabs-CsDQ72Qk.cjs → tabs-t3nMfg1F.cjs} +1 -1
  255. package/dist/{tabs-CsDQ72Qk.cjs.map → tabs-t3nMfg1F.cjs.map} +1 -1
  256. package/dist/tabs.cjs +1 -1
  257. package/dist/tabs.js +1 -1
  258. package/dist/teleport.cjs +1 -1
  259. package/dist/teleport.js +1 -1
  260. package/dist/{textarea-C_ps0lL-.js → textarea-DSxHCCle.js} +1 -1
  261. package/dist/{textarea-C_ps0lL-.js.map → textarea-DSxHCCle.js.map} +1 -1
  262. package/dist/{textarea-aeAP9cDG.cjs → textarea-o9vysorM.cjs} +1 -1
  263. package/dist/{textarea-aeAP9cDG.cjs.map → textarea-o9vysorM.cjs.map} +1 -1
  264. package/dist/textarea.cjs +1 -1
  265. package/dist/textarea.js +1 -1
  266. package/dist/{theme-DAYTVw13.cjs → theme-Ce9eIP05.cjs} +1 -1
  267. package/dist/{theme-DAYTVw13.cjs.map → theme-Ce9eIP05.cjs.map} +1 -1
  268. package/dist/{theme-DAx1iRNr.js → theme-XO3nHDbW.js} +2 -2
  269. package/dist/{theme-DAx1iRNr.js.map → theme-XO3nHDbW.js.map} +1 -1
  270. package/dist/{theme-button-BrHkzCtj.js → theme-button-DNutDO1j.js} +1 -1
  271. package/dist/{theme-button-BrHkzCtj.js.map → theme-button-DNutDO1j.js.map} +1 -1
  272. package/dist/{theme-button-LsMKY_N_.cjs → theme-button-H7PRz_bg.cjs} +1 -1
  273. package/dist/{theme-button-LsMKY_N_.cjs.map → theme-button-H7PRz_bg.cjs.map} +1 -1
  274. package/dist/theme-button.cjs +1 -1
  275. package/dist/theme-button.js +1 -1
  276. package/dist/theme.cjs +1 -1
  277. package/dist/{theme.interface-C_034TxG.js.map → theme.interface-B9TjbSBF.js.map} +1 -1
  278. package/dist/{theme.interface-DESopuZS.cjs.map → theme.interface-BujperTo.cjs.map} +1 -1
  279. package/dist/theme.js +3 -3
  280. package/dist/tree.cjs +1 -1
  281. package/dist/tree.js +1 -1
  282. package/dist/typography.cjs +1 -1
  283. package/dist/typography.js +1 -1
  284. package/dist/{utils-oLBkMvor.cjs → utils-Dt5PpmaQ.cjs} +1 -1
  285. package/dist/{utils-oLBkMvor.cjs.map → utils-Dt5PpmaQ.cjs.map} +1 -1
  286. package/dist/{utils-BzFQfaIr.js → utils-kND2Z9Xg.js} +1 -1
  287. package/dist/{utils-BzFQfaIr.js.map → utils-kND2Z9Xg.js.map} +1 -1
  288. package/dist/utils.cjs +1 -1
  289. package/dist/utils.js +2 -2
  290. package/dist/visually-hidden.cjs +1 -1
  291. package/dist/visually-hidden.js +1 -1
  292. package/dist/{window-BJrKS6Zr.cjs → window-BaoSwgGE.cjs} +1 -1
  293. package/dist/{window-BJrKS6Zr.cjs.map → window-BaoSwgGE.cjs.map} +1 -1
  294. package/dist/{window-CyDuTN80.js → window-KnLWhQ3S.js} +2 -2
  295. package/dist/{window-CyDuTN80.js.map → window-KnLWhQ3S.js.map} +1 -1
  296. package/dist/window.cjs +1 -1
  297. package/dist/window.js +1 -1
  298. package/package.json +4 -5
  299. package/skills/schmancy/INDEX.md +9 -6
  300. package/src/index.ts +0 -8
  301. package/types/src/index.d.ts +0 -8
  302. package/dist/agent/vendor-highlight-CHJZQQB7.js +0 -2178
  303. package/dist/agent/vendor-highlight-CHJZQQB7.js.map +0 -1
  304. package/dist/agent/vendor-jsqr-r7GNh4P3.js +0 -10212
  305. package/dist/agent/vendor-jsqr-r7GNh4P3.js.map +0 -1
  306. package/dist/charts.cjs +0 -112
  307. package/dist/charts.cjs.map +0 -1
  308. package/dist/charts.js +0 -374
  309. package/dist/charts.js.map +0 -1
  310. package/dist/code-highlight-Ddp0oZnm.cjs +0 -190
  311. package/dist/code-highlight-Ddp0oZnm.cjs.map +0 -1
  312. package/dist/code-highlight-DtE2-ObF.js +0 -296
  313. package/dist/code-highlight-DtE2-ObF.js.map +0 -1
  314. package/dist/code-highlight.cjs +0 -1
  315. package/dist/code-highlight.js +0 -2
  316. package/dist/extra-B8IPs6gG.cjs +0 -31
  317. package/dist/extra-B8IPs6gG.cjs.map +0 -1
  318. package/dist/extra-DxEWs41z.js +0 -3440
  319. package/dist/extra-DxEWs41z.js.map +0 -1
  320. package/dist/extra.cjs +0 -1
  321. package/dist/extra.js +0 -2
  322. package/dist/mailbox-CDWqbVvZ.cjs +0 -1140
  323. package/dist/mailbox-CDWqbVvZ.cjs.map +0 -1
  324. package/dist/mailbox-DD2How0H.js +0 -1607
  325. package/dist/mailbox-DD2How0H.js.map +0 -1
  326. package/dist/mailbox.cjs +0 -1
  327. package/dist/mailbox.js +0 -2
  328. package/dist/map-1uwxxvBa.js +0 -208
  329. package/dist/map-1uwxxvBa.js.map +0 -1
  330. package/dist/map-BrBSrIqg.cjs +0 -80
  331. package/dist/map-BrBSrIqg.cjs.map +0 -1
  332. package/dist/map.cjs +0 -1
  333. package/dist/map.js +0 -2
  334. package/dist/mixins-B34UxxCe.js +0 -627
  335. package/dist/mixins-CAb0b03r.cjs +0 -298
  336. package/dist/payment-card-form-C4jb-OdM.js +0 -729
  337. package/dist/payment-card-form-C4jb-OdM.js.map +0 -1
  338. package/dist/payment-card-form-WEx4CscR.cjs +0 -73
  339. package/dist/payment-card-form-WEx4CscR.cjs.map +0 -1
  340. package/dist/payment-card-form.cjs +0 -1
  341. package/dist/payment-card-form.js +0 -2
  342. package/dist/qr-scanner.cjs +0 -35
  343. package/dist/qr-scanner.cjs.map +0 -1
  344. package/dist/qr-scanner.js +0 -123
  345. package/dist/qr-scanner.js.map +0 -1
  346. package/dist/skills/charts.md +0 -93
  347. package/dist/skills/code-highlight.md +0 -47
  348. package/dist/skills/extra.md +0 -59
  349. package/dist/skills/mailbox.md +0 -102
  350. package/dist/skills/map.md +0 -55
  351. package/dist/skills/qr-scanner.md +0 -51
  352. package/dist/skills/schmancy/charts.md +0 -93
  353. package/dist/skills/schmancy/code-highlight.md +0 -47
  354. package/dist/skills/schmancy/extra.md +0 -59
  355. package/dist/skills/schmancy/mailbox.md +0 -102
  356. package/dist/skills/schmancy/map.md +0 -55
  357. package/dist/skills/schmancy/qr-scanner.md +0 -51
  358. package/dist/skills/schmancy/timeline-tile.md +0 -95
  359. package/dist/skills/timeline-tile.md +0 -95
  360. package/dist/timeline.cjs +0 -277
  361. package/dist/timeline.cjs.map +0 -1
  362. package/dist/timeline.js +0 -326
  363. package/dist/timeline.js.map +0 -1
  364. package/skills/schmancy/charts.md +0 -93
  365. package/skills/schmancy/code-highlight.md +0 -47
  366. package/skills/schmancy/extra.md +0 -59
  367. package/skills/schmancy/mailbox.md +0 -102
  368. package/skills/schmancy/map.md +0 -55
  369. package/skills/schmancy/qr-scanner.md +0 -51
  370. package/skills/schmancy/timeline-tile.md +0 -95
  371. package/src/charts/area-chart.ts +0 -498
  372. package/src/charts/index.ts +0 -4
  373. package/src/charts/pills.ts +0 -352
  374. package/src/charts/types.ts +0 -66
  375. package/src/charts/utils.ts +0 -65
  376. package/src/code-highlight/code-highlight.ts +0 -345
  377. package/src/code-highlight/code-preview.ts +0 -125
  378. package/src/code-highlight/index.ts +0 -3
  379. package/src/extra/countries/countries.data.ts +0 -196
  380. package/src/extra/countries/countries.ts +0 -109
  381. package/src/extra/countries/index.ts +0 -2
  382. package/src/extra/index.ts +0 -2
  383. package/src/extra/timezone/index.ts +0 -2
  384. package/src/extra/timezone/timezone.ts +0 -118
  385. package/src/extra/timezone/timezones.data.ts +0 -2546
  386. package/src/mailbox/README.md +0 -128
  387. package/src/mailbox/email-editor.ts +0 -1076
  388. package/src/mailbox/email-layout-selector.ts +0 -58
  389. package/src/mailbox/email-recipients.ts +0 -599
  390. package/src/mailbox/email-template-picker.ts +0 -303
  391. package/src/mailbox/email-viewer.ts +0 -717
  392. package/src/mailbox/index.ts +0 -31
  393. package/src/mailbox/mailbox.ts +0 -364
  394. package/src/mailbox/types.ts +0 -180
  395. package/src/map/index.ts +0 -1
  396. package/src/map/map.ts +0 -485
  397. package/src/payment-card-form/index.ts +0 -1
  398. package/src/payment-card-form/payment-card-form.ts +0 -331
  399. package/src/qr-scanner/index.ts +0 -1
  400. package/src/qr-scanner/qr-scanner.ts +0 -242
  401. package/src/timeline/index.ts +0 -1
  402. package/src/timeline/timeline-tile.ts +0 -431
  403. package/types/src/charts/area-chart.d.ts +0 -58
  404. package/types/src/charts/index.d.ts +0 -4
  405. package/types/src/charts/pills.d.ts +0 -51
  406. package/types/src/charts/types.d.ts +0 -62
  407. package/types/src/charts/utils.d.ts +0 -28
  408. package/types/src/code-highlight/code-highlight.d.ts +0 -49
  409. package/types/src/code-highlight/code-preview.d.ts +0 -30
  410. package/types/src/code-highlight/index.d.ts +0 -3
  411. package/types/src/extra/countries/countries.d.ts +0 -26
  412. package/types/src/extra/countries/countries.data.d.ts +0 -5
  413. package/types/src/extra/countries/index.d.ts +0 -2
  414. package/types/src/extra/index.d.ts +0 -2
  415. package/types/src/extra/timezone/index.d.ts +0 -2
  416. package/types/src/extra/timezone/timezone.d.ts +0 -34
  417. package/types/src/extra/timezone/timezones.data.d.ts +0 -7
  418. package/types/src/mailbox/email-editor.d.ts +0 -101
  419. package/types/src/mailbox/email-layout-selector.d.ts +0 -18
  420. package/types/src/mailbox/email-recipients.d.ts +0 -122
  421. package/types/src/mailbox/email-template-picker.d.ts +0 -54
  422. package/types/src/mailbox/email-viewer.d.ts +0 -86
  423. package/types/src/mailbox/index.d.ts +0 -12
  424. package/types/src/mailbox/mailbox.d.ts +0 -82
  425. package/types/src/mailbox/types.d.ts +0 -176
  426. package/types/src/map/index.d.ts +0 -1
  427. package/types/src/map/map.d.ts +0 -130
  428. package/types/src/payment-card-form/index.d.ts +0 -1
  429. package/types/src/payment-card-form/payment-card-form.d.ts +0 -85
  430. package/types/src/qr-scanner/index.d.ts +0 -1
  431. package/types/src/qr-scanner/qr-scanner.d.ts +0 -26
  432. package/types/src/timeline/index.d.ts +0 -1
  433. package/types/src/timeline/timeline-tile.d.ts +0 -44
  434. /package/dist/agent/{flow-CaPi2G8y.js → flow-CvG1fLW5.js} +0 -0
  435. /package/dist/agent/{vendor-material-color-Be96dpGE.js → vendor-material-color-DcL7ZPxx.js} +0 -0
  436. /package/dist/{form-CI59gad4.js → form-CFvwnfuJ.js} +0 -0
  437. /package/dist/{form-B2qudx_q.cjs → form-Ceijw1aA.cjs} +0 -0
  438. /package/dist/{hashContent-a8uVr3xs.js → hashContent-BU6jl5ih.js} +0 -0
  439. /package/dist/{hashContent-ejkBgDnN.cjs → hashContent-Bobsobip.cjs} +0 -0
  440. /package/dist/{overlay-stack-CCiTaf_C.js → overlay-stack-DCDS17uj.js} +0 -0
  441. /package/dist/{overlay-stack-CFGiYf34.cjs → overlay-stack-DPIe_aYv.cjs} +0 -0
  442. /package/dist/{rxjs-utils-BXpvHN4-.js → rxjs-utils-CVeJQ9KG.js} +0 -0
  443. /package/dist/{rxjs-utils-CaC-tdot.cjs → rxjs-utils-DCUHg_Ml.cjs} +0 -0
  444. /package/dist/{theme.interface-C_034TxG.js → theme.interface-B9TjbSBF.js} +0 -0
  445. /package/dist/{theme.interface-DESopuZS.cjs → theme.interface-BujperTo.cjs} +0 -0
@@ -1,1076 +0,0 @@
1
- import { SchmancyElement } from '@mixins/index'
2
- import { css, html } from 'lit'
3
- import { customElement, property, state } from 'lit/decorators.js'
4
- import { createRef, ref } from 'lit/directives/ref.js'
5
- import { repeat } from 'lit/directives/repeat.js'
6
- import { when } from 'lit/directives/when.js'
7
- import { fromEvent, takeUntil } from 'rxjs'
8
- import { $notify } from '../notification'
9
- import { show } from '../overlay/overlay.service'
10
- import './email-layout-selector'
11
- import SchmancyTextarea from '../textarea/textarea'
12
- import { SchmancyEmailTemplatePicker } from './email-template-picker'
13
- import type { EmailAttachment, EmailComposeConfig, EmailTemplate } from './types'
14
-
15
- /**
16
- * Email editor component with rich text formatting and file attachments
17
- *
18
- * Features:
19
- * - Markdown formatting toolbar
20
- * - Image upload and insertion
21
- * - File attachments with drag & drop
22
- * - Layout templates (columns, sidebars, image rows)
23
- * - Real-time character/word count
24
- *
25
- * @example
26
- * ```html
27
- * <schmancy-email-editor
28
- * .subject="Welcome to our service"
29
- * .body="Email content..."
30
- * @editor-change=${handleChange}
31
- * ></schmancy-email-editor>
32
- * ```
33
- */
34
- @customElement('schmancy-email-editor')
35
- export class SchmancyEmailEditor extends SchmancyElement {
36
- static styles = [css`
37
- :host {
38
- display: block;
39
- height: 100%;
40
- }
41
- `]
42
-
43
- /** Email subject */
44
- @property({ type: String }) subject = ''
45
-
46
- /** Email body content (markdown) */
47
- @property({ type: String }) body = ''
48
-
49
-
50
- /** Disable all interactions */
51
- @property({ type: Boolean }) disabled = false
52
-
53
- /** Email attachments */
54
- @property({ type: Array }) attachments: EmailAttachment[] = []
55
-
56
- /** Configuration for upload handlers */
57
- @property({ type: Object }) config: EmailComposeConfig = {}
58
-
59
- /** Available email templates */
60
- @property({ type: Array }) templates: EmailTemplate[] = this.getDefaultTemplates()
61
-
62
- /** Internal state */
63
- @state() private dragOver = false
64
- @state() private isUploading = false
65
-
66
- /** Element references */
67
- private subjectInputRef = createRef<HTMLInputElement>()
68
- private bodyTextAreaRef = createRef<SchmancyTextarea>()
69
- private fileInputRef = createRef<HTMLInputElement>()
70
- private imageInputRef = createRef<HTMLInputElement>()
71
-
72
- connectedCallback() {
73
- super.connectedCallback()
74
- this.addEventListeners()
75
- }
76
-
77
- disconnectedCallback() {
78
- super.disconnectedCallback()
79
- // Event listeners are automatically cleaned up via takeUntil(this.disconnecting)
80
- }
81
-
82
- /** Get default email templates */
83
- private getDefaultTemplates(): EmailTemplate[] {
84
- return [
85
- {
86
- id: 'welcome',
87
- name: 'Welcome Email',
88
- subject: 'Welcome to Our Community! 🌟',
89
- description: 'A warm welcome message for new users',
90
- category: 'onboarding',
91
- body: `# Welcome to Our Community!
92
-
93
- We're thrilled to have you on board. Thank you for joining us on this journey.
94
-
95
- ## What's Next?
96
-
97
- * **Explore** your dashboard and discover all the features
98
- * **Connect** with other community members
99
- * **Get support** whenever you need it - we're here to help
100
-
101
- ---
102
-
103
- *Need assistance? Simply reply to this email and we'll get back to you within 24 hours.*
104
-
105
- Best regards,
106
- The Team`
107
- },
108
- {
109
- id: 'newsletter',
110
- name: 'Newsletter',
111
- subject: 'Weekly Insights & Updates',
112
- description: 'Regular newsletter template with updates and insights',
113
- category: 'communication',
114
- body: `# This Week's Highlights
115
-
116
- ## Featured Story
117
-
118
- **[Article Title]**
119
- Brief description of the main story or update that you want to highlight this week.
120
-
121
- [Read More](https://example.com)
122
-
123
- ## Quick Updates
124
-
125
- * **Update 1**: Brief description of an important update
126
- * **Update 2**: Another noteworthy development
127
- * **Update 3**: Additional news worth sharing
128
-
129
- ## Upcoming Events
130
-
131
- **[Event Name]** - *Date*
132
- Short description of the upcoming event.
133
-
134
- ---
135
-
136
- *Thanks for reading! Forward this to a friend who might enjoy it.*
137
-
138
- Until next week,
139
- The Team`
140
- },
141
- {
142
- id: 'product-launch',
143
- name: 'Product Launch',
144
- subject: 'Introducing Our Latest Innovation 🚀',
145
- description: 'Announce new products or features',
146
- category: 'marketing',
147
- body: `# Something Amazing is Here
148
-
149
- We've been working hard behind the scenes, and today we're excited to introduce our latest creation.
150
-
151
- ## Key Features
152
-
153
- * **Feature 1**: Benefit that matters to your users
154
- * **Feature 2**: Another compelling capability
155
- * **Feature 3**: The feature that sets you apart
156
-
157
- ## Early Access
158
-
159
- As a valued member, you get **exclusive early access** starting today.
160
-
161
- [Get Started Now](https://example.com)
162
-
163
- ---
164
-
165
- *Questions? We'd love to hear from you. Just hit reply!*
166
-
167
- Best,
168
- The Product Team`
169
- },
170
- {
171
- id: 'event-invitation',
172
- name: 'Event Invitation',
173
- subject: 'You\'re Invited: [Event Name]',
174
- description: 'Professional event invitation template',
175
- category: 'events',
176
- body: `# You're Invited!
177
-
178
- ## [Event Name]
179
-
180
- **When**: [Date & Time]
181
- **Where**: [Location or Virtual Link]
182
- **Duration**: [Duration]
183
-
184
- Join us for an exclusive gathering where we'll explore [brief event description].
185
-
186
- ## What to Expect
187
-
188
- * **Networking** with industry professionals
189
- * **Insights** from leading experts
190
- * **Interactive** sessions and discussions
191
-
192
- ## RSVP Required
193
-
194
- Space is limited, so please confirm your attendance by [RSVP Date].
195
-
196
- [Confirm Attendance](https://example.com)
197
-
198
- ---
199
-
200
- *Can't make it? Let us know and we'll share the key highlights with you.*
201
-
202
- Looking forward to seeing you there,
203
- The Events Team`
204
- },
205
- {
206
- id: 'thank-you',
207
- name: 'Thank You',
208
- subject: 'Thank You - It Means Everything',
209
- description: 'Express gratitude to customers or supporters',
210
- category: 'appreciation',
211
- body: `# Thank You
212
-
213
- Your support means the world to us.
214
-
215
- Whether you've been with us from the beginning or just joined our community, we want you to know how much we appreciate you.
216
-
217
- ## Because of You
218
-
219
- * We've been able to improve our service
220
- * Our community has grown stronger
221
- * We've achieved milestones we never thought possible
222
-
223
- ## What's Next
224
-
225
- We're committed to continuing to earn your trust and providing even more value in the coming months.
226
-
227
- ---
228
-
229
- *Your feedback shapes everything we do. Reply anytime with thoughts or suggestions.*
230
-
231
- With genuine gratitude,
232
- The Team`
233
- },
234
- {
235
- id: 'feedback-request',
236
- name: 'Feedback Request',
237
- subject: 'Your Opinion Matters - 2 Minutes?',
238
- description: 'Request feedback or reviews from users',
239
- category: 'feedback',
240
- body: `# We'd Love Your Feedback
241
-
242
- Your experience matters to us, and we're always looking for ways to improve.
243
-
244
- ## Quick Favor?
245
-
246
- Could you spare **2 minutes** to share your thoughts? Your honest feedback helps us serve you better.
247
-
248
- [Share Your Feedback](https://example.com)
249
-
250
- ## What We're Asking
251
-
252
- * How has your experience been so far?
253
- * What's working well for you?
254
- * What could we improve?
255
-
256
- ## Thank You Gift
257
-
258
- As a small token of appreciation, everyone who completes our feedback form receives [incentive].
259
-
260
- ---
261
-
262
- *Every response is read personally by our team. We take your input seriously.*
263
-
264
- Thanks in advance,
265
- The Team`
266
- },
267
- {
268
- id: 'password-reset',
269
- name: 'Password Reset',
270
- subject: 'Reset Your Password - Action Required',
271
- description: 'Secure password reset instructions',
272
- category: 'security',
273
- body: `# Password Reset Request
274
-
275
- We received a request to reset the password for your account.
276
-
277
- ## Reset Your Password
278
-
279
- Click the button below to create a new password. This link will expire in **24 hours** for your security.
280
-
281
- [Reset Password](https://example.com/reset)
282
-
283
- ## Didn't Request This?
284
-
285
- If you didn't request a password reset, please ignore this email. Your account remains secure.
286
-
287
- ## Need Help?
288
-
289
- If you're having trouble with the reset process, contact our support team and we'll assist you right away.
290
-
291
- ---
292
-
293
- *For security reasons, this link can only be used once and expires in 24 hours.*
294
-
295
- Best regards,
296
- Security Team`
297
- },
298
- {
299
- id: 'order-confirmation',
300
- name: 'Order Confirmation',
301
- subject: 'Order Confirmed - #[ORDER-NUMBER]',
302
- description: 'Professional order confirmation template',
303
- category: 'commerce',
304
- body: `# Order Confirmation
305
-
306
- Thanks for your order! We've received your payment and are preparing your items for shipment.
307
-
308
- ## Order Details
309
-
310
- **Order Number**: #[ORDER-NUMBER]
311
- **Order Date**: [DATE]
312
- **Total**: $[AMOUNT]
313
-
314
- ## Items Ordered
315
-
316
- * **[Item 1]** - Quantity: [QTY] - $[PRICE]
317
- * **[Item 2]** - Quantity: [QTY] - $[PRICE]
318
-
319
- ## Shipping Information
320
-
321
- **Address**: [SHIPPING ADDRESS]
322
- **Method**: [SHIPPING METHOD]
323
- **Estimated Delivery**: [DELIVERY DATE]
324
-
325
- ## Next Steps
326
-
327
- You'll receive a tracking number via email once your order ships (usually within 1-2 business days).
328
-
329
- [Track Your Order](https://example.com/track)
330
-
331
- ---
332
-
333
- *Questions about your order? Reply to this email or contact our support team.*
334
-
335
- Thank you for your business,
336
- The Fulfillment Team`
337
- }
338
- ]
339
- }
340
-
341
- private addEventListeners() {
342
- // Keyboard events
343
- fromEvent(this, 'keydown').pipe(
344
- takeUntil(this.disconnecting)
345
- ).subscribe(this.handleKeyDown)
346
-
347
- // Document paste events
348
- fromEvent(document, 'paste').pipe(
349
- takeUntil(this.disconnecting)
350
- ).subscribe(this.handlePaste)
351
-
352
- // Document drag events
353
- fromEvent(document, 'dragenter').pipe(
354
- takeUntil(this.disconnecting)
355
- ).subscribe(this.handleDragEnter)
356
-
357
- fromEvent(document, 'dragleave').pipe(
358
- takeUntil(this.disconnecting)
359
- ).subscribe(this.handleDocumentDragLeave)
360
-
361
- fromEvent(document, 'drop').pipe(
362
- takeUntil(this.disconnecting)
363
- ).subscribe(this.handleDocumentDrop)
364
- }
365
-
366
- /** Handle keyboard shortcuts and tab indentation */
367
- private handleKeyDown = (e: KeyboardEvent) => {
368
- if (this.disabled) return
369
-
370
- // Tab key inserts 2 spaces instead of changing focus
371
- const textarea = this.bodyTextAreaRef.value?.shadowRoot?.querySelector('textarea')
372
- if (e.key === 'Tab' && e.target === textarea) {
373
- e.preventDefault()
374
- this.insertAtCursor(' ')
375
- }
376
- }
377
-
378
- /** Handle paste events for image pasting */
379
- private handlePaste = (event: ClipboardEvent) => {
380
- const textarea = this.bodyTextAreaRef.value?.shadowRoot?.querySelector('textarea')
381
- if (this.disabled || document.activeElement !== textarea) return
382
-
383
- const items = event.clipboardData?.items
384
- if (!items) return
385
-
386
- for (let i = 0; i < items.length; i++) {
387
- const item = items[i]
388
- if (item.type.indexOf('image') !== -1) {
389
- event.preventDefault()
390
- const file = item.getAsFile()
391
- if (file) {
392
- this.uploadImage(file)
393
- }
394
- break
395
- }
396
- }
397
- }
398
-
399
- /** Handle subject input changes */
400
- private handleSubjectChange = (event: Event) => {
401
- const input = event.target as HTMLInputElement
402
- this.subject = input.value
403
- this.dispatchChange()
404
- }
405
-
406
- /** Handle body textarea changes */
407
- private handleBodyChange = (event: CustomEvent<{ value: string }>) => {
408
- this.body = event.detail.value
409
- this.dispatchChange()
410
- }
411
-
412
- /** Dispatch composer change event */
413
- private dispatchChange = () => {
414
- this.dispatchEvent(new CustomEvent('editor-change', {
415
- detail: {
416
- subject: this.subject,
417
- body: this.body,
418
- attachments: this.attachments
419
- },
420
- bubbles: true,
421
- composed: true
422
- }))
423
- }
424
-
425
- /** Insert text at cursor position */
426
- private insertAtCursor(text: string, selectText?: string) {
427
- if (!this.bodyTextAreaRef.value) return
428
-
429
- // For schmancy-textarea, access the internal textarea
430
- const textarea = this.bodyTextAreaRef.value.shadowRoot?.querySelector('textarea')
431
- if (!textarea) return
432
-
433
- const start = textarea.selectionStart
434
- const end = textarea.selectionEnd
435
-
436
- const newValue =
437
- textarea.value.substring(0, start) +
438
- text +
439
- textarea.value.substring(end)
440
-
441
- this.body = newValue
442
- this.dispatchChange()
443
-
444
- this.updateComplete.then(() => {
445
- const updatedTextarea = this.bodyTextAreaRef.value?.shadowRoot?.querySelector('textarea')
446
- if (updatedTextarea) {
447
- updatedTextarea.focus()
448
- if (selectText) {
449
- const selectStart = start + text.indexOf(selectText)
450
- const selectEnd = selectStart + selectText.length
451
- updatedTextarea.setSelectionRange(selectStart, selectEnd)
452
- } else {
453
- updatedTextarea.setSelectionRange(start + text.length, start + text.length)
454
- }
455
- }
456
- return
457
- })
458
- }
459
-
460
- /** Wrap selected text with formatting */
461
- private wrapSelection(before: string, after: string, placeholder: string) {
462
- if (!this.bodyTextAreaRef.value) return
463
-
464
- // For schmancy-textarea, access the internal textarea
465
- const textarea = this.bodyTextAreaRef.value.shadowRoot?.querySelector('textarea')
466
- if (!textarea) return
467
-
468
- const start = textarea.selectionStart
469
- const end = textarea.selectionEnd
470
- const selectedText = textarea.value.substring(start, end)
471
-
472
- const textToWrap = selectedText || placeholder
473
- const newText = before + textToWrap + after
474
-
475
- const newValue =
476
- textarea.value.substring(0, start) +
477
- newText +
478
- textarea.value.substring(end)
479
-
480
- this.body = newValue
481
- this.dispatchChange()
482
-
483
- this.updateComplete.then(() => {
484
- const updatedTextarea = this.bodyTextAreaRef.value?.shadowRoot?.querySelector('textarea')
485
- if (updatedTextarea) {
486
- updatedTextarea.focus()
487
- if (!selectedText) {
488
- // Select the placeholder text
489
- updatedTextarea.setSelectionRange(start + before.length, start + before.length + placeholder.length)
490
- } else {
491
- // Position cursor at the end
492
- updatedTextarea.setSelectionRange(start + newText.length, start + newText.length)
493
- }
494
- }
495
- return
496
- })
497
- }
498
-
499
- /** Open layout selection dialog */
500
- private openLayoutDialog = () => {
501
- // Inline-template overlay; the selector's `layout-select` event is
502
- // re-dispatched as `close` so `show()` resolves with the chosen layout.
503
- show<string>(html`
504
- <schmancy-email-layout-selector
505
- @layout-select=${(e: CustomEvent) => {
506
- e.currentTarget?.dispatchEvent(
507
- new CustomEvent('close', { detail: e.detail.layout, bubbles: true, composed: true }),
508
- )
509
- }}
510
- ></schmancy-email-layout-selector>
511
- `)
512
- .pipe(takeUntil(this.disconnecting))
513
- .subscribe(layout => {
514
- if (layout) this.applyLayout(layout)
515
- })
516
- }
517
-
518
- /** Open template picker */
519
- private openTemplatePicker = () => {
520
- show<EmailTemplate>(SchmancyEmailTemplatePicker, { props: { templates: this.templates } })
521
- .pipe(takeUntil(this.disconnecting))
522
- .subscribe(template => {
523
- if (template) this.handleTemplateSelected(template)
524
- })
525
- }
526
-
527
- /** Handle template selection */
528
- private handleTemplateSelected = (template: EmailTemplate) => {
529
- this.subject = template.subject
530
- this.body = template.body
531
- this.dispatchChange()
532
- $notify.success(`Template "${template.name}" applied successfully`)
533
- }
534
-
535
- /** Apply layout template to content */
536
- private applyLayout = (layoutType: string) => {
537
- const layouts: Record<string, string> = {
538
- 'columns-2': `
539
- :::layout columns-2
540
- <div class="column">
541
- ![Left Photo](https://via.placeholder.com/400x300?text=Replace+with+your+photo){height=300px}
542
-
543
- **Photo Title**
544
-
545
- Replace the placeholder image above with your own photo. The height=300px ensures both images have equal height while width adjusts automatically.
546
- </div>
547
-
548
- <div class="column">
549
- ![Right Photo](https://via.placeholder.com/400x300?text=Replace+with+your+photo){height=300px}
550
-
551
- **Photo Title**
552
-
553
- Use the same height value (300px) for both images to keep them aligned perfectly side by side.
554
- </div>
555
- :::
556
- `,
557
- 'columns-3': `
558
- :::layout columns-3
559
- <div class="column">
560
- ![Photo 1](https://via.placeholder.com/300x200?text=Photo+1){height=200px}
561
-
562
- **Item Title**
563
-
564
- Brief description or caption for this item.
565
- </div>
566
-
567
- <div class="column">
568
- ![Photo 2](https://via.placeholder.com/300x200?text=Photo+2){height=200px}
569
-
570
- **Item Title**
571
-
572
- Brief description or caption for this item.
573
- </div>
574
-
575
- <div class="column">
576
- ![Photo 3](https://via.placeholder.com/300x200?text=Photo+3){height=200px}
577
-
578
- **Item Title**
579
-
580
- Brief description or caption for this item.
581
- </div>
582
- :::
583
- `,
584
- 'sidebar-left': `
585
- :::layout sidebar-left
586
- <div class="sidebar">
587
- **Sidebar Content**
588
-
589
- * Navigation item 1
590
- * Navigation item 2
591
- * Navigation item 3
592
- </div>
593
-
594
- <div class="main">
595
- **Main Content Area**
596
-
597
- Your primary content goes here. This area takes up most of the width while the sidebar provides supplementary information or navigation.
598
- </div>
599
- :::
600
- `,
601
- 'sidebar-right': `
602
- :::layout sidebar-right
603
- <div class="main">
604
- **Main Content Area**
605
-
606
- Your primary content goes here. This area takes up most of the width while the sidebar provides supplementary information or navigation.
607
- </div>
608
-
609
- <div class="sidebar">
610
- **Sidebar Content**
611
-
612
- * Quick links
613
- * Related info
614
- * Contact details
615
- </div>
616
- :::
617
- `,
618
- 'image-row': `
619
- :::layout image-row
620
- <div class="image">
621
- ![Gallery Image 1](https://via.placeholder.com/400x250?text=Gallery+Image+1){height=250px}
622
- </div>
623
-
624
- <div class="image">
625
- ![Gallery Image 2](https://via.placeholder.com/400x250?text=Gallery+Image+2){height=250px}
626
- </div>
627
-
628
- <div class="image">
629
- ![Gallery Image 3](https://via.placeholder.com/400x250?text=Gallery+Image+3){height=250px}
630
- </div>
631
- :::
632
- `
633
- }
634
-
635
- const layoutMarkdown = layouts[layoutType]
636
- if (layoutMarkdown) {
637
- this.insertAtCursor(layoutMarkdown)
638
- }
639
- }
640
-
641
- /** Upload image with configurable handler */
642
- private uploadImage = async (file: File) => {
643
- if (!file.type.startsWith('image/')) {
644
- $notify.error(`File "${file.name}" is not an image`)
645
- return
646
- }
647
-
648
- // Check file size (max 10MB for images)
649
- const maxSize = 10 * 1024 * 1024
650
- if (file.size > maxSize) {
651
- $notify.error(`Image "${file.name}" is too large. Maximum size is 10MB.`)
652
- return
653
- }
654
-
655
- // Show loading state
656
- this.isUploading = true
657
-
658
- try {
659
- let url: string
660
-
661
- if (this.config.imageUploadHandler) {
662
- // Use custom upload handler
663
- url = await this.config.imageUploadHandler(file)
664
- } else if (this.config.uploadHandler) {
665
- // Use generic upload handler
666
- url = await this.config.uploadHandler(file)
667
- } else {
668
- // Fallback to data URL for preview
669
- url = await this.createDataUrl(file)
670
- $notify.warning('No upload handler configured. Using local preview.')
671
- }
672
-
673
- // Get image dimensions
674
- const dimensions = await this.getImageDimensions(file)
675
-
676
- // Insert markdown at cursor position
677
- this.insertImageMarkdown(url, file.name, dimensions.width, dimensions.height)
678
-
679
- $notify.success('Image uploaded successfully')
680
- } catch (error) {
681
- console.error('Upload failed:', error)
682
- $notify.error('Failed to upload image')
683
- } finally {
684
- this.isUploading = false
685
- }
686
- }
687
-
688
- /** Create data URL for local preview */
689
- private createDataUrl = (file: File): Promise<string> => {
690
- return new Promise((resolve, reject) => {
691
- const reader = new FileReader()
692
- reader.addEventListener('load', () => resolve(reader.result as string), { once: true })
693
- reader.addEventListener('error', () => reject(reader.error), { once: true })
694
- reader.readAsDataURL(file)
695
- })
696
- }
697
-
698
- /** Get image dimensions */
699
- private getImageDimensions = (file: File): Promise<{width: number, height: number}> => {
700
- return new Promise((resolve) => {
701
- const img = new Image()
702
- img.addEventListener('load', () => {
703
- resolve({ width: img.width, height: img.height })
704
- URL.revokeObjectURL(img.src)
705
- }, { once: true })
706
- img.addEventListener('error', () => {
707
- resolve({ width: 400, height: 300 }) // Default dimensions
708
- URL.revokeObjectURL(img.src)
709
- }, { once: true })
710
- img.src = URL.createObjectURL(file)
711
- })
712
- }
713
-
714
- /** Insert image markdown at cursor */
715
- private insertImageMarkdown = (url: string, alt: string, width: number, _height: number) => {
716
- const textarea = this.bodyTextAreaRef.value?.shadowRoot?.querySelector('textarea')
717
- if (!textarea) return
718
-
719
- const markdown = `![${alt}](${url}){width=${Math.min(width, 600)}px height=auto}`
720
-
721
- const start = textarea.selectionStart
722
- const end = textarea.selectionEnd
723
- const newValue =
724
- this.body.substring(0, start) +
725
- markdown +
726
- this.body.substring(end)
727
-
728
- this.body = newValue
729
- this.dispatchChange()
730
-
731
- // Set cursor after inserted markdown
732
- this.updateComplete.then(() => {
733
- const updatedTextarea = this.bodyTextAreaRef.value?.shadowRoot?.querySelector('textarea')
734
- if (updatedTextarea) {
735
- const newPosition = start + markdown.length
736
- updatedTextarea.setSelectionRange(newPosition, newPosition)
737
- updatedTextarea.focus()
738
- }
739
- return
740
- })
741
- }
742
-
743
-
744
- /** Handle file input changes */
745
- private handleFileChange = (event: Event) => {
746
- const input = event.target as HTMLInputElement
747
- const files = input.files
748
- if (files) {
749
- for (let i = 0; i < files.length; i++) {
750
- const file = files[i]
751
- if (file.type.startsWith('image/')) {
752
- this.uploadImage(file)
753
- } else {
754
- this.addFile(file)
755
- }
756
- }
757
- }
758
- input.value = ''
759
- }
760
-
761
- /** Handle image selection */
762
- private handleImageSelect = (event: Event) => {
763
- const input = event.target as HTMLInputElement
764
- const file = input.files?.[0]
765
- if (file && file.type.startsWith('image/')) {
766
- this.uploadImage(file)
767
- }
768
- input.value = '' // Reset for next selection
769
- }
770
-
771
- /** Drag and drop handlers */
772
- private handleDrop = (event: DragEvent) => {
773
- event.preventDefault()
774
- this.dragOver = false
775
-
776
- const files = event.dataTransfer?.files
777
- if (files) {
778
- for (let i = 0; i < files.length; i++) {
779
- const file = files[i]
780
- if (file.type.startsWith('image/')) {
781
- this.uploadImage(file)
782
- } else {
783
- this.addFile(file)
784
- }
785
- }
786
- }
787
- }
788
-
789
- private handleDragEnter = (event: DragEvent) => {
790
- event.preventDefault()
791
- this.dragOver = true
792
- }
793
-
794
- private handleDocumentDragLeave = (event: DragEvent) => {
795
- event.preventDefault()
796
- this.dragOver = false
797
- }
798
-
799
- private handleDocumentDrop = (event: DragEvent) => {
800
- event.preventDefault()
801
- this.dragOver = false
802
- }
803
-
804
- private handleDragOver = (event: DragEvent) => {
805
- event.preventDefault()
806
- }
807
-
808
- private handleDragLeave = (event: DragEvent) => {
809
- event.preventDefault()
810
- // Let document handler manage this
811
- }
812
-
813
- /** Add file as attachment */
814
- private addFile = (file: File) => {
815
- // Check file size (max 10MB)
816
- const maxSize = 10 * 1024 * 1024
817
- if (file.size > maxSize) {
818
- $notify.error(`File "${file.name}" is too large. Maximum size is 10MB.`)
819
- return
820
- }
821
-
822
- // Check if file already exists
823
- const exists = this.attachments.some(att =>
824
- att.name === file.name && att.size === file.size
825
- )
826
- if (exists) {
827
- $notify.warning(`File "${file.name}" is already attached.`)
828
- return
829
- }
830
-
831
- const attachment: EmailAttachment = {
832
- id: crypto.randomUUID(),
833
- file,
834
- name: file.name,
835
- size: file.size,
836
- type: file.type || 'application/octet-stream'
837
- }
838
-
839
- this.attachments = [...this.attachments, attachment]
840
- this.dispatchChange()
841
- }
842
-
843
- /** Remove attachment */
844
- private removeAttachment = (attachmentId: string) => {
845
- this.attachments = this.attachments.filter(att => att.id !== attachmentId)
846
- this.dispatchChange()
847
- }
848
-
849
-
850
- render() {
851
- return html`
852
- <schmancy-surface
853
- type="solid"
854
- rounded="all"
855
- class=${this.classMap({
856
- 'border-2 border-dashed border-primary': this.dragOver,
857
- 'h-full flex flex-col': true
858
- })}
859
- @drop=${this.handleDrop}
860
- @dragover=${this.handleDragOver}
861
- @dragleave=${this.handleDragLeave}
862
- >
863
- <div class="flex flex-col h-full gap-4">
864
-
865
- <!-- Header Section with Subject -->
866
- <div class="shrink-0 p-4 pb-0 space-y-4">
867
- <!-- Subject Field -->
868
- <div class="space-y-2">
869
- <schmancy-typography type="label" token="md">
870
- Subject *
871
- </schmancy-typography>
872
- <schmancy-input
873
- ${ref(this.subjectInputRef)}
874
- .value=${this.subject}
875
- @input=${this.handleSubjectChange}
876
- placeholder="Enter email subject..."
877
- .disabled=${this.disabled}
878
- class="w-full"
879
- ></schmancy-input>
880
- </div>
881
- </div>
882
-
883
- <!-- Formatting Toolbar -->
884
- <div class="shrink-0 px-4">
885
- <schmancy-surface type="subtle" rounded="all" class="p-3">
886
- <div class="flex flex-wrap gap-2 items-center">
887
- <!-- Text Formatting Group -->
888
- <div class="flex gap-1">
889
- <schmancy-icon-button
890
- size="sm"
891
- variant="text"
892
- title="Bold"
893
- ?disabled=${this.disabled}
894
- @click=${() => this.wrapSelection('**', '**', 'bold text')}
895
- >
896
- <schmancy-icon>format_bold</schmancy-icon>
897
- </schmancy-icon-button>
898
- <schmancy-icon-button
899
- size="sm"
900
- variant="text"
901
- title="Italic"
902
- ?disabled=${this.disabled}
903
- @click=${() => this.wrapSelection('*', '*', 'italic text')}
904
- >
905
- <schmancy-icon>format_italic</schmancy-icon>
906
- </schmancy-icon-button>
907
- <schmancy-icon-button
908
- size="sm"
909
- variant="text"
910
- title="Link"
911
- ?disabled=${this.disabled}
912
- @click=${() => this.insertAtCursor('[link text](https://example.com)', 'link text')}
913
- >
914
- <schmancy-icon>link</schmancy-icon>
915
- </schmancy-icon-button>
916
- </div>
917
-
918
- <!-- Divider -->
919
- <div class="h-6 w-px bg-outline-variant"></div>
920
-
921
- <!-- Structure Formatting Group -->
922
- <div class="flex gap-1">
923
- <schmancy-icon-button
924
- size="sm"
925
- variant="text"
926
- title="Heading"
927
- ?disabled=${this.disabled}
928
- @click=${() => this.insertAtCursor('\n# Heading\n', 'Heading')}
929
- >
930
- <schmancy-icon>title</schmancy-icon>
931
- </schmancy-icon-button>
932
- <schmancy-icon-button
933
- size="sm"
934
- variant="text"
935
- title="Bullet List"
936
- ?disabled=${this.disabled}
937
- @click=${() => this.insertAtCursor('\n* List item\n', 'List item')}
938
- >
939
- <schmancy-icon>format_list_bulleted</schmancy-icon>
940
- </schmancy-icon-button>
941
- </div>
942
-
943
- <!-- Divider -->
944
- <div class="h-6 w-px bg-outline-variant"></div>
945
-
946
- <!-- Media and Layout Group -->
947
- <div class="flex gap-1">
948
- <schmancy-icon-button
949
- size="sm"
950
- variant="text"
951
- title="Insert Image"
952
- ?disabled=${this.disabled || this.isUploading}
953
- @click=${() => this.imageInputRef.value?.click()}
954
- >
955
- ${when(this.isUploading,
956
- () => html`<schmancy-progress size="sm" class="w-4 h-4"></schmancy-progress>`,
957
- () => html`<schmancy-icon>image</schmancy-icon>`
958
- )}
959
- </schmancy-icon-button>
960
- <schmancy-icon-button
961
- size="sm"
962
- variant="text"
963
- title="Insert Layout"
964
- ?disabled=${this.disabled}
965
- @click=${this.openLayoutDialog}
966
- >
967
- <schmancy-icon>mobile_layout</schmancy-icon>
968
- </schmancy-icon-button>
969
- <schmancy-icon-button
970
- size="sm"
971
- variant="text"
972
- title="Use Template"
973
- ?disabled=${this.disabled || this.templates.length === 0}
974
- @click=${this.openTemplatePicker}
975
- >
976
- <schmancy-icon>description</schmancy-icon>
977
- </schmancy-icon-button>
978
- </div>
979
- </div>
980
- </schmancy-surface>
981
- </div>
982
-
983
- <!-- Textarea Container - Takes remaining space -->
984
- <div class="flex-1 px-4 relative min-h-0">
985
- <schmancy-textarea
986
- ${ref(this.bodyTextAreaRef)}
987
- .value=${this.body}
988
- @change=${this.handleBodyChange}
989
- placeholder="Enter your email message here...
990
-
991
- Use the toolbar buttons above for formatting, or type markdown directly:
992
- **bold**, *italic*, [link](url), ![image](url)
993
-
994
- Drag & drop images or press Ctrl+V to paste from clipboard.
995
- Tab key inserts 2 spaces for better formatting."
996
- .disabled=${this.disabled}
997
- .required=${true}
998
- .rows=${4}
999
- class="w-full font-mono text-sm"
1000
- ></schmancy-textarea>
1001
-
1002
- <!-- Upload Progress Overlay -->
1003
- ${when(this.isUploading, () => html`
1004
- <div class="absolute top-3 right-3 z-10">
1005
- <schmancy-surface type="subtle" rounded="all" class="p-2">
1006
- <div class="flex items-center gap-2">
1007
- <schmancy-progress size="sm" class="w-4 h-4"></schmancy-progress>
1008
- <schmancy-typography type="body" token="xs">Uploading...</schmancy-typography>
1009
- </div>
1010
- </schmancy-surface>
1011
- </div>
1012
- `)}
1013
- </div>
1014
-
1015
- <!-- Footer Section -->
1016
- <div class="shrink-0 p-4 pt-0 space-y-2">
1017
- <!-- Character/Word Counter -->
1018
- <div class="text-center">
1019
- <schmancy-typography type="body" token="xs">
1020
- ${this.body.length} characters • ${this.body.trim() ? this.body.trim().split(/\s+/).length : 0} words
1021
- </schmancy-typography>
1022
- </div>
1023
-
1024
- <!-- Attachments Display (if any) -->
1025
- ${when(this.attachments.length > 0, () => html`
1026
- <div class="space-y-2">
1027
- <schmancy-typography type="label" token="sm" class="flex items-center gap-2">
1028
- <schmancy-icon size="16px">attach_file</schmancy-icon>
1029
- Attachments (${this.attachments.length})
1030
- </schmancy-typography>
1031
- <div class="flex flex-wrap gap-2">
1032
- ${repeat(this.attachments, att => att.id, (attachment) => html`
1033
- <schmancy-chip class="text-xs">
1034
- <span class="truncate max-w-32">${attachment.name}</span>
1035
- <button
1036
- @click=${() => this.removeAttachment(attachment.id)}
1037
- class="ml-2 text-error hover:text-error-container"
1038
- title="Remove attachment"
1039
- >
1040
- <schmancy-icon size="14px">close</schmancy-icon>
1041
- </button>
1042
- </schmancy-chip>
1043
- `)}
1044
- </div>
1045
- </div>
1046
- `)}
1047
- </div>
1048
-
1049
- <!-- Hidden File Inputs -->
1050
- <div class="hidden">
1051
- <input
1052
- ${ref(this.fileInputRef)}
1053
- type="file"
1054
- multiple
1055
- @change=${this.handleFileChange}
1056
- >
1057
- <input
1058
- ${ref(this.imageInputRef)}
1059
- type="file"
1060
- accept="image/*"
1061
- @change=${this.handleImageSelect}
1062
- >
1063
- </div>
1064
-
1065
- </div>
1066
- </schmancy-surface>
1067
-
1068
- `
1069
- }
1070
- }
1071
-
1072
- declare global {
1073
- interface HTMLElementTagNameMap {
1074
- 'schmancy-email-editor': SchmancyEmailEditor
1075
- }
1076
- }