Skip to content

Commit 291f61c

Browse files
author
Bradley Marques
authored
Can hide default inputs with mods (#69)
Add ability to hide default inputs with mods
1 parent 52666fc commit 291f61c

File tree

13 files changed

+325
-47
lines changed

13 files changed

+325
-47
lines changed

docs/Background.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ When a form element is dependent on another form element, it will appear with da
9393

9494
The Form Builder also supports the **definitions** property in JSON Schema Form and the resulting **$ref** tags pointing to those definitions. By default, if there are no definitiosn detected in the underlying schema, the option to choose an input type as a reference will be disabled. However, if there is at least one defined definition, then a new option in the *Input Types* dropdown will appear, allowing the Form Builder to select a form input to have a reference to an existing definition. Any changes to that definition will propagate to all form elements that have a reference to it.
9595

96-
When a card is of a reference type, many of the usual options are no longer editable - instead, they become inherited from the parent definition.
97-
9896
![reference](img/reference.png)
9997

98+
Since [this pull request](https://github.com/rjsf-team/react-jsonschema-form/pull/179), the `react-jsonschema-form` package has supported local overrides to `$ref` titles and descriptions. The Form Builder also supports this.
99+
100100
In the [usage doc](Usage.md), there is an optional additional component called the **PredefinedGallery** that allows a builder to also visually build the definitions.

docs/Mods.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ declare type Mods = {|
3333
inputTypeLabel?: string,
3434
|},
3535
showFormHead?: boolean,
36+
deactivatedFormInputs?: Array<string>,
37+
newElementDefaultDataOptions?: {
38+
title: string,
39+
type?: string,
40+
description?: string,
41+
$ref?: string,
42+
default?: string,
43+
},
3644
|};
3745
```
3846

docs/Usage.md

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ The following example is a React component that simply maintains a Form Builder
1414

1515
```react
1616
import React, { Component } from 'react';
17-
17+
1818
import {FormBuilder} from 'react-json-schema-form-builder';
19-
19+
2020
class Example extends Component {
2121
constructor(props) {
2222
super(props);
@@ -56,10 +56,10 @@ The following example uses this form preview adjacent to the Form Builder:
5656

5757
``` react
5858
import React, { Component } from 'react';
59-
59+
6060
import {FormBuilder} from 'react-json-schema-form-builder';
6161
import Form from '@rjsf/core';
62-
62+
6363
class Example extends Component {
6464
constructor(props) {
6565
super(props);
@@ -101,9 +101,9 @@ JSON Schema forms also make use of definitions, allowing a form builder to defin
101101

102102
``` react
103103
import React, { Component } from 'react';
104-
104+
105105
import {FormBuilder, PredefinedGallery} from "@ginkgo-bioworks/react-json-schema-form-builder";
106-
106+
107107
class Example extends Component {
108108
constructor(props) {
109109
super(props);
@@ -147,9 +147,9 @@ The following is an example that implements the `FormBuilder` in a React functio
147147

148148
``` react
149149
import * as React from 'react';
150-
150+
151151
import {FormBuilder, PredefinedGallery} from "@ginkgo-bioworks/react-json-schema-form-builder";
152-
152+
153153
export default function Example() {
154154
const [schema, setSchema] = React.useState('{}');
155155
const [uischema, setUiSchema] = React.useState('{}');
@@ -222,9 +222,9 @@ This can then be passed into an app using the `FormBuilder` as follows:
222222

223223
```react
224224
import React, { Component } from 'react';
225-
225+
226226
import { FormBuilder } from 'react-json-schema-form-builder';
227-
227+
228228
class Example extends Component {
229229
constructor(props) {
230230
super(props);
@@ -246,7 +246,7 @@ class Example extends Component {
246246
}}
247247
mods={
248248
{
249-
optionalFormInputs: customFormInputs
249+
customFormInputs
250250
}
251251
}
252252
/>
@@ -255,26 +255,46 @@ class Example extends Component {
255255
}
256256
```
257257

258-
The full type definition of the mods that can be passed into the `FormBuilder` and `PredefinedGallery` (they must be passed into both!) are as follows:
258+
The `customFormInputs` define the logic that translates abstract "Input Types" into raw data schema and UI schema. For more information about these Custon Form Inputs, see the page [here](Mods.md).
259259

260-
``` react
261-
export type Mods = {
262-
customFormInputs?: {
263-
[string]: FormInput
264-
},
265-
tooltipDescriptions?: {
266-
add?: string,
267-
cardObjectName?: string,
268-
cardDisplayName?: string,
269-
cardDescription?: string,
270-
cardInputType?: string
271-
}
260+
The `tooltipDescriptions` allows an implementation of the `FormBuilder` that changes the tooltip descriptions that appear on hover over certain areas of the tool. The `add` popup appears when hovering over the plus buttons, the `cardObjectName` is the name of the back end name that appears in every card object input, the `cardDisplayName` allows rewriting the description of the display name tooltip, the `cardDescription` option allows overwriting the tooltip for the description, and the `cardInputType` allows setting a custom tooltip for the Input Type dropdown.
261+
262+
### Deactivated Form Inputs
263+
264+
It is also possible to deactivate (hide) certain Input Types by setting the `deactivatedFormInputs` property on mods. For example, to hide the `time` and `checkbox` form inputs that are usually included by default, you may set the mods to:
265+
266+
```react
267+
mods = {
268+
deactivatedFormInputs: ['time', 'checkbox'],
272269
}
273270
```
274271

275-
The `customFormInputs` define the logic that translates abstract "Input Types" into raw data schema and UI schema. For more information about these Custon Form Inputs, see the page [here](Mods.md).
272+
This will hide these Input Types on the `FormBuilder` component.
276273

277-
The `tooltipDescriptions` allows an implementation of the `FormBuilder` that changes the tooltip descriptions that appear on hover over certain areas of the tool. The `add` popup appears when hovering over the plus buttons, the `cardObjectName` is the name of the back end name that appears in every card object input, the `cardDisplayName` allows rewriting the description of the display name tooltip, the `cardDescription` option allows overwriting the tooltip for the description, and the `cardInputType` allows setting a custom tooltip for the Input Type dropdown.
274+
### Default New Form Element (newElementDefaultDataOptions)
275+
276+
By default, when adding a new form element, the dataOptions are set to:
277+
278+
```react
279+
{
280+
title: `New Input ${i}`,
281+
type: 'string',
282+
default: '',
283+
}
284+
```
285+
286+
This means that by default, a new form element has the "Short answer" input type. If you wish to override this (for example, if the "Short answer" input is deactivated), you can do so by using the `newElementDefaultDataOptions` mod. For example, setting the mods to the following:
287+
288+
```react
289+
mods = {
290+
newElementDefaultDataOptions: {
291+
'$ref': '#/definitions/firstNames',
292+
title: 'Field',
293+
},
294+
};
295+
```
296+
297+
will default new form elements to a "Reference" type to some definition "firstNames" defined in the schema.
278298

279299
### Styling
280300

example/src/JsonSchemaFormSuite.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class JsonSchemaFormEditor extends React.Component<Props, State> {
149149
<FormBuilder
150150
schema={this.props.schema}
151151
uischema={this.props.uischema}
152+
mods={this.props.mods}
152153
onChange={(newSchema: string, newUiSchema: string) => {
153154
if (this.props.onChange)
154155
this.props.onChange(newSchema, newUiSchema);
@@ -317,6 +318,7 @@ class JsonSchemaFormEditor extends React.Component<Props, State> {
317318
<PredefinedGallery
318319
schema={this.props.schema}
319320
uischema={this.props.uischema}
321+
mods={{}}
320322
onChange={(newSchema: string, newUiSchema: string) => {
321323
if (this.props.onChange)
322324
this.props.onChange(newSchema, newUiSchema);

example/src/PlaygroundContainer.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,16 @@ const useStyles = createUseStyles({
1818
},
1919
});
2020

21+
// Can be used to set initial schemas and mods (useful for development)
22+
const initialJsonSchema = {};
23+
const initialUiSchema = {};
24+
const mods = {};
25+
2126
export default function PlaygroundContainer({ title }: { title: string }) {
22-
const [schema, setSchema] = React.useState('{}');
23-
const [uischema, setUischema] = React.useState('{}');
27+
const [schema, setSchema] = React.useState(JSON.stringify(initialJsonSchema));
28+
const [uischema, setUischema] = React.useState(
29+
JSON.stringify(initialUiSchema),
30+
);
2431
const classes = useStyles();
2532
return (
2633
<div className='playground'>
@@ -48,6 +55,7 @@ export default function PlaygroundContainer({ title }: { title: string }) {
4855
lang={'json'}
4956
schema={schema}
5057
uischema={uischema}
58+
mods={mods}
5159
schemaTitle='Data Schema'
5260
uischemaTitle='UI Schema'
5361
onChange={(newSchema: string, newUiSchema: string) => {

flow-libdef/@ginkgo-bioworks/react-json-schema-form-builder_v1.x.x/flow_v0.92.x-/react-json-schema-form-builder_v1.x.x.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ declare module '@ginkgo-bioworks/react-json-schema-form-builder' {
5454
modalBody?: React$ComponentType<CardBodyProps>,
5555
|};
5656

57+
declare type DataOptions = {|
58+
title: string,
59+
type?: string,
60+
description?: string,
61+
$ref?: string,
62+
default?: string,
63+
|};
64+
5765
// optional properties that can add custom features to the form builder
5866
declare type Mods = {|
5967
customFormInputs?: {
@@ -79,6 +87,8 @@ declare module '@ginkgo-bioworks/react-json-schema-form-builder' {
7987
inputTypeLabel?: string,
8088
|},
8189
showFormHead?: boolean,
90+
deactivatedFormInputs?: Array<string>,
91+
newElementDefaultDataOptions?: DataOptions,
8292
|};
8393

8494
declare type FormBuilderProps = {|

src/formBuilder/CardGallery.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export default function CardGallery({
8181
addCardObj({
8282
schema: { properties: definitionSchema },
8383
uischema: definitionUiSchema,
84+
mods: mods,
8485
onChange: (newDefinitions, newDefinitionUis) => {
8586
const oldUi = newDefinitionUis;
8687
const newUi = {};

src/formBuilder/CardGeneralParameterInputs.js

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
defaultDataProps,
1010
categoryToNameMap,
1111
categoryType,
12+
subtractArray,
1213
} from './utils';
1314
import type { Parameters, Mods, FormInput } from './types';
1415
import Tooltip from './Tooltip';
@@ -43,6 +44,22 @@ export default function CardGeneralParameterInputs({
4344
const descriptionLabel = fetchLabel('descriptionLabel', 'Description');
4445
const inputTypeLabel = fetchLabel('inputTypeLabel', 'Input Type');
4546

47+
const availableInputTypes = () => {
48+
const definitionsInSchema =
49+
parameters.definitionData &&
50+
Object.keys(parameters.definitionData).length !== 0;
51+
52+
// Hide the "Reference" option if there are no definitions in the schema
53+
let inputKeys = Object.keys(categoryMap).filter(
54+
(key) => key !== 'ref' || definitionsInSchema,
55+
);
56+
57+
// Exclude hidden inputs based on mods
58+
if (mods) inputKeys = subtractArray(inputKeys, mods.deactivatedFormInputs);
59+
60+
return inputKeys.map((key) => ({ value: key, label: categoryMap[key] }));
61+
};
62+
4663
return (
4764
<div>
4865
<div className='card-entry'>
@@ -158,17 +175,7 @@ export default function CardGeneralParameterInputs({
158175
label: categoryMap[parameters.category],
159176
}}
160177
placeholder='Category'
161-
options={Object.keys(categoryMap)
162-
.filter(
163-
(key) =>
164-
key !== 'ref' ||
165-
(parameters.definitionData &&
166-
Object.keys(parameters.definitionData).length !== 0),
167-
)
168-
.map((key) => ({
169-
value: key,
170-
label: categoryMap[key],
171-
}))}
178+
options={availableInputTypes()}
172179
onChange={(val: any) => {
173180
// figure out the new 'type'
174181
const newCategory = val.value;

src/formBuilder/FormBuilder.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ export default function FormBuilder({
385385
addCardObj({
386386
schema: schemaData,
387387
uischema: uiSchemaData,
388+
mods: mods,
388389
onChange: (newSchema, newUiSchema) =>
389390
onChange(stringify(newSchema), stringify(newUiSchema)),
390391
definitionData: schemaData.definitions,

src/formBuilder/Section.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ export default function Section({
421421
addCardObj({
422422
schema,
423423
uischema,
424+
mods,
424425
onChange,
425426
definitionData,
426427
definitionUi,

0 commit comments

Comments
 (0)