diff options
Diffstat (limited to 'src/client/views/nodes/formattedText')
4 files changed, 47 insertions, 24 deletions
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index 5b03e2236..8802a032f 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -1,6 +1,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import { action, computed, IReactionDisposer, makeObservable, observable, reaction, trace } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction, trace } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; @@ -22,15 +22,20 @@ import { OpenWhere } from '../DocumentView'; import './DashFieldView.scss'; import { FormattedTextBox } from './FormattedTextBox'; import { DocData } from '../../../../fields/DocSymbols'; +import { NodeSelection, TextSelection } from 'prosemirror-state'; export class DashFieldView { dom: HTMLDivElement; // container for label and value root: any; node: any; tbox: FormattedTextBox; + @observable expanded = false; + Expanded = () => this.expanded; unclickable = () => !this.tbox._props.rootSelected?.() && this.node.marks.some((m: any) => m.type === this.tbox.EditorView?.state.schema.marks.linkAnchor && m.attrs.noPreview); constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) { + makeObservable(this); + const self = this; this.node = node; this.tbox = tbox; this.dom = document.createElement('div'); @@ -38,11 +43,26 @@ export class DashFieldView { this.dom.style.height = node.attrs.height; this.dom.style.position = 'relative'; this.dom.style.display = 'inline-block'; - this.dom.onkeypress = function (e: any) { + const tBox = this.tbox; + this.dom.onkeypress = function (e: KeyboardEvent) { e.stopPropagation(); }; - this.dom.onkeydown = function (e: any) { + this.dom.onkeydown = function (e: KeyboardEvent) { e.stopPropagation(); + if (e.key === 'Tab') { + e.preventDefault(); + const editor = tbox.EditorView; + if (editor) { + const state = editor.state; + for (var i = state.selection.to; i < state.doc.content.size; i++) { + if (state.doc.nodeAt(i)?.type.name === state.schema.nodes.dashField.name) { + editor.dispatch(state.tr.setSelection(new NodeSelection(state.doc.resolve(i)))); + return; + } + } + tBox.setFocus(state.selection.to + 1); + } + } }; this.dom.onkeyup = function (e: any) { e.stopPropagation(); @@ -51,6 +71,8 @@ export class DashFieldView { e.stopPropagation(); }; + this.expanded = node.attrs.expanded; + this.root = ReactDOM.createRoot(this.dom); this.root.render( <DashFieldViewInternal @@ -63,7 +85,7 @@ export class DashFieldView { height={node.attrs.height} hideKey={node.attrs.hideKey} editable={node.attrs.editable} - expanded={node.attrs.expanded} + expanded={this.Expanded} dataDoc={node.attrs.dataDoc} tbox={tbox} /> @@ -77,9 +99,11 @@ export class DashFieldView { }); } deselectNode() { + runInAction(() => (this.expanded = false)); this.dom.classList.remove('ProseMirror-selectednode'); } selectNode() { + setTimeout(() => runInAction(() => (this.expanded = true)), 100); this.dom.classList.add('ProseMirror-selectednode'); } } @@ -92,7 +116,7 @@ interface IDashFieldViewInternal { width: number; height: number; editable: boolean; - expanded: boolean; + expanded: () => boolean; dataDoc: boolean; node: any; getPos: any; @@ -106,7 +130,7 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi _fieldKey: string; _fieldRef = React.createRef<HTMLDivElement>(); @observable _dashDoc: Doc | undefined = undefined; - @observable _expanded = this._props.expanded; + @observable _expanded = this._props.expanded(); constructor(props: IDashFieldViewInternal) { super(props); @@ -132,7 +156,7 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi componentWillUnmount() { this._reactionDisposer?.(); } - isRowActive = () => this._expanded && this._props.editable; + isRowActive = () => (this._props.expanded() || this._expanded) && this._props.editable; finishEdit = action(() => { if (this._expanded) { @@ -155,7 +179,7 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi deselectCell={emptyFunction} selectCell={emptyFunction} maxWidth={this._props.hideKey || this._hideKey ? undefined : this._props.tbox._props.PanelWidth} - columnWidth={this._expanded ? this.columnWidth : returnZero} + columnWidth={this._expanded || this._props.expanded() ? this.columnWidth : returnZero} selectedCell={this.selectedCell} fieldKey={this._fieldKey} rowHeight={returnZero} @@ -164,7 +188,7 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi getFinfo={emptyFunction} setColumnValues={returnFalse} allowCRs={true} - oneLine={!this._expanded} + oneLine={!this._expanded && !this._props.expanded()} finishEdit={this.finishEdit} transform={Transform.Identity} menuTarget={null} @@ -217,7 +241,7 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi }; @computed get values() { - if (this._props.expanded) return []; + if (this._props.expanded()) return []; const vals = FilterPanel.gatherFieldValues(DocListCast(Doc.ActiveDashboard?.data), this._fieldKey, []); return vals.strings.map(facet => ({ value: facet, label: facet })); @@ -239,13 +263,13 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi </span> )} {this._props.fieldKey.startsWith('#') ? null : this.fieldValueContent} - {!this.values.length ? null : ( - <select className="dashFieldView-select" onChange={this.selectVal}> + {/* {!this.values.length ? null : ( + <select className="dashFieldView-select" tabIndex={-1} onChange={this.selectVal}> {this.values.map(val => ( <option value={val.value}>{val.label}</option> ))} </select> - )} + )} */} </div> ); } diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx index b786c5ffb..b90653acc 100644 --- a/src/client/views/nodes/formattedText/EquationView.tsx +++ b/src/client/views/nodes/formattedText/EquationView.tsx @@ -8,6 +8,7 @@ import { StrCast } from '../../../../fields/Types'; import './DashFieldView.scss'; import EquationEditor from './EquationEditor'; import { FormattedTextBox } from './FormattedTextBox'; +import { DocData } from '../../../../fields/DocSymbols'; export class EquationView { dom: HTMLDivElement; // container for label and value @@ -88,7 +89,6 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal> } e.stopPropagation(); }} - onKeyPress={e => e.stopPropagation()} style={{ position: 'relative', display: 'inline-block', @@ -96,12 +96,11 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal> height: this.props.height, background: 'white', borderRadius: '10%', - bottom: 3, }}> <EquationEditor ref={this._ref} - value={StrCast(this._textBoxDoc[this._fieldKey], 'y=')} - onChange={(str: any) => (this._textBoxDoc[this._fieldKey] = str)} + value={StrCast(this._textBoxDoc[DocData][this._fieldKey])} + onChange={(str: any) => (this._textBoxDoc[DocData][this._fieldKey] = str)} autoCommands="pi theta sqrt sum prod alpha beta gamma rho" autoOperatorNames="sin cos tan" spaceBehavesLikeTab={true} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index eb7293054..70b3b52fd 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1616,10 +1616,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB e.stopPropagation(); } }; - setFocus = () => { - const pos = this._editorView?.state.selection.$from.pos || 1; - (this.ProseRef?.children?.[0] as any).focus(); - setTimeout(() => this._editorView?.dispatch(this._editorView?.state.tr.setSelection(TextSelection.create(this._editorView.state.doc, pos)))); + setFocus = (ipos?: number) => { + const pos = ipos ?? (this._editorView?.state.selection.$from.pos || 1); + setTimeout(() => this._editorView?.dispatch(this._editorView.state.tr.setSelection(TextSelection.near(this._editorView.state.doc.resolve(pos)))), 100); + setTimeout(() => (this.ProseRef?.children?.[0] as any).focus(), 200); }; @action onFocused = (e: React.FocusEvent): void => { diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index adc031636..c3eaf4dd2 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -385,10 +385,10 @@ export class RichTextRules { }), // create an inline equation node - // eq:<equation>> - new InputRule(new RegExp(/%eq([a-zA-Z-0-9\(\)]*)$/), (state, match, start, end) => { + // %eq + new InputRule(new RegExp(/%eq/), (state, match, start, end) => { const fieldKey = 'math' + Utils.GenerateGuid(); - this.TextBox.dataDoc[fieldKey] = match[1]; + this.TextBox.dataDoc[fieldKey] = 'y='; const tr = state.tr.setSelection(new TextSelection(state.tr.doc.resolve(end - 3), state.tr.doc.resolve(end))).replaceSelectionWith(schema.nodes.equation.create({ fieldKey })); return tr.setSelection(new NodeSelection(tr.doc.resolve(tr.selection.$from.pos - 1))); }), |
