Giter VIP home page Giter VIP logo

gorg-ui-v3's Introduction

๐Ÿฆ‹ Gorg UI v3 CircleCI codecov Netlify Status Storybook

This repo contains the base architecture of the project, while further development was moved to a private monorepo (for now). You might also like to checkout the first ever version of the project for prior updates.

โš™๏ธ Installation

  1. Create the application:

    $ npx create-react-app gorg-ui-v3 --typescript
  2. Add Storybook:

    $ cd gorg-ui-v3 && npx -p @storybook/cli sb init
  3. Quickly check that all environments are working properly:

    # Run the test runner (Jest) in a terminal:
    $ yarn test
    
    # Start the component explorer on port 9009:
    $ yarn run storybook
    
    # Run the frontend app proper on port 3000:
    $ yarn start
  4. Automated Testing via StoryShots:

    Install the package and its types:

    $ yarn add -D @storybook/addon-storyshots @types/storybook__addon-storyshots

    Create a src/storybook.test.js file and put:

    import initStoryshots from "@storybook/addon-storyshots";
    initStoryshots();
  5. Configure the App for Jest (Component Story Format (CSF) version):

    Configure Jest to work with Webpack's require.context():

    // .storybook/config.js
    
    import { configure } from "@storybook/react";
    
    const req = require.context("../src/components", true, /\.stories\.js$/); // <- import all the stories at once
    configure(req, module);

    The above works only during the build with Webpack, polyfill this to work with Jest by first installing Macro (for CRA v2+):

    $ yarn add -D require-context.macro

    In the same file, import the Macro and run it in place of require.context:

    import requireContext from "require-context.macro";
    
    // const req = require.context('../src/components', true, /\.stories\.js$/); <-- replaced
    const req = requireContext("../src/components", true, /\.stories\.js$/);

    StoryShots is dependent on react-test-renderer:

    $ yarn add -D react-test-renderer
  6. Setting Up Addons - Knobs

    Install Addon Knobs:

    $ yarn add @storybook/addon-knobs

    Register Knobs in your .storybook/addons.js file:

    import "@storybook/addon-actions/register";
    import "@storybook/addon-knobs/register";
    import "@storybook/addon-links/register";

    Usage:

    import { withKnobs, text } from "@storybook/addon-knobs/react";
    import Button from "./Button";
    
    export default {
      title: "Button",
      component: Button,
      decorators: [withKnobs]
    };
    
    export const Default = () => (
      <Button>{text("children", "Simple Button")}</Button>
    );
  7. Finishing up TypeScript Setup

    Add custom Webpack config by creating .storybook/webpack.config.js file and put:

    module.exports = ({ config, mode }) => {
      config.module.rules.push({
        test: /\.(ts|tsx)$/,
        loader: require.resolve("babel-loader"),
        options: {
          presets: [["react-app", { flow: false, typescript: true }]]
        }
      });
      config.resolve.extensions.push(".ts", ".tsx");
      return config;
    };

    Make sure to add babel-loader:

    $ yarn add -D babel-loader

    Update extensions accordingly (from .js to .ts|tsx):

    .storybook/config.js => .storybook/config.ts

    requireContext('../src/components', true, /\.stories\.js$/) => requireContext('../src/components', true, /\.stories\.tsx$/)

๐Ÿ› Bug Fixes

TypeScript Issue(s)

Could not find a declaration file for module '@storybook/addon-knobs/react'

// BEFORE:
import { withKnobs, object } from "@storybook/addon-knobs/react";

// AFTER:
import { withKnobs, object } from "@storybook/addon-knobs";

Styled System Issue(s)

Type '{ color?: ... }' is not assignable to type 'ButtonHTMLAttributes'

// FIX 1: Set styled component type to `any`:
const Button: any = styled("button") < ButtonProps > ``;

// Fix 2: Define custom prop `textColor` in place of `color`:
const textColor = system({
  textColor: {
    property: "color", // <-- CSS property
    scale: "colors" // <-- key reference in the `theme` object
  }
});

For Fix 2, make sure to do the same thing for prop bg|backgroundColor since this is also part of the built-in API color.


๐Ÿ“„ DocsPage Setup

  1. Install DocsPage:

    $ yarn add -D @storybook/addon-docs
  2. Create the file .storybook/presets.js and put:

    module.exports = ["@storybook/addon-docs/react/preset"];
  3. Install react-docgen-typescript-loader:

    $ yarn add -D react-docgen-typescript-loader

    May need to specify the tsconfig for the loader in case props are not displaying:

    // webpack.config.js
    
    config.module.rules.push({
      ...
      use: [
        {
          loader: require.resolve('react-docgen-typescript-loader'),
          options: {
            tsconfigPath: path.resolve(__dirname, '../tsconfig.json')
          }
        }
      ]
    });

Storybook tests UI visually via an add-on called storyshot-puppeteer:

Same as storyshots, it works by comparing screenshots โ€“ only this time it takes screenshots of the browser and not code

Quick Setup

  1. Install storyshot-puppeteer:

    $  yarn add D @storybook/addon-storyshots-puppeteer
  2. Update the test file storybook.test.ts to override the test comparison with imageSnapshot from the puppeteer add-on:

    // storybook.test.ts
    
    import initStoryshots from "@storybook/addon-storyshots";
    import { imageSnapshot } from "@storybook/addon-storyshots-puppeteer";
    
    initStoryshots({
      test: imageSnapshot({ storybookUrl: "http://localhost:9009/" })
    });

    Note that the tests now depend on having an instance of Storybook running, so make sure Storybook server is up and running before running the tests.

Running on CI

Running two terminals (one for Storybook, another one for Testing) at the same time on CI environment is made possible by start-server-and-test.

  1. Install it:

    $ yarn add start-server-and-test
  2. Sample script:

    // package.json
    
    "scripts": {
      "test": "react-scripts test --coverage",
      "storybook": "start-storybook -p 9009 -s public",
      "ci:test": "start-test storybook 9009 test",
    }

CircleCI Setup

Collecting Jest Data via Junit (CRA version)

  1. Install jest-junit:

    $ yarn add -D jest-junit
  2. Tell Junit to save the report output to a directory of your choice (test-reports in my case):

    // package.json
    
    "jest-junit": {
      "outputDirectory": "test-reports"
    }

Sample command line (CRA version):

$ CI=true yarn run test:coverage -i --reporters=default --reporters=jest-junit

More CircleCI required config:

# .circleci/config.yml

- store_artifacts:
    path: test-reports/ # upload the test result folder as an artifact
- store_test_results:
    path: test-reports/ # display test result in build summary section

  1. Install the required dependencies:

    $ yarn add -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
  2. Create the .eslintrc file and put:

    {
      "parser": "@typescript-eslint/parser",
      "plugins": ["@typescript-eslint"]
    }

    In the same file, add the following recommended rules:

    // .eslintrc
    
    {
      ...
      // Add this to avoid runtime error
      "parserOptions": {
        "project": "./tsconfig.json"
      },
      "extends": [
        // Rules which recommended for all projects by the ESLint Team
        "eslint:recommended",
        // Make all eslint rules compatible with TS
        "plugin:@typescript-eslint/eslint-recommended",
        "plugin:@typescript-eslint/recommended",
        // for type-checking to work properly with highly-valuable rules
        "plugin:@typescript-eslint/recommended-requiring-type-checking"
      ]
    }
$ npx install-peerdeps --dev eslint-config-airbnb
// .eslintrc

{
  ...
  "extends": [
    // ESLint rules, including ES6+ and React
    "airbnb",
    // Enable the linting rules for React hooks
    "airbnb/hooks",
    ...
  ],
}
$ yarn add -D eslint-config-prettier
// .eslintrc

{
  ...
  "extends": [
    ...
    // Disable above code formatting related rules
    "prettier",
    // Required if a config uses a plugin to avoid conflict with Prettier
    "prettier/@typescript-eslint",
    "prettier/react"
  ],
}

In case of Prettier not configured in a workspace, add eslint-plugin-prettier to enforce the formatter.

$ yarn add -D prettier eslint-plugin-prettier
// .eslintrc

{
  ...
  "plugins": [..., "prettier"],
  "extends": [
    "prettier/react"
    "plugin:prettier/recommended"
  ],
  "prettier/prettier": [
      "error",
      {
        "no-var-keyword": true,
        "printWidth": 100,
        "semi": true,
        "singleQuote": true,
        "trailingComma": "es5",
        "tabWidth": 2
      }
    ]
}

Git Hooks

  1. Install the required dependencies:

    $ yarn add -D husky lint-staged prettier pretty-quick
  2. Sample config files:

    // .huskyrc
    
    {
      "hooks": {
        "pre-commit": "pretty-quick --staged --verbose && lint-staged",
        "pre-push": "yarn run test:all"
      }
    }
    // .lintstagedrc
    
    {
      "src/**/*.{js,ts,tsx}": [
        "eslint --fix",
        "git add"
      ]
    }

gorg-ui-v3's People

Contributors

nelsieborja avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

kamaz

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.