@inshapardaz/likhari-react 0.1.16 → 0.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/EditorRoot.d.ts.map +1 -1
- package/dist/EditorRoot.js +2 -1
- package/dist/blocks/FootnoteListNode.d.ts +46 -0
- package/dist/blocks/FootnoteListNode.d.ts.map +1 -0
- package/dist/blocks/FootnoteListNode.js +117 -0
- package/dist/blocks/FootnoteNode.d.ts +38 -0
- package/dist/blocks/FootnoteNode.d.ts.map +1 -0
- package/dist/blocks/FootnoteNode.js +90 -0
- package/dist/blocks/footnoteActions.d.ts +9 -0
- package/dist/blocks/footnoteActions.d.ts.map +1 -0
- package/dist/blocks/footnoteActions.js +42 -0
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/Toolbar.js +4 -2
- package/dist/i18n/strings.d.ts +1 -0
- package/dist/i18n/strings.d.ts.map +1 -1
- package/dist/i18n/strings.js +3 -0
- package/dist/nodes.d.ts.map +1 -1
- package/dist/nodes.js +5 -0
- package/dist/plugins/FootnotePlugin.d.ts +9 -0
- package/dist/plugins/FootnotePlugin.d.ts.map +1 -0
- package/dist/plugins/FootnotePlugin.js +51 -0
- package/dist/theme/editor.css +39 -0
- package/dist/theme/editorTheme.d.ts.map +1 -1
- package/dist/theme/editorTheme.js +3 -0
- package/package.json +1 -1
package/dist/EditorRoot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAY1D,OAAO,KAAK,EAA8B,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEjF,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAAwB,KAAK,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAKzH,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAY1D,OAAO,KAAK,EAA8B,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEjF,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAAwB,KAAK,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAKzH,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAKjE,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,uGAmXrB,CAAC"}
|
package/dist/EditorRoot.js
CHANGED
|
@@ -22,6 +22,7 @@ import { injectUrduWebFontsCss } from './fonts/index.js';
|
|
|
22
22
|
import { LinkPastePlugin } from './plugins/LinkPastePlugin.js';
|
|
23
23
|
import { PageBreakPlugin } from './plugins/PageBreakPlugin.js';
|
|
24
24
|
import { LayoutPlugin } from './plugins/LayoutPlugin.js';
|
|
25
|
+
import { FootnotePlugin } from './plugins/FootnotePlugin.js';
|
|
25
26
|
import { DraftRestore } from './components/DraftRestore.js';
|
|
26
27
|
import { LeaveDialog } from './components/LeaveDialog.js';
|
|
27
28
|
import { clearDraft, createDraftId, hasDraftContent, pruneDrafts, writeDraft, } from './persistence/draftStorage.js';
|
|
@@ -278,7 +279,7 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, initialCo
|
|
|
278
279
|
const portalTargetSelector = `#${CSS.escape(portalTargetId)}`;
|
|
279
280
|
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
|
|
280
281
|
? { currentId: draftId, maxBytes: autosaveMaxBytes, adoptOnRestore: !documentId, onRestored: handleDraftRestored }
|
|
281
|
-
: undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _jsx("div", { className: "likhari-canvas", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "likhari-content-editable", dir: dir, "aria-label": strings.editor.contentLabel }), placeholder: _jsx("div", { className: "likhari-placeholder", children: resolvedPlaceholder }), ErrorBoundary: LexicalErrorBoundary }) }), config.history && _jsx(HistoryPlugin, {}), (config.lists.bullet || config.lists.numbered || config.lists.check) && _jsx(ListPlugin, {}), config.lists.check && _jsx(CheckListPlugin, {}), config.links && _jsx(LinkPlugin, {}), config.links && _jsx(LinkPastePlugin, {}), config.blocks.pageBreak && _jsx(PageBreakPlugin, {}), config.columns && _jsx(LayoutPlugin, {}), config.tables && _jsx(TablePlugin, { hasCellMerge: true, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(EditorInstancePlugin, { instanceRef: editorInstanceRef }), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
|
|
282
|
+
: 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.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: () => {
|
|
282
283
|
handleSave();
|
|
283
284
|
settleLeave(true);
|
|
284
285
|
}, onSaveDraft: () => {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type DOMConversionMap, type DOMExportOutput, type EditorConfig, type LexicalNode, type NodeKey, type SerializedElementNode, type Spread, ElementNode } from 'lexical';
|
|
2
|
+
export type SerializedFootnoteListNode = SerializedElementNode;
|
|
3
|
+
export type SerializedFootnoteItemNode = Spread<{
|
|
4
|
+
footnoteId: string;
|
|
5
|
+
}, SerializedElementNode>;
|
|
6
|
+
/** The document's single footnote list, rendered at the end (requirements
|
|
7
|
+
* doc §4.10). An ordered-list-like container of FootnoteItemNode; its items'
|
|
8
|
+
* displayed numbers are a CSS counter (editor.css), same mechanism as
|
|
9
|
+
* FootnoteReferenceNode, so both sequences stay in sync as long as items
|
|
10
|
+
* are appended in the same order their references were inserted — which
|
|
11
|
+
* FootnotePlugin's insert command always does. */
|
|
12
|
+
export declare class FootnoteListNode extends ElementNode {
|
|
13
|
+
static getType(): string;
|
|
14
|
+
static clone(node: FootnoteListNode): FootnoteListNode;
|
|
15
|
+
static importJSON(): FootnoteListNode;
|
|
16
|
+
exportJSON(): SerializedFootnoteListNode;
|
|
17
|
+
static importDOM(): DOMConversionMap | null;
|
|
18
|
+
exportDOM(): DOMExportOutput;
|
|
19
|
+
createDOM(config: EditorConfig): HTMLElement;
|
|
20
|
+
updateDOM(): boolean;
|
|
21
|
+
isShadowRoot(): boolean;
|
|
22
|
+
insertNewAfter(): null;
|
|
23
|
+
}
|
|
24
|
+
export declare function $createFootnoteListNode(): FootnoteListNode;
|
|
25
|
+
export declare function $isFootnoteListNode(node: LexicalNode | null | undefined): node is FootnoteListNode;
|
|
26
|
+
/** One entry in the FootnoteListNode — the editable note text for a given
|
|
27
|
+
* footnoteId. Always keeps at least an empty paragraph (mirrors
|
|
28
|
+
* TableCellNode/LayoutItemNode). */
|
|
29
|
+
export declare class FootnoteItemNode extends ElementNode {
|
|
30
|
+
__footnoteId: string;
|
|
31
|
+
constructor(footnoteId: string, key?: NodeKey);
|
|
32
|
+
static getType(): string;
|
|
33
|
+
static clone(node: FootnoteItemNode): FootnoteItemNode;
|
|
34
|
+
getFootnoteId(): string;
|
|
35
|
+
static importJSON(serializedNode: SerializedFootnoteItemNode): FootnoteItemNode;
|
|
36
|
+
exportJSON(): SerializedFootnoteItemNode;
|
|
37
|
+
static importDOM(): DOMConversionMap | null;
|
|
38
|
+
exportDOM(): DOMExportOutput;
|
|
39
|
+
createDOM(config: EditorConfig): HTMLElement;
|
|
40
|
+
updateDOM(): boolean;
|
|
41
|
+
canBeEmpty(): false;
|
|
42
|
+
canIndent(): false;
|
|
43
|
+
}
|
|
44
|
+
export declare function $createFootnoteItemNode(footnoteId: string): FootnoteItemNode;
|
|
45
|
+
export declare function $isFootnoteItemNode(node: LexicalNode | null | undefined): node is FootnoteItemNode;
|
|
46
|
+
//# sourceMappingURL=FootnoteListNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FootnoteListNode.d.ts","sourceRoot":"","sources":["../../src/blocks/FootnoteListNode.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,0BAA0B,GAAG,qBAAqB,CAAC;AAC/D,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,EAAE,qBAAqB,CAAC,CAAC;AAE/F;;;;;kDAKkD;AAClD,qBAAa,gBAAiB,SAAQ,WAAW;IAC/C,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,gBAAgB,GAAG,gBAAgB;IAItD,MAAM,CAAC,UAAU,IAAI,gBAAgB;IAIrC,UAAU,IAAI,0BAA0B;IAIxC,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAS3C,SAAS,IAAI,eAAe;IAM5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAM5C,SAAS,IAAI,OAAO;IAIpB,YAAY,IAAI,OAAO;IAIvB,cAAc,IAAI,IAAI;CAGvB;AAED,wBAAgB,uBAAuB,IAAI,gBAAgB,CAE1D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,gBAAgB,CAElG;AAED;;oCAEoC;AACpC,qBAAa,gBAAiB,SAAQ,WAAW;IAC/C,YAAY,EAAE,MAAM,CAAC;gBAET,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO;IAK7C,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,gBAAgB,GAAG,gBAAgB;IAItD,aAAa,IAAI,MAAM;IAIvB,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,0BAA0B,GAAG,gBAAgB;IAI/E,UAAU,IAAI,0BAA0B;IAIxC,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAU3C,SAAS,IAAI,eAAe;IAO5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAO5C,SAAS,IAAI,OAAO;IAIpB,UAAU,IAAI,KAAK;IAInB,SAAS,IAAI,KAAK;CAGnB;AAED,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,CAE5E;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,gBAAgB,CAElG"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { addClassNamesToElement } from '@lexical/utils';
|
|
2
|
+
import { $applyNodeReplacement, ElementNode, } from 'lexical';
|
|
3
|
+
/** The document's single footnote list, rendered at the end (requirements
|
|
4
|
+
* doc §4.10). An ordered-list-like container of FootnoteItemNode; its items'
|
|
5
|
+
* displayed numbers are a CSS counter (editor.css), same mechanism as
|
|
6
|
+
* FootnoteReferenceNode, so both sequences stay in sync as long as items
|
|
7
|
+
* are appended in the same order their references were inserted — which
|
|
8
|
+
* FootnotePlugin's insert command always does. */
|
|
9
|
+
export class FootnoteListNode extends ElementNode {
|
|
10
|
+
static getType() {
|
|
11
|
+
return 'footnote-list';
|
|
12
|
+
}
|
|
13
|
+
static clone(node) {
|
|
14
|
+
return new FootnoteListNode(node.__key);
|
|
15
|
+
}
|
|
16
|
+
static importJSON() {
|
|
17
|
+
return $createFootnoteListNode();
|
|
18
|
+
}
|
|
19
|
+
exportJSON() {
|
|
20
|
+
return { ...super.exportJSON(), type: 'footnote-list', version: 1 };
|
|
21
|
+
}
|
|
22
|
+
static importDOM() {
|
|
23
|
+
return {
|
|
24
|
+
ol: (domNode) => {
|
|
25
|
+
if (!domNode.hasAttribute('data-likhari-footnote-list'))
|
|
26
|
+
return null;
|
|
27
|
+
return { conversion: () => ({ node: $createFootnoteListNode() }), priority: 2 };
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
exportDOM() {
|
|
32
|
+
const element = document.createElement('ol');
|
|
33
|
+
element.setAttribute('data-likhari-footnote-list', '');
|
|
34
|
+
return { element };
|
|
35
|
+
}
|
|
36
|
+
createDOM(config) {
|
|
37
|
+
const element = document.createElement('ol');
|
|
38
|
+
addClassNamesToElement(element, config.theme.footnoteList ?? 'likhari-footnote-list');
|
|
39
|
+
return element;
|
|
40
|
+
}
|
|
41
|
+
updateDOM() {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
isShadowRoot() {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
insertNewAfter() {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export function $createFootnoteListNode() {
|
|
52
|
+
return $applyNodeReplacement(new FootnoteListNode());
|
|
53
|
+
}
|
|
54
|
+
export function $isFootnoteListNode(node) {
|
|
55
|
+
return node instanceof FootnoteListNode;
|
|
56
|
+
}
|
|
57
|
+
/** One entry in the FootnoteListNode — the editable note text for a given
|
|
58
|
+
* footnoteId. Always keeps at least an empty paragraph (mirrors
|
|
59
|
+
* TableCellNode/LayoutItemNode). */
|
|
60
|
+
export class FootnoteItemNode extends ElementNode {
|
|
61
|
+
constructor(footnoteId, key) {
|
|
62
|
+
super(key);
|
|
63
|
+
this.__footnoteId = footnoteId;
|
|
64
|
+
}
|
|
65
|
+
static getType() {
|
|
66
|
+
return 'footnote-item';
|
|
67
|
+
}
|
|
68
|
+
static clone(node) {
|
|
69
|
+
return new FootnoteItemNode(node.__footnoteId, node.__key);
|
|
70
|
+
}
|
|
71
|
+
getFootnoteId() {
|
|
72
|
+
return this.getLatest().__footnoteId;
|
|
73
|
+
}
|
|
74
|
+
static importJSON(serializedNode) {
|
|
75
|
+
return $createFootnoteItemNode(serializedNode.footnoteId);
|
|
76
|
+
}
|
|
77
|
+
exportJSON() {
|
|
78
|
+
return { ...super.exportJSON(), type: 'footnote-item', version: 1, footnoteId: this.getFootnoteId() };
|
|
79
|
+
}
|
|
80
|
+
static importDOM() {
|
|
81
|
+
return {
|
|
82
|
+
li: (domNode) => {
|
|
83
|
+
const id = domNode.getAttribute('data-likhari-footnote-item');
|
|
84
|
+
if (!id)
|
|
85
|
+
return null;
|
|
86
|
+
return { conversion: () => ({ node: $createFootnoteItemNode(id) }), priority: 2 };
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
exportDOM() {
|
|
91
|
+
const element = document.createElement('li');
|
|
92
|
+
element.setAttribute('id', `fn-${this.getFootnoteId()}`);
|
|
93
|
+
element.setAttribute('data-likhari-footnote-item', this.getFootnoteId());
|
|
94
|
+
return { element };
|
|
95
|
+
}
|
|
96
|
+
createDOM(config) {
|
|
97
|
+
const element = document.createElement('li');
|
|
98
|
+
addClassNamesToElement(element, config.theme.footnoteItem ?? 'likhari-footnote-item');
|
|
99
|
+
element.id = `fn-${this.getFootnoteId()}`;
|
|
100
|
+
return element;
|
|
101
|
+
}
|
|
102
|
+
updateDOM() {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
canBeEmpty() {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
canIndent() {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export function $createFootnoteItemNode(footnoteId) {
|
|
113
|
+
return $applyNodeReplacement(new FootnoteItemNode(footnoteId));
|
|
114
|
+
}
|
|
115
|
+
export function $isFootnoteItemNode(node) {
|
|
116
|
+
return node instanceof FootnoteItemNode;
|
|
117
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import { DecoratorNode, type DOMConversionMap, type DOMExportOutput, type EditorConfig, type EditorState, type LexicalCommand, type LexicalNode, type NodeKey, type SerializedLexicalNode, type Spread } from 'lexical';
|
|
3
|
+
export declare const INSERT_FOOTNOTE_COMMAND: LexicalCommand<void>;
|
|
4
|
+
export type SerializedFootnoteReferenceNode = Spread<{
|
|
5
|
+
footnoteId: string;
|
|
6
|
+
}, SerializedLexicalNode>;
|
|
7
|
+
/** Inline marker in the text flow (requirements doc §4.10, architecture doc
|
|
8
|
+
* §3.3). Holds only an id — its displayed number is never stored, it's
|
|
9
|
+
* rendered by a CSS counter (editor.css) that counts these markers in DOM
|
|
10
|
+
* order, so insert/delete/reorder auto-renumbers with no JS bookkeeping.
|
|
11
|
+
* The note's actual content lives in a matching FootnoteItemNode inside the
|
|
12
|
+
* document's single FootnoteListNode, not here (same split as Lexical's own
|
|
13
|
+
* comments/annotations pattern: reference in the flow, content out-of-band). */
|
|
14
|
+
export declare class FootnoteReferenceNode extends DecoratorNode<ReactElement> {
|
|
15
|
+
__footnoteId: string;
|
|
16
|
+
constructor(footnoteId: string, key?: NodeKey);
|
|
17
|
+
static getType(): string;
|
|
18
|
+
static clone(node: FootnoteReferenceNode): FootnoteReferenceNode;
|
|
19
|
+
getFootnoteId(): string;
|
|
20
|
+
static importJSON(serializedNode: SerializedFootnoteReferenceNode): FootnoteReferenceNode;
|
|
21
|
+
exportJSON(): SerializedFootnoteReferenceNode;
|
|
22
|
+
static importDOM(): DOMConversionMap | null;
|
|
23
|
+
exportDOM(): DOMExportOutput;
|
|
24
|
+
createDOM(config: EditorConfig): HTMLElement;
|
|
25
|
+
updateDOM(): boolean;
|
|
26
|
+
getTextContent(): string;
|
|
27
|
+
isInline(): true;
|
|
28
|
+
decorate(): ReactElement;
|
|
29
|
+
}
|
|
30
|
+
export declare function $createFootnoteReferenceNode(footnoteId: string): FootnoteReferenceNode;
|
|
31
|
+
export declare function $isFootnoteReferenceNode(node: LexicalNode | null | undefined): node is FootnoteReferenceNode;
|
|
32
|
+
/** Resolves a reference's footnoteId from the editor state just before its
|
|
33
|
+
* deletion committed — a mutation listener's 'destroyed' entries only carry
|
|
34
|
+
* the NodeKey, and by the time the listener fires the *current* state no
|
|
35
|
+
* longer has the node, so the caller must pass the listener's own
|
|
36
|
+
* `prevEditorState` here to know which FootnoteItemNode to clean up. */
|
|
37
|
+
export declare function $getFootnoteIdByKey(prevEditorState: EditorState, key: NodeKey): string | null;
|
|
38
|
+
//# sourceMappingURL=FootnoteNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FootnoteNode.d.ts","sourceRoot":"","sources":["../../src/blocks/FootnoteNode.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAIL,aAAa,EAEb,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EACZ,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,uBAAuB,EAAE,cAAc,CAAC,IAAI,CAA4C,CAAC;AAEtG,MAAM,MAAM,+BAA+B,GAAG,MAAM,CAAC;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,EAAE,qBAAqB,CAAC,CAAC;AAEpG;;;;;;gFAMgF;AAChF,qBAAa,qBAAsB,SAAQ,aAAa,CAAC,YAAY,CAAC;IACpE,YAAY,EAAE,MAAM,CAAC;gBAET,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO;IAK7C,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,qBAAqB,GAAG,qBAAqB;IAIhE,aAAa,IAAI,MAAM;IAIvB,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,+BAA+B,GAAG,qBAAqB;IAIzF,UAAU,IAAI,+BAA+B;IAI7C,MAAM,CAAC,SAAS,IAAI,gBAAgB,GAAG,IAAI;IAU3C,SAAS,IAAI,eAAe;IAU5B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW;IAM5C,SAAS,IAAI,OAAO;IAIpB,cAAc,IAAI,MAAM;IAIxB,QAAQ,IAAI,IAAI;IAIhB,QAAQ,IAAI,YAAY;CAKzB;AAED,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,CAEtF;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,qBAAqB,CAE5G;AAED;;;;wEAIwE;AACxE,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAO7F"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { addClassNamesToElement } from '@lexical/utils';
|
|
3
|
+
import { $applyNodeReplacement, $getNodeByKey, createCommand, DecoratorNode, } from 'lexical';
|
|
4
|
+
export const INSERT_FOOTNOTE_COMMAND = createCommand('INSERT_FOOTNOTE_COMMAND');
|
|
5
|
+
/** Inline marker in the text flow (requirements doc §4.10, architecture doc
|
|
6
|
+
* §3.3). Holds only an id — its displayed number is never stored, it's
|
|
7
|
+
* rendered by a CSS counter (editor.css) that counts these markers in DOM
|
|
8
|
+
* order, so insert/delete/reorder auto-renumbers with no JS bookkeeping.
|
|
9
|
+
* The note's actual content lives in a matching FootnoteItemNode inside the
|
|
10
|
+
* document's single FootnoteListNode, not here (same split as Lexical's own
|
|
11
|
+
* comments/annotations pattern: reference in the flow, content out-of-band). */
|
|
12
|
+
export class FootnoteReferenceNode extends DecoratorNode {
|
|
13
|
+
constructor(footnoteId, key) {
|
|
14
|
+
super(key);
|
|
15
|
+
this.__footnoteId = footnoteId;
|
|
16
|
+
}
|
|
17
|
+
static getType() {
|
|
18
|
+
return 'footnote-reference';
|
|
19
|
+
}
|
|
20
|
+
static clone(node) {
|
|
21
|
+
return new FootnoteReferenceNode(node.__footnoteId, node.__key);
|
|
22
|
+
}
|
|
23
|
+
getFootnoteId() {
|
|
24
|
+
return this.getLatest().__footnoteId;
|
|
25
|
+
}
|
|
26
|
+
static importJSON(serializedNode) {
|
|
27
|
+
return $createFootnoteReferenceNode(serializedNode.footnoteId);
|
|
28
|
+
}
|
|
29
|
+
exportJSON() {
|
|
30
|
+
return { type: 'footnote-reference', version: 1, footnoteId: this.getFootnoteId() };
|
|
31
|
+
}
|
|
32
|
+
static importDOM() {
|
|
33
|
+
return {
|
|
34
|
+
sup: (domNode) => {
|
|
35
|
+
const id = domNode.getAttribute('data-likhari-footnote-ref');
|
|
36
|
+
if (!id)
|
|
37
|
+
return null;
|
|
38
|
+
return { conversion: () => ({ node: $createFootnoteReferenceNode(id) }), priority: 2 };
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
exportDOM() {
|
|
43
|
+
const element = document.createElement('sup');
|
|
44
|
+
element.setAttribute('data-likhari-footnote-ref', this.getFootnoteId());
|
|
45
|
+
const anchor = document.createElement('a');
|
|
46
|
+
anchor.setAttribute('href', `#fn-${this.getFootnoteId()}`);
|
|
47
|
+
anchor.setAttribute('id', `fnref-${this.getFootnoteId()}`);
|
|
48
|
+
element.appendChild(anchor);
|
|
49
|
+
return { element };
|
|
50
|
+
}
|
|
51
|
+
createDOM(config) {
|
|
52
|
+
const element = document.createElement('sup');
|
|
53
|
+
addClassNamesToElement(element, config.theme.footnoteReference ?? 'likhari-footnote-ref');
|
|
54
|
+
return element;
|
|
55
|
+
}
|
|
56
|
+
updateDOM() {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
getTextContent() {
|
|
60
|
+
return `[^${this.getFootnoteId()}]`;
|
|
61
|
+
}
|
|
62
|
+
isInline() {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
decorate() {
|
|
66
|
+
// The bracketed number itself is a CSS ::after counter (editor.css) —
|
|
67
|
+
// nothing to render here but the counted element.
|
|
68
|
+
return _jsx(_Fragment, {});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export function $createFootnoteReferenceNode(footnoteId) {
|
|
72
|
+
return $applyNodeReplacement(new FootnoteReferenceNode(footnoteId));
|
|
73
|
+
}
|
|
74
|
+
export function $isFootnoteReferenceNode(node) {
|
|
75
|
+
return node instanceof FootnoteReferenceNode;
|
|
76
|
+
}
|
|
77
|
+
/** Resolves a reference's footnoteId from the editor state just before its
|
|
78
|
+
* deletion committed — a mutation listener's 'destroyed' entries only carry
|
|
79
|
+
* the NodeKey, and by the time the listener fires the *current* state no
|
|
80
|
+
* longer has the node, so the caller must pass the listener's own
|
|
81
|
+
* `prevEditorState` here to know which FootnoteItemNode to clean up. */
|
|
82
|
+
export function $getFootnoteIdByKey(prevEditorState, key) {
|
|
83
|
+
let id = null;
|
|
84
|
+
prevEditorState.read(() => {
|
|
85
|
+
const node = $getNodeByKey(key);
|
|
86
|
+
if ($isFootnoteReferenceNode(node))
|
|
87
|
+
id = node.getFootnoteId();
|
|
88
|
+
});
|
|
89
|
+
return id;
|
|
90
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Inserts a reference at the caret and a matching empty item at the end of
|
|
2
|
+
* the document's footnote list (creating the list if this is the first
|
|
3
|
+
* footnote), then focuses the new item so the user can type the note. */
|
|
4
|
+
export declare function $insertFootnote(): boolean;
|
|
5
|
+
/** Removes the FootnoteItemNode for `footnoteId`, and the FootnoteListNode
|
|
6
|
+
* itself if that was its last item — called by FootnotePlugin's mutation
|
|
7
|
+
* listener when a FootnoteReferenceNode is deleted from the text. */
|
|
8
|
+
export declare function $removeFootnoteItem(footnoteId: string): void;
|
|
9
|
+
//# sourceMappingURL=footnoteActions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"footnoteActions.d.ts","sourceRoot":"","sources":["../../src/blocks/footnoteActions.ts"],"names":[],"mappings":"AAcA;;yEAEyE;AACzE,wBAAgB,eAAe,IAAI,OAAO,CAgBzC;AAED;;qEAEqE;AACrE,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAM5D"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { $createParagraphNode, $getRoot, $getSelection, $isRangeSelection } from 'lexical';
|
|
2
|
+
import { $createFootnoteReferenceNode } from './FootnoteNode.js';
|
|
3
|
+
import { $createFootnoteItemNode, $createFootnoteListNode, $isFootnoteItemNode, $isFootnoteListNode } from './FootnoteListNode.js';
|
|
4
|
+
let counter = 0;
|
|
5
|
+
/** Short, collision-resistant within a single document: a monotonic counter
|
|
6
|
+
* is enough here (ids never need to be stable/meaningful across documents),
|
|
7
|
+
* and avoids a hard dependency on crypto.randomUUID being available. */
|
|
8
|
+
function newFootnoteId() {
|
|
9
|
+
counter += 1;
|
|
10
|
+
return `${Date.now().toString(36)}${counter.toString(36)}`;
|
|
11
|
+
}
|
|
12
|
+
/** Inserts a reference at the caret and a matching empty item at the end of
|
|
13
|
+
* the document's footnote list (creating the list if this is the first
|
|
14
|
+
* footnote), then focuses the new item so the user can type the note. */
|
|
15
|
+
export function $insertFootnote() {
|
|
16
|
+
const selection = $getSelection();
|
|
17
|
+
if (!$isRangeSelection(selection))
|
|
18
|
+
return false;
|
|
19
|
+
const footnoteId = newFootnoteId();
|
|
20
|
+
selection.insertNodes([$createFootnoteReferenceNode(footnoteId)]);
|
|
21
|
+
const root = $getRoot();
|
|
22
|
+
const lastChild = root.getLastChild();
|
|
23
|
+
const list = $isFootnoteListNode(lastChild) ? lastChild : $createFootnoteListNode();
|
|
24
|
+
if (!$isFootnoteListNode(lastChild))
|
|
25
|
+
root.append(list);
|
|
26
|
+
const item = $createFootnoteItemNode(footnoteId).append($createParagraphNode());
|
|
27
|
+
list.append(item);
|
|
28
|
+
item.getFirstDescendant()?.selectStart();
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
/** Removes the FootnoteItemNode for `footnoteId`, and the FootnoteListNode
|
|
32
|
+
* itself if that was its last item — called by FootnotePlugin's mutation
|
|
33
|
+
* listener when a FootnoteReferenceNode is deleted from the text. */
|
|
34
|
+
export function $removeFootnoteItem(footnoteId) {
|
|
35
|
+
const list = $getRoot().getChildren().find($isFootnoteListNode);
|
|
36
|
+
if (!list)
|
|
37
|
+
return;
|
|
38
|
+
const item = list.getChildren().find((child) => $isFootnoteItemNode(child) && child.getFootnoteId() === footnoteId);
|
|
39
|
+
item?.remove();
|
|
40
|
+
if (list.getChildrenSize() === 0)
|
|
41
|
+
list.remove();
|
|
42
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AA8DA,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;AA2avD,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,+BAg+BxJ"}
|
|
@@ -13,6 +13,7 @@ import { ImageDialog } from '../image/ImageDialog.js';
|
|
|
13
13
|
import { $createImageNode } from '../image/ImageNode.js';
|
|
14
14
|
import { INSERT_PAGE_BREAK_COMMAND } from '../blocks/PageBreakNode.js';
|
|
15
15
|
import { INSERT_LAYOUT_COMMAND } from '../blocks/LayoutNode.js';
|
|
16
|
+
import { INSERT_FOOTNOTE_COMMAND } from '../blocks/FootnoteNode.js';
|
|
16
17
|
import { TableDialog } from './TableDialog.js';
|
|
17
18
|
import { LayoutDialog } from './LayoutDialog.js';
|
|
18
19
|
import { $getTableCellNodeFromLexicalNode, $isTableSelection, INSERT_TABLE_COMMAND } from '@lexical/table';
|
|
@@ -25,7 +26,7 @@ import { CANVAS_FONT_DEFAULTS, DEFAULT_FONT_OPTIONS, FONT_SIZES_PX } from '../fo
|
|
|
25
26
|
import { setStyleProperty } from '../utils/style.js';
|
|
26
27
|
import { useStrings } from '../i18n/useStrings.js';
|
|
27
28
|
import { usePortalTarget } from '../PortalTargetContext.js';
|
|
28
|
-
import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconBold, IconClearFormatting, IconDeviceFloppy, IconDots, IconHistory, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPageBreak, IconPencil, IconPhoto, IconPilcrow, IconQuote, IconSeparatorHorizontal, IconSparkles, IconStrikethrough, IconSubscript, IconSuperscript, IconArrowMergeBoth, IconArrowsSplit2, IconColumnInsertLeft, IconColumnInsertRight, IconColumnRemove, IconColumns, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconTable, IconTableMinus, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
29
|
+
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, IconNumber1Small, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconTable, IconTableMinus, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
|
|
29
30
|
/** Sentinel for "no inline style": Lexical returns the default it is given when
|
|
30
31
|
* the selection has none, so this tells "unstyled" (show the canvas default)
|
|
31
32
|
* apart from "styled with a value the dropdown doesn't list" (show nothing). */
|
|
@@ -566,6 +567,7 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
566
567
|
config.blocks.horizontalRule ||
|
|
567
568
|
config.blocks.pageBreak ||
|
|
568
569
|
config.columns ||
|
|
570
|
+
config.footnotes ||
|
|
569
571
|
config.poetry.enabled;
|
|
570
572
|
const showLanguageGroup = config.language.autocorrect || config.language.textCleanup || config.language.spellCheck;
|
|
571
573
|
// The "script & cleanup" and "indent/outdent" groups (UI spec §3.3) render
|
|
@@ -738,7 +740,7 @@ export function Toolbar({ config, onSave, isDirty, showSave, fontOptions = DEFAU
|
|
|
738
740
|
restoreSelection();
|
|
739
741
|
openLinkDialog();
|
|
740
742
|
}, onRemove: removeLink, strings: strings }) })] })) : (_jsx(ToolbarButton, { icon: IconLink, title: strings.toolbar.insertLink, onClick: openLinkDialog })) }, "link")),
|
|
741
|
-
showStubInsertGroup && (_jsxs("div", { className: "likhari-toolbar-group likhari-toolbar-group--collapse-tablet", children: [(config.images.linked || config.images.embedded) && (_jsx(ToolbarButton, { icon: IconPhoto, title: strings.toolbar.insertImage, onClick: openImageDialog })), config.blocks.pageBreak && (_jsx(ToolbarButton, { icon: IconPageBreak, title: strings.toolbar.insertPageBreak, onClick: () => editor.dispatchCommand(INSERT_PAGE_BREAK_COMMAND, undefined) })), config.tables && _jsx(ToolbarButton, { icon: IconTable, title: strings.toolbar.insertTable, onClick: openTableDialog }), config.columns && _jsx(ToolbarButton, { icon: IconColumns, title: strings.toolbar.insertColumns, onClick: openLayoutDialog }), config.blocks.horizontalRule && (_jsx(ToolbarButton, { icon: IconSeparatorHorizontal, title: strings.toolbar.insertHorizontalRule, onClick: () => editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, undefined) })), config.poetry.enabled && _jsx(StubButton, { icon: IconFeather, title: strings.toolbar.poetryBlocks, comingSoon: strings.toolbar.comingSoon })] }, "stubInsert")),
|
|
743
|
+
showStubInsertGroup && (_jsxs("div", { className: "likhari-toolbar-group likhari-toolbar-group--collapse-tablet", children: [(config.images.linked || config.images.embedded) && (_jsx(ToolbarButton, { icon: IconPhoto, title: strings.toolbar.insertImage, onClick: openImageDialog })), config.blocks.pageBreak && (_jsx(ToolbarButton, { icon: IconPageBreak, title: strings.toolbar.insertPageBreak, onClick: () => editor.dispatchCommand(INSERT_PAGE_BREAK_COMMAND, undefined) })), config.tables && _jsx(ToolbarButton, { icon: IconTable, title: strings.toolbar.insertTable, onClick: openTableDialog }), config.columns && _jsx(ToolbarButton, { icon: IconColumns, title: strings.toolbar.insertColumns, onClick: openLayoutDialog }), config.footnotes && (_jsx(ToolbarButton, { icon: IconNumber1Small, title: strings.toolbar.insertFootnote, onClick: () => editor.dispatchCommand(INSERT_FOOTNOTE_COMMAND, undefined) })), config.blocks.horizontalRule && (_jsx(ToolbarButton, { icon: IconSeparatorHorizontal, title: strings.toolbar.insertHorizontalRule, onClick: () => editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, undefined) })), config.poetry.enabled && _jsx(StubButton, { icon: IconFeather, title: strings.toolbar.poetryBlocks, comingSoon: strings.toolbar.comingSoon })] }, "stubInsert")),
|
|
742
744
|
config.tables && state.inTable && (_jsx("div", { className: "likhari-toolbar-group", children: _jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 240, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx("button", { type: "button", className: "likhari-toolbar-button", "data-active": "true", "aria-pressed": "true", "aria-haspopup": "menu", "aria-label": strings.toolbar.tableOptions, title: strings.toolbar.tableOptions, onMouseDown: (e) => e.preventDefault(), children: _jsx(IconTableOptions, { size: ICON_SIZE, stroke: ICON_STROKE }) }) }), _jsx(Menu.Dropdown, { children: _jsx(TableMenuItems, { strings: strings, direction: direction, rows: state.tableRows, columns: state.tableColumns, canMergeCells: state.canMergeCells, canUnmergeCell: state.canUnmergeCell, onAction: runTableAction }) })] }) }, "tableActions")),
|
|
743
745
|
showLanguageGroup && (_jsxs("div", { className: "likhari-toolbar-group likhari-toolbar-group--collapse-tablet", children: [config.language.autocorrect && _jsx(StubButton, { icon: IconWand, title: strings.toolbar.autocorrect, comingSoon: strings.toolbar.comingSoon }), config.language.textCleanup && _jsx(StubButton, { icon: IconSparkles, title: strings.toolbar.textCleanup, comingSoon: strings.toolbar.comingSoon }), config.language.spellCheck && _jsx(StubButton, { icon: IconAbc, title: strings.toolbar.spellChecker, comingSoon: strings.toolbar.comingSoon })] }, "language")),
|
|
744
746
|
];
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;+DAC+D;AAC/D,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,cAAc,CAAC;AAElD,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE;QACN,mGAAmG;QACnG,WAAW,EAAE,MAAM,CAAC;QACpB,gDAAgD;QAChD,YAAY,EAAE,MAAM,CAAC;QACrB,sEAAsE;QACtE,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,EAAE;QACP,gEAAgE;QAChE,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,0CAA0C;QAC1C,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,eAAe,EAAE,MAAM,CAAC;QACxB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,qBAAqB,EAAE,MAAM,CAAC;QAC9B,QAAQ,EAAE,MAAM,CAAC;QACjB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,8FAA8F;QAC9F,YAAY,EAAE,MAAM,CAAC;QACrB,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,oBAAoB,EAAE,MAAM,CAAC;QAC7B,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;QACtC,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,iBAAiB,EAAE;YACjB,SAAS,EAAE,MAAM,CAAC;YAClB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;YACnC,YAAY,EAAE,MAAM,CAAC;YACrB,UAAU,EAAE,MAAM,CAAC;YACnB,QAAQ,EAAE,MAAM,CAAC;YACjB,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;QACF,YAAY,EAAE;YACZ,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,EAAE,MAAM,CAAC;YACf,GAAG,EAAE,MAAM,CAAC;YACZ,OAAO,EAAE,MAAM,CAAC;YAChB,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;KACH,CAAC;IACF,uIAAuI;IACvI,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,2FAA2F;QAC3F,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,oGAAoG;IACpG,MAAM,EAAE;QACN,0GAA0G;QAC1G,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;QACxC,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,2DAA2D;QAC3D,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;QACtC,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;QACzC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;QAClC,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;QAC7B,aAAa,EAAE,MAAM,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,yEAAyE;IACzE,SAAS,EAAE;QACT,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,2EAA2E;QAC3E,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,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;AAmmBD,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAI3C,CAAC;AAEF;;sDAEsD;AACtD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAElD"}
|
package/dist/i18n/strings.js
CHANGED
|
@@ -38,6 +38,7 @@ const en = {
|
|
|
38
38
|
insertPageBreak: 'Insert page break',
|
|
39
39
|
insertTable: 'Insert table',
|
|
40
40
|
insertColumns: 'Insert columns',
|
|
41
|
+
insertFootnote: 'Insert footnote',
|
|
41
42
|
insertHorizontalRule: 'Insert horizontal rule',
|
|
42
43
|
poetryBlocks: 'Poetry blocks',
|
|
43
44
|
comingSoon: (label) => `${label} (coming soon)`,
|
|
@@ -238,6 +239,7 @@ const ur = {
|
|
|
238
239
|
insertPageBreak: 'صفحے کی تقسیم شامل کریں',
|
|
239
240
|
insertTable: 'جدول شامل کریں',
|
|
240
241
|
insertColumns: 'کالم شامل کریں',
|
|
242
|
+
insertFootnote: 'فٹ نوٹ شامل کریں',
|
|
241
243
|
insertHorizontalRule: 'افقی لکیر شامل کریں',
|
|
242
244
|
poetryBlocks: 'شاعری کے بلاکس',
|
|
243
245
|
comingSoon: (label) => `${label} (جلد آ رہا ہے)`,
|
|
@@ -438,6 +440,7 @@ const paShahmukhi = {
|
|
|
438
440
|
insertPageBreak: 'صفحے دی ونڈ پاؤ',
|
|
439
441
|
insertTable: 'ٹیبل پاؤ',
|
|
440
442
|
insertColumns: 'کالم پاؤ',
|
|
443
|
+
insertFootnote: 'فٹ نوٹ پاؤ',
|
|
441
444
|
insertHorizontalRule: 'لیٹی لکیر پاؤ',
|
|
442
445
|
poetryBlocks: 'شاعری بلاک',
|
|
443
446
|
comingSoon: (label) => `${label} (چھیتی آ رہا اے)`,
|
package/dist/nodes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../src/nodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../src/nodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAYlD;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,EAiB5C,CAAC"}
|
package/dist/nodes.js
CHANGED
|
@@ -6,6 +6,8 @@ import { TableCellNode, TableNode, TableRowNode } from '@lexical/table';
|
|
|
6
6
|
import { ImageNode } from './image/ImageNode.js';
|
|
7
7
|
import { PageBreakNode } from './blocks/PageBreakNode.js';
|
|
8
8
|
import { LayoutContainerNode, LayoutItemNode } from './blocks/LayoutNode.js';
|
|
9
|
+
import { FootnoteReferenceNode } from './blocks/FootnoteNode.js';
|
|
10
|
+
import { FootnoteItemNode, FootnoteListNode } from './blocks/FootnoteListNode.js';
|
|
9
11
|
/**
|
|
10
12
|
* Node types registered on the editor at construction time. Per
|
|
11
13
|
* editor-architecture-design.md §2, node registration cannot be conditional
|
|
@@ -29,4 +31,7 @@ export const EDITOR_NODES = [
|
|
|
29
31
|
PageBreakNode,
|
|
30
32
|
LayoutContainerNode,
|
|
31
33
|
LayoutItemNode,
|
|
34
|
+
FootnoteReferenceNode,
|
|
35
|
+
FootnoteListNode,
|
|
36
|
+
FootnoteItemNode,
|
|
32
37
|
];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers INSERT_FOOTNOTE_COMMAND, a mutation listener that removes a
|
|
3
|
+
* FootnoteItemNode when its matching FootnoteReferenceNode is deleted from
|
|
4
|
+
* the text (so the list never accumulates orphaned notes), and two node
|
|
5
|
+
* transforms that keep the list/item nesting valid against malformed trees
|
|
6
|
+
* from paste, undo or JSON import — mirrors LayoutPlugin's shape.
|
|
7
|
+
*/
|
|
8
|
+
export declare function FootnotePlugin(): null;
|
|
9
|
+
//# sourceMappingURL=FootnotePlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FootnotePlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/FootnotePlugin.tsx"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH,wBAAgB,cAAc,SAyC7B"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
3
|
+
import { mergeRegister } from '@lexical/utils';
|
|
4
|
+
import { COMMAND_PRIORITY_EDITOR } from 'lexical';
|
|
5
|
+
import { $getFootnoteIdByKey, FootnoteReferenceNode, INSERT_FOOTNOTE_COMMAND } from '../blocks/FootnoteNode.js';
|
|
6
|
+
import { $isFootnoteItemNode, $isFootnoteListNode, FootnoteItemNode, FootnoteListNode } from '../blocks/FootnoteListNode.js';
|
|
7
|
+
import { $insertFootnote, $removeFootnoteItem } from '../blocks/footnoteActions.js';
|
|
8
|
+
/**
|
|
9
|
+
* Registers INSERT_FOOTNOTE_COMMAND, a mutation listener that removes a
|
|
10
|
+
* FootnoteItemNode when its matching FootnoteReferenceNode is deleted from
|
|
11
|
+
* the text (so the list never accumulates orphaned notes), and two node
|
|
12
|
+
* transforms that keep the list/item nesting valid against malformed trees
|
|
13
|
+
* from paste, undo or JSON import — mirrors LayoutPlugin's shape.
|
|
14
|
+
*/
|
|
15
|
+
export function FootnotePlugin() {
|
|
16
|
+
const [editor] = useLexicalComposerContext();
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!editor.hasNodes([FootnoteReferenceNode, FootnoteListNode, FootnoteItemNode])) {
|
|
19
|
+
throw new Error('FootnotePlugin: footnote node types not registered on the editor');
|
|
20
|
+
}
|
|
21
|
+
return mergeRegister(editor.registerCommand(INSERT_FOOTNOTE_COMMAND, () => $insertFootnote(), COMMAND_PRIORITY_EDITOR), editor.registerMutationListener(FootnoteReferenceNode, (mutations, { prevEditorState }) => {
|
|
22
|
+
const destroyedIds = [];
|
|
23
|
+
for (const [key, mutation] of mutations) {
|
|
24
|
+
if (mutation !== 'destroyed')
|
|
25
|
+
continue;
|
|
26
|
+
const id = $getFootnoteIdByKey(prevEditorState, key);
|
|
27
|
+
if (id)
|
|
28
|
+
destroyedIds.push(id);
|
|
29
|
+
}
|
|
30
|
+
if (destroyedIds.length === 0)
|
|
31
|
+
return;
|
|
32
|
+
editor.update(() => {
|
|
33
|
+
for (const id of destroyedIds)
|
|
34
|
+
$removeFootnoteItem(id);
|
|
35
|
+
});
|
|
36
|
+
}, { skipInitialization: true }), editor.registerNodeTransform(FootnoteItemNode, (node) => {
|
|
37
|
+
const parent = node.getParent();
|
|
38
|
+
if ($isFootnoteListNode(parent))
|
|
39
|
+
return;
|
|
40
|
+
for (const child of node.getChildren())
|
|
41
|
+
node.insertBefore(child);
|
|
42
|
+
node.remove();
|
|
43
|
+
}), editor.registerNodeTransform(FootnoteListNode, (node) => {
|
|
44
|
+
for (const child of node.getChildren()) {
|
|
45
|
+
if (!$isFootnoteItemNode(child))
|
|
46
|
+
child.remove();
|
|
47
|
+
}
|
|
48
|
+
}));
|
|
49
|
+
}, [editor]);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
package/dist/theme/editor.css
CHANGED
|
@@ -178,6 +178,10 @@
|
|
|
178
178
|
font-family: 'IBM Plex Serif', Georgia, serif;
|
|
179
179
|
font-size: 15px;
|
|
180
180
|
line-height: 1.75;
|
|
181
|
+
/* Scopes the footnote-reference counter to the whole document (editor.css
|
|
182
|
+
footnote rules below), so numbering is consistent regardless of which
|
|
183
|
+
blocks the references happen to sit in. */
|
|
184
|
+
counter-reset: likhari-footnote-ref;
|
|
181
185
|
}
|
|
182
186
|
|
|
183
187
|
.likhari-content-editable[dir='rtl'] {
|
|
@@ -335,6 +339,41 @@
|
|
|
335
339
|
margin-bottom: 0;
|
|
336
340
|
}
|
|
337
341
|
|
|
342
|
+
/* Footnotes (lexical-editor-spec.md §4.10). The bracketed number on both
|
|
343
|
+
the inline reference and its list entry is a CSS counter, not stored
|
|
344
|
+
state — Lexical insert/delete/reorder of the underlying nodes renumbers
|
|
345
|
+
both sequences automatically as long as list items stay in the same
|
|
346
|
+
order their references were inserted (FootnotePlugin's insert command
|
|
347
|
+
always appends in that order). */
|
|
348
|
+
.likhari-footnote-ref {
|
|
349
|
+
counter-increment: likhari-footnote-ref;
|
|
350
|
+
cursor: default;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.likhari-footnote-ref::after {
|
|
354
|
+
content: '[' counter(likhari-footnote-ref) ']';
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.likhari-footnote-list {
|
|
358
|
+
counter-reset: likhari-footnote-item;
|
|
359
|
+
list-style: none;
|
|
360
|
+
margin: 2em 0 0 0;
|
|
361
|
+
padding-inline-start: 1.5em;
|
|
362
|
+
border-top: 1px solid var(--editor-line);
|
|
363
|
+
padding-top: 0.75em;
|
|
364
|
+
font-size: 0.9em;
|
|
365
|
+
color: var(--editor-ink-soft);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.likhari-footnote-item {
|
|
369
|
+
counter-increment: likhari-footnote-item;
|
|
370
|
+
margin: 0.3em 0;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.likhari-footnote-item::marker {
|
|
374
|
+
content: '[' counter(likhari-footnote-item) '] ';
|
|
375
|
+
}
|
|
376
|
+
|
|
338
377
|
.likhari-table {
|
|
339
378
|
border-collapse: collapse;
|
|
340
379
|
margin: 1em 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editorTheme.d.ts","sourceRoot":"","sources":["../../src/theme/editorTheme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"editorTheme.d.ts","sourceRoot":"","sources":["../../src/theme/editorTheme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,kBA+CzB,CAAC"}
|
|
@@ -42,6 +42,9 @@ export const editorTheme = {
|
|
|
42
42
|
pageBreak: 'likhari-page-break',
|
|
43
43
|
layoutContainer: 'likhari-layout-container',
|
|
44
44
|
layoutItem: 'likhari-layout-item',
|
|
45
|
+
footnoteReference: 'likhari-footnote-ref',
|
|
46
|
+
footnoteList: 'likhari-footnote-list',
|
|
47
|
+
footnoteItem: 'likhari-footnote-item',
|
|
45
48
|
table: 'likhari-table',
|
|
46
49
|
tableRow: 'likhari-table-row',
|
|
47
50
|
tableCell: 'likhari-table-cell',
|