@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.
- package/dist/EditorRoot.d.ts +9 -0
- package/dist/EditorRoot.d.ts.map +1 -1
- package/dist/EditorRoot.js +12 -11
- package/dist/autocorrect/AutoCorrectPlugin.d.ts +27 -0
- package/dist/autocorrect/AutoCorrectPlugin.d.ts.map +1 -0
- package/dist/autocorrect/AutoCorrectPlugin.js +108 -0
- package/dist/autocorrect/autoCorrectActions.d.ts +35 -0
- package/dist/autocorrect/autoCorrectActions.d.ts.map +1 -0
- package/dist/autocorrect/autoCorrectActions.js +182 -0
- package/dist/autocorrect/autoCorrectStores.d.ts +52 -0
- package/dist/autocorrect/autoCorrectStores.d.ts.map +1 -0
- package/dist/autocorrect/autoCorrectStores.js +115 -0
- package/dist/autocorrect/punctuationRules.d.ts +26 -0
- package/dist/autocorrect/punctuationRules.d.ts.map +1 -0
- package/dist/autocorrect/punctuationRules.js +53 -0
- package/dist/cleanup/textCleanupActions.d.ts +8 -0
- package/dist/cleanup/textCleanupActions.d.ts.map +1 -0
- package/dist/cleanup/textCleanupActions.js +28 -0
- package/dist/components/AutoCorrectPanel.d.ts +15 -0
- package/dist/components/AutoCorrectPanel.d.ts.map +1 -0
- package/dist/components/AutoCorrectPanel.js +44 -0
- package/dist/components/Toolbar.d.ts +4 -1
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/Toolbar.js +112 -109
- package/dist/i18n/strings.d.ts +22 -0
- package/dist/i18n/strings.d.ts.map +1 -1
- package/dist/i18n/strings.js +71 -5
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/normalization/urduNormalize.d.ts +24 -0
- package/dist/normalization/urduNormalize.d.ts.map +1 -0
- package/dist/normalization/urduNormalize.js +116 -0
- package/dist/spellcheck/spellingMenu.d.ts +15 -0
- package/dist/spellcheck/spellingMenu.d.ts.map +1 -0
- package/dist/spellcheck/spellingMenu.js +27 -0
- package/dist/theme/editor.css +58 -0
- 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":"
|
|
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
|
-
//
|
|
467
|
-
|
|
468
|
-
|
|
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
|
-
|
|
504
|
-
const [tableContext, setTableContext] = useState(null);
|
|
476
|
+
const [contextMenu, setContextMenu] = useState(null);
|
|
505
477
|
useEffect(() => {
|
|
506
|
-
|
|
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
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
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
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
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 (
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
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(
|
|
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)))) })] })),
|
|
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
|
-
|
|
832
|
-
}, position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width:
|
|
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',
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -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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"}
|