Add EditableText component

Added editable text component and use component for project name edit.
This commit is contained in:
IA 2020-01-05 17:31:13 +00:00 committed by Israel Adura
parent 67e499321c
commit 24c99c3e1c
4 changed files with 121 additions and 4 deletions

View file

@ -0,0 +1,74 @@
import React, { createRef, Fragment, Component } from "react";
type InputState = {
initialValue: string;
value: string;
edit: boolean;
};
type Props = {
value: string;
updateName: (name: string) => void;
};
export default class EditableInput extends Component<Props, InputState> {
constructor(props: Props) {
super(props);
const { value } = props;
this.state = {
initialValue: value,
value,
edit: false
};
}
private inputRef = createRef<HTMLInputElement>();
private handleEdit(e: React.ChangeEvent<HTMLInputElement>) {
this.setState({ value: e.target.value });
}
private handleBlur() {
const { value, initialValue } = this.state;
if (!value) {
this.setState({ value: initialValue, edit: false });
return;
}
this.props.updateName(value);
this.setState({ edit: false, initialValue: value });
}
private focusInput() {
const input = this.inputRef.current;
if (input) {
input.focus();
}
this.setState({ edit: true });
}
public render() {
const { value, edit } = this.state;
return (
<Fragment>
{edit ? (
<input
className="project-name-input"
name="name"
maxLength={25}
value={value}
onChange={e => this.handleEdit(e)}
onBlur={() => this.handleBlur()}
ref={this.inputRef}
/>
) : (
<span onClick={() => this.focusInput()} className="project-name">
{value}
</span>
)}
</Fragment>
);
}
}

View file

@ -6,6 +6,8 @@ import { SketchPicker } from "react-color";
import { moveOneLeft, moveAllLeft, moveOneRight, moveAllRight } from "./zindex";
import { roundRect } from "./roundRect";
import EditableText from "./components/EditableText";
import { getDateTime } from "./utils";
import "./styles.scss";
@ -573,17 +575,17 @@ function loadFromJSON() {
function exportAsPNG({
exportBackground,
exportPadding = 10,
viewBackgroundColor
viewBackgroundColor,
name
}: {
exportBackground: boolean;
exportPadding?: number;
viewBackgroundColor: string;
scrollX: number;
scrollY: number;
name: string;
}) {
if (!elements.length) return window.alert("Cannot export empty canvas.");
const fileName = prompt("Enter name of project");
// calculate smallest area to fit the contents in
let subCanvasX1 = Infinity;
@ -873,6 +875,7 @@ type AppState = {
viewBackgroundColor: string;
scrollX: number;
scrollY: number;
name: string;
};
const KEYS = {
@ -988,6 +991,11 @@ class App extends React.Component<{}, AppState> {
if (savedState) {
this.setState(savedState);
}
if (!(savedState && savedState.name)) {
const name = `excalidraw-${getDateTime()}`;
this.setState({ name });
}
}
public componentWillUnmount() {
@ -1005,7 +1013,8 @@ class App extends React.Component<{}, AppState> {
currentItemBackgroundColor: "#ffffff",
viewBackgroundColor: "#ffffff",
scrollX: 0,
scrollY: 0
scrollY: 0,
name: ""
};
private onResize = () => {
@ -1130,10 +1139,16 @@ class App extends React.Component<{}, AppState> {
private removeWheelEventListener: (() => void) | undefined;
private updateProjectName(name: string): void {
this.setState({ name });
}
public render() {
const canvasWidth = window.innerWidth - CANVAS_WINDOW_OFFSET_LEFT;
const canvasHeight = window.innerHeight - CANVAS_WINDOW_OFFSET_TOP;
const { name } = this.state;
return (
<div
className="container"
@ -1178,6 +1193,14 @@ class App extends React.Component<{}, AppState> {
}}
>
<div className="sidePanel">
<h4>Project name</h4>
{name && (
<EditableText
value={name}
updateName={(name: string) => this.updateProjectName(name)}
/>
)}
<h4>Shapes</h4>
<div className="panelTools">
{SHAPES.map(({ value, icon }) => (

View file

@ -173,3 +173,12 @@ button {
padding: 2px 4px;
border: 1px solid #ddd;
}
.project-name {
font-size: 14px;
cursor: pointer;
}
.project-name-input {
width: 200px;
font: inherit;
}

11
src/utils/index.ts Normal file
View file

@ -0,0 +1,11 @@
export const getDateTime = (): string => {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hr = date.getHours();
const min = date.getMinutes();
const secs = date.getSeconds();
return `${year}${month}${day}${hr}${min}${secs}`;
};