@inshapardaz/likhari-react 0.1.18-dev.152 → 0.1.18-dev.156
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/blocks/PoetryCoupletNode.d.ts +36 -0
- package/dist/blocks/PoetryCoupletNode.d.ts.map +1 -0
- package/dist/blocks/PoetryCoupletNode.js +85 -0
- package/dist/blocks/PoetryNode.d.ts +10 -2
- package/dist/blocks/PoetryNode.d.ts.map +1 -1
- package/dist/blocks/PoetryNode.js +29 -7
- package/dist/blocks/poetryActions.d.ts +19 -7
- package/dist/blocks/poetryActions.d.ts.map +1 -1
- package/dist/blocks/poetryActions.js +77 -10
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/Toolbar.js +8 -4
- package/dist/i18n/strings.d.ts +4 -0
- package/dist/i18n/strings.d.ts.map +1 -1
- package/dist/i18n/strings.js +12 -0
- package/dist/nodes.d.ts.map +1 -1
- package/dist/nodes.js +2 -0
- package/dist/plugins/PoetryPlugin.d.ts.map +1 -1
- package/dist/plugins/PoetryPlugin.js +3 -2
- package/dist/theme/editor.css +26 -12
- package/dist/theme/editorTheme.d.ts.map +1 -1
- package/dist/theme/editorTheme.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type DOMConversionMap, type DOMExportOutput, type EditorConfig, type LexicalNode, type NodeKey, type SerializedElementNode, type Spread, ElementNode } from 'lexical';
|
|
2
|
+
export type SerializedPoetryCoupletNode = Spread<{
|
|
3
|
+
centered: boolean;
|
|
4
|
+
}, SerializedElementNode>;
|
|
5
|
+
/**
|
|
6
|
+
* One couplet's two misra lines, wrapped so each couplet can carry its own
|
|
7
|
+
* rendering override independent of its PoetryBlockNode's overall layout —
|
|
8
|
+
* currently just `centered` (a narrower box, centered on the page, instead
|
|
9
|
+
* of the block's default width): "two columns with a couplet that is
|
|
10
|
+
* single, aligned centered" mixes LayoutContainerNode rows (two-column
|
|
11
|
+
* couplets) with centered PoetryCoupletNodes in the same block, each
|
|
12
|
+
* couplet choosing independently.
|
|
13
|
+
*
|
|
14
|
+
* Used for single-column and alternating block layouts; a two-column
|
|
15
|
+
* couplet uses LayoutContainerNode instead (its own two-item row already
|
|
16
|
+
* gives it a natural per-couplet box, so it doesn't need this wrapper).
|
|
17
|
+
*/
|
|
18
|
+
export declare class PoetryCoupletNode extends ElementNode {
|
|
19
|
+
__centered: boolean;
|
|
20
|
+
constructor(centered?: boolean, key?: NodeKey);
|
|
21
|
+
static getType(): string;
|
|
22
|
+
static clone(node: PoetryCoupletNode): PoetryCoupletNode;
|
|
23
|
+
getCentered(): boolean;
|
|
24
|
+
setCentered(centered: boolean): this;
|
|
25
|
+
static importJSON(serializedNode: SerializedPoetryCoupletNode): PoetryCoupletNode;
|
|
26
|
+
exportJSON(): SerializedPoetryCoupletNode;
|
|
27
|
+
static importDOM(): DOMConversionMap | null;
|
|
28
|
+
exportDOM(): DOMExportOutput;
|
|
29
|
+
createDOM(config: EditorConfig): HTMLElement;
|
|
30
|
+
updateDOM(prevNode: PoetryCoupletNode, dom: HTMLElement, config: EditorConfig): boolean;
|
|
31
|
+
canBeEmpty(): false;
|
|
32
|
+
canIndent(): false;
|
|
33
|
+
}
|
|
34
|
+
export declare function $createPoetryCoupletNode(centered?: boolean): PoetryCoupletNode;
|
|
35
|
+
export declare function $isPoetryCoupletNode(node: LexicalNode | null | undefined): node is PoetryCoupletNode;
|
|
36
|
+
//# sourceMappingURL=PoetryCoupletNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PoetryCoupletNode.d.ts","sourceRoot":"","sources":["../../src/blocks/PoetryCoupletNode.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,2BAA2B,GAAG,MAAM,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,EAAE,qBAAqB,CAAC,CAAC;AAE/F;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,UAAU,EAAE,OAAO,CAAC;gBAER,QAAQ,UAAQ,EAAE,GAAG,CAAC,EAAE,OAAO;IAK3C,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,iBAAiB,GAAG,iBAAiB;IAIxD,WAAW,IAAI,OAAO;IAItB,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAMpC,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,2BAA2B,GAAG,iBAAiB;IAIjF,UAAU,IAAI,2BAA2B;IAIzC,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAU3C,SAAS,IAAI,eAAe;IAO5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAQ5C,SAAS,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO;IAQvF,UAAU,IAAI,KAAK;IAInB,SAAS,IAAI,KAAK;CAGnB;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,UAAQ,GAAG,iBAAiB,CAE5E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,iBAAiB,CAEpG"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { addClassNamesToElement } from '@lexical/utils';
|
|
2
|
+
import { $applyNodeReplacement, ElementNode, } from 'lexical';
|
|
3
|
+
/**
|
|
4
|
+
* One couplet's two misra lines, wrapped so each couplet can carry its own
|
|
5
|
+
* rendering override independent of its PoetryBlockNode's overall layout —
|
|
6
|
+
* currently just `centered` (a narrower box, centered on the page, instead
|
|
7
|
+
* of the block's default width): "two columns with a couplet that is
|
|
8
|
+
* single, aligned centered" mixes LayoutContainerNode rows (two-column
|
|
9
|
+
* couplets) with centered PoetryCoupletNodes in the same block, each
|
|
10
|
+
* couplet choosing independently.
|
|
11
|
+
*
|
|
12
|
+
* Used for single-column and alternating block layouts; a two-column
|
|
13
|
+
* couplet uses LayoutContainerNode instead (its own two-item row already
|
|
14
|
+
* gives it a natural per-couplet box, so it doesn't need this wrapper).
|
|
15
|
+
*/
|
|
16
|
+
export class PoetryCoupletNode extends ElementNode {
|
|
17
|
+
constructor(centered = false, key) {
|
|
18
|
+
super(key);
|
|
19
|
+
this.__centered = centered;
|
|
20
|
+
}
|
|
21
|
+
static getType() {
|
|
22
|
+
return 'poetry-couplet';
|
|
23
|
+
}
|
|
24
|
+
static clone(node) {
|
|
25
|
+
return new PoetryCoupletNode(node.__centered, node.__key);
|
|
26
|
+
}
|
|
27
|
+
getCentered() {
|
|
28
|
+
return this.getLatest().__centered;
|
|
29
|
+
}
|
|
30
|
+
setCentered(centered) {
|
|
31
|
+
const writable = this.getWritable();
|
|
32
|
+
writable.__centered = centered;
|
|
33
|
+
return writable;
|
|
34
|
+
}
|
|
35
|
+
static importJSON(serializedNode) {
|
|
36
|
+
return $createPoetryCoupletNode(serializedNode.centered);
|
|
37
|
+
}
|
|
38
|
+
exportJSON() {
|
|
39
|
+
return { ...super.exportJSON(), type: 'poetry-couplet', version: 1, centered: this.getCentered() };
|
|
40
|
+
}
|
|
41
|
+
static importDOM() {
|
|
42
|
+
return {
|
|
43
|
+
div: (domNode) => {
|
|
44
|
+
if (!domNode.hasAttribute('data-likhari-poetry-couplet'))
|
|
45
|
+
return null;
|
|
46
|
+
const centered = domNode.getAttribute('data-likhari-poetry-couplet-centered') === 'true';
|
|
47
|
+
return { conversion: () => ({ node: $createPoetryCoupletNode(centered) }), priority: 2 };
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
exportDOM() {
|
|
52
|
+
const element = document.createElement('div');
|
|
53
|
+
element.setAttribute('data-likhari-poetry-couplet', '');
|
|
54
|
+
if (this.getCentered())
|
|
55
|
+
element.setAttribute('data-likhari-poetry-couplet-centered', 'true');
|
|
56
|
+
return { element };
|
|
57
|
+
}
|
|
58
|
+
createDOM(config) {
|
|
59
|
+
const element = document.createElement('div');
|
|
60
|
+
const base = config.theme.poetryCouplet ?? 'likhari-poetry-couplet';
|
|
61
|
+
addClassNamesToElement(element, base);
|
|
62
|
+
if (this.__centered)
|
|
63
|
+
element.classList.add(`${base}--centered`);
|
|
64
|
+
return element;
|
|
65
|
+
}
|
|
66
|
+
updateDOM(prevNode, dom, config) {
|
|
67
|
+
if (prevNode.__centered !== this.__centered) {
|
|
68
|
+
const base = config.theme.poetryCouplet ?? 'likhari-poetry-couplet';
|
|
69
|
+
dom.classList.toggle(`${base}--centered`, this.__centered);
|
|
70
|
+
}
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
canBeEmpty() {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
canIndent() {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export function $createPoetryCoupletNode(centered = false) {
|
|
81
|
+
return $applyNodeReplacement(new PoetryCoupletNode(centered));
|
|
82
|
+
}
|
|
83
|
+
export function $isPoetryCoupletNode(node) {
|
|
84
|
+
return node instanceof PoetryCoupletNode;
|
|
85
|
+
}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { type DOMConversionMap, type DOMExportOutput, type EditorConfig, type LexicalNode, type NodeKey, type SerializedElementNode, type Spread, ElementNode } from 'lexical';
|
|
2
2
|
export type PoetryLayout = 'single' | 'two-column';
|
|
3
3
|
export type PoetryAlign = 'justify' | 'left' | 'right' | 'start';
|
|
4
|
+
/** Vertical space between couplets — an ordered scale the menu steps through. */
|
|
5
|
+
export declare const POETRY_SPACINGS: readonly ["compact", "normal", "relaxed", "loose"];
|
|
6
|
+
export type PoetrySpacing = (typeof POETRY_SPACINGS)[number];
|
|
7
|
+
export declare const DEFAULT_POETRY_SPACING: PoetrySpacing;
|
|
4
8
|
export type SerializedPoetryBlockNode = Spread<{
|
|
5
9
|
layout: PoetryLayout;
|
|
6
10
|
align: PoetryAlign;
|
|
7
11
|
width?: number;
|
|
12
|
+
spacing?: PoetrySpacing;
|
|
8
13
|
}, SerializedElementNode>;
|
|
9
14
|
/**
|
|
10
15
|
* A poetry *section*: one or more couplets (two-line verse units) sharing
|
|
@@ -25,7 +30,8 @@ export declare class PoetryBlockNode extends ElementNode {
|
|
|
25
30
|
/** User-chosen width in px (drag-resized), overriding editor.css's default
|
|
26
31
|
* max-width: 70%. Undefined until the user resizes it. */
|
|
27
32
|
__width?: number;
|
|
28
|
-
|
|
33
|
+
__spacing: PoetrySpacing;
|
|
34
|
+
constructor(layout?: PoetryLayout, align?: PoetryAlign, width?: number, spacing?: PoetrySpacing, key?: NodeKey);
|
|
29
35
|
static getType(): string;
|
|
30
36
|
static clone(node: PoetryBlockNode): PoetryBlockNode;
|
|
31
37
|
getLayout(): PoetryLayout;
|
|
@@ -36,6 +42,8 @@ export declare class PoetryBlockNode extends ElementNode {
|
|
|
36
42
|
* poetryActions.ts's $setPoetryLayout, not a node method, since it needs
|
|
37
43
|
* $-context tree mutations beyond this node's own state. */
|
|
38
44
|
setLayoutAttribute(layout: PoetryLayout): this;
|
|
45
|
+
getSpacing(): PoetrySpacing;
|
|
46
|
+
setSpacing(spacing: PoetrySpacing): this;
|
|
39
47
|
setAlign(align: PoetryAlign): this;
|
|
40
48
|
static importJSON(serializedNode: SerializedPoetryBlockNode): PoetryBlockNode;
|
|
41
49
|
exportJSON(): SerializedPoetryBlockNode;
|
|
@@ -46,6 +54,6 @@ export declare class PoetryBlockNode extends ElementNode {
|
|
|
46
54
|
canBeEmpty(): false;
|
|
47
55
|
isShadowRoot(): boolean;
|
|
48
56
|
}
|
|
49
|
-
export declare function $createPoetryBlockNode(layout?: PoetryLayout, align?: PoetryAlign, width?: number): PoetryBlockNode;
|
|
57
|
+
export declare function $createPoetryBlockNode(layout?: PoetryLayout, align?: PoetryAlign, width?: number, spacing?: PoetrySpacing): PoetryBlockNode;
|
|
50
58
|
export declare function $isPoetryBlockNode(node: LexicalNode | null | undefined): node is PoetryBlockNode;
|
|
51
59
|
//# 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;AACjE,iFAAiF;AACjF,eAAO,MAAM,eAAe,oDAAqD,CAAC;AAClF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAC7D,eAAO,MAAM,sBAAsB,EAAE,aAAwB,CAAC;AAyB9D,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAC5C;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,WAAW,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,aAAa,CAAA;CAAE,EACrF,qBAAqB,CACtB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB;8DAC0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,aAAa,CAAC;gBAGvB,MAAM,GAAE,YAAuB,EAC/B,KAAK,GAAE,WAAuB,EAC9B,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,GAAE,aAAsC,EAC/C,GAAG,CAAC,EAAE,OAAO;IASf,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,UAAU,IAAI,aAAa;IAI3B,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAMxC,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAMlC,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,yBAAyB,GAAG,eAAe;IAI7E,UAAU,IAAI,yBAAyB;IAavC,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAiB3C,SAAS,IAAI,eAAe;IAY5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAa5C,SAAS,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO;IAoBrF,UAAU,IAAI,KAAK;IAInB,YAAY,IAAI,OAAO;CAGxB;AAED,wBAAgB,sBAAsB,CACpC,MAAM,GAAE,YAAuB,EAC/B,KAAK,GAAE,WAAuB,EAC9B,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,GAAE,aAAsC,GAC9C,eAAe,CAEjB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,eAAe,CAEhG"}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { addClassNamesToElement } from '@lexical/utils';
|
|
2
2
|
import { $applyNodeReplacement, ElementNode, } from 'lexical';
|
|
3
|
+
/** Vertical space between couplets — an ordered scale the menu steps through. */
|
|
4
|
+
export const POETRY_SPACINGS = ['compact', 'normal', 'relaxed', 'loose'];
|
|
5
|
+
export const DEFAULT_POETRY_SPACING = 'normal';
|
|
3
6
|
const VALID_LAYOUTS = new Set(['single', 'two-column']);
|
|
4
7
|
const VALID_ALIGNS = new Set(['justify', 'left', 'right', 'start']);
|
|
8
|
+
const VALID_SPACINGS = new Set(POETRY_SPACINGS);
|
|
5
9
|
/** `text-align: justify` only stretches a line that actually wraps — a
|
|
6
10
|
* misra short enough to fit on one line would otherwise just sit at its own
|
|
7
11
|
* start edge instead of spreading its words across the full column width.
|
|
@@ -35,17 +39,18 @@ function applyWidthStyle(element, width) {
|
|
|
35
39
|
* fixed templates, per requirements doc §4.11.
|
|
36
40
|
*/
|
|
37
41
|
export class PoetryBlockNode extends ElementNode {
|
|
38
|
-
constructor(layout = 'single', align = 'justify', width, key) {
|
|
42
|
+
constructor(layout = 'single', align = 'justify', width, spacing = DEFAULT_POETRY_SPACING, key) {
|
|
39
43
|
super(key);
|
|
40
44
|
this.__layout = layout;
|
|
41
45
|
this.__align = align;
|
|
42
46
|
this.__width = width;
|
|
47
|
+
this.__spacing = spacing;
|
|
43
48
|
}
|
|
44
49
|
static getType() {
|
|
45
50
|
return 'poetry-couplet';
|
|
46
51
|
}
|
|
47
52
|
static clone(node) {
|
|
48
|
-
return new PoetryBlockNode(node.__layout, node.__align, node.__width, node.__key);
|
|
53
|
+
return new PoetryBlockNode(node.__layout, node.__align, node.__width, node.__spacing, node.__key);
|
|
49
54
|
}
|
|
50
55
|
getLayout() {
|
|
51
56
|
return this.getLatest().__layout;
|
|
@@ -69,13 +74,21 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
69
74
|
writable.__layout = layout;
|
|
70
75
|
return writable;
|
|
71
76
|
}
|
|
77
|
+
getSpacing() {
|
|
78
|
+
return this.getLatest().__spacing;
|
|
79
|
+
}
|
|
80
|
+
setSpacing(spacing) {
|
|
81
|
+
const writable = this.getWritable();
|
|
82
|
+
writable.__spacing = spacing;
|
|
83
|
+
return writable;
|
|
84
|
+
}
|
|
72
85
|
setAlign(align) {
|
|
73
86
|
const writable = this.getWritable();
|
|
74
87
|
writable.__align = align;
|
|
75
88
|
return writable;
|
|
76
89
|
}
|
|
77
90
|
static importJSON(serializedNode) {
|
|
78
|
-
return $createPoetryBlockNode(serializedNode.layout, serializedNode.align, serializedNode.width);
|
|
91
|
+
return $createPoetryBlockNode(serializedNode.layout, serializedNode.align, serializedNode.width, serializedNode.spacing);
|
|
79
92
|
}
|
|
80
93
|
exportJSON() {
|
|
81
94
|
const width = this.getWidth();
|
|
@@ -85,6 +98,7 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
85
98
|
version: 1,
|
|
86
99
|
layout: this.getLayout(),
|
|
87
100
|
align: this.getAlign(),
|
|
101
|
+
spacing: this.getSpacing(),
|
|
88
102
|
...(width !== undefined ? { width } : {}),
|
|
89
103
|
};
|
|
90
104
|
}
|
|
@@ -99,7 +113,9 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
99
113
|
const align = VALID_ALIGNS.has(rawAlign) ? rawAlign : 'justify';
|
|
100
114
|
const rawWidth = Number(domNode.getAttribute('data-likhari-poetry-width'));
|
|
101
115
|
const width = Number.isFinite(rawWidth) && rawWidth > 0 ? rawWidth : undefined;
|
|
102
|
-
|
|
116
|
+
const rawSpacing = domNode.getAttribute('data-likhari-poetry-spacing');
|
|
117
|
+
const spacing = VALID_SPACINGS.has(rawSpacing) ? rawSpacing : DEFAULT_POETRY_SPACING;
|
|
118
|
+
return { conversion: () => ({ node: $createPoetryBlockNode(layout, align, width, spacing) }), priority: 2 };
|
|
103
119
|
},
|
|
104
120
|
};
|
|
105
121
|
}
|
|
@@ -107,6 +123,7 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
107
123
|
const element = document.createElement('div');
|
|
108
124
|
element.setAttribute('data-likhari-poetry-layout', this.getLayout());
|
|
109
125
|
element.setAttribute('data-likhari-poetry-align', this.getAlign());
|
|
126
|
+
element.setAttribute('data-likhari-poetry-spacing', this.getSpacing());
|
|
110
127
|
const width = this.getWidth();
|
|
111
128
|
if (width !== undefined)
|
|
112
129
|
element.setAttribute('data-likhari-poetry-width', String(width));
|
|
@@ -117,7 +134,7 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
117
134
|
createDOM(config) {
|
|
118
135
|
const element = document.createElement('div');
|
|
119
136
|
const base = config.theme.poetry ?? 'likhari-poetry';
|
|
120
|
-
addClassNamesToElement(element, base, `${base}--${this.__layout}`);
|
|
137
|
+
addClassNamesToElement(element, base, `${base}--${this.__layout}`, `${base}--spacing-${this.__spacing}`);
|
|
121
138
|
applyAlignStyle(element, this.__align);
|
|
122
139
|
applyWidthStyle(element, this.__width);
|
|
123
140
|
return element;
|
|
@@ -132,6 +149,11 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
132
149
|
dom.classList.remove(`${base}--${prevNode.__layout}`);
|
|
133
150
|
dom.classList.add(`${base}--${this.__layout}`);
|
|
134
151
|
}
|
|
152
|
+
if (prevNode.__spacing !== this.__spacing) {
|
|
153
|
+
const base = config.theme.poetry ?? 'likhari-poetry';
|
|
154
|
+
dom.classList.remove(`${base}--spacing-${prevNode.__spacing}`);
|
|
155
|
+
dom.classList.add(`${base}--spacing-${this.__spacing}`);
|
|
156
|
+
}
|
|
135
157
|
if (prevNode.__align !== this.__align) {
|
|
136
158
|
applyAlignStyle(dom, this.__align);
|
|
137
159
|
}
|
|
@@ -147,8 +169,8 @@ export class PoetryBlockNode extends ElementNode {
|
|
|
147
169
|
return true;
|
|
148
170
|
}
|
|
149
171
|
}
|
|
150
|
-
export function $createPoetryBlockNode(layout = 'single', align = 'justify', width) {
|
|
151
|
-
return $applyNodeReplacement(new PoetryBlockNode(layout, align, width));
|
|
172
|
+
export function $createPoetryBlockNode(layout = 'single', align = 'justify', width, spacing = DEFAULT_POETRY_SPACING) {
|
|
173
|
+
return $applyNodeReplacement(new PoetryBlockNode(layout, align, width, spacing));
|
|
152
174
|
}
|
|
153
175
|
export function $isPoetryBlockNode(node) {
|
|
154
176
|
return node instanceof PoetryBlockNode;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ParagraphNode } from 'lexical';
|
|
2
|
-
import { type PoetryAlign, type
|
|
2
|
+
import { type PoetryAlign, type PoetryBlockNode, type PoetryLayout } from './PoetryNode.js';
|
|
3
3
|
/** One couplet's two misra paragraphs, in order. */
|
|
4
4
|
export type Couplet = [ParagraphNode, ParagraphNode];
|
|
5
5
|
/**
|
|
@@ -17,6 +17,14 @@ export declare function $getCouplets(node: PoetryBlockNode): Couplet[];
|
|
|
17
17
|
export declare function $getMisraParagraphs(node: PoetryBlockNode): ParagraphNode[];
|
|
18
18
|
/** The PoetryBlockNode the current selection is inside, or null. */
|
|
19
19
|
export declare function $getPoetryBlockFromSelection(): PoetryBlockNode | null;
|
|
20
|
+
/**
|
|
21
|
+
* The explicit "Insert couplet above/below" menu actions — mirrors the
|
|
22
|
+
* table menu's "Insert row before/after". Targets the couplet the caret is
|
|
23
|
+
* currently in, falling back to the block's last couplet (so the toolbar's
|
|
24
|
+
* always-available insert button has somewhere sensible to act on even
|
|
25
|
+
* without a precise caret position).
|
|
26
|
+
*/
|
|
27
|
+
export declare function $insertCoupletRelativeToSelection(position: 'before' | 'after'): boolean;
|
|
20
28
|
/**
|
|
21
29
|
* Converts every couplet in the block between single-column (two stacked
|
|
22
30
|
* misras) and two-column (built on the columns primitive, §4.9) in place —
|
|
@@ -36,12 +44,13 @@ export declare function $setPoetryLayout(node: PoetryBlockNode, layout: PoetryLa
|
|
|
36
44
|
export declare function $ensureTrailingParagraph(node: PoetryBlockNode): void;
|
|
37
45
|
/**
|
|
38
46
|
* Inserts a poetry couplet at the caret. If the caret is already inside a
|
|
39
|
-
* poetry block,
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
47
|
+
* poetry block, inserts a new couplet right after the one the caret is in
|
|
48
|
+
* (same as the "Insert couplet below" menu action — table-row-insert
|
|
49
|
+
* semantics, in its existing layout: "one poetry block can contain one or
|
|
50
|
+
* more couplets, in one or two column layout", so a block's layout is
|
|
51
|
+
* fixed once it has couplets, not chosen per couplet) and focuses its first
|
|
52
|
+
* misra. Otherwise creates a new block (in `layout`/`align`) with one
|
|
53
|
+
* couplet, after the selection's top-level element.
|
|
45
54
|
*/
|
|
46
55
|
export declare function $insertPoetryCouplet(layout: PoetryLayout, align: PoetryAlign): boolean;
|
|
47
56
|
/** Removes the couplet the selection is inside. If it's the block's only
|
|
@@ -79,4 +88,7 @@ export declare function $deletePoetryOnBackspace(): boolean;
|
|
|
79
88
|
* next couplet's first misra.
|
|
80
89
|
*/
|
|
81
90
|
export declare function $exitPoetryOnEnter(): boolean;
|
|
91
|
+
/** Steps the caret's poetry block one notch looser (+1) or tighter (-1) on
|
|
92
|
+
* the couplet-spacing scale; clamps at either end. */
|
|
93
|
+
export declare function $adjustPoetrySpacing(step: 1 | -1): boolean;
|
|
82
94
|
//# sourceMappingURL=poetryActions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,EAIL,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AAEtB,oDAAoD;AACpD,MAAM,MAAM,OAAO,GAAG,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAErD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,EAAE,CAgB7D;AAED;;6CAE6C;AAC7C,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,GAAG,aAAa,EAAE,CAE1E;AAED,oEAAoE;AACpE,wBAAgB,4BAA4B,IAAI,eAAe,GAAG,IAAI,CAKrE;AA0DD;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,GAAG,OAAO,CAevF;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAmBlF;AAED;;;;;;qDAMqD;AACrD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAEpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAiBtF;AAED;;;;wCAIwC;AACxC,wBAAgB,oBAAoB,IAAI,OAAO,CAwB9C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAqClD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAgD5C;AAED;sDACsD;AACtD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAO1D"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { $findMatchingParent } from '@lexical/utils';
|
|
2
2
|
import { $createParagraphNode, $getSelection, $isElementNode, $isParagraphNode, $isRangeSelection } from 'lexical';
|
|
3
3
|
import { $createLayoutContainerNode, $createLayoutItemNode, $isLayoutContainerNode, $isLayoutItemNode } from './LayoutNode.js';
|
|
4
|
-
import { $createPoetryBlockNode, $isPoetryBlockNode } from './PoetryNode.js';
|
|
4
|
+
import { $createPoetryBlockNode, $isPoetryBlockNode, POETRY_SPACINGS, } from './PoetryNode.js';
|
|
5
5
|
/**
|
|
6
6
|
* A poetry block is a *section* of one or more couplets sharing one layout
|
|
7
7
|
* (single-column stacks each couplet's two misras directly as paragraph
|
|
@@ -68,6 +68,63 @@ function $appendCoupletTo(node) {
|
|
|
68
68
|
}
|
|
69
69
|
return [misraA, misraB];
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Inserts a new, empty couplet immediately before or after an existing one —
|
|
73
|
+
* the table-row-insert equivalent for a poetry block ("add/remove couplets
|
|
74
|
+
* just like adding/removing table rows"). `existingFirstMisra` is that
|
|
75
|
+
* couplet's first misra, used to locate its wrapper (nothing, in single
|
|
76
|
+
* layout — just its two sibling paragraphs; a LayoutContainerNode row in
|
|
77
|
+
* two-column) so the new couplet can be spliced in at the right spot
|
|
78
|
+
* regardless of layout.
|
|
79
|
+
*/
|
|
80
|
+
function $insertCoupletRelativeTo(existingFirstMisra, layout, position) {
|
|
81
|
+
const misraA = $createParagraphNode();
|
|
82
|
+
const misraB = $createParagraphNode();
|
|
83
|
+
if (layout === 'single') {
|
|
84
|
+
if (position === 'before') {
|
|
85
|
+
existingFirstMisra.insertBefore(misraA);
|
|
86
|
+
misraA.insertAfter(misraB);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
const existingSecondMisra = existingFirstMisra.getNextSibling() ?? existingFirstMisra;
|
|
90
|
+
existingSecondMisra.insertAfter(misraA);
|
|
91
|
+
misraA.insertAfter(misraB);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
const container = $findMatchingParent(existingFirstMisra, $isLayoutContainerNode);
|
|
96
|
+
const newContainer = $createLayoutContainerNode('repeat(2, 1fr)');
|
|
97
|
+
newContainer.append($createLayoutItemNode().append(misraA), $createLayoutItemNode().append(misraB));
|
|
98
|
+
if (position === 'before')
|
|
99
|
+
container.insertBefore(newContainer);
|
|
100
|
+
else
|
|
101
|
+
container.insertAfter(newContainer);
|
|
102
|
+
}
|
|
103
|
+
return [misraA, misraB];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The explicit "Insert couplet above/below" menu actions — mirrors the
|
|
107
|
+
* table menu's "Insert row before/after". Targets the couplet the caret is
|
|
108
|
+
* currently in, falling back to the block's last couplet (so the toolbar's
|
|
109
|
+
* always-available insert button has somewhere sensible to act on even
|
|
110
|
+
* without a precise caret position).
|
|
111
|
+
*/
|
|
112
|
+
export function $insertCoupletRelativeToSelection(position) {
|
|
113
|
+
const block = $getPoetryBlockFromSelection();
|
|
114
|
+
if (!block)
|
|
115
|
+
return false;
|
|
116
|
+
const selection = $getSelection();
|
|
117
|
+
const couplets = $getCouplets(block);
|
|
118
|
+
const anchorNode = $isRangeSelection(selection) ? selection.anchor.getNode() : null;
|
|
119
|
+
const found = anchorNode ? $findCoupletPosition(couplets, anchorNode) : null;
|
|
120
|
+
const index = found ? found.coupletIndex : couplets.length - 1;
|
|
121
|
+
const target = couplets[index];
|
|
122
|
+
if (!target)
|
|
123
|
+
return false;
|
|
124
|
+
const [newA] = $insertCoupletRelativeTo(target[0], block.getLayout(), position);
|
|
125
|
+
newA.selectStart();
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
71
128
|
/**
|
|
72
129
|
* Converts every couplet in the block between single-column (two stacked
|
|
73
130
|
* misras) and two-column (built on the columns primitive, §4.9) in place —
|
|
@@ -112,12 +169,13 @@ export function $ensureTrailingParagraph(node) {
|
|
|
112
169
|
}
|
|
113
170
|
/**
|
|
114
171
|
* Inserts a poetry couplet at the caret. If the caret is already inside a
|
|
115
|
-
* poetry block,
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
172
|
+
* poetry block, inserts a new couplet right after the one the caret is in
|
|
173
|
+
* (same as the "Insert couplet below" menu action — table-row-insert
|
|
174
|
+
* semantics, in its existing layout: "one poetry block can contain one or
|
|
175
|
+
* more couplets, in one or two column layout", so a block's layout is
|
|
176
|
+
* fixed once it has couplets, not chosen per couplet) and focuses its first
|
|
177
|
+
* misra. Otherwise creates a new block (in `layout`/`align`) with one
|
|
178
|
+
* couplet, after the selection's top-level element.
|
|
121
179
|
*/
|
|
122
180
|
export function $insertPoetryCouplet(layout, align) {
|
|
123
181
|
const selection = $getSelection();
|
|
@@ -125,9 +183,7 @@ export function $insertPoetryCouplet(layout, align) {
|
|
|
125
183
|
return false;
|
|
126
184
|
const existing = $getPoetryBlockFromSelection();
|
|
127
185
|
if (existing) {
|
|
128
|
-
|
|
129
|
-
misraA.selectStart();
|
|
130
|
-
return true;
|
|
186
|
+
return $insertCoupletRelativeToSelection('after');
|
|
131
187
|
}
|
|
132
188
|
const anchorTopLevel = selection.anchor.getNode().getTopLevelElementOrThrow();
|
|
133
189
|
const node = $createPoetryBlockNode(layout, align);
|
|
@@ -280,3 +336,14 @@ export function $exitPoetryOnEnter() {
|
|
|
280
336
|
newA.selectStart();
|
|
281
337
|
return true;
|
|
282
338
|
}
|
|
339
|
+
/** Steps the caret's poetry block one notch looser (+1) or tighter (-1) on
|
|
340
|
+
* the couplet-spacing scale; clamps at either end. */
|
|
341
|
+
export function $adjustPoetrySpacing(step) {
|
|
342
|
+
const block = $getPoetryBlockFromSelection();
|
|
343
|
+
if (!block)
|
|
344
|
+
return false;
|
|
345
|
+
const index = POETRY_SPACINGS.indexOf(block.getSpacing());
|
|
346
|
+
const next = POETRY_SPACINGS[Math.min(POETRY_SPACINGS.length - 1, Math.max(0, index + step))];
|
|
347
|
+
block.setSpacing(next);
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
@@ -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":"AAuEA,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;AAsfvD,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,+BA+jCxJ"}
|
|
@@ -15,7 +15,7 @@ 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
17
|
import { $isPoetryBlockNode } from '../blocks/PoetryNode.js';
|
|
18
|
-
import { $deletePoetryCouplet, $getPoetryBlockFromSelection, $setPoetryLayout } from '../blocks/poetryActions.js';
|
|
18
|
+
import { $adjustPoetrySpacing, $deletePoetryCouplet, $getPoetryBlockFromSelection, $insertCoupletRelativeToSelection, $setPoetryLayout, } from '../blocks/poetryActions.js';
|
|
19
19
|
import { INSERT_POETRY_COUPLET_COMMAND } from '../plugins/PoetryPlugin.js';
|
|
20
20
|
import { TableDialog } from './TableDialog.js';
|
|
21
21
|
import { LayoutDialog } from './LayoutDialog.js';
|
|
@@ -29,7 +29,7 @@ import { CANVAS_FONT_DEFAULTS, DEFAULT_FONT_OPTIONS, FONT_SIZES_PX } from '../fo
|
|
|
29
29
|
import { setStyleProperty } from '../utils/style.js';
|
|
30
30
|
import { useStrings } from '../i18n/useStrings.js';
|
|
31
31
|
import { usePortalTarget } from '../PortalTargetContext.js';
|
|
32
|
-
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
|
+
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, IconArrowsMaximize, IconArrowsMinimize, IconTable, IconTableMinus, IconTrash, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
33
33
|
/** Sentinel for "no inline style": Lexical returns the default it is given when
|
|
34
34
|
* the selection has none, so this tells "unstyled" (show the canvas default)
|
|
35
35
|
* apart from "styled with a value the dropdown doesn't list" (show nothing). */
|
|
@@ -164,7 +164,11 @@ function TableMenuItems({ strings, direction, rows, columns, canMergeCells, canU
|
|
|
164
164
|
}
|
|
165
165
|
/** The poetry couplet menu's contents — layout (single/two-column) and
|
|
166
166
|
* literal alignment, both per-instance overrides (requirements doc §4.11:
|
|
167
|
-
* "set per CoupletNode, not inherited from a document-wide setting")
|
|
167
|
+
* "set per CoupletNode, not inherited from a document-wide setting"), plus
|
|
168
|
+
* table-row-style structural actions (insert a couplet above/below the one
|
|
169
|
+
* the caret is in, delete it) — a poetry block is "one object with multiple
|
|
170
|
+
* couplets, add/remove like table rows", so these mirror TableMenuItems'
|
|
171
|
+
* own insert-before/insert-after/delete-row actions. */
|
|
168
172
|
function PoetryMenuItems({ strings, alignIcons, layout, align, onAction, }) {
|
|
169
173
|
const t = strings.poetryMenu;
|
|
170
174
|
const a = strings.toolbar.alignOptions;
|
|
@@ -180,7 +184,7 @@ function PoetryMenuItems({ strings, alignIcons, layout, align, onAction, }) {
|
|
|
180
184
|
const setAlign = (next) => () => {
|
|
181
185
|
$getPoetryBlockFromSelection()?.setAlign(next);
|
|
182
186
|
};
|
|
183
|
-
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')] }));
|
|
187
|
+
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(IconRowInsertTop, t.insertCoupletBefore, () => $insertCoupletRelativeToSelection('before')), item(IconRowInsertBottom, t.insertCoupletAfter, () => $insertCoupletRelativeToSelection('after')), item(IconArrowsMinimize, t.tighterSpacing, () => $adjustPoetrySpacing(-1)), item(IconArrowsMaximize, t.looserSpacing, () => $adjustPoetrySpacing(1)), item(IconTrash, t.deleteCouplet, $deletePoetryCouplet, false, 'red')] }));
|
|
184
188
|
}
|
|
185
189
|
export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
|
|
186
190
|
const [editor] = useLexicalComposerContext();
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -142,6 +142,10 @@ export interface Strings {
|
|
|
142
142
|
menuLabel: string;
|
|
143
143
|
singleColumn: string;
|
|
144
144
|
twoColumn: string;
|
|
145
|
+
insertCoupletBefore: string;
|
|
146
|
+
insertCoupletAfter: string;
|
|
147
|
+
tighterSpacing: string;
|
|
148
|
+
looserSpacing: string;
|
|
145
149
|
deleteCouplet: string;
|
|
146
150
|
};
|
|
147
151
|
link: {
|
|
@@ -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
|
@@ -125,6 +125,10 @@ const en = {
|
|
|
125
125
|
menuLabel: 'Poetry',
|
|
126
126
|
singleColumn: 'Single column',
|
|
127
127
|
twoColumn: 'Two column',
|
|
128
|
+
insertCoupletBefore: 'Insert couplet above',
|
|
129
|
+
insertCoupletAfter: 'Insert couplet below',
|
|
130
|
+
tighterSpacing: 'Tighter couplet spacing',
|
|
131
|
+
looserSpacing: 'Looser couplet spacing',
|
|
128
132
|
deleteCouplet: 'Delete couplet',
|
|
129
133
|
},
|
|
130
134
|
link: {
|
|
@@ -333,6 +337,10 @@ const ur = {
|
|
|
333
337
|
menuLabel: 'شاعری',
|
|
334
338
|
singleColumn: 'ایک کالم',
|
|
335
339
|
twoColumn: 'دو کالم',
|
|
340
|
+
insertCoupletBefore: 'اوپر شعر شامل کریں',
|
|
341
|
+
insertCoupletAfter: 'نیچے شعر شامل کریں',
|
|
342
|
+
tighterSpacing: 'شعروں کے درمیان کم جگہ',
|
|
343
|
+
looserSpacing: 'شعروں کے درمیان زیادہ جگہ',
|
|
336
344
|
deleteCouplet: 'شعر حذف کریں',
|
|
337
345
|
},
|
|
338
346
|
link: {
|
|
@@ -541,6 +549,10 @@ const paShahmukhi = {
|
|
|
541
549
|
menuLabel: 'شاعری',
|
|
542
550
|
singleColumn: 'اک کالم',
|
|
543
551
|
twoColumn: 'دو کالم',
|
|
552
|
+
insertCoupletBefore: 'اُتے شعر شامل کرو',
|
|
553
|
+
insertCoupletAfter: 'ھیٹھ شعر شامل کرو',
|
|
554
|
+
tighterSpacing: 'شعراں وچکار گھٹ جگہ',
|
|
555
|
+
looserSpacing: 'شعراں وچکار ودھ جگہ',
|
|
544
556
|
deleteCouplet: 'شعر مٹاؤ',
|
|
545
557
|
},
|
|
546
558
|
link: {
|
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;AAclD;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,EAmB5C,CAAC"}
|
package/dist/nodes.js
CHANGED
|
@@ -9,6 +9,7 @@ import { LayoutContainerNode, LayoutItemNode } from './blocks/LayoutNode.js';
|
|
|
9
9
|
import { FootnoteReferenceNode } from './blocks/FootnoteNode.js';
|
|
10
10
|
import { FootnoteItemNode, FootnoteListNode } from './blocks/FootnoteListNode.js';
|
|
11
11
|
import { PoetryBlockNode } from './blocks/PoetryNode.js';
|
|
12
|
+
import { PoetryCoupletNode } from './blocks/PoetryCoupletNode.js';
|
|
12
13
|
/**
|
|
13
14
|
* Node types registered on the editor at construction time. Per
|
|
14
15
|
* editor-architecture-design.md §2, node registration cannot be conditional
|
|
@@ -36,4 +37,5 @@ export const EDITOR_NODES = [
|
|
|
36
37
|
FootnoteListNode,
|
|
37
38
|
FootnoteItemNode,
|
|
38
39
|
PoetryBlockNode,
|
|
40
|
+
PoetryCoupletNode,
|
|
39
41
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PoetryPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/PoetryPlugin.tsx"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"PoetryPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/PoetryPlugin.tsx"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AAIjB,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"}
|
|
@@ -3,6 +3,7 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
|
|
|
3
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
|
+
import { PoetryCoupletNode } from '../blocks/PoetryCoupletNode.js';
|
|
6
7
|
import { PoetryBlockNode } from '../blocks/PoetryNode.js';
|
|
7
8
|
import { $deletePoetryOnBackspace, $ensureTrailingParagraph, $exitPoetryOnEnter, $insertPoetryCouplet } from '../blocks/poetryActions.js';
|
|
8
9
|
export const INSERT_POETRY_COUPLET_COMMAND = createCommand('INSERT_POETRY_COUPLET_COMMAND');
|
|
@@ -21,8 +22,8 @@ export const INSERT_POETRY_COUPLET_COMMAND = createCommand('INSERT_POETRY_COUPLE
|
|
|
21
22
|
export function PoetryPlugin() {
|
|
22
23
|
const [editor] = useLexicalComposerContext();
|
|
23
24
|
useEffect(() => {
|
|
24
|
-
if (!editor.hasNodes([PoetryBlockNode, LayoutContainerNode, LayoutItemNode])) {
|
|
25
|
-
throw new Error('PoetryPlugin: PoetryBlockNode (and the columns nodes
|
|
25
|
+
if (!editor.hasNodes([PoetryBlockNode, PoetryCoupletNode, LayoutContainerNode, LayoutItemNode])) {
|
|
26
|
+
throw new Error('PoetryPlugin: PoetryBlockNode/PoetryCoupletNode (and the columns nodes two-column composes) not registered on the editor');
|
|
26
27
|
}
|
|
27
28
|
return mergeRegister(editor.registerCommand(INSERT_POETRY_COUPLET_COMMAND, ({ layout, align }) => $insertPoetryCouplet(layout, align), COMMAND_PRIORITY_EDITOR), editor.registerNodeTransform(PoetryBlockNode, (node) => {
|
|
28
29
|
if (node.getChildrenSize() === 0) {
|
package/dist/theme/editor.css
CHANGED
|
@@ -407,29 +407,43 @@
|
|
|
407
407
|
/* Misra lines sit tight against each other within a couplet — the generic
|
|
408
408
|
.likhari-paragraph margin would otherwise add the same gap between a
|
|
409
409
|
couplet's own two lines as between separate couplets within the same
|
|
410
|
-
block, losing the pairing entirely.
|
|
411
|
-
line (nth-child(2n)) — one couplet's worth of lines — so the extra space
|
|
412
|
-
falls after every couplet, not after every single line. */
|
|
410
|
+
block, losing the pairing entirely. */
|
|
413
411
|
.likhari-poetry .likhari-paragraph {
|
|
414
412
|
margin: 0;
|
|
415
413
|
}
|
|
416
414
|
|
|
417
|
-
|
|
418
|
-
|
|
415
|
+
/* A poetry block is "one object with multiple couplets, add/remove like
|
|
416
|
+
table rows" — so couplet boundaries get the same visible divider as a
|
|
417
|
+
table's internal row borders, not just extra space. Every couplet but
|
|
418
|
+
the first (nth-child(odd), since each couplet is two paragraph
|
|
419
|
+
children — its first misra always lands on an odd position) gets a
|
|
420
|
+
border-top in place of the previous couplet's margin-bottom. */
|
|
421
|
+
.likhari-poetry--single .likhari-paragraph:nth-child(odd):not(:first-child) {
|
|
422
|
+
border-top: 1px dashed var(--editor-line-strong);
|
|
423
|
+
margin-top: var(--poetry-couplet-gap);
|
|
424
|
+
padding-top: calc(var(--poetry-couplet-gap) * 0.6);
|
|
419
425
|
}
|
|
420
426
|
|
|
427
|
+
.likhari-poetry--spacing-compact { --poetry-couplet-gap: 0.4em; }
|
|
428
|
+
.likhari-poetry--spacing-normal { --poetry-couplet-gap: 1em; }
|
|
429
|
+
.likhari-poetry--spacing-relaxed { --poetry-couplet-gap: 1.8em; }
|
|
430
|
+
.likhari-poetry--spacing-loose { --poetry-couplet-gap: 2.8em; }
|
|
431
|
+
|
|
421
432
|
.likhari-poetry--two-column .likhari-layout-container {
|
|
422
433
|
margin: 0;
|
|
423
|
-
/* No grid gap — the divider
|
|
424
|
-
spacing instead comes from matching padding on each side of it,
|
|
425
|
-
keeps the gutter visually even on both sides of the line. */
|
|
434
|
+
/* No grid gap — the column divider sits exactly on the track boundary,
|
|
435
|
+
so spacing instead comes from matching padding on each side of it,
|
|
436
|
+
which keeps the gutter visually even on both sides of the line. */
|
|
426
437
|
gap: 0;
|
|
427
438
|
}
|
|
428
439
|
|
|
429
|
-
/* One row per couplet in two-column layout — same
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
440
|
+
/* One row per couplet in two-column layout — same table-row-border
|
|
441
|
+
treatment as the single-column rule above, between couplets instead of
|
|
442
|
+
within one. */
|
|
443
|
+
.likhari-poetry--two-column .likhari-layout-container:not(:first-child) {
|
|
444
|
+
border-top: 1px dashed var(--editor-line-strong);
|
|
445
|
+
margin-top: var(--poetry-couplet-gap);
|
|
446
|
+
padding-top: calc(var(--poetry-couplet-gap) * 0.6);
|
|
433
447
|
}
|
|
434
448
|
|
|
435
449
|
.likhari-poetry--two-column .likhari-layout-item {
|
|
@@ -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,kBAiDzB,CAAC"}
|
|
@@ -46,6 +46,7 @@ export const editorTheme = {
|
|
|
46
46
|
footnoteList: 'likhari-footnote-list',
|
|
47
47
|
footnoteItem: 'likhari-footnote-item',
|
|
48
48
|
poetry: 'likhari-poetry',
|
|
49
|
+
poetryCouplet: 'likhari-poetry-couplet',
|
|
49
50
|
table: 'likhari-table',
|
|
50
51
|
tableRow: 'likhari-table-row',
|
|
51
52
|
tableCell: 'likhari-table-cell',
|