@pinkpixel/marzipan 1.1.0 → 1.1.2

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 (130) hide show
  1. package/README.md +72 -37
  2. package/dist/_basePickBy-D4kyG5Tu.js +152 -0
  3. package/dist/_basePickBy-D4kyG5Tu.js.map +1 -0
  4. package/dist/_baseUniq-s5uZhHMt.js +615 -0
  5. package/dist/_baseUniq-s5uZhHMt.js.map +1 -0
  6. package/dist/arc-Cd2Fw3V6.js +84 -0
  7. package/dist/arc-Cd2Fw3V6.js.map +1 -0
  8. package/dist/architectureDiagram-VXUJARFQ-ylT61Lln.js +4663 -0
  9. package/dist/architectureDiagram-VXUJARFQ-ylT61Lln.js.map +1 -0
  10. package/dist/blockDiagram-VD42YOAC-CoIxLSyQ.js +2257 -0
  11. package/dist/blockDiagram-VD42YOAC-CoIxLSyQ.js.map +1 -0
  12. package/dist/c4Diagram-YG6GDRKO-CsQimMM6.js +1581 -0
  13. package/dist/c4Diagram-YG6GDRKO-CsQimMM6.js.map +1 -0
  14. package/dist/channel-0tZUlnqz.js +6 -0
  15. package/dist/channel-0tZUlnqz.js.map +1 -0
  16. package/dist/chunk-4BX2VUAB-DVkBhLxy.js +9 -0
  17. package/dist/chunk-4BX2VUAB-DVkBhLxy.js.map +1 -0
  18. package/dist/chunk-55IACEB6-CVQcegI-.js +9 -0
  19. package/dist/chunk-55IACEB6-CVQcegI-.js.map +1 -0
  20. package/dist/chunk-B4BG7PRW-DPUTNckV.js +1376 -0
  21. package/dist/chunk-B4BG7PRW-DPUTNckV.js.map +1 -0
  22. package/dist/chunk-DI55MBZ5-F7DI2N9R.js +1371 -0
  23. package/dist/chunk-DI55MBZ5-F7DI2N9R.js.map +1 -0
  24. package/dist/chunk-FMBD7UC4-C3wNpU7V.js +20 -0
  25. package/dist/chunk-FMBD7UC4-C3wNpU7V.js.map +1 -0
  26. package/dist/chunk-QN33PNHL-BOdqrixJ.js +20 -0
  27. package/dist/chunk-QN33PNHL-BOdqrixJ.js.map +1 -0
  28. package/dist/chunk-QZHKN3VN-BFPNdgmW.js +16 -0
  29. package/dist/chunk-QZHKN3VN-BFPNdgmW.js.map +1 -0
  30. package/dist/chunk-TZMSLE5B-BZuxNW58.js +65 -0
  31. package/dist/chunk-TZMSLE5B-BZuxNW58.js.map +1 -0
  32. package/dist/classDiagram-2ON5EDUG-CiRjpBEe.js +17 -0
  33. package/dist/classDiagram-2ON5EDUG-CiRjpBEe.js.map +1 -0
  34. package/dist/classDiagram-v2-WZHVMYZB-CiRjpBEe.js +17 -0
  35. package/dist/classDiagram-v2-WZHVMYZB-CiRjpBEe.js.map +1 -0
  36. package/dist/clone-Bm_onhkP.js +9 -0
  37. package/dist/clone-Bm_onhkP.js.map +1 -0
  38. package/dist/cose-bilkent-S5V4N54A-D9xMKgKB.js +2609 -0
  39. package/dist/cose-bilkent-S5V4N54A-D9xMKgKB.js.map +1 -0
  40. package/dist/dagre-6UL2VRFP-BhIQJjaK.js +445 -0
  41. package/dist/dagre-6UL2VRFP-BhIQJjaK.js.map +1 -0
  42. package/dist/diagram-PSM6KHXK-h4YEzD1S.js +532 -0
  43. package/dist/diagram-PSM6KHXK-h4YEzD1S.js.map +1 -0
  44. package/dist/diagram-QEK2KX5R-spuV0akZ.js +218 -0
  45. package/dist/diagram-QEK2KX5R-spuV0akZ.js.map +1 -0
  46. package/dist/diagram-S2PKOQOG-CQx-wsyw.js +143 -0
  47. package/dist/diagram-S2PKOQOG-CQx-wsyw.js.map +1 -0
  48. package/dist/erDiagram-Q2GNP2WA-Cqkjjf2a.js +842 -0
  49. package/dist/erDiagram-Q2GNP2WA-Cqkjjf2a.js.map +1 -0
  50. package/dist/flowDiagram-NV44I4VS-mCXE9u9b.js +1621 -0
  51. package/dist/flowDiagram-NV44I4VS-mCXE9u9b.js.map +1 -0
  52. package/dist/ganttDiagram-JELNMOA3-Bz1GBIHE.js +2671 -0
  53. package/dist/ganttDiagram-JELNMOA3-Bz1GBIHE.js.map +1 -0
  54. package/dist/gitGraphDiagram-V2S2FVAM-Be01Oq15.js +700 -0
  55. package/dist/gitGraphDiagram-V2S2FVAM-Be01Oq15.js.map +1 -0
  56. package/dist/graph-DVWVTM7e.js +248 -0
  57. package/dist/graph-DVWVTM7e.js.map +1 -0
  58. package/dist/index-kKw24iiA.js +34 -0
  59. package/dist/index-kKw24iiA.js.map +1 -0
  60. package/dist/index.d.ts +0 -11
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +270 -277
  63. package/dist/index.js.map +1 -1
  64. package/dist/infoDiagram-HS3SLOUP-joTtnw9j.js +25 -0
  65. package/dist/infoDiagram-HS3SLOUP-joTtnw9j.js.map +1 -0
  66. package/dist/journeyDiagram-XKPGCS4Q-CMVu7VEd.js +835 -0
  67. package/dist/journeyDiagram-XKPGCS4Q-CMVu7VEd.js.map +1 -0
  68. package/dist/kanban-definition-3W4ZIXB7-CfanK5Eg.js +720 -0
  69. package/dist/kanban-definition-3W4ZIXB7-CfanK5Eg.js.map +1 -0
  70. package/dist/katex-Cj93GM5Y.js +11605 -0
  71. package/dist/katex-Cj93GM5Y.js.map +1 -0
  72. package/dist/layout-BC8VSiQq.js +1336 -0
  73. package/dist/layout-BC8VSiQq.js.map +1 -0
  74. package/dist/linear-GV5CIa17.js +260 -0
  75. package/dist/linear-GV5CIa17.js.map +1 -0
  76. package/dist/marzipan.d.ts +1 -2
  77. package/dist/marzipan.d.ts.map +1 -1
  78. package/dist/marzipan.js +1 -19
  79. package/dist/marzipan.js.map +1 -1
  80. package/dist/mermaid.core-cSWK5aGH.js +15302 -0
  81. package/dist/mermaid.core-cSWK5aGH.js.map +1 -0
  82. package/dist/mindmap-definition-VGOIOE7T-Vu_RTZar.js +785 -0
  83. package/dist/mindmap-definition-VGOIOE7T-Vu_RTZar.js.map +1 -0
  84. package/dist/parser.d.ts.map +1 -1
  85. package/dist/parser.js +6 -5
  86. package/dist/parser.js.map +1 -1
  87. package/dist/pieDiagram-ADFJNKIX-BUcd1l-6.js +162 -0
  88. package/dist/pieDiagram-ADFJNKIX-BUcd1l-6.js.map +1 -0
  89. package/dist/plugins/accentSwatchPlugin.d.ts +1 -1
  90. package/dist/plugins/accentSwatchPlugin.d.ts.map +1 -1
  91. package/dist/plugins/accentSwatchPlugin.js +162 -81
  92. package/dist/plugins/accentSwatchPlugin.js.map +1 -1
  93. package/dist/plugins/block-handles.d.ts +10 -2
  94. package/dist/plugins/block-handles.d.ts.map +1 -1
  95. package/dist/plugins/block-handles.js +77 -51
  96. package/dist/plugins/block-handles.js.map +1 -1
  97. package/dist/plugins/index.d.ts +0 -2
  98. package/dist/plugins/index.d.ts.map +1 -1
  99. package/dist/plugins/index.js +27 -29
  100. package/dist/plugins/index.js.map +1 -1
  101. package/dist/plugins/mermaidPlugin.js +1 -1
  102. package/dist/plugins/tinyHighlight.d.ts.map +1 -1
  103. package/dist/plugins/tinyHighlight.js +34 -22
  104. package/dist/plugins/tinyHighlight.js.map +1 -1
  105. package/dist/quadrantDiagram-AYHSOK5B-B1ekOH99.js +1023 -0
  106. package/dist/quadrantDiagram-AYHSOK5B-B1ekOH99.js.map +1 -0
  107. package/dist/requirementDiagram-UZGBJVZJ-BNcVcwNf.js +851 -0
  108. package/dist/requirementDiagram-UZGBJVZJ-BNcVcwNf.js.map +1 -0
  109. package/dist/sankeyDiagram-TZEHDZUN-BpHcdj5K.js +811 -0
  110. package/dist/sankeyDiagram-TZEHDZUN-BpHcdj5K.js.map +1 -0
  111. package/dist/sequenceDiagram-WL72ISMW-D5UyNvsv.js +2512 -0
  112. package/dist/sequenceDiagram-WL72ISMW-D5UyNvsv.js.map +1 -0
  113. package/dist/stateDiagram-FKZM4ZOC-C8DBscXu.js +264 -0
  114. package/dist/stateDiagram-FKZM4ZOC-C8DBscXu.js.map +1 -0
  115. package/dist/stateDiagram-v2-4FDKWEC3-CHqwUDPY.js +17 -0
  116. package/dist/stateDiagram-v2-4FDKWEC3-CHqwUDPY.js.map +1 -0
  117. package/dist/timeline-definition-IT6M3QCI-Dtg0oJbr.js +796 -0
  118. package/dist/timeline-definition-IT6M3QCI-Dtg0oJbr.js.map +1 -0
  119. package/dist/treemap-GDKQZRPO-rbQo3Em-.js +17926 -0
  120. package/dist/treemap-GDKQZRPO-rbQo3Em-.js.map +1 -0
  121. package/dist/xychartDiagram-PRI3JC2R-uNpgYSnV.js +1341 -0
  122. package/dist/xychartDiagram-PRI3JC2R-uNpgYSnV.js.map +1 -0
  123. package/docs/.vitepress/config.ts +1 -1
  124. package/docs/README.md +6 -8
  125. package/docs/TABLE_OF_CONTENTS.md +4 -1
  126. package/docs/api.md +262 -202
  127. package/docs/index.md +22 -19
  128. package/docs/plugins.md +27 -23
  129. package/package.json +1 -1
  130. package/docs/block-handles.md +0 -325
package/docs/index.md CHANGED
@@ -15,6 +15,9 @@ hero:
15
15
  - theme: alt
16
16
  text: API Reference
17
17
  link: /api
18
+ - theme: alt
19
+ text: 🛝 Playground
20
+ link: https://bakeshop.pinkpixel.dev
18
21
  - theme: alt
19
22
  text: View on GitHub
20
23
  link: https://github.com/pinkpixel-dev/marzipan
@@ -49,11 +52,11 @@ npm install @pinkpixel/marzipan
49
52
  ## Create Your First Editor
50
53
 
51
54
  ```ts
52
- import { Marzipan } from '@pinkpixel/marzipan';
55
+ import { Marzipan } from "@pinkpixel/marzipan";
53
56
 
54
- const [editor] = new Marzipan('#my-textarea', {
57
+ const [editor] = new Marzipan("#my-textarea", {
55
58
  toolbar: true,
56
- theme: 'cave',
59
+ theme: "cave",
57
60
  smartLists: true,
58
61
  });
59
62
  ```
@@ -61,35 +64,35 @@ const [editor] = new Marzipan('#my-textarea', {
61
64
  ## Use the Bundled Actions
62
65
 
63
66
  ```ts
64
- import { actions } from '@pinkpixel/marzipan';
67
+ import { actions } from "@pinkpixel/marzipan";
65
68
 
66
- const textarea = document.querySelector('textarea')!;
69
+ const textarea = document.querySelector("textarea")!;
67
70
  actions.toggleBold(textarea);
68
71
  ```
69
72
 
70
73
  ## Add a Plugin
71
74
 
72
75
  ```ts
73
- import { tablePlugin } from '@pinkpixel/marzipan/plugins/tablePlugin';
76
+ import { tablePlugin } from "@pinkpixel/marzipan/plugins/tablePlugin";
74
77
 
75
- new Marzipan('#editor', {
78
+ new Marzipan("#editor", {
76
79
  plugins: [tablePlugin()],
77
80
  });
78
81
  ```
79
82
 
80
83
  ## Bundled Plugins
81
84
 
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 |
85
+ | Plugin | Description |
86
+ | ----------------------- | ----------------------------------------------------------------------------------------- |
87
+ | `tablePlugin` | Toolbar-driven table generator with inline editing controls |
88
+ | `tableGridPlugin` | Grid overlay for rapid column/row creation |
89
+ | `tableGeneratorPlugin` | Quick GFM table inserter with prompt-driven sizing |
90
+ | `tinyHighlightPlugin` | Zero-runtime syntax highlighting for fenced code blocks |
91
+ | `accentSwatchPlugin` | Synced accent palette picker |
92
+ | `imageManagerPlugin` | Dropzone and gallery UI for inserting images and managing uploads |
93
+ | `imagePickerPlugin` | Toolbar button for inserting images via URL or optional uploader callback |
94
+ | `mermaidPlugin` | Diagram rendering via ESM import |
95
+ | `mermaidExternalPlugin` | Mermaid integration via CDN script tag |
96
+ | `BlockHandlesPlugin` | Interactive block manipulation with visual handles, context menus, and keyboard shortcuts |
94
97
 
95
98
  See the full [Plugin Catalogue](/plugins) for configuration details.
package/docs/plugins.md CHANGED
@@ -5,33 +5,38 @@ Marzipan ships first-party plugins from the `src/plugins` directory. Each plugin
5
5
  ## Using a plugin
6
6
 
7
7
  ### Individual plugin imports (recommended)
8
+
8
9
  ```ts
9
- import { Marzipan } from '@pinkpixel/marzipan';
10
- import { tablePlugin } from '@pinkpixel/marzipan/plugins/tablePlugin';
10
+ import { Marzipan } from "@pinkpixel/marzipan";
11
+ import { tablePlugin } from "@pinkpixel/marzipan/plugins/tablePlugin";
11
12
 
12
- new Marzipan('#editor', {
13
+ new Marzipan("#editor", {
13
14
  toolbar: true,
14
- plugins: [tablePlugin({
15
- defaultColumns: 3,
16
- defaultRows: 4,
17
- })],
15
+ plugins: [
16
+ tablePlugin({
17
+ defaultColumns: 3,
18
+ defaultRows: 4,
19
+ }),
20
+ ],
18
21
  });
19
22
  ```
20
23
 
21
24
  ### Main package imports (convenience)
25
+
22
26
  ```ts
23
- import { Marzipan, tablePlugin, mermaidPlugin } from '@pinkpixel/marzipan';
27
+ import { Marzipan, tablePlugin, mermaidPlugin } from "@pinkpixel/marzipan";
24
28
 
25
- new Marzipan('#editor', {
29
+ new Marzipan("#editor", {
26
30
  plugins: [tablePlugin(), mermaidPlugin()],
27
31
  });
28
32
  ```
29
33
 
30
34
  ### Namespace imports (all plugins)
35
+
31
36
  ```ts
32
- import { Marzipan, plugins } from '@pinkpixel/marzipan';
37
+ import { Marzipan, plugins } from "@pinkpixel/marzipan";
33
38
 
34
- new Marzipan('#editor', {
39
+ new Marzipan("#editor", {
35
40
  plugins: [
36
41
  plugins.tablePlugin(),
37
42
  plugins.mermaidPlugin(),
@@ -44,18 +49,17 @@ Every factory returns an object that Marzipan consumes internally. You can mix a
44
49
 
45
50
  ## Available plugins
46
51
 
47
- | Plugin | Import Path | Description |
48
- |--------|-------------|-------------|
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. |
51
- | `imageManagerPlugin` | `@pinkpixel/marzipan/plugins/imageManagerPlugin` | Dropzone and gallery UI for inserting images and managing uploads. |
52
- | `imagePickerPlugin` | `@pinkpixel/marzipan/plugins/imagePickerPlugin` | Toolbar button for inserting images via URL or optional uploader callback. |
53
- | `mermaidPlugin` | `@pinkpixel/marzipan/plugins/mermaidPlugin` | Lazy-loads Mermaid from npm/ESM and renders diagrams inline. |
54
- | `mermaidExternalPlugin` | `@pinkpixel/marzipan/plugins/mermaidExternal` | Mermaid integration that targets a CDN script tag—perfect for sandboxed playgrounds. |
55
- | `tablePlugin` | `@pinkpixel/marzipan/plugins/tablePlugin` | Toolbar-driven table generator with inline editing controls. |
56
- | `tableGridPlugin` | `@pinkpixel/marzipan/plugins/tableGridPlugin` | Grid overlay for rapid column/row creation (exports `tableGridStyles`). |
57
- | `tableGeneratorPlugin` | `@pinkpixel/marzipan/plugins/tableGenerator` | Quick GFM table inserter with prompt-driven sizing. |
58
- | `tinyHighlightPlugin` | `@pinkpixel/marzipan/plugins/tinyHighlight` | Zero-runtime syntax highlighting for fenced code blocks (`tinyHighlightStyles` helper available). |
52
+ | Plugin | Import Path | Description |
53
+ | ----------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
54
+ | `accentSwatchPlugin` | `@pinkpixel/marzipan/plugins/accentSwatchPlugin` | Adds a palette picker for accent colours and syncs with the toolbar + stats bar. |
55
+ | `imageManagerPlugin` | `@pinkpixel/marzipan/plugins/imageManagerPlugin` | Dropzone and gallery UI for inserting images and managing uploads. |
56
+ | `imagePickerPlugin` | `@pinkpixel/marzipan/plugins/imagePickerPlugin` | Toolbar button for inserting images via URL or optional uploader callback. |
57
+ | `mermaidPlugin` | `@pinkpixel/marzipan/plugins/mermaidPlugin` | Lazy-loads Mermaid from npm/ESM and renders diagrams inline. |
58
+ | `mermaidExternalPlugin` | `@pinkpixel/marzipan/plugins/mermaidExternal` | Mermaid integration that targets a CDN script tag—perfect for sandboxed playgrounds. |
59
+ | `tablePlugin` | `@pinkpixel/marzipan/plugins/tablePlugin` | Toolbar-driven table generator with inline editing controls. |
60
+ | `tableGridPlugin` | `@pinkpixel/marzipan/plugins/tableGridPlugin` | Grid overlay for rapid column/row creation (exports `tableGridStyles`). |
61
+ | `tableGeneratorPlugin` | `@pinkpixel/marzipan/plugins/tableGenerator` | Quick GFM table inserter with prompt-driven sizing. |
62
+ | `tinyHighlightPlugin` | `@pinkpixel/marzipan/plugins/tinyHighlight` | Zero-runtime syntax highlighting for fenced code blocks (`tinyHighlightStyles` helper available). |
59
63
 
60
64
  > 📝 The plugin names map 1:1 to files in `src/plugins`. Inspect those files for advanced configuration options.
61
65
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pinkpixel/marzipan",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Pure TypeScript markdown editor library with overlay preview",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -1,325 +0,0 @@
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)