Skip to content

Commit 3e18a00

Browse files
Feature/dom (#15)
* Update 2017-04-08.md * DOM Components and their exporting updated. * Removed dist and @types from simplr-validation.
1 parent ebff871 commit 3e18a00

26 files changed

+187
-427
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,5 +252,7 @@ paket-files/
252252
*.sln.iml
253253
yarn.lock
254254

255+
packages/simplr-forms-test
256+
255257
dist
256-
@types
258+
@types

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ Development right now is being done by [SimplrJS](https://github.com/SimplrJS) t
1616

1717
### Notes
1818

19-
[2017-04-08 Initial notes](https://github.com/SimplrJS/simplr-forms/blob/master/docs/2017-04/2017-04-08.md)
19+
* [2017-04-08 Initial notes](https://github.com/SimplrJS/simplr-forms/blob/master/docs/2017-04/2017-04-08.md)
20+
* [2017-04-14 Progress update](https://github.com/SimplrJS/simplr-forms/blob/master/docs/2017-04/2017-04-14.md)

docs/2017-04/2017-04-08.md

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
## April 8 ([discuss](https://github.com/SimplrJS/simplr-forms/pull/1))
2+
3+
### Attendees
4+
5+
* [Dovydas](https://twitter.com/dovydasnav) (QuatroDev)
6+
* [Martynas](https://twitter.com/MartiogalaLT) (QuatroDev)
7+
8+
### Why do we need yet another forms library?
9+
10+
Over the past few years we worked with React, we tried **MANY** form libraries that are out there.
11+
12+
#### Problems with existing libraries
13+
14+
* There is no de-facto standard library for forms in React, like there is for routing ([react-router](https://github.com/ReactTraining/react-router))
15+
* They all have their limitations and usually big ones
16+
* Performance is usually bottlenecking as the project grows
17+
* No really flux friendly
18+
* Not friendly with TypeScript
19+
* There is not a single library that is built **in the React way**
20+
21+
Ok, so the big one is the libraries can never be consumed in a **React** way, which raises a whole bunch of other problems:
22+
* You have to learn everything from the ground up to use the library
23+
* When you write your app in a declarative react way, you have to fallback to imperative or semi-imperative way for forms
24+
* Library has to reinvent the wheel to *do things*
25+
* Lifecycle management becomes hell on earth
26+
* Race conditions appear out of the blue
27+
28+
I could go on here, but [Michael Jackson](https://github.com/mjackson) said it better [here](https://www.youtube.com/watch?v=Vur2dAFZ4GE)
29+
and the problems are more than apparent.
30+
31+
## So why do we start now?
32+
33+
Well, technically, we started almost a year ago (Jan 12, 2016) by building a `simplr-forms` v0.0.4 and used it internally.
34+
35+
v1.0.0 was also released internally on May 30, 2016.
36+
37+
v2.0.0 as well, released internally on September 7th, 2016.
38+
39+
We introduced v3.0.0-beta in Dec 7, 2016. And we made all possible mistakes during these 3 versions (hopefully).
40+
41+
We had 113 different alphas, betas, RCs and stable ones in between.
42+
43+
And more than a year later, we still don't see a proper library for forms out there. This is why we are putting the efforts into
44+
spec'ing, architecting and building the library out there in public.
45+
46+
### What's the plan?
47+
48+
For a few days already we were talking and ploting the architecture, raising and solving problems on the whiteboard.
49+
At the moment we are ready to to start coding, but first - we'll try to write out ideas.
50+
51+
### Integrity with flux
52+
53+
During 3 versions, we tried different approaches, to have forms:
54+
- Live on their own
55+
- Live in the flux lifecycle
56+
- Something in between the first two
57+
58+
At the moment, we think the best way to have responsive forms (as of fast response time), we have to make the library live on its own.
59+
60+
And for architectural integration (flux/redux/mobx/etc), we hope to make initial flux and redux versions ourselves and then get some help from community as the library becomes **the best forms library out there**.
61+
62+
## Let's get to the point
63+
64+
### Lifecycle
65+
66+
For forms lifecycle, we will be using somewhat flux-ish architecture of actions and at first and it's gonna be quick-and-dirty switches and immutable objects. Later on, we will incorporate [simplr-flux package](https://github.com/SimplrJS/simplr-flux), as we will open-source it soon.
67+
68+
### Principles
69+
70+
1. The source code is written in TypeScript.
71+
2. Architecture is compile-time checked as much as possible.
72+
3. Declarative API first. An imperative API is not going to be first-class citizen.
73+
4. Simplicity in developer-facing API, performance in the backend.
74+
5. Have React Fiber in mind.
75+
6. Validation is first-class citizen.
76+
77+
### Code samples
78+
79+
To get the idea how JSX looks:
80+
81+
```tsx
82+
<Form onSubmit={this.onFormSubmit}>
83+
<Text name="FirstName">
84+
<Validators.MinLength value={3} errorMessage="First name has to be at least ${value} long."/>
85+
<Validators.MaxLength value={10} errorMessage="First name has to be at most ${value} long."/>
86+
</Text>
87+
<Submit>Submit</Submit>
88+
</Form>
89+
```
90+
91+
And the rendered DOM:
92+
```html
93+
<form>
94+
<input type="text" name="FirstName" />
95+
<button type="submit">Submit</button>
96+
</form>
97+
```
98+
99+
As you can see, no wrappers, no custom elements, divs, spans or anything, just a clean form with inputs and buttons.
100+
101+
Having clean output really helps with styling, because you see the same structure in JSX, except for `simplr-forms` specific validators inside text element.
102+
103+
For now, we have to render validators in the virtual DOM, because `input` elements cannot have childrens (at least some of them).
104+
105+
That will change with React Fiber coming in as it will have the ability to return array of elements in the `render` function. With that change, we will be able to render validators alongside, but, of course, that is yet to come.
106+
107+
### Validators
108+
109+
A really important functionality while using forms is data validation.
110+
111+
And the main pains behind validation are:
112+
* Reusability of validators code
113+
* An easy way of defining the requirements of your data
114+
115+
Imperative API is probably the worst solution for this, which leaves a nice spot for declarative one. Unfortunately, there is no way of doing that today, but...
116+
117+
We have another package `simplr-validation`, which was released internally on Feb 15, 2016 and did not change much since. We had 19 versions of the package and most of them were adding functionality, not changing the core principles. Which means the package is done right from the start.
118+
119+
#### More interesting use case
120+
121+
Want to have your mind blown?
122+
123+
Suppose you need to validate your username to be:
124+
* 4 to 128 symbols of length
125+
* Unique in your system, which is a call to your server
126+
127+
Take a second to think how would you approach it today. Then look at this:
128+
129+
```tsx
130+
import { MinLength, MaxLength, DebouncerValidator } from "simplr-forms-core/validators";
131+
132+
<Text name="username">
133+
<MinLength value={4} errorMessage="Min length is ${value}!" />
134+
<MaxLength value={128} errorMessage="Max length is ${value}!" />
135+
/*
136+
Waits for 3 seconds before executing to the next validator.
137+
If the value changes before debouncer expires,
138+
the validation will be stopped and rejected as an error.
139+
Also, form store will ignore validation changes until the value is the newest,
140+
therefore store will update validation result to Valid or Invalid
141+
only after ALL needed validators are executed.
142+
*/
143+
<DebouncerValidator value={3000} />
144+
<CostyValidatorToTheServer />
145+
</Text>
146+
```
147+
148+
What you see here is a declarative way to check all of the requirements *AND* do it in an optimal manner, which is debouncing for some time until the user stops typing the username.
149+
150+
Mind blown? :tada: I hoped so. :clap:
151+
152+
### Coding time!
153+
154+
There are more things to cover here, but we are already hyped-up to get our hands dirty and start coding.
155+
156+
------------
157+
158+
The feedback and questions are more than welcome!
159+
160+
------------
161+
162+
Please feel free to discuss these notes in the [corresponding pull request](https://github.com/SimplrJS/simplr-forms/pull/1).
163+

packages/simplr-forms-dom/src/abstractions/base-dom-field.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ export interface BaseDomFieldState extends CoreAbstractions.BaseFieldState {
77

88
export abstract class BaseDomField<TProps extends CoreContracts.FieldProps, TState extends BaseDomFieldState>
99
extends CoreAbstractions.BaseField<TProps, TState> {
10-
protected RawInitialValue: any;
11-
protected DefaultValue: any;
12-
1310
public abstract renderField(): JSX.Element | null;
1411

1512
public render() {
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,2 @@
1-
import * as Form from "./form";
2-
import * as Text from "./text";
3-
4-
export {
5-
Form,
6-
Text
7-
};
1+
export * from "./form";
2+
export * from "./text";

packages/simplr-forms-dom/src/components/text.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,12 @@ import { OnChangeCallback } from "../contracts/field";
1212
* @extends {CoreContracts.FieldProps}
1313
* @extends {React.HTMLProps<HTMLInputElement>}
1414
*/
15-
export interface Props extends CoreContracts.FieldProps, React.HTMLProps<HTMLInputElement> {
15+
export interface TextProps extends CoreContracts.FieldProps, React.HTMLProps<HTMLInputElement> {
1616
name: string;
1717
onFocus?: React.EventHandler<React.FocusEvent<HTMLInputElement>>;
1818
onBlur?: React.EventHandler<React.FocusEvent<HTMLInputElement>>;
19-
ref?: any;
20-
}
21-
22-
export interface TextProps extends Props {
2319
onChange?: OnChangeCallback<HTMLInputElement>;
20+
ref?: any;
2421
}
2522

2623
export class Text extends BaseDomField<TextProps, BaseDomFieldState> {
@@ -40,6 +37,21 @@ export class Text extends BaseDomField<TextProps, BaseDomFieldState> {
4037
// TODO: FormProps.OnFieldChange
4138
}
4239

40+
41+
protected get RawInitialValue(): CoreContracts.FieldValue {
42+
if (this.props != null && this.props.value != null) {
43+
return this.props.value;
44+
}
45+
return "";
46+
}
47+
48+
protected get DefaultValue(): CoreContracts.FieldValue {
49+
if (this.props != null && this.props.defaultValue != null) {
50+
return this.props.defaultValue;
51+
}
52+
return "";
53+
}
54+
4355
protected get IsDisabled() {
4456
let disabled: boolean | undefined;
4557

packages/simplr-validation/@types/abstractions/base-validator.d.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

packages/simplr-validation/@types/abstractions/index.d.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/simplr-validation/@types/contracts.d.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/simplr-validation/@types/index.d.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)