Skip to content

Commit

Permalink
[refactor] simplify React component's updating with MobX
Browse files Browse the repository at this point in the history
[optimize] React component supports Form submitting
  • Loading branch information
TechQuery committed Jun 18, 2023
1 parent b135250 commit 56e0ea4
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 45 deletions.
14 changes: 10 additions & 4 deletions React/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ https://github.com/idea2app/Edkit#tools
#### Shell command

```shell
npm install react@17 react-bootstrap-editor
npm install react react-bootstrap-editor
```

#### HTML entry
Expand All @@ -28,11 +28,11 @@ npm install react@17 react-bootstrap-editor
<head>
<link
rel="stylesheet"
href="https://unpkg.com/bootstrap@5.2.3/dist/css/bootstrap.min.css"
href="https://unpkg.com/bootstrap@5.3.0/dist/css/bootstrap.min.css"
/>
<link
rel="stylesheet"
href="https://unpkg.com/bootstrap-icons@1.10.2/font/bootstrap-icons.css"
href="https://unpkg.com/bootstrap-icons@1.10.4/font/bootstrap-icons.css"
/>
</head>
```
Expand All @@ -45,7 +45,13 @@ import { Editor } from 'react-bootstrap-editor';

export class PostEdit extends PureComponent {
render() {
return <Editor defaultValue="<p>test</p>" onChange={console.log} />;
return (
<Editor
name="content"
defaultValue="<p>test</p>"
onChange={console.log}
/>
);
}
}
```
Expand Down
4 changes: 3 additions & 1 deletion React/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
"dependencies": {
"@swc/helpers": "^0.4.14",
"edkit": "^1.0.0-rc.6",
"mobx": "^5.15.7",
"mobx-react": "^6.3.1",
"web-utility": "^4.0.0"
},
"peerDependencies": {
Expand All @@ -40,7 +42,7 @@
"react-dom": "^17.0.2",
"typescript": "~5.1.3"
},
"browserslist": "> 0.5%, last 2 versions, not dead",
"browserslist": "> 0.5%, last 2 versions, not dead, IE 11",
"scripts": {
"start": "cd test/ && parcel index.html --open",
"build": "rm -rf dist/ && parcel build",
Expand Down
48 changes: 42 additions & 6 deletions React/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

85 changes: 51 additions & 34 deletions React/source/Editor.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { Tool } from 'edkit';
import { createRef, PureComponent, ClipboardEvent, DragEvent } from 'react';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import {
createRef,
InputHTMLAttributes,
PureComponent,
ClipboardEvent,
DragEvent
} from 'react';
import {
Constructor,
parseDOM,
Expand All @@ -10,52 +18,60 @@ import {

import { ImageTool, AudioTool, VideoTool, DefaultTools } from './tools';

export interface EditorProps {
tools?: { new (...args: any[]): Tool }[];
defaultValue?: string;
export interface EditorProps
extends Pick<
InputHTMLAttributes<HTMLInputElement>,
'name' | 'defaultValue'
> {
tools?: Constructor<Tool>[];
onChange?: (value: string) => any;
}

interface EditorState {
toolList: Tool[];
data: string;
}

export class Editor extends PureComponent<EditorProps, EditorState> {
@observer
export class Editor extends PureComponent<EditorProps> {
static displayName = 'Editor';

box = createRef<HTMLDivElement>();

state = {
toolList: [] as Tool[],
data: ''
};
@observable
toolList: Tool[] = [];

static getDerivedStateFromProps(
{ tools = DefaultTools, defaultValue }: EditorProps,
{ toolList, data }: EditorState
): EditorState {
return {
toolList: toolList[0]
? toolList
: tools.map(ToolButton => new ToolButton()),
data: data || defaultValue
};
}
defaultValue = this.props.defaultValue;

@observable
innerValue = this.defaultValue;

componentDidMount() {
this.bootTools();

document.addEventListener('selectionchange', this.updateTools);
}

componentDidUpdate({ tools }: Readonly<EditorProps>) {
if (tools !== this.props.tools) this.bootTools();
}

componentWillUnmount() {
document.removeEventListener('selectionchange', this.updateTools);
}

bootTools() {
const { tools = DefaultTools } = this.props;

this.toolList = tools.map(ToolButton => new ToolButton());
}

updateTools = () => {
if (this.box.current === document.activeElement)
this.setState({ toolList: [...this.state.toolList] });
this.toolList = [...this.toolList];
};

updateValue(markup: string) {
this.innerValue = markup = markup.trim();

this.props.onChange?.(markup);
}

async uploadFile(
Type:
| Constructor<ImageTool>
Expand All @@ -66,7 +82,7 @@ export class Editor extends PureComponent<EditorProps, EditorState> {
if (typeof data === 'string' && !/^(data|blob):/.test(data))
return data;

const tool = this.state.toolList.find(
const tool = this.toolList.find(
tool => tool instanceof Type
) as ImageTool;

Expand Down Expand Up @@ -136,12 +152,12 @@ export class Editor extends PureComponent<EditorProps, EditorState> {

if (URI) insertToCursor(...parseDOM(`<video src="${URI}" />`));
}
this.props.onChange?.(currentTarget.innerHTML);
this.updateValue(currentTarget.innerHTML);
};

render() {
const { toolList, data } = this.state,
{ onChange } = this.props;
const { toolList, defaultValue, innerValue } = this,
{ name } = this.props;

return (
<>
Expand All @@ -150,13 +166,14 @@ export class Editor extends PureComponent<EditorProps, EditorState> {
ref={this.box}
className="form-control h-auto"
contentEditable
dangerouslySetInnerHTML={{ __html: data }}
onPaste={this.handlePasteDrop}
onDrop={this.handlePasteDrop}
dangerouslySetInnerHTML={{ __html: defaultValue }}
onInput={({ currentTarget: { innerHTML } }) =>
onChange?.(innerHTML)
this.updateValue(innerHTML)
}
onPaste={this.handlePasteDrop}
onDrop={this.handlePasteDrop}
/>
<input type="hidden" name={name} value={innerValue} />
</>
);
}
Expand Down
1 change: 1 addition & 0 deletions React/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"moduleResolution": "Node",
"esModuleInterop": true,
"downlevelIteration": true,
"experimentalDecorators": true,
"jsx": "react-jsx",
"lib": ["ES2021", "DOM", "DOM.Iterable"],
"declaration": true,
Expand Down

0 comments on commit 56e0ea4

Please sign in to comment.