@inshapardaz/likhari-react 0.1.18-dev.140 → 0.1.18-dev.144
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/PoetryNode.d.ts +8 -2
- package/dist/blocks/PoetryNode.d.ts.map +1 -1
- package/dist/blocks/PoetryNode.js +43 -7
- package/dist/blocks/PoetryResizer.d.ts +11 -0
- package/dist/blocks/PoetryResizer.d.ts.map +1 -0
- package/dist/blocks/PoetryResizer.js +94 -0
- package/dist/blocks/poetryActions.d.ts +14 -0
- package/dist/blocks/poetryActions.d.ts.map +1 -1
- package/dist/blocks/poetryActions.js +43 -1
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/Toolbar.js +5 -5
- package/dist/i18n/strings.d.ts +1 -0
- package/dist/i18n/strings.d.ts.map +1 -1
- package/dist/i18n/strings.js +3 -0
- package/dist/plugins/PoetryPlugin.d.ts +5 -2
- package/dist/plugins/PoetryPlugin.d.ts.map +1 -1
- package/dist/plugins/PoetryPlugin.js +12 -4
- package/dist/theme/editor.css +39 -2
- 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;AAOjE,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,uGAqXrB,CAAC"}
|
package/dist/EditorRoot.js
CHANGED
|
@@ -24,6 +24,7 @@ import { PageBreakPlugin } from './plugins/PageBreakPlugin.js';
|
|
|
24
24
|
import { LayoutPlugin } from './plugins/LayoutPlugin.js';
|
|
25
25
|
import { FootnotePlugin } from './plugins/FootnotePlugin.js';
|
|
26
26
|
import { PoetryPlugin } from './plugins/PoetryPlugin.js';
|
|
27
|
+
import { PoetryResizer } from './blocks/PoetryResizer.js';
|
|
27
28
|
import { DraftRestore } from './components/DraftRestore.js';
|
|
28
29
|
import { LeaveDialog } from './components/LeaveDialog.js';
|
|
29
30
|
import { clearDraft, createDraftId, hasDraftContent, pruneDrafts, writeDraft, } from './persistence/draftStorage.js';
|
|
@@ -280,7 +281,7 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, initialCo
|
|
|
280
281
|
const portalTargetSelector = `#${CSS.escape(portalTargetId)}`;
|
|
281
282
|
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
|
|
282
283
|
? { currentId: draftId, maxBytes: autosaveMaxBytes, adoptOnRestore: !documentId, onRestored: handleDraftRestored }
|
|
283
|
-
: 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.footnotes && _jsx(FootnotePlugin, {}), config.poetry.enabled && _jsx(PoetryPlugin, {}), 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: () => {
|
|
284
|
+
: 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.footnotes && _jsx(FootnotePlugin, {}), config.poetry.enabled && _jsx(PoetryPlugin, {}), config.poetry.enabled && _jsx(PoetryResizer, {}), 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: () => {
|
|
284
285
|
handleSave();
|
|
285
286
|
settleLeave(true);
|
|
286
287
|
}, onSaveDraft: () => {
|
|
@@ -4,6 +4,7 @@ export type PoetryAlign = 'justify' | 'left' | 'right' | 'start';
|
|
|
4
4
|
export type SerializedPoetryBlockNode = Spread<{
|
|
5
5
|
layout: PoetryLayout;
|
|
6
6
|
align: PoetryAlign;
|
|
7
|
+
width?: number;
|
|
7
8
|
}, SerializedElementNode>;
|
|
8
9
|
/**
|
|
9
10
|
* A couplet (two-line verse unit), the one extensible primitive requirements
|
|
@@ -18,11 +19,16 @@ export type SerializedPoetryBlockNode = Spread<{
|
|
|
18
19
|
export declare class PoetryBlockNode extends ElementNode {
|
|
19
20
|
__layout: PoetryLayout;
|
|
20
21
|
__align: PoetryAlign;
|
|
21
|
-
|
|
22
|
+
/** User-chosen width in px (drag-resized), overriding editor.css's default
|
|
23
|
+
* max-width: 70%. Undefined until the user resizes it. */
|
|
24
|
+
__width?: number;
|
|
25
|
+
constructor(layout?: PoetryLayout, align?: PoetryAlign, width?: number, key?: NodeKey);
|
|
22
26
|
static getType(): string;
|
|
23
27
|
static clone(node: PoetryBlockNode): PoetryBlockNode;
|
|
24
28
|
getLayout(): PoetryLayout;
|
|
25
29
|
getAlign(): PoetryAlign;
|
|
30
|
+
getWidth(): number | undefined;
|
|
31
|
+
setWidth(width: number | undefined): this;
|
|
26
32
|
/** Attribute-only — restructuring children for a layout change is
|
|
27
33
|
* poetryActions.ts's $setPoetryLayout, not a node method, since it needs
|
|
28
34
|
* $-context tree mutations beyond this node's own state. */
|
|
@@ -37,6 +43,6 @@ export declare class PoetryBlockNode extends ElementNode {
|
|
|
37
43
|
canBeEmpty(): false;
|
|
38
44
|
isShadowRoot(): boolean;
|
|
39
45
|
}
|
|
40
|
-
export declare function $createPoetryBlockNode(layout?: PoetryLayout, align?: PoetryAlign): PoetryBlockNode;
|
|
46
|
+
export declare function $createPoetryBlockNode(layout?: PoetryLayout, align?: PoetryAlign, width?: number): PoetryBlockNode;
|
|
41
47
|
export declare function $isPoetryBlockNode(node: LexicalNode | null | undefined): node is PoetryBlockNode;
|
|
42
48
|
//# sourceMappingURL=PoetryNode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PoetryNode.d.ts","sourceRoot":"","sources":["../../src/blocks/PoetryNode.tsx"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EACX,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;AACnD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"PoetryNode.d.ts","sourceRoot":"","sources":["../../src/blocks/PoetryNode.tsx"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EACX,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;AACnD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAwBjE,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,WAAW,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,qBAAqB,CAAC,CAAC;AAEpI;;;;;;;;;GASG;AACH,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB;8DAC0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;gBAEL,MAAM,GAAE,YAAuB,EAAE,KAAK,GAAE,WAAuB,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO;IAO1G,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,eAAe;IAIpD,SAAS,IAAI,YAAY;IAIzB,QAAQ,IAAI,WAAW;IAIvB,QAAQ,IAAI,MAAM,GAAG,SAAS;IAI9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAMzC;;gEAE4D;IAC5D,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAM9C,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAMlC,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,yBAAyB,GAAG,eAAe;IAI7E,UAAU,IAAI,yBAAyB;IAYvC,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAe3C,SAAS,IAAI,eAAe;IAW5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAa5C,SAAS,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO;IAerF,UAAU,IAAI,KAAK;IAInB,YAAY,IAAI,OAAO;CAGxB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,GAAE,YAAuB,EAAE,KAAK,GAAE,WAAuB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CAEvI;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,eAAe,CAEhG"}
|
|
@@ -12,6 +12,15 @@ function applyAlignStyle(element, align) {
|
|
|
12
12
|
element.style.textAlign = align;
|
|
13
13
|
element.style.textAlignLast = align === 'justify' ? 'justify' : '';
|
|
14
14
|
}
|
|
15
|
+
/** A user-dragged width overrides editor.css's default max-width: 70% —
|
|
16
|
+
* clearing the inline style (rather than setting it to that same 70%)
|
|
17
|
+
* lets the CSS default keep tracking the canvas if it's ever resized. */
|
|
18
|
+
function applyWidthStyle(element, width) {
|
|
19
|
+
if (width === undefined)
|
|
20
|
+
element.style.removeProperty('max-width');
|
|
21
|
+
else
|
|
22
|
+
element.style.maxWidth = `${width}px`;
|
|
23
|
+
}
|
|
15
24
|
/**
|
|
16
25
|
* A couplet (two-line verse unit), the one extensible primitive requirements
|
|
17
26
|
* doc §4.11 recommends in place of four fixed templates. `layout` picks
|
|
@@ -23,16 +32,17 @@ function applyAlignStyle(element, align) {
|
|
|
23
32
|
* between layouts doesn't lose selection/undo coherence.
|
|
24
33
|
*/
|
|
25
34
|
export class PoetryBlockNode extends ElementNode {
|
|
26
|
-
constructor(layout = 'single', align = 'justify', key) {
|
|
35
|
+
constructor(layout = 'single', align = 'justify', width, key) {
|
|
27
36
|
super(key);
|
|
28
37
|
this.__layout = layout;
|
|
29
38
|
this.__align = align;
|
|
39
|
+
this.__width = width;
|
|
30
40
|
}
|
|
31
41
|
static getType() {
|
|
32
42
|
return 'poetry-couplet';
|
|
33
43
|
}
|
|
34
44
|
static clone(node) {
|
|
35
|
-
return new PoetryBlockNode(node.__layout, node.__align, node.__key);
|
|
45
|
+
return new PoetryBlockNode(node.__layout, node.__align, node.__width, node.__key);
|
|
36
46
|
}
|
|
37
47
|
getLayout() {
|
|
38
48
|
return this.getLatest().__layout;
|
|
@@ -40,6 +50,14 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
40
50
|
getAlign() {
|
|
41
51
|
return this.getLatest().__align;
|
|
42
52
|
}
|
|
53
|
+
getWidth() {
|
|
54
|
+
return this.getLatest().__width;
|
|
55
|
+
}
|
|
56
|
+
setWidth(width) {
|
|
57
|
+
const writable = this.getWritable();
|
|
58
|
+
writable.__width = width;
|
|
59
|
+
return writable;
|
|
60
|
+
}
|
|
43
61
|
/** Attribute-only — restructuring children for a layout change is
|
|
44
62
|
* poetryActions.ts's $setPoetryLayout, not a node method, since it needs
|
|
45
63
|
* $-context tree mutations beyond this node's own state. */
|
|
@@ -54,10 +72,18 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
54
72
|
return writable;
|
|
55
73
|
}
|
|
56
74
|
static importJSON(serializedNode) {
|
|
57
|
-
return $createPoetryBlockNode(serializedNode.layout, serializedNode.align);
|
|
75
|
+
return $createPoetryBlockNode(serializedNode.layout, serializedNode.align, serializedNode.width);
|
|
58
76
|
}
|
|
59
77
|
exportJSON() {
|
|
60
|
-
|
|
78
|
+
const width = this.getWidth();
|
|
79
|
+
return {
|
|
80
|
+
...super.exportJSON(),
|
|
81
|
+
type: 'poetry-couplet',
|
|
82
|
+
version: 1,
|
|
83
|
+
layout: this.getLayout(),
|
|
84
|
+
align: this.getAlign(),
|
|
85
|
+
...(width !== undefined ? { width } : {}),
|
|
86
|
+
};
|
|
61
87
|
}
|
|
62
88
|
static importDOM() {
|
|
63
89
|
return {
|
|
@@ -68,7 +94,9 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
68
94
|
const layout = VALID_LAYOUTS.has(rawLayout) ? rawLayout : 'single';
|
|
69
95
|
const rawAlign = domNode.getAttribute('data-likhari-poetry-align') ?? 'justify';
|
|
70
96
|
const align = VALID_ALIGNS.has(rawAlign) ? rawAlign : 'justify';
|
|
71
|
-
|
|
97
|
+
const rawWidth = Number(domNode.getAttribute('data-likhari-poetry-width'));
|
|
98
|
+
const width = Number.isFinite(rawWidth) && rawWidth > 0 ? rawWidth : undefined;
|
|
99
|
+
return { conversion: () => ({ node: $createPoetryBlockNode(layout, align, width) }), priority: 2 };
|
|
72
100
|
},
|
|
73
101
|
};
|
|
74
102
|
}
|
|
@@ -76,7 +104,11 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
76
104
|
const element = document.createElement('div');
|
|
77
105
|
element.setAttribute('data-likhari-poetry-layout', this.getLayout());
|
|
78
106
|
element.setAttribute('data-likhari-poetry-align', this.getAlign());
|
|
107
|
+
const width = this.getWidth();
|
|
108
|
+
if (width !== undefined)
|
|
109
|
+
element.setAttribute('data-likhari-poetry-width', String(width));
|
|
79
110
|
applyAlignStyle(element, this.getAlign());
|
|
111
|
+
applyWidthStyle(element, width);
|
|
80
112
|
return { element };
|
|
81
113
|
}
|
|
82
114
|
createDOM(config) {
|
|
@@ -84,6 +116,7 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
84
116
|
const base = config.theme.poetry ?? 'likhari-poetry';
|
|
85
117
|
addClassNamesToElement(element, base, `${base}--${this.__layout}`);
|
|
86
118
|
applyAlignStyle(element, this.__align);
|
|
119
|
+
applyWidthStyle(element, this.__width);
|
|
87
120
|
return element;
|
|
88
121
|
}
|
|
89
122
|
// Only ever adds/removes the layout modifier class, never touches the
|
|
@@ -99,6 +132,9 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
99
132
|
if (prevNode.__align !== this.__align) {
|
|
100
133
|
applyAlignStyle(dom, this.__align);
|
|
101
134
|
}
|
|
135
|
+
if (prevNode.__width !== this.__width) {
|
|
136
|
+
applyWidthStyle(dom, this.__width);
|
|
137
|
+
}
|
|
102
138
|
return false;
|
|
103
139
|
}
|
|
104
140
|
canBeEmpty() {
|
|
@@ -108,8 +144,8 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
108
144
|
return true;
|
|
109
145
|
}
|
|
110
146
|
}
|
|
111
|
-
export function $createPoetryBlockNode(layout = 'single', align = 'justify') {
|
|
112
|
-
return $applyNodeReplacement(new PoetryBlockNode(layout, align));
|
|
147
|
+
export function $createPoetryBlockNode(layout = 'single', align = 'justify', width) {
|
|
148
|
+
return $applyNodeReplacement(new PoetryBlockNode(layout, align, width));
|
|
113
149
|
}
|
|
114
150
|
export function $isPoetryBlockNode(node) {
|
|
115
151
|
return node instanceof PoetryBlockNode;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A floating drag handle over the currently-active poetry couplet's
|
|
3
|
+
* inline-end edge, letting the user resize how wide the block reads on the
|
|
4
|
+
* page — "size it according to the length of the couplet" — rather than
|
|
5
|
+
* being stuck with editor.css's default max-width: 70%. Rendered as a
|
|
6
|
+
* portal into the editor's own portal-target element, never as a child of
|
|
7
|
+
* the couplet's own DOM, so it can't interfere with Lexical's
|
|
8
|
+
* reconciliation of the couplet's real (editable) children.
|
|
9
|
+
*/
|
|
10
|
+
export declare function PoetryResizer(): import("react").JSX.Element | null;
|
|
11
|
+
//# sourceMappingURL=PoetryResizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PoetryResizer.d.ts","sourceRoot":"","sources":["../../src/blocks/PoetryResizer.tsx"],"names":[],"mappings":"AAuBA;;;;;;;;GAQG;AACH,wBAAgB,aAAa,uCAqF5B"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
4
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
5
|
+
import { $getNodeByKey } from 'lexical';
|
|
6
|
+
import { usePortalTarget } from '../PortalTargetContext.js';
|
|
7
|
+
import { $getPoetryBlockFromSelection } from './poetryActions.js';
|
|
8
|
+
import { $isPoetryBlockNode } from './PoetryNode.js';
|
|
9
|
+
const MIN_WIDTH_PX = 160;
|
|
10
|
+
function measure(el) {
|
|
11
|
+
const box = el.getBoundingClientRect();
|
|
12
|
+
return { top: box.top, left: box.left, width: box.width, height: box.height, rtl: getComputedStyle(el).direction === 'rtl' };
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A floating drag handle over the currently-active poetry couplet's
|
|
16
|
+
* inline-end edge, letting the user resize how wide the block reads on the
|
|
17
|
+
* page — "size it according to the length of the couplet" — rather than
|
|
18
|
+
* being stuck with editor.css's default max-width: 70%. Rendered as a
|
|
19
|
+
* portal into the editor's own portal-target element, never as a child of
|
|
20
|
+
* the couplet's own DOM, so it can't interfere with Lexical's
|
|
21
|
+
* reconciliation of the couplet's real (editable) children.
|
|
22
|
+
*/
|
|
23
|
+
export function PoetryResizer() {
|
|
24
|
+
const [editor] = useLexicalComposerContext();
|
|
25
|
+
const portalSelector = usePortalTarget();
|
|
26
|
+
const [activeKey, setActiveKey] = useState(null);
|
|
27
|
+
const [box, setBox] = useState(null);
|
|
28
|
+
const dragStart = useRef(null);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
const recompute = () => {
|
|
31
|
+
if (dragStart.current)
|
|
32
|
+
return; // the pointermove handler owns `box` mid-drag
|
|
33
|
+
editor.getEditorState().read(() => {
|
|
34
|
+
const couplet = $getPoetryBlockFromSelection();
|
|
35
|
+
const el = couplet ? editor.getElementByKey(couplet.getKey()) : null;
|
|
36
|
+
if (!couplet || !el) {
|
|
37
|
+
setActiveKey(null);
|
|
38
|
+
setBox(null);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
setActiveKey(couplet.getKey());
|
|
42
|
+
setBox(measure(el));
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
recompute();
|
|
46
|
+
const unregister = editor.registerUpdateListener(recompute);
|
|
47
|
+
window.addEventListener('resize', recompute);
|
|
48
|
+
window.addEventListener('scroll', recompute, true);
|
|
49
|
+
return () => {
|
|
50
|
+
unregister();
|
|
51
|
+
window.removeEventListener('resize', recompute);
|
|
52
|
+
window.removeEventListener('scroll', recompute, true);
|
|
53
|
+
};
|
|
54
|
+
}, [editor]);
|
|
55
|
+
if (!box || !activeKey)
|
|
56
|
+
return null;
|
|
57
|
+
const onPointerDown = (event) => {
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
60
|
+
dragStart.current = { x: event.clientX, width: box.width, rtl: box.rtl };
|
|
61
|
+
};
|
|
62
|
+
const onPointerMove = (event) => {
|
|
63
|
+
const start = dragStart.current;
|
|
64
|
+
const el = editor.getElementByKey(activeKey);
|
|
65
|
+
if (!start || !el)
|
|
66
|
+
return;
|
|
67
|
+
const delta = event.clientX - start.x;
|
|
68
|
+
const signedDelta = start.rtl ? -delta : delta;
|
|
69
|
+
const canvasMax = editor.getRootElement()?.clientWidth ?? start.width + signedDelta;
|
|
70
|
+
const width = Math.round(Math.min(Math.max(start.width + signedDelta, MIN_WIDTH_PX), canvasMax));
|
|
71
|
+
// Live visual feedback: the couplet is centered (margin: auto), so
|
|
72
|
+
// resizing it moves both edges — re-measure after mutating rather than
|
|
73
|
+
// computing the new position from the drag delta alone.
|
|
74
|
+
el.style.maxWidth = `${width}px`;
|
|
75
|
+
setBox(measure(el));
|
|
76
|
+
};
|
|
77
|
+
const onPointerUp = () => {
|
|
78
|
+
const start = dragStart.current;
|
|
79
|
+
dragStart.current = null;
|
|
80
|
+
const el = editor.getElementByKey(activeKey);
|
|
81
|
+
const width = el ? Math.round(el.getBoundingClientRect().width) : null;
|
|
82
|
+
if (start && width !== null) {
|
|
83
|
+
editor.update(() => {
|
|
84
|
+
const node = $getNodeByKey(activeKey);
|
|
85
|
+
if ($isPoetryBlockNode(node))
|
|
86
|
+
node.setWidth(width);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const handleX = box.rtl ? box.left : box.left + box.width;
|
|
91
|
+
const handle = (_jsx("div", { className: "likhari-poetry-resize-handle", style: { position: 'fixed', top: box.top, left: handleX, height: box.height }, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerUp, role: "separator", "aria-orientation": "vertical" }));
|
|
92
|
+
const portalRoot = portalSelector ? document.querySelector(portalSelector) : null;
|
|
93
|
+
return portalRoot ? createPortal(handle, portalRoot) : handle;
|
|
94
|
+
}
|
|
@@ -24,6 +24,20 @@ export declare function $ensureTrailingParagraph(node: PoetryBlockNode): void;
|
|
|
24
24
|
/** Inserts a new two-misra couplet after the selection's top-level block,
|
|
25
25
|
* in `layout`/`align`, and focuses its first misra. */
|
|
26
26
|
export declare function $insertPoetryCouplet(layout: PoetryLayout, align: PoetryAlign): boolean;
|
|
27
|
+
/** Removes the whole couplet the selection is inside, if any — the explicit,
|
|
28
|
+
* always-available counterpart to $deletePoetryOnBackspace's empty-couplet
|
|
29
|
+
* shortcut (mirrors the table menu's own "Delete table" action). */
|
|
30
|
+
export declare function $deletePoetryCouplet(): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Backspace at the very start of an empty couplet's first misra removes the
|
|
33
|
+
* whole block — the natural keystroke to try first, and otherwise there was
|
|
34
|
+
* no way to get rid of an empty couplet created by mistake (its two misra
|
|
35
|
+
* paragraphs each have their own default canBeEmpty, so Lexical's usual
|
|
36
|
+
* "delete the empty block" handling never reaches the couplet itself).
|
|
37
|
+
* Returns false for every other caret position, including a non-empty
|
|
38
|
+
* couplet, so normal Backspace handling (e.g. deleting within text) proceeds.
|
|
39
|
+
*/
|
|
40
|
+
export declare function $deletePoetryOnBackspace(): boolean;
|
|
27
41
|
/**
|
|
28
42
|
* Enter at the end of a couplet's last misra would otherwise land inside
|
|
29
43
|
* ParagraphNode's own insertNewAfter — which inserts the new paragraph as a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"poetryActions.d.ts","sourceRoot":"","sources":["../../src/blocks/poetryActions.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"poetryActions.d.ts","sourceRoot":"","sources":["../../src/blocks/poetryActions.ts"],"names":[],"mappings":"AACA,OAAO,EAA4F,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAEvI,OAAO,EAA8C,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAErI;wCACwC;AACxC,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,GAAG,aAAa,EAAE,CAW1E;AAED,oEAAoE;AACpE,wBAAgB,4BAA4B,IAAI,eAAe,GAAG,IAAI,CAKrE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAclF;AAED;;;;;;qDAMqD;AACrD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAEpE;AAED;uDACuD;AACvD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAyBtF;AAED;;oEAEoE;AACpE,wBAAgB,oBAAoB,IAAI,OAAO,CAK9C;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAoBlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAuB5C"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { $findMatchingParent } from '@lexical/utils';
|
|
2
|
-
import { $createParagraphNode, $getSelection, $isParagraphNode, $isRangeSelection } from 'lexical';
|
|
2
|
+
import { $createParagraphNode, $getSelection, $isElementNode, $isParagraphNode, $isRangeSelection } from 'lexical';
|
|
3
3
|
import { $createLayoutContainerNode, $createLayoutItemNode, $isLayoutContainerNode, $isLayoutItemNode } from './LayoutNode.js';
|
|
4
4
|
import { $createPoetryBlockNode, $isPoetryBlockNode } from './PoetryNode.js';
|
|
5
5
|
/** The couplet's two misra paragraphs, in document order, regardless of
|
|
@@ -91,6 +91,48 @@ export function $insertPoetryCouplet(layout, align) {
|
|
|
91
91
|
misraA.selectStart();
|
|
92
92
|
return true;
|
|
93
93
|
}
|
|
94
|
+
/** Removes the whole couplet the selection is inside, if any — the explicit,
|
|
95
|
+
* always-available counterpart to $deletePoetryOnBackspace's empty-couplet
|
|
96
|
+
* shortcut (mirrors the table menu's own "Delete table" action). */
|
|
97
|
+
export function $deletePoetryCouplet() {
|
|
98
|
+
const couplet = $getPoetryBlockFromSelection();
|
|
99
|
+
if (!couplet)
|
|
100
|
+
return false;
|
|
101
|
+
couplet.remove();
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Backspace at the very start of an empty couplet's first misra removes the
|
|
106
|
+
* whole block — the natural keystroke to try first, and otherwise there was
|
|
107
|
+
* no way to get rid of an empty couplet created by mistake (its two misra
|
|
108
|
+
* paragraphs each have their own default canBeEmpty, so Lexical's usual
|
|
109
|
+
* "delete the empty block" handling never reaches the couplet itself).
|
|
110
|
+
* Returns false for every other caret position, including a non-empty
|
|
111
|
+
* couplet, so normal Backspace handling (e.g. deleting within text) proceeds.
|
|
112
|
+
*/
|
|
113
|
+
export function $deletePoetryOnBackspace() {
|
|
114
|
+
const selection = $getSelection();
|
|
115
|
+
if (!$isRangeSelection(selection) || !selection.isCollapsed())
|
|
116
|
+
return false;
|
|
117
|
+
const couplet = $getPoetryBlockFromSelection();
|
|
118
|
+
if (!couplet)
|
|
119
|
+
return false;
|
|
120
|
+
const misras = $getMisraParagraphs(couplet);
|
|
121
|
+
const firstMisra = misras[0];
|
|
122
|
+
if (!firstMisra)
|
|
123
|
+
return false;
|
|
124
|
+
if (misras.some((m) => !m.isEmpty()))
|
|
125
|
+
return false;
|
|
126
|
+
const anchor = selection.anchor;
|
|
127
|
+
const isAtStart = anchor.key === firstMisra.getKey() && anchor.offset === 0;
|
|
128
|
+
if (!isAtStart)
|
|
129
|
+
return false;
|
|
130
|
+
const previous = couplet.getPreviousSibling();
|
|
131
|
+
couplet.remove();
|
|
132
|
+
if ($isElementNode(previous))
|
|
133
|
+
previous.selectEnd();
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
94
136
|
/**
|
|
95
137
|
* Enter at the end of a couplet's last misra would otherwise land inside
|
|
96
138
|
* ParagraphNode's own insertNewAfter — which inserts the new paragraph as a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AAiEA,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;
|
|
1
|
+
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AAiEA,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;AA4evD,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,+BAugCxJ"}
|
|
@@ -14,7 +14,7 @@ import { $createImageNode } from '../image/ImageNode.js';
|
|
|
14
14
|
import { INSERT_PAGE_BREAK_COMMAND } from '../blocks/PageBreakNode.js';
|
|
15
15
|
import { INSERT_LAYOUT_COMMAND } from '../blocks/LayoutNode.js';
|
|
16
16
|
import { INSERT_FOOTNOTE_COMMAND } from '../blocks/FootnoteNode.js';
|
|
17
|
-
import { $getPoetryBlockFromSelection, $setPoetryLayout } from '../blocks/poetryActions.js';
|
|
17
|
+
import { $deletePoetryCouplet, $getPoetryBlockFromSelection, $setPoetryLayout } from '../blocks/poetryActions.js';
|
|
18
18
|
import { INSERT_POETRY_COUPLET_COMMAND } from '../plugins/PoetryPlugin.js';
|
|
19
19
|
import { TableDialog } from './TableDialog.js';
|
|
20
20
|
import { LayoutDialog } from './LayoutDialog.js';
|
|
@@ -28,7 +28,7 @@ import { CANVAS_FONT_DEFAULTS, DEFAULT_FONT_OPTIONS, FONT_SIZES_PX } from '../fo
|
|
|
28
28
|
import { setStyleProperty } from '../utils/style.js';
|
|
29
29
|
import { useStrings } from '../i18n/useStrings.js';
|
|
30
30
|
import { usePortalTarget } from '../PortalTargetContext.js';
|
|
31
|
-
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, IconColumns1, IconColumns2, IconNumber1Small, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconTable, IconTableMinus, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
31
|
+
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, IconColumns1, IconColumns2, IconNumber1Small, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconTable, IconTableMinus, IconTrash, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
32
32
|
/** Sentinel for "no inline style": Lexical returns the default it is given when
|
|
33
33
|
* the selection has none, so this tells "unstyled" (show the canvas default)
|
|
34
34
|
* apart from "styled with a value the dropdown doesn't list" (show nothing). */
|
|
@@ -167,9 +167,9 @@ function TableMenuItems({ strings, direction, rows, columns, canMergeCells, canU
|
|
|
167
167
|
function PoetryMenuItems({ strings, alignIcons, layout, align, onAction, }) {
|
|
168
168
|
const t = strings.poetryMenu;
|
|
169
169
|
const a = strings.toolbar.alignOptions;
|
|
170
|
-
const item = (icon, label, action, active) => {
|
|
170
|
+
const item = (icon, label, action, active = false, color) => {
|
|
171
171
|
const Icon = icon;
|
|
172
|
-
return (_jsx(Menu.Item, { disabled: active, leftSection: _jsx(Icon, { size: ICON_SIZE, stroke: ICON_STROKE }), onMouseDown: (e) => e.preventDefault(), onClick: onAction(action), children: label }));
|
|
172
|
+
return (_jsx(Menu.Item, { color: color, disabled: active, leftSection: _jsx(Icon, { size: ICON_SIZE, stroke: ICON_STROKE }), onMouseDown: (e) => e.preventDefault(), onClick: onAction(action), children: label }));
|
|
173
173
|
};
|
|
174
174
|
const setLayout = (next) => () => {
|
|
175
175
|
const node = $getPoetryBlockFromSelection();
|
|
@@ -179,7 +179,7 @@ function PoetryMenuItems({ strings, alignIcons, layout, align, onAction, }) {
|
|
|
179
179
|
const setAlign = (next) => () => {
|
|
180
180
|
$getPoetryBlockFromSelection()?.setAlign(next);
|
|
181
181
|
};
|
|
182
|
-
return (_jsxs(_Fragment, { children: [_jsx(Menu.Label, { children: t.menuLabel }), item(IconColumns1, t.singleColumn, setLayout('single'), layout === 'single'), item(IconColumns2, t.twoColumn, setLayout('two-column'), layout === 'two-column'), _jsx(Menu.Divider, {}), item(alignIcons.justify ?? IconAlignJustified, a.justify, setAlign('justify'), align === 'justify'), item(alignIcons.start ?? IconAlignLeft, a.start, setAlign('start'), align === 'start'), item(IconAlignLeft, a.left, setAlign('left'), align === 'left'), item(IconAlignRight, a.right, setAlign('right'), align === 'right')] }));
|
|
182
|
+
return (_jsxs(_Fragment, { children: [_jsx(Menu.Label, { children: t.menuLabel }), item(IconColumns1, t.singleColumn, setLayout('single'), layout === 'single'), item(IconColumns2, t.twoColumn, setLayout('two-column'), layout === 'two-column'), _jsx(Menu.Divider, {}), item(alignIcons.justify ?? IconAlignJustified, a.justify, setAlign('justify'), align === 'justify'), item(alignIcons.start ?? IconAlignLeft, a.start, setAlign('start'), align === 'start'), item(IconAlignLeft, a.left, setAlign('left'), align === 'left'), item(IconAlignRight, a.right, setAlign('right'), align === 'right'), _jsx(Menu.Divider, {}), item(IconTrash, t.deleteCouplet, $deletePoetryCouplet, false, 'red')] }));
|
|
183
183
|
}
|
|
184
184
|
export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
|
|
185
185
|
const [editor] = useLexicalComposerContext();
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -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":"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,sEAAsE;QACtE,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,0CAA0C;QAC1C,MAAM,EAAE,MAAM,CAAC;QACf,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,8FAA8F;QAC9F,YAAY,EAAE,MAAM,CAAC;QACrB,0GAA0G;QAC1G,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,oBAAoB,EAAE,MAAM,CAAC;QAC7B,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;QACtC,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,iBAAiB,EAAE;YACjB,SAAS,EAAE,MAAM,CAAC;YAClB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;YACnC,YAAY,EAAE,MAAM,CAAC;YACrB,UAAU,EAAE,MAAM,CAAC;YACnB,QAAQ,EAAE,MAAM,CAAC;YACjB,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;QACF,YAAY,EAAE;YACZ,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,EAAE,MAAM,CAAC;YACf,GAAG,EAAE,MAAM,CAAC;YACZ,OAAO,EAAE,MAAM,CAAC;YAChB,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;KACH,CAAC;IACF,uIAAuI;IACvI,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,2FAA2F;QAC3F,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,oGAAoG;IACpG,MAAM,EAAE;QACN,0GAA0G;QAC1G,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;QACxC,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,2DAA2D;QAC3D,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;QACtC,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;QACzC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;QAClC,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;QAC7B,aAAa,EAAE,MAAM,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,yEAAyE;IACzE,SAAS,EAAE;QACT,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,2EAA2E;QAC3E,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,UAAU,EAAE;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,IAAI,EAAE;QACJ,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,UAAU,EAAE;QACV,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,CAAC;QACxB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,YAAY,EAAE;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,WAAW,EAAE;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,kBAAkB,EAAE,MAAM,CAAC;QAC3B,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;QACpC,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,cAAc,EAAE,MAAM,CAAC;QACvB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,gBAAgB,EAAE,MAAM,CAAC;QACzB,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,KAAK,MAAM,CAAC;QAC1E,YAAY,EAAE,MAAM,CAAC;QACrB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,YAAY,EAAE,MAAM,CAAC;QACrB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,MAAM,EAAE;YACN,QAAQ,EAAE,MAAM,CAAC;YACjB,UAAU,EAAE,MAAM,CAAC;YACnB,OAAO,EAAE,MAAM,CAAC;YAChB,cAAc,EAAE,MAAM,CAAC;YACvB,YAAY,EAAE,MAAM,CAAC;YACrB,eAAe,EAAE,MAAM,CAAC;YACxB,gBAAgB,EAAE,MAAM,CAAC;YACzB,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;SAC3C,CAAC;KACH,CAAC;IACF,eAAe,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,CAAC,OAAO,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,KAAK,MAAM,CAAC;QACxE,MAAM,EAAE;YACN,cAAc,EAAE,MAAM,CAAC;YACvB,YAAY,EAAE,MAAM,CAAC;YACrB,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;SAC3C,CAAC;KACH,CAAC;IACF,SAAS,EAAE;QACT,SAAS,EAAE,MAAM,CAAC;QAClB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAwnBD,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAI3C,CAAC;AAEF;;sDAEsD;AACtD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAElD"}
|
package/dist/i18n/strings.js
CHANGED
|
@@ -125,6 +125,7 @@ const en = {
|
|
|
125
125
|
menuLabel: 'Poetry',
|
|
126
126
|
singleColumn: 'Single column',
|
|
127
127
|
twoColumn: 'Two column',
|
|
128
|
+
deleteCouplet: 'Delete couplet',
|
|
128
129
|
},
|
|
129
130
|
link: {
|
|
130
131
|
menuLabel: 'Link',
|
|
@@ -332,6 +333,7 @@ const ur = {
|
|
|
332
333
|
menuLabel: 'شاعری',
|
|
333
334
|
singleColumn: 'ایک کالم',
|
|
334
335
|
twoColumn: 'دو کالم',
|
|
336
|
+
deleteCouplet: 'شعر حذف کریں',
|
|
335
337
|
},
|
|
336
338
|
link: {
|
|
337
339
|
menuLabel: 'لنک',
|
|
@@ -539,6 +541,7 @@ const paShahmukhi = {
|
|
|
539
541
|
menuLabel: 'شاعری',
|
|
540
542
|
singleColumn: 'اک کالم',
|
|
541
543
|
twoColumn: 'دو کالم',
|
|
544
|
+
deleteCouplet: 'شعر مٹاؤ',
|
|
542
545
|
},
|
|
543
546
|
link: {
|
|
544
547
|
menuLabel: 'لنک',
|
|
@@ -8,10 +8,13 @@ export declare const INSERT_POETRY_COUPLET_COMMAND: LexicalCommand<{
|
|
|
8
8
|
* Registers INSERT_POETRY_COUPLET_COMMAND (mirrors LayoutPlugin/FootnotePlugin's
|
|
9
9
|
* shape); a node transform that removes a couplet left with no misra
|
|
10
10
|
* content (e.g. after undo/paste leaves it structurally empty) and keeps a
|
|
11
|
-
* trailing couplet always followed by an editable paragraph;
|
|
11
|
+
* trailing couplet always followed by an editable paragraph; a
|
|
12
12
|
* KEY_ENTER_COMMAND handler (above RichTextPlugin's own, which would
|
|
13
13
|
* otherwise trap Enter inside the couplet — see poetryActions.ts) that lets
|
|
14
|
-
* Enter at the end of the last misra add a paragraph after the block
|
|
14
|
+
* Enter at the end of the last misra add a paragraph after the block; and a
|
|
15
|
+
* KEY_BACKSPACE_COMMAND handler that removes an empty couplet entirely when
|
|
16
|
+
* Backspace is pressed at its very start (the explicit "Delete couplet"
|
|
17
|
+
* menu action in Toolbar.tsx covers removing a non-empty one).
|
|
15
18
|
*/
|
|
16
19
|
export declare function PoetryPlugin(): null;
|
|
17
20
|
//# sourceMappingURL=PoetryPlugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PoetryPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/PoetryPlugin.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"PoetryPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/PoetryPlugin.tsx"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAmB,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAG5F,eAAO,MAAM,6BAA6B,EAAE,cAAc,CAAC;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAEtG,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,SA4C3B"}
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
3
|
-
import { COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_HIGH, KEY_ENTER_COMMAND, createCommand } from 'lexical';
|
|
3
|
+
import { COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_HIGH, KEY_BACKSPACE_COMMAND, KEY_ENTER_COMMAND, createCommand, } from 'lexical';
|
|
4
4
|
import { mergeRegister } from '@lexical/utils';
|
|
5
5
|
import { LayoutContainerNode, LayoutItemNode } from '../blocks/LayoutNode.js';
|
|
6
6
|
import { PoetryBlockNode } from '../blocks/PoetryNode.js';
|
|
7
|
-
import { $ensureTrailingParagraph, $exitPoetryOnEnter, $insertPoetryCouplet } from '../blocks/poetryActions.js';
|
|
7
|
+
import { $deletePoetryOnBackspace, $ensureTrailingParagraph, $exitPoetryOnEnter, $insertPoetryCouplet } from '../blocks/poetryActions.js';
|
|
8
8
|
export const INSERT_POETRY_COUPLET_COMMAND = createCommand('INSERT_POETRY_COUPLET_COMMAND');
|
|
9
9
|
/**
|
|
10
10
|
* Registers INSERT_POETRY_COUPLET_COMMAND (mirrors LayoutPlugin/FootnotePlugin's
|
|
11
11
|
* shape); a node transform that removes a couplet left with no misra
|
|
12
12
|
* content (e.g. after undo/paste leaves it structurally empty) and keeps a
|
|
13
|
-
* trailing couplet always followed by an editable paragraph;
|
|
13
|
+
* trailing couplet always followed by an editable paragraph; a
|
|
14
14
|
* KEY_ENTER_COMMAND handler (above RichTextPlugin's own, which would
|
|
15
15
|
* otherwise trap Enter inside the couplet — see poetryActions.ts) that lets
|
|
16
|
-
* Enter at the end of the last misra add a paragraph after the block
|
|
16
|
+
* Enter at the end of the last misra add a paragraph after the block; and a
|
|
17
|
+
* KEY_BACKSPACE_COMMAND handler that removes an empty couplet entirely when
|
|
18
|
+
* Backspace is pressed at its very start (the explicit "Delete couplet"
|
|
19
|
+
* menu action in Toolbar.tsx covers removing a non-empty one).
|
|
17
20
|
*/
|
|
18
21
|
export function PoetryPlugin() {
|
|
19
22
|
const [editor] = useLexicalComposerContext();
|
|
@@ -34,6 +37,11 @@ export function PoetryPlugin() {
|
|
|
34
37
|
if (handled)
|
|
35
38
|
event?.preventDefault();
|
|
36
39
|
return handled;
|
|
40
|
+
}, COMMAND_PRIORITY_HIGH), editor.registerCommand(KEY_BACKSPACE_COMMAND, (event) => {
|
|
41
|
+
const handled = $deletePoetryOnBackspace();
|
|
42
|
+
if (handled)
|
|
43
|
+
event?.preventDefault();
|
|
44
|
+
return handled;
|
|
37
45
|
}, COMMAND_PRIORITY_HIGH));
|
|
38
46
|
}, [editor]);
|
|
39
47
|
return null;
|
package/dist/theme/editor.css
CHANGED
|
@@ -406,18 +406,55 @@
|
|
|
406
406
|
|
|
407
407
|
.likhari-poetry--two-column .likhari-layout-container {
|
|
408
408
|
margin: 0;
|
|
409
|
-
gap
|
|
409
|
+
/* No grid gap — the divider below sits exactly on the track boundary, so
|
|
410
|
+
spacing instead comes from matching padding on each side of it, which
|
|
411
|
+
keeps the gutter visually even on both sides of the line. */
|
|
412
|
+
gap: 0;
|
|
410
413
|
}
|
|
411
414
|
|
|
412
415
|
.likhari-poetry--two-column .likhari-layout-item {
|
|
413
416
|
text-align: inherit;
|
|
414
417
|
}
|
|
415
418
|
|
|
419
|
+
.likhari-poetry--two-column .likhari-layout-item:first-child {
|
|
420
|
+
padding-inline-end: 20px;
|
|
421
|
+
}
|
|
422
|
+
|
|
416
423
|
/* A visible divider between misra columns, same dashed language as the
|
|
417
424
|
couplet's own border — matches a table's internal cell borders. */
|
|
418
425
|
.likhari-poetry--two-column .likhari-layout-item:not(:first-child) {
|
|
419
426
|
border-inline-start: 1px dashed var(--editor-line-strong);
|
|
420
|
-
padding-inline-start:
|
|
427
|
+
padding-inline-start: 20px;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/* PoetryResizer.tsx's drag handle — portaled to a fixed position over the
|
|
431
|
+
active couplet's inline-end edge, so top/left are set inline per drag. */
|
|
432
|
+
.likhari-poetry-resize-handle {
|
|
433
|
+
position: fixed;
|
|
434
|
+
width: 10px;
|
|
435
|
+
/* Physical, not logical: PoetryResizer.tsx already computes `left` as the
|
|
436
|
+
couplet's actual edge in viewport coordinates for either direction, so
|
|
437
|
+
centering the handle on it must stay physical too. */
|
|
438
|
+
margin-left: -5px;
|
|
439
|
+
cursor: ew-resize;
|
|
440
|
+
touch-action: none;
|
|
441
|
+
z-index: 20;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
.likhari-poetry-resize-handle::before {
|
|
445
|
+
content: '';
|
|
446
|
+
display: block;
|
|
447
|
+
width: 3px;
|
|
448
|
+
height: 100%;
|
|
449
|
+
margin-inline: auto;
|
|
450
|
+
border-radius: 2px;
|
|
451
|
+
background: var(--editor-accent);
|
|
452
|
+
opacity: 0;
|
|
453
|
+
transition: opacity 0.1s ease;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
.likhari-poetry-resize-handle:hover::before {
|
|
457
|
+
opacity: 0.6;
|
|
421
458
|
}
|
|
422
459
|
|
|
423
460
|
.likhari-table {
|