@inshapardaz/likhari-react 0.1.48-dev.371 → 0.1.49-dev.391
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"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;AAmDtF,OAAO,EAAgB,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAkF,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAI1I,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -289,7 +289,6 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
289
289
|
// join lines) is lower priority still, so it is first to move.
|
|
290
290
|
const toolbarContainerRef = useRef(null);
|
|
291
291
|
const toolbarMeasureRef = useRef(null);
|
|
292
|
-
const toolbarOverflowMeasureRef = useRef(null);
|
|
293
292
|
const [overflowGroupKeys, setOverflowGroupKeys] = useState(EMPTY_OVERFLOW);
|
|
294
293
|
const updateToolbar = useCallback(() => {
|
|
295
294
|
editor.getEditorState().read(() => {
|
|
@@ -692,8 +691,7 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
692
691
|
word = atPoint;
|
|
693
692
|
}
|
|
694
693
|
if (!cell && !couplet && config.joinLines) {
|
|
695
|
-
menu.text =
|
|
696
|
-
menu.canJoin = $canJoinLines();
|
|
694
|
+
menu.text = $canJoinLines();
|
|
697
695
|
}
|
|
698
696
|
}, { discrete: true });
|
|
699
697
|
const language = spellCheckLanguage !== 'auto' ? spellCheckLanguage : word?.direction === 'rtl' ? 'ur' : 'en';
|
|
@@ -992,9 +990,8 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
992
990
|
void wordActionAtCaret((language, word) => onAddAutoCorrect(word, language));
|
|
993
991
|
};
|
|
994
992
|
// Keyboard shortcuts mirroring the right-click menu: Ctrl/Cmd+Alt+J joins the
|
|
995
|
-
// selected lines
|
|
996
|
-
//
|
|
997
|
-
// way the menu's Ignore / Add to dictionary / Add to auto-correct items do.
|
|
993
|
+
// selected lines, and Ctrl/Cmd+Alt+I/D/A act on the misspelled word at the caret
|
|
994
|
+
// the way the menu's Ignore / Add to dictionary / Add to auto-correct items do.
|
|
998
995
|
// Matched on event.code (the physical key), not event.key, so they still fire
|
|
999
996
|
// while typing in Urdu or another non-Latin layout, where event.key would be
|
|
1000
997
|
// whatever character that layout produces rather than "j"/"i"/"d"/"a".
|
|
@@ -1034,7 +1031,7 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
1034
1031
|
});
|
|
1035
1032
|
// The tools group is always built, even when every command in it is off, so the ribbon asks first.
|
|
1036
1033
|
const hasToolsGroup = config.language.autocorrect || config.language.textCleanup || config.language.spellCheck || config.joinLines;
|
|
1037
|
-
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,
|
|
1034
|
+
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 && state.canJoinLines && (_jsx(ToolbarButton, { icon: IconArrowsJoin, title: strings.toolbar.joinLines, onClick: joinLines }))] }, "tools"));
|
|
1038
1035
|
// Uniform mode's zoom: [-] 100% [+], stepping through the preset levels; the
|
|
1039
1036
|
// percentage resets to 100%. Always laid out left-to-right, like a number.
|
|
1040
1037
|
const showZoom = uniform && config.font.size;
|
|
@@ -1082,9 +1079,10 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
1082
1079
|
const measure = toolbarMeasureRef.current;
|
|
1083
1080
|
if (!container || !measure)
|
|
1084
1081
|
return;
|
|
1085
|
-
//
|
|
1086
|
-
//
|
|
1087
|
-
|
|
1082
|
+
// Rough width of the "..." button itself (icon button + its gap) —
|
|
1083
|
+
// only charged against the budget once something has actually moved
|
|
1084
|
+
// into it, since it isn't rendered at all otherwise.
|
|
1085
|
+
const OVERFLOW_BUTTON_WIDTH = 38;
|
|
1088
1086
|
const recompute = () => {
|
|
1089
1087
|
const available = container.clientWidth;
|
|
1090
1088
|
const total = measure.scrollWidth;
|
|
@@ -1096,10 +1094,6 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
1096
1094
|
measure.querySelectorAll('[data-group-key]').forEach((el) => {
|
|
1097
1095
|
widths.set(el.dataset.groupKey, el.getBoundingClientRect().width);
|
|
1098
1096
|
});
|
|
1099
|
-
// Measured from a real (hidden) copy of the "..." button, in the toolbar's own
|
|
1100
|
-
// CSS, rather than guessed — only charged against the budget once something
|
|
1101
|
-
// has actually moved into it, since it isn't rendered at all otherwise.
|
|
1102
|
-
const overflowButtonWidth = toolbarOverflowMeasureRef.current?.scrollWidth ?? OVERFLOW_BUTTON_FALLBACK_WIDTH;
|
|
1103
1097
|
let remaining = total;
|
|
1104
1098
|
const next = new Set();
|
|
1105
1099
|
for (const key of movableGroupKeys.split(',').filter(Boolean)) {
|
|
@@ -1112,15 +1106,13 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
1112
1106
|
next.add(key);
|
|
1113
1107
|
}
|
|
1114
1108
|
if (next.size > 0)
|
|
1115
|
-
remaining +=
|
|
1109
|
+
remaining += OVERFLOW_BUTTON_WIDTH;
|
|
1116
1110
|
setOverflowGroupKeys((prev) => (setsEqual(prev, next) ? prev : next));
|
|
1117
1111
|
};
|
|
1118
1112
|
recompute();
|
|
1119
1113
|
const ro = new ResizeObserver(recompute);
|
|
1120
1114
|
ro.observe(container);
|
|
1121
1115
|
ro.observe(measure);
|
|
1122
|
-
if (toolbarOverflowMeasureRef.current)
|
|
1123
|
-
ro.observe(toolbarOverflowMeasureRef.current);
|
|
1124
1116
|
return () => ro.disconnect();
|
|
1125
1117
|
});
|
|
1126
1118
|
const isVisible = (section) => !overflowGroupKeys.has(section.key);
|
|
@@ -1168,7 +1160,7 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
1168
1160
|
}, children: synonym }, synonym)))] })] })), contextMenu?.link !== undefined && (_jsxs(Menu.Sub, { ...CONTEXT_SUBMENU_PROPS, children: [_jsx(Menu.Sub.Target, { children: _jsx(Menu.Sub.Item, { leftSection: _jsx(IconLink, { size: ICON_SIZE, stroke: ICON_STROKE }), children: strings.link.menuLabel }) }), _jsx(Menu.Sub.Dropdown, { children: _jsx(LinkMenuItems, { mode: "submenu", url: contextMenu.link, onEdit: () => {
|
|
1169
1161
|
restoreSelection();
|
|
1170
1162
|
openLinkDialog();
|
|
1171
|
-
}, onRemove: removeLink, strings: strings }) })] })), contextMenu?.table && (_jsx(TableMenuItems, { mode: "icons", strings: strings, direction: direction, rows: contextMenu.table.rows, columns: contextMenu.table.columns, canMergeCells: state.canMergeCells, canUnmergeCell: state.canUnmergeCell, onAction: runMenuAction })), contextMenu?.poetry && (_jsx(PoetryMenuItems, { mode: "icons", strings: strings, layout: state.poetryLayout, scale: state.poetryScale, centered: state.poetryCentered, onAction: runMenuAction })), contextMenu?.text && (_jsx(Menu.Item, { leftSection: _jsx(IconArrowsJoin, { size: ICON_SIZE, stroke: ICON_STROKE }), rightSection: _jsx(ShortcutHint, { keys: "Ctrl+Alt+J" }), "aria-keyshortcuts": "Control+Alt+J",
|
|
1163
|
+
}, onRemove: removeLink, strings: strings }) })] })), contextMenu?.table && (_jsx(TableMenuItems, { mode: "icons", strings: strings, direction: direction, rows: contextMenu.table.rows, columns: contextMenu.table.columns, canMergeCells: state.canMergeCells, canUnmergeCell: state.canUnmergeCell, onAction: runMenuAction })), contextMenu?.poetry && (_jsx(PoetryMenuItems, { mode: "icons", strings: strings, layout: state.poetryLayout, scale: state.poetryScale, centered: state.poetryCentered, onAction: runMenuAction })), contextMenu?.text && (_jsx(Menu.Item, { leftSection: _jsx(IconArrowsJoin, { size: ICON_SIZE, stroke: ICON_STROKE }), rightSection: _jsx(ShortcutHint, { keys: "Ctrl+Alt+J" }), "aria-keyshortcuts": "Control+Alt+J", onClick: runMenuAction(() => {
|
|
1172
1164
|
$joinSelectedLines();
|
|
1173
1165
|
}), children: strings.contextMenu.joinLines })), ((contextMenu?.thesaurus && contextMenu.thesaurus.items?.length !== 0) ||
|
|
1174
1166
|
contextMenu?.link !== undefined ||
|
|
@@ -1263,5 +1255,5 @@ export function Toolbar({ config, toolbarStyle, dictionaryStores = [], thesaurus
|
|
|
1263
1255
|
setRibbonPeek(false);
|
|
1264
1256
|
}, children: _jsx(MantineToolbar, { "aria-label": strings.toolbar.ariaLabel, className: bordered ? 'likhari-toolbar likhari-ribbon-panel' : 'likhari-toolbar likhari-toolbar--plain likhari-ribbon-panel', withBorder: bordered, variant: variant, color: "var(--editor-accent)", children: withDividers(activeTab.groups) }) })), contextMenuEl, dialogsEl] }));
|
|
1265
1257
|
}
|
|
1266
|
-
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, { opened: overflowMenuOpen, onChange: handleOverflowMenuChange, position: "bottom-end", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: "max-content", closeOnItemClick: false, 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)) }) })] })] })), _jsx("span", { "aria-hidden": "true", style: { flex: '1 1 auto' } }), visibleEnd.map((section) => section.node), contextMenuEl, overflowEnabled && (_jsxs(MantineToolbar, { "aria-hidden": "true", ref: toolbarMeasureRef,
|
|
1258
|
+
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, { opened: overflowMenuOpen, onChange: handleOverflowMenuChange, position: "bottom-end", withinPortal: true, portalProps: { target: portalTarget }, shadow: "sm", width: "max-content", closeOnItemClick: false, 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)) }) })] })] })), _jsx("span", { "aria-hidden": "true", style: { flex: '1 1 auto' } }), visibleEnd.map((section) => section.node), contextMenuEl, 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)))] })), dialogsEl] }));
|
|
1267
1259
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"joinLinesActions.d.ts","sourceRoot":"","sources":["../../src/join/joinLinesActions.ts"],"names":[],"mappings":"AAqCA,wBAAgB,aAAa,IAAI,OAAO,CAKvC;
|
|
1
|
+
{"version":3,"file":"joinLinesActions.d.ts","sourceRoot":"","sources":["../../src/join/joinLinesActions.ts"],"names":[],"mappings":"AAqCA,wBAAgB,aAAa,IAAI,OAAO,CAKvC;AAgFD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAgC5C"}
|
|
@@ -28,11 +28,10 @@ export function $canJoinLines() {
|
|
|
28
28
|
return selection.getNodes().some($isLineBreakNode) || $textNodesWithNewlines(selection).length > 0;
|
|
29
29
|
}
|
|
30
30
|
/** Replaces the newlines in the selected part of a text node, each by one space (none if one is already there). */
|
|
31
|
-
function $replaceNewlinesInText(node,
|
|
32
|
-
const [start, end] = selection.getStartEndPoints() ?? [];
|
|
31
|
+
function $replaceNewlinesInText(node, start, end) {
|
|
33
32
|
const text = node.getTextContent();
|
|
34
|
-
const from = start
|
|
35
|
-
const to = end
|
|
33
|
+
const from = start.key === node.getKey() ? start.offset : 0;
|
|
34
|
+
const to = end.key === node.getKey() ? end.offset : text.length;
|
|
36
35
|
const joined = text.slice(from, to).replace(/[ \t]*\r?\n[ \t]*/g, ' ');
|
|
37
36
|
node.setTextContent(text.slice(0, from) + joined + text.slice(to));
|
|
38
37
|
}
|
|
@@ -126,27 +125,26 @@ export function $joinSelectedLines() {
|
|
|
126
125
|
const textsWithNewlines = $textNodesWithNewlines(selection);
|
|
127
126
|
if (paragraphs.length < 2 && lineBreaks.length === 0 && textsWithNewlines.length === 0)
|
|
128
127
|
return false;
|
|
129
|
-
|
|
128
|
+
// RangeSelection's anchor/focus track drag direction, not document order (and
|
|
129
|
+
// getStartEndPoints() returns them as-is, anchor first) — reorder them so "start"/"end"
|
|
130
|
+
// below always mean "earlier"/"later" in the document, regardless of which way the user
|
|
131
|
+
// dragged, or Shift+arrow'd, the selection. Getting this wrong silently skips the tail
|
|
132
|
+
// split below (sweeping unselected content into the join) for any backward selection.
|
|
133
|
+
const [start, end] = selection.isBackward() ? [selection.focus, selection.anchor] : [selection.anchor, selection.focus];
|
|
130
134
|
for (const lineBreak of lineBreaks)
|
|
131
135
|
$replaceBreakWithSpace(lineBreak);
|
|
132
136
|
for (const textNode of textsWithNewlines)
|
|
133
|
-
$replaceNewlinesInText(textNode,
|
|
137
|
+
$replaceNewlinesInText(textNode, start, end);
|
|
134
138
|
const [target, ...rest] = paragraphs;
|
|
135
139
|
if (!target)
|
|
136
140
|
return false;
|
|
137
141
|
const lastParagraph = paragraphs[paragraphs.length - 1];
|
|
138
|
-
|
|
139
|
-
$splitUnselectedTail(lastParagraph, end);
|
|
142
|
+
$splitUnselectedTail(lastParagraph, end);
|
|
140
143
|
for (const paragraph of rest)
|
|
141
144
|
$appendParagraph(target, paragraph);
|
|
142
145
|
// Keep the caret where the selection began, rather than at the end of everything
|
|
143
146
|
// just joined — useful on its own, and essential when many lines were joined at
|
|
144
147
|
// once, where "the end" could otherwise land far past where the user was working.
|
|
145
|
-
|
|
146
|
-
start.getNode().select(start.offset, start.offset);
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
target.selectEnd();
|
|
150
|
-
}
|
|
148
|
+
start.getNode().select(start.offset, start.offset);
|
|
151
149
|
return true;
|
|
152
150
|
}
|