diff options
Diffstat (limited to 'src/client/views/EditableView.tsx')
-rw-r--r-- | src/client/views/EditableView.tsx | 91 |
1 files changed, 64 insertions, 27 deletions
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 684b948af..af6a43555 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -1,6 +1,6 @@ /* eslint-disable jsx-a11y/no-static-element-interactions */ /* eslint-disable jsx-a11y/click-events-have-key-events */ -import { action, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import * as Autosuggest from 'react-autosuggest'; @@ -10,6 +10,8 @@ import { DocumentIconContainer } from './nodes/DocumentIcon'; import { FieldView, FieldViewProps } from './nodes/FieldView'; import { ObservableReactComponent } from './ObservableReactComponent'; import { OverlayView } from './OverlayView'; +import { Padding } from 'browndash-components'; +import { SchemaFieldType } from './collections/collectionSchema/SchemaColumnHeader'; export interface EditableProps { /** @@ -54,6 +56,13 @@ export interface EditableProps { background?: string | undefined; placeholder?: string; wrap?: string; // nowrap, pre-wrap, etc + + schemaFieldType?: SchemaFieldType; + prohibitedText?: Array<string>; + onClick?: () => void; + updateAlt?: (newAlt: string) => void; + updateSearch?: (value: string) => void; + highlightCells?: (text: string) => void; } /** @@ -65,18 +74,17 @@ export interface EditableProps { export class EditableView extends ObservableReactComponent<EditableProps> { private _ref = React.createRef<HTMLDivElement>(); private _inputref: HTMLInputElement | HTMLTextAreaElement | null = null; + private _disposers: { [name: string]: IReactionDisposer } = {}; _overlayDisposer?: () => void; - _editingDisposer?: IReactionDisposer; @observable _editing: boolean = false; constructor(props: EditableProps) { super(props); makeObservable(this); - this._editing = !!this._props.editing; } componentDidMount(): void { - this._editingDisposer = reaction( + this._disposers.editing = reaction( () => this._editing, editing => { if (editing) { @@ -84,11 +92,13 @@ export class EditableView extends ObservableReactComponent<EditableProps> { if (this._inputref?.value.startsWith('=') || this._inputref?.value.startsWith(':=')) { this._overlayDisposer?.(); this._overlayDisposer = OverlayView.Instance.addElement(<DocumentIconContainer />, { x: 0, y: 0 }); - } + this._props.highlightCells?.(this._props.GetValue() ?? ''); + } }); } else { this._overlayDisposer?.(); this._overlayDisposer = undefined; + this._props.highlightCells?.(''); } }, { fireImmediately: true } @@ -107,7 +117,7 @@ export class EditableView extends ObservableReactComponent<EditableProps> { componentWillUnmount() { this._overlayDisposer?.(); - this._editingDisposer?.(); + this._disposers.editing?.(); this._inputref?.value && this.finalizeEdit(this._inputref.value, false, true, false); } @@ -119,6 +129,8 @@ export class EditableView extends ObservableReactComponent<EditableProps> { } else if (!this._overlayDisposer) { this._overlayDisposer = OverlayView.Instance.addElement(<DocumentIconContainer />, { x: 0, y: 0 }); } + this._props.updateSearch && this._props.updateSearch(targVal); + this._props.highlightCells?.(targVal); }; @action @@ -155,7 +167,7 @@ export class EditableView extends ObservableReactComponent<EditableProps> { case 'ArrowDown': case 'ArrowLeft': case 'ArrowRight': - e.stopPropagation(); + //e.stopPropagation(); break; case 'Shift': case 'Alt': @@ -179,9 +191,10 @@ export class EditableView extends ObservableReactComponent<EditableProps> { }; @action - onClick = (e: React.MouseEvent) => { + onClick = (e?: React.MouseEvent) => { + this._props.onClick && this._props.onClick(); if (this._props.editing !== false) { - e.nativeEvent.stopPropagation(); + e?.nativeEvent.stopPropagation(); if (this._ref.current && this._props.showMenuOnLoad) { this._props.menuCallback?.(this._ref.current.getBoundingClientRect().x, this._ref.current.getBoundingClientRect().y); } else { @@ -190,7 +203,7 @@ export class EditableView extends ObservableReactComponent<EditableProps> { } } }; - + @action finalizeEdit(value: string, shiftDown: boolean, lostFocus: boolean, enterKey: boolean) { if (this._props.SetValue(value, shiftDown, enterKey)) { @@ -221,6 +234,12 @@ export class EditableView extends ObservableReactComponent<EditableProps> { return wasFocused !== this._editing; }; + @action + setIsEditing = (value: boolean) => { + this._editing = value; + return this._editing; + } + renderEditor() { return this._props.autosuggestProps ? ( <Autosuggest @@ -240,11 +259,11 @@ export class EditableView extends ObservableReactComponent<EditableProps> { onChange: this._props.autosuggestProps.onChange, }} /> - ) : this._props.oneLine !== false && this._props.GetValue()?.toString().indexOf('\n') === -1 ? ( + ) : ( this._props.oneLine !== false && this._props.GetValue()?.toString().indexOf('\n') === -1 ? ( <input - className="editableView-input" + className="editableView-input" ref={r => { this._inputref = r; }} // prettier-ignore - style={{ display: this._props.display, overflow: 'auto', fontSize: this._props.fontSize, minWidth: 20, background: this._props.background }} + style={{ display: this._props.display, overflow: 'auto', fontSize: this._props.fontSize, minWidth: 20, background: this._props.background}} placeholder={this._props.placeholder} onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)} defaultValue={this._props.GetValue()} @@ -272,16 +291,42 @@ export class EditableView extends ObservableReactComponent<EditableProps> { onClick={this.stopPropagation} onPointerUp={this.stopPropagation} /> - ); + )); + } + + staticDisplay = () => { + let toDisplay; + const gval = this._props.GetValue()?.replace(/\n/g, '\\r\\n'); + if (this._props.schemaFieldType === SchemaFieldType.Header){ + toDisplay = <input className="editableView-input" + value={gval} + placeholder='Add key' + readOnly + style={{ display: this._props.display, overflow: 'auto', pointerEvents: 'none', fontSize: this._props.fontSize, width: '100%', margin: 0, background: this._props.background}} + // eslint-disable-next-line jsx-a11y/no-autofocus + /> + } else { + toDisplay = (<span className='editableView-static' + style={{ + fontStyle: this._props.fontStyle, + fontSize: this._props.fontSize + }}> + { + // eslint-disable-next-line react/jsx-props-no-spreading + this._props.fieldContents ? <FieldView {...this._props.fieldContents} /> : this.props.contents ? this._props.contents?.valueOf() : '' + } + </span>) + } + + return toDisplay; } render() { const gval = this._props.GetValue()?.replace(/\n/g, '\\r\\n'); - if (this._editing && gval !== undefined) { + if ((this._editing && gval !== undefined)) { return this._props.sizeToContent ? ( <div style={{ display: 'grid', minWidth: 100 }}> - <div style={{ display: 'inline-block', position: 'relative', height: 0, width: '100%', overflow: 'hidden' }}>{gval}</div> - {this.renderEditor()} + <div style={{ display: 'inline-block', position: 'relative', height: 0, width: '100%', overflow: 'hidden' }}>{this.renderEditor()}</div> </div> ) : ( this.renderEditor() @@ -298,21 +343,13 @@ export class EditableView extends ObservableReactComponent<EditableProps> { minHeight: '10px', whiteSpace: this._props.oneLine ? 'nowrap' : 'pre-line', height: this._props.height, + width: '100%', maxHeight: this._props.maxHeight, fontStyle: this._props.fontStyle, fontSize: this._props.fontSize, }} onClick={this.onClick}> - <span - style={{ - fontStyle: this._props.fontStyle, - fontSize: this._props.fontSize, - }}> - { - // eslint-disable-next-line react/jsx-props-no-spreading - this._props.fieldContents ? <FieldView {...this._props.fieldContents} /> : this.props.contents ? this._props.contents?.valueOf() : '' - } - </span> + {this.staticDisplay()} </div> ); } |