Skip to content

Commit b71f343

Browse files
WIP. registerField, unregisterField and updateValue.
1 parent 2175143 commit b71f343

18 files changed

+2494
-168
lines changed

.prettierrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"trailingComma": "none",
3+
"tabWidth": 4,
4+
"semi": true,
5+
"singleQuote": false,
6+
"printWidth": 80
7+
}

package-lock.json

Lines changed: 2025 additions & 79 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,31 @@
44
"description": "",
55
"main": "dist/index.js",
66
"scripts": {
7-
"start": "npm run build:tools && cross-env NODE_ENV=development webpack-dev-server",
7+
"start": "cross-env NODE_ENV=development webpack-dev-server",
88
"build": "npm run build:tools && cross-end NODE_ENV=development webpack",
99
"build:tools": "tsc -p ./tools"
1010
},
1111
"keywords": [],
1212
"author": "ReactWay",
1313
"license": "AGPLv3",
1414
"devDependencies": {
15-
"@types/html-webpack-plugin": "3.2.0",
15+
"@reactway/webpack-builder": "^1.0.0-alpha.6",
16+
"@reactway/webpack-builder-plugin-clean": "^1.0.0-alpha.6",
17+
"@reactway/webpack-builder-plugin-html": "^1.0.0-alpha.6",
18+
"@reactway/webpack-builder-plugin-images": "^1.0.0-alpha.6",
19+
"@reactway/webpack-builder-plugin-styles": "^1.0.0-alpha.6",
20+
"@reactway/webpack-builder-plugin-typescript": "^1.0.0-alpha.6",
21+
"@reactway/webpack-builder-plugin-web-dev": "^1.0.0-alpha.6",
22+
"@reactway/webpack-builder-plugin-write-file": "^1.0.0-alpha.6",
23+
"@types/copy-webpack-plugin": "^4.4.3",
1624
"@types/node": "11.11.3",
1725
"@types/react": "16.8.8",
1826
"@types/react-dom": "16.8.2",
1927
"@types/webpack": "4.4.25",
2028
"babel-preset-react-app": "7.0.2",
29+
"copy-webpack-plugin": "^5.0.2",
2130
"cross-env": "5.2.0",
22-
"html-webpack-plugin": "3.2.0",
23-
"html-webpack-root-plugin": "0.10.0",
31+
"node-sass": "^4.11.0",
2432
"simplr-tslint": "^1.0.0-alpha.14",
2533
"tslint": "^5.14.0",
2634
"tslint-language-service": "^0.9.9",
@@ -31,6 +39,7 @@
3139
},
3240
"dependencies": {
3341
"babel-loader": "8.0.5",
42+
"immer": "^2.1.4",
3443
"react": "16.8.4",
3544
"react-dom": "16.8.4",
3645
"saga": "^4.0.0-alpha"

postcss.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
plugins: {
3+
autoprefixer: {}
4+
}
5+
};

src/app.scss

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
@import url("https://fonts.googleapis.com/css?family=Open+Sans|Source+Code+Pro");
2+
3+
html,
4+
body,
5+
#root {
6+
display: flex;
7+
flex: 1 0 auto;
8+
}
9+
10+
.forms,
11+
.store,
12+
.store-result {
13+
padding: 10px;
14+
}
15+
16+
.forms {
17+
flex: 1 0 auto;
18+
font-family: "Open Sans", sans-serif;
19+
20+
input {
21+
font-family: "Open Sans", sans-serif;
22+
}
23+
}
24+
25+
.store {
26+
flex: ą 0 auto;
27+
font-family: "Source Code Pro", monospace;
28+
font-size: 14px;
29+
}
30+
31+
.store-result {
32+
flex: 3 0 auto;
33+
font-family: "Source Code Pro", monospace;
34+
font-size: 14px;
35+
}
36+
37+
label > * {
38+
display: block;
39+
}

src/app.tsx

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React, { useState, useEffect } from "react";
2+
import ReactDOM from "react-dom";
3+
import { Test } from "./components";
4+
import { TextField } from "./components/text-field";
5+
import { GroupStore, GroupStoreMutable } from "./stores/group-store";
6+
import { GroupContext, GroupContextObject } from "./contexts/group-context";
7+
import { useForceUpdate } from "./force-update";
8+
9+
import "./reset.scss";
10+
import "./app.scss";
11+
12+
const store = new GroupStoreMutable();
13+
const App = () => {
14+
const forceUpdate = useForceUpdate();
15+
useEffect(() => {
16+
const listener = () => {
17+
forceUpdate();
18+
};
19+
forceUpdate();
20+
store.addListener(listener);
21+
return () => store.removeListener(listener);
22+
}, []);
23+
24+
const groupContext: GroupContextObject = {
25+
store: store,
26+
test: "app",
27+
groupId: "person"
28+
};
29+
30+
const [show, setShow] = useState(true);
31+
32+
return (
33+
<>
34+
<div className="forms">
35+
<GroupContext.Provider value={groupContext}>
36+
<div>
37+
<label>
38+
Imported:
39+
{show ? (
40+
<TextField
41+
name="firstName"
42+
initialValue="Test"
43+
/>
44+
) : null}
45+
</label>
46+
<button onClick={() => setShow(!show)}>
47+
{!show ? "Mount" : "Unmount"}
48+
</button>
49+
</div>
50+
</GroupContext.Provider>
51+
</div>
52+
<div className="store">
53+
<pre>
54+
{JSON.stringify(
55+
store,
56+
// tslint:disable-next-line:no-any
57+
(_, value: any) => {
58+
if (typeof value !== "function") {
59+
return value;
60+
}
61+
62+
return `${value.name}()`;
63+
},
64+
4
65+
)}
66+
</pre>
67+
</div>
68+
<div className="store-result">
69+
{JSON.stringify(store.toObject())}
70+
</div>
71+
</>
72+
);
73+
};
74+
75+
ReactDOM.render(<App />, document.getElementById("root"));

src/components/text-field.tsx

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React, { useContext, useEffect, useState } from "react";
22
import { FieldContext } from "../contexts/field-context";
3+
import { GroupContext } from "../contexts/group-context";
4+
import { useForceUpdate } from "../force-update";
35

46
export interface FieldValues {
57
defaultValue?: string;
@@ -11,29 +13,72 @@ export interface TextFieldProps extends FieldValues {
1113
name: string;
1214
}
1315

14-
const useFieldValues = (values: FieldValues) => {
15-
console.info("useFieldValues");
16-
const [defaultValue, setDefaultValue] = useState(values.defaultValue || "");
17-
let [initialValue, setInitialValue] = useState(values.initialValue);
18-
if (initialValue == null) {
19-
initialValue = defaultValue;
16+
export const SEPARATOR = ".";
17+
18+
function useFieldId(props: Pick<TextFieldProps, "name">): string {
19+
const { groupId } = useContext(GroupContext);
20+
if (groupId == null) {
21+
return props.name;
2022
}
23+
return `${groupId}${SEPARATOR}${props.name}`;
24+
}
2125

22-
const [currentValue, setCurrentValue] = useState(initialValue);
26+
function useRegisterField(fieldId: string, props: TextFieldProps) {
27+
useEffect(() => {
28+
const { store } = useContext(GroupContext);
2329

24-
return { currentValue, setCurrentValue };
25-
};
30+
let { defaultValue, initialValue } = props;
31+
if (defaultValue == null) {
32+
defaultValue = "";
33+
}
34+
35+
if (initialValue == null) {
36+
initialValue = defaultValue;
37+
}
38+
39+
store.registerField(fieldId, props.name, defaultValue, initialValue);
40+
}, []);
41+
}
2642

2743
export const TextField = (props: TextFieldProps) => {
28-
const { currentValue, setCurrentValue } = useFieldValues({
29-
defaultValue: props.defaultValue,
30-
initialValue: props.initialValue,
31-
currentValue: props.currentValue,
32-
});
44+
const { store } = useContext(GroupContext);
45+
const [currentValue, setCurrentValue] = useState("");
46+
47+
const fieldId = useFieldId(props);
48+
49+
useEffect(() => {
50+
let { defaultValue, initialValue } = props;
51+
52+
if (defaultValue == null) {
53+
defaultValue = "";
54+
}
55+
56+
if (initialValue == null) {
57+
initialValue = defaultValue;
58+
}
59+
60+
store.registerField(fieldId, props.name, defaultValue, initialValue);
61+
62+
const updateValue = () => {
63+
const field = store.getField(fieldId);
64+
if (field == null) {
65+
return;
66+
}
67+
setCurrentValue(field.currentValue);
68+
};
69+
updateValue();
70+
71+
store.addListener(updateValue);
72+
73+
return () => {
74+
store.removeListener(updateValue);
75+
store.unregisterField(fieldId);
76+
};
77+
}, []);
3378

3479
const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
35-
// store.setCurrentValue(event.target.value);
36-
setCurrentValue(event.target.value);
80+
const value = event.target.value;
81+
store.updateValue(fieldId, value);
3782
};
3883

3984
const onFocus = (event: React.FocusEvent<HTMLInputElement>) => {

src/contexts/group-context.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { GroupStore } from "../stores/group-store";
2+
import { createContext } from "react";
3+
4+
export interface GroupContextObject {
5+
store: GroupStore;
6+
groupId?: string;
7+
test?: string;
8+
}
9+
10+
export const GroupContext = createContext<GroupContextObject>({
11+
store: {} as GroupStore
12+
});

src/contexts/test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { createContext } from "react";
1+
// import { createContext } from "react";
22

3-
interface TestContextDto {
4-
value: string;
5-
setValue: (value: string) => void;
6-
}
3+
// interface TestContextDto {
4+
// value: string;
5+
// setValue: (value: string) => void;
6+
// }
77

8-
export const TestContext = createContext<TestContextDto>({
9-
value: "default value",
10-
setValue: value => {},
11-
});
8+
// export const TestContext = createContext<TestContextDto>({
9+
// value: "default value",
10+
// setValue: value => {}
11+
// });

src/contracts/fields-group.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export interface FieldsGroupState {
2-
groupId: string;
3-
fields
4-
}
1+
// export interface FieldsGroupState {
2+
// groupId: string;
3+
// fields
4+
// }

0 commit comments

Comments
 (0)