@pinkpixel/marzipan 1.0.8 → 1.1.0

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 (163) hide show
  1. package/README.md +23 -1
  2. package/dist/{_basePickBy-BXyyc71p.js → _basePickBy-CBhXlrs3.js} +3 -3
  3. package/dist/{_basePickBy-BXyyc71p.js.map → _basePickBy-CBhXlrs3.js.map} +1 -1
  4. package/dist/{_baseUniq-Dde5pUWM.js → _baseUniq-BnlNEqx5.js} +2 -2
  5. package/dist/{_baseUniq-Dde5pUWM.js.map → _baseUniq-BnlNEqx5.js.map} +1 -1
  6. package/dist/actions/core/formats.d.ts.map +1 -1
  7. package/dist/actions/core/formats.js +5 -0
  8. package/dist/actions/core/formats.js.map +1 -1
  9. package/dist/actions/index.d.ts +4 -0
  10. package/dist/actions/index.d.ts.map +1 -1
  11. package/dist/actions/index.js +20 -0
  12. package/dist/actions/index.js.map +1 -1
  13. package/dist/{arc-CfMWIGxd.js → arc-DKfQKN_X.js} +2 -2
  14. package/dist/{arc-CfMWIGxd.js.map → arc-DKfQKN_X.js.map} +1 -1
  15. package/dist/{architectureDiagram-VXUJARFQ-Bb4i7x-6.js → architectureDiagram-VXUJARFQ-DyTB8Kgd.js} +5 -5
  16. package/dist/{architectureDiagram-VXUJARFQ-Bb4i7x-6.js.map → architectureDiagram-VXUJARFQ-DyTB8Kgd.js.map} +1 -1
  17. package/dist/{blockDiagram-VD42YOAC-ldSoJhgA.js → blockDiagram-VD42YOAC-BCYA47jf.js} +7 -12
  18. package/dist/{blockDiagram-VD42YOAC-ldSoJhgA.js.map → blockDiagram-VD42YOAC-BCYA47jf.js.map} +1 -1
  19. package/dist/{c4Diagram-YG6GDRKO-D-ENeA7h.js → c4Diagram-YG6GDRKO-ChtfMRpM.js} +3 -3
  20. package/dist/{c4Diagram-YG6GDRKO-D-ENeA7h.js.map → c4Diagram-YG6GDRKO-ChtfMRpM.js.map} +1 -1
  21. package/dist/channel-XZzkxuXg.js +6 -0
  22. package/dist/{channel-BCTxewZI.js.map → channel-XZzkxuXg.js.map} +1 -1
  23. package/dist/{chunk-4BX2VUAB-Cfh_4i4X.js → chunk-4BX2VUAB-Cx8HPvOf.js} +2 -2
  24. package/dist/{chunk-4BX2VUAB-Cfh_4i4X.js.map → chunk-4BX2VUAB-Cx8HPvOf.js.map} +1 -1
  25. package/dist/{chunk-55IACEB6-DNOIVRvW.js → chunk-55IACEB6-DGQSbiTY.js} +2 -2
  26. package/dist/{chunk-55IACEB6-DNOIVRvW.js.map → chunk-55IACEB6-DGQSbiTY.js.map} +1 -1
  27. package/dist/{chunk-B4BG7PRW-C_qWbbk6.js → chunk-B4BG7PRW-CY260R4Q.js} +5 -5
  28. package/dist/{chunk-B4BG7PRW-C_qWbbk6.js.map → chunk-B4BG7PRW-CY260R4Q.js.map} +1 -1
  29. package/dist/{chunk-DI55MBZ5-D_yXJA03.js → chunk-DI55MBZ5-B4h9UrCS.js} +4 -4
  30. package/dist/{chunk-DI55MBZ5-D_yXJA03.js.map → chunk-DI55MBZ5-B4h9UrCS.js.map} +1 -1
  31. package/dist/{chunk-FMBD7UC4-B9NJjOBf.js → chunk-FMBD7UC4-BrVGjj-q.js} +2 -2
  32. package/dist/{chunk-FMBD7UC4-B9NJjOBf.js.map → chunk-FMBD7UC4-BrVGjj-q.js.map} +1 -1
  33. package/dist/{chunk-QN33PNHL-CVrLUVsI.js → chunk-QN33PNHL-DZm-2bJu.js} +2 -2
  34. package/dist/{chunk-QN33PNHL-CVrLUVsI.js.map → chunk-QN33PNHL-DZm-2bJu.js.map} +1 -1
  35. package/dist/{chunk-QZHKN3VN-FvAf_VJR.js → chunk-QZHKN3VN-Hi_p5q2K.js} +2 -2
  36. package/dist/{chunk-QZHKN3VN-FvAf_VJR.js.map → chunk-QZHKN3VN-Hi_p5q2K.js.map} +1 -1
  37. package/dist/{chunk-TZMSLE5B-DxYTPD3t.js → chunk-TZMSLE5B-CIZlLW3r.js} +2 -2
  38. package/dist/{chunk-TZMSLE5B-DxYTPD3t.js.map → chunk-TZMSLE5B-CIZlLW3r.js.map} +1 -1
  39. package/dist/{classDiagram-2ON5EDUG-Cg641kit.js → classDiagram-2ON5EDUG-QSrTDjZ0.js} +3 -3
  40. package/dist/{classDiagram-2ON5EDUG-Cg641kit.js.map → classDiagram-2ON5EDUG-QSrTDjZ0.js.map} +1 -1
  41. package/dist/{classDiagram-v2-WZHVMYZB-Cg641kit.js → classDiagram-v2-WZHVMYZB-QSrTDjZ0.js} +3 -3
  42. package/dist/{classDiagram-v2-WZHVMYZB-Cg641kit.js.map → classDiagram-v2-WZHVMYZB-QSrTDjZ0.js.map} +1 -1
  43. package/dist/clone-B6rhP1DC.js +9 -0
  44. package/dist/{clone-D062_nJ-.js.map → clone-B6rhP1DC.js.map} +1 -1
  45. package/dist/{cose-bilkent-S5V4N54A-DIb5rck_.js → cose-bilkent-S5V4N54A-Cz05oWQ-.js} +3 -3
  46. package/dist/{cose-bilkent-S5V4N54A-DIb5rck_.js.map → cose-bilkent-S5V4N54A-Cz05oWQ-.js.map} +1 -1
  47. package/dist/{cytoscape.esm-DfdJODL8.js → cytoscape.esm-Cvf3sx9F.js} +16 -47
  48. package/dist/{cytoscape.esm-DfdJODL8.js.map → cytoscape.esm-Cvf3sx9F.js.map} +1 -1
  49. package/dist/{dagre-6UL2VRFP-CZKadRq9.js → dagre-6UL2VRFP-24cZIDCv.js} +7 -7
  50. package/dist/{dagre-6UL2VRFP-CZKadRq9.js.map → dagre-6UL2VRFP-24cZIDCv.js.map} +1 -1
  51. package/dist/defaultLocale-BgPVtth8.js +172 -0
  52. package/dist/defaultLocale-BgPVtth8.js.map +1 -0
  53. package/dist/{diagram-PSM6KHXK-VDtnZynV.js → diagram-PSM6KHXK-hMkwALkg.js} +7 -7
  54. package/dist/{diagram-PSM6KHXK-VDtnZynV.js.map → diagram-PSM6KHXK-hMkwALkg.js.map} +1 -1
  55. package/dist/{diagram-QEK2KX5R-DxjNZqZ_.js → diagram-QEK2KX5R-DN407_qN.js} +4 -4
  56. package/dist/{diagram-QEK2KX5R-DxjNZqZ_.js.map → diagram-QEK2KX5R-DN407_qN.js.map} +1 -1
  57. package/dist/{diagram-S2PKOQOG-CCX3j4vi.js → diagram-S2PKOQOG-DYfbxKMk.js} +4 -4
  58. package/dist/{diagram-S2PKOQOG-CCX3j4vi.js.map → diagram-S2PKOQOG-DYfbxKMk.js.map} +1 -1
  59. package/dist/{erDiagram-Q2GNP2WA-nwmrf6lJ.js → erDiagram-Q2GNP2WA-CyzD1x2b.js} +5 -5
  60. package/dist/{erDiagram-Q2GNP2WA-nwmrf6lJ.js.map → erDiagram-Q2GNP2WA-CyzD1x2b.js.map} +1 -1
  61. package/dist/{flowDiagram-NV44I4VS-DQEdMlRX.js → flowDiagram-NV44I4VS-BHrJSYHv.js} +6 -6
  62. package/dist/{flowDiagram-NV44I4VS-DQEdMlRX.js.map → flowDiagram-NV44I4VS-BHrJSYHv.js.map} +1 -1
  63. package/dist/ganttDiagram-JELNMOA3-DibD3FLu.js +2671 -0
  64. package/dist/ganttDiagram-JELNMOA3-DibD3FLu.js.map +1 -0
  65. package/dist/{gitGraphDiagram-NY62KEGX-BgmbSTgN.js → gitGraphDiagram-V2S2FVAM-BlXeU9uI.js} +5 -5
  66. package/dist/gitGraphDiagram-V2S2FVAM-BlXeU9uI.js.map +1 -0
  67. package/dist/{graph-CSVEP8oS.js → graph-BN01VVM9.js} +3 -3
  68. package/dist/{graph-CSVEP8oS.js.map → graph-BN01VVM9.js.map} +1 -1
  69. package/dist/index-DjXgvYA3.js +36 -0
  70. package/dist/index-DjXgvYA3.js.map +1 -0
  71. package/dist/index.d.ts +60 -0
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +350 -264
  74. package/dist/index.js.map +1 -1
  75. package/dist/{infoDiagram-F6ZHWCRC-BzTgHHGF.js → infoDiagram-HS3SLOUP-Dqf1wtMF.js} +3 -3
  76. package/dist/{infoDiagram-F6ZHWCRC-BzTgHHGF.js.map → infoDiagram-HS3SLOUP-Dqf1wtMF.js.map} +1 -1
  77. package/dist/{journeyDiagram-XKPGCS4Q-B5P7hkT-.js → journeyDiagram-XKPGCS4Q-DCJl6fPA.js} +5 -5
  78. package/dist/{journeyDiagram-XKPGCS4Q-B5P7hkT-.js.map → journeyDiagram-XKPGCS4Q-DCJl6fPA.js.map} +1 -1
  79. package/dist/{kanban-definition-3W4ZIXB7-CLtnd0xR.js → kanban-definition-3W4ZIXB7-C4uKwcnd.js} +17 -17
  80. package/dist/{kanban-definition-3W4ZIXB7-CLtnd0xR.js.map → kanban-definition-3W4ZIXB7-C4uKwcnd.js.map} +1 -1
  81. package/dist/{layout-CdTiJocX.js → layout-DPZm-_SA.js} +33 -22
  82. package/dist/layout-DPZm-_SA.js.map +1 -0
  83. package/dist/{linear-BhblBDrV.js → linear-DgKHAz_i.js} +3 -3
  84. package/dist/{linear-BhblBDrV.js.map → linear-DgKHAz_i.js.map} +1 -1
  85. package/dist/marzipan.d.ts +2 -0
  86. package/dist/marzipan.d.ts.map +1 -1
  87. package/dist/marzipan.js +23 -5
  88. package/dist/marzipan.js.map +1 -1
  89. package/dist/{mermaid.core-DENutRS8.js → mermaid.core-KR6iXUBd.js} +430 -415
  90. package/dist/{mermaid.core-DENutRS8.js.map → mermaid.core-KR6iXUBd.js.map} +1 -1
  91. package/dist/{mindmap-definition-VGOIOE7T-BXBE9eta.js → mindmap-definition-VGOIOE7T-DDKBtjHc.js} +4 -4
  92. package/dist/{mindmap-definition-VGOIOE7T-BXBE9eta.js.map → mindmap-definition-VGOIOE7T-DDKBtjHc.js.map} +1 -1
  93. package/dist/{ordinal-DfAQgscy.js → ordinal-B6-f3MAq.js} +2 -2
  94. package/dist/{ordinal-DfAQgscy.js.map → ordinal-B6-f3MAq.js.map} +1 -1
  95. package/dist/parser.d.ts +12 -1
  96. package/dist/parser.d.ts.map +1 -1
  97. package/dist/parser.js +61 -14
  98. package/dist/parser.js.map +1 -1
  99. package/dist/{pieDiagram-ADFJNKIX-BND3UUQ-.js → pieDiagram-ADFJNKIX-hp1Z1x8W.js} +6 -6
  100. package/dist/{pieDiagram-ADFJNKIX-BND3UUQ-.js.map → pieDiagram-ADFJNKIX-hp1Z1x8W.js.map} +1 -1
  101. package/dist/plugins/accentSwatchPlugin.d.ts.map +1 -1
  102. package/dist/plugins/accentSwatchPlugin.js +33 -33
  103. package/dist/plugins/accentSwatchPlugin.js.map +1 -1
  104. package/dist/plugins/block-handles.d.ts +177 -0
  105. package/dist/plugins/block-handles.d.ts.map +1 -0
  106. package/dist/plugins/block-handles.js +379 -0
  107. package/dist/plugins/block-handles.js.map +1 -0
  108. package/dist/plugins/imageManagerPlugin.js.map +1 -1
  109. package/dist/plugins/index.d.ts +24 -0
  110. package/dist/plugins/index.d.ts.map +1 -0
  111. package/dist/plugins/index.js +32 -0
  112. package/dist/plugins/index.js.map +1 -0
  113. package/dist/plugins/mermaidPlugin.js +1 -1
  114. package/dist/plugins/tableGridPlugin.d.ts.map +1 -1
  115. package/dist/plugins/tableGridPlugin.js +23 -23
  116. package/dist/plugins/tableGridPlugin.js.map +1 -1
  117. package/dist/{quadrantDiagram-AYHSOK5B-CnLHbrEF.js → quadrantDiagram-AYHSOK5B-B9wjnoWH.js} +3 -3
  118. package/dist/{quadrantDiagram-AYHSOK5B-CnLHbrEF.js.map → quadrantDiagram-AYHSOK5B-B9wjnoWH.js.map} +1 -1
  119. package/dist/{requirementDiagram-UZGBJVZJ-caC7K17a.js → requirementDiagram-UZGBJVZJ-CAYg9pNG.js} +4 -4
  120. package/dist/{requirementDiagram-UZGBJVZJ-caC7K17a.js.map → requirementDiagram-UZGBJVZJ-CAYg9pNG.js.map} +1 -1
  121. package/dist/{sankeyDiagram-TZEHDZUN-CV5-bwv8.js → sankeyDiagram-TZEHDZUN-Dbi0-ImG.js} +3 -3
  122. package/dist/{sankeyDiagram-TZEHDZUN-CV5-bwv8.js.map → sankeyDiagram-TZEHDZUN-Dbi0-ImG.js.map} +1 -1
  123. package/dist/{sequenceDiagram-WL72ISMW-Cq1otbHU.js → sequenceDiagram-WL72ISMW-CgnGVPN0.js} +4 -4
  124. package/dist/{sequenceDiagram-WL72ISMW-Cq1otbHU.js.map → sequenceDiagram-WL72ISMW-CgnGVPN0.js.map} +1 -1
  125. package/dist/{stateDiagram-FKZM4ZOC-BJ5UwskL.js → stateDiagram-FKZM4ZOC-BnrHMBt-.js} +5 -5
  126. package/dist/{stateDiagram-FKZM4ZOC-BJ5UwskL.js.map → stateDiagram-FKZM4ZOC-BnrHMBt-.js.map} +1 -1
  127. package/dist/{stateDiagram-v2-4FDKWEC3-H1gqsSsO.js → stateDiagram-v2-4FDKWEC3-CvQCssRZ.js} +3 -3
  128. package/dist/{stateDiagram-v2-4FDKWEC3-H1gqsSsO.js.map → stateDiagram-v2-4FDKWEC3-CvQCssRZ.js.map} +1 -1
  129. package/dist/styles.d.ts.map +1 -1
  130. package/dist/styles.js +25 -21
  131. package/dist/styles.js.map +1 -1
  132. package/dist/themes.d.ts +6 -0
  133. package/dist/themes.d.ts.map +1 -1
  134. package/dist/themes.js +2 -0
  135. package/dist/themes.js.map +1 -1
  136. package/dist/{timeline-definition-IT6M3QCI-CqPEUsh4.js → timeline-definition-IT6M3QCI-C9po0EuD.js} +3 -3
  137. package/dist/{timeline-definition-IT6M3QCI-CqPEUsh4.js.map → timeline-definition-IT6M3QCI-C9po0EuD.js.map} +1 -1
  138. package/dist/treemap-GDKQZRPO-DUJ_UgsM.js +17929 -0
  139. package/dist/treemap-GDKQZRPO-DUJ_UgsM.js.map +1 -0
  140. package/dist/{xychartDiagram-PRI3JC2R-C3_IO4Rm.js → xychartDiagram-PRI3JC2R-Daz1URdd.js} +4 -4
  141. package/dist/{xychartDiagram-PRI3JC2R-C3_IO4Rm.js.map → xychartDiagram-PRI3JC2R-Daz1URdd.js.map} +1 -1
  142. package/docs/.vitepress/config.ts +77 -0
  143. package/docs/README.md +3 -1
  144. package/docs/TABLE_OF_CONTENTS.md +1 -0
  145. package/docs/api.md +42 -2
  146. package/docs/block-handles.md +325 -0
  147. package/docs/index.md +95 -0
  148. package/docs/plugins.md +24 -0
  149. package/docs/public/favicon.png +0 -0
  150. package/docs/public/logo.png +0 -0
  151. package/docs/types.d.ts +1 -1
  152. package/docs/types.md +150 -0
  153. package/package.json +12 -4
  154. package/dist/channel-BCTxewZI.js +0 -6
  155. package/dist/clone-D062_nJ-.js +0 -9
  156. package/dist/defaultLocale-D7EN2tov.js +0 -172
  157. package/dist/defaultLocale-D7EN2tov.js.map +0 -1
  158. package/dist/ganttDiagram-LVOFAZNH-WMiy-Gep.js +0 -2506
  159. package/dist/ganttDiagram-LVOFAZNH-WMiy-Gep.js.map +0 -1
  160. package/dist/gitGraphDiagram-NY62KEGX-BgmbSTgN.js.map +0 -1
  161. package/dist/layout-CdTiJocX.js.map +0 -1
  162. package/dist/treemap-75Q7IDZK-DmPg5GN7.js +0 -12988
  163. package/dist/treemap-75Q7IDZK-DmPg5GN7.js.map +0 -1
@@ -0,0 +1,77 @@
1
+ import { defineConfig } from 'vitepress'
2
+
3
+ export default defineConfig({
4
+ title: 'Marzipan',
5
+ description: 'Framework-agnostic markdown editor with a live overlay preview, zero runtime dependencies, and batteries-included formatting actions.',
6
+ lang: 'en-US',
7
+
8
+ outDir: '../docs-site',
9
+
10
+ // Links to files outside the docs root (CHANGELOG, OVERVIEW, etc.) are valid
11
+ // relative links for GitHub markdown but are not part of the VitePress site.
12
+ ignoreDeadLinks: [
13
+ /\/OVERVIEW/,
14
+ /\/CHANGELOG/,
15
+ /\/bakeshop-demo\//,
16
+ /\.d\.ts$/,
17
+ ],
18
+
19
+ head: [
20
+ ['link', { rel: 'icon', href: '/favicon.png' }],
21
+ ],
22
+
23
+ themeConfig: {
24
+ logo: '/logo.png',
25
+ siteTitle: 'Marzipan',
26
+
27
+ nav: [
28
+ { text: 'Home', link: '/' },
29
+ { text: 'Quick Start', link: '/quick-start' },
30
+ { text: 'API', link: '/api' },
31
+ { text: 'Plugins', link: '/plugins' },
32
+ {
33
+ text: 'v1.1.0',
34
+ items: [
35
+ { text: 'Changelog', link: 'https://github.com/pinkpixel-dev/marzipan/blob/main/CHANGELOG.md' },
36
+ ]
37
+ }
38
+ ],
39
+
40
+ sidebar: [
41
+ {
42
+ text: 'Getting Started',
43
+ items: [
44
+ { text: 'Introduction', link: '/' },
45
+ { text: 'Quick Start', link: '/quick-start' },
46
+ ]
47
+ },
48
+ {
49
+ text: 'Core Reference',
50
+ items: [
51
+ { text: 'API Reference', link: '/api' },
52
+ { text: 'Type Definitions', link: '/types' },
53
+ ]
54
+ },
55
+ {
56
+ text: 'Plugins',
57
+ items: [
58
+ { text: 'Plugin Catalogue', link: '/plugins' },
59
+ { text: 'Block Handles', link: '/block-handles' },
60
+ ]
61
+ },
62
+ ],
63
+
64
+ socialLinks: [
65
+ { icon: 'github', link: 'https://github.com/pinkpixel-dev/marzipan' },
66
+ ],
67
+
68
+ footer: {
69
+ message: 'Released under the Apache 2.0 License.',
70
+ copyright: 'Copyright © Pink Pixel'
71
+ },
72
+
73
+ search: {
74
+ provider: 'local'
75
+ }
76
+ }
77
+ })
package/docs/README.md CHANGED
@@ -9,6 +9,7 @@ Welcome! This folder contains everything you need to install, configure, and ext
9
9
  | [Quick Start](./quick-start.md) | Install the library, render your first editor, and wire up bundled actions and plugins. |
10
10
  | [API Reference](./api.md) | Full class API, key options, utility methods, and action helper signatures. |
11
11
  | [Plugin Catalogue](./plugins.md) | Overview of the first-party plugins shipped from `src/plugins` with configuration tips. |
12
+ | [Block Handles Plugin](./block-handles.md) | Interactive block manipulation with visual handles, context menus, and keyboard shortcuts. |
12
13
  | [Type Definitions](./types.d.ts) | Generated TypeScript declarations for deep integration and tooling. |
13
14
 
14
15
  ## 🧭 Orientation
@@ -22,7 +23,8 @@ Welcome! This folder contains everything you need to install, configure, and ext
22
23
  1. **Quick Start** – get an editor running in under five minutes.
23
24
  2. **API Reference** – understand the Marzipan class, events, and helper utilities.
24
25
  3. **Plugin Catalogue** – explore optional capabilities like tables, Mermaid, media helpers, and syntax highlight.
25
- 4. **Type Definitions** – browse generated typings for IDE integration.
26
+ 4. **Block Handles** – interactive block manipulation for the preview overlay.
27
+ 5. **Type Definitions** – browse generated typings for IDE integration.
26
28
 
27
29
  ## 🧁 Related Resources
28
30
 
@@ -10,6 +10,7 @@
10
10
 
11
11
  ## Extensions
12
12
  - [Plugin Catalogue](./plugins.md)
13
+ - [Block Handles Plugin](./block-handles.md)
13
14
 
14
15
  ## Related Root Docs
15
16
  - [Project Overview](../OVERVIEW.md)
package/docs/api.md CHANGED
@@ -9,6 +9,7 @@ A comprehensive guide to the core Marzipan class, bundled action toolkit, and fi
9
9
  - [Instance Methods](#instance-methods)
10
10
  - [Static Methods](#static-methods)
11
11
  - [Actions API](#actions-api)
12
+ - [Link Tooltip](#link-tooltip)
12
13
  - [Options](#options)
13
14
  - [Themes](#themes)
14
15
  - [Plugin Exports](#plugin-exports)
@@ -321,18 +322,57 @@ Available helpers include:
321
322
  - `toggleBold(textarea)`
322
323
  - `toggleItalic(textarea)`
323
324
  - `toggleCode(textarea)`
325
+ - `toggleStrikethrough(textarea)` — toggles `~~text~~` / `~text~` strikethrough
324
326
  - `insertLink(textarea, options?)`
327
+ - `insertHorizontalRule(textarea)` — inserts a `---` divider at the cursor
325
328
  - `toggleBulletList(textarea)`
326
329
  - `toggleNumberedList(textarea)`
327
330
  - `toggleQuote(textarea)`
328
331
  - `toggleTaskList(textarea)`
329
- - `toggleH1/H2/H3(textarea)`
332
+ - `insertHeader(textarea, level?, toggle?)`
333
+ - `toggleH1(textarea)` / `toggleH2(textarea)` / `toggleH3(textarea)`
330
334
  - `applyCustomFormat(textarea, format)`
331
- - `getActiveFormats(textarea)`
335
+ - `getActiveFormats(textarea)` / `hasFormat(textarea, format)`
336
+ - `expandSelection(textarea)` / `preserveSelection(textarea, fn)`
332
337
  - `setUndoMethod(method)` / `getUndoMethod()`
338
+ - `setDebugMode(enabled)` / `getDebugMode()`
333
339
 
334
340
  These functions mirror the toolbar and keyboard shortcut behaviour, making it easy to build custom UI without extra dependencies.
335
341
 
342
+ ### Strikethrough
343
+
344
+ ```ts
345
+ import { actions } from '@pinkpixel/marzipan';
346
+
347
+ // Wraps selection in ~~…~~ or ~…~
348
+ actions.toggleStrikethrough(textarea);
349
+ ```
350
+
351
+ ### Horizontal Rule
352
+
353
+ ```ts
354
+ import { actions } from '@pinkpixel/marzipan';
355
+
356
+ // Inserts --- at the cursor with surrounding newlines
357
+ actions.insertHorizontalRule(textarea);
358
+ ```
359
+
360
+ ## Link Tooltip
361
+
362
+ Marzipan automatically shows a floating URL tooltip whenever the cursor moves inside a markdown link (`[text](url)`). The tooltip is clickable and opens the link in a new tab.
363
+
364
+ ```
365
+ [Visit docs](https://marzipan.pinkpixel.dev)
366
+ ^^^ cursor here → tooltip appears
367
+ ```
368
+
369
+ **Implementation details:**
370
+ - Uses the CSS Anchor Positioning API (`position-anchor` / `position-area`) for pixel-accurate placement below the link.
371
+ - Gracefully degrades — in browsers that do not support CSS anchor positioning the tooltip is silently disabled.
372
+ - Managed by the `LinkTooltip` class, which is instantiated automatically by every editor and cleaned up on `destroy()`.
373
+
374
+ No configuration is required; the feature is always active.
375
+
336
376
  ## Options
337
377
 
338
378
  Default options and their descriptions:
@@ -0,0 +1,325 @@
1
+ # Block Handles Plugin
2
+
3
+ The **Block Handles Plugin** provides an interactive block manipulation system for Marzipan's preview overlay. It displays visual handles on the left side of markdown blocks, allowing users to easily select, copy, and delete blocks with mouse and keyboard interactions.
4
+
5
+ ## Features
6
+
7
+ - 🎨 **Visual Handles**: Unique icons for each block type (headings, paragraphs, lists, quotes, code, tables, etc.)
8
+ - 🖱️ **Hover Interaction**: Handles appear when hovering over blocks
9
+ - ✨ **Selection System**: Click handles or Shift+Click blocks to select them
10
+ - 📋 **Context Menu**: Right-click handles for quick actions (copy, delete, select)
11
+ - ⌨️ **Keyboard Shortcuts**: Ctrl/Cmd+C to copy, Delete/Backspace to delete selected blocks
12
+ - 🎯 **Visual Feedback**: Highlight effects for hover and selection states
13
+ - 🔔 **Toast Notifications**: User-friendly feedback for actions
14
+ - 📡 **Event System**: Custom events for block selection and deselection
15
+
16
+ ## Installation
17
+
18
+ The plugin is included with Marzipan by default. Simply enable it in your editor configuration:
19
+
20
+ ```javascript
21
+ import Marzipan from '@pinkpixel/marzipan';
22
+
23
+ const editor = new Marzipan('#editor', {
24
+ blockHandles: true // Enabled by default
25
+ });
26
+ ```
27
+
28
+ ## Configuration
29
+
30
+ You can customize the plugin's behavior and appearance:
31
+
32
+ ```javascript
33
+ const editor = new Marzipan('#editor', {
34
+ blockHandles: {
35
+ enabled: true, // Enable/disable the plugin
36
+ showOnHover: true, // Show handles on hover
37
+ handleOffset: 4, // Horizontal offset from block's left edge (px)
38
+ handleSize: 20, // Handle size (px)
39
+ colors: {
40
+ hover: 'rgba(59, 130, 246, 0.1)', // Hover highlight color
41
+ selected: 'rgba(59, 130, 246, 0.2)', // Selection highlight color
42
+ handle: 'rgba(59, 130, 246, 0.8)', // Handle background color
43
+ }
44
+ }
45
+ });
46
+ ```
47
+
48
+ ### Configuration Options
49
+
50
+ | Option | Type | Default | Description |
51
+ |--------|------|---------|-------------|
52
+ | `enabled` | `boolean` | `true` | Enable or disable the plugin |
53
+ | `showOnHover` | `boolean` | `true` | Show handles when hovering over blocks |
54
+ | `handleOffset` | `number` | `4` | Horizontal offset of handles from the block's left edge (in pixels) |
55
+ | `handleSize` | `number` | `20` | Size of handle buttons (in pixels) |
56
+ | `colors.hover` | `string` | `'rgba(59, 130, 246, 0.1)'` | Background color when hovering over blocks |
57
+ | `colors.selected` | `string` | `'rgba(59, 130, 246, 0.2)'` | Background color for selected blocks |
58
+ | `colors.handle` | `string` | `'rgba(59, 130, 246, 0.8)'` | Background color of handle buttons |
59
+
60
+ ## Usage
61
+
62
+ ### Basic Interactions
63
+
64
+ #### Mouse Interactions
65
+
66
+ 1. **Hover**: Move your mouse over any markdown block to see its handle appear on the left
67
+ 2. **Click Handle**: Click a handle to select the block
68
+ 3. **Right-Click Handle**: Right-click to open the context menu with available actions
69
+ 4. **Shift+Click Block**: Hold Shift and click anywhere on a block to select it
70
+
71
+ #### Keyboard Shortcuts
72
+
73
+ - **Escape**: Deselect the currently selected block
74
+ - **Ctrl/Cmd+C**: Copy the selected block to clipboard
75
+ - **Delete** or **Backspace**: Delete the selected block
76
+
77
+ ### Context Menu Actions
78
+
79
+ Right-click any handle to access these actions:
80
+
81
+ - **Copy**: Copy the block's content to clipboard
82
+ - **Delete**: Remove the block from the document
83
+ - **Select**: Select the block (same as clicking the handle)
84
+
85
+ ### Block Types and Icons
86
+
87
+ Each markdown block type has a unique icon:
88
+
89
+ | Block Type | Icon | Description |
90
+ |------------|------|-------------|
91
+ | Heading | ⚡ | H1-H6 headers |
92
+ | Paragraph | ¶ | Regular text paragraphs |
93
+ | List Item | • | Bullet and numbered lists |
94
+ | Quote | " | Blockquotes |
95
+ | Code Fence | { | Code fence markers |
96
+ | Code Content | {} | Content inside code blocks |
97
+ | Horizontal Rule | ― | Horizontal lines |
98
+ | Table Row | ⊞ | Table data rows |
99
+ | Table Separator | ═ | Table header separators |
100
+
101
+ ## Programmatic API
102
+
103
+ Access the plugin instance through your Marzipan editor:
104
+
105
+ ```javascript
106
+ const editor = new Marzipan('#editor', {
107
+ blockHandles: true
108
+ });
109
+
110
+ const plugin = editor[0].blockHandlesPlugin;
111
+ ```
112
+
113
+ ### Methods
114
+
115
+ #### `refresh()`
116
+ Rescan blocks and update handle positions.
117
+
118
+ ```javascript
119
+ plugin.refresh();
120
+ ```
121
+
122
+ #### `updateAllHandlePositions()`
123
+ Update positions of all handles (useful after scroll or resize).
124
+
125
+ ```javascript
126
+ plugin.updateAllHandlePositions();
127
+ ```
128
+
129
+ #### `getSelectedBlock()`
130
+ Get the currently selected block.
131
+
132
+ ```javascript
133
+ const block = plugin.getSelectedBlock();
134
+ if (block) {
135
+ console.log('Selected block:', block.type, block.lineStart, block.lineEnd);
136
+ }
137
+ ```
138
+
139
+ #### `getAllBlocks()`
140
+ Get all blocks tracked by the plugin.
141
+
142
+ ```javascript
143
+ const blocks = plugin.getAllBlocks();
144
+ console.log(`Found ${blocks.length} blocks`);
145
+ ```
146
+
147
+ #### `enable()`
148
+ Enable the plugin.
149
+
150
+ ```javascript
151
+ plugin.enable();
152
+ ```
153
+
154
+ #### `disable()`
155
+ Disable the plugin and remove all handles.
156
+
157
+ ```javascript
158
+ plugin.disable();
159
+ ```
160
+
161
+ #### `destroy()`
162
+ Clean up and remove the plugin completely.
163
+
164
+ ```javascript
165
+ plugin.destroy();
166
+ ```
167
+
168
+ ### Events
169
+
170
+ Listen for block selection events:
171
+
172
+ ```javascript
173
+ const preview = editor[0].preview;
174
+
175
+ preview.addEventListener('blockSelected', (e) => {
176
+ console.log('Block selected:', e.detail.blockId, e.detail.block);
177
+ });
178
+
179
+ preview.addEventListener('blockDeselected', (e) => {
180
+ console.log('Block deselected:', e.detail.blockId);
181
+ });
182
+ ```
183
+
184
+ ### Block Object Structure
185
+
186
+ Each block object contains:
187
+
188
+ ```typescript
189
+ interface BlockHandle {
190
+ id: string; // Unique block identifier
191
+ type: string; // Block type (heading, paragraph, etc.)
192
+ lineStart: number; // Starting line number in editor
193
+ lineEnd: number; // Ending line number in editor
194
+ element: HTMLElement; // DOM element for the block
195
+ handleElement: HTMLElement | null; // Handle DOM element
196
+ }
197
+ ```
198
+
199
+ ## Advanced Usage
200
+
201
+ ### Custom Handle Styling
202
+
203
+ You can override handle styles with CSS:
204
+
205
+ ```css
206
+ /* Customize handle appearance */
207
+ .mz-block-handle {
208
+ border: 2px solid white;
209
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
210
+ }
211
+
212
+ /* Style specific block types */
213
+ .mz-block-handle-heading {
214
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
215
+ }
216
+
217
+ .mz-block-handle-quote {
218
+ background: #10b981;
219
+ }
220
+ ```
221
+
222
+ ### Conditional Enable/Disable
223
+
224
+ Enable handles only for certain conditions:
225
+
226
+ ```javascript
227
+ const editor = new Marzipan('#editor', {
228
+ blockHandles: {
229
+ enabled: window.innerWidth > 768 // Only on desktop
230
+ }
231
+ });
232
+
233
+ // Toggle based on user preference
234
+ window.addEventListener('resize', () => {
235
+ if (window.innerWidth > 768) {
236
+ editor[0].blockHandlesPlugin?.enable();
237
+ } else {
238
+ editor[0].blockHandlesPlugin?.disable();
239
+ }
240
+ });
241
+ ```
242
+
243
+ ### Integrate with Custom Actions
244
+
245
+ ```javascript
246
+ const preview = editor[0].preview;
247
+
248
+ preview.addEventListener('blockSelected', (e) => {
249
+ const block = e.detail.block;
250
+
251
+ // Add custom toolbar for selected block
252
+ showCustomToolbar(block);
253
+
254
+ // Highlight corresponding line in editor
255
+ highlightEditorLines(block.lineStart, block.lineEnd);
256
+ });
257
+
258
+ preview.addEventListener('blockDeselected', () => {
259
+ hideCustomToolbar();
260
+ clearEditorHighlights();
261
+ });
262
+ ```
263
+
264
+ ## Browser Compatibility
265
+
266
+ The Block Handles Plugin requires:
267
+
268
+ - Modern browser with ES6+ support
269
+ - `navigator.clipboard` API for copy functionality
270
+ - CSS Grid support for handle positioning
271
+
272
+ Supported browsers:
273
+ - Chrome/Edge 90+
274
+ - Firefox 88+
275
+ - Safari 14+
276
+
277
+ ## Troubleshooting
278
+
279
+ ### Handles Not Appearing
280
+
281
+ 1. Verify the plugin is enabled:
282
+ ```javascript
283
+ console.log(editor[0].blockHandlesPlugin);
284
+ ```
285
+
286
+ 2. Check if block metadata is present:
287
+ ```javascript
288
+ const blocks = editor[0].preview.querySelectorAll('[data-block-id]');
289
+ console.log('Blocks found:', blocks.length);
290
+ ```
291
+
292
+ 3. Ensure preview has relative positioning:
293
+ ```javascript
294
+ console.log(getComputedStyle(editor[0].preview).position);
295
+ ```
296
+
297
+ ### Handles Misaligned
298
+
299
+ Call `updateAllHandlePositions()` after DOM changes:
300
+
301
+ ```javascript
302
+ editor[0].blockHandlesPlugin.updateAllHandlePositions();
303
+ ```
304
+
305
+ ### Performance Issues
306
+
307
+ If you notice performance issues with many blocks:
308
+
309
+ 1. Disable hover effects:
310
+ ```javascript
311
+ blockHandles: { showOnHover: false }
312
+ ```
313
+
314
+ 2. Throttle position updates on scroll
315
+
316
+ ## License
317
+
318
+ Apache 2.0
319
+
320
+ ## Credits
321
+
322
+ Created by **Pink Pixel** as part of the Marzipan markdown editor.
323
+
324
+ - Website: [pinkpixel.dev](https://pinkpixel.dev)
325
+ - GitHub: [@pinkpixel-dev](https://github.com/pinkpixel-dev)
package/docs/index.md ADDED
@@ -0,0 +1,95 @@
1
+ ---
2
+ layout: home
3
+
4
+ hero:
5
+ name: "🧁 Marzipan"
6
+ text: "Framework-agnostic markdown editor"
7
+ tagline: "Live overlay preview, zero runtime dependencies, and batteries-included formatting actions."
8
+ image:
9
+ src: /logo.png
10
+ alt: Marzipan Logo
11
+ actions:
12
+ - theme: brand
13
+ text: Get Started
14
+ link: /quick-start
15
+ - theme: alt
16
+ text: API Reference
17
+ link: /api
18
+ - theme: alt
19
+ text: View on GitHub
20
+ link: https://github.com/pinkpixel-dev/marzipan
21
+
22
+ features:
23
+ - icon: 🔷
24
+ title: Pure TypeScript Core
25
+ details: Ships typed ESM builds and declaration files with zero runtime dependencies.
26
+ - icon: ⚡
27
+ title: First-Party Actions
28
+ details: Formatting helpers live in src/actions and export with the library — no extra installs needed.
29
+ - icon: 🧩
30
+ title: Plugin Library
31
+ details: Production-ready plugins for tables, Mermaid, syntax highlighting, media helpers, and more.
32
+ - icon: 👁️
33
+ title: Overlay Preview
34
+ details: Renders markdown directly over the textarea so alignment never drifts.
35
+ - icon: 🎨
36
+ title: Themeable UI
37
+ details: Includes Solar (light) and Cave (dark) themes, plus accent swatch tooling for custom palettes.
38
+ - icon: 🛝
39
+ title: Demo Bakeshop
40
+ details: A Vite + React playground that exercises every option and plugin in a live environment.
41
+ ---
42
+
43
+ ## Quick Install
44
+
45
+ ```bash
46
+ npm install @pinkpixel/marzipan
47
+ ```
48
+
49
+ ## Create Your First Editor
50
+
51
+ ```ts
52
+ import { Marzipan } from '@pinkpixel/marzipan';
53
+
54
+ const [editor] = new Marzipan('#my-textarea', {
55
+ toolbar: true,
56
+ theme: 'cave',
57
+ smartLists: true,
58
+ });
59
+ ```
60
+
61
+ ## Use the Bundled Actions
62
+
63
+ ```ts
64
+ import { actions } from '@pinkpixel/marzipan';
65
+
66
+ const textarea = document.querySelector('textarea')!;
67
+ actions.toggleBold(textarea);
68
+ ```
69
+
70
+ ## Add a Plugin
71
+
72
+ ```ts
73
+ import { tablePlugin } from '@pinkpixel/marzipan/plugins/tablePlugin';
74
+
75
+ new Marzipan('#editor', {
76
+ plugins: [tablePlugin()],
77
+ });
78
+ ```
79
+
80
+ ## Bundled Plugins
81
+
82
+ | Plugin | Description |
83
+ |--------|-------------|
84
+ | `tablePlugin` | Toolbar-driven table generator with inline editing controls |
85
+ | `tableGridPlugin` | Grid overlay for rapid column/row creation |
86
+ | `tableGeneratorPlugin` | Quick GFM table inserter with prompt-driven sizing |
87
+ | `tinyHighlightPlugin` | Zero-runtime syntax highlighting for fenced code blocks |
88
+ | `accentSwatchPlugin` | Synced accent palette picker |
89
+ | `imageManagerPlugin` | Dropzone and gallery UI for inserting images and managing uploads |
90
+ | `imagePickerPlugin` | Toolbar button for inserting images via URL or optional uploader callback |
91
+ | `mermaidPlugin` | Diagram rendering via ESM import |
92
+ | `mermaidExternalPlugin` | Mermaid integration via CDN script tag |
93
+ | `BlockHandlesPlugin` | Interactive block manipulation with visual handles, context menus, and keyboard shortcuts |
94
+
95
+ See the full [Plugin Catalogue](/plugins) for configuration details.
package/docs/plugins.md CHANGED
@@ -4,6 +4,7 @@ Marzipan ships first-party plugins from the `src/plugins` directory. Each plugin
4
4
 
5
5
  ## Using a plugin
6
6
 
7
+ ### Individual plugin imports (recommended)
7
8
  ```ts
8
9
  import { Marzipan } from '@pinkpixel/marzipan';
9
10
  import { tablePlugin } from '@pinkpixel/marzipan/plugins/tablePlugin';
@@ -17,6 +18,28 @@ new Marzipan('#editor', {
17
18
  });
18
19
  ```
19
20
 
21
+ ### Main package imports (convenience)
22
+ ```ts
23
+ import { Marzipan, tablePlugin, mermaidPlugin } from '@pinkpixel/marzipan';
24
+
25
+ new Marzipan('#editor', {
26
+ plugins: [tablePlugin(), mermaidPlugin()],
27
+ });
28
+ ```
29
+
30
+ ### Namespace imports (all plugins)
31
+ ```ts
32
+ import { Marzipan, plugins } from '@pinkpixel/marzipan';
33
+
34
+ new Marzipan('#editor', {
35
+ plugins: [
36
+ plugins.tablePlugin(),
37
+ plugins.mermaidPlugin(),
38
+ plugins.accentSwatchPlugin(),
39
+ ],
40
+ });
41
+ ```
42
+
20
43
  Every factory returns an object that Marzipan consumes internally. You can mix and match plugins freely.
21
44
 
22
45
  ## Available plugins
@@ -24,6 +47,7 @@ Every factory returns an object that Marzipan consumes internally. You can mix a
24
47
  | Plugin | Import Path | Description |
25
48
  |--------|-------------|-------------|
26
49
  | `accentSwatchPlugin` | `@pinkpixel/marzipan/plugins/accentSwatchPlugin` | Adds a palette picker for accent colours and syncs with the toolbar + stats bar. |
50
+ | `BlockHandlesPlugin` | `@pinkpixel/marzipan/plugins/block-handles` | Interactive block manipulation with visual handles, context menus, and keyboard shortcuts. See [Block Handles](./block-handles.md) for full documentation. |
27
51
  | `imageManagerPlugin` | `@pinkpixel/marzipan/plugins/imageManagerPlugin` | Dropzone and gallery UI for inserting images and managing uploads. |
28
52
  | `imagePickerPlugin` | `@pinkpixel/marzipan/plugins/imagePickerPlugin` | Toolbar button for inserting images via URL or optional uploader callback. |
29
53
  | `mermaidPlugin` | `@pinkpixel/marzipan/plugins/mermaidPlugin` | Lazy-loads Mermaid from npm/ESM and renders diagrams inline. |
Binary file
Binary file
package/docs/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * TypeScript definitions for Marzipan markdown editor
3
- * @version 1.0.7
3
+ * @version 1.0.9
4
4
  * @author Pink Pixel
5
5
  */
6
6