@inshapardaz/likhari-react 0.1.7-dev.77 → 0.1.7-dev.81
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/dist/EditorRoot.d.ts.map +1 -1
- package/dist/EditorRoot.js +2 -2
- package/dist/blocks/PageBreakNode.d.ts +30 -0
- package/dist/blocks/PageBreakNode.d.ts.map +1 -0
- package/dist/blocks/PageBreakNode.js +110 -0
- package/dist/components/Toolbar.js +4 -4
- package/dist/i18n/strings.d.ts +3 -1
- package/dist/i18n/strings.d.ts.map +1 -1
- package/dist/i18n/strings.js +6 -3
- package/dist/nodes.d.ts.map +1 -1
- package/dist/nodes.js +2 -0
- package/dist/plugins/PageBreakPlugin.d.ts +3 -0
- package/dist/plugins/PageBreakPlugin.d.ts.map +1 -0
- package/dist/plugins/PageBreakPlugin.js +19 -0
- package/dist/theme/editor.css +39 -0
- package/dist/theme/editorTheme.d.ts.map +1 -1
- package/dist/theme/editorTheme.js +1 -0
- package/package.json +1 -1
package/dist/EditorRoot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAU1D,OAAO,KAAK,EAAe,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAAwB,KAAK,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAKzH,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAKjE,OAAO,EAAgC,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,cAAc,GAAG,YAAY,CAAC,CAAC;IACzD,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAClD;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,KAAK,IAAI,CAAC;IACrD;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IACrC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC;IAClD,iBAAiB,IAAI,OAAO,CAAC;IAC7B,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,KAAK,IAAI,IAAI,CAAC;CACf;AAQD,eAAO,MAAM,UAAU,uGAmKrB,CAAC"}
|
package/dist/EditorRoot.js
CHANGED
|
@@ -7,7 +7,6 @@ import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
|
|
|
7
7
|
import { ListPlugin } from '@lexical/react/LexicalListPlugin';
|
|
8
8
|
import { CheckListPlugin } from '@lexical/react/LexicalCheckListPlugin';
|
|
9
9
|
import { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';
|
|
10
|
-
import { HorizontalRulePlugin } from '@lexical/react/LexicalHorizontalRulePlugin';
|
|
11
10
|
import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';
|
|
12
11
|
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
|
|
13
12
|
import { defaultFormatRegistry } from '@inshapardaz/likhari-converters';
|
|
@@ -18,6 +17,7 @@ import { EditorThemeProvider } from './theme/EditorThemeProvider.js';
|
|
|
18
17
|
import { Toolbar } from './components/Toolbar.js';
|
|
19
18
|
import { injectUrduWebFontsCss } from './fonts/index.js';
|
|
20
19
|
import { LinkPastePlugin } from './plugins/LinkPastePlugin.js';
|
|
20
|
+
import { PageBreakPlugin } from './plugins/PageBreakPlugin.js';
|
|
21
21
|
import { ImageOptionsContext } from './image/ImageOptionsContext.js';
|
|
22
22
|
import { PortalTargetContext } from './PortalTargetContext.js';
|
|
23
23
|
import { UiStringsContext, getStrings } from './i18n/index.js';
|
|
@@ -112,5 +112,5 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, initialCo
|
|
|
112
112
|
// rather than colliding on a shared one.
|
|
113
113
|
const portalTargetId = useId();
|
|
114
114
|
const portalTargetSelector = `#${CSS.escape(portalTargetId)}`;
|
|
115
|
-
return (_jsx(EditorThemeProvider, { theme: theme, colorScheme: colorScheme, accentColor: accentColor, scopeElementId: portalTargetId, children: _jsxs("div", { className: "likhari-root", dir: dir, ref: rootElementRef, "data-document-id": documentId, style: { height: typeof height === 'number' ? `${height}px` : height }, children: [_jsx("div", { id: portalTargetId, className: "likhari-portal-target" }), _jsx(PortalTargetContext.Provider, { value: portalTargetSelector, children: _jsx(UiStringsContext.Provider, { value: strings, children: _jsx(ImageOptionsContext.Provider, { value: imageOptions, children: _jsxs(LexicalComposer, { initialConfig: initialConfig, children: [_jsx(Toolbar, { config: config, onSave: handleSave, isDirty: isDirty, showSave: showSave, fontOptions: fontOptions, direction: dir, locale: locale }), _jsx("div", { className: "likhari-canvas", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "likhari-content-editable", dir: dir, "aria-label": strings.editor.contentLabel }), placeholder: _jsx("div", { className: "likhari-placeholder", children: resolvedPlaceholder }), ErrorBoundary: LexicalErrorBoundary }) }), config.history && _jsx(HistoryPlugin, {}), (config.lists.bullet || config.lists.numbered || config.lists.check) && _jsx(ListPlugin, {}), config.lists.check && _jsx(CheckListPlugin, {}), config.links && _jsx(LinkPlugin, {}), config.links && _jsx(LinkPastePlugin, {}), config.blocks.
|
|
115
|
+
return (_jsx(EditorThemeProvider, { theme: theme, colorScheme: colorScheme, accentColor: accentColor, scopeElementId: portalTargetId, children: _jsxs("div", { className: "likhari-root", dir: dir, ref: rootElementRef, "data-document-id": documentId, style: { height: typeof height === 'number' ? `${height}px` : height }, children: [_jsx("div", { id: portalTargetId, className: "likhari-portal-target" }), _jsx(PortalTargetContext.Provider, { value: portalTargetSelector, children: _jsx(UiStringsContext.Provider, { value: strings, children: _jsx(ImageOptionsContext.Provider, { value: imageOptions, children: _jsxs(LexicalComposer, { initialConfig: initialConfig, children: [_jsx(Toolbar, { config: config, onSave: handleSave, isDirty: isDirty, showSave: showSave, fontOptions: fontOptions, direction: dir, locale: locale }), _jsx("div", { className: "likhari-canvas", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "likhari-content-editable", dir: dir, "aria-label": strings.editor.contentLabel }), placeholder: _jsx("div", { className: "likhari-placeholder", children: resolvedPlaceholder }), ErrorBoundary: LexicalErrorBoundary }) }), config.history && _jsx(HistoryPlugin, {}), (config.lists.bullet || config.lists.numbered || config.lists.check) && _jsx(ListPlugin, {}), config.lists.check && _jsx(CheckListPlugin, {}), config.links && _jsx(LinkPlugin, {}), config.links && _jsx(LinkPastePlugin, {}), config.blocks.pageBreak && _jsx(PageBreakPlugin, {}), _jsx(OnChangePlugin, { onChange: handleChange })] }) }) }) })] }) }));
|
|
116
116
|
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type ReactElement } from 'react';
|
|
2
|
+
import { DecoratorNode, type DOMConversionMap, type DOMExportOutput, type EditorConfig, type LexicalCommand, type LexicalNode, type SerializedLexicalNode } from 'lexical';
|
|
3
|
+
export declare const INSERT_PAGE_BREAK_COMMAND: LexicalCommand<void>;
|
|
4
|
+
export type SerializedPageBreakNode = SerializedLexicalNode;
|
|
5
|
+
/**
|
|
6
|
+
* A manual page break — a print/paginated-export concept with no native
|
|
7
|
+
* Lexical node (lexical-editor-spec.md §4.3/§4.6). Renders as a visible
|
|
8
|
+
* dashed marker while editing, and as `page-break-after: always` both live
|
|
9
|
+
* (a print stylesheet, editor.css) and in exported HTML (`exportDOM`).
|
|
10
|
+
*
|
|
11
|
+
* Mirrors @lexical/react's HorizontalRuleNode pattern: `createDOM` returns
|
|
12
|
+
* the actual visible element (the click target `PageBreakComponent` wires
|
|
13
|
+
* selection/delete against), rather than `decorate()` rendering visuals.
|
|
14
|
+
*/
|
|
15
|
+
export declare class PageBreakNode extends DecoratorNode<ReactElement> {
|
|
16
|
+
static getType(): string;
|
|
17
|
+
static clone(node: PageBreakNode): PageBreakNode;
|
|
18
|
+
static importJSON(): PageBreakNode;
|
|
19
|
+
exportJSON(): SerializedPageBreakNode;
|
|
20
|
+
static importDOM(): DOMConversionMap | null;
|
|
21
|
+
exportDOM(): DOMExportOutput;
|
|
22
|
+
createDOM(config: EditorConfig): HTMLElement;
|
|
23
|
+
getTextContent(): string;
|
|
24
|
+
isInline(): false;
|
|
25
|
+
updateDOM(): boolean;
|
|
26
|
+
decorate(): import("react").JSX.Element;
|
|
27
|
+
}
|
|
28
|
+
export declare function $createPageBreakNode(): PageBreakNode;
|
|
29
|
+
export declare function $isPageBreakNode(node: LexicalNode | null | undefined): node is PageBreakNode;
|
|
30
|
+
//# sourceMappingURL=PageBreakNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageBreakNode.d.ts","sourceRoot":"","sources":["../../src/blocks/PageBreakNode.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAKlE,OAAO,EAOL,aAAa,EAGb,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,EAEhB,KAAK,qBAAqB,EAC3B,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,yBAAyB,EAAE,cAAc,CAAC,IAAI,CAA8C,CAAC;AAE1G,MAAM,MAAM,uBAAuB,GAAG,qBAAqB,CAAC;AA2D5D;;;;;;;;;GASG;AACH,qBAAa,aAAc,SAAQ,aAAa,CAAC,YAAY,CAAC;IAC5D,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa;IAIhD,MAAM,CAAC,UAAU,IAAI,aAAa;IAIlC,UAAU,IAAI,uBAAuB;IAIrC,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAS3C,SAAS,IAAI,eAAe;IAO5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAM5C,cAAc,IAAI,MAAM;IAIxB,QAAQ,IAAI,KAAK;IAIjB,SAAS,IAAI,OAAO;IAIpB,QAAQ;CAGT;AAED,wBAAgB,oBAAoB,IAAI,aAAa,CAEpD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,aAAa,CAE5F"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect } from 'react';
|
|
3
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
4
|
+
import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection';
|
|
5
|
+
import { addClassNamesToElement, mergeRegister, removeClassNamesFromElement } from '@lexical/utils';
|
|
6
|
+
import { useUiStrings } from '../i18n/useStrings.js';
|
|
7
|
+
import { $applyNodeReplacement, $getSelection, $isNodeSelection, CLICK_COMMAND, COMMAND_PRIORITY_LOW, createCommand, DecoratorNode, KEY_BACKSPACE_COMMAND, KEY_DELETE_COMMAND, } from 'lexical';
|
|
8
|
+
export const INSERT_PAGE_BREAK_COMMAND = createCommand('INSERT_PAGE_BREAK_COMMAND');
|
|
9
|
+
const SELECTED_CLASS_NAME = 'likhari-page-break-selected';
|
|
10
|
+
function PageBreakComponent({ nodeKey }) {
|
|
11
|
+
const [editor] = useLexicalComposerContext();
|
|
12
|
+
const strings = useUiStrings();
|
|
13
|
+
const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);
|
|
14
|
+
const onDelete = useCallback((event) => {
|
|
15
|
+
const selection = $getSelection();
|
|
16
|
+
if (isSelected && $isNodeSelection(selection)) {
|
|
17
|
+
event.preventDefault();
|
|
18
|
+
editor.update(() => {
|
|
19
|
+
selection.getNodes().forEach((node) => {
|
|
20
|
+
if ($isPageBreakNode(node))
|
|
21
|
+
node.remove();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
}, [editor, isSelected]);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
return mergeRegister(editor.registerCommand(CLICK_COMMAND, (event) => {
|
|
29
|
+
const element = editor.getElementByKey(nodeKey);
|
|
30
|
+
if (event.target !== element)
|
|
31
|
+
return false;
|
|
32
|
+
if (!event.shiftKey)
|
|
33
|
+
clearSelection();
|
|
34
|
+
setSelected(!isSelected);
|
|
35
|
+
return true;
|
|
36
|
+
}, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_DELETE_COMMAND, onDelete, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_BACKSPACE_COMMAND, onDelete, COMMAND_PRIORITY_LOW));
|
|
37
|
+
}, [clearSelection, editor, isSelected, nodeKey, onDelete, setSelected]);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const element = editor.getElementByKey(nodeKey);
|
|
40
|
+
if (!element)
|
|
41
|
+
return;
|
|
42
|
+
if (isSelected)
|
|
43
|
+
addClassNamesToElement(element, SELECTED_CLASS_NAME);
|
|
44
|
+
else
|
|
45
|
+
removeClassNamesFromElement(element, SELECTED_CLASS_NAME);
|
|
46
|
+
}, [editor, isSelected, nodeKey]);
|
|
47
|
+
return (_jsxs(_Fragment, { children: [_jsx("span", { className: "likhari-page-break-line", "aria-hidden": "true" }), _jsx("span", { className: "likhari-page-break-label", children: strings.editor.pageBreakLabel }), _jsx("span", { className: "likhari-page-break-line", "aria-hidden": "true" })] }));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A manual page break — a print/paginated-export concept with no native
|
|
51
|
+
* Lexical node (lexical-editor-spec.md §4.3/§4.6). Renders as a visible
|
|
52
|
+
* dashed marker while editing, and as `page-break-after: always` both live
|
|
53
|
+
* (a print stylesheet, editor.css) and in exported HTML (`exportDOM`).
|
|
54
|
+
*
|
|
55
|
+
* Mirrors @lexical/react's HorizontalRuleNode pattern: `createDOM` returns
|
|
56
|
+
* the actual visible element (the click target `PageBreakComponent` wires
|
|
57
|
+
* selection/delete against), rather than `decorate()` rendering visuals.
|
|
58
|
+
*/
|
|
59
|
+
export class PageBreakNode extends DecoratorNode {
|
|
60
|
+
static getType() {
|
|
61
|
+
return 'page-break';
|
|
62
|
+
}
|
|
63
|
+
static clone(node) {
|
|
64
|
+
return new PageBreakNode(node.__key);
|
|
65
|
+
}
|
|
66
|
+
static importJSON() {
|
|
67
|
+
return $createPageBreakNode();
|
|
68
|
+
}
|
|
69
|
+
exportJSON() {
|
|
70
|
+
return { type: 'page-break', version: 1 };
|
|
71
|
+
}
|
|
72
|
+
static importDOM() {
|
|
73
|
+
return {
|
|
74
|
+
div: (domNode) => {
|
|
75
|
+
if (!domNode.hasAttribute('data-likhari-page-break'))
|
|
76
|
+
return null;
|
|
77
|
+
return { conversion: () => ({ node: $createPageBreakNode() }), priority: 2 };
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
exportDOM() {
|
|
82
|
+
const element = document.createElement('div');
|
|
83
|
+
element.setAttribute('data-likhari-page-break', '');
|
|
84
|
+
element.style.pageBreakAfter = 'always';
|
|
85
|
+
return { element };
|
|
86
|
+
}
|
|
87
|
+
createDOM(config) {
|
|
88
|
+
const element = document.createElement('div');
|
|
89
|
+
addClassNamesToElement(element, config.theme.pageBreak ?? 'likhari-page-break');
|
|
90
|
+
return element;
|
|
91
|
+
}
|
|
92
|
+
getTextContent() {
|
|
93
|
+
return '\n';
|
|
94
|
+
}
|
|
95
|
+
isInline() {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
updateDOM() {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
decorate() {
|
|
102
|
+
return _jsx(PageBreakComponent, { nodeKey: this.__key });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export function $createPageBreakNode() {
|
|
106
|
+
return $applyNodeReplacement(new PageBreakNode());
|
|
107
|
+
}
|
|
108
|
+
export function $isPageBreakNode(node) {
|
|
109
|
+
return node instanceof PageBreakNode;
|
|
110
|
+
}
|
|
@@ -8,9 +8,9 @@ import { $createParagraphNode } from 'lexical';
|
|
|
8
8
|
import { $createHeadingNode, $createQuoteNode, $isHeadingNode, $isQuoteNode } from '@lexical/rich-text';
|
|
9
9
|
import { $isListNode, INSERT_CHECK_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND, } from '@lexical/list';
|
|
10
10
|
import { $findMatchingParent, $insertNodeToNearestRoot } from '@lexical/utils';
|
|
11
|
-
import { INSERT_HORIZONTAL_RULE_COMMAND } from '@lexical/react/LexicalHorizontalRuleNode';
|
|
12
11
|
import { ImageDialog } from '../image/ImageDialog.js';
|
|
13
12
|
import { $createImageNode } from '../image/ImageNode.js';
|
|
13
|
+
import { INSERT_PAGE_BREAK_COMMAND } from '../blocks/PageBreakNode.js';
|
|
14
14
|
import { $createLinkNode, $isLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link';
|
|
15
15
|
import { LinkDialog } from './LinkDialog.js';
|
|
16
16
|
import { normalizeLinkUrl } from '../utils/linkUrl.js';
|
|
@@ -18,7 +18,7 @@ import { CANVAS_FONT_DEFAULTS, DEFAULT_FONT_OPTIONS, FONT_SIZES_PX } from '../fo
|
|
|
18
18
|
import { setStyleProperty } from '../utils/style.js';
|
|
19
19
|
import { useStrings } from '../i18n/useStrings.js';
|
|
20
20
|
import { usePortalTarget } from '../PortalTargetContext.js';
|
|
21
|
-
import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconBold, IconClearFormatting, IconDeviceFloppy, IconDots, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPencil, IconPhoto, IconPilcrow, IconQuote,
|
|
21
|
+
import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconBold, IconClearFormatting, IconDeviceFloppy, IconDots, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPageBreak, IconPencil, IconPhoto, IconPilcrow, IconQuote, IconSparkles, IconStrikethrough, IconSubscript, IconSuperscript, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
22
22
|
/** Sentinel for "no inline style": Lexical returns the default it is given when
|
|
23
23
|
* the selection has none, so this tells "unstyled" (show the canvas default)
|
|
24
24
|
* apart from "styled with a value the dropdown doesn't list" (show nothing). */
|
|
@@ -427,7 +427,7 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
427
427
|
const showFormattingGroup = headingLevels.length > 0 || config.lists.bullet || config.lists.numbered || config.lists.check || config.blocks.quote;
|
|
428
428
|
const showInlineGroup = fmt.bold || fmt.italic || fmt.underline;
|
|
429
429
|
const showAlignGroup = config.alignment.start || config.alignment.center || config.alignment.justify || config.alignment.left || config.alignment.right;
|
|
430
|
-
const showStubInsertGroup = config.images.linked || config.images.embedded || config.blocks.
|
|
430
|
+
const showStubInsertGroup = config.images.linked || config.images.embedded || config.blocks.pageBreak || config.poetry.enabled;
|
|
431
431
|
const showLanguageGroup = config.language.autocorrect || config.language.textCleanup || config.language.spellCheck;
|
|
432
432
|
// The "script & cleanup" and "indent/outdent" groups (UI spec §3.3) render
|
|
433
433
|
// as normal inline toolbar groups whenever there's room, and only move
|
|
@@ -596,7 +596,7 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
596
596
|
restoreSelection();
|
|
597
597
|
openLinkDialog();
|
|
598
598
|
}, onRemove: removeLink, strings: strings }) })] })) : (_jsx(ToolbarButton, { icon: IconLink, title: strings.toolbar.insertLink, onClick: openLinkDialog })) }, "link")),
|
|
599
|
-
showStubInsertGroup && (_jsxs("div", { className: "likhari-toolbar-group likhari-toolbar-group--collapse-tablet", children: [(config.images.linked || config.images.embedded) && (_jsx(ToolbarButton, { icon: IconPhoto, title: strings.toolbar.insertImage, onClick: openImageDialog })), config.blocks.
|
|
599
|
+
showStubInsertGroup && (_jsxs("div", { className: "likhari-toolbar-group likhari-toolbar-group--collapse-tablet", children: [(config.images.linked || config.images.embedded) && (_jsx(ToolbarButton, { icon: IconPhoto, title: strings.toolbar.insertImage, onClick: openImageDialog })), config.blocks.pageBreak && (_jsx(ToolbarButton, { icon: IconPageBreak, title: strings.toolbar.insertPageBreak, onClick: () => editor.dispatchCommand(INSERT_PAGE_BREAK_COMMAND, undefined) })), config.poetry.enabled && _jsx(StubButton, { icon: IconFeather, title: strings.toolbar.poetryBlocks, comingSoon: strings.toolbar.comingSoon })] }, "stubInsert")),
|
|
600
600
|
showLanguageGroup && (_jsxs("div", { className: "likhari-toolbar-group likhari-toolbar-group--collapse-tablet", children: [config.language.autocorrect && _jsx(StubButton, { icon: IconWand, title: strings.toolbar.autocorrect, comingSoon: strings.toolbar.comingSoon }), config.language.textCleanup && _jsx(StubButton, { icon: IconSparkles, title: strings.toolbar.textCleanup, comingSoon: strings.toolbar.comingSoon }), config.language.spellCheck && _jsx(StubButton, { icon: IconAbc, title: strings.toolbar.spellChecker, comingSoon: strings.toolbar.comingSoon })] }, "language")),
|
|
601
601
|
];
|
|
602
602
|
return (_jsxs("div", { className: "likhari-toolbar", role: "toolbar", "aria-label": strings.toolbar.ariaLabel, ref: toolbarContainerRef, children: [fixedGroups, movableGroups
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export interface Strings {
|
|
|
15
15
|
contentLabel: string;
|
|
16
16
|
/** window.confirm() prompt shown by EditorRef.confirmDiscard() when there are unsaved changes. */
|
|
17
17
|
confirmDiscard: string;
|
|
18
|
+
/** Label shown on a page-break marker's dashed line while editing. */
|
|
19
|
+
pageBreakLabel: string;
|
|
18
20
|
};
|
|
19
21
|
common: {
|
|
20
22
|
cancel: string;
|
|
@@ -40,7 +42,7 @@ export interface Strings {
|
|
|
40
42
|
linkOptions: string;
|
|
41
43
|
insertLink: string;
|
|
42
44
|
insertImage: string;
|
|
43
|
-
|
|
45
|
+
insertPageBreak: string;
|
|
44
46
|
poetryBlocks: string;
|
|
45
47
|
comingSoon: (label: string) => string;
|
|
46
48
|
autocorrect: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;+DAC+D;AAC/D,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,cAAc,CAAC;AAElD,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE;QACN,mGAAmG;QACnG,WAAW,EAAE,MAAM,CAAC;QACpB,gDAAgD;QAChD,YAAY,EAAE,MAAM,CAAC;QACrB,kGAAkG;QAClG,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,EAAE;QACP,gEAAgE;QAChE,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,eAAe,EAAE,MAAM,CAAC;QACxB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,qBAAqB,EAAE,MAAM,CAAC;QAC9B,QAAQ,EAAE,MAAM,CAAC;QACjB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,
|
|
1
|
+
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"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"}
|
package/dist/i18n/strings.js
CHANGED
|
@@ -9,6 +9,7 @@ const en = {
|
|
|
9
9
|
placeholder: 'Start writing…',
|
|
10
10
|
contentLabel: 'Editor content',
|
|
11
11
|
confirmDiscard: 'You have unsaved changes. Discard them?',
|
|
12
|
+
pageBreakLabel: 'Page break',
|
|
12
13
|
},
|
|
13
14
|
common: {
|
|
14
15
|
cancel: 'Cancel',
|
|
@@ -33,7 +34,7 @@ const en = {
|
|
|
33
34
|
linkOptions: 'Link options',
|
|
34
35
|
insertLink: 'Insert link (Ctrl+K)',
|
|
35
36
|
insertImage: 'Insert image',
|
|
36
|
-
|
|
37
|
+
insertPageBreak: 'Insert page break',
|
|
37
38
|
poetryBlocks: 'Poetry blocks',
|
|
38
39
|
comingSoon: (label) => `${label} (coming soon)`,
|
|
39
40
|
autocorrect: 'Auto-correct',
|
|
@@ -146,6 +147,7 @@ const ur = {
|
|
|
146
147
|
placeholder: 'لکھنا شروع کریں…',
|
|
147
148
|
contentLabel: 'ایڈیٹر کا مواد',
|
|
148
149
|
confirmDiscard: 'آپ کی غیر محفوظ شدہ تبدیلیاں ہیں۔ کیا انہیں رد کر دیا جائے؟',
|
|
150
|
+
pageBreakLabel: 'صفحے کی تقسیم',
|
|
149
151
|
},
|
|
150
152
|
common: {
|
|
151
153
|
cancel: 'منسوخ کریں',
|
|
@@ -170,7 +172,7 @@ const ur = {
|
|
|
170
172
|
linkOptions: 'لنک کے اختیارات',
|
|
171
173
|
insertLink: 'لنک شامل کریں (Ctrl+K)',
|
|
172
174
|
insertImage: 'تصویر شامل کریں',
|
|
173
|
-
|
|
175
|
+
insertPageBreak: 'صفحے کی تقسیم شامل کریں',
|
|
174
176
|
poetryBlocks: 'شاعری کے بلاکس',
|
|
175
177
|
comingSoon: (label) => `${label} (جلد آ رہا ہے)`,
|
|
176
178
|
autocorrect: 'خودکار تصحیح',
|
|
@@ -283,6 +285,7 @@ const paShahmukhi = {
|
|
|
283
285
|
placeholder: 'لکھنا شروع کرو…',
|
|
284
286
|
contentLabel: 'ایڈیٹر دی سامگری',
|
|
285
287
|
confirmDiscard: 'تہاڈیاں کجھ تبدیلیاں سنبھالیاں نئیں گئیاں۔ کی ایہناں نوں رد کر دیئے؟',
|
|
288
|
+
pageBreakLabel: 'صفحے دی ونڈ',
|
|
286
289
|
},
|
|
287
290
|
common: {
|
|
288
291
|
cancel: 'رد کرو',
|
|
@@ -307,7 +310,7 @@ const paShahmukhi = {
|
|
|
307
310
|
linkOptions: 'لنک دے اختیار',
|
|
308
311
|
insertLink: 'لنک پاؤ (Ctrl+K)',
|
|
309
312
|
insertImage: 'تصویر پاؤ',
|
|
310
|
-
|
|
313
|
+
insertPageBreak: 'صفحے دی ونڈ پاؤ',
|
|
311
314
|
poetryBlocks: 'شاعری بلاک',
|
|
312
315
|
comingSoon: (label) => `${label} (چھیتی آ رہا اے)`,
|
|
313
316
|
autocorrect: 'خودکار درستی',
|
package/dist/nodes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../src/nodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../src/nodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAQlD;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,EAS5C,CAAC"}
|
package/dist/nodes.js
CHANGED
|
@@ -3,6 +3,7 @@ import { ListItemNode, ListNode } from '@lexical/list';
|
|
|
3
3
|
import { LinkNode } from '@lexical/link';
|
|
4
4
|
import { HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode';
|
|
5
5
|
import { ImageNode } from './image/ImageNode.js';
|
|
6
|
+
import { PageBreakNode } from './blocks/PageBreakNode.js';
|
|
6
7
|
/**
|
|
7
8
|
* Node types registered on the editor at construction time. Per
|
|
8
9
|
* editor-architecture-design.md §2, node registration cannot be conditional
|
|
@@ -20,4 +21,5 @@ export const EDITOR_NODES = [
|
|
|
20
21
|
LinkNode,
|
|
21
22
|
HorizontalRuleNode,
|
|
22
23
|
ImageNode,
|
|
24
|
+
PageBreakNode,
|
|
23
25
|
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageBreakPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/PageBreakPlugin.tsx"],"names":[],"mappings":"AAMA,+FAA+F;AAC/F,wBAAgB,eAAe,SAiB9B"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
3
|
+
import { $getSelection, $isRangeSelection, COMMAND_PRIORITY_EDITOR } from 'lexical';
|
|
4
|
+
import { $insertNodeToNearestRoot } from '@lexical/utils';
|
|
5
|
+
import { $createPageBreakNode, INSERT_PAGE_BREAK_COMMAND } from '../blocks/PageBreakNode.js';
|
|
6
|
+
/** Registers INSERT_PAGE_BREAK_COMMAND — mirrors @lexical/react's own HorizontalRulePlugin. */
|
|
7
|
+
export function PageBreakPlugin() {
|
|
8
|
+
const [editor] = useLexicalComposerContext();
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
return editor.registerCommand(INSERT_PAGE_BREAK_COMMAND, () => {
|
|
11
|
+
const selection = $getSelection();
|
|
12
|
+
if (!$isRangeSelection(selection))
|
|
13
|
+
return false;
|
|
14
|
+
$insertNodeToNearestRoot($createPageBreakNode());
|
|
15
|
+
return true;
|
|
16
|
+
}, COMMAND_PRIORITY_EDITOR);
|
|
17
|
+
}, [editor]);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
package/dist/theme/editor.css
CHANGED
|
@@ -253,6 +253,45 @@
|
|
|
253
253
|
margin: 1.5em 0;
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
+
/* Page break — a print/export concept with no visual meaning while editing
|
|
257
|
+
on screen, so it gets its own clearly-labeled dashed marker rather than
|
|
258
|
+
masquerading as a horizontal rule. The actual page-break behavior only
|
|
259
|
+
takes effect when printing (lexical-editor-spec.md §4.3/§4.6). */
|
|
260
|
+
.likhari-page-break {
|
|
261
|
+
display: flex;
|
|
262
|
+
align-items: center;
|
|
263
|
+
gap: 8px;
|
|
264
|
+
margin: 1.5em 0;
|
|
265
|
+
font-size: 12px;
|
|
266
|
+
cursor: default;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.likhari-page-break-line {
|
|
270
|
+
flex: 1 1 auto;
|
|
271
|
+
border-top: 1px dashed var(--editor-line);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.likhari-page-break-label {
|
|
275
|
+
color: var(--editor-ink-soft);
|
|
276
|
+
white-space: nowrap;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.likhari-page-break-selected {
|
|
280
|
+
outline: 2px solid var(--editor-accent);
|
|
281
|
+
outline-offset: 2px;
|
|
282
|
+
border-radius: 4px;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@media print {
|
|
286
|
+
.likhari-page-break {
|
|
287
|
+
page-break-after: always;
|
|
288
|
+
/* Hide the on-screen marker itself when actually printing — the
|
|
289
|
+
browser's own pagination (triggered by page-break-after) is what
|
|
290
|
+
matters there, not the editing-time label. */
|
|
291
|
+
visibility: hidden;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
256
295
|
/* Images — block-level figure; the caption is static text (edited in the
|
|
257
296
|
image's dialog), and a selected image gets a corner resize handle. */
|
|
258
297
|
.likhari-image-block {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editorTheme.d.ts","sourceRoot":"","sources":["../../src/theme/editorTheme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"editorTheme.d.ts","sourceRoot":"","sources":["../../src/theme/editorTheme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,kBA+BzB,CAAC"}
|