@barocss/math-editor 0.2.1 → 0.4.0
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/ADAPTERS.md +25 -14
- package/API-JAVASCRIPT.md +1 -1
- package/API-REACT.md +5 -1
- package/API-SESSION.md +168 -6
- package/API-SOLID.md +1 -1
- package/API-SVELTE.md +1 -1
- package/API-VUE.md +1 -1
- package/API-WEB-COMPONENT.md +1 -1
- package/CHANGELOG.md +45 -0
- package/EMBEDDING.md +4 -0
- package/IMPLEMENTATION.md +27 -2
- package/JSON-MODEL.md +1 -0
- package/LATEX-GUIDE.md +8 -1
- package/LATEX-SCOPE.md +2 -2
- package/LICENSE +1 -3
- package/README.md +145 -37
- package/ROADMAP.md +93 -11
- package/STYLING.md +157 -0
- package/SUPPORT.md +24 -12
- package/VALIDATION.md +113 -4
- package/dist/core.d.ts +5 -1
- package/dist/core.js +5 -1
- package/dist/document-codec.d.ts +0 -1
- package/dist/document-codec.js +0 -1
- package/dist/dom/caret-geometry.d.ts +3 -0
- package/dist/dom/caret-geometry.js +41 -0
- package/dist/dom/elements.d.ts +1 -2
- package/dist/dom/elements.js +2 -3
- package/dist/dom/latex-panel.d.ts +10 -0
- package/dist/dom/latex-panel.js +59 -0
- package/dist/dom/matrix-selection.d.ts +11 -0
- package/dist/dom/matrix-selection.js +30 -0
- package/dist/dom/menu-position.d.ts +14 -2
- package/dist/dom/menu-position.js +84 -15
- package/dist/dom/presentation-controls.d.ts +4 -0
- package/dist/dom/presentation-controls.js +56 -0
- package/dist/dom/quick-panel.d.ts +12 -0
- package/dist/dom/quick-panel.js +102 -0
- package/dist/dom/selection.d.ts +29 -0
- package/dist/dom/selection.js +53 -0
- package/dist/dom/symbol-panel.d.ts +9 -0
- package/dist/dom/symbol-panel.js +146 -0
- package/dist/dom/theme.d.ts +6 -0
- package/dist/dom/theme.js +68 -0
- package/dist/dom/toolbar-catalog.d.ts +10 -0
- package/dist/dom/toolbar-catalog.js +35 -0
- package/dist/dom/toolbar.d.ts +13 -2
- package/dist/dom/toolbar.js +295 -28
- package/dist/dom.d.ts +7 -1
- package/dist/dom.js +510 -128
- package/dist/editor-labels.d.ts +0 -1
- package/dist/editor-labels.js +0 -1
- package/dist/enter-policy.d.ts +0 -1
- package/dist/enter-policy.js +0 -1
- package/dist/fences.d.ts +0 -1
- package/dist/fences.js +0 -1
- package/dist/i18n.d.ts +0 -1
- package/dist/i18n.js +0 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/latex-insertion.d.ts +12 -0
- package/dist/latex-insertion.js +26 -0
- package/dist/latex-paste-panel.d.ts +3 -0
- package/dist/latex-paste-panel.js +18 -0
- package/dist/latex.d.ts +0 -1
- package/dist/latex.js +0 -1
- package/dist/lines.d.ts +0 -1
- package/dist/lines.js +0 -1
- package/dist/locales/en.js +27 -1
- package/dist/locales/en.json +27 -1
- package/dist/locales/ko.js +27 -1
- package/dist/locales/ko.json +27 -1
- package/dist/math-editor-toolbar.d.ts +4 -2
- package/dist/math-editor-toolbar.js +3 -4
- package/dist/math-editor.d.ts +5 -2
- package/dist/math-editor.js +285 -46
- package/dist/matrix-range.d.ts +40 -0
- package/dist/matrix-range.js +242 -0
- package/dist/matrix.d.ts +0 -1
- package/dist/matrix.js +0 -1
- package/dist/model.d.ts +0 -1
- package/dist/model.js +0 -1
- package/dist/outputs.d.ts +0 -1
- package/dist/outputs.js +0 -1
- package/dist/preferences.d.ts +24 -0
- package/dist/preferences.js +66 -0
- package/dist/presentation-controls.d.ts +10 -0
- package/dist/presentation-controls.js +10 -0
- package/dist/presentation.d.ts +13 -0
- package/dist/presentation.js +86 -0
- package/dist/quick-panel.d.ts +2 -0
- package/dist/quick-panel.js +17 -0
- package/dist/range.d.ts +2 -1
- package/dist/range.js +11 -1
- package/dist/react.d.ts +0 -1
- package/dist/react.js +0 -1
- package/dist/session.d.ts +31 -2
- package/dist/session.js +108 -7
- package/dist/solid.d.ts +0 -1
- package/dist/solid.js +0 -1
- package/dist/suggestions.d.ts +4 -1
- package/dist/suggestions.js +100 -12
- package/dist/svelte.d.ts +0 -1
- package/dist/svelte.js +0 -1
- package/dist/symbol-browser.d.ts +0 -1
- package/dist/symbol-browser.js +0 -1
- package/dist/symbols.d.ts +0 -1
- package/dist/symbols.js +0 -1
- package/dist/templates.d.ts +0 -1
- package/dist/templates.js +0 -1
- package/dist/tokens.d.ts +0 -1
- package/dist/tokens.js +0 -1
- package/dist/vertical-navigation.d.ts +15 -0
- package/dist/vertical-navigation.js +145 -0
- package/dist/vue.d.ts +0 -1
- package/dist/vue.js +0 -1
- package/dist/web-component.d.ts +0 -1
- package/dist/web-component.js +0 -1
- package/package.json +1 -1
- package/src/style.css +254 -129
- package/dist/core.d.ts.map +0 -1
- package/dist/core.js.map +0 -1
- package/dist/document-codec.d.ts.map +0 -1
- package/dist/document-codec.js.map +0 -1
- package/dist/dom/elements.d.ts.map +0 -1
- package/dist/dom/elements.js.map +0 -1
- package/dist/dom/menu-position.d.ts.map +0 -1
- package/dist/dom/menu-position.js.map +0 -1
- package/dist/dom/toolbar.d.ts.map +0 -1
- package/dist/dom/toolbar.js.map +0 -1
- package/dist/dom.d.ts.map +0 -1
- package/dist/dom.js.map +0 -1
- package/dist/editor-labels.d.ts.map +0 -1
- package/dist/editor-labels.js.map +0 -1
- package/dist/enter-policy.d.ts.map +0 -1
- package/dist/enter-policy.js.map +0 -1
- package/dist/fences.d.ts.map +0 -1
- package/dist/fences.js.map +0 -1
- package/dist/i18n.d.ts.map +0 -1
- package/dist/i18n.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/latex.d.ts.map +0 -1
- package/dist/latex.js.map +0 -1
- package/dist/lines.d.ts.map +0 -1
- package/dist/lines.js.map +0 -1
- package/dist/math-editor-toolbar.d.ts.map +0 -1
- package/dist/math-editor-toolbar.js.map +0 -1
- package/dist/math-editor.d.ts.map +0 -1
- package/dist/math-editor.js.map +0 -1
- package/dist/matrix.d.ts.map +0 -1
- package/dist/matrix.js.map +0 -1
- package/dist/model.d.ts.map +0 -1
- package/dist/model.js.map +0 -1
- package/dist/outputs.d.ts.map +0 -1
- package/dist/outputs.js.map +0 -1
- package/dist/range.d.ts.map +0 -1
- package/dist/range.js.map +0 -1
- package/dist/react.d.ts.map +0 -1
- package/dist/react.js.map +0 -1
- package/dist/session.d.ts.map +0 -1
- package/dist/session.js.map +0 -1
- package/dist/solid.d.ts.map +0 -1
- package/dist/solid.js.map +0 -1
- package/dist/suggestions.d.ts.map +0 -1
- package/dist/suggestions.js.map +0 -1
- package/dist/svelte.d.ts.map +0 -1
- package/dist/svelte.js.map +0 -1
- package/dist/symbol-browser.d.ts.map +0 -1
- package/dist/symbol-browser.js.map +0 -1
- package/dist/symbols.d.ts.map +0 -1
- package/dist/symbols.js.map +0 -1
- package/dist/templates.d.ts.map +0 -1
- package/dist/templates.js.map +0 -1
- package/dist/tokens.d.ts.map +0 -1
- package/dist/tokens.js.map +0 -1
- package/dist/vue.d.ts.map +0 -1
- package/dist/vue.js.map +0 -1
- package/dist/web-component.d.ts.map +0 -1
- package/dist/web-component.js.map +0 -1
package/dist/math-editor.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { setMathPresentation } from './presentation.js';
|
|
3
|
+
import { PresentationControls } from './presentation-controls.js';
|
|
4
|
+
import { createMathPreferences } from './preferences.js';
|
|
5
|
+
import { QuickPanel } from './quick-panel.js';
|
|
6
|
+
import { toolbarTemplates } from './dom/toolbar-catalog.js';
|
|
7
|
+
import { insertLatex } from './latex-insertion.js';
|
|
8
|
+
import { LatexPastePanel } from './latex-paste-panel.js';
|
|
9
|
+
import { followMathTheme } from './dom/theme.js';
|
|
10
|
+
import { matrixPointerRange } from './dom/matrix-selection.js';
|
|
2
11
|
import { positionMathMenu } from './dom/menu-position.js';
|
|
3
12
|
import { fences } from './fences.js';
|
|
4
13
|
import { parseLatex } from './latex.js';
|
|
@@ -7,26 +16,34 @@ import { MathEditorToolbar } from './math-editor-toolbar.js';
|
|
|
7
16
|
import { SymbolBrowser } from './symbol-browser.js';
|
|
8
17
|
import { insertTemplate } from './templates.js';
|
|
9
18
|
import { translate, mathLocaleDirection, } from './i18n.js';
|
|
10
|
-
import { extendKeyboardRange, wrapRange, wrappingKinds, copyRange, deleteRange, fragmentLatex, MATH_CLIPBOARD_TYPE, parseFragment, pasteFragment, resolveRange, } from './range.js';
|
|
19
|
+
import { extendKeyboardRange, collapseKeyboardRange, wrapRange, wrappingKinds, copyRange, deleteRange, fragmentLatex, MATH_CLIPBOARD_TYPE, parseFragment, pasteFragment, resolveRange, } from './range.js';
|
|
11
20
|
import { tokenizeMathText, tokenIndexAt } from './tokens.js';
|
|
12
|
-
import { splitLine, joinPreviousLine
|
|
13
|
-
import {
|
|
21
|
+
import { splitLine, joinPreviousLine } from './lines.js';
|
|
22
|
+
import { moveVertical } from './vertical-navigation.js';
|
|
23
|
+
import { renderedCaretGeometry } from './dom/caret-geometry.js';
|
|
24
|
+
import { insertIdentityMatrix, insertMatrix, activeGrid, MATRIX_MAX_SIZE, matrixEnvironments, resizeMatrix, setMatrixEnvironment, } from './matrix.js';
|
|
25
|
+
import { MATH_MATRIX_CLIPBOARD_TYPE, parseMatrixFragment, matrixFragment, matrixFromTSV, matrixRangeBetween, resolveMatrixRange, extendMatrixRange, focusMatrixCell, copyMatrixRange, clearMatrixRange, pasteMatrixFragment, transposeMatrix, } from './matrix-range.js';
|
|
14
26
|
import { createPortal } from 'react-dom';
|
|
15
27
|
import { acceptSuggestion, findSuggestions, mathStructures } from './suggestions.js';
|
|
16
28
|
import { useId, useImperativeHandle, useLayoutEffect, useRef, useState, } from 'react';
|
|
17
29
|
import { gridDeletionTarget, removeGrid, row, documentRows, isLiteralText, isGrid, commit, createHistory, initialState, insertStructure, moveCaret, redo, setText, textNodes, toLatex, undo, unwrapPrevious, } from './model.js';
|
|
18
30
|
const structures = mathStructures;
|
|
19
31
|
/** Native text fields own IME and local text selection; the tree owns structural editing. */
|
|
20
|
-
export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline', onCommit, onCancel, showPopovers = true, defaultValue, excludedStructures = [], multiline = true, onChange, onExit, label, locale = 'ko', showLineNumbers = true, toolbar = true, toolbarMaxItems = 8, toolbarEnd, showTokenLegend = true, }) {
|
|
32
|
+
export function MathEditor({ preferences: suppliedPreferences, apiRef, autoFocus = false, enterBehavior = 'newline', onCommit, onCancel, showPopovers = true, defaultValue, excludedStructures = [], multiline = true, onChange, onExit, label, locale = 'ko', showLineNumbers = true, toolbar = true, toolbarMaxItems = 8, toolbarEnd, showTokenLegend = true, }) {
|
|
21
33
|
const t = (key, parameters) => translate(locale, key, parameters);
|
|
22
34
|
const labels = createEditorLabels(locale);
|
|
23
35
|
const [history, setHistory] = useState(() => createHistory(initialState(defaultValue)));
|
|
24
36
|
const historyRef = useRef(history);
|
|
25
37
|
const suggestionMenu = useRef(null);
|
|
26
38
|
const selectionMenu = useRef(null);
|
|
39
|
+
const [ownPreferences] = useState(createMathPreferences);
|
|
40
|
+
const preferences = suppliedPreferences ?? ownPreferences;
|
|
41
|
+
const [quickOpen, setQuickOpen] = useState(false);
|
|
42
|
+
const [latexOpen, setLatexOpen] = useState(false);
|
|
27
43
|
const [symbolsOpen, setSymbolsOpen] = useState(false);
|
|
28
44
|
const [editing, setEditing] = useState(autoFocus);
|
|
29
45
|
const [range, setRange] = useState();
|
|
46
|
+
const [matrixRange, setMatrixRange] = useState();
|
|
30
47
|
const [clipboardMessage, setClipboardMessage] = useState('');
|
|
31
48
|
const surface = useRef(null);
|
|
32
49
|
const drag = useRef(undefined);
|
|
@@ -61,6 +78,7 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
61
78
|
const suggestionId = useId();
|
|
62
79
|
const state = history.present;
|
|
63
80
|
const matrixContext = activeGrid(state);
|
|
81
|
+
const matrixSelection = matrixRange && resolveMatrixRange(state.document, matrixRange);
|
|
64
82
|
const active = textNodes(state.document).find((n) => n.id === state.caret.id);
|
|
65
83
|
const searchCaret = composing ? state.caret.end : state.caret.start;
|
|
66
84
|
const matches = findSuggestions(active.text, searchCaret, locale);
|
|
@@ -73,6 +91,7 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
73
91
|
!isLiteralText(state.document, state.caret.id) &&
|
|
74
92
|
(composing || state.caret.start === state.caret.end) &&
|
|
75
93
|
!range &&
|
|
94
|
+
!matrixRange &&
|
|
76
95
|
focused &&
|
|
77
96
|
(composing || state.caret.start === state.caret.end) &&
|
|
78
97
|
dismissed !== queryKey
|
|
@@ -85,6 +104,7 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
85
104
|
if (changed) {
|
|
86
105
|
setSelectedGrid(undefined);
|
|
87
106
|
setRange(undefined);
|
|
107
|
+
setMatrixRange(undefined);
|
|
88
108
|
}
|
|
89
109
|
if (focus)
|
|
90
110
|
setEditing(true);
|
|
@@ -98,7 +118,30 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
98
118
|
setSelectedGrid(undefined);
|
|
99
119
|
publish(commit(historyRef.current, next), true);
|
|
100
120
|
};
|
|
121
|
+
const pasteLatex = (source) => {
|
|
122
|
+
if (composing || matrixRange)
|
|
123
|
+
return {
|
|
124
|
+
ok: false,
|
|
125
|
+
source,
|
|
126
|
+
diagnostics: [
|
|
127
|
+
{
|
|
128
|
+
code: 'unsupported-structure',
|
|
129
|
+
message: 'Finish composition or select one insertion point.',
|
|
130
|
+
start: 0,
|
|
131
|
+
end: source.length,
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
};
|
|
135
|
+
const result = insertLatex(historyRef.current.present, source, range, {
|
|
136
|
+
multiline,
|
|
137
|
+
excludedStructures,
|
|
138
|
+
});
|
|
139
|
+
if (result.ok)
|
|
140
|
+
apply(result.state);
|
|
141
|
+
return result;
|
|
142
|
+
};
|
|
101
143
|
useImperativeHandle(apiRef, () => ({
|
|
144
|
+
pasteLatex,
|
|
102
145
|
importLatex(source) {
|
|
103
146
|
const result = parseLatex(source, { multiline, excludedStructures });
|
|
104
147
|
if (!result.ok)
|
|
@@ -167,10 +210,14 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
167
210
|
if (suggestionMenu.current)
|
|
168
211
|
positionMathMenu(suggestionMenu.current, new DOMRect(x, rect.top, 0, rect.height), 340);
|
|
169
212
|
};
|
|
213
|
+
const stopTheme = surface.current && suggestionMenu.current
|
|
214
|
+
? followMathTheme(surface.current.closest('.me-editor'), suggestionMenu.current)
|
|
215
|
+
: undefined;
|
|
170
216
|
position();
|
|
171
217
|
window.addEventListener('resize', position);
|
|
172
218
|
window.addEventListener('scroll', position, true);
|
|
173
219
|
return () => {
|
|
220
|
+
stopTheme?.();
|
|
174
221
|
window.removeEventListener('resize', position);
|
|
175
222
|
window.removeEventListener('scroll', position, true);
|
|
176
223
|
};
|
|
@@ -195,6 +242,7 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
195
242
|
if (!candidate)
|
|
196
243
|
return;
|
|
197
244
|
apply(acceptSuggestion(historyRef.current.present, query, candidate));
|
|
245
|
+
preferences.record(candidate.id);
|
|
198
246
|
setCandidateIndex(0);
|
|
199
247
|
setDismissed(`${active.id}:${state.caret.start}:${query}`);
|
|
200
248
|
};
|
|
@@ -257,6 +305,7 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
257
305
|
};
|
|
258
306
|
};
|
|
259
307
|
const activate = (point) => {
|
|
308
|
+
setMatrixRange(undefined);
|
|
260
309
|
setRange(undefined);
|
|
261
310
|
setFocused(true);
|
|
262
311
|
setSelectedGrid(undefined);
|
|
@@ -273,6 +322,19 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
273
322
|
},
|
|
274
323
|
}, true);
|
|
275
324
|
};
|
|
325
|
+
const selectCells = (selection) => {
|
|
326
|
+
if (!resolveMatrixRange(historyRef.current.present.document, selection))
|
|
327
|
+
return;
|
|
328
|
+
setMatrixRange(selection);
|
|
329
|
+
setRange(undefined);
|
|
330
|
+
setEditing(false);
|
|
331
|
+
setSymbolsOpen(false);
|
|
332
|
+
publish({
|
|
333
|
+
...historyRef.current,
|
|
334
|
+
present: focusMatrixCell(historyRef.current.present, selection.matrixId, selection.focus),
|
|
335
|
+
});
|
|
336
|
+
surface.current?.focus({ preventScroll: true });
|
|
337
|
+
};
|
|
276
338
|
// Promote a pointer drag to a model range, including a drag that starts in the active input.
|
|
277
339
|
const beginPointer = (event) => {
|
|
278
340
|
if (event.button !== 0 ||
|
|
@@ -282,6 +344,17 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
282
344
|
const point = pointAt(event.clientX, event.clientY);
|
|
283
345
|
if (!point)
|
|
284
346
|
return;
|
|
347
|
+
if (event.shiftKey) {
|
|
348
|
+
const current = historyRef.current.present;
|
|
349
|
+
const rectangle = matrixRangeBetween(current.document, matrixRange
|
|
350
|
+
? focusMatrixCell(current, matrixRange.matrixId, matrixRange.anchor).caret.id
|
|
351
|
+
: current.caret.id, point.id);
|
|
352
|
+
if (rectangle) {
|
|
353
|
+
event.preventDefault();
|
|
354
|
+
selectCells(rectangle);
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
285
358
|
const input = event.target instanceof HTMLInputElement;
|
|
286
359
|
drag.current = { anchor: point, x: event.clientX, y: event.clientY, moving: false, input };
|
|
287
360
|
if (!input) {
|
|
@@ -308,10 +381,20 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
308
381
|
event.preventDefault();
|
|
309
382
|
current.moving = true;
|
|
310
383
|
setEditing(false);
|
|
311
|
-
|
|
384
|
+
const rectangle = current.matrixRange ??
|
|
385
|
+
matrixRangeBetween(historyRef.current.present.document, current.anchor.id, point.id);
|
|
386
|
+
const bounds = rectangle && resolveMatrixRange(historyRef.current.present.document, rectangle);
|
|
387
|
+
if (rectangle && bounds) {
|
|
388
|
+
current.matrixRange = matrixPointerRange(event.currentTarget, rectangle, bounds.matrix.columns, event.clientX, event.clientY);
|
|
389
|
+
selectCells(current.matrixRange);
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
setMatrixRange(undefined);
|
|
393
|
+
setRange({ anchor: current.anchor, focus: point });
|
|
394
|
+
}
|
|
312
395
|
setSelectedGrid(undefined);
|
|
313
396
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
314
|
-
event.currentTarget.focus();
|
|
397
|
+
event.currentTarget.focus({ preventScroll: true });
|
|
315
398
|
};
|
|
316
399
|
const endPointer = (event) => {
|
|
317
400
|
const current = drag.current;
|
|
@@ -345,17 +428,24 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
345
428
|
};
|
|
346
429
|
// Structured clipboard data preserves editable math; plain LaTeX is the interoperability fallback.
|
|
347
430
|
const copySelection = (event, cut = false) => {
|
|
348
|
-
if (!range
|
|
431
|
+
if (compositionStart.current || (!range && !matrixRange))
|
|
349
432
|
return;
|
|
350
|
-
const
|
|
433
|
+
const cells = matrixRange && copyMatrixRange(historyRef.current.present.document, matrixRange);
|
|
434
|
+
const fragment = cells
|
|
435
|
+
? matrixFragment(cells)
|
|
436
|
+
: copyRange(historyRef.current.present.document, range);
|
|
351
437
|
if (!fragment)
|
|
352
438
|
return;
|
|
353
439
|
event.preventDefault();
|
|
354
440
|
event.stopPropagation();
|
|
441
|
+
if (cells)
|
|
442
|
+
event.clipboardData.setData(MATH_MATRIX_CLIPBOARD_TYPE, JSON.stringify(cells));
|
|
355
443
|
event.clipboardData.setData(MATH_CLIPBOARD_TYPE, JSON.stringify(fragment));
|
|
356
444
|
event.clipboardData.setData('text/plain', toLatex(fragmentLatex(fragment)));
|
|
357
445
|
if (cut)
|
|
358
|
-
apply(
|
|
446
|
+
apply(matrixRange
|
|
447
|
+
? clearMatrixRange(historyRef.current.present, matrixRange)
|
|
448
|
+
: deleteRange(historyRef.current.present, range));
|
|
359
449
|
setClipboardMessage(cut ? 'clipboard.cut' : 'clipboard.copied');
|
|
360
450
|
};
|
|
361
451
|
const pasteSelection = (event) => {
|
|
@@ -364,6 +454,40 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
364
454
|
const source = event.clipboardData.getData(MATH_CLIPBOARD_TYPE);
|
|
365
455
|
const fragment = source ? parseFragment(source) : undefined;
|
|
366
456
|
const text = event.clipboardData.getData('text/plain');
|
|
457
|
+
const matrixSource = event.clipboardData.getData(MATH_MATRIX_CLIPBOARD_TYPE);
|
|
458
|
+
const cells = matrixSource ? parseMatrixFragment(matrixSource) : matrixFromTSV(text);
|
|
459
|
+
const current = historyRef.current.present;
|
|
460
|
+
const inMatrix = !!matrixRange || activeGrid(current)?.matrix.type === 'matrix';
|
|
461
|
+
if (matrixSource || (inMatrix && text.includes('\t'))) {
|
|
462
|
+
event.preventDefault();
|
|
463
|
+
event.stopPropagation();
|
|
464
|
+
if (!cells) {
|
|
465
|
+
setClipboardMessage('matrix.pasteRejected');
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
const next = inMatrix
|
|
469
|
+
? pasteMatrixFragment(current, cells, matrixRange)
|
|
470
|
+
: pasteFragment(current, matrixFragment(cells), range);
|
|
471
|
+
if (next === current)
|
|
472
|
+
setClipboardMessage('matrix.pasteRejected');
|
|
473
|
+
else {
|
|
474
|
+
apply(next);
|
|
475
|
+
setClipboardMessage('clipboard.pasted');
|
|
476
|
+
}
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
if (matrixRange && !fragment && !text.includes('\n') && !text.includes('\r')) {
|
|
480
|
+
event.preventDefault();
|
|
481
|
+
event.stopPropagation();
|
|
482
|
+
apply(clearMatrixRange(current, matrixRange, text));
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
if (matrixRange) {
|
|
486
|
+
event.preventDefault();
|
|
487
|
+
event.stopPropagation();
|
|
488
|
+
setClipboardMessage('matrix.pasteRejected');
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
367
491
|
if (!fragment && !text)
|
|
368
492
|
return;
|
|
369
493
|
event.preventDefault();
|
|
@@ -383,6 +507,43 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
383
507
|
apply(next);
|
|
384
508
|
setClipboardMessage('clipboard.pasted');
|
|
385
509
|
};
|
|
510
|
+
const matrixSelectionKey = (event) => {
|
|
511
|
+
if (!matrixRange || compositionStart.current || event.nativeEvent.isComposing)
|
|
512
|
+
return false;
|
|
513
|
+
const current = historyRef.current.present;
|
|
514
|
+
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === 'a') {
|
|
515
|
+
event.preventDefault();
|
|
516
|
+
event.stopPropagation();
|
|
517
|
+
const matrix = resolveMatrixRange(current.document, matrixRange)?.matrix;
|
|
518
|
+
if (matrix)
|
|
519
|
+
selectCells({ matrixId: matrix.id, anchor: 0, focus: matrix.slots.length - 1 });
|
|
520
|
+
return true;
|
|
521
|
+
}
|
|
522
|
+
if (event.metaKey || event.ctrlKey || event.altKey)
|
|
523
|
+
return false;
|
|
524
|
+
const arrow = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.key);
|
|
525
|
+
if (arrow || ['Escape', 'Enter', 'F2'].includes(event.key)) {
|
|
526
|
+
event.preventDefault();
|
|
527
|
+
event.stopPropagation();
|
|
528
|
+
const next = arrow
|
|
529
|
+
? extendMatrixRange(current.document, matrixRange, event.key)
|
|
530
|
+
: matrixRange;
|
|
531
|
+
if (arrow && event.shiftKey)
|
|
532
|
+
selectCells(next);
|
|
533
|
+
else {
|
|
534
|
+
const caret = focusMatrixCell(current, next.matrixId, next.focus).caret;
|
|
535
|
+
activate({ id: caret.id, offset: caret.start });
|
|
536
|
+
}
|
|
537
|
+
return true;
|
|
538
|
+
}
|
|
539
|
+
if (['Delete', 'Backspace'].includes(event.key) || Array.from(event.key).length === 1) {
|
|
540
|
+
event.preventDefault();
|
|
541
|
+
event.stopPropagation();
|
|
542
|
+
apply(clearMatrixRange(current, matrixRange, ['Delete', 'Backspace'].includes(event.key) ? '' : event.key));
|
|
543
|
+
return true;
|
|
544
|
+
}
|
|
545
|
+
return false;
|
|
546
|
+
};
|
|
386
547
|
const keyboardSelect = (event) => {
|
|
387
548
|
if (!event.shiftKey ||
|
|
388
549
|
event.altKey ||
|
|
@@ -399,7 +560,7 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
399
560
|
const selectionKey = (event) => {
|
|
400
561
|
if (event.target instanceof HTMLInputElement || compositionStart.current)
|
|
401
562
|
return;
|
|
402
|
-
if (keyboardSelect(event))
|
|
563
|
+
if (matrixSelectionKey(event) || keyboardSelect(event))
|
|
403
564
|
return;
|
|
404
565
|
const current = historyRef.current.present, nodes = textNodes(current.document);
|
|
405
566
|
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === 'a') {
|
|
@@ -415,9 +576,17 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
415
576
|
publish((event.shiftKey ? redo : undo)(historyRef.current), false);
|
|
416
577
|
return;
|
|
417
578
|
}
|
|
418
|
-
if (event.metaKey || event.ctrlKey
|
|
579
|
+
if (event.metaKey || event.ctrlKey)
|
|
580
|
+
return;
|
|
581
|
+
const point = !event.altKey && collapseKeyboardRange(current.document, range, event.key);
|
|
582
|
+
if (point) {
|
|
583
|
+
event.preventDefault();
|
|
584
|
+
activate(point);
|
|
419
585
|
return;
|
|
420
|
-
|
|
586
|
+
}
|
|
587
|
+
if (range &&
|
|
588
|
+
selectionChoices.length &&
|
|
589
|
+
(event.key === 'Enter' || (event.altKey && ['ArrowDown', 'ArrowUp'].includes(event.key)))) {
|
|
421
590
|
event.preventDefault();
|
|
422
591
|
if (event.key === 'Enter') {
|
|
423
592
|
if (canWrap)
|
|
@@ -428,6 +597,8 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
428
597
|
selectionChoices.length);
|
|
429
598
|
return;
|
|
430
599
|
}
|
|
600
|
+
if (event.altKey)
|
|
601
|
+
return;
|
|
431
602
|
// A model selection must behave like a text selection when typing resumes.
|
|
432
603
|
if (range && !event.nativeEvent.isComposing && Array.from(event.key).length === 1) {
|
|
433
604
|
event.preventDefault();
|
|
@@ -441,6 +612,7 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
441
612
|
}
|
|
442
613
|
if (event.key === 'Escape') {
|
|
443
614
|
setRange(undefined);
|
|
615
|
+
setMatrixRange(undefined);
|
|
444
616
|
return;
|
|
445
617
|
}
|
|
446
618
|
if (event.key === 'Enter' || event.key === 'F2') {
|
|
@@ -448,13 +620,15 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
448
620
|
activate(range?.focus ?? { id: current.caret.id, offset: current.caret.start });
|
|
449
621
|
}
|
|
450
622
|
};
|
|
451
|
-
const selectedRange =
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
623
|
+
const selectedRange = matrixRange
|
|
624
|
+
? undefined
|
|
625
|
+
: range ??
|
|
626
|
+
(state.caret.start !== state.caret.end
|
|
627
|
+
? {
|
|
628
|
+
anchor: { id: state.caret.id, offset: state.caret.start },
|
|
629
|
+
focus: { id: state.caret.id, offset: state.caret.end },
|
|
630
|
+
}
|
|
631
|
+
: undefined);
|
|
458
632
|
const selectionFragment = selectedRange ? copyRange(state.document, selectedRange) : undefined;
|
|
459
633
|
const canWrap = selectionFragment?.rows.length === 1 &&
|
|
460
634
|
!isLiteralText(state.document, selectedRange.anchor.id);
|
|
@@ -504,11 +678,15 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
504
678
|
if (rect && selectionMenu.current)
|
|
505
679
|
positionMathMenu(selectionMenu.current, rect, 340);
|
|
506
680
|
};
|
|
681
|
+
const stopTheme = surface.current && selectionMenu.current
|
|
682
|
+
? followMathTheme(surface.current.closest('.me-editor'), selectionMenu.current)
|
|
683
|
+
: undefined;
|
|
507
684
|
position();
|
|
508
685
|
window.addEventListener('scroll', position, true);
|
|
509
686
|
window.addEventListener('resize', position);
|
|
510
687
|
return () => {
|
|
511
688
|
window.removeEventListener('scroll', position, true);
|
|
689
|
+
stopTheme?.();
|
|
512
690
|
window.removeEventListener('resize', position);
|
|
513
691
|
};
|
|
514
692
|
}, [range, state.document, state.caret, showPopovers]);
|
|
@@ -524,7 +702,7 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
524
702
|
list.scrollTop += item.bottom - box.bottom;
|
|
525
703
|
}, [selectionIndex]);
|
|
526
704
|
const insertTool = (kind) => {
|
|
527
|
-
if (excludedStructures.includes(kind))
|
|
705
|
+
if (excludedStructures.includes(kind) || matrixRange)
|
|
528
706
|
return;
|
|
529
707
|
const current = historyRef.current.present;
|
|
530
708
|
const selection = range ??
|
|
@@ -545,11 +723,13 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
545
723
|
// Nested slots share the same caret model. Only the active lexical token mounts an input.
|
|
546
724
|
const renderRow = (r, name, role = 'expression') => (_jsx("span", { className: "me-row", "data-math-role": role, children: r.children.map((node) => {
|
|
547
725
|
if (isGrid(node))
|
|
548
|
-
return (_jsxs("span", { className: "me-matrix", "data-selected": selectedGrid === node.id || undefined, "data-structure": node.type, "data-environment": node.type === 'matrix'
|
|
726
|
+
return (_jsxs("span", { className: "me-matrix", "data-selected": selectedGrid === node.id || undefined, "data-structure": node.type, "data-matrix-id": node.id, "data-environment": node.type === 'matrix'
|
|
549
727
|
? node.environment
|
|
550
728
|
: node.type === 'cases'
|
|
551
729
|
? 'Bmatrix'
|
|
552
|
-
: 'matrix', children: [_jsx("span", { className: "me-matrix-delimiter me-matrix-left", "aria-hidden": "true" }), _jsx("span", { className: "me-matrix-grid", style: { gridTemplateColumns: `repeat(${node.columns}, max-content)` }, children: node.slots.map((cell, index) => (_jsx("span", { className: "me-matrix-cell",
|
|
730
|
+
: 'matrix', children: [_jsx("span", { className: "me-matrix-delimiter me-matrix-left", "aria-hidden": "true" }), _jsx("span", { className: "me-matrix-grid", style: { gridTemplateColumns: `repeat(${node.columns}, max-content)` }, children: node.slots.map((cell, index) => (_jsx("span", { className: "me-matrix-cell", "data-cell-index": index, "data-cell-selected": (matrixSelection?.matrix.id === node.id &&
|
|
731
|
+
matrixSelection.indices.includes(index)) ||
|
|
732
|
+
undefined, children: renderRow(cell, labels.grid(name, node.type, index, node.columns), 'group') }, cell.id))) }), _jsx("span", { className: "me-matrix-delimiter me-matrix-right", "aria-hidden": "true" })] }, node.id));
|
|
553
733
|
if (node.type === 'limit' || node.type === 'limsup' || node.type === 'liminf')
|
|
554
734
|
return (_jsxs("span", { className: "me-structure me-limit-operator", "data-structure": node.type, "data-math-style": node.mathStyle, "data-limit-placement": node.limits === false ? 'nolimits' : node.limits ? 'limits' : 'auto', children: [_jsxs("span", { className: "me-limits", children: [_jsx("span", { className: "me-limit-glyph", "aria-hidden": "true", children: node.type === 'limit' ? 'lim' : node.type === 'limsup' ? 'lim sup' : 'lim inf' }), _jsx("span", { className: "me-limit me-slot", children: renderRow(node.slots[0], labels.slot(name, node.type, 0), 'lower') })] }), _jsx("span", { className: "me-slot", children: renderRow(node.slots[1], labels.slot(name, node.type, 1)) })] }, node.id));
|
|
555
735
|
if (node.type !== 'text' &&
|
|
@@ -591,6 +771,7 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
591
771
|
const selected = selectedText(node.id, token.start, token.end);
|
|
592
772
|
const isActive = editing &&
|
|
593
773
|
!range &&
|
|
774
|
+
!matrixRange &&
|
|
594
775
|
state.caret.id === node.id &&
|
|
595
776
|
tokenIndexAt(parts, state.caret.start, state.caret.affinity) === tokenIndex;
|
|
596
777
|
const caretFrom = (input) => ({
|
|
@@ -651,7 +832,7 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
651
832
|
compositionStart.current ||
|
|
652
833
|
event.keyCode === 229)
|
|
653
834
|
return;
|
|
654
|
-
if (keyboardSelect(event))
|
|
835
|
+
if (matrixSelectionKey(event) || keyboardSelect(event))
|
|
655
836
|
return;
|
|
656
837
|
const current = historyRef.current.present;
|
|
657
838
|
if (selectedGrid) {
|
|
@@ -773,21 +954,10 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
773
954
|
}
|
|
774
955
|
return;
|
|
775
956
|
}
|
|
776
|
-
if (!event.shiftKey &&
|
|
777
|
-
current.caret.start === current.caret.end &&
|
|
778
|
-
activeGrid(current) &&
|
|
779
|
-
['ArrowUp', 'ArrowDown'].includes(event.key)) {
|
|
780
|
-
event.preventDefault();
|
|
781
|
-
publish({
|
|
782
|
-
...historyRef.current,
|
|
783
|
-
present: moveMatrixVertical(current, event.key === 'ArrowUp' ? -1 : 1),
|
|
784
|
-
}, true);
|
|
785
|
-
return;
|
|
786
|
-
}
|
|
787
957
|
if (!event.shiftKey &&
|
|
788
958
|
current.caret.start === current.caret.end &&
|
|
789
959
|
['ArrowUp', 'ArrowDown'].includes(event.key)) {
|
|
790
|
-
const next =
|
|
960
|
+
const next = moveVertical(current, event.key === 'ArrowUp' ? -1 : 1, surface.current ? renderedCaretGeometry(surface.current) : undefined);
|
|
791
961
|
if (next !== current) {
|
|
792
962
|
event.preventDefault();
|
|
793
963
|
publish({ ...historyRef.current, present: next }, true);
|
|
@@ -836,7 +1006,19 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
836
1006
|
} })) : (_jsx("span", { className: "me-preview-token", "data-token-kind": token.kind, "aria-label": name, role: "button", tabIndex: -1, children: selected && token.text ? (_jsxs("span", { children: [token.text.slice(0, selected[0]), _jsx("mark", { className: "me-range-highlight", children: token.text.slice(selected[0], selected[1]) }), token.text.slice(selected[1])] })) : (token.text || (r.children.length === 1 ? '□' : '\u200b')) }))] }, key));
|
|
837
1007
|
});
|
|
838
1008
|
}) }, r.id));
|
|
839
|
-
return (_jsxs("div", { className: "me-editor", "data-math-editor-owner": suggestionId,
|
|
1009
|
+
return (_jsxs("div", { className: "me-editor", "data-math-editor-owner": suggestionId, onKeyDownCapture: (event) => {
|
|
1010
|
+
if (!event.nativeEvent.isComposing &&
|
|
1011
|
+
!composing &&
|
|
1012
|
+
event.altKey &&
|
|
1013
|
+
event.shiftKey &&
|
|
1014
|
+
event.code === 'KeyV') {
|
|
1015
|
+
event.preventDefault();
|
|
1016
|
+
event.stopPropagation();
|
|
1017
|
+
setQuickOpen(false);
|
|
1018
|
+
setSymbolsOpen(false);
|
|
1019
|
+
setLatexOpen(true);
|
|
1020
|
+
}
|
|
1021
|
+
}, onCopy: copySelection, onCut: (event) => copySelection(event, true), onPaste: pasteSelection, role: "group", lang: locale, dir: mathLocaleDirection(locale), "aria-label": label ?? t('editor.label'), onBlur: (event) => {
|
|
840
1022
|
if (!event.currentTarget.contains(event.relatedTarget) &&
|
|
841
1023
|
!suggestionMenu.current?.contains(event.relatedTarget) &&
|
|
842
1024
|
!selectionMenu.current?.contains(event.relatedTarget) &&
|
|
@@ -846,19 +1028,74 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
846
1028
|
setFocused(false);
|
|
847
1029
|
setEditing(false);
|
|
848
1030
|
}
|
|
849
|
-
}, children: [toolbar && (_jsx(MathEditorToolbar, { locale: locale, kinds: Array.isArray(toolbar) ? toolbar : undefined, maxItems: toolbarMaxItems, excludedStructures: excludedStructures, composing: composing, hasRange: !!range, canWrap: canWrap, canUndo: !!history.past.length, canRedo: !!history.future.length, symbolsOpen: symbolsOpen,
|
|
1031
|
+
}, children: [toolbar && (_jsx(MathEditorToolbar, { locale: locale, kinds: Array.isArray(toolbar) ? toolbar : undefined, maxItems: toolbarMaxItems, excludedStructures: excludedStructures, composing: composing, hasRange: !!range || !!matrixRange, cellRange: !!matrixRange, canWrap: canWrap, canUndo: !!history.past.length, canRedo: !!history.future.length, symbolsOpen: symbolsOpen, onQuick: () => {
|
|
1032
|
+
setSymbolsOpen(false);
|
|
1033
|
+
setLatexOpen(false);
|
|
1034
|
+
setQuickOpen(true);
|
|
1035
|
+
}, onPasteLatex: () => {
|
|
1036
|
+
setQuickOpen(false);
|
|
1037
|
+
setSymbolsOpen(false);
|
|
1038
|
+
setLatexOpen(true);
|
|
1039
|
+
}, onInsertStructure: insertTool, onMatrixPreset: (value) => apply(value.startsWith('identity-')
|
|
850
1040
|
? insertIdentityMatrix(historyRef.current.present, Number(value.slice(9)))
|
|
851
|
-
: insertMatrix(historyRef.current.present, Number(value))), onTemplate: (id) =>
|
|
1041
|
+
: insertMatrix(historyRef.current.present, Number(value))), onTemplate: (id) => {
|
|
1042
|
+
apply(insertTemplate(historyRef.current.present, id, range));
|
|
1043
|
+
preferences.record(`template-${id}`);
|
|
1044
|
+
}, onToggleSymbols: () => {
|
|
1045
|
+
setQuickOpen(false);
|
|
1046
|
+
setLatexOpen(false);
|
|
1047
|
+
setSymbolsOpen((value) => !value);
|
|
1048
|
+
}, onInsertSymbol: (glyph) => {
|
|
1049
|
+
preferences.record(`symbol-${glyph}`);
|
|
852
1050
|
const current = historyRef.current.present, caret = current.caret;
|
|
853
1051
|
const value = textNodes(current.document).find((node) => node.id === caret.id).text;
|
|
854
1052
|
apply(setText(current, value.slice(0, caret.start) + glyph + value.slice(caret.end), caret.start + glyph.length));
|
|
855
|
-
}, onUndo: () => publish(undo(historyRef.current), true), onRedo: () => publish(redo(historyRef.current), true), children: toolbarEnd })), toolbar &&
|
|
1053
|
+
}, onUndo: () => publish(undo(historyRef.current), true), onRedo: () => publish(redo(historyRef.current), true), children: toolbarEnd })), toolbar && (_jsx(PresentationControls, { state: state, locale: locale, disabled: composing || !!range || !!matrixRange, kinds: mathStructures
|
|
1054
|
+
.filter((item) => !excludedStructures.includes(item.kind) &&
|
|
1055
|
+
(!Array.isArray(toolbar) || toolbar.includes(item.kind)))
|
|
1056
|
+
.map((item) => item.kind), onChange: (id, change) => apply(setMathPresentation(historyRef.current.present, id, change)) })), quickOpen && (_jsx(QuickPanel, { locale: locale, preferences: preferences, allowedTemplates: toolbarTemplates(mathStructures
|
|
1057
|
+
.filter((item) => !excludedStructures.includes(item.kind) &&
|
|
1058
|
+
(!Array.isArray(toolbar) || toolbar.includes(item.kind)))
|
|
1059
|
+
.map((item) => item.kind)).map((item) => item.id), onInsert: (item) => {
|
|
1060
|
+
if (composing || matrixRange)
|
|
1061
|
+
return false;
|
|
1062
|
+
const current = historyRef.current.present;
|
|
1063
|
+
const next = item.template
|
|
1064
|
+
? insertTemplate(current, item.template, range)
|
|
1065
|
+
: pasteFragment(current, { version: 1, rows: [row(item.glyph)] }, range);
|
|
1066
|
+
if (next === current)
|
|
1067
|
+
return false;
|
|
1068
|
+
apply(next);
|
|
1069
|
+
return true;
|
|
1070
|
+
}, onClose: () => {
|
|
1071
|
+
setQuickOpen(false);
|
|
1072
|
+
publish({ ...historyRef.current }, true);
|
|
1073
|
+
} })), latexOpen && (_jsx(LatexPastePanel, { locale: locale, onInsert: pasteLatex, onClose: () => {
|
|
1074
|
+
setLatexOpen(false);
|
|
1075
|
+
focusNext.current = true;
|
|
1076
|
+
setEditing(true);
|
|
1077
|
+
publish({ ...historyRef.current }, true);
|
|
1078
|
+
} })), toolbar && symbolsOpen && (_jsx(SymbolBrowser, { locale: locale, onClose: () => {
|
|
856
1079
|
setSymbolsOpen(false);
|
|
857
1080
|
surface.current?.focus();
|
|
858
1081
|
}, onInsert: (glyph) => {
|
|
1082
|
+
preferences.record(`symbol-${glyph}`);
|
|
859
1083
|
apply(pasteFragment(historyRef.current.present, { version: 1, rows: [row(glyph)] }, range));
|
|
860
1084
|
setSymbolsOpen(false);
|
|
861
|
-
} })), showTokenLegend && (_jsxs("div", { className: "me-token-legend", "aria-label": t('token.legend'), children: [_jsx("span", { "data-kind": "variable", children: t('token.variable') }), _jsx("span", { "data-kind": "constant", children: t('token.constant') }), _jsx("span", { "data-kind": "symbol", children: t('token.symbol') }), _jsx("span", { "data-kind": "function", children: t('token.function') }), _jsx("small", { children: t('editor.interactionHint') })] })), clipboardMessage && (_jsx("div", { className: "me-grid-selection-hint", role: "status", children: t(clipboardMessage) })), selectedGrid && (_jsx("div", { className: "me-grid-selection-hint", role: "status", children: t('grid.selectionHint') })), toolbar && matrixContext && (_jsxs("div", { className: "me-matrix-tools", role: "toolbar", "aria-label": t(matrixContext.matrix.type === 'matrix' ? 'matrix.edit' : 'grid.editRows'), children: [_jsxs("span", { children: [matrixContext.rows, " \u00D7 ", matrixContext.matrix.columns, ' ', _jsxs("small", { children: ["\u00B7", ' ', t('grid.position', { row: matrixContext.row + 1, column: matrixContext.column + 1 })] })] }), matrixContext.matrix.type === 'matrix' && (_jsx("select", { "aria-label": t('matrix.delimiters'), value: matrixContext.matrix.environment, disabled: composing, onChange: (event) => apply(setMatrixEnvironment(historyRef.current.present, event.target.value)), children: matrixEnvironments.map((item) => (_jsx("option", { value: item.value, children: t(item.label) }, item.value))) })),
|
|
1085
|
+
} })), showTokenLegend && (_jsxs("div", { className: "me-token-legend", "aria-label": t('token.legend'), children: [_jsx("span", { "data-kind": "variable", children: t('token.variable') }), _jsx("span", { "data-kind": "constant", children: t('token.constant') }), _jsx("span", { "data-kind": "symbol", children: t('token.symbol') }), _jsx("span", { "data-kind": "function", children: t('token.function') }), _jsx("small", { children: t('editor.interactionHint') })] })), clipboardMessage && (_jsx("div", { className: "me-grid-selection-hint", role: "status", children: t(clipboardMessage) })), selectedGrid && (_jsx("div", { className: "me-grid-selection-hint", role: "status", children: t('grid.selectionHint') })), toolbar && matrixContext && (_jsxs("div", { className: "me-matrix-tools", role: "toolbar", "aria-label": t(matrixContext.matrix.type === 'matrix' ? 'matrix.edit' : 'grid.editRows'), children: [_jsxs("span", { children: [matrixContext.rows, " \u00D7 ", matrixContext.matrix.columns, ' ', _jsxs("small", { children: ["\u00B7", ' ', t('grid.position', { row: matrixContext.row + 1, column: matrixContext.column + 1 })] })] }), matrixContext.matrix.type === 'matrix' && (_jsx("select", { "aria-label": t('matrix.delimiters'), value: matrixContext.matrix.environment, disabled: composing || !!matrixRange || !!range, onChange: (event) => apply(setMatrixEnvironment(historyRef.current.present, event.target.value)), children: matrixEnvironments.map((item) => (_jsx("option", { value: item.value, children: t(item.label) }, item.value))) })), matrixContext.matrix.type === 'matrix' && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", disabled: composing || !!range, onMouseDown: (event) => event.preventDefault(), onClick: () => selectCells({
|
|
1086
|
+
matrixId: matrixContext.matrix.id,
|
|
1087
|
+
anchor: matrixContext.cell,
|
|
1088
|
+
focus: matrixContext.cell,
|
|
1089
|
+
}), children: t('matrix.selectCells') }), _jsx("button", { type: "button", disabled: composing || !!range, onMouseDown: (event) => event.preventDefault(), onClick: () => selectCells({
|
|
1090
|
+
matrixId: matrixContext.matrix.id,
|
|
1091
|
+
anchor: 0,
|
|
1092
|
+
focus: matrixContext.matrix.slots.length - 1,
|
|
1093
|
+
}), children: t('matrix.selectAll') }), _jsx("button", { type: "button", disabled: composing || !!range, onMouseDown: (event) => event.preventDefault(), onClick: () => {
|
|
1094
|
+
const current = historyRef.current.present;
|
|
1095
|
+
const next = transposeMatrix(current, matrixRange?.matrixId);
|
|
1096
|
+
if (next !== current)
|
|
1097
|
+
apply(next);
|
|
1098
|
+
}, children: t('matrix.transpose') })] })), ['row', 'column']
|
|
862
1099
|
.filter((axis) => axis === 'row' || matrixContext.matrix.type === 'matrix')
|
|
863
1100
|
.flatMap((axis) => ['insert', 'delete'].map((action) => {
|
|
864
1101
|
const size = axis === 'row' ? matrixContext.rows : matrixContext.matrix.columns;
|
|
@@ -868,7 +1105,10 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
868
1105
|
? axis === 'row'
|
|
869
1106
|
? 'Alt+Shift+ArrowUp'
|
|
870
1107
|
: 'Alt+Shift+ArrowLeft'
|
|
871
|
-
: undefined, disabled: composing ||
|
|
1108
|
+
: undefined, disabled: composing ||
|
|
1109
|
+
!!matrixRange ||
|
|
1110
|
+
!!range ||
|
|
1111
|
+
(action === 'delete' ? size === 1 : size >= MATRIX_MAX_SIZE), onMouseDown: (event) => event.preventDefault(), onClick: () => apply(resizeMatrix(historyRef.current.present, axis, action)), children: t(axis === 'row'
|
|
872
1112
|
? action === 'insert'
|
|
873
1113
|
? 'grid.addRow'
|
|
874
1114
|
: 'grid.deleteRow'
|
|
@@ -879,10 +1119,9 @@ export function MathEditor({ apiRef, autoFocus = false, enterBehavior = 'newline
|
|
|
879
1119
|
? t('matrix.keyboardHint')
|
|
880
1120
|
: `${t(matrixContext.matrix.type === 'aligned' ? 'aligned.inputHint' : 'cases.inputHint')} · ${t('grid.keyboardHint')}` })] })), showPopovers &&
|
|
881
1121
|
candidates.length > 0 &&
|
|
882
|
-
createPortal(_jsxs("div", { className: "me-suggestion-panel", "data-math-editor-owner": suggestionId, lang: locale, dir: mathLocaleDirection(locale), ref: suggestionMenu, onMouseDown: (event) => event.preventDefault(), children: [_jsxs("div", { className: "me-suggestion-heading", children: [t('suggestion.create', { query })
|
|
1122
|
+
createPortal(_jsxs("div", { className: "me-suggestion-panel", "data-math-editor-owner": suggestionId, lang: locale, dir: mathLocaleDirection(locale), ref: suggestionMenu, onMouseDown: (event) => event.preventDefault(), children: [_jsxs("div", { className: "me-suggestion-heading", children: [_jsx("span", { className: "me-suggestion-query", children: t('suggestion.create', { query }) }), _jsx("span", { children: t(composing ? 'suggestion.composing' : 'suggestion.keyboardHint') })] }), _jsx("div", { className: "me-suggestions", id: suggestionId, role: "listbox", "aria-label": t('suggestion.label'), children: candidates.map((c, index) => (_jsxs("button", { type: "button", id: `${suggestionId}-${index}`, role: "option", disabled: composing, "aria-selected": !composing && index === selectedIndex, onClick: () => choose(index), children: [_jsx("span", { className: "me-candidate-glyph", children: c.glyph }), _jsxs("span", { className: "me-candidate-copy", children: [_jsx("strong", { children: c.label }), _jsx("small", { children: c.detail })] })] }, c.id))) }), _jsx("div", { className: "me-suggestion-footer", children: t(composing ? 'suggestion.imeHint' : 'suggestion.keepSource') })] }), surface.current?.closest('dialog, [role="dialog"]') ?? document.body), _jsx("div", { className: "me-surface", dir: "ltr", ref: surface, tabIndex: 0, "aria-label": t('selection.surface'), "data-mode": editing ? 'edit' : 'preview', onPointerDown: beginPointer, onPointerMove: movePointer, onPointerUp: endPointer, onPointerCancel: () => {
|
|
883
1123
|
drag.current = undefined;
|
|
884
|
-
}, onKeyDown: selectionKey, children: _jsx("div", { className: "me-document-lines", children: documentRows(state.document).map((line, index) => (_jsxs("div", { className: "me-document-line", children: [showLineNumbers && documentRows(state.document).length > 1 && (_jsx("span", { className: "me-line-number", "aria-hidden": "true", children: index + 1 })), renderRow(line, labels.line(index))] }, line.id))) }) }), showPopovers &&
|
|
1124
|
+
}, onKeyDown: selectionKey, children: _jsx("div", { className: "me-document-lines", children: documentRows(state.document).map((line, index) => (_jsxs("div", { className: "me-document-line", children: [showLineNumbers && documentRows(state.document).length > 1 && (_jsx("span", { className: "me-line-number", "aria-hidden": "true", children: index + 1 })), renderRow(line, labels.line(index))] }, line.id))) }) }), matrixSelection && (_jsx("div", { className: "me-grid-selection-hint", role: "status", children: t('matrix.rangeHint', { rows: matrixSelection.rows, columns: matrixSelection.columns }) })), showPopovers &&
|
|
885
1125
|
selectionFragment &&
|
|
886
|
-
createPortal(_jsxs("div", { className: "me-suggestion-panel", "data-math-editor-owner": suggestionId, ref: selectionMenu, role: "presentation", "aria-label": t('selection.toolbar'), onKeyDown: selectionKey, children: [_jsx("div", { className: "me-suggestion-heading", children: t(canWrap ? 'selection.highlighted' : 'selection.singleRowRequired') }), _jsx("div", { className: "me-suggestions", role: "listbox", "aria-label": t('selection.toolbar'), children: selectionChoices.map((s, index) => (_jsxs("button", { type: "button", role: "option", "aria-selected": index === selectionIndex, disabled: !canWrap, onMouseDown: (event) => event.preventDefault(), onClick: () => insertTool(s.kind), "aria-label": t('selection.wrap', { kind: t(s.label) }), children: [_jsx("span", { className: "me-candidate-glyph", children: s.glyph }), _jsxs("span", { children: [_jsx("strong", { children: t(s.label) }), _jsx("small", { children: t(s.detail) })] })] }, s.kind))) })] }), surface.current?.closest('dialog, [role="dialog"]') ?? document.body)] }));
|
|
1126
|
+
createPortal(_jsxs("div", { className: "me-suggestion-panel", "data-math-editor-owner": suggestionId, ref: selectionMenu, role: "presentation", "aria-label": t('selection.toolbar'), onKeyDown: selectionKey, children: [_jsx("div", { className: "me-suggestion-heading", children: t(canWrap ? 'selection.highlighted' : 'selection.singleRowRequired') }), _jsx("div", { className: "me-suggestions", role: "listbox", "aria-label": t('selection.toolbar'), children: selectionChoices.map((s, index) => (_jsxs("button", { type: "button", role: "option", "aria-selected": index === selectionIndex, disabled: !canWrap, onMouseDown: (event) => event.preventDefault(), onClick: () => insertTool(s.kind), "aria-label": t('selection.wrap', { kind: t(s.label) }), children: [_jsx("span", { className: "me-candidate-glyph", children: s.glyph }), _jsxs("span", { className: "me-candidate-copy", children: [_jsx("strong", { children: t(s.label) }), _jsx("small", { children: t(s.detail) })] })] }, s.kind))) })] }), surface.current?.closest('dialog, [role="dialog"]') ?? document.body)] }));
|
|
887
1127
|
}
|
|
888
|
-
//# sourceMappingURL=math-editor.js.map
|