Apollo Form Library
import gql from 'graphql-tag';
const fragment = gql`
fragment client on ClientData {
name
age
}
`;
import gql from 'graphql-tag';
const inputQuery = gql`
${fragment}
{
sampleForm @client {
...client
}
}
`;
Error queries are namespaced like so: {FORM_NAME}Errors
import gql from 'graphql-tag';
const errorsQuery = gql`
${fragment}
{
sampleFormErrors @client {
...client
}
}
`;
import { combineValidators, composeValidators, isAlphabetic, isNumeric, isRequired } from 'revalidate';
const validator = combineValidators({
name: composeValidators(isRequired, isAlphabetic)('Name'),
age: composeValidators(isRequired, isNumeric)('Age'),
});
const initialData = {
name: null,
age: null,
}
const sampleMutation = gql`
mutation($inputData: PersonInput) {
createSample(inputData: $inputData)
}
`;
import { createForm, FormSchema, FormProvider } from 'apollo-forms';
const Form = createForm({ mutation: sampleMutation, inputQuery, errorsQuery })(FormProvider);
export default function Root() {
return (
<Form
initialData={initialData}
formName="sampleForm"
>
</Form>
);
}
import { withInput } from 'apollo-forms';
const Input = withInput('input');
export default function Root() {
return (
<Form
formName="sampleForm"
>
<Input
field="name"
/>
<Input
type="number"
field="age"
/>
</Form>
);
}
export default function Root() {
return (
<Form
formName="sampleForm"
>
<Input
field="name"
/>
<Input
type="number"
field="age"
/>
<button type="submit">Submit</button>
</Form>
);
}
As long as a FormProvider
gets initialData
the form will hydrate the appropriate fields in the form.
There are some utils provided that may help you hydrate your Form:
import { createHydrateProvider } from 'apollo-forms';
const query = gql`
{
query sample {
sampleForm {
name
age
}
}
}
`;
const HydrateProvider = createHydrateProvider({
query,
queryKey: 'sampleForm',
});
export default function Root() {
return (
<HydrateProvider>
{(data) => {
return (
<Form
initialData={data}
formName="sampleForm"
>
<Input field="name" />
<Input type="number" field="age" />
<SubmitControls />
</Form>
);
}}
</HydrateProvider>
);
}
import { withHandlers } from 'recompose';
function Root({ renderForm }) {
return (
<HydrateProvider>
{renderForm}
</HydrateProvider>
);
}
export default withHandlers({
renderForm: () => {
return (data) => {
return (
<Form
initialData={data}
formName="sampleForm"
>
<Input field="name" />
<Input type="number" field="age" />
<SubmitControls />
</Form>
);
}
}
})(Root);
Under the hood, apollo-forms
creates a ApolloClient
instance with apollo-linked-state
. The form gets its own
state graph to work with keyed off formName
. When onChange
is called from the Input
components, both internal react state is updated as well as the local ApolloClient
cache.
Validation through the revalidate
library is run when the inputs have values and validation messages are passed as props to the base component.
onSubmit
, the FormProvider
component takes the form state and passes it to the supplied mutation
in the form. By default the variables are formatted like this: { inputData: FORM_STATE }
. To customize your mutation arguments, pass a transform
to the FormProvider to return the form state however you wish.