forked from teslamotors/informed
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
527 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import React from 'react'; | ||
|
||
const Label = ({ title }) => <label>{title}</label>; | ||
|
||
export default Label; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,74 @@ | ||
import React from 'react'; | ||
import useFormApi from '../hooks/useFormApi'; | ||
import useFormState from '../hooks/useFormState'; | ||
import FormFields from '../components/FormFields'; | ||
import { RelevantContext } from '../Context'; | ||
|
||
const Relevant = ({ when, children }) => { | ||
const Relevant = ({ when, children, relevant }) => { | ||
const formState = useFormState(); | ||
|
||
const isRelevant = when(formState); | ||
|
||
if (isRelevant && relevant) { | ||
return ( | ||
<RelevantContext.Provider value={relevant}> | ||
{children} | ||
</RelevantContext.Provider> | ||
); | ||
} | ||
|
||
if (isRelevant) { | ||
return children; | ||
} | ||
|
||
return null; | ||
}; | ||
|
||
export const RelevantFields = ({ relevant, children }) => { | ||
// Grab the form api ( we need it to get the actual field name because might be in scope ) | ||
const { getOptions } = useFormApi(); | ||
|
||
// Grap the schema | ||
const { schema } = getOptions(); | ||
|
||
// Find conditional from schema | ||
const conditional = schema.allOf.find(c => c.relevant === relevant); | ||
|
||
// Example then ( its a subschema ) | ||
// then: { | ||
// properties: { | ||
// spouse: { | ||
// type: 'string', | ||
// title: 'Spouse name', | ||
// 'ui:control': 'input' | ||
// } | ||
// } | ||
// } | ||
const subSchema = conditional.then; | ||
|
||
// Turn the if into a when function for informed | ||
// Example if condition | ||
// if: { | ||
// properties: { | ||
// married: { const: 'yes' } | ||
// }, | ||
// required: ['married'] | ||
// }, | ||
const { properties: conditions } = conditional.if; | ||
const when = ({ values }) => { | ||
// Example key "married, Example condition: "{ const: 'yes' }" | ||
return Object.keys(conditions).every(key => { | ||
const condition = conditions[key]; | ||
// values.married === 'yes' | ||
return values[key] === condition.const; | ||
}); | ||
}; | ||
|
||
return ( | ||
<Relevant when={when} relevant={relevant}> | ||
{children ? children : <FormFields schema={subSchema} />} | ||
</Relevant> | ||
); | ||
}; | ||
|
||
export default Relevant; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# Formatted Conditional Schema | ||
|
||
** Note: This is in beta and is subject to change! ** | ||
|
||
<!-- STORY --> | ||
|
||
```jsx | ||
import { Form, FormField, RelevantFields } from 'informed'; | ||
|
||
const schema = { | ||
type: 'object', | ||
required: ['name'], | ||
properties: { | ||
name: { | ||
type: 'string', | ||
title: 'First name', | ||
'ui:control': 'input' | ||
}, | ||
married: { | ||
type: 'string', | ||
title: 'Are you married?', | ||
enum: ['yes', 'no'], | ||
'ui:control': 'radio' | ||
}, | ||
ofAge: { | ||
type: 'string', | ||
title: 'Are you over 21?', | ||
enum: ['yes', 'no'], | ||
'ui:control': 'radio' | ||
} | ||
}, | ||
allOf: [ | ||
{ | ||
relevant: 'married', | ||
if: { | ||
properties: { | ||
married: { const: 'yes' } | ||
}, | ||
required: ['married'] | ||
}, | ||
then: { | ||
properties: { | ||
spouse: { | ||
type: 'string', | ||
title: 'Spouse name', | ||
'ui:control': 'input' | ||
} | ||
} | ||
} | ||
}, | ||
{ | ||
relevant: 'over21', | ||
if: { | ||
properties: { | ||
ofAge: { const: 'yes' } | ||
}, | ||
required: ['ofAge'] | ||
}, | ||
then: { | ||
properties: { | ||
age: { | ||
type: 'number', | ||
title: 'Age', | ||
'ui:control': 'input', | ||
'input:props': { | ||
type: 'number' | ||
} | ||
}, | ||
drink: { | ||
type: 'string', | ||
title: 'What do you want to drink?', | ||
'ui:control': 'input' | ||
} | ||
} | ||
} | ||
} | ||
] | ||
}; | ||
|
||
const Component = () => { | ||
return ( | ||
<Form schema={schema}> | ||
<FormField field="name" /> | ||
<label>Are you married?</label> | ||
<FormField field="married" /> | ||
<RelevantFields relevant="married"> | ||
<FormField field="spouse" /> | ||
</RelevantFields> | ||
<label>Are you over21?</label> | ||
<FormField field="ofAge" /> | ||
<RelevantFields relevant="over21"> | ||
<FormField field="age" /> | ||
<FormField field="drink" /> | ||
</RelevantFields> | ||
<button type="submit">Submit</button> | ||
<FormState /> | ||
</Form> | ||
); | ||
}; | ||
``` |
Oops, something went wrong.