diff options
| author | Bob Zeleznik <zzzman@gmail.com> | 2020-02-08 13:48:11 -0500 |
|---|---|---|
| committer | Bob Zeleznik <zzzman@gmail.com> | 2020-02-08 13:48:11 -0500 |
| commit | 90d7fb57a64011763ad1d608126eacb052061e43 (patch) | |
| tree | fd96990ebd0ffe38f2285fbbceca942c1fb45587 /src/client/views/EditableView.tsx | |
| parent | e310c0fdcef6ac71ee492470d4ac689cbb094167 (diff) | |
| parent | 1b046f76cf39f1f6cb1875aa84b45db74b6d994e (diff) | |
Merge branch 'master' into monika_animation
Diffstat (limited to 'src/client/views/EditableView.tsx')
| -rw-r--r-- | src/client/views/EditableView.tsx | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 8e86f58ee..84c6b0dfd 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -1,16 +1,18 @@ import React = require('react'); +import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; -import { observable, action, trace } from 'mobx'; -import "./EditableView.scss"; import * as Autosuggest from 'react-autosuggest'; -import { undoBatch } from '../util/UndoManager'; +import { ObjectField } from '../../new_fields/ObjectField'; import { SchemaHeaderField } from '../../new_fields/SchemaHeaderField'; +import { ContextMenu } from './ContextMenu'; +import { ContextMenuProps } from './ContextMenuItem'; +import "./EditableView.scss"; export interface EditableProps { /** * Called to get the initial value for editing * */ - GetValue(): string; + GetValue(): string | undefined; /** * Called to apply changes @@ -21,7 +23,7 @@ export interface EditableProps { OnFillDown?(value: string): void; - OnTab?(): void; + OnTab?(shift?: boolean): void; /** * The contents to render when not editing @@ -36,13 +38,15 @@ export interface EditableProps { resetValue: () => void; value: string, onChange: (e: React.ChangeEvent, { newValue }: { newValue: string }) => void, - autosuggestProps: Autosuggest.AutosuggestProps<string> + autosuggestProps: Autosuggest.AutosuggestProps<string, any> }; oneLine?: boolean; editing?: boolean; onClick?: (e: React.MouseEvent) => boolean; isEditingCallback?: (isEditing: boolean) => void; + menuCallback?: (x: number, y: number) => void; + showMenuOnLoad?: boolean; HeadingObject?: SchemaHeaderField | undefined; HeadingsHack?: number; toggle?: () => void; @@ -65,7 +69,7 @@ export class EditableView extends React.Component<EditableProps> { } @action - componentWillReceiveProps(nextProps: EditableProps) { + componentDidUpdate(nextProps: EditableProps) { // this is done because when autosuggest is turned on, the suggestions are passed in as a prop, // so when the suggestions are passed in, and no editing prop is passed in, it used to set it // to false. this will no longer do so -syip @@ -74,12 +78,14 @@ export class EditableView extends React.Component<EditableProps> { } } + _didShow = false; + @action onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => { if (e.key === "Tab") { e.stopPropagation(); this.finalizeEdit(e.currentTarget.value, e.shiftKey); - this.props.OnTab && this.props.OnTab(); + this.props.OnTab && this.props.OnTab(e.shiftKey); } else if (e.key === "Enter") { e.stopPropagation(); if (!e.ctrlKey) { @@ -87,30 +93,36 @@ export class EditableView extends React.Component<EditableProps> { } else if (this.props.OnFillDown) { this.props.OnFillDown(e.currentTarget.value); this._editing = false; - this.props.isEditingCallback && this.props.isEditingCallback(false); + this.props.isEditingCallback?.(false); } } else if (e.key === "Escape") { e.stopPropagation(); this._editing = false; - this.props.isEditingCallback && this.props.isEditingCallback(false); + this.props.isEditingCallback?.(false); + } else if (e.key === ":") { + this.props.menuCallback?.(e.currentTarget.getBoundingClientRect().x, e.currentTarget.getBoundingClientRect().y); } } @action onClick = (e: React.MouseEvent) => { e.nativeEvent.stopPropagation(); - if (!this.props.onClick || !this.props.onClick(e)) { - this._editing = true; - this.props.isEditingCallback && this.props.isEditingCallback(true); + if (this._ref.current && this.props.showMenuOnLoad) { + this.props.menuCallback?.(this._ref.current.getBoundingClientRect().x, this._ref.current.getBoundingClientRect().y); + } else { + if (!this.props.onClick || !this.props.onClick(e)) { + this._editing = true; + this.props.isEditingCallback?.(true); + } } e.stopPropagation(); } @action private finalizeEdit(value: string, shiftDown: boolean) { + this._editing = false; if (this.props.SetValue(value, shiftDown)) { - this._editing = false; - this.props.isEditingCallback && this.props.isEditingCallback(false); + this.props.isEditingCallback?.(false); } } @@ -120,11 +132,14 @@ export class EditableView extends React.Component<EditableProps> { @action setIsFocused = (value: boolean) => { + const wasFocused = this._editing; this._editing = value; + return wasFocused !== this._editing; } + _ref = React.createRef<HTMLDivElement>(); render() { - if (this._editing) { + if (this._editing && this.props.GetValue() !== undefined) { return this.props.autosuggestProps ? <Autosuggest {...this.props.autosuggestProps.autosuggestProps} @@ -149,9 +164,10 @@ export class EditableView extends React.Component<EditableProps> { style={{ display: this.props.display, fontSize: this.props.fontSize }} />; } else { - if (this.props.autosuggestProps) this.props.autosuggestProps.resetValue(); - return ( + this.props.autosuggestProps?.resetValue(); + return (this.props.contents instanceof ObjectField ? (null) : <div className={`editableView-container-editing${this.props.oneLine ? "-oneLine" : ""}`} + ref={this._ref} style={{ display: this.props.display, minHeight: "20px", height: `${this.props.height ? this.props.height : "auto"}`, maxHeight: `${this.props.maxHeight}` }} onClick={this.onClick}> <span style={{ fontStyle: this.props.fontStyle, fontSize: this.props.fontSize }}>{this.props.contents}</span> |
