@bendyline/squisq-editor-react 0.1.0 → 1.0.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.
- package/README.md +76 -0
- package/dist/index.js +41 -33
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/Toolbar.tsx +50 -45
- package/src/styles/editor.css +21 -0
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# @bendyline/squisq-editor-react
|
|
2
|
+
|
|
3
|
+
React editor shell for Squisq documents with three integrated views: a Monaco-powered raw Markdown editor, a Tiptap WYSIWYG rich text editor, and a live block preview. Switching between views keeps the document in sync automatically.
|
|
4
|
+
|
|
5
|
+
Part of the [Squisq](https://github.com/bendyline/squisq) monorepo.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@bendyline/squisq-editor-react)
|
|
8
|
+
[](https://github.com/bendyline/squisq/blob/main/LICENSE)
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @bendyline/squisq-editor-react @bendyline/squisq @bendyline/squisq-react
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Peer dependencies:** `react` and `react-dom` (v18 or v19).
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import { EditorShell } from '@bendyline/squisq-editor-react';
|
|
22
|
+
import '@bendyline/squisq-editor-react/styles';
|
|
23
|
+
|
|
24
|
+
function App() {
|
|
25
|
+
return <EditorShell initialMarkdown="# Hello World" />;
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Editor Views
|
|
30
|
+
|
|
31
|
+
| View | Powered By | Description |
|
|
32
|
+
| ----------- | ------------- | ----------------------------------------------------- |
|
|
33
|
+
| **Raw** | Monaco Editor | Full Markdown source editing with syntax highlighting |
|
|
34
|
+
| **WYSIWYG** | Tiptap | Rich text editing with a formatting toolbar |
|
|
35
|
+
| **Preview** | DocPlayer | Live rendered block preview with theme selection |
|
|
36
|
+
|
|
37
|
+
## Components
|
|
38
|
+
|
|
39
|
+
| Component | Description |
|
|
40
|
+
| ---------------- | ---------------------------------------------------------------- |
|
|
41
|
+
| `EditorShell` | Top-level editor — combines all three views with a view switcher |
|
|
42
|
+
| `EditorProvider` | Context provider for editor state management |
|
|
43
|
+
|
|
44
|
+
## Context API
|
|
45
|
+
|
|
46
|
+
Use `useEditorContext()` to access editor state and actions from child components:
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import { EditorProvider, useEditorContext } from '@bendyline/squisq-editor-react';
|
|
50
|
+
|
|
51
|
+
function MyComponent() {
|
|
52
|
+
const { state, actions } = useEditorContext();
|
|
53
|
+
// state.markdown, state.view, state.doc
|
|
54
|
+
// actions.setMarkdown(), actions.setView()
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Styles
|
|
59
|
+
|
|
60
|
+
Import the editor CSS:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import '@bendyline/squisq-editor-react/styles';
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Related Packages
|
|
67
|
+
|
|
68
|
+
| Package | Description |
|
|
69
|
+
| ------------------------------------------------------------------------------------ | -------------------------------------------------------------- |
|
|
70
|
+
| [@bendyline/squisq](https://www.npmjs.com/package/@bendyline/squisq) | Headless core — schemas, templates, spatial, markdown, storage |
|
|
71
|
+
| [@bendyline/squisq-react](https://www.npmjs.com/package/@bendyline/squisq-react) | React components for rendering docs |
|
|
72
|
+
| [@bendyline/squisq-formats](https://www.npmjs.com/package/@bendyline/squisq-formats) | DOCX, PDF, HTML import/export |
|
|
73
|
+
|
|
74
|
+
## License
|
|
75
|
+
|
|
76
|
+
[MIT](https://github.com/bendyline/squisq/blob/main/LICENSE)
|
package/dist/index.js
CHANGED
|
@@ -472,43 +472,51 @@ function Toolbar({ className }) {
|
|
|
472
472
|
},
|
|
473
473
|
view.id
|
|
474
474
|
)) }),
|
|
475
|
-
!isPreview && /* @__PURE__ */
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
/* @__PURE__ */ jsxs(
|
|
500
|
-
"select",
|
|
475
|
+
!isPreview && /* @__PURE__ */ jsxs("div", { className: "squisq-toolbar-actions", children: [
|
|
476
|
+
groups.map((group, gi) => /* @__PURE__ */ jsxs("div", { className: "squisq-toolbar-group", children: [
|
|
477
|
+
gi > 0 && /* @__PURE__ */ jsx2("div", { className: "squisq-toolbar-separator" }),
|
|
478
|
+
BUTTONS.filter((b) => b.group === group).map((btn) => {
|
|
479
|
+
const active = isWysiwyg ? isTiptapActive(tiptapEditor, btn.id) : false;
|
|
480
|
+
return /* @__PURE__ */ jsx2(
|
|
481
|
+
"button",
|
|
482
|
+
{
|
|
483
|
+
className: `squisq-toolbar-button${active ? " squisq-toolbar-button--active" : ""}`,
|
|
484
|
+
title: btn.title,
|
|
485
|
+
onClick: () => handleAction(btn.id),
|
|
486
|
+
"aria-label": btn.title,
|
|
487
|
+
"aria-pressed": active,
|
|
488
|
+
style: btn.iconStyle,
|
|
489
|
+
children: btn.icon
|
|
490
|
+
},
|
|
491
|
+
btn.id
|
|
492
|
+
);
|
|
493
|
+
})
|
|
494
|
+
] }, group)),
|
|
495
|
+
currentTemplate !== null && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
496
|
+
/* @__PURE__ */ jsx2("div", { className: "squisq-toolbar-separator" }),
|
|
497
|
+
/* @__PURE__ */ jsx2("div", { className: "squisq-toolbar-group squisq-template-picker", children: /* @__PURE__ */ jsxs(
|
|
498
|
+
"label",
|
|
501
499
|
{
|
|
502
|
-
className: "squisq-template-picker-
|
|
503
|
-
|
|
504
|
-
onChange: (e) => handleTemplatePick(e.target.value),
|
|
500
|
+
className: "squisq-template-picker-label",
|
|
501
|
+
title: "Block template for this heading",
|
|
505
502
|
children: [
|
|
506
|
-
|
|
507
|
-
|
|
503
|
+
"Template:",
|
|
504
|
+
/* @__PURE__ */ jsxs(
|
|
505
|
+
"select",
|
|
506
|
+
{
|
|
507
|
+
className: "squisq-template-picker-select",
|
|
508
|
+
value: currentTemplate,
|
|
509
|
+
onChange: (e) => handleTemplatePick(e.target.value),
|
|
510
|
+
children: [
|
|
511
|
+
/* @__PURE__ */ jsx2("option", { value: "", children: "\u2014 none \u2014" }),
|
|
512
|
+
templateNames.map((name) => /* @__PURE__ */ jsx2("option", { value: name, children: name }, name))
|
|
513
|
+
]
|
|
514
|
+
}
|
|
515
|
+
)
|
|
508
516
|
]
|
|
509
517
|
}
|
|
510
|
-
)
|
|
511
|
-
] })
|
|
518
|
+
) })
|
|
519
|
+
] })
|
|
512
520
|
] })
|
|
513
521
|
]
|
|
514
522
|
}
|