@inshapardaz/likhari-react 0.1.15 → 0.1.16-dev.120
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 -1
- package/dist/blocks/LayoutNode.d.ts +54 -0
- package/dist/blocks/LayoutNode.d.ts.map +1 -0
- package/dist/blocks/LayoutNode.js +138 -0
- package/dist/blocks/layoutActions.d.ts +12 -0
- package/dist/blocks/layoutActions.d.ts.map +1 -0
- package/dist/blocks/layoutActions.js +39 -0
- package/dist/components/LayoutDialog.d.ts +11 -0
- package/dist/components/LayoutDialog.d.ts.map +1 -0
- package/dist/components/LayoutDialog.js +24 -0
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/Toolbar.js +22 -3
- package/dist/i18n/strings.d.ts +5 -0
- package/dist/i18n/strings.d.ts.map +1 -1
- package/dist/i18n/strings.js +15 -0
- package/dist/nodes.d.ts.map +1 -1
- package/dist/nodes.js +3 -0
- package/dist/plugins/LayoutPlugin.d.ts +9 -0
- package/dist/plugins/LayoutPlugin.d.ts.map +1 -0
- package/dist/plugins/LayoutPlugin.js +23 -0
- package/dist/theme/editor.css +18 -0
- package/dist/theme/editorTheme.d.ts.map +1 -1
- package/dist/theme/editorTheme.js +2 -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;AAY1D,OAAO,KAAK,EAA8B,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEjF,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;
|
|
1
|
+
{"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAY1D,OAAO,KAAK,EAA8B,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEjF,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;AAIjE,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAYhF,OAAO,EAAgC,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAMnE,yEAAyE;AACzE,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,YAAY,GAAG,KAAK,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,QAAQ,CAAC;IACjB,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;IAC3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC;;;;;;;;;;;;;;;OAeG;IACH,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,uGAAuG;IACvG,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3E,6EAA6E;IAC7E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,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,uGAkXrB,CAAC"}
|
package/dist/EditorRoot.js
CHANGED
|
@@ -21,6 +21,7 @@ import { Toolbar } from './components/Toolbar.js';
|
|
|
21
21
|
import { injectUrduWebFontsCss } from './fonts/index.js';
|
|
22
22
|
import { LinkPastePlugin } from './plugins/LinkPastePlugin.js';
|
|
23
23
|
import { PageBreakPlugin } from './plugins/PageBreakPlugin.js';
|
|
24
|
+
import { LayoutPlugin } from './plugins/LayoutPlugin.js';
|
|
24
25
|
import { DraftRestore } from './components/DraftRestore.js';
|
|
25
26
|
import { LeaveDialog } from './components/LeaveDialog.js';
|
|
26
27
|
import { clearDraft, createDraftId, hasDraftContent, pruneDrafts, writeDraft, } from './persistence/draftStorage.js';
|
|
@@ -277,7 +278,7 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, initialCo
|
|
|
277
278
|
const portalTargetSelector = `#${CSS.escape(portalTargetId)}`;
|
|
278
279
|
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: _jsxs(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, drafts: autosave
|
|
279
280
|
? { currentId: draftId, maxBytes: autosaveMaxBytes, adoptOnRestore: !documentId, onRestored: handleDraftRestored }
|
|
280
|
-
: undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _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, {}), config.tables && _jsx(TablePlugin, { hasCellMerge: true, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(EditorInstancePlugin, { instanceRef: editorInstanceRef }), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
|
|
281
|
+
: undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _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, {}), config.columns && _jsx(LayoutPlugin, {}), config.tables && _jsx(TablePlugin, { hasCellMerge: true, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(EditorInstancePlugin, { instanceRef: editorInstanceRef }), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
|
|
281
282
|
handleSave();
|
|
282
283
|
settleLeave(true);
|
|
283
284
|
}, onSaveDraft: () => {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type DOMConversionMap, type DOMExportOutput, type EditorConfig, type LexicalCommand, type LexicalNode, type NodeKey, type SerializedElementNode, type Spread, ElementNode } from 'lexical';
|
|
2
|
+
/** Payload: how many (equal-width) columns to create. Ratio support beyond
|
|
3
|
+
* equal widths is deferred (lexical-editor-spec.md §4.9 mentions it as a
|
|
4
|
+
* "configurable" possibility, not a committed requirement for Phase 3). */
|
|
5
|
+
export declare const INSERT_LAYOUT_COMMAND: LexicalCommand<{
|
|
6
|
+
columnCount: number;
|
|
7
|
+
}>;
|
|
8
|
+
export type SerializedLayoutContainerNode = Spread<{
|
|
9
|
+
templateColumns: string;
|
|
10
|
+
}, SerializedElementNode>;
|
|
11
|
+
export type SerializedLayoutItemNode = SerializedElementNode;
|
|
12
|
+
/** A multi-column row (editor-architecture-design.md §3.2): an ElementNode
|
|
13
|
+
* holding one LayoutItemNode per column, laid out with CSS grid. Reused as
|
|
14
|
+
* the structural basis for two-column poetry layouts (spec §4.11). */
|
|
15
|
+
export declare class LayoutContainerNode extends ElementNode {
|
|
16
|
+
__templateColumns: string;
|
|
17
|
+
constructor(templateColumns?: string, key?: NodeKey);
|
|
18
|
+
static getType(): string;
|
|
19
|
+
static clone(node: LayoutContainerNode): LayoutContainerNode;
|
|
20
|
+
getTemplateColumns(): string;
|
|
21
|
+
setTemplateColumns(templateColumns: string): this;
|
|
22
|
+
static importJSON(serializedNode: SerializedLayoutContainerNode): LayoutContainerNode;
|
|
23
|
+
exportJSON(): SerializedLayoutContainerNode;
|
|
24
|
+
static importDOM(): DOMConversionMap | null;
|
|
25
|
+
exportDOM(): DOMExportOutput;
|
|
26
|
+
createDOM(config: EditorConfig): HTMLElement;
|
|
27
|
+
updateDOM(prevNode: LayoutContainerNode, dom: HTMLElement): boolean;
|
|
28
|
+
canBeEmpty(): false;
|
|
29
|
+
isShadowRoot(): boolean;
|
|
30
|
+
}
|
|
31
|
+
export declare function $createLayoutContainerNode(templateColumns?: string): LayoutContainerNode;
|
|
32
|
+
export declare function $isLayoutContainerNode(node: LexicalNode | null | undefined): node is LayoutContainerNode;
|
|
33
|
+
/** One column's content area inside a LayoutContainerNode. Always keeps at
|
|
34
|
+
* least an empty paragraph (mirrors TableCellNode), so a column can never
|
|
35
|
+
* collapse to an unselectable, unfocusable void. */
|
|
36
|
+
export declare class LayoutItemNode extends ElementNode {
|
|
37
|
+
static getType(): string;
|
|
38
|
+
static clone(node: LayoutItemNode): LayoutItemNode;
|
|
39
|
+
static importJSON(): LayoutItemNode;
|
|
40
|
+
exportJSON(): SerializedLayoutItemNode;
|
|
41
|
+
static importDOM(): DOMConversionMap | null;
|
|
42
|
+
exportDOM(): DOMExportOutput;
|
|
43
|
+
createDOM(config: EditorConfig): HTMLElement;
|
|
44
|
+
updateDOM(): boolean;
|
|
45
|
+
canBeEmpty(): false;
|
|
46
|
+
canIndent(): false;
|
|
47
|
+
}
|
|
48
|
+
export declare function $createLayoutItemNode(): LayoutItemNode;
|
|
49
|
+
export declare function $isLayoutItemNode(node: LexicalNode | null | undefined): node is LayoutItemNode;
|
|
50
|
+
/** Builds a container with `columnCount` empty items — the shape every
|
|
51
|
+
* LAYOUT insert produces, and what the node-transform below re-normalizes
|
|
52
|
+
* a malformed tree back toward. */
|
|
53
|
+
export declare function $createLayoutWithColumns(columnCount: number): LayoutContainerNode;
|
|
54
|
+
//# sourceMappingURL=LayoutNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LayoutNode.d.ts","sourceRoot":"","sources":["../../src/blocks/LayoutNode.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EAEX,WAAW,EACZ,MAAM,SAAS,CAAC;AAGjB;;2EAE2E;AAC3E,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAAC;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAA0C,CAAC;AAErH,MAAM,MAAM,6BAA6B,GAAG,MAAM,CAAC;IAAE,eAAe,EAAE,MAAM,CAAA;CAAE,EAAE,qBAAqB,CAAC,CAAC;AACvG,MAAM,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AAE7D;;sEAEsE;AACtE,qBAAa,mBAAoB,SAAQ,WAAW;IAClD,iBAAiB,EAAE,MAAM,CAAC;gBAEd,eAAe,SAAmB,EAAE,GAAG,CAAC,EAAE,OAAO;IAK7D,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,mBAAmB,GAAG,mBAAmB;IAI5D,kBAAkB,IAAI,MAAM;IAI5B,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI;IAMjD,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,6BAA6B,GAAG,mBAAmB;IAIrF,UAAU,IAAI,6BAA6B;IAI3C,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAU3C,SAAS,IAAI,eAAe;IAQ5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAO5C,SAAS,CAAC,QAAQ,EAAE,mBAAmB,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO;IAOnE,UAAU,IAAI,KAAK;IAInB,YAAY,IAAI,OAAO;CAGxB;AAED,wBAAgB,0BAA0B,CAAC,eAAe,SAAmB,GAAG,mBAAmB,CAElG;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,mBAAmB,CAExG;AAED;;oDAEoD;AACpD,qBAAa,cAAe,SAAQ,WAAW;IAC7C,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc;IAIlD,MAAM,CAAC,UAAU,IAAI,cAAc;IAInC,UAAU,IAAI,wBAAwB;IAItC,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAS3C,SAAS,IAAI,eAAe;IAM5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAM5C,SAAS,IAAI,OAAO;IAIpB,UAAU,IAAI,KAAK;IAInB,SAAS,IAAI,KAAK;CAGnB;AAED,wBAAgB,qBAAqB,IAAI,cAAc,CAEtD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,cAAc,CAE9F;AAED;;mCAEmC;AACnC,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,CAOjF"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { $applyNodeReplacement, $createParagraphNode, createCommand, ElementNode, } from 'lexical';
|
|
2
|
+
import { addClassNamesToElement } from '@lexical/utils';
|
|
3
|
+
/** Payload: how many (equal-width) columns to create. Ratio support beyond
|
|
4
|
+
* equal widths is deferred (lexical-editor-spec.md §4.9 mentions it as a
|
|
5
|
+
* "configurable" possibility, not a committed requirement for Phase 3). */
|
|
6
|
+
export const INSERT_LAYOUT_COMMAND = createCommand('INSERT_LAYOUT_COMMAND');
|
|
7
|
+
/** A multi-column row (editor-architecture-design.md §3.2): an ElementNode
|
|
8
|
+
* holding one LayoutItemNode per column, laid out with CSS grid. Reused as
|
|
9
|
+
* the structural basis for two-column poetry layouts (spec §4.11). */
|
|
10
|
+
export class LayoutContainerNode extends ElementNode {
|
|
11
|
+
constructor(templateColumns = 'repeat(2, 1fr)', key) {
|
|
12
|
+
super(key);
|
|
13
|
+
this.__templateColumns = templateColumns;
|
|
14
|
+
}
|
|
15
|
+
static getType() {
|
|
16
|
+
return 'layout-container';
|
|
17
|
+
}
|
|
18
|
+
static clone(node) {
|
|
19
|
+
return new LayoutContainerNode(node.__templateColumns, node.__key);
|
|
20
|
+
}
|
|
21
|
+
getTemplateColumns() {
|
|
22
|
+
return this.getLatest().__templateColumns;
|
|
23
|
+
}
|
|
24
|
+
setTemplateColumns(templateColumns) {
|
|
25
|
+
const writable = this.getWritable();
|
|
26
|
+
writable.__templateColumns = templateColumns;
|
|
27
|
+
return writable;
|
|
28
|
+
}
|
|
29
|
+
static importJSON(serializedNode) {
|
|
30
|
+
return $createLayoutContainerNode(serializedNode.templateColumns);
|
|
31
|
+
}
|
|
32
|
+
exportJSON() {
|
|
33
|
+
return { ...super.exportJSON(), type: 'layout-container', version: 1, templateColumns: this.getTemplateColumns() };
|
|
34
|
+
}
|
|
35
|
+
static importDOM() {
|
|
36
|
+
return {
|
|
37
|
+
div: (domNode) => {
|
|
38
|
+
if (!domNode.hasAttribute('data-likhari-layout-container'))
|
|
39
|
+
return null;
|
|
40
|
+
const templateColumns = domNode.style.gridTemplateColumns || undefined;
|
|
41
|
+
return { conversion: () => ({ node: $createLayoutContainerNode(templateColumns) }), priority: 2 };
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
exportDOM() {
|
|
46
|
+
const element = document.createElement('div');
|
|
47
|
+
element.setAttribute('data-likhari-layout-container', '');
|
|
48
|
+
element.style.display = 'grid';
|
|
49
|
+
element.style.gridTemplateColumns = this.getTemplateColumns();
|
|
50
|
+
return { element };
|
|
51
|
+
}
|
|
52
|
+
createDOM(config) {
|
|
53
|
+
const element = document.createElement('div');
|
|
54
|
+
addClassNamesToElement(element, config.theme.layoutContainer ?? 'likhari-layout-container');
|
|
55
|
+
element.style.gridTemplateColumns = this.__templateColumns;
|
|
56
|
+
return element;
|
|
57
|
+
}
|
|
58
|
+
updateDOM(prevNode, dom) {
|
|
59
|
+
if (prevNode.__templateColumns !== this.__templateColumns) {
|
|
60
|
+
dom.style.gridTemplateColumns = this.__templateColumns;
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
canBeEmpty() {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
isShadowRoot() {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export function $createLayoutContainerNode(templateColumns = 'repeat(2, 1fr)') {
|
|
72
|
+
return $applyNodeReplacement(new LayoutContainerNode(templateColumns));
|
|
73
|
+
}
|
|
74
|
+
export function $isLayoutContainerNode(node) {
|
|
75
|
+
return node instanceof LayoutContainerNode;
|
|
76
|
+
}
|
|
77
|
+
/** One column's content area inside a LayoutContainerNode. Always keeps at
|
|
78
|
+
* least an empty paragraph (mirrors TableCellNode), so a column can never
|
|
79
|
+
* collapse to an unselectable, unfocusable void. */
|
|
80
|
+
export class LayoutItemNode extends ElementNode {
|
|
81
|
+
static getType() {
|
|
82
|
+
return 'layout-item';
|
|
83
|
+
}
|
|
84
|
+
static clone(node) {
|
|
85
|
+
return new LayoutItemNode(node.__key);
|
|
86
|
+
}
|
|
87
|
+
static importJSON() {
|
|
88
|
+
return $createLayoutItemNode();
|
|
89
|
+
}
|
|
90
|
+
exportJSON() {
|
|
91
|
+
return { ...super.exportJSON(), type: 'layout-item', version: 1 };
|
|
92
|
+
}
|
|
93
|
+
static importDOM() {
|
|
94
|
+
return {
|
|
95
|
+
div: (domNode) => {
|
|
96
|
+
if (!domNode.hasAttribute('data-likhari-layout-item'))
|
|
97
|
+
return null;
|
|
98
|
+
return { conversion: () => ({ node: $createLayoutItemNode() }), priority: 2 };
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
exportDOM() {
|
|
103
|
+
const element = document.createElement('div');
|
|
104
|
+
element.setAttribute('data-likhari-layout-item', '');
|
|
105
|
+
return { element };
|
|
106
|
+
}
|
|
107
|
+
createDOM(config) {
|
|
108
|
+
const element = document.createElement('div');
|
|
109
|
+
addClassNamesToElement(element, config.theme.layoutItem ?? 'likhari-layout-item');
|
|
110
|
+
return element;
|
|
111
|
+
}
|
|
112
|
+
updateDOM() {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
canBeEmpty() {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
canIndent() {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export function $createLayoutItemNode() {
|
|
123
|
+
return $applyNodeReplacement(new LayoutItemNode());
|
|
124
|
+
}
|
|
125
|
+
export function $isLayoutItemNode(node) {
|
|
126
|
+
return node instanceof LayoutItemNode;
|
|
127
|
+
}
|
|
128
|
+
/** Builds a container with `columnCount` empty items — the shape every
|
|
129
|
+
* LAYOUT insert produces, and what the node-transform below re-normalizes
|
|
130
|
+
* a malformed tree back toward. */
|
|
131
|
+
export function $createLayoutWithColumns(columnCount) {
|
|
132
|
+
const count = Math.max(2, Math.min(6, Math.round(columnCount)));
|
|
133
|
+
const container = $createLayoutContainerNode(`repeat(${count}, 1fr)`);
|
|
134
|
+
for (let i = 0; i < count; i++) {
|
|
135
|
+
container.append($createLayoutItemNode().append($createParagraphNode()));
|
|
136
|
+
}
|
|
137
|
+
return container;
|
|
138
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { LayoutContainerNode, LayoutItemNode } from './LayoutNode.js';
|
|
2
|
+
/** Inserts a `columnCount`-column layout right after the selection's
|
|
3
|
+
* top-level block, and focuses its first column. Returns false (so the
|
|
4
|
+
* command falls through) when there's no usable selection to anchor on. */
|
|
5
|
+
export declare function $insertLayout(columnCount: number): boolean;
|
|
6
|
+
/** Keeps LayoutContainerNode/LayoutItemNode nesting valid against malformed
|
|
7
|
+
* trees from paste, undo or JSON import — a LayoutItemNode can only live
|
|
8
|
+
* directly inside a LayoutContainerNode and vice versa. */
|
|
9
|
+
export declare function $normalizeLayoutItem(node: LayoutItemNode): void;
|
|
10
|
+
/** See $normalizeLayoutItem — the container-side half of the same rule. */
|
|
11
|
+
export declare function $normalizeLayoutContainer(node: LayoutContainerNode): void;
|
|
12
|
+
//# sourceMappingURL=layoutActions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layoutActions.d.ts","sourceRoot":"","sources":["../../src/blocks/layoutActions.ts"],"names":[],"mappings":"AACA,OAAO,EAAuE,mBAAmB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAExI;;2EAE2E;AAC3E,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAQ1D;AAED;;2DAE2D;AAC3D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAM/D;AAED,2EAA2E;AAC3E,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CASzE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { $getSelection, $isRangeSelection } from 'lexical';
|
|
2
|
+
import { $createLayoutWithColumns, $isLayoutContainerNode, $isLayoutItemNode } from './LayoutNode.js';
|
|
3
|
+
/** Inserts a `columnCount`-column layout right after the selection's
|
|
4
|
+
* top-level block, and focuses its first column. Returns false (so the
|
|
5
|
+
* command falls through) when there's no usable selection to anchor on. */
|
|
6
|
+
export function $insertLayout(columnCount) {
|
|
7
|
+
const selection = $getSelection();
|
|
8
|
+
if (!$isRangeSelection(selection))
|
|
9
|
+
return false;
|
|
10
|
+
const anchorTopLevel = selection.anchor.getNode().getTopLevelElementOrThrow();
|
|
11
|
+
const container = $createLayoutWithColumns(columnCount);
|
|
12
|
+
anchorTopLevel.insertAfter(container);
|
|
13
|
+
container.getFirstDescendant()?.selectStart();
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
/** Keeps LayoutContainerNode/LayoutItemNode nesting valid against malformed
|
|
17
|
+
* trees from paste, undo or JSON import — a LayoutItemNode can only live
|
|
18
|
+
* directly inside a LayoutContainerNode and vice versa. */
|
|
19
|
+
export function $normalizeLayoutItem(node) {
|
|
20
|
+
const parent = node.getParent();
|
|
21
|
+
if ($isLayoutContainerNode(parent))
|
|
22
|
+
return;
|
|
23
|
+
// Orphaned: unwrap into plain content rather than leaving a stray node.
|
|
24
|
+
for (const child of node.getChildren())
|
|
25
|
+
node.insertBefore(child);
|
|
26
|
+
node.remove();
|
|
27
|
+
}
|
|
28
|
+
/** See $normalizeLayoutItem — the container-side half of the same rule. */
|
|
29
|
+
export function $normalizeLayoutContainer(node) {
|
|
30
|
+
const children = node.getChildren();
|
|
31
|
+
if (children.length === 0) {
|
|
32
|
+
node.remove();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
for (const child of children) {
|
|
36
|
+
if (!$isLayoutItemNode(child))
|
|
37
|
+
child.remove();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface LayoutDialogValue {
|
|
2
|
+
columnCount: number;
|
|
3
|
+
}
|
|
4
|
+
export interface LayoutDialogProps {
|
|
5
|
+
opened: boolean;
|
|
6
|
+
onSubmit: (value: LayoutDialogValue) => void;
|
|
7
|
+
onClose: () => void;
|
|
8
|
+
}
|
|
9
|
+
/** Insert-columns dialog: how many equal-width columns to create. */
|
|
10
|
+
export declare function LayoutDialog({ opened, onSubmit, onClose }: LayoutDialogProps): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=LayoutDialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LayoutDialog.d.ts","sourceRoot":"","sources":["../../src/components/LayoutDialog.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC7C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAMD,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,iBAAiB,+BAmC5E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Button, Group, Modal, NumberInput } from '@mantine/core';
|
|
4
|
+
import { useUiStrings } from '../i18n/useStrings.js';
|
|
5
|
+
import { usePortalTarget } from '../PortalTargetContext.js';
|
|
6
|
+
const MIN_COLUMNS = 2;
|
|
7
|
+
const MAX_COLUMNS = 6;
|
|
8
|
+
const DEFAULT_COLUMNS = 2;
|
|
9
|
+
/** Insert-columns dialog: how many equal-width columns to create. */
|
|
10
|
+
export function LayoutDialog({ opened, onSubmit, onClose }) {
|
|
11
|
+
const strings = useUiStrings();
|
|
12
|
+
const portalTarget = usePortalTarget();
|
|
13
|
+
const [columnCount, setColumnCount] = useState(DEFAULT_COLUMNS);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (!opened)
|
|
16
|
+
return;
|
|
17
|
+
setColumnCount(DEFAULT_COLUMNS);
|
|
18
|
+
}, [opened]);
|
|
19
|
+
const handleSubmit = (e) => {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
onSubmit({ columnCount });
|
|
22
|
+
};
|
|
23
|
+
return (_jsx(Modal, { opened: opened, onClose: onClose, title: strings.layoutDialog.title, centered: true, size: "sm", portalProps: { target: portalTarget }, children: _jsxs("form", { onSubmit: handleSubmit, children: [_jsx(NumberInput, { label: strings.layoutDialog.columnCount, min: MIN_COLUMNS, max: MAX_COLUMNS, value: columnCount, onChange: (v) => setColumnCount(typeof v === 'number' ? v : DEFAULT_COLUMNS), "data-autofocus": true }), _jsxs(Group, { justify: "flex-end", gap: "xs", mt: "md", children: [_jsx(Button, { variant: "default", onClick: onClose, children: strings.common.cancel }), _jsx(Button, { type: "submit", children: strings.common.insert })] })] }) }));
|
|
24
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AA6DA,OAAO,EAAgB,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAA6D,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAItG,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,iBAAiB,CAAC;AA0avD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,2BAA2B,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sEAAsE;IACtE,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,wFAAwF;IACxF,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAkC,EAAE,SAAiB,EAAE,MAAa,EAAE,MAAM,EAAE,EAAE,YAAY,+BAw9BxJ"}
|
|
@@ -12,7 +12,9 @@ import { INSERT_HORIZONTAL_RULE_COMMAND } from '@lexical/react/LexicalHorizontal
|
|
|
12
12
|
import { ImageDialog } from '../image/ImageDialog.js';
|
|
13
13
|
import { $createImageNode } from '../image/ImageNode.js';
|
|
14
14
|
import { INSERT_PAGE_BREAK_COMMAND } from '../blocks/PageBreakNode.js';
|
|
15
|
+
import { INSERT_LAYOUT_COMMAND } from '../blocks/LayoutNode.js';
|
|
15
16
|
import { TableDialog } from './TableDialog.js';
|
|
17
|
+
import { LayoutDialog } from './LayoutDialog.js';
|
|
16
18
|
import { $getTableCellNodeFromLexicalNode, $isTableSelection, INSERT_TABLE_COMMAND } from '@lexical/table';
|
|
17
19
|
import { $canMergeSelectedCells, $canUnmergeSelectedCell, $deleteTable, $deleteTableColumns, $deleteTableRows, $getTableSelectionSize, $insertTableColumns, $insertTableRows, $mergeTableCells, $unmergeTableCell, } from '../table/tableActions.js';
|
|
18
20
|
import { $createLinkNode, $isLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link';
|
|
@@ -23,7 +25,7 @@ import { CANVAS_FONT_DEFAULTS, DEFAULT_FONT_OPTIONS, FONT_SIZES_PX } from '../fo
|
|
|
23
25
|
import { setStyleProperty } from '../utils/style.js';
|
|
24
26
|
import { useStrings } from '../i18n/useStrings.js';
|
|
25
27
|
import { usePortalTarget } from '../PortalTargetContext.js';
|
|
26
|
-
import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconBold, IconClearFormatting, IconDeviceFloppy, IconDots, IconHistory, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPageBreak, IconPencil, IconPhoto, IconPilcrow, IconQuote, IconSeparatorHorizontal, IconSparkles, IconStrikethrough, IconSubscript, IconSuperscript, IconArrowMergeBoth, IconArrowsSplit2, IconColumnInsertLeft, IconColumnInsertRight, IconColumnRemove, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconTable, IconTableMinus, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
28
|
+
import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconBold, IconClearFormatting, IconDeviceFloppy, IconDots, IconHistory, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPageBreak, IconPencil, IconPhoto, IconPilcrow, IconQuote, IconSeparatorHorizontal, IconSparkles, IconStrikethrough, IconSubscript, IconSuperscript, IconArrowMergeBoth, IconArrowsSplit2, IconColumnInsertLeft, IconColumnInsertRight, IconColumnRemove, IconColumns, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconTable, IconTableMinus, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
27
29
|
/** Sentinel for "no inline style": Lexical returns the default it is given when
|
|
28
30
|
* the selection has none, so this tells "unstyled" (show the canvas default)
|
|
29
31
|
* apart from "styled with a value the dropdown doesn't list" (show nothing). */
|
|
@@ -345,6 +347,22 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
345
347
|
});
|
|
346
348
|
closeTableDialog();
|
|
347
349
|
};
|
|
350
|
+
const [layoutDialogOpen, setLayoutDialogOpen] = useState(false);
|
|
351
|
+
const openLayoutDialog = () => {
|
|
352
|
+
snapshotSelection();
|
|
353
|
+
setLayoutDialogOpen(true);
|
|
354
|
+
};
|
|
355
|
+
const closeLayoutDialog = () => {
|
|
356
|
+
setLayoutDialogOpen(false);
|
|
357
|
+
editor.focus();
|
|
358
|
+
};
|
|
359
|
+
const insertLayout = ({ columnCount }) => {
|
|
360
|
+
const saved = menuSelectionRef.current;
|
|
361
|
+
if (saved)
|
|
362
|
+
editor.update(() => $setSelection(saved.clone()), { discrete: true });
|
|
363
|
+
editor.dispatchCommand(INSERT_LAYOUT_COMMAND, { columnCount });
|
|
364
|
+
closeLayoutDialog();
|
|
365
|
+
};
|
|
348
366
|
/** Applies a font property per `config.font.scope`: to the selection, to
|
|
349
367
|
* every text node in the document, or (for 'both') to the selection when
|
|
350
368
|
* there is a range and to the whole document when there isn't. */
|
|
@@ -547,6 +565,7 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
547
565
|
config.tables ||
|
|
548
566
|
config.blocks.horizontalRule ||
|
|
549
567
|
config.blocks.pageBreak ||
|
|
568
|
+
config.columns ||
|
|
550
569
|
config.poetry.enabled;
|
|
551
570
|
const showLanguageGroup = config.language.autocorrect || config.language.textCleanup || config.language.spellCheck;
|
|
552
571
|
// The "script & cleanup" and "indent/outdent" groups (UI spec §3.3) render
|
|
@@ -719,7 +738,7 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
719
738
|
restoreSelection();
|
|
720
739
|
openLinkDialog();
|
|
721
740
|
}, onRemove: removeLink, strings: strings }) })] })) : (_jsx(ToolbarButton, { icon: IconLink, title: strings.toolbar.insertLink, onClick: openLinkDialog })) }, "link")),
|
|
722
|
-
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.tables && _jsx(ToolbarButton, { icon: IconTable, title: strings.toolbar.insertTable, onClick: openTableDialog }), config.blocks.horizontalRule && (_jsx(ToolbarButton, { icon: IconSeparatorHorizontal, title: strings.toolbar.insertHorizontalRule, onClick: () => editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, undefined) })), config.poetry.enabled && _jsx(StubButton, { icon: IconFeather, title: strings.toolbar.poetryBlocks, comingSoon: strings.toolbar.comingSoon })] }, "stubInsert")),
|
|
741
|
+
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.tables && _jsx(ToolbarButton, { icon: IconTable, title: strings.toolbar.insertTable, onClick: openTableDialog }), config.columns && _jsx(ToolbarButton, { icon: IconColumns, title: strings.toolbar.insertColumns, onClick: openLayoutDialog }), config.blocks.horizontalRule && (_jsx(ToolbarButton, { icon: IconSeparatorHorizontal, title: strings.toolbar.insertHorizontalRule, onClick: () => editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, undefined) })), config.poetry.enabled && _jsx(StubButton, { icon: IconFeather, title: strings.toolbar.poetryBlocks, comingSoon: strings.toolbar.comingSoon })] }, "stubInsert")),
|
|
723
742
|
config.tables && state.inTable && (_jsx("div", { className: "likhari-toolbar-group", children: _jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 240, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx("button", { type: "button", className: "likhari-toolbar-button", "data-active": "true", "aria-pressed": "true", "aria-haspopup": "menu", "aria-label": strings.toolbar.tableOptions, title: strings.toolbar.tableOptions, onMouseDown: (e) => e.preventDefault(), children: _jsx(IconTableOptions, { size: ICON_SIZE, stroke: ICON_STROKE }) }) }), _jsx(Menu.Dropdown, { children: _jsx(TableMenuItems, { strings: strings, direction: direction, rows: state.tableRows, columns: state.tableColumns, canMergeCells: state.canMergeCells, canUnmergeCell: state.canUnmergeCell, onAction: runTableAction }) })] }) }, "tableActions")),
|
|
724
743
|
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")),
|
|
725
744
|
];
|
|
@@ -745,5 +764,5 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
745
764
|
display: 'flex',
|
|
746
765
|
flexWrap: 'nowrap',
|
|
747
766
|
gap: 8,
|
|
748
|
-
}, children: [fixedGroups, movableGroups.map((group) => (_jsx(MovableGroupButtons, { group: group }, group.key)))] }), (config.images.linked || config.images.embedded) && (_jsx(ImageDialog, { mode: "insert", opened: imageDialogOpen, onSubmit: insertImage, onClose: closeImageDialog })), config.tables && _jsx(TableDialog, { opened: tableDialogOpen, onSubmit: insertTable, onClose: closeTableDialog }), config.links && (_jsx(LinkDialog, { opened: linkDialogOpen, initialUrl: state.linkUrl, showTextField: linkNeedsText, onSubmit: applyLink, onRemove: state.isLink ? removeLink : undefined, onClose: closeLinkDialog })), drafts && _jsx(DraftsDialog, { opened: draftsOpen, locale: locale, onClose: () => setDraftsOpen(false), ...drafts })] }));
|
|
767
|
+
}, children: [fixedGroups, movableGroups.map((group) => (_jsx(MovableGroupButtons, { group: group }, group.key)))] }), (config.images.linked || config.images.embedded) && (_jsx(ImageDialog, { mode: "insert", opened: imageDialogOpen, onSubmit: insertImage, onClose: closeImageDialog })), config.tables && _jsx(TableDialog, { opened: tableDialogOpen, onSubmit: insertTable, onClose: closeTableDialog }), config.columns && _jsx(LayoutDialog, { opened: layoutDialogOpen, onSubmit: insertLayout, onClose: closeLayoutDialog }), config.links && (_jsx(LinkDialog, { opened: linkDialogOpen, initialUrl: state.linkUrl, showTextField: linkNeedsText, onSubmit: applyLink, onRemove: state.isLink ? removeLink : undefined, onClose: closeLinkDialog })), drafts && _jsx(DraftsDialog, { opened: draftsOpen, locale: locale, onClose: () => setDraftsOpen(false), ...drafts })] }));
|
|
749
768
|
}
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ export interface Strings {
|
|
|
46
46
|
insertImage: string;
|
|
47
47
|
insertPageBreak: string;
|
|
48
48
|
insertTable: string;
|
|
49
|
+
insertColumns: string;
|
|
49
50
|
insertHorizontalRule: string;
|
|
50
51
|
poetryBlocks: string;
|
|
51
52
|
comingSoon: (label: string) => string;
|
|
@@ -156,6 +157,10 @@ export interface Strings {
|
|
|
156
157
|
columns: string;
|
|
157
158
|
headerRow: string;
|
|
158
159
|
};
|
|
160
|
+
layoutDialog: {
|
|
161
|
+
title: string;
|
|
162
|
+
columnCount: string;
|
|
163
|
+
};
|
|
159
164
|
imageDialog: {
|
|
160
165
|
titleInsert: string;
|
|
161
166
|
titleEdit: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"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
|
|
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
|
@@ -37,6 +37,7 @@ const en = {
|
|
|
37
37
|
insertImage: 'Insert image',
|
|
38
38
|
insertPageBreak: 'Insert page break',
|
|
39
39
|
insertTable: 'Insert table',
|
|
40
|
+
insertColumns: 'Insert columns',
|
|
40
41
|
insertHorizontalRule: 'Insert horizontal rule',
|
|
41
42
|
poetryBlocks: 'Poetry blocks',
|
|
42
43
|
comingSoon: (label) => `${label} (coming soon)`,
|
|
@@ -140,6 +141,10 @@ const en = {
|
|
|
140
141
|
columns: 'Columns',
|
|
141
142
|
headerRow: 'Header row',
|
|
142
143
|
},
|
|
144
|
+
layoutDialog: {
|
|
145
|
+
title: 'Insert columns',
|
|
146
|
+
columnCount: 'Number of columns',
|
|
147
|
+
},
|
|
143
148
|
imageDialog: {
|
|
144
149
|
titleInsert: 'Insert image',
|
|
145
150
|
titleEdit: 'Edit image',
|
|
@@ -232,6 +237,7 @@ const ur = {
|
|
|
232
237
|
insertImage: 'تصویر شامل کریں',
|
|
233
238
|
insertPageBreak: 'صفحے کی تقسیم شامل کریں',
|
|
234
239
|
insertTable: 'جدول شامل کریں',
|
|
240
|
+
insertColumns: 'کالم شامل کریں',
|
|
235
241
|
insertHorizontalRule: 'افقی لکیر شامل کریں',
|
|
236
242
|
poetryBlocks: 'شاعری کے بلاکس',
|
|
237
243
|
comingSoon: (label) => `${label} (جلد آ رہا ہے)`,
|
|
@@ -335,6 +341,10 @@ const ur = {
|
|
|
335
341
|
columns: 'کالم',
|
|
336
342
|
headerRow: 'سرِ فہرست قطار',
|
|
337
343
|
},
|
|
344
|
+
layoutDialog: {
|
|
345
|
+
title: 'کالم شامل کریں',
|
|
346
|
+
columnCount: 'کالموں کی تعداد',
|
|
347
|
+
},
|
|
338
348
|
imageDialog: {
|
|
339
349
|
titleInsert: 'تصویر شامل کریں',
|
|
340
350
|
titleEdit: 'تصویر میں ترمیم کریں',
|
|
@@ -427,6 +437,7 @@ const paShahmukhi = {
|
|
|
427
437
|
insertImage: 'تصویر پاؤ',
|
|
428
438
|
insertPageBreak: 'صفحے دی ونڈ پاؤ',
|
|
429
439
|
insertTable: 'ٹیبل پاؤ',
|
|
440
|
+
insertColumns: 'کالم پاؤ',
|
|
430
441
|
insertHorizontalRule: 'لیٹی لکیر پاؤ',
|
|
431
442
|
poetryBlocks: 'شاعری بلاک',
|
|
432
443
|
comingSoon: (label) => `${label} (چھیتی آ رہا اے)`,
|
|
@@ -530,6 +541,10 @@ const paShahmukhi = {
|
|
|
530
541
|
columns: 'کالم',
|
|
531
542
|
headerRow: 'سرکڑی قطار',
|
|
532
543
|
},
|
|
544
|
+
layoutDialog: {
|
|
545
|
+
title: 'کالم پاؤ',
|
|
546
|
+
columnCount: 'کالماں دی گنتی',
|
|
547
|
+
},
|
|
533
548
|
imageDialog: {
|
|
534
549
|
titleInsert: 'تصویر پاؤ',
|
|
535
550
|
titleEdit: 'تصویر وچ تبدیلی کرو',
|
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;AAUlD;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,EAc5C,CAAC"}
|
package/dist/nodes.js
CHANGED
|
@@ -5,6 +5,7 @@ import { HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode';
|
|
|
5
5
|
import { TableCellNode, TableNode, TableRowNode } from '@lexical/table';
|
|
6
6
|
import { ImageNode } from './image/ImageNode.js';
|
|
7
7
|
import { PageBreakNode } from './blocks/PageBreakNode.js';
|
|
8
|
+
import { LayoutContainerNode, LayoutItemNode } from './blocks/LayoutNode.js';
|
|
8
9
|
/**
|
|
9
10
|
* Node types registered on the editor at construction time. Per
|
|
10
11
|
* editor-architecture-design.md §2, node registration cannot be conditional
|
|
@@ -26,4 +27,6 @@ export const EDITOR_NODES = [
|
|
|
26
27
|
TableCellNode,
|
|
27
28
|
ImageNode,
|
|
28
29
|
PageBreakNode,
|
|
30
|
+
LayoutContainerNode,
|
|
31
|
+
LayoutItemNode,
|
|
29
32
|
];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers INSERT_LAYOUT_COMMAND (mirrors PageBreakPlugin) and two node
|
|
3
|
+
* transforms that keep the container/item pairing structurally valid —
|
|
4
|
+
* needed because paste, undo and JSON import can all produce a tree the UI
|
|
5
|
+
* itself never would. The actual logic lives in blocks/layoutActions.ts so
|
|
6
|
+
* it's testable without mounting a React tree.
|
|
7
|
+
*/
|
|
8
|
+
export declare function LayoutPlugin(): null;
|
|
9
|
+
//# sourceMappingURL=LayoutPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LayoutPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/LayoutPlugin.tsx"],"names":[],"mappings":"AAOA;;;;;;GAMG;AACH,wBAAgB,YAAY,SAgB3B"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
3
|
+
import { mergeRegister } from '@lexical/utils';
|
|
4
|
+
import { COMMAND_PRIORITY_EDITOR } from 'lexical';
|
|
5
|
+
import { INSERT_LAYOUT_COMMAND, LayoutContainerNode, LayoutItemNode } from '../blocks/LayoutNode.js';
|
|
6
|
+
import { $insertLayout, $normalizeLayoutContainer, $normalizeLayoutItem } from '../blocks/layoutActions.js';
|
|
7
|
+
/**
|
|
8
|
+
* Registers INSERT_LAYOUT_COMMAND (mirrors PageBreakPlugin) and two node
|
|
9
|
+
* transforms that keep the container/item pairing structurally valid —
|
|
10
|
+
* needed because paste, undo and JSON import can all produce a tree the UI
|
|
11
|
+
* itself never would. The actual logic lives in blocks/layoutActions.ts so
|
|
12
|
+
* it's testable without mounting a React tree.
|
|
13
|
+
*/
|
|
14
|
+
export function LayoutPlugin() {
|
|
15
|
+
const [editor] = useLexicalComposerContext();
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!editor.hasNodes([LayoutContainerNode, LayoutItemNode])) {
|
|
18
|
+
throw new Error('LayoutPlugin: LayoutContainerNode/LayoutItemNode not registered on the editor');
|
|
19
|
+
}
|
|
20
|
+
return mergeRegister(editor.registerCommand(INSERT_LAYOUT_COMMAND, ({ columnCount }) => $insertLayout(columnCount), COMMAND_PRIORITY_EDITOR), editor.registerNodeTransform(LayoutItemNode, $normalizeLayoutItem), editor.registerNodeTransform(LayoutContainerNode, $normalizeLayoutContainer));
|
|
21
|
+
}, [editor]);
|
|
22
|
+
return null;
|
|
23
|
+
}
|
package/dist/theme/editor.css
CHANGED
|
@@ -317,6 +317,24 @@
|
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
+
/* Columns layout (lexical-editor-spec.md §4.9) — a CSS grid row whose
|
|
321
|
+
column count/widths come from the node's own inline style, not this
|
|
322
|
+
stylesheet, so each container can differ. */
|
|
323
|
+
.likhari-layout-container {
|
|
324
|
+
display: grid;
|
|
325
|
+
gap: 24px;
|
|
326
|
+
margin: 0 0 1em 0;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.likhari-layout-item {
|
|
330
|
+
min-width: 0;
|
|
331
|
+
overflow-wrap: break-word;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.likhari-layout-item > :last-child {
|
|
335
|
+
margin-bottom: 0;
|
|
336
|
+
}
|
|
337
|
+
|
|
320
338
|
.likhari-table {
|
|
321
339
|
border-collapse: collapse;
|
|
322
340
|
margin: 1em 0;
|
|
@@ -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,kBA4CzB,CAAC"}
|
|
@@ -40,6 +40,8 @@ export const editorTheme = {
|
|
|
40
40
|
hr: 'likhari-hr',
|
|
41
41
|
image: 'likhari-image-block',
|
|
42
42
|
pageBreak: 'likhari-page-break',
|
|
43
|
+
layoutContainer: 'likhari-layout-container',
|
|
44
|
+
layoutItem: 'likhari-layout-item',
|
|
43
45
|
table: 'likhari-table',
|
|
44
46
|
tableRow: 'likhari-table-row',
|
|
45
47
|
tableCell: 'likhari-table-cell',
|