Skip to content

Commit a61c4fc

Browse files
authored
Migrate from Flow to Typescript #456 (#475)
1 parent 58ed4fc commit a61c4fc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+36069
-19941
lines changed

.babelrc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
{
2-
"presets": ["@babel/preset-env", "@babel/preset-flow", "@babel/preset-react"]
2+
"presets": [
3+
"@babel/preset-env",
4+
"@babel/preset-react",
5+
"@babel/preset-typescript"
6+
],
7+
"plugins": [
8+
"@babel/proposal-class-properties",
9+
"@babel/proposal-object-rest-spread"
10+
]
311
}

.eslintignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,3 @@ example/build/
44
node_modules/
55
.snapshots/
66
*.min.js
7-
flow-libdef/

.eslintrc

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
2-
"parser": "@babel/eslint-parser",
2+
"parser": "@typescript-eslint/parser",
33
"extends": [
44
"react-app",
55
"plugin:prettier/recommended",
6-
"prettier",
7-
"plugin:flowtype/recommended"
6+
"plugin:@typescript-eslint/recommended",
7+
"prettier"
88
],
9-
"plugins": ["flowtype"],
9+
"plugins": ["@typescript-eslint"],
1010
"env": {
1111
"node": true
1212
},
@@ -28,6 +28,10 @@
2828
"react/jsx-handler-names": 0,
2929
"react/jsx-fragments": 0,
3030
"react/no-unused-prop-types": 0,
31-
"import/export": 0
32-
}
31+
"import/export": 0,
32+
"@typescript-eslint/no-empty-function": 0,
33+
"@typescript-eslint/no-explicit-any": 0,
34+
"@typescript-eslint/no-non-null-assertion": 0
35+
},
36+
"root": true
3337
}

.flowconfig

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

.github/workflows/ci.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,16 @@ jobs:
3030
node-version: 16
3131
- run: npm ci
3232
- run: npm run-s test:prettier
33-
flow:
34-
name: Flow
33+
typescript:
34+
name: Typescript
3535
runs-on: ubuntu-latest
3636
steps:
3737
- uses: actions/checkout@v3
3838
- uses: actions/setup-node@v3
3939
with:
4040
node-version: 16
4141
- run: npm ci
42-
- run: npm run-s test:flow
42+
- run: npm run-s test:ts
4343
test:
4444
name: Test
4545
runs-on: ubuntu-latest
@@ -91,7 +91,6 @@ jobs:
9191
needs:
9292
- lint
9393
- prettier
94-
- flow
9594
- test
9695
- build
9796
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
@@ -123,7 +122,6 @@ jobs:
123122
needs:
124123
- lint
125124
- prettier
126-
- flow
127125
- test
128126
- build
129127
if: github.event.action == 'published'

CONTRIBUTING.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@ For pull requests, go the the *Pull Request* tab on the same repo. Select the br
1010

1111
## Repository Structure
1212

13-
In this repository, the source code for the component library is in the `src` directory. Building the repository creates a new folder `dist`, hidden through `.gitignore`, that compiles out the [Flow type annotations](https://flow.org/en/docs/types/) and [JSX](https://reactjs.org/docs/introducing-jsx.html). This is necessary to publish the code onto NPM so that other developers can use the code in their own apps, agnostic to their developer environments.
13+
In this repository, the source code for the component library is in the `src` directory. Building the repository creates a new folder `dist`, hidden through `.gitignore`, that compiles out the [Typescript type annotations](https://www.typescriptlang.org/) and [JSX](https://reactjs.org/docs/introducing-jsx.html). This is necessary to publish the code onto NPM so that other developers can use the code in their own apps, agnostic to their developer environments.
1414

1515
The example app being run on the [GitHub Pages site](https://ginkgobioworks.github.io/react-json-schema-form-builder/), meanwhile, has its code stored in the `example` directory. It relies on an additional set of dependencies, which are stored in the `devDependencies` within the `package.json` file.
1616

17-
Library definitions for [Flow type annotations](https://flow.org/en/docs/types/) are stored in `flow-libdef`, where the file structure under the `flow-typed` [best practices](https://github.com/flow-typed/flow-typed/blob/master/CONTRIBUTING.md) are followed. If any of the types in `src/formBuilder/types.js` are changed, or if the properties of the `FormBuilder` or `PredefinedGallery` are altered, then these `flow-typed` library definitions as well as the definitions in the actual `flow-typed` [repository](https://github.com/flow-typed/flow-typed) should also be changed. These library definitions are updated manually, and are currently set for major version 1 of the Form Builder. To update to library definition in the `flow-typed` repository a PR must be made on the [flow-typed repository](https://github.com/flow-typed/flow-typed).
17+
[Type declarations](https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html) are also output to the `dist` folder for both the component library and the example site. If any of the types in `src/formBuilder/types.js` are changed, or if the properties of the `FormBuilder` or `PredefinedGallery` are altered, then these declaration files will be changed on the next build.
1818

1919
## Testing
2020

2121
The `src` directory also contains testing files written for the [jest](https://jestjs.io/en/) test harness. The tests use [Enzyme](https://github.com/enzymejs/enzyme) for component and DOM manipulation and traversal. These tests are run in the CI/CD pipeline, and must pass before a branch can be merged into the 'main' branch. Changes may be needed to the test harness to accommodate new features or fixes.
2222

23-
The CI/CD pipeline also runs `prettier`, `eslint`, and `flow` checks which must pass before a branch can be merged into 'main'. You can run `npm run prettier` to auto-format code to pass `prettier` standards, and `npm test` to run all of these tests to ensure that they will pass in the CI/CD pipeline.
23+
The CI/CD pipeline also runs `prettier`, `eslint` and `tsc` checks which must pass before a branch can be merged into 'main'. You can run `npm run prettier` to auto-format code to pass `prettier` standards, and `npm test` to run all of these tests to ensure that they will pass in the CI/CD pipeline.
2424

2525
Test coverage is [tracked in coveralls.io](https://coveralls.io/github/ginkgobioworks/react-json-schema-form-builder) to make sure that test coverage is maintained or increased as time goes on.
2626

docs/Mods.md

Lines changed: 114 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -4,78 +4,77 @@ Mods provide for the customization of the Form Builder component, such as the de
44

55
## Type Definition
66

7-
Flow type definitions are available via [flow-typed](https://github.com/flow-typed/flow-typed).
7+
Type definitions are available via [TypeScript](https://github.com/microsoft/TypeScript).
88

99
The type definition for Mods is as follows:
1010

11-
```react
12-
declare type Mods = {|
11+
```typescript
12+
interface Mods {
1313
customFormInputs?: {
14-
[string]: FormInput,
15-
...
16-
},
17-
components?: {|
18-
add?: (properties: { [string]: any }) => void,
19-
},
20-
tooltipDescriptions?: {|
21-
add?: string,
22-
cardObjectName?: string,
23-
cardDisplayName?: string,
24-
cardDescription?: string,
25-
cardInputType?: string,
26-
cardSectionObjectName?: string,
27-
cardSectionDisplayName?: string,
28-
cardSectionDescription?: string,
29-
|},
30-
labels?: {|
31-
formNameLabel?: string,
32-
formDescriptionLabel?: string,
33-
objectNameLabel?: string,
34-
displayNameLabel?: string,
35-
descriptionLabel?: string,
36-
inputTypeLabel?: string,
37-
addElementLabel?: string,
38-
addSectionLabel?: string,
39-
|},
40-
showFormHead?: boolean,
41-
deactivatedFormInputs?: Array<string>,
14+
[key: string]: FormInputType;
15+
};
16+
components?: {
17+
add?: (properties?: {
18+
[key: string]: any;
19+
}) => ReactElement | ReactElement[] | [];
20+
};
21+
tooltipDescriptions?: {
22+
add?: string;
23+
cardObjectName?: string;
24+
cardDisplayName?: string;
25+
cardDescription?: string;
26+
cardInputType?: string;
27+
cardSectionObjectName?: string;
28+
cardSectionDisplayName?: string;
29+
cardSectionDescription?: string;
30+
};
31+
labels?: {
32+
formNameLabel?: string;
33+
formDescriptionLabel?: string;
34+
objectNameLabel?: string;
35+
displayNameLabel?: string;
36+
descriptionLabel?: string;
37+
inputTypeLabel?: string;
38+
addElementLabel?: string;
39+
addSectionLabel?: string;
40+
};
41+
showFormHead?: boolean;
42+
deactivatedFormInputs?: Array<string>;
4243
newElementDefaultDataOptions?: {
43-
title: string,
44-
type?: string,
45-
description?: string,
46-
$ref?: string,
47-
default?: string,
48-
},
49-
newElementDefaultUiSchema?: { [string]: any },
50-
|};
44+
title: string;
45+
type?: string;
46+
description?: string;
47+
$ref?: string;
48+
default?: string | number;
49+
};
50+
newElementDefaultUiSchema?: { [key: string]: any };
51+
}
5152
```
5253

5354
`tooltipDescriptions` and `labels` describe how some of the labels and tooltips in the Form Builder are to be customized. `showFormHead` is a boolean which controls whether the top section of the Form Builder, which contains inputs for the Form Name and Form Description, are show. It is set to `true` by default.
5455

55-
A single `FormInput` has a type definition as follows:
56+
A single `FormInput` has a type definition `FormInputType` as follows:
5657

57-
```react
58-
declare type FormInput = {|
59-
displayName: string,
58+
```typescript
59+
interface FormInputType {
60+
displayName: string;
6061
// given a data and ui schema, determine if the object is of this input type
61-
matchIf: Array<MatchType>,
62+
matchIf: Array<MatchType>;
6263
// allowed keys for ui:options
63-
possibleOptions?: Array<string>,
64+
possibleOptions?: Array<string>;
6465
defaultDataSchema: {
65-
[string]: any,
66-
...
67-
},
66+
[key: string]: any;
67+
};
6868
defaultUiSchema: {
69-
[string]: any,
70-
...
71-
},
69+
[key: string]: any;
70+
};
7271
// the data schema type
73-
type: DataType,
72+
type: DataType;
7473
// inputs on the preview card
75-
cardBody: React$ComponentType<CardBodyProps>,
74+
cardBody: CardComponentType;
7675
// inputs for the modal
77-
modalBody?: React$ComponentType<CardBodyProps>,
78-
|};
76+
modalBody?: CardComponentType;
77+
}
7978
```
8079

8180
The `displayName` is the full name of the desired form input. For example, **Short Answer** is the `displayName` for the `shortAnswer` form input.
@@ -90,8 +89,8 @@ The `displayName` is the full name of the desired form input. For example, **Sho
9089

9190
`type` is the Data Schema type that this input type defaults to. While a custom form input can have multiple types (would need to be defined in the `matchIf` array), this refers to the type that gets assigned immediately after a user selects this input type in the dropdown. The possible `DataType` options supported by `react-jsonschema-form` are as follows:
9291

93-
```react
94-
declare type DataType =
92+
```typescript
93+
type DataType =
9594
| 'string'
9695
| 'number'
9796
| 'boolean'
@@ -119,15 +118,15 @@ Custom input types are encoded in exactly the same way the Default input types a
119118

120119
The `matchIf` array in a `FormInput` contains a series of `MatchType` objects, which represent different possible 'scenarios' that the `FormBuilder` may encounter when parsing a set of Data and UI Schema. The `MatchType` is defined as follows:
121120

122-
```react
123-
declare type MatchType = {|
124-
types: Array<DataType>,
125-
widget?: string,
126-
field?: string,
127-
format?: string,
128-
$ref?: boolean,
129-
enum?: boolean,
130-
|};
121+
```typescript
122+
interface MatchType {
123+
types: Array<DataType>;
124+
widget?: string;
125+
field?: string;
126+
format?: string;
127+
$ref?: boolean;
128+
enum?: boolean;
129+
}
131130
```
132131

133132
`types` refers to the set of possible input types that can register in a particular scenario.
@@ -144,30 +143,60 @@ declare type MatchType = {|
144143

145144
### Component Types
146145

147-
`cardBody` and `modalBody` are components whose props have a type of `CardBodyProps`:
146+
`cardBody` and `modalBody` are components whose props have a type of `CardComponentType`:
148147

149-
```react
150-
declare export type CardBodyProps = {|
151-
parameters: Parameters,
152-
onChange: (newParams: Parameters) => void,
153-
|};
148+
```typescript
149+
type CardComponentType = FunctionComponent<{
150+
parameters: CardComponentPropsType;
151+
onChange: (newParams: CardComponentPropsType) => void;
152+
mods?: Mods;
153+
}>;
154154
```
155155

156-
`Parameters` is defined as:
157-
158-
```react
159-
declare type Parameters = {|
160-
[string]: any,
161-
name: string,
162-
path: string,
163-
definitionData: { [string]: any, ... },
164-
definitionUi: { [string]: any, ... },
165-
category: string,
166-
'ui:option': { [string]: any, ... },
167-
|};
156+
`CardComponentPropsType` is a type that describes most params passed between cards and modals.
157+
158+
```typescript
159+
interface CardComponentPropsType {
160+
name: string;
161+
required?: boolean;
162+
hideKey?: boolean;
163+
definitionData?: { [key: string]: any };
164+
definitionUi?: { [key: string]: any };
165+
neighborNames?: string[];
166+
dependents?: { children: string[]; value?: any }[];
167+
dependent?: boolean;
168+
parent?: string;
169+
'ui:options'?: { [key: string]: any };
170+
category?: string;
171+
schema?: { [key: string]: any };
172+
type?: string;
173+
'ui:column'?: string;
174+
minLength?: number;
175+
maxLength?: number;
176+
pattern?: string;
177+
'ui:autofocus'?: boolean;
178+
'ui:placeholder'?: string;
179+
minItems?: number;
180+
maxItems?: number;
181+
title?: string;
182+
$ref?: string;
183+
format?: string;
184+
'ui:autocomplete'?: string;
185+
default?: string | number | boolean;
186+
items?: { [key: string]: any };
187+
'ui:*items'?: { [key: string]: any };
188+
multipleOf?: number | null;
189+
minimum?: number | null;
190+
exclusiveMinimum?: number | null;
191+
maximum?: number | null;
192+
exclusiveMaximum?: number | null;
193+
enum?: (number | string)[];
194+
enumNames?: string[] | null;
195+
description?: string;
196+
}
168197
```
169198

170-
It can hold any number of keys pointing to specific values. One common example is `parameters.default`, which stores the default value specified by the builder for this `FormInput`.
199+
It can hold any number of keys pointing to specific values. One common example is `default`, which stores the default value specified by the builder for this `FormInput`.
171200

172201
## Tooltips and Labels
173202

0 commit comments

Comments
 (0)