@qalma/editor 0.0.1-alpha.0 → 0.0.1-alpha.1
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 +106 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,35 @@
|
|
|
1
1
|
# @qalma/editor
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Angular-first, headless rich text editor toolkit built on [ProseMirror](https://prosemirror.net/).
|
|
4
|
+
|
|
5
|
+
Qalma gives you a typed editor controller, signal-based state, and a small set
|
|
6
|
+
of unstyled Angular primitives (`<qalma-editor>`, `<qalma-content>`,
|
|
7
|
+
`<qalma-toolbar>`, `qalmaCommand`). Everything else — toolbar UI, styling,
|
|
8
|
+
menus, popovers — stays in your app. You choose the plugins, you own the
|
|
9
|
+
markup.
|
|
10
|
+
|
|
11
|
+
> **Status:** alpha (`0.0.x`). The public API may still change between
|
|
12
|
+
> releases.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
npm install @qalma/editor
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`@angular/core` `>=21 <22` is a peer dependency.
|
|
21
|
+
|
|
22
|
+
## Quick start
|
|
4
23
|
|
|
5
24
|
```ts
|
|
25
|
+
import {
|
|
26
|
+
createQalmaEditor,
|
|
27
|
+
HistoryPlugin,
|
|
28
|
+
TextFormattingKit,
|
|
29
|
+
} from '@qalma/editor';
|
|
30
|
+
|
|
6
31
|
const editor = createQalmaEditor({
|
|
32
|
+
content: '<p>Hello world</p>',
|
|
7
33
|
plugins: [
|
|
8
34
|
...TextFormattingKit,
|
|
9
35
|
HistoryPlugin.configure({
|
|
@@ -26,20 +52,86 @@ const editor = createQalmaEditor({
|
|
|
26
52
|
</qalma-editor>
|
|
27
53
|
```
|
|
28
54
|
|
|
29
|
-
##
|
|
55
|
+
## Core concepts
|
|
56
|
+
|
|
57
|
+
### `createQalmaEditor(options)`
|
|
58
|
+
|
|
59
|
+
Builds a `QalmaEditorController`, the headless API your components bind to:
|
|
60
|
+
|
|
61
|
+
| Member | Description |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| `html: Signal<string>` | Serialized HTML of the current document, kept in sync with every edit. |
|
|
64
|
+
| `editable: Signal<boolean>` | Whether the document can be edited. |
|
|
65
|
+
| `execute(command, value?)` | Runs a registered command, e.g. `editor.execute('toggleBold')`. |
|
|
66
|
+
| `canExecute(command, value?)` | Whether a command would currently succeed. |
|
|
67
|
+
| `isCommandActive(command)` | Whether a toggleable command is active for the current selection. |
|
|
68
|
+
| `query<T>(name)` | Reads plugin-provided state, e.g. the link or image under the cursor. |
|
|
69
|
+
| `setHtml(html)` | Replaces the document content. |
|
|
70
|
+
| `setEditable(editable)` | Toggles editability at runtime. |
|
|
71
|
+
| `focus()` | Focuses the editor view. |
|
|
72
|
+
|
|
73
|
+
`options.content` accepts an initial HTML string, and `options.plugins`
|
|
74
|
+
accepts the list of `QalmaPlugin`s that define the schema, commands, and
|
|
75
|
+
behavior available to the editor.
|
|
76
|
+
|
|
77
|
+
### Components and directives
|
|
78
|
+
|
|
79
|
+
- `<qalma-editor [editor]="editor">` — root container that shares the
|
|
80
|
+
controller with its content.
|
|
81
|
+
- `<qalma-content />` — mounts the ProseMirror view. Style its
|
|
82
|
+
`.qalma-content` / `.ProseMirror` descendants from your app's CSS.
|
|
83
|
+
- `<qalma-toolbar>` — an accessible (`role="toolbar"`) wrapper for your
|
|
84
|
+
toolbar controls. Purely structural.
|
|
85
|
+
- `button[qalmaCommand]` — binds a button to a command by name. It calls
|
|
86
|
+
`execute()` on click, reflects `isCommandActive()` via
|
|
87
|
+
`.qalma-command-active` and `aria-pressed`, and disables itself when
|
|
88
|
+
`canExecute()` is false. Pass a command argument with `[qalmaCommandValue]`.
|
|
89
|
+
|
|
90
|
+
### Plugins and kits
|
|
91
|
+
|
|
92
|
+
A `QalmaPlugin` contributes schema nodes/marks, commands, command-state
|
|
93
|
+
queries, shortcuts, and ProseMirror plugins. A **kit** (e.g.
|
|
94
|
+
`TextFormattingKit`) is just a `readonly QalmaPlugin[]` bundling related
|
|
95
|
+
plugins — spread it into `plugins` like any other entry.
|
|
96
|
+
|
|
97
|
+
Configurable plugins expose a `.configure(options)` method that returns a new
|
|
98
|
+
plugin instance with merged options, e.g.
|
|
99
|
+
`HistoryPlugin.configure({ depth: 200 })`.
|
|
100
|
+
|
|
101
|
+
## Available plugins
|
|
102
|
+
|
|
103
|
+
| Plugin | Commands |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| `BoldPlugin`, `ItalicPlugin`, `UnderlinePlugin`, `StrikePlugin` (`TextFormattingKit`) | `toggleBold`, `toggleItalic`, `toggleUnderline`, `toggleStrike` |
|
|
106
|
+
| `SubscriptSuperscriptPlugin` | `toggleSubscript`, `toggleSuperscript` |
|
|
107
|
+
| `HeadingsPlugin` | `setParagraph`, `toggleHeading1`…`toggleHeading6` (configurable levels) |
|
|
108
|
+
| `BlockquotePlugin` | `toggleBlockquote` |
|
|
109
|
+
| `ListsPlugin` | `toggleBulletList`, `toggleOrderedList`, `splitListItem`, `liftListItem`, `sinkListItem` |
|
|
110
|
+
| `CodeBlockPlugin` | `toggleCodeBlock`, `setCodeBlockLanguage` |
|
|
111
|
+
| `LinkPlugin` | `setLink`, `unsetLink` |
|
|
112
|
+
| `ImagePlugin` | `insertImage`, `updateImage` |
|
|
113
|
+
| `MentionPlugin` | `insertMention` |
|
|
114
|
+
| `ColorPlugin` | `setTextColor`, `unsetTextColor`, `setBackgroundColor`, `unsetBackgroundColor` |
|
|
115
|
+
| `HighlightPlugin` | `setHighlight`, `unsetHighlight` |
|
|
116
|
+
| `TextAlignPlugin` | alignment commands for configured node types |
|
|
117
|
+
| `ClearFormattingPlugin` | `clearFormatting` |
|
|
118
|
+
| `HardBreakPlugin` | `insertHardBreak` |
|
|
119
|
+
| `HistoryPlugin` | `undo`, `redo` (`Mod-z`, `Shift-Mod-z`, `Mod-y`) |
|
|
120
|
+
| `PasteRulesPlugin` | normalizes pasted content |
|
|
121
|
+
| `PlaceholderPlugin` | shows placeholder text in an empty document |
|
|
122
|
+
| `TrailingParagraphPlugin` | keeps a trailing empty paragraph at the end of the document |
|
|
123
|
+
|
|
124
|
+
Read each plugin's source under `src/lib/plugins` for configuration options
|
|
125
|
+
(e.g. `HeadingsPlugin.configure({ levels: [1, 2, 3] })`,
|
|
126
|
+
`MentionPlugin.configure({ trigger: '@' })`,
|
|
127
|
+
`LinkPlugin.configure({ allowedProtocols: [...] })`).
|
|
30
128
|
|
|
31
|
-
|
|
32
|
-
styles or classes — the library stays headless. The node is part of a
|
|
33
|
-
paragraph's inline content, so if your global CSS resets images to
|
|
34
|
-
`display: block` (the default in Tailwind's preflight, normalize.css, etc.),
|
|
35
|
-
inline images will behave like standalone blocks: the cursor can't be placed
|
|
36
|
-
next to them and `text-align` won't affect their position.
|
|
129
|
+
## Learn more
|
|
37
130
|
|
|
38
|
-
|
|
131
|
+
`apps/sandbox` is a full working example: a toolbar, link popover, mention
|
|
132
|
+
menu, image upload, and code block highlighting, all built from the public
|
|
133
|
+
`@qalma/editor` API.
|
|
39
134
|
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
display: inline-block;
|
|
43
|
-
vertical-align: bottom;
|
|
44
|
-
}
|
|
135
|
+
```sh
|
|
136
|
+
npx nx serve sandbox
|
|
45
137
|
```
|