@notectl/core 1.0.0 → 1.0.3
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 +5 -2
- package/dist/index.d.ts +104 -13
- package/dist/notectl-core.js +133 -40
- package/dist/notectl-core.js.map +1 -1
- package/dist/notectl-core.mjs +4689 -4100
- package/dist/notectl-core.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -28,6 +28,7 @@ Most editors bolt formatting on top of `contenteditable` and hope for the best.
|
|
|
28
28
|
- **Immutable state** — predictable updates, time-travel undo/redo, zero mutation bugs
|
|
29
29
|
- **Transaction system** — atomic, invertible steps with middleware support
|
|
30
30
|
- **Zero framework lock-in** — works with React, Vue, Svelte, Angular, or plain JS
|
|
31
|
+
- **Native Angular integration** — available as [`@notectl/angular`](https://www.npmjs.com/package/@notectl/angular) for idiomatic Angular usage
|
|
31
32
|
- **Tiny dependency footprint** — single runtime dependency (DOMPurify)
|
|
32
33
|
|
|
33
34
|
<br />
|
|
@@ -37,6 +38,7 @@ Check out the [live playground](https://samyssmile.github.io/notectl/playground/
|
|
|
37
38
|
|
|
38
39
|
## Wanna see full working example?
|
|
39
40
|
`examples/vanillajs/` is a great place to see everything in action.
|
|
41
|
+
`examples/angular/` shows how to use notectl in Angular with the `@notectl/angular` package.
|
|
40
42
|
|
|
41
43
|
## Quick Start
|
|
42
44
|
|
|
@@ -52,15 +54,16 @@ npm install @notectl/core
|
|
|
52
54
|
```ts
|
|
53
55
|
import {
|
|
54
56
|
createEditor,
|
|
57
|
+
ThemePreset,
|
|
55
58
|
TextFormattingPlugin,
|
|
56
59
|
HeadingPlugin,
|
|
57
60
|
ListPlugin,
|
|
58
61
|
LinkPlugin,
|
|
59
62
|
TablePlugin,
|
|
60
|
-
ToolbarPlugin,
|
|
61
63
|
} from '@notectl/core';
|
|
62
64
|
|
|
63
65
|
const editor = await createEditor({
|
|
66
|
+
theme: ThemePreset.Light,
|
|
64
67
|
toolbar: [
|
|
65
68
|
[new TextFormattingPlugin({ bold: true, italic: true, underline: true })],
|
|
66
69
|
[new HeadingPlugin()],
|
|
@@ -74,7 +77,7 @@ const editor = await createEditor({
|
|
|
74
77
|
document.body.appendChild(editor);
|
|
75
78
|
```
|
|
76
79
|
|
|
77
|
-
That's it. A full-featured editor in
|
|
80
|
+
That's it. A full-featured editor in 16 lines. `ThemePreset.Light` and `ThemePreset.Dark` are available out of the box.
|
|
78
81
|
|
|
79
82
|
<br />
|
|
80
83
|
|
package/dist/index.d.ts
CHANGED
|
@@ -122,6 +122,21 @@ export declare class BlockquotePlugin implements Plugin_2 {
|
|
|
122
122
|
private setBlockType;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
export declare interface BlockTypePickerEntry {
|
|
126
|
+
/** Unique identifier, e.g. 'heading-1', 'footer'. */
|
|
127
|
+
readonly id: string;
|
|
128
|
+
/** Display label shown in the picker, e.g. 'Heading 1'. */
|
|
129
|
+
readonly label: string;
|
|
130
|
+
/** Command to execute when the entry is selected. */
|
|
131
|
+
readonly command: string;
|
|
132
|
+
/** Sort order — lower values appear first. */
|
|
133
|
+
readonly priority: number;
|
|
134
|
+
/** Optional styling for the label in the picker dropdown. */
|
|
135
|
+
readonly style?: PickerEntryStyle;
|
|
136
|
+
/** Returns true when this entry matches the current block type. */
|
|
137
|
+
isActive(state: EditorState): boolean;
|
|
138
|
+
}
|
|
139
|
+
|
|
125
140
|
export declare interface BoldMark extends Mark {
|
|
126
141
|
readonly type: MarkTypeName & 'bold';
|
|
127
142
|
}
|
|
@@ -194,6 +209,28 @@ export declare interface CodeBlockConfig {
|
|
|
194
209
|
readonly textColor?: string;
|
|
195
210
|
/** Default header/label text color (overrides --notectl-code-block-header-color). */
|
|
196
211
|
readonly headerColor?: string;
|
|
212
|
+
/** Customize keyboard bindings for code block actions. */
|
|
213
|
+
readonly keymap?: CodeBlockKeymap;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Configurable keyboard bindings for CodeBlockPlugin actions.
|
|
218
|
+
* Omit a slot to use the default; set to `null` to disable the binding.
|
|
219
|
+
*
|
|
220
|
+
* Key descriptor format: `'Mod-Enter'`, `'Mod-Shift-M'`, etc.
|
|
221
|
+
* `Mod` resolves to Cmd on macOS, Ctrl on Windows/Linux.
|
|
222
|
+
*/
|
|
223
|
+
export declare interface CodeBlockKeymap {
|
|
224
|
+
/**
|
|
225
|
+
* Insert a new paragraph below the code block and move the cursor there.
|
|
226
|
+
* @default 'Mod-Enter'
|
|
227
|
+
*/
|
|
228
|
+
readonly insertAfter?: string | null;
|
|
229
|
+
/**
|
|
230
|
+
* Toggle the current block between code block and paragraph.
|
|
231
|
+
* @default 'Mod-Shift-M'
|
|
232
|
+
*/
|
|
233
|
+
readonly toggle?: string | null;
|
|
197
234
|
}
|
|
198
235
|
|
|
199
236
|
export declare class CodeBlockPlugin implements Plugin_2 {
|
|
@@ -201,10 +238,12 @@ export declare class CodeBlockPlugin implements Plugin_2 {
|
|
|
201
238
|
readonly name = "Code Block";
|
|
202
239
|
readonly priority = 36;
|
|
203
240
|
private readonly config;
|
|
241
|
+
private readonly resolvedKeymap;
|
|
204
242
|
private context;
|
|
205
243
|
constructor(config?: Partial<CodeBlockConfig>);
|
|
206
244
|
init(context: PluginContext): void;
|
|
207
245
|
destroy(): void;
|
|
246
|
+
onStateChange(oldState: EditorState, newState: EditorState, _tr: Transaction): void;
|
|
208
247
|
decorations(state: EditorState): DecorationSet;
|
|
209
248
|
private registerNodeSpec;
|
|
210
249
|
private registerNodeView;
|
|
@@ -234,6 +273,21 @@ export declare class CodeBlockPlugin implements Plugin_2 {
|
|
|
234
273
|
* Exits to the previous block.
|
|
235
274
|
*/
|
|
236
275
|
private handleArrowUp;
|
|
276
|
+
/**
|
|
277
|
+
* Handles ArrowRight at the end of a code block.
|
|
278
|
+
* Exits to the next block or creates a paragraph below.
|
|
279
|
+
*/
|
|
280
|
+
private handleArrowRight;
|
|
281
|
+
/**
|
|
282
|
+
* Handles ArrowLeft at the start of a code block.
|
|
283
|
+
* Exits to the previous block at end.
|
|
284
|
+
*/
|
|
285
|
+
private handleArrowLeft;
|
|
286
|
+
/**
|
|
287
|
+
* Handles Mod+Enter: always creates a paragraph below and moves cursor there.
|
|
288
|
+
*/
|
|
289
|
+
private handleModEnter;
|
|
290
|
+
private setBlockFocused;
|
|
237
291
|
private toggleCodeBlock;
|
|
238
292
|
private insertCodeBlock;
|
|
239
293
|
private exitOnDoubleEnter;
|
|
@@ -751,6 +805,7 @@ export declare class HeadingPlugin implements Plugin_2 {
|
|
|
751
805
|
private registerCommands;
|
|
752
806
|
private registerKeymaps;
|
|
753
807
|
private registerInputRules;
|
|
808
|
+
private registerPickerEntries;
|
|
754
809
|
private registerToolbarItem;
|
|
755
810
|
private updateComboLabel;
|
|
756
811
|
private getActiveLabel;
|
|
@@ -1286,6 +1341,14 @@ export declare interface NodeSpec<T extends string = string> {
|
|
|
1286
1341
|
readonly parseHTML?: readonly ParseRule[];
|
|
1287
1342
|
/** Tags and attributes this spec needs through DOMPurify sanitization. */
|
|
1288
1343
|
readonly sanitize?: SanitizeConfig;
|
|
1344
|
+
/**
|
|
1345
|
+
* If provided, the Reconciler groups consecutive blocks with the same
|
|
1346
|
+
* wrapper key into a shared wrapper element. Useful for semantic list
|
|
1347
|
+
* wrappers (`<ul>`, `<ol>`) around `<li>` block elements.
|
|
1348
|
+
*/
|
|
1349
|
+
wrapper?(node: Omit<BlockNode, 'attrs'> & {
|
|
1350
|
+
readonly attrs: NodeAttrsFor<T>;
|
|
1351
|
+
}): WrapperSpec;
|
|
1289
1352
|
}
|
|
1290
1353
|
|
|
1291
1354
|
/** @deprecated Use {@link NodeTypeName} for new code. */
|
|
@@ -1413,7 +1476,7 @@ export declare class NotectlEditor extends HTMLElement {
|
|
|
1413
1476
|
private emit;
|
|
1414
1477
|
private onStateChange;
|
|
1415
1478
|
private updateEmptyState;
|
|
1416
|
-
private
|
|
1479
|
+
private announceStateChange;
|
|
1417
1480
|
private replaceState;
|
|
1418
1481
|
private serializeBlock;
|
|
1419
1482
|
private serializeInlineContent;
|
|
@@ -1462,6 +1525,11 @@ export declare interface PartialTheme {
|
|
|
1462
1525
|
readonly tooltip?: Partial<ThemeTooltip>;
|
|
1463
1526
|
}
|
|
1464
1527
|
|
|
1528
|
+
export declare interface PickerEntryStyle {
|
|
1529
|
+
readonly fontSize: string;
|
|
1530
|
+
readonly fontWeight: string;
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1465
1533
|
declare interface Plugin_2<TConfig extends Record<string, unknown> = Record<string, unknown>> {
|
|
1466
1534
|
readonly id: string;
|
|
1467
1535
|
readonly name: string;
|
|
@@ -1504,7 +1572,10 @@ export declare interface PluginContext {
|
|
|
1504
1572
|
registerToolbarItem(item: ToolbarItem): void;
|
|
1505
1573
|
registerInlineNodeSpec<T extends string>(spec: InlineNodeSpec<T>): void;
|
|
1506
1574
|
registerFileHandler(pattern: string, handler: FileHandler): void;
|
|
1575
|
+
registerBlockTypePickerEntry(entry: BlockTypePickerEntry): void;
|
|
1507
1576
|
getSchemaRegistry(): SchemaRegistry;
|
|
1577
|
+
/** Pushes a screen reader announcement via the editor's aria-live region. */
|
|
1578
|
+
announce(text: string): void;
|
|
1508
1579
|
}
|
|
1509
1580
|
|
|
1510
1581
|
export declare interface PluginEventBus {
|
|
@@ -1573,6 +1644,8 @@ export declare interface PluginManagerInitOptions {
|
|
|
1573
1644
|
dispatch(transaction: Transaction): void;
|
|
1574
1645
|
getContainer(): HTMLElement;
|
|
1575
1646
|
getPluginContainer(position: 'top' | 'bottom'): HTMLElement;
|
|
1647
|
+
/** Pushes a screen reader announcement via the editor's aria-live region. */
|
|
1648
|
+
announce?(text: string): void;
|
|
1576
1649
|
/** Called after all plugin init() calls complete, before onReady(). */
|
|
1577
1650
|
onBeforeReady?(): void | Promise<void>;
|
|
1578
1651
|
}
|
|
@@ -1660,6 +1733,7 @@ export declare class SchemaRegistry {
|
|
|
1660
1733
|
private readonly _toolbarItems;
|
|
1661
1734
|
private readonly _toolbarItemPluginMap;
|
|
1662
1735
|
private readonly _fileHandlers;
|
|
1736
|
+
private readonly _blockTypePickerEntries;
|
|
1663
1737
|
registerNodeSpec<T extends string>(spec: NodeSpec<T>): void;
|
|
1664
1738
|
getNodeSpec(type: string): NodeSpec | undefined;
|
|
1665
1739
|
removeNodeSpec(type: string): void;
|
|
@@ -1690,6 +1764,9 @@ export declare class SchemaRegistry {
|
|
|
1690
1764
|
getFileHandlers(): readonly FileHandlerEntry[];
|
|
1691
1765
|
matchFileHandlers(mimeType: string): FileHandler[];
|
|
1692
1766
|
removeFileHandler(handler: FileHandler): void;
|
|
1767
|
+
registerBlockTypePickerEntry(entry: BlockTypePickerEntry): void;
|
|
1768
|
+
getBlockTypePickerEntries(): readonly BlockTypePickerEntry[];
|
|
1769
|
+
removeBlockTypePickerEntry(id: string): void;
|
|
1693
1770
|
/** Returns all NodeSpec parseHTML rules, sorted by priority descending. */
|
|
1694
1771
|
getBlockParseRules(): readonly {
|
|
1695
1772
|
readonly rule: ParseRule;
|
|
@@ -2126,37 +2203,38 @@ export declare class ToolbarPlugin implements Plugin_2 {
|
|
|
2126
2203
|
private context;
|
|
2127
2204
|
private toolbarElement;
|
|
2128
2205
|
private buttons;
|
|
2129
|
-
private activePopup;
|
|
2130
|
-
private closePopupHandler;
|
|
2131
2206
|
private readonly hiddenItems;
|
|
2132
|
-
private tooltipElement;
|
|
2133
|
-
private tooltipTimer;
|
|
2134
2207
|
private readonly layoutConfig;
|
|
2208
|
+
private focusedIndex;
|
|
2209
|
+
private tooltip;
|
|
2210
|
+
private popupController;
|
|
2135
2211
|
constructor(layoutConfig?: ToolbarLayoutConfig);
|
|
2136
2212
|
init(context: PluginContext): void;
|
|
2137
2213
|
onReady(): void;
|
|
2138
2214
|
destroy(): void;
|
|
2139
2215
|
onStateChange(_oldState: EditorState, newState: EditorState, _tr: Transaction): void;
|
|
2140
2216
|
onConfigure(config: PluginConfig): void;
|
|
2141
|
-
private createTooltipElement;
|
|
2142
|
-
private showTooltip;
|
|
2143
|
-
private hideTooltip;
|
|
2144
2217
|
private createToolbarElement;
|
|
2145
2218
|
private renderItems;
|
|
2219
|
+
private initRovingTabindex;
|
|
2220
|
+
private setRovingFocus;
|
|
2221
|
+
/** Returns the active element, respecting shadow DOM boundaries. */
|
|
2222
|
+
private getActiveElement;
|
|
2223
|
+
private syncFocusedIndex;
|
|
2224
|
+
private handleToolbarKeydown;
|
|
2225
|
+
/** Activates a toolbar button (shared between mouse click and keyboard). */
|
|
2226
|
+
private activateButton;
|
|
2146
2227
|
private renderItemsByLayout;
|
|
2147
2228
|
private renderItemsByPriority;
|
|
2148
2229
|
private createButton;
|
|
2149
|
-
private activePopupButton;
|
|
2150
|
-
private togglePopup;
|
|
2151
|
-
private closePopup;
|
|
2152
|
-
private renderGridPicker;
|
|
2153
|
-
private renderDropdown;
|
|
2154
2230
|
private updateButtonStates;
|
|
2155
2231
|
}
|
|
2156
2232
|
|
|
2157
2233
|
export declare interface ToolbarServiceAPI {
|
|
2158
2234
|
/** Re-reads isActive/isEnabled from state and updates all buttons. */
|
|
2159
2235
|
refresh(): void;
|
|
2236
|
+
/** Closes the currently open popup, if any. */
|
|
2237
|
+
closePopup(): void;
|
|
2160
2238
|
}
|
|
2161
2239
|
|
|
2162
2240
|
export declare const ToolbarServiceKey: ServiceKey<ToolbarServiceAPI>;
|
|
@@ -2229,6 +2307,7 @@ export declare class TransactionBuilder {
|
|
|
2229
2307
|
export declare interface TransactionMetadata {
|
|
2230
2308
|
readonly origin: TransactionOrigin;
|
|
2231
2309
|
readonly timestamp: number;
|
|
2310
|
+
readonly historyDirection?: 'undo' | 'redo';
|
|
2232
2311
|
}
|
|
2233
2312
|
|
|
2234
2313
|
export declare type TransactionMiddleware = (tr: Transaction, state: EditorState, next: MiddlewareNext) => void;
|
|
@@ -2266,4 +2345,16 @@ export declare function widgetDecoration(blockId: BlockId, offset: number, toDOM
|
|
|
2266
2345
|
readonly key?: string;
|
|
2267
2346
|
}): WidgetDecoration;
|
|
2268
2347
|
|
|
2348
|
+
/** Describes a wrapper element that groups consecutive blocks of the same kind. */
|
|
2349
|
+
export declare interface WrapperSpec {
|
|
2350
|
+
/** The HTML tag for the wrapper element (e.g., 'ul', 'ol'). */
|
|
2351
|
+
readonly tag: string;
|
|
2352
|
+
/** A key to group consecutive blocks. Blocks with the same key share a wrapper. */
|
|
2353
|
+
readonly key: string;
|
|
2354
|
+
/** Optional CSS class for the wrapper element. */
|
|
2355
|
+
readonly className?: string;
|
|
2356
|
+
/** Optional attributes for the wrapper element. */
|
|
2357
|
+
readonly attrs?: Readonly<Record<string, string>>;
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2269
2360
|
export { }
|