Next Atomic

image

Introduction

Next Atomic is a high end app starter kit to quickly create powerful apps based on GraphQL and React

Why high end ?

Here some features:

Install

Next atomic is super easy to install, just fork/clone/dowload this repo and launch yarn to install packages.

Next Atomic use yarn for security and package versioning features

Main Strategy

The main goal of Next Atomic is to isolate as much as possible each component, and associate a GraphQL Fragment to each component then the N+1 component can use children’s GraphQL Fragment inside it’s own index.graphql. With this strategy you can easly design and create components without carrying about data availability. This is a Data Driven UI.

Development Workflow

To take full advantage of Next Atomic i recommend to use the following development workflow:

Storybook development (to develop)

To start the story book you need to launch yarn storybook A mocked server with graphql playground is available at http://localhost:1337/playground or http://localhost:1338/playground You can find global mocks mocks in graphql/mock/mocks.ts

Next development (to test app, fix last bugs)

Start the next dev app with yarn dev, the next app will try to connect to the GraphQL server at http://localhost:1337/playground. A mocked server with graphql playground is available at http://localhost:1337/playground or http://localhost:1338/playground You can test your app with a true GraphQL Server by starting the Next Atomic GraphQL Server: https://github.com/Moumouls/next-atomic-gql-server

Fetch GraphQL Schema from remote

Fetch the schema of the Next Atomic Server or other GraphQL Server from yarn refresh-schema

Stories

Without data or props

Here a quick example of the logout atom

// stories.tsx
import React from 'react'
import { LogOutButton } from './index'

export default {
	component: LogOutButton,
	title: 'Atoms/LogOutButton',
}

export const Base = () => <LogOutButton />

With data using GQLProvider

Here a quick example of the viewer chip molecule

// stories.tsx
import React from 'react'
import {
	GQLLoadingProvider,
	GQLProvider,
	GQLErrorProvider,
} from '@graphql-mock'
import { ViewerChip } from './index'

export default {
	component: ViewerChip,
	title: 'Molecules/ViewerChip',
}

// A default GQLProvider wrapper exist on each story
export const Base = () => <ViewerChip />

// Every graphql request will stay into a loading state
export const Loading = () => (
	<GQLLoadingProvider>
		<ViewerChip />
	</GQLLoadingProvider>
)

// Every graphql request will raise an error
export const NoViewer = () => (
	<GQLErrorProvider>
		<ViewerChip />
	</GQLErrorProvider>
)

// Here we define a special GraphQL mock resolver
// to complete the use case
const customResolvers = {
	User: () => ({
		picture: null,
	}),
}

export const WithoutPicture = () => (
	<GQLProvider customResolvers={customResolvers}>
		<ViewerChip />
	</GQLProvider>
)

With fine grained GraphQL error/response

Here a quick example of the personal informations molecule that display a form

// stories.tsx
import React from 'react'
import { GQLProvider } from '@graphql-mock'
import { PersonalInformations } from './index'

export default {
	component: PersonalInformations,
	title: 'Molecules/PersonalInformations',
}

const customResolvers = {
	Mutation: () => ({
		updateUser: () => {
			// eslint-disable-next-line
			throw 'error'
		},
	}),
}

export const Base = () => <PersonalInformations />
export const Error = () => (
	<GQLProvider customResolvers={customResolvers}>
		<PersonalInformations />
	</GQLProvider>
)

GraphQL Codegen

GraphQL Codegen watch and compile each file in ./components folder that’s end with .graphql Each GraphQL stuff (Mutation,Query,Fragment, etc…) that you define inside .graphql files will be transformed into Typescript and merged into a special module @graphql.

For example:

# index.graphql
query viewer {
	viewer {
		user {
			...Viewer
		}
	}
}
fragment Viewer on User {
	id
	firstname
	lastname
}

Will generate a useViewerQuery typed GraphQL apollo hook and a ViewerFragment type; then you can import generated query/mutation/type like:

import { useViewerQuery } from '@graphql'

image