Skip to content

Releases: fabrix-framework/fabrix

@fabrix-framework/unstyled@0.1.1

04 Feb 09:06
1013057
Compare
Choose a tag to compare

Patch Changes

@fabrix-framework/graphql-config@0.4.1

04 Feb 09:06
1013057
Compare
Choose a tag to compare

Patch Changes

@fabrix-framework/fabrix@0.7.0

04 Feb 09:06
1013057
Compare
Choose a tag to compare

Minor Changes

  • #166 d433fe0 Thanks @IzumiSy! - Support constraints for nested object field in fabrixForm directive API

  • #155 b577afa Thanks @IzumiSy! - This update contains the breaking changes specifically on functions that the children prop in FabrixComponent passes down to bring more flexibility in rendering the view.

    See #168 for more about the motivation about this change.

    Input and Output

    The newly introduced functions in the children prop is getInput and getOutput.

    • getInput is a function that plays a role as a form renderer, and also an accessor of the form context and form field control. Input fields are inferred from variable definitions in the corresponding GraphQL operation.
    • getOutput is a function that works as a result renderer (the behaviour of it depends on the component registered in the component registry), and also a direct accessor of the query data. Output fields are inferred from selected fields in the corresponding GraphQL operation.

    Here is the example implementation that renders the form to get the search condition for Query operation alongside the result component like tables.

    <FabrixComponent
      query={gql`
        query getTodos($input: GetTodoInput!) {
          getTodos(input: $input) {
            edges {
              node {
                name
                priority
              }
            }
          }
        }
      `}
    >
      {({ getInput, getOutput }) => (
        <>
          {/*
           * `getInput` renders the all form fields inferred from the variables
           * The rendered view by `getInput` without render props also has the button to execute the query.
           */}
          {getInput()}
    
          {/*
           * `getOuput` renders the result of the mutation
           * This example assumes that `getTodos` is rendered as a table component.
           */}
          {getOutput("getTodos")}
        </>
      )}
    </FabrixComponent>

    The important point to mention is that getOutput and getInput work in the same way both for Query and Mutation by this update.

    data accessor

    With this update, data accessor is accessible through getOuput function, since the data is tied from the query result (output).

    <FabrixComponent
      query={gql`
        query getTodo {
          getTodo {
            name
            priority
          }
        }
      `}
    >
      {({ getOutput }) =>
        getOutput("getTodo", ({ data }) => <div>Todo name: {data.name}</div>)
      }
    </FabrixComponent>

    More customizable, layoutable form

    Here is the complex example to create an update form to show the customizability and layoutability.

    <FabrixComponent
      query={gql`
        mutation updateTodo($id: ID!, $input: CreateTodoInput!) {
          updateTodo(id: $id, input: $input) {
            id
          }
        }
      `}
    >
      {({ getInput }) =>
        /*
         * `getInput` is a function to render form view which can acess functions to build forms.
         * `Field` and `getAction` are the key functions (see their explanation below)
         */
        getInput({
          /*
           * If the form is the one to update resource, set `defaultValues` here to prefill the form fields.
           * The data structure should be matched with the variables of query/mutation.
           */
          defaultValues: {
            id: "user-id",
            input: {
              name: "John Doe"
            }
          }
        }, ({ Field, getAction }) => (
          {/*
            * `getAction` is expcted to be passed as an descructive props to `form` element.
            * It is an object that contains `onSubmit` function as a member that kicks off the query execution.
            */}
          <form {...getAction()}>
            {/*
              * `Field` is a React component that renders the form field  that autotimacally deciding
              * the corresponding component according to GraphQL type for the path specified in the `name` prop.
              *
              * `extraProps` is the prop to carry information to the form field.
              * In this example, I assume the component that is registered in the component registry
              * as the form field handles `label` to show it as a text content in the `label` element.
              *
              * The props for the `extraProps` should have more variety (e.g., `disabled`, `placeholder`, ...),
              * but I will work on adding them in other PRs later on.
              */}
            <HStack>
              <Field name="input.name" extraProps={{ label: "Task Name" }} />
              <Field name="input.priority" extraProps={{ label: "Task Priority" }} />
            </HStack>
            <Button type="submit">Add</Button>
          </form>
        ))
      }
    </FabrixComponent>

    Additionally, for more page-by-page customization for the form, getInput functions offers more functions in its render props, mostly powered by react-hook-form that fabrix internal uses.

    Field-level handler

    In the case that the field component automatially decided by GraphQL type does not fit the requirement in the form, getInput function provides the another customizable point at the field level in the form.

    getField function returns the value of UseFormRegisterReturn in react-hook-form. Users would be able to use the another input component on the spot with this.

    <FabrixComponent query={`/* ... */`}>
      {({ getInput }) =>
        getInput({}, ({ Field, getAction, getField }) => {
          <form {...getAction()}>
            <Field name="input.name" />
            <Field name="input.priority" />
            <input {...getField("input.email")} type="text" />
          </form>;
        })
      }
    </FabrixComponent>

    Form context

    The render props of getInput function also passes down formContext that is the react-hook-form context that the form rendered by getInput internally maintains.

    This helps users create the flexible form-wide funcionality as they want by lerveraging the functionality of react-hook-form like inter-field interactibity.

    import { UseFormReturn } from "react-hook-form";
    
    const Page = () => (
      <FabrixComponent query={`/* ... */`}>
        {({ getInput }) =>
          getInput({}, ({ getAction, formContext }) => {
            <form {...getAction()}>
              <WatchingField formContext={formContext} />
            </form>;
          })
        }
      </FabrixComponent>
    );
    
    const WatchingField = (props: { formContext: UseFormReturn }) => {
      /*
       * Watches the value on the form field using `watch` method in the form context of react-hook-form
       */
      const status = formContext.watch("input.priority");
    };

    Backward incompatibility

    The previous behaviour of FabrixComponent is that only the component for the result was rendered in Query and only the form for Mutation on the contrary.
    However, from this relelase, FabrixComponent will render both the form and the result of the component regardless of operation type.

    If you would like to maintain the previous behaviour, use directives to guide the query render only the specific component that you want.

    /*
     * `@fabrixForm` directive does not
     */
    <FabrixComponent
      query={gql`
        mutation updateTodo($id: ID!, $input: CreateTodoInput!) {
          updateTodo(id: $id, input: $input) @fabrixForm {
            id
          }
        }
      `}
    />

    fabrixView also works for Query operation in the same way.

Patch Changes

@fabrix-framework/chakra-ui@0.6.1

04 Feb 09:06
1013057
Compare
Choose a tag to compare

Patch Changes

@fabrix-framework/fabrix@0.6.0

27 Jan 05:00
2b69b73
Compare
Choose a tag to compare

Minor Changes

@fabrix-framework/chakra-ui@0.6.0

27 Jan 05:00
2b69b73
Compare
Choose a tag to compare

Minor Changes

Patch Changes

  • Updated dependencies [2434e76]:
    • @fabrix-framework/fabrix@0.6.0

@fabrix-framework/graphql-config@0.4.0

24 Jan 09:06
303b327
Compare
Choose a tag to compare

Minor Changes

@fabrix-framework/fabrix@0.5.0

24 Jan 09:06
303b327
Compare
Choose a tag to compare

Minor Changes

  • #144 c19ff4e Thanks @IzumiSy! - Add provenance

  • #153 7c104b0 Thanks @IzumiSy! - Add TypedDocumentNode support: now when the TypedDocumentNode query is given, data and variables are typed.

    Also, getComponent has the first argument that is typed to help users select the component associated to the query.

  • #152 d474f8c Thanks @IzumiSy! - Remove getOperation function from children props in FabrixComponent.

    Now query prop in FabrixComponent supports only a single query to get it future compatible with TypedDocumentNode.

@fabrix-framework/chakra-ui@0.5.0

24 Jan 09:06
303b327
Compare
Choose a tag to compare

Minor Changes

Patch Changes

@fabrix-framework/graphql-config@0.3.0

14 Jan 07:14
3776d73
Compare
Choose a tag to compare

Minor Changes