@inshapardaz/likhari-react 0.1.29 → 0.1.31-dev.270
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/components/Toolbar.d.ts +6 -0
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/Toolbar.js +100 -10
- package/dist/i18n/strings.d.ts +3 -0
- package/dist/i18n/strings.d.ts.map +1 -1
- package/dist/i18n/strings.js +6 -0
- package/dist/join/joinLinesActions.d.ts +9 -0
- package/dist/join/joinLinesActions.d.ts.map +1 -0
- package/dist/join/joinLinesActions.js +89 -0
- package/dist/theme/editor.css +13 -3
- package/package.json +3 -3
|
@@ -11,6 +11,12 @@ export interface ToolbarStyle {
|
|
|
11
11
|
bordered?: boolean;
|
|
12
12
|
/** `light` tints the active button, `filled` fills it with the accent. Default `light`. */
|
|
13
13
|
variant?: 'light' | 'filled';
|
|
14
|
+
/**
|
|
15
|
+
* Move the lowest-priority groups into a "..." menu once the toolbar no
|
|
16
|
+
* longer fits its width (UI spec §3.3). `false` keeps every group inline
|
|
17
|
+
* and lets the toolbar wrap onto as many rows as it needs. Default `true`.
|
|
18
|
+
*/
|
|
19
|
+
overflow?: boolean;
|
|
14
20
|
}
|
|
15
21
|
export interface ToolbarProps {
|
|
16
22
|
config: ResolvedEditorFeatureConfig;
|
|
@@ -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":"AA2CA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAgDtF,OAAO,EAAgB,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAA6D,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAItG,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,iBAAiB,CAAC;AA8gBvD,0FAA0F;AAC1F,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,2BAA2B,CAAC;IACpC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,gCAAgC;IAChC,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,aAAa,EAAE,CAAC;IACnC,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IACnE,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,iGAAiG;IACjG,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sEAAsE;IACtE,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,wFAAwF;IACxF,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAqB,EAAE,eAAoB,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAgB,EAAE,YAAY,EAAE,SAAiB,EAAE,aAAa,EAAE,eAAuB,EAAE,mBAAmB,EAAE,WAAkC,EAAE,SAAiB,EAAE,MAAa,EAAE,MAAM,EAAE,EAAE,YAAY,+BAuqCrV"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Fragment, forwardRef, useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { Fragment, forwardRef, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { Menu, Select, Toolbar as MantineToolbar } from '@mantine/core';
|
|
4
4
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
5
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';
|
|
@@ -9,6 +9,7 @@ import { $createHeadingNode, $createQuoteNode, $isHeadingNode, $isQuoteNode } fr
|
|
|
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
11
|
import { CORRECT_DOCUMENT_COMMAND } from '../autocorrect/AutoCorrectPlugin.js';
|
|
12
|
+
import { $canJoinLines, $joinSelectedLines } from '../join/joinLinesActions.js';
|
|
12
13
|
import { $replaceMatch } from '../find/findReplaceActions.js';
|
|
13
14
|
import { getSpeller } from '../spellcheck/spellDictionaries.js';
|
|
14
15
|
import { lookupSynonyms } from '../thesaurus/thesaurusStores.js';
|
|
@@ -35,12 +36,13 @@ import { CANVAS_FONT_DEFAULTS, DEFAULT_FONT_OPTIONS, FONT_SIZES_PX } from '../fo
|
|
|
35
36
|
import { setStyleProperty } from '../utils/style.js';
|
|
36
37
|
import { useStrings } from '../i18n/useStrings.js';
|
|
37
38
|
import { usePortalTarget } from '../PortalTargetContext.js';
|
|
38
|
-
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';
|
|
39
|
+
import { IconAbc, IconAlignCenter, IconAlignJustified, IconAlignLeft, IconAlignRight, IconArrowBackUp, IconArrowForwardUp, IconArrowsJoin, 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';
|
|
39
40
|
/** Sentinel for "no inline style": Lexical returns the default it is given when
|
|
40
41
|
* the selection has none, so this tells "unstyled" (show the canvas default)
|
|
41
42
|
* apart from "styled with a value the dropdown doesn't list" (show nothing). */
|
|
42
43
|
const UNSET_STYLE = '__unset__';
|
|
43
44
|
const INITIAL_STATE = {
|
|
45
|
+
canJoinLines: false,
|
|
44
46
|
blockType: 'paragraph',
|
|
45
47
|
activeFormats: new Set(),
|
|
46
48
|
elementFormat: 'start',
|
|
@@ -121,6 +123,15 @@ function withDividers(sections) {
|
|
|
121
123
|
.filter((section) => Boolean(section))
|
|
122
124
|
.flatMap((section, index) => (index === 0 ? [section] : [_jsx(MantineToolbar.Divider, {}, `divider-${index}`), section]));
|
|
123
125
|
}
|
|
126
|
+
const EMPTY_OVERFLOW = new Set();
|
|
127
|
+
function setsEqual(a, b) {
|
|
128
|
+
if (a.size !== b.size)
|
|
129
|
+
return false;
|
|
130
|
+
for (const v of a)
|
|
131
|
+
if (!b.has(v))
|
|
132
|
+
return false;
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
124
135
|
/** Mantine Select (combobox) for the toolbar's dropdown controls. The icon
|
|
125
136
|
* labels the control itself, since a dropdown can't show one per option in
|
|
126
137
|
* its closed state. The dropdown portals to <body>, so it is not clipped by
|
|
@@ -177,6 +188,7 @@ function PoetryMenuItems({ strings, layout, scale, centered, onAction, }) {
|
|
|
177
188
|
export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurusStores = [], onAddAutoCorrect, onSave, isDirty, showSave, findOpen = false, onToggleFind, spellOpen = false, onToggleSpell, autoCorrectOpen = false, onToggleAutoCorrect, fontOptions = DEFAULT_FONT_OPTIONS, direction = 'ltr', locale = 'en', drafts }) {
|
|
178
189
|
const bordered = toolbarStyle?.bordered ?? true;
|
|
179
190
|
const variant = toolbarStyle?.variant ?? 'light';
|
|
191
|
+
const overflowEnabled = toolbarStyle?.overflow ?? true;
|
|
180
192
|
const [editor] = useLexicalComposerContext();
|
|
181
193
|
const [state, setState] = useState(INITIAL_STATE);
|
|
182
194
|
const strings = useStrings(locale);
|
|
@@ -184,6 +196,17 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
184
196
|
const [draftsOpen, setDraftsOpen] = useState(false);
|
|
185
197
|
const rtl = direction === 'rtl';
|
|
186
198
|
const ALIGN_ICONS = rtl ? ALIGN_ICONS_RTL : ALIGN_ICONS_LTR;
|
|
199
|
+
// Responsive "priority+" overflow (UI spec §3.3): the toolbar's outer
|
|
200
|
+
// container and a hidden nowrap clone (every movable group forced inline)
|
|
201
|
+
// are both measured; whenever the clone's natural width exceeds the
|
|
202
|
+
// container's available width, the lowest-priority movable groups move
|
|
203
|
+
// into the "..." menu, lowest-priority first, until what remains inline
|
|
204
|
+
// fits (or nothing is left to move). Font and insert are overflow-menu
|
|
205
|
+
// items per spec §3.1's closing note, and tools (autocorrect, spellcheck,
|
|
206
|
+
// join lines) is lower priority still, so it is first to move.
|
|
207
|
+
const toolbarContainerRef = useRef(null);
|
|
208
|
+
const toolbarMeasureRef = useRef(null);
|
|
209
|
+
const [overflowGroupKeys, setOverflowGroupKeys] = useState(EMPTY_OVERFLOW);
|
|
187
210
|
const updateToolbar = useCallback(() => {
|
|
188
211
|
editor.getEditorState().read(() => {
|
|
189
212
|
const selection = $getSelection();
|
|
@@ -226,6 +249,7 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
226
249
|
// Lexical's read/update context has already closed, so any $-prefixed
|
|
227
250
|
// node method (getFormatType() included) must not be deferred into it.
|
|
228
251
|
const elementFormat = ($isElementNode(element) ? element.getFormatType() : 'start') || 'start';
|
|
252
|
+
const canJoinLines = $canJoinLines();
|
|
229
253
|
const poetryLayout = poetryBlock?.getLayout();
|
|
230
254
|
const poetryCentered = $getCoupletCenteredFromSelection();
|
|
231
255
|
const poetryScale = poetryBlock
|
|
@@ -233,6 +257,7 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
233
257
|
: null;
|
|
234
258
|
setState((s) => ({
|
|
235
259
|
...s,
|
|
260
|
+
canJoinLines,
|
|
236
261
|
blockType,
|
|
237
262
|
activeFormats,
|
|
238
263
|
elementFormat,
|
|
@@ -502,6 +527,10 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
502
527
|
}
|
|
503
528
|
if (point)
|
|
504
529
|
word = $wordAtDomPoint(point.node, point.offset);
|
|
530
|
+
if (!cell && !couplet && config.joinLines) {
|
|
531
|
+
menu.text = true;
|
|
532
|
+
menu.canJoin = $canJoinLines();
|
|
533
|
+
}
|
|
505
534
|
}, { discrete: true });
|
|
506
535
|
const language = word?.direction === 'rtl' ? 'ur' : 'en';
|
|
507
536
|
if (word && config.language.thesaurus) {
|
|
@@ -530,7 +559,7 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
530
559
|
previous?.removeEventListener('contextmenu', onContextMenu);
|
|
531
560
|
root?.addEventListener('contextmenu', onContextMenu);
|
|
532
561
|
});
|
|
533
|
-
}, [editor, config.links, config.tables, config.poetry.enabled, config.language.spellCheck, config.language.thesaurus, thesaurusStores]);
|
|
562
|
+
}, [editor, config.links, config.tables, config.poetry.enabled, config.language.spellCheck, config.language.thesaurus, config.joinLines, thesaurusStores]);
|
|
534
563
|
// Cut and copy put the selected text on the clipboard as plain text.
|
|
535
564
|
const copyOrCut = (cut) => async () => {
|
|
536
565
|
restoreSelection();
|
|
@@ -639,7 +668,6 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
639
668
|
(config.poetry.enabled && locale !== 'en') ||
|
|
640
669
|
(config.tables && state.inTable) ||
|
|
641
670
|
(config.poetry.enabled && state.inPoetry);
|
|
642
|
-
const showLanguageGroup = config.language.autocorrect || config.language.textCleanup || config.language.spellCheck;
|
|
643
671
|
const moreItems = [];
|
|
644
672
|
if (fmt.superscript) {
|
|
645
673
|
moreItems.push({
|
|
@@ -733,18 +761,78 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
733
761
|
restoreSelection();
|
|
734
762
|
openLinkDialog();
|
|
735
763
|
}, onRemove: removeLink, strings: strings }) })] })) : (_jsx(ToolbarButton, { icon: IconLink, title: strings.toolbar.insertLink, onClick: openLinkDialog }))), (config.images.linked || config.images.embedded) && (_jsx(ToolbarButton, { icon: IconPhoto, title: strings.toolbar.insertImage, onClick: openImageDialog })), config.blocks.horizontalRule && (_jsx(ToolbarButton, { icon: IconSeparatorHorizontal, title: strings.toolbar.insertHorizontalRule, onClick: () => editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, undefined) })), config.tables && _jsx(ToolbarButton, { icon: IconTable, title: strings.toolbar.insertTable, onClick: openTableDialog }), config.tables && state.inTable && (_jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 240, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx(ToolbarButton, { icon: IconTableOptions, title: strings.toolbar.tableOptions, active: true, "aria-haspopup": "menu" }) }), _jsx(Menu.Dropdown, { children: _jsx(TableMenuItems, { strings: strings, direction: direction, rows: state.tableRows, columns: state.tableColumns, canMergeCells: state.canMergeCells, canUnmergeCell: state.canUnmergeCell, onAction: runMenuAction }) })] })), 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.pageBreak && (_jsx(ToolbarButton, { icon: IconPageBreak, title: strings.toolbar.insertPageBreak, onClick: () => editor.dispatchCommand(INSERT_PAGE_BREAK_COMMAND, undefined) })), config.poetry.enabled && locale !== 'en' && (_jsx(ToolbarButton, { icon: IconFeather, title: strings.toolbar.insertPoetryCouplet, onClick: () => editor.dispatchCommand(INSERT_POETRY_COUPLET_COMMAND, { layout: config.poetry.defaultLayout }) })), config.poetry.enabled && state.inPoetry && (_jsxs(Menu, { position: "bottom-start", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: 200, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx(ToolbarButton, { icon: IconFeather, title: strings.toolbar.poetryOptions, active: true, "aria-haspopup": "menu" }) }), _jsx(Menu.Dropdown, { children: _jsx(PoetryMenuItems, { strings: strings, layout: state.poetryLayout, scale: state.poetryScale, centered: state.poetryCentered, onAction: runMenuAction }) })] }))] }, "insert"));
|
|
736
|
-
const
|
|
764
|
+
const joinLines = () => {
|
|
765
|
+
editor.update(() => {
|
|
766
|
+
$joinSelectedLines();
|
|
767
|
+
}, { discrete: true });
|
|
768
|
+
editor.focus();
|
|
769
|
+
};
|
|
770
|
+
const toolsSection = (_jsxs(MantineToolbar.Group, { className: "likhari-toolbar-cluster", 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 })), config.joinLines && (_jsx(ToolbarButton, { icon: IconArrowsJoin, title: strings.toolbar.joinLines, disabled: !state.canJoinLines, onClick: joinLines }))] }, "tools"));
|
|
737
771
|
const endSection = (drafts || config.findReplace) && (_jsxs(MantineToolbar.Group, { className: "likhari-toolbar-cluster", style: { marginInlineStart: 'auto' }, children: [drafts && _jsx(ToolbarButton, { icon: IconHistory, title: strings.toolbar.drafts, onClick: () => setDraftsOpen(true) }), config.findReplace && (_jsx(ToolbarButton, { icon: IconSearch, title: strings.findReplace.toggle, active: findOpen, onClick: onToggleFind }))] }, "end"));
|
|
738
772
|
const startSections = [
|
|
739
773
|
showSave && (_jsx(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: _jsx(ToolbarButton, { icon: IconDeviceFloppy, title: strings.toolbar.save, dirty: Boolean(isDirty), onClick: onSave }) }, "save")),
|
|
740
774
|
config.history && (_jsxs(MantineToolbar.Group, { className: "likhari-toolbar-cluster", children: [_jsx(ToolbarButton, { icon: IconArrowBackUp, title: strings.toolbar.undo, disabled: !state.canUndo, onClick: () => editor.dispatchCommand(UNDO_COMMAND, undefined) }), _jsx(ToolbarButton, { icon: IconArrowForwardUp, title: strings.toolbar.redo, disabled: !state.canRedo, onClick: () => editor.dispatchCommand(REDO_COMMAND, undefined) })] }, "history")),
|
|
741
775
|
formatSection,
|
|
742
776
|
alignSection,
|
|
743
|
-
fontSection,
|
|
744
|
-
insertSection,
|
|
745
|
-
toolsSection,
|
|
746
777
|
];
|
|
747
|
-
|
|
778
|
+
// Lowest priority first: the first to move into the "..." menu once the
|
|
779
|
+
// toolbar stops fitting its available width.
|
|
780
|
+
const movableSections = [
|
|
781
|
+
{ key: 'tools', node: toolsSection },
|
|
782
|
+
{ key: 'font', node: fontSection },
|
|
783
|
+
{ key: 'insert', node: insertSection },
|
|
784
|
+
].filter((section) => Boolean(section.node));
|
|
785
|
+
const movableGroupKeys = useMemo(() => movableSections.map((section) => section.key).join(','), [movableSections]);
|
|
786
|
+
// Re-measure whenever the container is resized, or whenever the set of
|
|
787
|
+
// movable sections (and so the hidden clone's content) changes.
|
|
788
|
+
useLayoutEffect(() => {
|
|
789
|
+
if (!overflowEnabled) {
|
|
790
|
+
setOverflowGroupKeys((prev) => (prev.size === 0 ? prev : EMPTY_OVERFLOW));
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
const container = toolbarContainerRef.current;
|
|
794
|
+
const measure = toolbarMeasureRef.current;
|
|
795
|
+
if (!container || !measure)
|
|
796
|
+
return;
|
|
797
|
+
// Rough width of the "..." button itself (icon button + its gap) —
|
|
798
|
+
// only charged against the budget once something has actually moved
|
|
799
|
+
// into it, since it isn't rendered at all otherwise.
|
|
800
|
+
const OVERFLOW_BUTTON_WIDTH = 38;
|
|
801
|
+
const recompute = () => {
|
|
802
|
+
const available = container.clientWidth;
|
|
803
|
+
const total = measure.scrollWidth;
|
|
804
|
+
if (total <= available) {
|
|
805
|
+
setOverflowGroupKeys((prev) => (prev.size === 0 ? prev : EMPTY_OVERFLOW));
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
const widths = new Map();
|
|
809
|
+
measure.querySelectorAll('[data-group-key]').forEach((el) => {
|
|
810
|
+
widths.set(el.dataset.groupKey, el.getBoundingClientRect().width);
|
|
811
|
+
});
|
|
812
|
+
let remaining = total;
|
|
813
|
+
const next = new Set();
|
|
814
|
+
for (const key of movableGroupKeys.split(',').filter(Boolean)) {
|
|
815
|
+
if (remaining <= available)
|
|
816
|
+
break;
|
|
817
|
+
const w = widths.get(key);
|
|
818
|
+
if (w === undefined)
|
|
819
|
+
continue;
|
|
820
|
+
remaining -= w;
|
|
821
|
+
next.add(key);
|
|
822
|
+
}
|
|
823
|
+
if (next.size > 0)
|
|
824
|
+
remaining += OVERFLOW_BUTTON_WIDTH;
|
|
825
|
+
setOverflowGroupKeys((prev) => (setsEqual(prev, next) ? prev : next));
|
|
826
|
+
};
|
|
827
|
+
recompute();
|
|
828
|
+
const ro = new ResizeObserver(recompute);
|
|
829
|
+
ro.observe(container);
|
|
830
|
+
ro.observe(measure);
|
|
831
|
+
return () => ro.disconnect();
|
|
832
|
+
});
|
|
833
|
+
const visibleMovable = movableSections.filter((section) => !overflowGroupKeys.has(section.key));
|
|
834
|
+
const hiddenMovable = movableSections.filter((section) => overflowGroupKeys.has(section.key));
|
|
835
|
+
return (_jsxs(MantineToolbar, { ref: toolbarContainerRef, "aria-label": strings.toolbar.ariaLabel, className: bordered ? 'likhari-toolbar' : 'likhari-toolbar likhari-toolbar--plain', withBorder: bordered, variant: variant, color: "var(--editor-accent)", children: [withDividers(startSections), visibleMovable.map((section) => (_jsxs(Fragment, { children: [_jsx(MantineToolbar.Divider, {}), section.node] }, section.key))), hiddenMovable.length > 0 && (_jsxs(_Fragment, { children: [_jsx(MantineToolbar.Divider, {}), _jsxs(Menu, { position: "bottom-end", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: "max-content", closeOnItemClick: false, onOpen: snapshotSelection, children: [_jsx(Menu.Target, { children: _jsx(ToolbarButton, { icon: IconDots, title: strings.toolbar.moreFormatting }) }), _jsx(Menu.Dropdown, { p: 6, children: _jsx(MantineToolbar, { withBorder: false, variant: variant, color: "var(--editor-accent)", style: { maxWidth: 320 }, children: withDividers(hiddenMovable.map((section) => section.node)) }) })] })] })), endSection, _jsxs(Menu, { opened: contextMenu !== null, onChange: (opened) => {
|
|
748
836
|
if (!opened)
|
|
749
837
|
setContextMenu(null);
|
|
750
838
|
}, 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: () => {
|
|
@@ -772,5 +860,7 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
772
860
|
}, children: synonym }, synonym))), _jsx(Menu.Divider, {})] })), contextMenu?.link !== undefined && (_jsxs(_Fragment, { children: [_jsx(LinkMenuItems, { url: contextMenu.link, onEdit: () => {
|
|
773
861
|
restoreSelection();
|
|
774
862
|
openLinkDialog();
|
|
775
|
-
}, 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, {})] })),
|
|
863
|
+
}, 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, {})] })), contextMenu?.text && (_jsxs(_Fragment, { children: [_jsx(Menu.Item, { leftSection: _jsx(IconArrowsJoin, { size: ICON_SIZE, stroke: ICON_STROKE }), disabled: !contextMenu.canJoin, onClick: runMenuAction(() => {
|
|
864
|
+
$joinSelectedLines();
|
|
865
|
+
}), children: strings.contextMenu.joinLines }), _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 })] })] }), overflowEnabled && (_jsxs(MantineToolbar, { "aria-hidden": "true", ref: toolbarMeasureRef, withBorder: bordered, variant: variant, color: "var(--editor-accent)", style: { position: 'absolute', visibility: 'hidden', pointerEvents: 'none', top: 0, left: 0, flexWrap: 'nowrap', width: 'max-content' }, children: [withDividers(startSections), movableSections.map((section) => (_jsxs(Fragment, { children: [_jsx(MantineToolbar.Divider, {}), _jsx("span", { "data-group-key": section.key, style: { display: 'inline-flex' }, children: section.node })] }, section.key)))] })), (config.images.linked || config.images.embedded) && (_jsx(ImageDialog, { mode: "insert", opened: imageDialogOpen, onSubmit: insertImage, onClose: closeImageDialog })), config.tables && _jsx(TableDialog, { opened: tableDialogOpen, onSubmit: insertTable, onClose: closeTableDialog }), config.columns && _jsx(LayoutDialog, { opened: layoutDialogOpen, onSubmit: insertLayout, onClose: closeLayoutDialog }), config.links && (_jsx(LinkDialog, { opened: linkDialogOpen, initialUrl: state.linkUrl, showTextField: linkNeedsText, onSubmit: applyLink, onRemove: state.isLink ? removeLink : undefined, onClose: closeLinkDialog })), drafts && _jsx(DraftsDialog, { opened: draftsOpen, locale: locale, onClose: () => setDraftsOpen(false), ...drafts })] }));
|
|
776
866
|
}
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -56,6 +56,8 @@ export interface Strings {
|
|
|
56
56
|
autocorrect: string;
|
|
57
57
|
textCleanup: string;
|
|
58
58
|
spellChecker: string;
|
|
59
|
+
/** Joins the selected lines into one paragraph. */
|
|
60
|
+
joinLines: string;
|
|
59
61
|
moreFormatting: string;
|
|
60
62
|
strikethrough: string;
|
|
61
63
|
superscript: string;
|
|
@@ -195,6 +197,7 @@ export interface Strings {
|
|
|
195
197
|
};
|
|
196
198
|
contextMenu: {
|
|
197
199
|
cut: string;
|
|
200
|
+
joinLines: string;
|
|
198
201
|
copy: string;
|
|
199
202
|
paste: string;
|
|
200
203
|
selectAll: 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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"}
|
package/dist/i18n/strings.js
CHANGED
|
@@ -46,6 +46,7 @@ const en = {
|
|
|
46
46
|
autocorrect: 'Auto-correct',
|
|
47
47
|
textCleanup: 'Text cleanup',
|
|
48
48
|
spellChecker: 'Spell-checker',
|
|
49
|
+
joinLines: 'Join lines',
|
|
49
50
|
moreFormatting: 'More formatting',
|
|
50
51
|
strikethrough: 'Strikethrough',
|
|
51
52
|
superscript: 'Superscript',
|
|
@@ -178,6 +179,7 @@ const en = {
|
|
|
178
179
|
},
|
|
179
180
|
contextMenu: {
|
|
180
181
|
cut: 'Cut',
|
|
182
|
+
joinLines: 'Join lines',
|
|
181
183
|
copy: 'Copy',
|
|
182
184
|
paste: 'Paste',
|
|
183
185
|
selectAll: 'Select all',
|
|
@@ -322,6 +324,7 @@ const ur = {
|
|
|
322
324
|
autocorrect: 'خودکار تصحیح',
|
|
323
325
|
textCleanup: 'متن کی صفائی',
|
|
324
326
|
spellChecker: 'ہجے چیک کرنے والا',
|
|
327
|
+
joinLines: 'سطریں ملائیں',
|
|
325
328
|
moreFormatting: 'مزید فارمیٹنگ',
|
|
326
329
|
strikethrough: 'خط زدہ',
|
|
327
330
|
superscript: 'بالا نویس',
|
|
@@ -454,6 +457,7 @@ const ur = {
|
|
|
454
457
|
},
|
|
455
458
|
contextMenu: {
|
|
456
459
|
cut: 'کاٹیں',
|
|
460
|
+
joinLines: 'سطریں ملائیں',
|
|
457
461
|
copy: 'کاپی کریں',
|
|
458
462
|
paste: 'چسپاں کریں',
|
|
459
463
|
selectAll: 'سب منتخب کریں',
|
|
@@ -598,6 +602,7 @@ const paShahmukhi = {
|
|
|
598
602
|
autocorrect: 'خودکار درستی',
|
|
599
603
|
textCleanup: 'متن دی صفائی',
|
|
600
604
|
spellChecker: 'ہجے چیکر',
|
|
605
|
+
joinLines: 'سطراں ملاؤ',
|
|
601
606
|
moreFormatting: 'ہور فارمیٹنگ',
|
|
602
607
|
strikethrough: 'کٹی لکیر',
|
|
603
608
|
superscript: 'اُتلا لکھت',
|
|
@@ -730,6 +735,7 @@ const paShahmukhi = {
|
|
|
730
735
|
},
|
|
731
736
|
contextMenu: {
|
|
732
737
|
cut: 'کٹو',
|
|
738
|
+
joinLines: 'سطراں ملاؤ',
|
|
733
739
|
copy: 'کاپی کرو',
|
|
734
740
|
paste: 'چسپاں کرو',
|
|
735
741
|
selectAll: 'سارا چنو',
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function $canJoinLines(): boolean;
|
|
2
|
+
/**
|
|
3
|
+
* Joins the lines in the selection into one paragraph. Soft breaks and the
|
|
4
|
+
* paragraph breaks between selected paragraphs become a single space each,
|
|
5
|
+
* unless there is already a space at that point. A soft break right after the
|
|
6
|
+
* selection becomes a paragraph break, so the joined text stands on its own.
|
|
7
|
+
*/
|
|
8
|
+
export declare function $joinSelectedLines(): boolean;
|
|
9
|
+
//# sourceMappingURL=joinLinesActions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"joinLinesActions.d.ts","sourceRoot":"","sources":["../../src/join/joinLinesActions.ts"],"names":[],"mappings":"AAyBA,wBAAgB,aAAa,IAAI,OAAO,CAKvC;AAuCD;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAyB5C"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { $createTextNode, $getSelection, $isLineBreakNode, $isParagraphNode, $isRangeSelection, $createParagraphNode, } from 'lexical';
|
|
2
|
+
function $paragraphsInSelection(selection) {
|
|
3
|
+
const seen = new Set();
|
|
4
|
+
const paragraphs = [];
|
|
5
|
+
for (const node of selection.getNodes()) {
|
|
6
|
+
const block = node.getTopLevelElement();
|
|
7
|
+
if (!block || !$isParagraphNode(block) || seen.has(block.getKey()))
|
|
8
|
+
continue;
|
|
9
|
+
seen.add(block.getKey());
|
|
10
|
+
paragraphs.push(block);
|
|
11
|
+
}
|
|
12
|
+
return paragraphs;
|
|
13
|
+
}
|
|
14
|
+
export function $canJoinLines() {
|
|
15
|
+
const selection = $getSelection();
|
|
16
|
+
if (!$isRangeSelection(selection) || selection.isCollapsed())
|
|
17
|
+
return false;
|
|
18
|
+
if ($paragraphsInSelection(selection).length > 1)
|
|
19
|
+
return true;
|
|
20
|
+
return selection.getNodes().some($isLineBreakNode);
|
|
21
|
+
}
|
|
22
|
+
/** A soft break becomes one space, unless the text either side already has a space there. */
|
|
23
|
+
function $replaceBreakWithSpace(lineBreak) {
|
|
24
|
+
const before = lineBreak.getPreviousSibling()?.getTextContent() ?? '';
|
|
25
|
+
const after = lineBreak.getNextSibling()?.getTextContent() ?? '';
|
|
26
|
+
if (before === '' || after === '' || /\s$/.test(before) || /^\s/.test(after)) {
|
|
27
|
+
lineBreak.remove();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
lineBreak.replace($createTextNode(' '));
|
|
31
|
+
}
|
|
32
|
+
/** Moves a paragraph's content onto the end of the target, with a space between when needed. */
|
|
33
|
+
function $appendParagraph(target, paragraph) {
|
|
34
|
+
const content = paragraph.getTextContent();
|
|
35
|
+
if (content !== '') {
|
|
36
|
+
const targetText = target.getTextContent();
|
|
37
|
+
if (targetText !== '' && !/\s$/.test(targetText) && !/^\s/.test(content)) {
|
|
38
|
+
target.append($createTextNode(' '));
|
|
39
|
+
}
|
|
40
|
+
for (const child of paragraph.getChildren())
|
|
41
|
+
target.append(child);
|
|
42
|
+
}
|
|
43
|
+
paragraph.remove();
|
|
44
|
+
}
|
|
45
|
+
/** Turns a soft break into a paragraph break: the content after it moves to a new paragraph. */
|
|
46
|
+
function $splitParagraphAt(lineBreak, paragraph) {
|
|
47
|
+
const rest = $createParagraphNode();
|
|
48
|
+
let sibling = lineBreak.getNextSibling();
|
|
49
|
+
while (sibling) {
|
|
50
|
+
const next = sibling.getNextSibling();
|
|
51
|
+
rest.append(sibling);
|
|
52
|
+
sibling = next;
|
|
53
|
+
}
|
|
54
|
+
lineBreak.remove();
|
|
55
|
+
paragraph.insertAfter(rest);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Joins the lines in the selection into one paragraph. Soft breaks and the
|
|
59
|
+
* paragraph breaks between selected paragraphs become a single space each,
|
|
60
|
+
* unless there is already a space at that point. A soft break right after the
|
|
61
|
+
* selection becomes a paragraph break, so the joined text stands on its own.
|
|
62
|
+
*/
|
|
63
|
+
export function $joinSelectedLines() {
|
|
64
|
+
const selection = $getSelection();
|
|
65
|
+
if (!$isRangeSelection(selection) || selection.isCollapsed())
|
|
66
|
+
return false;
|
|
67
|
+
const paragraphs = $paragraphsInSelection(selection);
|
|
68
|
+
const nodes = selection.getNodes();
|
|
69
|
+
const lineBreaks = nodes.filter($isLineBreakNode);
|
|
70
|
+
if (paragraphs.length < 2 && lineBreaks.length === 0)
|
|
71
|
+
return false;
|
|
72
|
+
const last = nodes[nodes.length - 1];
|
|
73
|
+
const breakAfter = last?.getNextSibling();
|
|
74
|
+
const trailingBreak = $isLineBreakNode(breakAfter) ? breakAfter : null;
|
|
75
|
+
for (const lineBreak of lineBreaks)
|
|
76
|
+
$replaceBreakWithSpace(lineBreak);
|
|
77
|
+
const [target, ...rest] = paragraphs;
|
|
78
|
+
if (!target)
|
|
79
|
+
return false;
|
|
80
|
+
for (const paragraph of rest)
|
|
81
|
+
$appendParagraph(target, paragraph);
|
|
82
|
+
if (trailingBreak?.isAttached()) {
|
|
83
|
+
const paragraph = trailingBreak.getParent();
|
|
84
|
+
if ($isParagraphNode(paragraph))
|
|
85
|
+
$splitParagraphAt(trailingBreak, paragraph);
|
|
86
|
+
}
|
|
87
|
+
target.selectEnd();
|
|
88
|
+
return true;
|
|
89
|
+
}
|
package/dist/theme/editor.css
CHANGED
|
@@ -19,15 +19,25 @@
|
|
|
19
19
|
its own height so only the canvas below scrolls. */
|
|
20
20
|
.likhari-toolbar {
|
|
21
21
|
display: flex;
|
|
22
|
+
/* Containing block for the hidden width-measuring clone (Toolbar.tsx):
|
|
23
|
+
without this, its position: absolute would resolve against the
|
|
24
|
+
viewport instead, and its intentionally-unwrapped (possibly very wide)
|
|
25
|
+
content could inflate the host page's scroll area instead of being
|
|
26
|
+
clipped by .likhari-root's overflow: hidden. */
|
|
27
|
+
position: relative;
|
|
22
28
|
flex-shrink: 0;
|
|
23
29
|
align-items: center;
|
|
24
30
|
gap: 8px;
|
|
25
31
|
min-height: 46px;
|
|
26
32
|
padding: 4px 8px;
|
|
27
33
|
background: var(--editor-paper-dim);
|
|
28
|
-
/* Wrap instead of scroll
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
/* Wrap instead of scroll, once the responsive overflow (UI spec §3.3) has
|
|
35
|
+
already moved the lowest-priority groups into the "..." menu: an
|
|
36
|
+
overflow container would clip menus and grow a scrollbar, where wrapping
|
|
37
|
+
to a second row keeps every control reachable without one. This is a
|
|
38
|
+
deliberate departure from the spec's literal "horizontal scroll"
|
|
39
|
+
fallback — it only applies in the edge case where even the essential
|
|
40
|
+
groups (§3.3's mobile tier) don't fit a very narrow viewport. */
|
|
31
41
|
flex-wrap: wrap;
|
|
32
42
|
row-gap: 4px;
|
|
33
43
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inshapardaz/likhari-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31-dev.270",
|
|
4
4
|
"description": "React implementation of the Likhari editor, built on @lexical/react.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"prepublishOnly": "npm run build"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@inshapardaz/likhari-converters": "
|
|
37
|
-
"@inshapardaz/likhari-core": "
|
|
36
|
+
"@inshapardaz/likhari-converters": "*",
|
|
37
|
+
"@inshapardaz/likhari-core": "*",
|
|
38
38
|
"@lexical/link": "^0.20.0",
|
|
39
39
|
"@lexical/list": "^0.20.0",
|
|
40
40
|
"@lexical/react": "^0.20.0",
|