@inshapardaz/likhari-react 0.1.33 → 0.1.35-dev.282

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.
@@ -1 +1 @@
1
- {"version":3,"file":"LayoutNode.d.ts","sourceRoot":"","sources":["../../src/blocks/LayoutNode.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EAEX,WAAW,EACZ,MAAM,SAAS,CAAC;AAGjB;;2EAE2E;AAC3E,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAAC;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAA0C,CAAC;AAErH,MAAM,MAAM,6BAA6B,GAAG,MAAM,CAAC;IAAE,eAAe,EAAE,MAAM,CAAA;CAAE,EAAE,qBAAqB,CAAC,CAAC;AACvG,MAAM,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AAE7D;;sEAEsE;AACtE,qBAAa,mBAAoB,SAAQ,WAAW;IAClD,iBAAiB,EAAE,MAAM,CAAC;gBAEd,eAAe,SAAmB,EAAE,GAAG,CAAC,EAAE,OAAO;IAK7D,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,mBAAmB,GAAG,mBAAmB;IAI5D,kBAAkB,IAAI,MAAM;IAI5B,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI;IAMjD,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,6BAA6B,GAAG,mBAAmB;IAIrF,UAAU,IAAI,6BAA6B;IAI3C,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAU3C,SAAS,IAAI,eAAe;IAQ5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAO5C,SAAS,CAAC,QAAQ,EAAE,mBAAmB,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO;IAOnE,UAAU,IAAI,KAAK;IAInB,YAAY,IAAI,OAAO;CAGxB;AAED,wBAAgB,0BAA0B,CAAC,eAAe,SAAmB,GAAG,mBAAmB,CAElG;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,mBAAmB,CAExG;AAED;;oDAEoD;AACpD,qBAAa,cAAe,SAAQ,WAAW;IAC7C,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc;IAIlD,MAAM,CAAC,UAAU,IAAI,cAAc;IAInC,UAAU,IAAI,wBAAwB;IAItC,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAS3C,SAAS,IAAI,eAAe;IAM5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAM5C,SAAS,IAAI,OAAO;IAIpB,UAAU,IAAI,KAAK;IAInB,SAAS,IAAI,KAAK;CAGnB;AAED,wBAAgB,qBAAqB,IAAI,cAAc,CAEtD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,cAAc,CAE9F;AAED;;mCAEmC;AACnC,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,CAOjF"}
1
+ {"version":3,"file":"LayoutNode.d.ts","sourceRoot":"","sources":["../../src/blocks/LayoutNode.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EAEX,WAAW,EACZ,MAAM,SAAS,CAAC;AAGjB;;2EAE2E;AAC3E,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAAC;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAA0C,CAAC;AAErH,MAAM,MAAM,6BAA6B,GAAG,MAAM,CAAC;IAAE,eAAe,EAAE,MAAM,CAAA;CAAE,EAAE,qBAAqB,CAAC,CAAC;AACvG,MAAM,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AAE7D;;sEAEsE;AACtE,qBAAa,mBAAoB,SAAQ,WAAW;IAClD,iBAAiB,EAAE,MAAM,CAAC;gBAEd,eAAe,SAAmB,EAAE,GAAG,CAAC,EAAE,OAAO;IAK7D,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,mBAAmB,GAAG,mBAAmB;IAI5D,kBAAkB,IAAI,MAAM;IAI5B,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI;IAMjD,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,6BAA6B,GAAG,mBAAmB;IAIrF,UAAU,IAAI,6BAA6B;IAI3C,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAU3C,SAAS,IAAI,eAAe;IAQ5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAW5C,SAAS,CAAC,QAAQ,EAAE,mBAAmB,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO;IAQnE,UAAU,IAAI,KAAK;IAInB,YAAY,IAAI,OAAO;CAGxB;AAED,wBAAgB,0BAA0B,CAAC,eAAe,SAAmB,GAAG,mBAAmB,CAElG;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,mBAAmB,CAExG;AAED;;oDAEoD;AACpD,qBAAa,cAAe,SAAQ,WAAW;IAC7C,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc;IAIlD,MAAM,CAAC,UAAU,IAAI,cAAc;IAInC,UAAU,IAAI,wBAAwB;IAItC,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAS3C,SAAS,IAAI,eAAe;IAM5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAM5C,SAAS,IAAI,OAAO;IAIpB,UAAU,IAAI,KAAK;IAInB,SAAS,IAAI,KAAK;CAGnB;AAED,wBAAgB,qBAAqB,IAAI,cAAc,CAEtD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,cAAc,CAE9F;AAED;;mCAEmC;AACnC,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,CAOjF"}
@@ -53,12 +53,17 @@ export class LayoutContainerNode extends ElementNode {
53
53
  const element = document.createElement('div');
54
54
  addClassNamesToElement(element, config.theme.layoutContainer ?? 'likhari-layout-container');
55
55
  element.style.gridTemplateColumns = this.__templateColumns;
56
+ // Lets a single-item row (a centered poetry couplet — poetryActions.ts's
57
+ // $setCoupletCentered) be styled from CSS alone, without a :has() selector
58
+ // (issue #25: :has() needs Firefox 121+).
59
+ element.toggleAttribute('data-likhari-single-column', this.getChildrenSize() === 1);
56
60
  return element;
57
61
  }
58
62
  updateDOM(prevNode, dom) {
59
63
  if (prevNode.__templateColumns !== this.__templateColumns) {
60
64
  dom.style.gridTemplateColumns = this.__templateColumns;
61
65
  }
66
+ dom.toggleAttribute('data-likhari-single-column', this.getChildrenSize() === 1);
62
67
  return false;
63
68
  }
64
69
  canBeEmpty() {
@@ -12,12 +12,18 @@ export declare const DEFAULT_POETRY_GUTTER: PoetryGutter;
12
12
  export declare const POETRY_STAGGERS: readonly ["compact", "normal", "relaxed", "loose"];
13
13
  export type PoetryStagger = (typeof POETRY_STAGGERS)[number];
14
14
  export declare const DEFAULT_POETRY_STAGGER: PoetryStagger;
15
+ /** Width of a centered couplet in two-column layout, as a share of the block
16
+ * (issue #27 — was a fixed 60%; 'normal' keeps that same width). */
17
+ export declare const POETRY_CENTER_WIDTHS: readonly ["compact", "normal", "relaxed", "loose"];
18
+ export type PoetryCenterWidth = (typeof POETRY_CENTER_WIDTHS)[number];
19
+ export declare const DEFAULT_POETRY_CENTER_WIDTH: PoetryCenterWidth;
15
20
  export type SerializedPoetryBlockNode = Spread<{
16
21
  layout: PoetryLayout;
17
22
  width?: number;
18
23
  spacing?: PoetrySpacing;
19
24
  gutter?: PoetryGutter;
20
25
  stagger?: PoetryStagger;
26
+ centerWidth?: PoetryCenterWidth;
21
27
  }, SerializedElementNode>;
22
28
  /**
23
29
  * A poetry *section*: one or more couplets (two-line verse units) sharing
@@ -40,7 +46,8 @@ export declare class PoetryBlockNode extends ElementNode {
40
46
  __spacing: PoetrySpacing;
41
47
  __gutter: PoetryGutter;
42
48
  __stagger: PoetryStagger;
43
- constructor(layout?: PoetryLayout, width?: number, spacing?: PoetrySpacing, gutter?: PoetryGutter, stagger?: PoetryStagger, key?: NodeKey);
49
+ __centerWidth: PoetryCenterWidth;
50
+ constructor(layout?: PoetryLayout, width?: number, spacing?: PoetrySpacing, gutter?: PoetryGutter, stagger?: PoetryStagger, centerWidth?: PoetryCenterWidth, key?: NodeKey);
44
51
  static getType(): string;
45
52
  static clone(node: PoetryBlockNode): PoetryBlockNode;
46
53
  getLayout(): PoetryLayout;
@@ -56,6 +63,8 @@ export declare class PoetryBlockNode extends ElementNode {
56
63
  setGutter(gutter: PoetryGutter): this;
57
64
  getStagger(): PoetryStagger;
58
65
  setStagger(stagger: PoetryStagger): this;
66
+ getCenterWidth(): PoetryCenterWidth;
67
+ setCenterWidth(centerWidth: PoetryCenterWidth): this;
59
68
  static importJSON(serializedNode: SerializedPoetryBlockNode): PoetryBlockNode;
60
69
  exportJSON(): SerializedPoetryBlockNode;
61
70
  static importDOM(): DOMConversionMap | null;
@@ -65,6 +74,6 @@ export declare class PoetryBlockNode extends ElementNode {
65
74
  canBeEmpty(): false;
66
75
  isShadowRoot(): boolean;
67
76
  }
68
- export declare function $createPoetryBlockNode(layout?: PoetryLayout, width?: number, spacing?: PoetrySpacing, gutter?: PoetryGutter, stagger?: PoetryStagger): PoetryBlockNode;
77
+ export declare function $createPoetryBlockNode(layout?: PoetryLayout, width?: number, spacing?: PoetrySpacing, gutter?: PoetryGutter, stagger?: PoetryStagger, centerWidth?: PoetryCenterWidth): PoetryBlockNode;
69
78
  export declare function $isPoetryBlockNode(node: LexicalNode | null | undefined): node is PoetryBlockNode;
70
79
  //# sourceMappingURL=PoetryNode.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PoetryNode.d.ts","sourceRoot":"","sources":["../../src/blocks/PoetryNode.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PoetryNode.d.ts","sourceRoot":"","sources":["../../src/blocks/PoetryNode.tsx"],"names":[],"mappings":"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"}
@@ -9,10 +9,15 @@ export const DEFAULT_POETRY_GUTTER = 'normal';
9
9
  /** Width of each couplet box in staggered layout, as a share of the block. */
10
10
  export const POETRY_STAGGERS = ['compact', 'normal', 'relaxed', 'loose'];
11
11
  export const DEFAULT_POETRY_STAGGER = 'normal';
12
+ /** Width of a centered couplet in two-column layout, as a share of the block
13
+ * (issue #27 — was a fixed 60%; 'normal' keeps that same width). */
14
+ export const POETRY_CENTER_WIDTHS = ['compact', 'normal', 'relaxed', 'loose'];
15
+ export const DEFAULT_POETRY_CENTER_WIDTH = 'normal';
12
16
  const VALID_LAYOUTS = new Set(['single', 'two-column', 'staggered']);
13
17
  const VALID_SPACINGS = new Set(POETRY_SPACINGS);
14
18
  const VALID_GUTTERS = new Set(POETRY_GUTTERS);
15
19
  const VALID_STAGGERS = new Set(POETRY_STAGGERS);
20
+ const VALID_CENTER_WIDTHS = new Set(POETRY_CENTER_WIDTHS);
16
21
  /** Poetry is always justified: `text-align-last: justify` stretches a
17
22
  * one-line misra across the full column width too, not just wrapped lines,
18
23
  * so every line reads edge-to-edge. */
@@ -43,19 +48,20 @@ function applyWidthStyle(element, width) {
43
48
  * per requirements doc §4.11.
44
49
  */
45
50
  export class PoetryBlockNode extends ElementNode {
46
- constructor(layout = 'single', width, spacing = DEFAULT_POETRY_SPACING, gutter = DEFAULT_POETRY_GUTTER, stagger = DEFAULT_POETRY_STAGGER, key) {
51
+ constructor(layout = 'single', width, spacing = DEFAULT_POETRY_SPACING, gutter = DEFAULT_POETRY_GUTTER, stagger = DEFAULT_POETRY_STAGGER, centerWidth = DEFAULT_POETRY_CENTER_WIDTH, key) {
47
52
  super(key);
48
53
  this.__layout = layout;
49
54
  this.__width = width;
50
55
  this.__spacing = spacing;
51
56
  this.__gutter = gutter;
52
57
  this.__stagger = stagger;
58
+ this.__centerWidth = centerWidth;
53
59
  }
54
60
  static getType() {
55
61
  return 'poetry-couplet';
56
62
  }
57
63
  static clone(node) {
58
- return new PoetryBlockNode(node.__layout, node.__width, node.__spacing, node.__gutter, node.__stagger, node.__key);
64
+ return new PoetryBlockNode(node.__layout, node.__width, node.__spacing, node.__gutter, node.__stagger, node.__centerWidth, node.__key);
59
65
  }
60
66
  getLayout() {
61
67
  return this.getLatest().__layout;
@@ -100,8 +106,28 @@ export class PoetryBlockNode extends ElementNode {
100
106
  writable.__stagger = stagger;
101
107
  return writable;
102
108
  }
109
+ getCenterWidth() {
110
+ return this.getLatest().__centerWidth;
111
+ }
112
+ setCenterWidth(centerWidth) {
113
+ const writable = this.getWritable();
114
+ writable.__centerWidth = centerWidth;
115
+ return writable;
116
+ }
117
+ // Validated the same way the DOM import below validates its attributes
118
+ // (issue #29) — hand-edited or otherwise untrusted JSON could carry any
119
+ // string here, which would otherwise add an unknown CSS modifier class
120
+ // and render with no style for that setting.
103
121
  static importJSON(serializedNode) {
104
- return $createPoetryBlockNode(serializedNode.layout, serializedNode.width, serializedNode.spacing, serializedNode.gutter, serializedNode.stagger);
122
+ const layout = VALID_LAYOUTS.has(serializedNode.layout) ? serializedNode.layout : 'single';
123
+ const width = typeof serializedNode.width === 'number' && serializedNode.width > 0 ? serializedNode.width : undefined;
124
+ const spacing = VALID_SPACINGS.has(serializedNode.spacing) ? serializedNode.spacing : DEFAULT_POETRY_SPACING;
125
+ const gutter = VALID_GUTTERS.has(serializedNode.gutter) ? serializedNode.gutter : DEFAULT_POETRY_GUTTER;
126
+ const stagger = VALID_STAGGERS.has(serializedNode.stagger) ? serializedNode.stagger : DEFAULT_POETRY_STAGGER;
127
+ const centerWidth = VALID_CENTER_WIDTHS.has(serializedNode.centerWidth)
128
+ ? serializedNode.centerWidth
129
+ : DEFAULT_POETRY_CENTER_WIDTH;
130
+ return $createPoetryBlockNode(layout, width, spacing, gutter, stagger, centerWidth);
105
131
  }
106
132
  exportJSON() {
107
133
  const width = this.getWidth();
@@ -113,6 +139,7 @@ export class PoetryBlockNode extends ElementNode {
113
139
  spacing: this.getSpacing(),
114
140
  gutter: this.getGutter(),
115
141
  stagger: this.getStagger(),
142
+ centerWidth: this.getCenterWidth(),
116
143
  ...(width !== undefined ? { width } : {}),
117
144
  };
118
145
  }
@@ -131,7 +158,11 @@ export class PoetryBlockNode extends ElementNode {
131
158
  const gutter = VALID_GUTTERS.has(rawGutter) ? rawGutter : DEFAULT_POETRY_GUTTER;
132
159
  const rawStagger = domNode.getAttribute('data-likhari-poetry-stagger');
133
160
  const stagger = VALID_STAGGERS.has(rawStagger) ? rawStagger : DEFAULT_POETRY_STAGGER;
134
- return { conversion: () => ({ node: $createPoetryBlockNode(layout, width, spacing, gutter, stagger) }), priority: 2 };
161
+ const rawCenterWidth = domNode.getAttribute('data-likhari-poetry-center-width');
162
+ const centerWidth = VALID_CENTER_WIDTHS.has(rawCenterWidth)
163
+ ? rawCenterWidth
164
+ : DEFAULT_POETRY_CENTER_WIDTH;
165
+ return { conversion: () => ({ node: $createPoetryBlockNode(layout, width, spacing, gutter, stagger, centerWidth) }), priority: 2 };
135
166
  },
136
167
  };
137
168
  }
@@ -141,6 +172,7 @@ export class PoetryBlockNode extends ElementNode {
141
172
  element.setAttribute('data-likhari-poetry-spacing', this.getSpacing());
142
173
  element.setAttribute('data-likhari-poetry-gutter', this.getGutter());
143
174
  element.setAttribute('data-likhari-poetry-stagger', this.getStagger());
175
+ element.setAttribute('data-likhari-poetry-center-width', this.getCenterWidth());
144
176
  const width = this.getWidth();
145
177
  if (width !== undefined)
146
178
  element.setAttribute('data-likhari-poetry-width', String(width));
@@ -151,7 +183,7 @@ export class PoetryBlockNode extends ElementNode {
151
183
  createDOM(config) {
152
184
  const element = document.createElement('div');
153
185
  const base = config.theme.poetry ?? 'likhari-poetry';
154
- addClassNamesToElement(element, base, `${base}--${this.__layout}`, `${base}--spacing-${this.__spacing}`, `${base}--gutter-${this.__gutter}`, `${base}--stagger-${this.__stagger}`);
186
+ addClassNamesToElement(element, base, `${base}--${this.__layout}`, `${base}--spacing-${this.__spacing}`, `${base}--gutter-${this.__gutter}`, `${base}--stagger-${this.__stagger}`, `${base}--center-${this.__centerWidth}`);
155
187
  applyJustifyStyle(element);
156
188
  applyWidthStyle(element, this.__width);
157
189
  return element;
@@ -178,6 +210,10 @@ export class PoetryBlockNode extends ElementNode {
178
210
  dom.classList.remove(`${base}--stagger-${prevNode.__stagger}`);
179
211
  dom.classList.add(`${base}--stagger-${this.__stagger}`);
180
212
  }
213
+ if (prevNode.__centerWidth !== this.__centerWidth) {
214
+ dom.classList.remove(`${base}--center-${prevNode.__centerWidth}`);
215
+ dom.classList.add(`${base}--center-${this.__centerWidth}`);
216
+ }
181
217
  if (prevNode.__width !== this.__width) {
182
218
  applyWidthStyle(dom, this.__width);
183
219
  }
@@ -190,8 +226,8 @@ export class PoetryBlockNode extends ElementNode {
190
226
  return true;
191
227
  }
192
228
  }
193
- export function $createPoetryBlockNode(layout = 'single', width, spacing = DEFAULT_POETRY_SPACING, gutter = DEFAULT_POETRY_GUTTER, stagger = DEFAULT_POETRY_STAGGER) {
194
- return $applyNodeReplacement(new PoetryBlockNode(layout, width, spacing, gutter, stagger));
229
+ export function $createPoetryBlockNode(layout = 'single', width, spacing = DEFAULT_POETRY_SPACING, gutter = DEFAULT_POETRY_GUTTER, stagger = DEFAULT_POETRY_STAGGER, centerWidth = DEFAULT_POETRY_CENTER_WIDTH) {
230
+ return $applyNodeReplacement(new PoetryBlockNode(layout, width, spacing, gutter, stagger, centerWidth));
195
231
  }
196
232
  export function $isPoetryBlockNode(node) {
197
233
  return node instanceof PoetryBlockNode;
@@ -101,6 +101,9 @@ export declare function $adjustPoetryGutter(step: 1 | -1): boolean;
101
101
  /** Steps the caret's staggered couplet width one notch narrower (-1) or wider
102
102
  * (+1); clamps at either end. */
103
103
  export declare function $adjustPoetryStagger(step: 1 | -1): boolean;
104
+ /** Steps the caret's centered-couplet width (issue #27) one notch narrower
105
+ * (-1) or wider (+1); clamps at either end. */
106
+ export declare function $adjustPoetryCenterWidth(step: 1 | -1): boolean;
104
107
  /** Whether the couplet the caret is in is centered, or null outside a
105
108
  * two-column poetry block (centering only applies there). */
106
109
  export declare function $getCoupletCenteredFromSelection(): boolean | null;
@@ -1 +1 @@
1
- {"version":3,"file":"poetryActions.d.ts","sourceRoot":"","sources":["../../src/blocks/poetryActions.ts"],"names":[],"mappings":"AACA,OAAO,EAOL,KAAK,aAAa,EACnB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAML,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,CAqB7D;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,GAAG,OAAO,CAiBlE;AAED;;;;wCAIwC;AACxC,wBAAgB,oBAAoB,IAAI,OAAO,CAwB9C;AAUD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAsClD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAkB9C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAgD5C;AAED;sDACsD;AACtD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAO1D;AAED;2BAC2B;AAC3B,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAOzD;AAED;iCACiC;AACjC,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAO1D;AAYD;6DAC6D;AAC7D,wBAAgB,gCAAgC,IAAI,OAAO,GAAG,IAAI,CAUjE;AAED;8DAC8D;AAC9D,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAuB9D;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,IAAI,OAAO,CAK5C;AAED;;;qDAGqD;AACrD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAGvE"}
1
+ {"version":3,"file":"poetryActions.d.ts","sourceRoot":"","sources":["../../src/blocks/poetryActions.ts"],"names":[],"mappings":"AACA,OAAO,EASL,KAAK,aAAa,EACnB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAOL,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,CAqB7D;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,CAmClF;AAED;;;;;;qDAMqD;AACrD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAEpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAiBlE;AAED;;;;wCAIwC;AACxC,wBAAgB,oBAAoB,IAAI,OAAO,CAwB9C;AAUD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAsClD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAkB9C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAgD5C;AAED;sDACsD;AACtD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAO1D;AAED;2BAC2B;AAC3B,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAOzD;AAED;iCACiC;AACjC,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAO1D;AAED;+CAC+C;AAC/C,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAO9D;AAYD;6DAC6D;AAC7D,wBAAgB,gCAAgC,IAAI,OAAO,GAAG,IAAI,CAUjE;AAED;8DAC8D;AAC9D,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAuB9D;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,IAAI,OAAO,CAK5C;AAED;;;qDAGqD;AACrD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAGvE"}
@@ -1,7 +1,7 @@
1
1
  import { $findMatchingParent } from '@lexical/utils';
2
- import { $createParagraphNode, $getSelection, $isElementNode, $isParagraphNode, $isRangeSelection, } from 'lexical';
2
+ import { $createParagraphNode, $createRangeSelection, $getSelection, $isElementNode, $isParagraphNode, $isRangeSelection, $setSelection, } from 'lexical';
3
3
  import { $createLayoutContainerNode, $createLayoutItemNode, $isLayoutContainerNode, $isLayoutItemNode } from './LayoutNode.js';
4
- import { $createPoetryBlockNode, $isPoetryBlockNode, POETRY_GUTTERS, POETRY_SPACINGS, POETRY_STAGGERS, } from './PoetryNode.js';
4
+ import { $createPoetryBlockNode, $isPoetryBlockNode, POETRY_CENTER_WIDTHS, POETRY_GUTTERS, POETRY_SPACINGS, POETRY_STAGGERS, } 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
@@ -143,6 +143,13 @@ export function $setPoetryLayout(node, layout) {
143
143
  if (node.getLayout() === layout)
144
144
  return;
145
145
  const couplets = $getCouplets(node);
146
+ // Removing a misra paragraph below (to re-append it in its new row) moves
147
+ // the selection away the moment it's detached, even though it lands back
148
+ // in the same paragraph a few lines later — so the caret ends up outside
149
+ // the block entirely unless it's explicitly restored afterward.
150
+ const selection = $getSelection();
151
+ const anchor = $isRangeSelection(selection) ? { key: selection.anchor.key, offset: selection.anchor.offset, type: selection.anchor.type } : null;
152
+ const focus = $isRangeSelection(selection) ? { key: selection.focus.key, offset: selection.focus.offset, type: selection.focus.type } : null;
146
153
  for (const [a, b] of couplets) {
147
154
  a.remove();
148
155
  b.remove();
@@ -161,6 +168,12 @@ export function $setPoetryLayout(node, layout) {
161
168
  }
162
169
  }
163
170
  node.setLayoutAttribute(layout);
171
+ if (anchor && focus) {
172
+ const restored = $createRangeSelection();
173
+ restored.anchor.set(anchor.key, anchor.offset, anchor.type);
174
+ restored.focus.set(focus.key, focus.offset, focus.type);
175
+ $setSelection(restored);
176
+ }
164
177
  }
165
178
  /** A block at the very end of the document would otherwise leave no
166
179
  * editable block to click or arrow down into — appends one empty paragraph
@@ -407,6 +420,17 @@ export function $adjustPoetryStagger(step) {
407
420
  block.setStagger(next);
408
421
  return true;
409
422
  }
423
+ /** Steps the caret's centered-couplet width (issue #27) one notch narrower
424
+ * (-1) or wider (+1); clamps at either end. */
425
+ export function $adjustPoetryCenterWidth(step) {
426
+ const block = $getPoetryBlockFromSelection();
427
+ if (!block)
428
+ return false;
429
+ const index = POETRY_CENTER_WIDTHS.indexOf(block.getCenterWidth());
430
+ const next = POETRY_CENTER_WIDTHS[Math.min(POETRY_CENTER_WIDTHS.length - 1, Math.max(0, index + step))];
431
+ block.setCenterWidth(next);
432
+ return true;
433
+ }
410
434
  /** A centered couplet is a two-column row holding both misras in one item
411
435
  * (a single-item row), rather than one item per misra. */
412
436
  function $isCoupletRowCentered(row) {
@@ -1 +1 @@
1
- {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AA2CA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAgDtF,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;AA8gBvD,0FAA0F;AAC1F,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,2BAA2B,CAAC;IACpC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,gCAAgC;IAChC,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,aAAa,EAAE,CAAC;IACnC,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IACnE,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,iGAAiG;IACjG,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,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,YAAY,EAAE,gBAAqB,EAAE,eAAoB,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAgB,EAAE,YAAY,EAAE,SAAiB,EAAE,aAAa,EAAE,eAAuB,EAAE,mBAAmB,EAAE,WAAkC,EAAE,SAAiB,EAAE,MAAa,EAAE,MAAM,EAAE,EAAE,YAAY,+BAuqCrV"}
1
+ {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AA2CA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAmDtF,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;AAojBvD,0FAA0F;AAC1F,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,2BAA2B,CAAC;IACpC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,gCAAgC;IAChC,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,aAAa,EAAE,CAAC;IACnC,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IACnE,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,iGAAiG;IACjG,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,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,YAAY,EAAE,gBAAqB,EAAE,eAAoB,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAgB,EAAE,YAAY,EAAE,SAAiB,EAAE,aAAa,EAAE,eAAuB,EAAE,mBAAmB,EAAE,WAAkC,EAAE,SAAiB,EAAE,MAAa,EAAE,MAAM,EAAE,EAAE,YAAY,+BA+rCrV"}
@@ -21,8 +21,8 @@ import { $createImageNode } from '../image/ImageNode.js';
21
21
  import { INSERT_PAGE_BREAK_COMMAND } from '../blocks/PageBreakNode.js';
22
22
  import { INSERT_LAYOUT_COMMAND } from '../blocks/LayoutNode.js';
23
23
  import { INSERT_FOOTNOTE_COMMAND } from '../blocks/FootnoteNode.js';
24
- import { $isPoetryBlockNode, POETRY_GUTTERS, POETRY_SPACINGS, POETRY_STAGGERS, } from '../blocks/PoetryNode.js';
25
- import { $adjustPoetryGutter, $getCoupletCenteredFromSelection, $setCoupletCentered, $adjustPoetryStagger, $adjustPoetrySpacing, $deletePoetryBlock, $deletePoetryCouplet, $getPoetryBlockFromSelection, $insertCoupletRelativeToSelection, $setPoetryLayout, } from '../blocks/poetryActions.js';
24
+ import { $isPoetryBlockNode, POETRY_CENTER_WIDTHS, POETRY_GUTTERS, POETRY_SPACINGS, POETRY_STAGGERS, } from '../blocks/PoetryNode.js';
25
+ import { $adjustPoetryCenterWidth, $adjustPoetryGutter, $getCoupletCenteredFromSelection, $setCoupletCentered, $adjustPoetryStagger, $adjustPoetrySpacing, $deletePoetryBlock, $deletePoetryCouplet, $getPoetryBlockFromSelection, $insertCoupletRelativeToSelection, $setPoetryLayout, } from '../blocks/poetryActions.js';
26
26
  import { INSERT_POETRY_COUPLET_COMMAND } from '../plugins/PoetryPlugin.js';
27
27
  import { TableDialog } from './TableDialog.js';
28
28
  import { LayoutDialog } from './LayoutDialog.js';
@@ -58,13 +58,34 @@ const INITIAL_STATE = {
58
58
  canUnmergeCell: false,
59
59
  inPoetry: false,
60
60
  poetryLayout: 'single',
61
- poetryScale: { spacing: 'normal', gutter: 'normal', stagger: 'normal' },
61
+ poetryScale: { spacing: 'normal', gutter: 'normal', stagger: 'normal', centerWidth: 'normal' },
62
62
  poetryCentered: false,
63
63
  canUndo: false,
64
64
  canRedo: false,
65
65
  };
66
66
  const ICON_SIZE = 17;
67
67
  const ICON_STROKE = 1.75;
68
+ /** The CSS Custom Highlight name; editor.css paints it like a native text selection. */
69
+ const SELECTION_HIGHLIGHT = 'likhari-toolbar-selection';
70
+ /** Paints the current native selection through the CSS Custom Highlight API, so it
71
+ * stays visible once a toolbar control (a Select, a Menu, a dialog) takes focus —
72
+ * which, unlike a ToolbarButton's onMouseDown/preventDefault, it must be able to do.
73
+ * The browser clears `window.getSelection()` on blur; this is called at the one
74
+ * moment before that happens (mousedown, or opening a menu/dialog), alongside the
75
+ * Lexical-level selection snapshot these controls already restore from. */
76
+ function paintSelectionHighlight() {
77
+ if (typeof CSS === 'undefined' || !('highlights' in CSS))
78
+ return;
79
+ const domSelection = window.getSelection();
80
+ if (!domSelection || domSelection.isCollapsed || domSelection.rangeCount === 0) {
81
+ CSS.highlights.delete(SELECTION_HIGHLIGHT);
82
+ return;
83
+ }
84
+ const ranges = [];
85
+ for (let i = 0; i < domSelection.rangeCount; i++)
86
+ ranges.push(domSelection.getRangeAt(i).cloneRange());
87
+ CSS.highlights.set(SELECTION_HIGHLIGHT, new Highlight(...ranges));
88
+ }
68
89
  const ALIGN_ICONS_LTR = {
69
90
  start: IconAlignLeft,
70
91
  left: IconAlignLeft,
@@ -135,10 +156,17 @@ function setsEqual(a, b) {
135
156
  /** Mantine Select (combobox) for the toolbar's dropdown controls. The icon
136
157
  * labels the control itself, since a dropdown can't show one per option in
137
158
  * its closed state. The dropdown portals to <body>, so it is not clipped by
138
- * the editor's `overflow: hidden` frame. */
139
- function ToolbarSelect({ icon: Icon, label, value, data, width, disabled, placeholder, searchable, renderOption, onChange, comingSoon, noMatchMessage }) {
159
+ * the editor's `overflow: hidden` frame.
160
+ *
161
+ * Unlike a ToolbarButton, this can't keep focus on the canvas with
162
+ * onMouseDown/preventDefault — a combobox needs focus to open. So picking an
163
+ * option blurs the canvas first, which clears Lexical's selection; `onMouseDown`
164
+ * is the caller's chance to snapshot it (the browser moves focus only after
165
+ * mousedown's listeners run), to restore before applying the change
166
+ * (see Toolbar's `withRefocus`). */
167
+ function ToolbarSelect({ icon: Icon, label, value, data, width, disabled, placeholder, searchable, renderOption, onChange, onMouseDown, comingSoon, noMatchMessage }) {
140
168
  const portalTarget = usePortalTarget();
141
- return (_jsx(Select, { size: "xs", w: width, "aria-label": label, title: disabled && comingSoon ? comingSoon(label) : label, data: data, value: value, placeholder: placeholder, disabled: disabled, searchable: searchable, renderOption: renderOption, nothingFoundMessage: searchable ? noMatchMessage : undefined, allowDeselect: false, leftSection: _jsx(Icon, { size: 15, stroke: ICON_STROKE }), comboboxProps: { withinPortal: true, position: 'bottom-start', middlewares: { flip: true, shift: true }, portalProps: { target: portalTarget } }, classNames: { input: 'likhari-toolbar-select-input', dropdown: 'likhari-toolbar-select-dropdown' }, onChange: (v) => v && onChange?.(v) }));
169
+ return (_jsx(Select, { size: "xs", w: width, "aria-label": label, title: disabled && comingSoon ? comingSoon(label) : label, data: data, value: value, placeholder: placeholder, disabled: disabled, searchable: searchable, onMouseDown: onMouseDown, renderOption: renderOption, nothingFoundMessage: searchable ? noMatchMessage : undefined, allowDeselect: false, leftSection: _jsx(Icon, { size: 15, stroke: ICON_STROKE }), comboboxProps: { withinPortal: true, position: 'bottom-start', middlewares: { flip: true, shift: true }, portalProps: { target: portalTarget } }, classNames: { input: 'likhari-toolbar-select-input', dropdown: 'likhari-toolbar-select-dropdown' }, onChange: (v) => v && onChange?.(v) }));
142
170
  }
143
171
  /** An item in the "..." menu. A mousedown here would blur the canvas, so it is kept. */
144
172
  function MoreMenuItem({ icon: Icon, label, active, onClick, }) {
@@ -183,7 +211,7 @@ function PoetryMenuItems({ strings, layout, scale, centered, onAction, }) {
183
211
  if (node)
184
212
  $setPoetryLayout(node, next);
185
213
  };
186
- 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'), item(IconArrowsShuffle, t.staggered, setLayout('staggered'), layout === 'staggered'), _jsx(Menu.Divider, {}), _jsx(Menu.Divider, {}), item(IconRowInsertTop, t.insertCoupletBefore, () => $insertCoupletRelativeToSelection('before')), item(IconRowInsertBottom, t.insertCoupletAfter, () => $insertCoupletRelativeToSelection('after')), item(IconArrowsMinimize, t.tighterSpacing, () => $adjustPoetrySpacing(-1), !canStep(POETRY_SPACINGS, scale.spacing, -1)), item(IconArrowsMaximize, t.looserSpacing, () => $adjustPoetrySpacing(1), !canStep(POETRY_SPACINGS, scale.spacing, 1)), layout === 'staggered' && (_jsxs(_Fragment, { children: [item(IconArrowsMinimize, t.narrowerCouplets, () => $adjustPoetryStagger(-1), !canStep(POETRY_STAGGERS, scale.stagger, -1)), item(IconArrowsMaximize, t.widerCouplets, () => $adjustPoetryStagger(1), !canStep(POETRY_STAGGERS, scale.stagger, 1))] })), layout === 'two-column' && (_jsxs(_Fragment, { children: [item(IconAlignCenter, centered ? t.uncenterCouplet : t.centerCouplet, () => $setCoupletCentered(!centered)), item(IconColumns2, t.narrowerGutter, () => $adjustPoetryGutter(-1), !canStep(POETRY_GUTTERS, scale.gutter, -1)), item(IconColumns2, t.widerGutter, () => $adjustPoetryGutter(1), !canStep(POETRY_GUTTERS, scale.gutter, 1))] })), item(IconTrash, t.deleteCouplet, $deletePoetryCouplet, false, 'red'), item(IconTrash, t.deletePoetry, $deletePoetryBlock, false, 'red')] }));
214
+ 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'), item(IconArrowsShuffle, t.staggered, setLayout('staggered'), layout === 'staggered'), _jsx(Menu.Divider, {}), _jsx(Menu.Divider, {}), item(IconRowInsertTop, t.insertCoupletBefore, () => $insertCoupletRelativeToSelection('before')), item(IconRowInsertBottom, t.insertCoupletAfter, () => $insertCoupletRelativeToSelection('after')), item(IconArrowsMinimize, t.tighterSpacing, () => $adjustPoetrySpacing(-1), !canStep(POETRY_SPACINGS, scale.spacing, -1)), item(IconArrowsMaximize, t.looserSpacing, () => $adjustPoetrySpacing(1), !canStep(POETRY_SPACINGS, scale.spacing, 1)), layout === 'staggered' && (_jsxs(_Fragment, { children: [item(IconArrowsMinimize, t.narrowerCouplets, () => $adjustPoetryStagger(-1), !canStep(POETRY_STAGGERS, scale.stagger, -1)), item(IconArrowsMaximize, t.widerCouplets, () => $adjustPoetryStagger(1), !canStep(POETRY_STAGGERS, scale.stagger, 1))] })), layout === 'two-column' && (_jsxs(_Fragment, { children: [item(IconAlignCenter, centered ? t.uncenterCouplet : t.centerCouplet, () => $setCoupletCentered(!centered)), centered && (_jsxs(_Fragment, { children: [item(IconArrowsMinimize, t.narrowerCenter, () => $adjustPoetryCenterWidth(-1), !canStep(POETRY_CENTER_WIDTHS, scale.centerWidth, -1)), item(IconArrowsMaximize, t.widerCenter, () => $adjustPoetryCenterWidth(1), !canStep(POETRY_CENTER_WIDTHS, scale.centerWidth, 1))] })), item(IconColumns2, t.narrowerGutter, () => $adjustPoetryGutter(-1), !canStep(POETRY_GUTTERS, scale.gutter, -1)), item(IconColumns2, t.widerGutter, () => $adjustPoetryGutter(1), !canStep(POETRY_GUTTERS, scale.gutter, 1))] })), item(IconTrash, t.deleteCouplet, $deletePoetryCouplet, false, 'red'), item(IconTrash, t.deletePoetry, $deletePoetryBlock, false, 'red')] }));
187
215
  }
188
216
  export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurusStores = [], onAddAutoCorrect, onSave, isDirty, showSave, findOpen = false, onToggleFind, spellOpen = false, onToggleSpell, autoCorrectOpen = false, onToggleAutoCorrect, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
189
217
  const bordered = toolbarStyle?.bordered ?? true;
@@ -253,7 +281,7 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
253
281
  const poetryLayout = poetryBlock?.getLayout();
254
282
  const poetryCentered = $getCoupletCenteredFromSelection();
255
283
  const poetryScale = poetryBlock
256
- ? { spacing: poetryBlock.getSpacing(), gutter: poetryBlock.getGutter(), stagger: poetryBlock.getStagger() }
284
+ ? { spacing: poetryBlock.getSpacing(), gutter: poetryBlock.getGutter(), stagger: poetryBlock.getStagger(), centerWidth: poetryBlock.getCenterWidth() }
257
285
  : null;
258
286
  setState((s) => ({
259
287
  ...s,
@@ -345,9 +373,24 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
345
373
  const selection = $getSelection();
346
374
  menuSelectionRef.current = selection ? selection.clone() : null;
347
375
  });
376
+ paintSelectionHighlight();
348
377
  };
349
378
  const snapshotSelectionRef = useRef(snapshotSelection);
350
379
  snapshotSelectionRef.current = snapshotSelection;
380
+ // Clears the stand-in highlight once the canvas has a real selection to show again.
381
+ useEffect(() => {
382
+ if (typeof CSS === 'undefined' || !('highlights' in CSS))
383
+ return;
384
+ const clear = () => CSS.highlights.delete(SELECTION_HIGHLIGHT);
385
+ const unregister = editor.registerRootListener((root, previous) => {
386
+ previous?.removeEventListener('focus', clear);
387
+ root?.addEventListener('focus', clear);
388
+ });
389
+ return () => {
390
+ unregister();
391
+ clear();
392
+ };
393
+ }, [editor]);
351
394
  const runMenuItem = (action) => () => {
352
395
  const saved = menuSelectionRef.current;
353
396
  if (saved)
@@ -610,7 +653,12 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
610
653
  return true;
611
654
  }, COMMAND_PRIORITY_NORMAL);
612
655
  }, [editor, config.links, openLinkDialog]);
656
+ // The Select has already blurred the canvas by the time this runs (see
657
+ // ToolbarSelect's doc comment), so the selection snapshotted on its
658
+ // mousedown is restored first, then the canvas regains focus afterward —
659
+ // the combobox otherwise keeps it, so typing after picking would go nowhere.
613
660
  const withRefocus = (fn) => (value) => {
661
+ restoreSelection();
614
662
  fn(value);
615
663
  editor.focus();
616
664
  };
@@ -753,9 +801,9 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
753
801
  ];
754
802
  const formattingValue = state.listType ?? state.blockType;
755
803
  const AlignIcon = ALIGN_ICONS[state.elementFormat] ?? IconAlignLeft;
756
- const formatSection = (showFormattingGroup || fmt.bold || fmt.italic || fmt.underline || fmt.strikethrough || moreItems.length > 0) && (_jsxs(Fragment, { children: [showFormattingGroup && (_jsx(MantineToolbar.Group, { children: _jsx(ToolbarSelect, { icon: IconPilcrow, label: strings.toolbar.formattingLabel, width: 148, value: formattingValue, data: formattingOptions, comingSoon: strings.toolbar.comingSoon, renderOption: iconOptionRenderer(FORMATTING_ICONS, IconPilcrow), onChange: withRefocus((v) => applyFormatting(v)) }) })), (fmt.bold || fmt.italic || fmt.underline || fmt.strikethrough || moreItems.length > 0) && (_jsxs(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: [fmt.bold && _jsx(ToolbarButton, { icon: IconBold, title: strings.toolbar.bold, active: state.activeFormats.has('bold'), onClick: () => formatText('bold') }), fmt.italic && (_jsx(ToolbarButton, { icon: IconItalic, title: strings.toolbar.italic, active: state.activeFormats.has('italic'), onClick: () => formatText('italic') })), fmt.underline && (_jsx(ToolbarButton, { icon: IconUnderline, title: strings.toolbar.underline, active: state.activeFormats.has('underline'), onClick: () => formatText('underline') })), fmt.strikethrough && (_jsx(ToolbarButton, { icon: IconStrikethrough, title: strings.toolbar.strikethrough, active: state.activeFormats.has('strikethrough'), onClick: () => formatText('strikethrough') })), moreItems.length > 0 && (_jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 210, closeOnItemClick: true, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx(ToolbarButton, { icon: IconDots, title: strings.toolbar.moreFormatting }) }), _jsx(Menu.Dropdown, { children: moreItems.map((item) => (_jsx(MoreMenuItem, { icon: item.icon, label: item.label, active: item.active, onClick: runMenuItem(item.onClick) }, item.key))) })] }))] }))] }, "format"));
757
- const alignSection = (showAlignGroup || indentItems.length > 0) && (_jsxs(Fragment, { children: [showAlignGroup && (_jsx(MantineToolbar.Group, { children: _jsx(ToolbarSelect, { icon: AlignIcon, label: strings.toolbar.alignment, width: 138, value: state.elementFormat || 'start', data: alignOptions, renderOption: iconOptionRenderer(ALIGN_ICONS, IconAlignLeft), onChange: withRefocus((v) => formatElement(v)) }) })), indentItems.length > 0 && (_jsx(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: indentItems.map((item) => (_jsx(ToolbarButton, { icon: item.icon, title: item.label, onClick: item.onClick }, item.key))) }))] }, "align"));
758
- const fontSection = (config.font.family || config.font.size) && (_jsxs(MantineToolbar.Group, { children: [config.font.family && (_jsx(ToolbarSelect, { icon: IconTypography, label: strings.toolbar.fontFamily, width: 150, value: fontOptions.some((f) => f.family === shownFontFamily) ? shownFontFamily : null, placeholder: strings.toolbar.fontFamilyPlaceholder, data: fontData, searchable: true, noMatchMessage: strings.toolbar.noMatch, renderOption: ({ option }) => _jsx("span", { style: { fontFamily: option.value }, children: option.label }), onChange: withRefocus((v) => applyFont('font-family', v)) })), config.font.size && (_jsx(ToolbarSelect, { icon: IconTextSize, label: strings.toolbar.fontSize, width: 84, value: FONT_SIZES_PX.some((px) => `${px}px` === shownFontSize) ? shownFontSize : null, placeholder: strings.toolbar.fontSizePlaceholder, data: FONT_SIZES_PX.map((px) => ({ value: `${px}px`, label: String(px) })), onChange: withRefocus((v) => applyFont('font-size', v)) }))] }, "font"));
804
+ const formatSection = (showFormattingGroup || fmt.bold || fmt.italic || fmt.underline || fmt.strikethrough || moreItems.length > 0) && (_jsxs(Fragment, { children: [showFormattingGroup && (_jsx(MantineToolbar.Group, { children: _jsx(ToolbarSelect, { icon: IconPilcrow, label: strings.toolbar.formattingLabel, width: 148, value: formattingValue, data: formattingOptions, comingSoon: strings.toolbar.comingSoon, renderOption: iconOptionRenderer(FORMATTING_ICONS, IconPilcrow), onMouseDown: snapshotSelection, onChange: withRefocus((v) => applyFormatting(v)) }) })), (fmt.bold || fmt.italic || fmt.underline || fmt.strikethrough || moreItems.length > 0) && (_jsxs(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: [fmt.bold && _jsx(ToolbarButton, { icon: IconBold, title: strings.toolbar.bold, active: state.activeFormats.has('bold'), onClick: () => formatText('bold') }), fmt.italic && (_jsx(ToolbarButton, { icon: IconItalic, title: strings.toolbar.italic, active: state.activeFormats.has('italic'), onClick: () => formatText('italic') })), fmt.underline && (_jsx(ToolbarButton, { icon: IconUnderline, title: strings.toolbar.underline, active: state.activeFormats.has('underline'), onClick: () => formatText('underline') })), fmt.strikethrough && (_jsx(ToolbarButton, { icon: IconStrikethrough, title: strings.toolbar.strikethrough, active: state.activeFormats.has('strikethrough'), onClick: () => formatText('strikethrough') })), moreItems.length > 0 && (_jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 210, closeOnItemClick: true, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx(ToolbarButton, { icon: IconDots, title: strings.toolbar.moreFormatting }) }), _jsx(Menu.Dropdown, { children: moreItems.map((item) => (_jsx(MoreMenuItem, { icon: item.icon, label: item.label, active: item.active, onClick: runMenuItem(item.onClick) }, item.key))) })] }))] }))] }, "format"));
805
+ const alignSection = (showAlignGroup || indentItems.length > 0) && (_jsxs(Fragment, { children: [showAlignGroup && (_jsx(MantineToolbar.Group, { children: _jsx(ToolbarSelect, { icon: AlignIcon, label: strings.toolbar.alignment, width: 138, value: state.elementFormat || 'start', data: alignOptions, renderOption: iconOptionRenderer(ALIGN_ICONS, IconAlignLeft), onMouseDown: snapshotSelection, onChange: withRefocus((v) => formatElement(v)) }) })), indentItems.length > 0 && (_jsx(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: indentItems.map((item) => (_jsx(ToolbarButton, { icon: item.icon, title: item.label, onClick: item.onClick }, item.key))) }))] }, "align"));
806
+ const fontSection = (config.font.family || config.font.size) && (_jsxs(MantineToolbar.Group, { children: [config.font.family && (_jsx(ToolbarSelect, { icon: IconTypography, label: strings.toolbar.fontFamily, width: 150, value: fontOptions.some((f) => f.family === shownFontFamily) ? shownFontFamily : null, placeholder: strings.toolbar.fontFamilyPlaceholder, data: fontData, searchable: true, noMatchMessage: strings.toolbar.noMatch, renderOption: ({ option }) => _jsx("span", { style: { fontFamily: option.value }, children: option.label }), onMouseDown: snapshotSelection, onChange: withRefocus((v) => applyFont('font-family', v)) })), config.font.size && (_jsx(ToolbarSelect, { icon: IconTextSize, label: strings.toolbar.fontSize, width: 84, value: FONT_SIZES_PX.some((px) => `${px}px` === shownFontSize) ? shownFontSize : null, placeholder: strings.toolbar.fontSizePlaceholder, data: FONT_SIZES_PX.map((px) => ({ value: `${px}px`, label: String(px) })), onMouseDown: snapshotSelection, onChange: withRefocus((v) => applyFont('font-size', v)) }))] }, "font"));
759
807
  const insertSection = showInsertGroup && (_jsxs(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: [config.links &&
760
808
  (state.isLink ? (_jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 240, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx(ToolbarButton, { icon: IconLink, title: strings.toolbar.linkOptions, active: true, "aria-haspopup": "menu" }) }), _jsx(Menu.Dropdown, { children: _jsx(LinkMenuItems, { url: state.linkUrl, onEdit: () => {
761
809
  restoreSelection();
@@ -153,6 +153,8 @@ export interface Strings {
153
153
  uncenterCouplet: string;
154
154
  tighterSpacing: string;
155
155
  looserSpacing: string;
156
+ narrowerCenter: string;
157
+ widerCenter: string;
156
158
  narrowerGutter: string;
157
159
  widerGutter: string;
158
160
  deleteCouplet: string;
@@ -1 +1 @@
1
- {"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;+DAC+D;AAC/D,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,cAAc,CAAC;AAElD,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE;QACN,mGAAmG;QACnG,WAAW,EAAE,MAAM,CAAC;QACpB,gDAAgD;QAChD,YAAY,EAAE,MAAM,CAAC;QACrB,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,mDAAmD;QACnD,SAAS,EAAE,MAAM,CAAC;QAClB,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,SAAS,EAAE,MAAM,CAAC;QAClB,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,WAAW,EAAE;QACX,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,eAAe,EAAE,MAAM,CAAC;QACxB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,UAAU,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,eAAe,EAAE,MAAM,CAAC;QACxB,EAAE,EAAE,MAAM,CAAC;QACX,aAAa,EAAE,MAAM,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,MAAM,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QACX,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,YAAY,EAAE;QACZ,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,SAAS,EAAE;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;KACd,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;AA00BD,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAI3C,CAAC;AAEF;;sDAEsD;AACtD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAElD"}
1
+ {"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"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"}
@@ -135,6 +135,8 @@ const en = {
135
135
  uncenterCouplet: 'Un-center this couplet',
136
136
  tighterSpacing: 'Tighter couplet spacing',
137
137
  looserSpacing: 'Looser couplet spacing',
138
+ narrowerCenter: 'Narrower centered couplet',
139
+ widerCenter: 'Wider centered couplet',
138
140
  narrowerGutter: 'Narrower gutter',
139
141
  widerGutter: 'Wider gutter',
140
142
  deleteCouplet: 'Delete couplet',
@@ -413,6 +415,8 @@ const ur = {
413
415
  uncenterCouplet: 'وسط میں رکھنا ختم کریں',
414
416
  tighterSpacing: 'شعروں کے درمیان کم جگہ',
415
417
  looserSpacing: 'شعروں کے درمیان زیادہ جگہ',
418
+ narrowerCenter: 'وسط شعر کی چوڑائی کم',
419
+ widerCenter: 'وسط شعر کی چوڑائی زیادہ',
416
420
  narrowerGutter: 'کالمز کے درمیان کم جگہ',
417
421
  widerGutter: 'کالمز کے درمیان زیادہ جگہ',
418
422
  deleteCouplet: 'شعر حذف کریں',
@@ -691,6 +695,8 @@ const paShahmukhi = {
691
695
  uncenterCouplet: 'وچکار رکھنا بند کرو',
692
696
  tighterSpacing: 'شعراں وچکار گھٹ جگہ',
693
697
  looserSpacing: 'شعراں وچکار ودھ جگہ',
698
+ narrowerCenter: 'وچکار شعر دی چوڑائی گھٹ',
699
+ widerCenter: 'وچکار شعر دی چوڑائی ودھ',
694
700
  narrowerGutter: 'کالماں وچکار گھٹ جگہ',
695
701
  widerGutter: 'کالماں وچکار ودھ جگہ',
696
702
  deleteCouplet: 'شعر مٹاؤ',
@@ -410,6 +410,12 @@
410
410
  .likhari-poetry--stagger-relaxed { --poetry-stagger-width: 75%; }
411
411
  .likhari-poetry--stagger-loose { --poetry-stagger-width: 85%; }
412
412
 
413
+ /* Centered-couplet width (issue #27) — 'normal' keeps the original fixed 60%. */
414
+ .likhari-poetry--center-compact { --poetry-center-width: 45%; }
415
+ .likhari-poetry--center-normal { --poetry-center-width: 60%; }
416
+ .likhari-poetry--center-relaxed { --poetry-center-width: 72%; }
417
+ .likhari-poetry--center-loose { --poetry-center-width: 85%; }
418
+
413
419
  /* Staggered: couplets are the same flat misra paragraphs as single column,
414
420
  but each couplet's two misras are placed in a 65%-wide box that alternates
415
421
  sides — the first couplet pushed to the start edge, the next to the end
@@ -428,6 +434,18 @@
428
434
  margin-inline-start: auto;
429
435
  }
430
436
 
437
+ /* The dashed divider matches this couplet's own box width, not the full
438
+ block (issue #26) — intentional: in an alternating layout, a full-width
439
+ line would cross the empty space the OTHER side's box leaves, reading as
440
+ if it belonged to that empty space rather than marking "this couplet
441
+ ends here". A box-width divider stays visually attached to what it is
442
+ actually separating. Spanning the full block would also need a width
443
+ that reliably escapes this box's own percentage width while still
444
+ landing at each couplet's own vertical offset in the flow — not solvable
445
+ with calc() alone (no percentage-by-percentage division), so it would
446
+ need either per-couplet DOM measurement or a newer CSS container-query
447
+ unit, i.e. the same kind of added browser requirement issue #25 just
448
+ removed. */
431
449
  .likhari-poetry--staggered .likhari-paragraph:nth-child(odd):not(:first-child) {
432
450
  border-top: 1px dashed var(--editor-line-strong);
433
451
  margin-top: var(--poetry-couplet-gap);
@@ -457,9 +475,11 @@
457
475
 
458
476
  /* A centered couplet: a two-column row holding one item (see poetryActions.ts's
459
477
  $setCoupletCentered) — narrowed to the middle of the block, with no column
460
- divider or gutter since there's only one column. */
461
- .likhari-poetry--two-column > .likhari-layout-container:has(> .likhari-layout-item:only-child) {
462
- width: 60%;
478
+ divider or gutter since there's only one column. The row carries this
479
+ itself (LayoutNode.tsx), rather than :has(), which needs Firefox 121+
480
+ (issue #25). Width is the --poetry-center-width scale (issue #27). */
481
+ .likhari-poetry--two-column > .likhari-layout-container[data-likhari-single-column] {
482
+ width: var(--poetry-center-width, 60%);
463
483
  margin-inline: auto;
464
484
  }
465
485
 
@@ -934,6 +954,13 @@
934
954
  text-decoration-skip-ink: none;
935
955
  }
936
956
 
957
+ /* Stands in for the native text selection while a toolbar control (which must
958
+ take focus, e.g. a Select) has it — otherwise the browser clears it the
959
+ moment focus leaves the canvas, making a selection look lost mid-edit. */
960
+ ::highlight(likhari-toolbar-selection) {
961
+ background-color: var(--editor-accent-soft);
962
+ }
963
+
937
964
  .likhari-spell-nav {
938
965
  display: flex;
939
966
  align-items: center;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inshapardaz/likhari-react",
3
- "version": "0.1.33",
3
+ "version": "0.1.35-dev.282",
4
4
  "description": "React implementation of the Likhari editor, built on @lexical/react.",
5
5
  "license": "MIT",
6
6
  "repository": {