@inshapardaz/likhari-react 0.1.22 → 0.1.23

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.
Files changed (38) hide show
  1. package/dist/EditorRoot.d.ts +9 -0
  2. package/dist/EditorRoot.d.ts.map +1 -1
  3. package/dist/EditorRoot.js +12 -11
  4. package/dist/autocorrect/AutoCorrectPlugin.d.ts +27 -0
  5. package/dist/autocorrect/AutoCorrectPlugin.d.ts.map +1 -0
  6. package/dist/autocorrect/AutoCorrectPlugin.js +108 -0
  7. package/dist/autocorrect/autoCorrectActions.d.ts +35 -0
  8. package/dist/autocorrect/autoCorrectActions.d.ts.map +1 -0
  9. package/dist/autocorrect/autoCorrectActions.js +182 -0
  10. package/dist/autocorrect/autoCorrectStores.d.ts +52 -0
  11. package/dist/autocorrect/autoCorrectStores.d.ts.map +1 -0
  12. package/dist/autocorrect/autoCorrectStores.js +115 -0
  13. package/dist/autocorrect/punctuationRules.d.ts +26 -0
  14. package/dist/autocorrect/punctuationRules.d.ts.map +1 -0
  15. package/dist/autocorrect/punctuationRules.js +53 -0
  16. package/dist/cleanup/textCleanupActions.d.ts +8 -0
  17. package/dist/cleanup/textCleanupActions.d.ts.map +1 -0
  18. package/dist/cleanup/textCleanupActions.js +28 -0
  19. package/dist/components/AutoCorrectPanel.d.ts +15 -0
  20. package/dist/components/AutoCorrectPanel.d.ts.map +1 -0
  21. package/dist/components/AutoCorrectPanel.js +44 -0
  22. package/dist/components/Toolbar.d.ts +4 -1
  23. package/dist/components/Toolbar.d.ts.map +1 -1
  24. package/dist/components/Toolbar.js +112 -109
  25. package/dist/i18n/strings.d.ts +22 -0
  26. package/dist/i18n/strings.d.ts.map +1 -1
  27. package/dist/i18n/strings.js +71 -5
  28. package/dist/index.d.ts +5 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +2 -0
  31. package/dist/normalization/urduNormalize.d.ts +24 -0
  32. package/dist/normalization/urduNormalize.d.ts.map +1 -0
  33. package/dist/normalization/urduNormalize.js +116 -0
  34. package/dist/spellcheck/spellingMenu.d.ts +15 -0
  35. package/dist/spellcheck/spellingMenu.d.ts.map +1 -0
  36. package/dist/spellcheck/spellingMenu.js +27 -0
  37. package/dist/theme/editor.css +58 -0
  38. package/package.json +1 -1
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Common Urdu punctuation and character fixes, as a snapshot of
3
+ * https://api.nawishta.co.uk/tools/ur/spellchecker/punctuation (fetched 2026-10-04).
4
+ * Bundled so the editor works offline and does not depend on that service;
5
+ * refresh the list when the service changes.
6
+ */
7
+ export interface PunctuationRule {
8
+ incorrect: string;
9
+ correct: string;
10
+ /** When true, the match must be a whole word (not part of a longer one). */
11
+ completeWord: boolean;
12
+ }
13
+ export declare const URDU_PUNCTUATION_RULES: PunctuationRule[];
14
+ export interface PunctuationOptions {
15
+ /** Apply the punctuation fixes. On by default. */
16
+ enabled?: boolean;
17
+ /** Replace a straight double quote (") with a closing curly quote (”). On by default. */
18
+ straightDoubleQuote?: boolean;
19
+ /** Space after Urdu punctuation and remove spaces before it, as urduhack's punctuations_space. Off by default. */
20
+ spacing?: boolean;
21
+ }
22
+ /** The rules in use for the options, longest match first, so `۔"` wins over `"`. */
23
+ export declare function activePunctuationRules(options?: PunctuationOptions): PunctuationRule[];
24
+ /** Spaces after Urdu punctuation (not inside numbers), and none before it. */
25
+ export declare function spacePunctuationText(text: string): string;
26
+ //# sourceMappingURL=punctuationRules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"punctuationRules.d.ts","sourceRoot":"","sources":["../../src/autocorrect/punctuationRules.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,sBAAsB,EAAE,eAAe,EAmCnD,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yFAAyF;IACzF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,kHAAkH;IAClH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,oFAAoF;AACpF,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,kBAAuB,GAAG,eAAe,EAAE,CAK1F;AAOD,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD"}
@@ -0,0 +1,53 @@
1
+ export const URDU_PUNCTUATION_RULES = [
2
+ { incorrect: ".", correct: "۔", completeWord: false },
3
+ { incorrect: ",", correct: "،", completeWord: false },
4
+ { incorrect: " ۔", correct: "۔", completeWord: false },
5
+ { incorrect: " - ", correct: "۔ ", completeWord: false },
6
+ { incorrect: " ،", correct: "،", completeWord: false },
7
+ { incorrect: "?", correct: "؟", completeWord: false },
8
+ { incorrect: " ؟", correct: "؟", completeWord: false },
9
+ { incorrect: " !", correct: "!", completeWord: false },
10
+ { incorrect: "( ", correct: "(", completeWord: false },
11
+ { incorrect: " (", correct: "(", completeWord: false },
12
+ { incorrect: "ه", correct: "ہ", completeWord: false },
13
+ { incorrect: "ک", correct: "ک", completeWord: false },
14
+ { incorrect: "ئو", correct: "ؤ", completeWord: false },
15
+ { incorrect: "’’", correct: "”", completeWord: false },
16
+ { incorrect: "‘‘", correct: "“", completeWord: false },
17
+ { incorrect: "…", correct: "۔۔۔", completeWord: false },
18
+ { incorrect: "——", correct: "۔۔۔", completeWord: false },
19
+ { incorrect: "—", correct: "۔۔۔", completeWord: false },
20
+ { incorrect: " ۔۔۔", correct: "۔۔۔ ", completeWord: false },
21
+ { incorrect: "،،", correct: "“", completeWord: false },
22
+ { incorrect: "۔\"", correct: "۔“", completeWord: false },
23
+ { incorrect: "، \"", correct: "۔ ”", completeWord: false },
24
+ { incorrect: "؟\"", correct: "؟“", completeWord: false },
25
+ { incorrect: "!\"", correct: "!“", completeWord: false },
26
+ { incorrect: "-", correct: "۔", completeWord: false },
27
+ { incorrect: " ، ", correct: "، ", completeWord: false },
28
+ { incorrect: " ۔", correct: "۔ ", completeWord: false },
29
+ { incorrect: " : ", correct: ": ", completeWord: false },
30
+ { incorrect: "آ", correct: "آ", completeWord: false },
31
+ { incorrect: "ؤ", correct: "ؤ", completeWord: false },
32
+ { incorrect: " ِ", correct: "ِ", completeWord: false },
33
+ { incorrect: " ً", correct: "ً", completeWord: false },
34
+ { incorrect: " :", correct: ":", completeWord: false },
35
+ { incorrect: "” ", correct: "”", completeWord: false },
36
+ ];
37
+ /** The rules in use for the options, longest match first, so `۔"` wins over `"`. */
38
+ export function activePunctuationRules(options = {}) {
39
+ if (options.enabled === false)
40
+ return [];
41
+ const rules = URDU_PUNCTUATION_RULES.filter((rule) => rule.incorrect !== rule.correct);
42
+ if (options.straightDoubleQuote !== false)
43
+ rules.push({ incorrect: '"', correct: '”', completeWord: false });
44
+ return rules.sort((a, b) => b.incorrect.length - a.incorrect.length);
45
+ }
46
+ /** Space after Urdu punctuation, when the next character is not punctuation, a digit or a space. */
47
+ const SPACE_AFTER_PUNCTUATION = /(?<=[؛،٫؟۔٪])(?=[^؛،٫؟۔٪0-9 \n])/gu;
48
+ /** Spaces before Urdu punctuation. */
49
+ const SPACE_BEFORE_PUNCTUATION = /\s+([؛،٫؟۔٪])/gu;
50
+ /** Spaces after Urdu punctuation (not inside numbers), and none before it. */
51
+ export function spacePunctuationText(text) {
52
+ return text.replace(SPACE_AFTER_PUNCTUATION, ' ').replace(SPACE_BEFORE_PUNCTUATION, '$1');
53
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tidies the whole document in place: Unicode NFC normalisation (Arabic-script
3
+ * text can store the same visible letters in different code points), collapsed
4
+ * repeated spaces, and empty text nodes removed. Formatting is kept, since each
5
+ * text node is only changed, never replaced. Returns how many text nodes changed.
6
+ */
7
+ export declare function $cleanUpText(): number;
8
+ //# sourceMappingURL=textCleanupActions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textCleanupActions.d.ts","sourceRoot":"","sources":["../../src/cleanup/textCleanupActions.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAMrC"}
@@ -0,0 +1,28 @@
1
+ import { $getRoot } from 'lexical';
2
+ /** Runs of two or more spaces or tabs, collapsed to one space. */
3
+ const REPEATED_SPACE = /[ \t]{2,}/g;
4
+ /**
5
+ * Tidies the whole document in place: Unicode NFC normalisation (Arabic-script
6
+ * text can store the same visible letters in different code points), collapsed
7
+ * repeated spaces, and empty text nodes removed. Formatting is kept, since each
8
+ * text node is only changed, never replaced. Returns how many text nodes changed.
9
+ */
10
+ export function $cleanUpText() {
11
+ let changed = 0;
12
+ for (const node of $getRoot().getAllTextNodes()) {
13
+ if (cleanNode(node))
14
+ changed += 1;
15
+ }
16
+ return changed;
17
+ }
18
+ function cleanNode(node) {
19
+ const text = node.getTextContent();
20
+ const cleaned = text.normalize('NFC').replace(REPEATED_SPACE, ' ');
21
+ if (cleaned === text)
22
+ return false;
23
+ if (cleaned === '')
24
+ node.remove();
25
+ else
26
+ node.setTextContent(cleaned);
27
+ return true;
28
+ }
@@ -0,0 +1,15 @@
1
+ import type { Strings } from '../i18n/strings.js';
2
+ import { type AutoCorrectStore } from '../autocorrect/autoCorrectStores.js';
3
+ /**
4
+ * Adds one correction (a typed word and its replacement) to the first store
5
+ * that accepts writes. Saving bumps the editor's correction version, so the new
6
+ * entry applies to the next word the user types.
7
+ */
8
+ export declare function AutoCorrectPanel({ strings, dir, stores, onSaved, onClose, }: {
9
+ strings: Strings;
10
+ dir: 'ltr' | 'rtl';
11
+ stores: AutoCorrectStore[];
12
+ onSaved: () => void;
13
+ onClose: () => void;
14
+ }): import("react").JSX.Element;
15
+ //# sourceMappingURL=AutoCorrectPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutoCorrectPanel.d.ts","sourceRoot":"","sources":["../../src/components/AutoCorrectPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAS/F;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,GAAG,EACH,MAAM,EACN,OAAO,EACP,OAAO,GACR,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,KAAK,GAAG,KAAK,CAAC;IACnB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,+BAqEA"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { IconX } from '@tabler/icons-react';
4
+ import { appendAutoCorrection } from '../autocorrect/autoCorrectStores.js';
5
+ const LANGUAGES = [
6
+ { value: 'en', label: 'English' },
7
+ { value: 'ur', label: 'اردو' },
8
+ { value: 'pa-shahmukhi', label: 'پنجابی (شاہ مکھی)' },
9
+ ];
10
+ /**
11
+ * Adds one correction (a typed word and its replacement) to the first store
12
+ * that accepts writes. Saving bumps the editor's correction version, so the new
13
+ * entry applies to the next word the user types.
14
+ */
15
+ export function AutoCorrectPanel({ strings, dir, stores, onSaved, onClose, }) {
16
+ const t = strings.autoCorrect;
17
+ const [language, setLanguage] = useState('en');
18
+ const [from, setFrom] = useState('');
19
+ const [to, setTo] = useState('');
20
+ const [status, setStatus] = useState('idle');
21
+ const save = async () => {
22
+ const entry = { from: from.trim(), to: to.trim() };
23
+ if (entry.from === '' || entry.to === '' || entry.from === entry.to)
24
+ return;
25
+ try {
26
+ const written = await appendAutoCorrection(stores, language, entry);
27
+ if (!written) {
28
+ setStatus('nowhere');
29
+ return;
30
+ }
31
+ setStatus('saved');
32
+ setFrom('');
33
+ setTo('');
34
+ onSaved();
35
+ }
36
+ catch {
37
+ setStatus('failed');
38
+ }
39
+ };
40
+ return (_jsxs("div", { className: "likhari-autocorrect-panel", role: "region", "aria-label": t.title, dir: dir, children: [_jsxs("div", { className: "likhari-spell-header", children: [_jsx("strong", { children: t.title }), _jsx("button", { type: "button", className: "likhari-spell-icon", onClick: onClose, "aria-label": t.close, title: t.close, children: _jsx(IconX, { size: 14, stroke: 1.75 }) })] }), _jsxs("label", { className: "likhari-autocorrect-field", children: [t.language, _jsx("select", { value: language, onChange: (e) => {
41
+ setLanguage(e.target.value);
42
+ setStatus('idle');
43
+ }, children: LANGUAGES.map((l) => (_jsx("option", { value: l.value, children: l.label }, l.value))) })] }), _jsxs("label", { className: "likhari-autocorrect-field", children: [t.from, _jsx("input", { value: from, onChange: (e) => setFrom(e.target.value), placeholder: t.fromPlaceholder })] }), _jsxs("label", { className: "likhari-autocorrect-field", children: [t.to, _jsx("input", { value: to, onChange: (e) => setTo(e.target.value), placeholder: t.toPlaceholder })] }), _jsxs("div", { className: "likhari-autocorrect-actions", children: [_jsx("button", { type: "button", onClick: save, disabled: from.trim() === '' || to.trim() === '', children: t.save }), _jsxs("span", { className: "likhari-spell-note", "aria-live": "polite", children: [status === 'saved' && t.saved, status === 'nowhere' && t.noWritableStore, status === 'failed' && t.failed] })] })] }));
44
+ }
@@ -10,6 +10,9 @@ export interface ToolbarProps {
10
10
  /** Whether the spellcheck panel is open, and how to toggle it (owned by EditorRoot). */
11
11
  spellOpen?: boolean;
12
12
  onToggleSpell?: () => void;
13
+ /** Whether the add-auto-correction panel is open, and how to toggle it (owned by EditorRoot). */
14
+ autoCorrectOpen?: boolean;
15
+ onToggleAutoCorrect?: () => void;
13
16
  onSave?: () => void;
14
17
  isDirty?: boolean;
15
18
  showSave?: boolean;
@@ -22,5 +25,5 @@ export interface ToolbarProps {
22
25
  /** Autosave drafts: when set, the toolbar offers a Drafts button that lists and restores them. */
23
26
  drafts?: DraftsToolbarOptions;
24
27
  }
25
- export declare function Toolbar({ config, onSave, isDirty, showSave, findOpen, onToggleFind, spellOpen, onToggleSpell, fontOptions, direction, locale, drafts }: ToolbarProps): import("react").JSX.Element;
28
+ export declare function Toolbar({ config, onSave, isDirty, showSave, findOpen, onToggleFind, spellOpen, onToggleSpell, autoCorrectOpen, onToggleAutoCorrect, fontOptions, direction, locale, drafts }: ToolbarProps): import("react").JSX.Element;
26
29
  //# sourceMappingURL=Toolbar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AAqFA,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;AA+gBvD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,2BAA2B,CAAC;IACpC,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,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,QAAgB,EAAE,YAAY,EAAE,SAAiB,EAAE,aAAa,EAAE,WAAkC,EAAE,SAAiB,EAAE,MAAa,EAAE,MAAM,EAAE,EAAE,YAAY,+BAwkC1N"}
1
+ {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AA0FA,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;AA6hBvD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,2BAA2B,CAAC;IACpC,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,iGAAiG;IACjG,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sEAAsE;IACtE,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,wFAAwF;IACxF,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAgB,EAAE,YAAY,EAAE,SAAiB,EAAE,aAAa,EAAE,eAAuB,EAAE,mBAAmB,EAAE,WAAkC,EAAE,SAAiB,EAAE,MAAa,EAAE,MAAM,EAAE,EAAE,YAAY,+BAslCxQ"}
@@ -2,12 +2,16 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
3
3
  import { Menu, Select } from '@mantine/core';
4
4
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
5
- import { $getSelection, $isRangeSelection, $isElementNode, $setSelection, $getRoot, $getNearestNodeFromDOMNode, $createTextNode, KEY_MODIFIER_COMMAND, COMMAND_PRIORITY_NORMAL, FORMAT_TEXT_COMMAND, FORMAT_ELEMENT_COMMAND, INDENT_CONTENT_COMMAND, OUTDENT_CONTENT_COMMAND, UNDO_COMMAND, REDO_COMMAND, SELECTION_CHANGE_COMMAND, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, COMMAND_PRIORITY_LOW, } from 'lexical';
5
+ import { $getSelection, $isRangeSelection, $isElementNode, $setSelection, $getRoot, $selectAll, $getNearestNodeFromDOMNode, $createTextNode, KEY_MODIFIER_COMMAND, COMMAND_PRIORITY_NORMAL, FORMAT_TEXT_COMMAND, FORMAT_ELEMENT_COMMAND, INDENT_CONTENT_COMMAND, OUTDENT_CONTENT_COMMAND, UNDO_COMMAND, REDO_COMMAND, SELECTION_CHANGE_COMMAND, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, COMMAND_PRIORITY_LOW, } from 'lexical';
6
6
  import { $getSelectionStyleValueForProperty, $patchStyleText, $setBlocksType } from '@lexical/selection';
7
7
  import { $createParagraphNode } from 'lexical';
8
8
  import { $createHeadingNode, $createQuoteNode, $isHeadingNode, $isQuoteNode } from '@lexical/rich-text';
9
9
  import { $isListNode, INSERT_CHECK_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND, } from '@lexical/list';
10
10
  import { $findMatchingParent, $insertNodeToNearestRoot } from '@lexical/utils';
11
+ import { CORRECT_DOCUMENT_COMMAND } from '../autocorrect/AutoCorrectPlugin.js';
12
+ import { $replaceMatch } from '../find/findReplaceActions.js';
13
+ import { getSpeller } from '../spellcheck/spellDictionaries.js';
14
+ import { $wordAtDomPoint, textPointAt } from '../spellcheck/spellingMenu.js';
11
15
  import { INSERT_HORIZONTAL_RULE_COMMAND } from '@lexical/react/LexicalHorizontalRuleNode';
12
16
  import { ImageDialog } from '../image/ImageDialog.js';
13
17
  import { $createImageNode } from '../image/ImageNode.js';
@@ -29,7 +33,7 @@ import { CANVAS_FONT_DEFAULTS, DEFAULT_FONT_OPTIONS, FONT_SIZES_PX } from '../fo
29
33
  import { setStyleProperty } from '../utils/style.js';
30
34
  import { useStrings } from '../i18n/useStrings.js';
31
35
  import { usePortalTarget } from '../PortalTargetContext.js';
32
- import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconBold, IconClearFormatting, IconDeviceFloppy, IconDots, IconHistory, IconExternalLink, IconFeather, IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconIndentDecrease, IconIndentIncrease, IconItalic, IconLetterCase, IconLetterCaseLower, IconLetterCaseUpper, IconLink, IconLinkOff, IconList, IconListCheck, IconListNumbers, IconPageBreak, IconPencil, IconPhoto, IconPilcrow, IconQuote, IconSeparatorHorizontal, IconSparkles, IconStrikethrough, IconSubscript, IconSuperscript, IconArrowMergeBoth, IconArrowsSplit2, IconColumnInsertLeft, IconColumnInsertRight, IconColumnRemove, IconColumns, IconSearch, IconColumns1, IconColumns2, IconNumber1Small, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconArrowsMaximize, IconArrowsMinimize, IconArrowsShuffle, IconTable, IconTableMinus, IconTrash, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
36
+ 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, IconClipboard, IconCopy, IconCut, IconSearch, IconSelectAll, IconColumns1, IconColumns2, IconNumber1Small, IconRowInsertBottom, IconRowInsertTop, IconRowRemove, IconArrowsMaximize, IconArrowsMinimize, IconArrowsShuffle, IconTable, IconTableMinus, IconTrash, IconTableOptions, IconTextSize, IconTypography, IconUnderline, IconWand, } from '@tabler/icons-react';
33
37
  /** Sentinel for "no inline style": Lexical returns the default it is given when
34
38
  * the selection has none, so this tells "unstyled" (show the canvas default)
35
39
  * apart from "styled with a value the dropdown doesn't list" (show nothing). */
@@ -139,8 +143,6 @@ function OverflowItem({ icon: Icon, label, active, onClick, }) {
139
143
  // Keep the editor's selection: a mousedown here would blur the canvas.
140
144
  onMouseDown: (e) => e.preventDefault(), onClick: onClick, children: label }));
141
145
  }
142
- /** The link menu's contents — shared by the toolbar button and the right-click
143
- * menu: the URL (opens in a new tab), Edit link, Remove link. */
144
146
  function LinkMenuItems({ url, onEdit, onRemove, strings }) {
145
147
  // Only offer the link as clickable if it's a URL the editor would have accepted.
146
148
  const safeUrl = normalizeLinkUrl(url);
@@ -182,7 +184,7 @@ function PoetryMenuItems({ strings, layout, scale, centered, onAction, }) {
182
184
  };
183
185
  return (_jsxs(_Fragment, { children: [_jsx(Menu.Label, { children: t.menuLabel }), item(IconColumns1, t.singleColumn, setLayout('single'), layout === 'single'), item(IconColumns2, t.twoColumn, setLayout('two-column'), layout === 'two-column'), item(IconArrowsShuffle, t.staggered, setLayout('staggered'), layout === 'staggered'), _jsx(Menu.Divider, {}), _jsx(Menu.Divider, {}), item(IconRowInsertTop, t.insertCoupletBefore, () => $insertCoupletRelativeToSelection('before')), item(IconRowInsertBottom, t.insertCoupletAfter, () => $insertCoupletRelativeToSelection('after')), item(IconArrowsMinimize, t.tighterSpacing, () => $adjustPoetrySpacing(-1), !canStep(POETRY_SPACINGS, scale.spacing, -1)), item(IconArrowsMaximize, t.looserSpacing, () => $adjustPoetrySpacing(1), !canStep(POETRY_SPACINGS, scale.spacing, 1)), layout === 'staggered' && (_jsxs(_Fragment, { children: [item(IconArrowsMinimize, t.narrowerCouplets, () => $adjustPoetryStagger(-1), !canStep(POETRY_STAGGERS, scale.stagger, -1)), item(IconArrowsMaximize, t.widerCouplets, () => $adjustPoetryStagger(1), !canStep(POETRY_STAGGERS, scale.stagger, 1))] })), layout === 'two-column' && (_jsxs(_Fragment, { children: [item(IconAlignCenter, centered ? t.uncenterCouplet : t.centerCouplet, () => $setCoupletCentered(!centered)), item(IconColumns2, t.narrowerGutter, () => $adjustPoetryGutter(-1), !canStep(POETRY_GUTTERS, scale.gutter, -1)), item(IconColumns2, t.widerGutter, () => $adjustPoetryGutter(1), !canStep(POETRY_GUTTERS, scale.gutter, 1))] })), item(IconTrash, t.deleteCouplet, $deletePoetryCouplet, false, 'red'), item(IconTrash, t.deletePoetry, $deletePoetryBlock, false, 'red')] }));
184
186
  }
185
- export function Toolbar({ config, onSave, isDirty, showSave, findOpen = false, onToggleFind, spellOpen = false, onToggleSpell, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
187
+ export function Toolbar({ config, onSave, isDirty, showSave, findOpen = false, onToggleFind, spellOpen = false, onToggleSpell, autoCorrectOpen = false, onToggleAutoCorrect, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
186
188
  const [editor] = useLexicalComposerContext();
187
189
  const [state, setState] = useState(INITIAL_STATE);
188
190
  const strings = useStrings(locale);
@@ -463,112 +465,115 @@ export function Toolbar({ config, onSave, isDirty, showSave, findOpen = false, o
463
465
  editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
464
466
  closeLinkDialog();
465
467
  };
466
- // Right-clicking a link in the text opens the same menu, at the pointer.
467
- const [linkContext, setLinkContext] = useState(null);
468
- useEffect(() => {
469
- if (!config.links)
470
- return;
471
- const onContextMenu = (event) => {
472
- const anchor = event.target?.closest?.('a');
473
- if (!anchor)
474
- return;
475
- let url = null;
476
- // Select the whole link first, so Edit / Remove act on it wherever the caret was.
477
- editor.update(() => {
478
- const node = $getNearestNodeFromDOMNode(anchor);
479
- const link = node ? $findMatchingParent(node, $isLinkNode) : null;
480
- if (!link || !$isLinkNode(link))
481
- return;
482
- url = link.getURL();
483
- link.select(0, link.getChildrenSize());
484
- }, { discrete: true });
485
- if (url === null)
486
- return;
487
- event.preventDefault();
488
- snapshotSelectionRef.current();
489
- setLinkContext({ x: event.clientX, y: event.clientY, url });
490
- };
491
- return editor.registerRootListener((root, previous) => {
492
- previous?.removeEventListener('contextmenu', onContextMenu);
493
- root?.addEventListener('contextmenu', onContextMenu);
494
- });
495
- }, [editor, config.links]);
496
- // Table/poetry contextual-menu actions. The menu takes focus, so the
497
- // selection is snapshotted when it opens and restored before an action runs.
468
+ // One right-click menu for the whole editor, replacing the browser's own. It
469
+ // adds what applies to what is under the pointer (a spelling fix, a link, a
470
+ // table cell, a poetry couplet) and always offers cut, copy, paste and select all.
498
471
  const runMenuAction = (action) => () => {
499
472
  restoreSelection();
500
473
  editor.update(action);
501
474
  editor.focus();
502
475
  };
503
- // Right-clicking a table cell opens the same actions at the pointer.
504
- const [tableContext, setTableContext] = useState(null);
476
+ const [contextMenu, setContextMenu] = useState(null);
505
477
  useEffect(() => {
506
- if (!config.tables)
507
- return;
508
- const onContextMenu = (event) => {
509
- if (event.defaultPrevented)
510
- return; // a link inside the cell already took it
511
- const cellElement = event.target?.closest?.('td, th');
512
- if (!cellElement)
513
- return;
514
- let handled = false;
515
- editor.update(() => {
516
- const node = $getNearestNodeFromDOMNode(cellElement);
517
- const cell = node ? $getTableCellNodeFromLexicalNode(node) : null;
518
- if (!cell)
519
- return;
520
- handled = true;
521
- const selection = $getSelection();
522
- // Keep a multi-cell selection that includes this cell, so "insert
523
- // rows" / "delete columns" act on everything selected.
524
- const insideSelection = $isTableSelection(selection) && selection.getNodes().some((n) => n.getKey() === cell.getKey());
525
- if (!insideSelection)
526
- cell.selectEnd();
527
- }, { discrete: true });
528
- if (!handled)
529
- return;
478
+ const onContextMenu = async (event) => {
530
479
  event.preventDefault();
531
480
  snapshotSelectionRef.current();
532
- const size = editor.getEditorState().read($getTableSelectionSize);
533
- setTableContext({ x: event.clientX, y: event.clientY, rows: size.rows, columns: size.columns });
534
- };
535
- return editor.registerRootListener((root, previous) => {
536
- previous?.removeEventListener('contextmenu', onContextMenu);
537
- root?.addEventListener('contextmenu', onContextMenu);
538
- });
539
- }, [editor, config.tables]);
540
- // Right-clicking a poetry couplet opens the same options menu at the pointer.
541
- const [poetryContext, setPoetryContext] = useState(null);
542
- useEffect(() => {
543
- if (!config.poetry.enabled)
544
- return;
545
- const onContextMenu = (event) => {
546
- if (event.defaultPrevented)
547
- return; // a link inside the couplet already took it
548
- const coupletElement = event.target?.closest?.('.likhari-poetry');
549
- if (!coupletElement)
550
- return;
551
- let handled = false;
481
+ const target = event.target;
482
+ const anchor = config.links ? (target?.closest?.('a') ?? null) : null;
483
+ const cell = config.tables ? (target?.closest?.('td, th') ?? null) : null;
484
+ const couplet = config.poetry.enabled ? (target?.closest?.('.likhari-poetry') ?? null) : null;
485
+ const point = config.language.spellCheck ? textPointAt(event.clientX, event.clientY) : null;
486
+ const menu = { x: event.clientX, y: event.clientY };
487
+ let word = null;
552
488
  editor.update(() => {
553
- const node = $getNearestNodeFromDOMNode(coupletElement);
554
- const couplet = node ? $findMatchingParent(node, $isPoetryBlockNode) : null;
555
- if (!couplet)
556
- return;
557
- handled = true;
558
- if (!$getPoetryBlockFromSelection())
559
- couplet.selectStart();
489
+ if (anchor) {
490
+ const node = $getNearestNodeFromDOMNode(anchor);
491
+ const link = node ? $findMatchingParent(node, $isLinkNode) : null;
492
+ if ($isLinkNode(link)) {
493
+ menu.link = link.getURL();
494
+ // Select the whole link first, so Edit / Remove act on it wherever the caret was.
495
+ link.select(0, link.getChildrenSize());
496
+ }
497
+ }
498
+ if (cell) {
499
+ const node = $getNearestNodeFromDOMNode(cell);
500
+ const tableCell = node ? $getTableCellNodeFromLexicalNode(node) : null;
501
+ if (tableCell) {
502
+ const selection = $getSelection();
503
+ // Keep a multi-cell selection that includes this cell.
504
+ const insideSelection = $isTableSelection(selection) && selection.getNodes().some((n) => n.getKey() === tableCell.getKey());
505
+ if (!insideSelection)
506
+ tableCell.selectEnd();
507
+ const size = $getTableSelectionSize();
508
+ menu.table = { rows: size.rows, columns: size.columns };
509
+ }
510
+ }
511
+ if (couplet) {
512
+ const node = $getNearestNodeFromDOMNode(couplet);
513
+ const block = node ? $findMatchingParent(node, $isPoetryBlockNode) : null;
514
+ if (block) {
515
+ menu.poetry = true;
516
+ if (!$getPoetryBlockFromSelection())
517
+ block.selectStart();
518
+ }
519
+ }
520
+ if (point)
521
+ word = $wordAtDomPoint(point.node, point.offset);
560
522
  }, { discrete: true });
561
- if (!handled)
562
- return;
563
- event.preventDefault();
564
- snapshotSelectionRef.current();
565
- setPoetryContext({ x: event.clientX, y: event.clientY });
523
+ if (word) {
524
+ const speller = getSpeller(word.direction === 'rtl' ? 'ur' : 'en');
525
+ if (speller) {
526
+ const checked = await speller;
527
+ if (!checked.correct(word.word)) {
528
+ menu.spelling = { suggestions: checked.suggest(word.word).slice(0, 5), match: word.match };
529
+ }
530
+ }
531
+ }
532
+ setContextMenu(menu);
566
533
  };
567
534
  return editor.registerRootListener((root, previous) => {
568
535
  previous?.removeEventListener('contextmenu', onContextMenu);
569
536
  root?.addEventListener('contextmenu', onContextMenu);
570
537
  });
571
- }, [editor, config.poetry.enabled]);
538
+ }, [editor, config.links, config.tables, config.poetry.enabled, config.language.spellCheck]);
539
+ // Cut and copy put the selected text on the clipboard as plain text.
540
+ const copyOrCut = (cut) => async () => {
541
+ restoreSelection();
542
+ let text = '';
543
+ editor.update(() => {
544
+ const selection = $getSelection();
545
+ if (!$isRangeSelection(selection))
546
+ return;
547
+ text = selection.getTextContent();
548
+ if (cut)
549
+ selection.removeText();
550
+ }, { discrete: true });
551
+ if (text)
552
+ await navigator.clipboard?.writeText(text).catch(() => undefined);
553
+ editor.focus();
554
+ };
555
+ // Paste reads plain text from the clipboard (the browser may ask for permission).
556
+ const paste = async () => {
557
+ restoreSelection();
558
+ let text;
559
+ try {
560
+ text = await navigator.clipboard.readText();
561
+ }
562
+ catch {
563
+ return;
564
+ }
565
+ editor.update(() => {
566
+ const selection = $getSelection();
567
+ if (!$isRangeSelection(selection))
568
+ return;
569
+ text.split(/\r?\n/).forEach((line, index) => {
570
+ if (index > 0)
571
+ selection.insertParagraph();
572
+ selection.insertText(line);
573
+ });
574
+ }, { discrete: true });
575
+ editor.focus();
576
+ };
572
577
  // Ctrl/Cmd+K opens the link dialog.
573
578
  useEffect(() => {
574
579
  if (!config.links)
@@ -811,25 +816,23 @@ export function Toolbar({ config, onSave, isDirty, showSave, findOpen = false, o
811
816
  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.findReplace && (_jsx(ToolbarButton, { icon: IconSearch, title: strings.findReplace.toggle, active: findOpen, onClick: onToggleFind })), config.poetry.enabled && locale !== 'en' && (_jsx(ToolbarButton, { icon: IconFeather, title: strings.toolbar.insertPoetryCouplet, onClick: () => editor.dispatchCommand(INSERT_POETRY_COUPLET_COMMAND, { layout: config.poetry.defaultLayout }) }))] }, "stubInsert")),
812
817
  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: runMenuAction }) })] }) }, "tableActions")),
813
818
  config.poetry.enabled && state.inPoetry && (_jsx("div", { className: "likhari-toolbar-group", children: _jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 200, 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.poetryOptions, title: strings.toolbar.poetryOptions, onMouseDown: (e) => e.preventDefault(), children: _jsx(IconFeather, { size: ICON_SIZE, stroke: ICON_STROKE }) }) }), _jsx(Menu.Dropdown, { children: _jsx(PoetryMenuItems, { strings: strings, layout: state.poetryLayout, scale: state.poetryScale, centered: state.poetryCentered, onAction: runMenuAction }) })] }) }, "poetryActions")),
814
- 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(ToolbarButton, { icon: IconAbc, title: strings.toolbar.spellChecker, active: spellOpen, onClick: onToggleSpell }))] }, "language")),
819
+ showLanguageGroup && (_jsxs("div", { className: "likhari-toolbar-group likhari-toolbar-group--collapse-tablet", children: [config.language.autocorrect && (_jsx(ToolbarButton, { icon: IconWand, title: strings.toolbar.autocorrect, active: autoCorrectOpen, onClick: onToggleAutoCorrect })), config.language.textCleanup && (_jsx(ToolbarButton, { icon: IconSparkles, title: strings.autoCorrect.correctDocument, onClick: () => editor.dispatchCommand(CORRECT_DOCUMENT_COMMAND, undefined) })), config.language.spellCheck && (_jsx(ToolbarButton, { icon: IconAbc, title: strings.toolbar.spellChecker, active: spellOpen, onClick: onToggleSpell }))] }, "language")),
815
820
  ];
816
821
  return (_jsxs("div", { className: "likhari-toolbar", role: "toolbar", "aria-label": strings.toolbar.ariaLabel, ref: toolbarContainerRef, children: [fixedGroups, movableGroups
817
822
  .filter((group) => !overflowGroupKeys.has(group.key))
818
823
  .map((group) => (_jsx(MovableGroupButtons, { group: group }, group.key))), overflowGroupKeys.size > 0 && (_jsxs(Menu, { position: "bottom-end", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 210, closeOnItemClick: true, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx("button", { type: "button", className: "likhari-toolbar-button", "aria-label": strings.toolbar.moreFormatting, title: strings.toolbar.moreFormatting, onMouseDown: (e) => e.preventDefault(), children: _jsx(IconDots, { size: ICON_SIZE, stroke: ICON_STROKE }) }) }), _jsx(Menu.Dropdown, { children: movableGroups
819
824
  .filter((group) => overflowGroupKeys.has(group.key))
820
- .flatMap((group) => group.items.map((item) => (_jsx(OverflowItem, { icon: item.icon, label: item.label, active: item.active, onClick: runOverflowAction(item.onClick) }, item.key)))) })] })), config.links && (_jsxs(Menu, { opened: linkContext !== null, onChange: (opened) => {
821
- if (!opened)
822
- setLinkContext(null);
823
- }, position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 240, children: [_jsx(Menu.Target, { children: _jsx("span", { "aria-hidden": "true", style: { position: 'fixed', left: linkContext?.x ?? -9999, top: linkContext?.y ?? -9999, width: 1, height: 1, pointerEvents: 'none' } }) }), _jsx(Menu.Dropdown, { children: _jsx(LinkMenuItems, { url: linkContext?.url ?? '', onEdit: () => {
824
- restoreSelection();
825
- openLinkDialog();
826
- }, onRemove: removeLink, strings: strings }) })] })), config.tables && (_jsxs(Menu, { opened: tableContext !== null, onChange: (opened) => {
827
- if (!opened)
828
- setTableContext(null);
829
- }, position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 240, children: [_jsx(Menu.Target, { children: _jsx("span", { "aria-hidden": "true", style: { position: 'fixed', left: tableContext?.x ?? -9999, top: tableContext?.y ?? -9999, width: 1, height: 1, pointerEvents: 'none' } }) }), _jsx(Menu.Dropdown, { children: _jsx(TableMenuItems, { strings: strings, direction: direction, rows: tableContext?.rows ?? 1, columns: tableContext?.columns ?? 1, canMergeCells: state.canMergeCells, canUnmergeCell: state.canUnmergeCell, onAction: runMenuAction }) })] })), config.poetry.enabled && (_jsxs(Menu, { opened: poetryContext !== null, onChange: (opened) => {
825
+ .flatMap((group) => group.items.map((item) => (_jsx(OverflowItem, { icon: item.icon, label: item.label, active: item.active, onClick: runOverflowAction(item.onClick) }, item.key)))) })] })), _jsxs(Menu, { opened: contextMenu !== null, onChange: (opened) => {
830
826
  if (!opened)
831
- setPoetryContext(null);
832
- }, position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 200, children: [_jsx(Menu.Target, { children: _jsx("span", { "aria-hidden": "true", style: { position: 'fixed', left: poetryContext?.x ?? -9999, top: poetryContext?.y ?? -9999, width: 1, height: 1, pointerEvents: 'none' } }) }), _jsx(Menu.Dropdown, { children: _jsx(PoetryMenuItems, { strings: strings, layout: state.poetryLayout, scale: state.poetryScale, centered: state.poetryCentered, onAction: runMenuAction }) })] })), _jsxs("div", { "aria-hidden": "true", ref: toolbarMeasureRef, style: {
827
+ setContextMenu(null);
828
+ }, position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 260, children: [_jsx(Menu.Target, { children: _jsx("span", { "aria-hidden": "true", style: { position: 'fixed', left: contextMenu?.x ?? -9999, top: contextMenu?.y ?? -9999, width: 1, height: 1, pointerEvents: 'none' } }) }), _jsxs(Menu.Dropdown, { children: [contextMenu?.spelling && (_jsxs(_Fragment, { children: [_jsx(Menu.Label, { children: strings.contextMenu.spelling }), contextMenu.spelling.suggestions.length === 0 && _jsx(Menu.Item, { disabled: true, children: strings.contextMenu.noSuggestions }), contextMenu.spelling.suggestions.map((suggestion) => (_jsx(Menu.Item, { onClick: () => {
829
+ const match = contextMenu.spelling.match;
830
+ editor.update(() => $replaceMatch(match, suggestion), { discrete: true });
831
+ editor.focus();
832
+ }, children: suggestion }, suggestion))), _jsx(Menu.Divider, {})] })), contextMenu?.link !== undefined && (_jsxs(_Fragment, { children: [_jsx(LinkMenuItems, { url: contextMenu.link, onEdit: () => {
833
+ restoreSelection();
834
+ openLinkDialog();
835
+ }, onRemove: removeLink, strings: strings }), _jsx(Menu.Divider, {})] })), contextMenu?.table && (_jsxs(_Fragment, { children: [_jsx(TableMenuItems, { strings: strings, direction: direction, rows: contextMenu.table.rows, columns: contextMenu.table.columns, canMergeCells: state.canMergeCells, canUnmergeCell: state.canUnmergeCell, onAction: runMenuAction }), _jsx(Menu.Divider, {})] })), contextMenu?.poetry && (_jsxs(_Fragment, { children: [_jsx(PoetryMenuItems, { strings: strings, layout: state.poetryLayout, scale: state.poetryScale, centered: state.poetryCentered, onAction: runMenuAction }), _jsx(Menu.Divider, {})] })), _jsx(Menu.Item, { leftSection: _jsx(IconCut, { size: ICON_SIZE, stroke: ICON_STROKE }), onClick: () => void copyOrCut(true)(), children: strings.contextMenu.cut }), _jsx(Menu.Item, { leftSection: _jsx(IconCopy, { size: ICON_SIZE, stroke: ICON_STROKE }), onClick: () => void copyOrCut(false)(), children: strings.contextMenu.copy }), _jsx(Menu.Item, { leftSection: _jsx(IconClipboard, { size: ICON_SIZE, stroke: ICON_STROKE }), onClick: () => void paste(), children: strings.contextMenu.paste }), _jsx(Menu.Item, { leftSection: _jsx(IconSelectAll, { size: ICON_SIZE, stroke: ICON_STROKE }), onClick: runMenuAction(() => $selectAll()), children: strings.contextMenu.selectAll })] })] }), _jsxs("div", { "aria-hidden": "true", ref: toolbarMeasureRef, style: {
833
836
  position: 'absolute',
834
837
  visibility: 'hidden',
835
838
  pointerEvents: 'none',
@@ -179,6 +179,28 @@ export interface Strings {
179
179
  next: string;
180
180
  noSuggestions: string;
181
181
  };
182
+ autoCorrect: {
183
+ title: string;
184
+ language: string;
185
+ from: string;
186
+ fromPlaceholder: string;
187
+ to: string;
188
+ toPlaceholder: string;
189
+ save: string;
190
+ saved: string;
191
+ noWritableStore: string;
192
+ failed: string;
193
+ close: string;
194
+ correctDocument: string;
195
+ };
196
+ contextMenu: {
197
+ cut: string;
198
+ copy: string;
199
+ paste: string;
200
+ selectAll: string;
201
+ spelling: string;
202
+ noSuggestions: string;
203
+ };
182
204
  link: {
183
205
  menuLabel: string;
184
206
  noUrl: 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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"}