@inshapardaz/likhari-react 0.1.18-dev.140 → 0.1.18-dev.144

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAY1D,OAAO,KAAK,EAA8B,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEjF,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAAwB,KAAK,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAKzH,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAMjE,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAYhF,OAAO,EAAgC,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAMnE,yEAAyE;AACzE,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,YAAY,GAAG,KAAK,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAClD;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,KAAK,IAAI,CAAC;IACrD;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC;;;;;;;;;;;;;;;OAeG;IACH,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,uGAAuG;IACvG,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3E,6EAA6E;IAC7E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IACrC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC;IAClD,iBAAiB,IAAI,OAAO,CAAC;IAC7B,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,KAAK,IAAI,IAAI,CAAC;CACf;AAQD,eAAO,MAAM,UAAU,uGAoXrB,CAAC"}
1
+ {"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAY1D,OAAO,KAAK,EAA8B,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEjF,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAAwB,KAAK,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAKzH,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAOjE,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAYhF,OAAO,EAAgC,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAMnE,yEAAyE;AACzE,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,YAAY,GAAG,KAAK,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAClD;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,KAAK,IAAI,CAAC;IACrD;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC;;;;;;;;;;;;;;;OAeG;IACH,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,uGAAuG;IACvG,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3E,6EAA6E;IAC7E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IACrC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC;IAClD,iBAAiB,IAAI,OAAO,CAAC;IAC7B,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,KAAK,IAAI,IAAI,CAAC;CACf;AAQD,eAAO,MAAM,UAAU,uGAqXrB,CAAC"}
@@ -24,6 +24,7 @@ import { PageBreakPlugin } from './plugins/PageBreakPlugin.js';
24
24
  import { LayoutPlugin } from './plugins/LayoutPlugin.js';
25
25
  import { FootnotePlugin } from './plugins/FootnotePlugin.js';
26
26
  import { PoetryPlugin } from './plugins/PoetryPlugin.js';
27
+ import { PoetryResizer } from './blocks/PoetryResizer.js';
27
28
  import { DraftRestore } from './components/DraftRestore.js';
28
29
  import { LeaveDialog } from './components/LeaveDialog.js';
29
30
  import { clearDraft, createDraftId, hasDraftContent, pruneDrafts, writeDraft, } from './persistence/draftStorage.js';
@@ -280,7 +281,7 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, initialCo
280
281
  const portalTargetSelector = `#${CSS.escape(portalTargetId)}`;
281
282
  return (_jsx(EditorThemeProvider, { theme: theme, colorScheme: colorScheme, accentColor: accentColor, scopeElementId: portalTargetId, children: _jsxs("div", { className: "likhari-root", dir: dir, ref: rootElementRef, "data-document-id": documentId, style: { height: typeof height === 'number' ? `${height}px` : height }, children: [_jsx("div", { id: portalTargetId, className: "likhari-portal-target" }), _jsx(PortalTargetContext.Provider, { value: portalTargetSelector, children: _jsxs(UiStringsContext.Provider, { value: strings, children: [_jsx(ImageOptionsContext.Provider, { value: imageOptions, children: _jsxs(LexicalComposer, { initialConfig: initialConfig, children: [_jsx(Toolbar, { config: config, onSave: handleSave, isDirty: isDirty, showSave: showSave, fontOptions: fontOptions, direction: dir, locale: locale, drafts: autosave
282
283
  ? { currentId: draftId, maxBytes: autosaveMaxBytes, adoptOnRestore: !documentId, onRestored: handleDraftRestored }
283
- : undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _jsx("div", { className: "likhari-canvas", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "likhari-content-editable", dir: dir, "aria-label": strings.editor.contentLabel }), placeholder: _jsx("div", { className: "likhari-placeholder", children: resolvedPlaceholder }), ErrorBoundary: LexicalErrorBoundary }) }), config.history && _jsx(HistoryPlugin, {}), (config.lists.bullet || config.lists.numbered || config.lists.check) && _jsx(ListPlugin, {}), config.lists.check && _jsx(CheckListPlugin, {}), config.links && _jsx(LinkPlugin, {}), config.links && _jsx(LinkPastePlugin, {}), config.blocks.pageBreak && _jsx(PageBreakPlugin, {}), config.columns && _jsx(LayoutPlugin, {}), config.footnotes && _jsx(FootnotePlugin, {}), config.poetry.enabled && _jsx(PoetryPlugin, {}), config.tables && _jsx(TablePlugin, { hasCellMerge: true, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(EditorInstancePlugin, { instanceRef: editorInstanceRef }), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
284
+ : undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _jsx("div", { className: "likhari-canvas", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "likhari-content-editable", dir: dir, "aria-label": strings.editor.contentLabel }), placeholder: _jsx("div", { className: "likhari-placeholder", children: resolvedPlaceholder }), ErrorBoundary: LexicalErrorBoundary }) }), config.history && _jsx(HistoryPlugin, {}), (config.lists.bullet || config.lists.numbered || config.lists.check) && _jsx(ListPlugin, {}), config.lists.check && _jsx(CheckListPlugin, {}), config.links && _jsx(LinkPlugin, {}), config.links && _jsx(LinkPastePlugin, {}), config.blocks.pageBreak && _jsx(PageBreakPlugin, {}), config.columns && _jsx(LayoutPlugin, {}), config.footnotes && _jsx(FootnotePlugin, {}), config.poetry.enabled && _jsx(PoetryPlugin, {}), config.poetry.enabled && _jsx(PoetryResizer, {}), config.tables && _jsx(TablePlugin, { hasCellMerge: true, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(EditorInstancePlugin, { instanceRef: editorInstanceRef }), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
284
285
  handleSave();
285
286
  settleLeave(true);
286
287
  }, onSaveDraft: () => {
@@ -4,6 +4,7 @@ export type PoetryAlign = 'justify' | 'left' | 'right' | 'start';
4
4
  export type SerializedPoetryBlockNode = Spread<{
5
5
  layout: PoetryLayout;
6
6
  align: PoetryAlign;
7
+ width?: number;
7
8
  }, SerializedElementNode>;
8
9
  /**
9
10
  * A couplet (two-line verse unit), the one extensible primitive requirements
@@ -18,11 +19,16 @@ export type SerializedPoetryBlockNode = Spread<{
18
19
  export declare class PoetryBlockNode extends ElementNode {
19
20
  __layout: PoetryLayout;
20
21
  __align: PoetryAlign;
21
- constructor(layout?: PoetryLayout, align?: PoetryAlign, key?: NodeKey);
22
+ /** User-chosen width in px (drag-resized), overriding editor.css's default
23
+ * max-width: 70%. Undefined until the user resizes it. */
24
+ __width?: number;
25
+ constructor(layout?: PoetryLayout, align?: PoetryAlign, width?: number, key?: NodeKey);
22
26
  static getType(): string;
23
27
  static clone(node: PoetryBlockNode): PoetryBlockNode;
24
28
  getLayout(): PoetryLayout;
25
29
  getAlign(): PoetryAlign;
30
+ getWidth(): number | undefined;
31
+ setWidth(width: number | undefined): this;
26
32
  /** Attribute-only — restructuring children for a layout change is
27
33
  * poetryActions.ts's $setPoetryLayout, not a node method, since it needs
28
34
  * $-context tree mutations beyond this node's own state. */
@@ -37,6 +43,6 @@ export declare class PoetryBlockNode extends ElementNode {
37
43
  canBeEmpty(): false;
38
44
  isShadowRoot(): boolean;
39
45
  }
40
- export declare function $createPoetryBlockNode(layout?: PoetryLayout, align?: PoetryAlign): PoetryBlockNode;
46
+ export declare function $createPoetryBlockNode(layout?: PoetryLayout, align?: PoetryAlign, width?: number): PoetryBlockNode;
41
47
  export declare function $isPoetryBlockNode(node: LexicalNode | null | undefined): node is PoetryBlockNode;
42
48
  //# sourceMappingURL=PoetryNode.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PoetryNode.d.ts","sourceRoot":"","sources":["../../src/blocks/PoetryNode.tsx"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EACX,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;AACnD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAgBjE,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,EAAE,qBAAqB,CAAC,CAAC;AAEpH;;;;;;;;;GASG;AACH,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,WAAW,CAAC;gBAET,MAAM,GAAE,YAAuB,EAAE,KAAK,GAAE,WAAuB,EAAE,GAAG,CAAC,EAAE,OAAO;IAM1F,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,eAAe;IAIpD,SAAS,IAAI,YAAY;IAIzB,QAAQ,IAAI,WAAW;IAIvB;;gEAE4D;IAC5D,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAM9C,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAMlC,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,yBAAyB,GAAG,eAAe;IAI7E,UAAU,IAAI,yBAAyB;IAIvC,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAa3C,SAAS,IAAI,eAAe;IAQ5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAY5C,SAAS,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO;IAYrF,UAAU,IAAI,KAAK;IAInB,YAAY,IAAI,OAAO;CAGxB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,GAAE,YAAuB,EAAE,KAAK,GAAE,WAAuB,GAAG,eAAe,CAEvH;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,eAAe,CAEhG"}
1
+ {"version":3,"file":"PoetryNode.d.ts","sourceRoot":"","sources":["../../src/blocks/PoetryNode.tsx"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EACX,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;AACnD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAwBjE,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,WAAW,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,qBAAqB,CAAC,CAAC;AAEpI;;;;;;;;;GASG;AACH,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB;8DAC0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;gBAEL,MAAM,GAAE,YAAuB,EAAE,KAAK,GAAE,WAAuB,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO;IAO1G,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,eAAe;IAIpD,SAAS,IAAI,YAAY;IAIzB,QAAQ,IAAI,WAAW;IAIvB,QAAQ,IAAI,MAAM,GAAG,SAAS;IAI9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAMzC;;gEAE4D;IAC5D,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAM9C,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAMlC,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,yBAAyB,GAAG,eAAe;IAI7E,UAAU,IAAI,yBAAyB;IAYvC,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAe3C,SAAS,IAAI,eAAe;IAW5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAa5C,SAAS,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO;IAerF,UAAU,IAAI,KAAK;IAInB,YAAY,IAAI,OAAO;CAGxB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,GAAE,YAAuB,EAAE,KAAK,GAAE,WAAuB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CAEvI;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,eAAe,CAEhG"}
@@ -12,6 +12,15 @@ function applyAlignStyle(element, align) {
12
12
  element.style.textAlign = align;
13
13
  element.style.textAlignLast = align === 'justify' ? 'justify' : '';
14
14
  }
15
+ /** A user-dragged width overrides editor.css's default max-width: 70% —
16
+ * clearing the inline style (rather than setting it to that same 70%)
17
+ * lets the CSS default keep tracking the canvas if it's ever resized. */
18
+ function applyWidthStyle(element, width) {
19
+ if (width === undefined)
20
+ element.style.removeProperty('max-width');
21
+ else
22
+ element.style.maxWidth = `${width}px`;
23
+ }
15
24
  /**
16
25
  * A couplet (two-line verse unit), the one extensible primitive requirements
17
26
  * doc §4.11 recommends in place of four fixed templates. `layout` picks
@@ -23,16 +32,17 @@ function applyAlignStyle(element, align) {
23
32
  * between layouts doesn't lose selection/undo coherence.
24
33
  */
25
34
  export class PoetryBlockNode extends ElementNode {
26
- constructor(layout = 'single', align = 'justify', key) {
35
+ constructor(layout = 'single', align = 'justify', width, key) {
27
36
  super(key);
28
37
  this.__layout = layout;
29
38
  this.__align = align;
39
+ this.__width = width;
30
40
  }
31
41
  static getType() {
32
42
  return 'poetry-couplet';
33
43
  }
34
44
  static clone(node) {
35
- return new PoetryBlockNode(node.__layout, node.__align, node.__key);
45
+ return new PoetryBlockNode(node.__layout, node.__align, node.__width, node.__key);
36
46
  }
37
47
  getLayout() {
38
48
  return this.getLatest().__layout;
@@ -40,6 +50,14 @@ export class PoetryBlockNode extends ElementNode {
40
50
  getAlign() {
41
51
  return this.getLatest().__align;
42
52
  }
53
+ getWidth() {
54
+ return this.getLatest().__width;
55
+ }
56
+ setWidth(width) {
57
+ const writable = this.getWritable();
58
+ writable.__width = width;
59
+ return writable;
60
+ }
43
61
  /** Attribute-only — restructuring children for a layout change is
44
62
  * poetryActions.ts's $setPoetryLayout, not a node method, since it needs
45
63
  * $-context tree mutations beyond this node's own state. */
@@ -54,10 +72,18 @@ export class PoetryBlockNode extends ElementNode {
54
72
  return writable;
55
73
  }
56
74
  static importJSON(serializedNode) {
57
- return $createPoetryBlockNode(serializedNode.layout, serializedNode.align);
75
+ return $createPoetryBlockNode(serializedNode.layout, serializedNode.align, serializedNode.width);
58
76
  }
59
77
  exportJSON() {
60
- return { ...super.exportJSON(), type: 'poetry-couplet', version: 1, layout: this.getLayout(), align: this.getAlign() };
78
+ const width = this.getWidth();
79
+ return {
80
+ ...super.exportJSON(),
81
+ type: 'poetry-couplet',
82
+ version: 1,
83
+ layout: this.getLayout(),
84
+ align: this.getAlign(),
85
+ ...(width !== undefined ? { width } : {}),
86
+ };
61
87
  }
62
88
  static importDOM() {
63
89
  return {
@@ -68,7 +94,9 @@ export class PoetryBlockNode extends ElementNode {
68
94
  const layout = VALID_LAYOUTS.has(rawLayout) ? rawLayout : 'single';
69
95
  const rawAlign = domNode.getAttribute('data-likhari-poetry-align') ?? 'justify';
70
96
  const align = VALID_ALIGNS.has(rawAlign) ? rawAlign : 'justify';
71
- return { conversion: () => ({ node: $createPoetryBlockNode(layout, align) }), priority: 2 };
97
+ const rawWidth = Number(domNode.getAttribute('data-likhari-poetry-width'));
98
+ const width = Number.isFinite(rawWidth) && rawWidth > 0 ? rawWidth : undefined;
99
+ return { conversion: () => ({ node: $createPoetryBlockNode(layout, align, width) }), priority: 2 };
72
100
  },
73
101
  };
74
102
  }
@@ -76,7 +104,11 @@ export class PoetryBlockNode extends ElementNode {
76
104
  const element = document.createElement('div');
77
105
  element.setAttribute('data-likhari-poetry-layout', this.getLayout());
78
106
  element.setAttribute('data-likhari-poetry-align', this.getAlign());
107
+ const width = this.getWidth();
108
+ if (width !== undefined)
109
+ element.setAttribute('data-likhari-poetry-width', String(width));
79
110
  applyAlignStyle(element, this.getAlign());
111
+ applyWidthStyle(element, width);
80
112
  return { element };
81
113
  }
82
114
  createDOM(config) {
@@ -84,6 +116,7 @@ export class PoetryBlockNode extends ElementNode {
84
116
  const base = config.theme.poetry ?? 'likhari-poetry';
85
117
  addClassNamesToElement(element, base, `${base}--${this.__layout}`);
86
118
  applyAlignStyle(element, this.__align);
119
+ applyWidthStyle(element, this.__width);
87
120
  return element;
88
121
  }
89
122
  // Only ever adds/removes the layout modifier class, never touches the
@@ -99,6 +132,9 @@ export class PoetryBlockNode extends ElementNode {
99
132
  if (prevNode.__align !== this.__align) {
100
133
  applyAlignStyle(dom, this.__align);
101
134
  }
135
+ if (prevNode.__width !== this.__width) {
136
+ applyWidthStyle(dom, this.__width);
137
+ }
102
138
  return false;
103
139
  }
104
140
  canBeEmpty() {
@@ -108,8 +144,8 @@ export class PoetryBlockNode extends ElementNode {
108
144
  return true;
109
145
  }
110
146
  }
111
- export function $createPoetryBlockNode(layout = 'single', align = 'justify') {
112
- return $applyNodeReplacement(new PoetryBlockNode(layout, align));
147
+ export function $createPoetryBlockNode(layout = 'single', align = 'justify', width) {
148
+ return $applyNodeReplacement(new PoetryBlockNode(layout, align, width));
113
149
  }
114
150
  export function $isPoetryBlockNode(node) {
115
151
  return node instanceof PoetryBlockNode;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * A floating drag handle over the currently-active poetry couplet's
3
+ * inline-end edge, letting the user resize how wide the block reads on the
4
+ * page — "size it according to the length of the couplet" — rather than
5
+ * being stuck with editor.css's default max-width: 70%. Rendered as a
6
+ * portal into the editor's own portal-target element, never as a child of
7
+ * the couplet's own DOM, so it can't interfere with Lexical's
8
+ * reconciliation of the couplet's real (editable) children.
9
+ */
10
+ export declare function PoetryResizer(): import("react").JSX.Element | null;
11
+ //# sourceMappingURL=PoetryResizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PoetryResizer.d.ts","sourceRoot":"","sources":["../../src/blocks/PoetryResizer.tsx"],"names":[],"mappings":"AAuBA;;;;;;;;GAQG;AACH,wBAAgB,aAAa,uCAqF5B"}
@@ -0,0 +1,94 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { createPortal } from 'react-dom';
4
+ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
5
+ import { $getNodeByKey } from 'lexical';
6
+ import { usePortalTarget } from '../PortalTargetContext.js';
7
+ import { $getPoetryBlockFromSelection } from './poetryActions.js';
8
+ import { $isPoetryBlockNode } from './PoetryNode.js';
9
+ const MIN_WIDTH_PX = 160;
10
+ function measure(el) {
11
+ const box = el.getBoundingClientRect();
12
+ return { top: box.top, left: box.left, width: box.width, height: box.height, rtl: getComputedStyle(el).direction === 'rtl' };
13
+ }
14
+ /**
15
+ * A floating drag handle over the currently-active poetry couplet's
16
+ * inline-end edge, letting the user resize how wide the block reads on the
17
+ * page — "size it according to the length of the couplet" — rather than
18
+ * being stuck with editor.css's default max-width: 70%. Rendered as a
19
+ * portal into the editor's own portal-target element, never as a child of
20
+ * the couplet's own DOM, so it can't interfere with Lexical's
21
+ * reconciliation of the couplet's real (editable) children.
22
+ */
23
+ export function PoetryResizer() {
24
+ const [editor] = useLexicalComposerContext();
25
+ const portalSelector = usePortalTarget();
26
+ const [activeKey, setActiveKey] = useState(null);
27
+ const [box, setBox] = useState(null);
28
+ const dragStart = useRef(null);
29
+ useEffect(() => {
30
+ const recompute = () => {
31
+ if (dragStart.current)
32
+ return; // the pointermove handler owns `box` mid-drag
33
+ editor.getEditorState().read(() => {
34
+ const couplet = $getPoetryBlockFromSelection();
35
+ const el = couplet ? editor.getElementByKey(couplet.getKey()) : null;
36
+ if (!couplet || !el) {
37
+ setActiveKey(null);
38
+ setBox(null);
39
+ return;
40
+ }
41
+ setActiveKey(couplet.getKey());
42
+ setBox(measure(el));
43
+ });
44
+ };
45
+ recompute();
46
+ const unregister = editor.registerUpdateListener(recompute);
47
+ window.addEventListener('resize', recompute);
48
+ window.addEventListener('scroll', recompute, true);
49
+ return () => {
50
+ unregister();
51
+ window.removeEventListener('resize', recompute);
52
+ window.removeEventListener('scroll', recompute, true);
53
+ };
54
+ }, [editor]);
55
+ if (!box || !activeKey)
56
+ return null;
57
+ const onPointerDown = (event) => {
58
+ event.preventDefault();
59
+ event.currentTarget.setPointerCapture(event.pointerId);
60
+ dragStart.current = { x: event.clientX, width: box.width, rtl: box.rtl };
61
+ };
62
+ const onPointerMove = (event) => {
63
+ const start = dragStart.current;
64
+ const el = editor.getElementByKey(activeKey);
65
+ if (!start || !el)
66
+ return;
67
+ const delta = event.clientX - start.x;
68
+ const signedDelta = start.rtl ? -delta : delta;
69
+ const canvasMax = editor.getRootElement()?.clientWidth ?? start.width + signedDelta;
70
+ const width = Math.round(Math.min(Math.max(start.width + signedDelta, MIN_WIDTH_PX), canvasMax));
71
+ // Live visual feedback: the couplet is centered (margin: auto), so
72
+ // resizing it moves both edges — re-measure after mutating rather than
73
+ // computing the new position from the drag delta alone.
74
+ el.style.maxWidth = `${width}px`;
75
+ setBox(measure(el));
76
+ };
77
+ const onPointerUp = () => {
78
+ const start = dragStart.current;
79
+ dragStart.current = null;
80
+ const el = editor.getElementByKey(activeKey);
81
+ const width = el ? Math.round(el.getBoundingClientRect().width) : null;
82
+ if (start && width !== null) {
83
+ editor.update(() => {
84
+ const node = $getNodeByKey(activeKey);
85
+ if ($isPoetryBlockNode(node))
86
+ node.setWidth(width);
87
+ });
88
+ }
89
+ };
90
+ const handleX = box.rtl ? box.left : box.left + box.width;
91
+ const handle = (_jsx("div", { className: "likhari-poetry-resize-handle", style: { position: 'fixed', top: box.top, left: handleX, height: box.height }, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerUp, role: "separator", "aria-orientation": "vertical" }));
92
+ const portalRoot = portalSelector ? document.querySelector(portalSelector) : null;
93
+ return portalRoot ? createPortal(handle, portalRoot) : handle;
94
+ }
@@ -24,6 +24,20 @@ export declare function $ensureTrailingParagraph(node: PoetryBlockNode): void;
24
24
  /** Inserts a new two-misra couplet after the selection's top-level block,
25
25
  * in `layout`/`align`, and focuses its first misra. */
26
26
  export declare function $insertPoetryCouplet(layout: PoetryLayout, align: PoetryAlign): boolean;
27
+ /** Removes the whole couplet the selection is inside, if any — the explicit,
28
+ * always-available counterpart to $deletePoetryOnBackspace's empty-couplet
29
+ * shortcut (mirrors the table menu's own "Delete table" action). */
30
+ export declare function $deletePoetryCouplet(): boolean;
31
+ /**
32
+ * Backspace at the very start of an empty couplet's first misra removes the
33
+ * whole block — the natural keystroke to try first, and otherwise there was
34
+ * no way to get rid of an empty couplet created by mistake (its two misra
35
+ * paragraphs each have their own default canBeEmpty, so Lexical's usual
36
+ * "delete the empty block" handling never reaches the couplet itself).
37
+ * Returns false for every other caret position, including a non-empty
38
+ * couplet, so normal Backspace handling (e.g. deleting within text) proceeds.
39
+ */
40
+ export declare function $deletePoetryOnBackspace(): boolean;
27
41
  /**
28
42
  * Enter at the end of a couplet's last misra would otherwise land inside
29
43
  * ParagraphNode's own insertNewAfter — which inserts the new paragraph as a
@@ -1 +1 @@
1
- {"version":3,"file":"poetryActions.d.ts","sourceRoot":"","sources":["../../src/blocks/poetryActions.ts"],"names":[],"mappings":"AACA,OAAO,EAA4E,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAEvH,OAAO,EAA8C,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAErI;wCACwC;AACxC,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,GAAG,aAAa,EAAE,CAW1E;AAED,oEAAoE;AACpE,wBAAgB,4BAA4B,IAAI,eAAe,GAAG,IAAI,CAKrE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAclF;AAED;;;;;;qDAMqD;AACrD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAEpE;AAED;uDACuD;AACvD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAyBtF;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAuB5C"}
1
+ {"version":3,"file":"poetryActions.d.ts","sourceRoot":"","sources":["../../src/blocks/poetryActions.ts"],"names":[],"mappings":"AACA,OAAO,EAA4F,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAEvI,OAAO,EAA8C,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAErI;wCACwC;AACxC,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,GAAG,aAAa,EAAE,CAW1E;AAED,oEAAoE;AACpE,wBAAgB,4BAA4B,IAAI,eAAe,GAAG,IAAI,CAKrE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAclF;AAED;;;;;;qDAMqD;AACrD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAEpE;AAED;uDACuD;AACvD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAyBtF;AAED;;oEAEoE;AACpE,wBAAgB,oBAAoB,IAAI,OAAO,CAK9C;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAoBlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAuB5C"}
@@ -1,5 +1,5 @@
1
1
  import { $findMatchingParent } from '@lexical/utils';
2
- import { $createParagraphNode, $getSelection, $isParagraphNode, $isRangeSelection } from 'lexical';
2
+ import { $createParagraphNode, $getSelection, $isElementNode, $isParagraphNode, $isRangeSelection } from 'lexical';
3
3
  import { $createLayoutContainerNode, $createLayoutItemNode, $isLayoutContainerNode, $isLayoutItemNode } from './LayoutNode.js';
4
4
  import { $createPoetryBlockNode, $isPoetryBlockNode } from './PoetryNode.js';
5
5
  /** The couplet's two misra paragraphs, in document order, regardless of
@@ -91,6 +91,48 @@ export function $insertPoetryCouplet(layout, align) {
91
91
  misraA.selectStart();
92
92
  return true;
93
93
  }
94
+ /** Removes the whole couplet the selection is inside, if any — the explicit,
95
+ * always-available counterpart to $deletePoetryOnBackspace's empty-couplet
96
+ * shortcut (mirrors the table menu's own "Delete table" action). */
97
+ export function $deletePoetryCouplet() {
98
+ const couplet = $getPoetryBlockFromSelection();
99
+ if (!couplet)
100
+ return false;
101
+ couplet.remove();
102
+ return true;
103
+ }
104
+ /**
105
+ * Backspace at the very start of an empty couplet's first misra removes the
106
+ * whole block — the natural keystroke to try first, and otherwise there was
107
+ * no way to get rid of an empty couplet created by mistake (its two misra
108
+ * paragraphs each have their own default canBeEmpty, so Lexical's usual
109
+ * "delete the empty block" handling never reaches the couplet itself).
110
+ * Returns false for every other caret position, including a non-empty
111
+ * couplet, so normal Backspace handling (e.g. deleting within text) proceeds.
112
+ */
113
+ export function $deletePoetryOnBackspace() {
114
+ const selection = $getSelection();
115
+ if (!$isRangeSelection(selection) || !selection.isCollapsed())
116
+ return false;
117
+ const couplet = $getPoetryBlockFromSelection();
118
+ if (!couplet)
119
+ return false;
120
+ const misras = $getMisraParagraphs(couplet);
121
+ const firstMisra = misras[0];
122
+ if (!firstMisra)
123
+ return false;
124
+ if (misras.some((m) => !m.isEmpty()))
125
+ return false;
126
+ const anchor = selection.anchor;
127
+ const isAtStart = anchor.key === firstMisra.getKey() && anchor.offset === 0;
128
+ if (!isAtStart)
129
+ return false;
130
+ const previous = couplet.getPreviousSibling();
131
+ couplet.remove();
132
+ if ($isElementNode(previous))
133
+ previous.selectEnd();
134
+ return true;
135
+ }
94
136
  /**
95
137
  * Enter at the end of a couplet's last misra would otherwise land inside
96
138
  * ParagraphNode's own insertNewAfter — which inserts the new paragraph as a
@@ -1 +1 @@
1
- {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AAiEA,OAAO,EAAgB,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAA6D,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAItG,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,iBAAiB,CAAC;AAwevD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,2BAA2B,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sEAAsE;IACtE,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,wFAAwF;IACxF,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAkC,EAAE,SAAiB,EAAE,MAAa,EAAE,MAAM,EAAE,EAAE,YAAY,+BAugCxJ"}
1
+ {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AAiEA,OAAO,EAAgB,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAA6D,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAItG,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,iBAAiB,CAAC;AA4evD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,2BAA2B,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sEAAsE;IACtE,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,wFAAwF;IACxF,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAkC,EAAE,SAAiB,EAAE,MAAa,EAAE,MAAM,EAAE,EAAE,YAAY,+BAugCxJ"}
@@ -14,7 +14,7 @@ import { $createImageNode } from '../image/ImageNode.js';
14
14
  import { INSERT_PAGE_BREAK_COMMAND } from '../blocks/PageBreakNode.js';
15
15
  import { INSERT_LAYOUT_COMMAND } from '../blocks/LayoutNode.js';
16
16
  import { INSERT_FOOTNOTE_COMMAND } from '../blocks/FootnoteNode.js';
17
- import { $getPoetryBlockFromSelection, $setPoetryLayout } from '../blocks/poetryActions.js';
17
+ import { $deletePoetryCouplet, $getPoetryBlockFromSelection, $setPoetryLayout } from '../blocks/poetryActions.js';
18
18
  import { INSERT_POETRY_COUPLET_COMMAND } from '../plugins/PoetryPlugin.js';
19
19
  import { TableDialog } from './TableDialog.js';
20
20
  import { LayoutDialog } from './LayoutDialog.js';
@@ -28,7 +28,7 @@ import { CANVAS_FONT_DEFAULTS, DEFAULT_FONT_OPTIONS, FONT_SIZES_PX } from '../fo
28
28
  import { setStyleProperty } from '../utils/style.js';
29
29
  import { useStrings } from '../i18n/useStrings.js';
30
30
  import { usePortalTarget } from '../PortalTargetContext.js';
31
- import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconBold, IconClearFormatting, IconDeviceFloppy, IconDots, IconHistory, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPageBreak, IconPencil, IconPhoto, IconPilcrow, IconQuote, IconSeparatorHorizontal, IconSparkles, IconStrikethrough, IconSubscript, IconSuperscript, IconArrowMergeBoth, IconArrowsSplit2, IconColumnInsertLeft, IconColumnInsertRight, IconColumnRemove, IconColumns, IconColumns1, IconColumns2, IconNumber1Small, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconTable, IconTableMinus, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
31
+ import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconBold, IconClearFormatting, IconDeviceFloppy, IconDots, IconHistory, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPageBreak, IconPencil, IconPhoto, IconPilcrow, IconQuote, IconSeparatorHorizontal, IconSparkles, IconStrikethrough, IconSubscript, IconSuperscript, IconArrowMergeBoth, IconArrowsSplit2, IconColumnInsertLeft, IconColumnInsertRight, IconColumnRemove, IconColumns, IconColumns1, IconColumns2, IconNumber1Small, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconTable, IconTableMinus, IconTrash, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
32
32
  /** Sentinel for "no inline style": Lexical returns the default it is given when
33
33
  * the selection has none, so this tells "unstyled" (show the canvas default)
34
34
  * apart from "styled with a value the dropdown doesn't list" (show nothing). */
@@ -167,9 +167,9 @@ function TableMenuItems({ strings, direction, rows, columns, canMergeCells, canU
167
167
  function PoetryMenuItems({ strings, alignIcons, layout, align, onAction, }) {
168
168
  const t = strings.poetryMenu;
169
169
  const a = strings.toolbar.alignOptions;
170
- const item = (icon, label, action, active) => {
170
+ const item = (icon, label, action, active = false, color) => {
171
171
  const Icon = icon;
172
- return (_jsx(Menu.Item, { disabled: active, leftSection: _jsx(Icon, { size: ICON_SIZE, stroke: ICON_STROKE }), onMouseDown: (e) => e.preventDefault(), onClick: onAction(action), children: label }));
172
+ return (_jsx(Menu.Item, { color: color, disabled: active, leftSection: _jsx(Icon, { size: ICON_SIZE, stroke: ICON_STROKE }), onMouseDown: (e) => e.preventDefault(), onClick: onAction(action), children: label }));
173
173
  };
174
174
  const setLayout = (next) => () => {
175
175
  const node = $getPoetryBlockFromSelection();
@@ -179,7 +179,7 @@ function PoetryMenuItems({ strings, alignIcons, layout, align, onAction, }) {
179
179
  const setAlign = (next) => () => {
180
180
  $getPoetryBlockFromSelection()?.setAlign(next);
181
181
  };
182
- return (_jsxs(_Fragment, { children: [_jsx(Menu.Label, { children: t.menuLabel }), item(IconColumns1, t.singleColumn, setLayout('single'), layout === 'single'), item(IconColumns2, t.twoColumn, setLayout('two-column'), layout === 'two-column'), _jsx(Menu.Divider, {}), item(alignIcons.justify ?? IconAlignJustified, a.justify, setAlign('justify'), align === 'justify'), item(alignIcons.start ?? IconAlignLeft, a.start, setAlign('start'), align === 'start'), item(IconAlignLeft, a.left, setAlign('left'), align === 'left'), item(IconAlignRight, a.right, setAlign('right'), align === 'right')] }));
182
+ return (_jsxs(_Fragment, { children: [_jsx(Menu.Label, { children: t.menuLabel }), item(IconColumns1, t.singleColumn, setLayout('single'), layout === 'single'), item(IconColumns2, t.twoColumn, setLayout('two-column'), layout === 'two-column'), _jsx(Menu.Divider, {}), item(alignIcons.justify ?? IconAlignJustified, a.justify, setAlign('justify'), align === 'justify'), item(alignIcons.start ?? IconAlignLeft, a.start, setAlign('start'), align === 'start'), item(IconAlignLeft, a.left, setAlign('left'), align === 'left'), item(IconAlignRight, a.right, setAlign('right'), align === 'right'), _jsx(Menu.Divider, {}), item(IconTrash, t.deleteCouplet, $deletePoetryCouplet, false, 'red')] }));
183
183
  }
184
184
  export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
185
185
  const [editor] = useLexicalComposerContext();
@@ -142,6 +142,7 @@ export interface Strings {
142
142
  menuLabel: string;
143
143
  singleColumn: string;
144
144
  twoColumn: string;
145
+ deleteCouplet: string;
145
146
  };
146
147
  link: {
147
148
  menuLabel: string;
@@ -1 +1 @@
1
- {"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"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"}
@@ -125,6 +125,7 @@ const en = {
125
125
  menuLabel: 'Poetry',
126
126
  singleColumn: 'Single column',
127
127
  twoColumn: 'Two column',
128
+ deleteCouplet: 'Delete couplet',
128
129
  },
129
130
  link: {
130
131
  menuLabel: 'Link',
@@ -332,6 +333,7 @@ const ur = {
332
333
  menuLabel: 'شاعری',
333
334
  singleColumn: 'ایک کالم',
334
335
  twoColumn: 'دو کالم',
336
+ deleteCouplet: 'شعر حذف کریں',
335
337
  },
336
338
  link: {
337
339
  menuLabel: 'لنک',
@@ -539,6 +541,7 @@ const paShahmukhi = {
539
541
  menuLabel: 'شاعری',
540
542
  singleColumn: 'اک کالم',
541
543
  twoColumn: 'دو کالم',
544
+ deleteCouplet: 'شعر مٹاؤ',
542
545
  },
543
546
  link: {
544
547
  menuLabel: 'لنک',
@@ -8,10 +8,13 @@ export declare const INSERT_POETRY_COUPLET_COMMAND: LexicalCommand<{
8
8
  * Registers INSERT_POETRY_COUPLET_COMMAND (mirrors LayoutPlugin/FootnotePlugin's
9
9
  * shape); a node transform that removes a couplet left with no misra
10
10
  * content (e.g. after undo/paste leaves it structurally empty) and keeps a
11
- * trailing couplet always followed by an editable paragraph; and a
11
+ * trailing couplet always followed by an editable paragraph; a
12
12
  * KEY_ENTER_COMMAND handler (above RichTextPlugin's own, which would
13
13
  * otherwise trap Enter inside the couplet — see poetryActions.ts) that lets
14
- * Enter at the end of the last misra add a paragraph after the block.
14
+ * Enter at the end of the last misra add a paragraph after the block; and a
15
+ * KEY_BACKSPACE_COMMAND handler that removes an empty couplet entirely when
16
+ * Backspace is pressed at its very start (the explicit "Delete couplet"
17
+ * menu action in Toolbar.tsx covers removing a non-empty one).
15
18
  */
16
19
  export declare function PoetryPlugin(): null;
17
20
  //# sourceMappingURL=PoetryPlugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PoetryPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/PoetryPlugin.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAoF,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAGhI,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;;;;;;;;GAQG;AACH,wBAAgB,YAAY,SAmC3B"}
1
+ {"version":3,"file":"PoetryPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/PoetryPlugin.tsx"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAmB,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAG5F,eAAO,MAAM,6BAA6B,EAAE,cAAc,CAAC;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAEtG,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,SA4C3B"}
@@ -1,19 +1,22 @@
1
1
  import { useEffect } from 'react';
2
2
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
3
- import { COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_HIGH, KEY_ENTER_COMMAND, createCommand } from 'lexical';
3
+ import { COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_HIGH, KEY_BACKSPACE_COMMAND, KEY_ENTER_COMMAND, createCommand, } from 'lexical';
4
4
  import { mergeRegister } from '@lexical/utils';
5
5
  import { LayoutContainerNode, LayoutItemNode } from '../blocks/LayoutNode.js';
6
6
  import { PoetryBlockNode } from '../blocks/PoetryNode.js';
7
- import { $ensureTrailingParagraph, $exitPoetryOnEnter, $insertPoetryCouplet } from '../blocks/poetryActions.js';
7
+ import { $deletePoetryOnBackspace, $ensureTrailingParagraph, $exitPoetryOnEnter, $insertPoetryCouplet } from '../blocks/poetryActions.js';
8
8
  export const INSERT_POETRY_COUPLET_COMMAND = createCommand('INSERT_POETRY_COUPLET_COMMAND');
9
9
  /**
10
10
  * Registers INSERT_POETRY_COUPLET_COMMAND (mirrors LayoutPlugin/FootnotePlugin's
11
11
  * shape); a node transform that removes a couplet left with no misra
12
12
  * content (e.g. after undo/paste leaves it structurally empty) and keeps a
13
- * trailing couplet always followed by an editable paragraph; and a
13
+ * trailing couplet always followed by an editable paragraph; a
14
14
  * KEY_ENTER_COMMAND handler (above RichTextPlugin's own, which would
15
15
  * otherwise trap Enter inside the couplet — see poetryActions.ts) that lets
16
- * Enter at the end of the last misra add a paragraph after the block.
16
+ * Enter at the end of the last misra add a paragraph after the block; and a
17
+ * KEY_BACKSPACE_COMMAND handler that removes an empty couplet entirely when
18
+ * Backspace is pressed at its very start (the explicit "Delete couplet"
19
+ * menu action in Toolbar.tsx covers removing a non-empty one).
17
20
  */
18
21
  export function PoetryPlugin() {
19
22
  const [editor] = useLexicalComposerContext();
@@ -34,6 +37,11 @@ export function PoetryPlugin() {
34
37
  if (handled)
35
38
  event?.preventDefault();
36
39
  return handled;
40
+ }, COMMAND_PRIORITY_HIGH), editor.registerCommand(KEY_BACKSPACE_COMMAND, (event) => {
41
+ const handled = $deletePoetryOnBackspace();
42
+ if (handled)
43
+ event?.preventDefault();
44
+ return handled;
37
45
  }, COMMAND_PRIORITY_HIGH));
38
46
  }, [editor]);
39
47
  return null;
@@ -406,18 +406,55 @@
406
406
 
407
407
  .likhari-poetry--two-column .likhari-layout-container {
408
408
  margin: 0;
409
- gap: 40px;
409
+ /* No grid gap — the divider below sits exactly on the track boundary, so
410
+ spacing instead comes from matching padding on each side of it, which
411
+ keeps the gutter visually even on both sides of the line. */
412
+ gap: 0;
410
413
  }
411
414
 
412
415
  .likhari-poetry--two-column .likhari-layout-item {
413
416
  text-align: inherit;
414
417
  }
415
418
 
419
+ .likhari-poetry--two-column .likhari-layout-item:first-child {
420
+ padding-inline-end: 20px;
421
+ }
422
+
416
423
  /* A visible divider between misra columns, same dashed language as the
417
424
  couplet's own border — matches a table's internal cell borders. */
418
425
  .likhari-poetry--two-column .likhari-layout-item:not(:first-child) {
419
426
  border-inline-start: 1px dashed var(--editor-line-strong);
420
- padding-inline-start: 24px;
427
+ padding-inline-start: 20px;
428
+ }
429
+
430
+ /* PoetryResizer.tsx's drag handle — portaled to a fixed position over the
431
+ active couplet's inline-end edge, so top/left are set inline per drag. */
432
+ .likhari-poetry-resize-handle {
433
+ position: fixed;
434
+ width: 10px;
435
+ /* Physical, not logical: PoetryResizer.tsx already computes `left` as the
436
+ couplet's actual edge in viewport coordinates for either direction, so
437
+ centering the handle on it must stay physical too. */
438
+ margin-left: -5px;
439
+ cursor: ew-resize;
440
+ touch-action: none;
441
+ z-index: 20;
442
+ }
443
+
444
+ .likhari-poetry-resize-handle::before {
445
+ content: '';
446
+ display: block;
447
+ width: 3px;
448
+ height: 100%;
449
+ margin-inline: auto;
450
+ border-radius: 2px;
451
+ background: var(--editor-accent);
452
+ opacity: 0;
453
+ transition: opacity 0.1s ease;
454
+ }
455
+
456
+ .likhari-poetry-resize-handle:hover::before {
457
+ opacity: 0.6;
421
458
  }
422
459
 
423
460
  .likhari-table {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inshapardaz/likhari-react",
3
- "version": "0.1.18-dev.140",
3
+ "version": "0.1.18-dev.144",
4
4
  "description": "React implementation of the Likhari editor, built on @lexical/react.",
5
5
  "license": "MIT",
6
6
  "repository": {