Skip to content

Latest commit

 

History

History
290 lines (187 loc) · 11.6 KB

CONTRIBUTING.md

File metadata and controls

290 lines (187 loc) · 11.6 KB

Contributing

Contents

  1. When does a component go in the design system?
  2. Maintaining Assets
  3. Git Strategy
  4. Code Standards
  5. Code Style
  6. Release Process
  7. Rules
  8. Build process
  9. ES Modules

When does a component go in the design system?

Does It Belong in the System?

Icons

Designing

Icons are exported from Figma and stored in the adjacent svg directory.

Each icon must:

  • have it's own 20×20 artboard.
    • in other words, a viewBox that is at least 20 on one axis:
      • good: viewBox="0 0 20 18", viewBox="0 0 20 20".
      • bad: viewbox="0 0 20 34".
  • contain only one exportable layer, which has:
    1. a single path or group.
    2. a kebab-case layer name prefixed with icon-
    3. the export format defined as "SVG".
  • have its color fill set to #DE1E7E (remember "DELETE") if you want the color to be modified.

Any changes to this Sketch file should be committed as well as the Sketch-generated SVGs. To export all SVGs in Sketch, select File > Export and in the next step choose the svg directory as the output location.

Building

For performance benefits (such as code-splitting) we opted for creating individual React components for each icon, rather than one single component.

We make use of SVGR, to transform the above SVG icons in assets to React components in sportsbet-icons.

To update/add icons run: yarn assets build

Git Strategy

Commits

Commits follow the Angular Commit Message Format. When committing changes, make use of the Commitizen CLI to generate consistent commit messages:

yarn commit

Branches

Base Branch

As a developer, you will you be branching and merging from develop, our base branch.

Consider origin/master to always represent the latest code deployed to production.

Supporting Branches

Use supporting branches for all new features and bug fixes. Unlike the base branch, these branches have a limited life-time and should be removed after merging.

The different types of branches should be named as follows:

  • Feature: feature/feature-name
  • Bug fix: fix/fix-name

Workflow

  1. Create the branch locally and then push to GitHub if it does not exist yet.

    A branch should always be 'publicly' available, and should never exist in just one developer's local repo.

  2. Make a pull request.

  3. Add the in progress tag until ready for review.

  4. Periodically, keep changes up to date with develop via git rebase develop.

  5. Grab a review and remove the in progress tag.

  6. One approved, it's down to you to merge the branch into develop. Code can only be contributed to develop via using pull requests.

  7. Delete your branch.

Rebasing develop branch to your branch example

  1. git checkout develop
  2. git pull
  3. git checkout your-branch
  4. git rebase develop

Rebasing pull requests example

  1. Pick your base commit, where you want add all other commits on top of.

    git log

    or the more visually friendly

    git log --oneline --graph --all --decorate -n 30

  2. git rebase -i hash - launches interactive shell where you choose your commits to squash

  3. git push -f - force push your git changes

Merge or Rebase

Use merge - not rebase whenever you've already pushed.

Never use git rebase on public branches. Consider using git rebase only if you want to avoid spaghetti-history in your local branch.

Feature Flags

Long-lived feature branches present problems when you need to build code on top of unfinished work. Merge unfinished features into the develop branch (following the steps outline above) so others can build off their work, but keep them hidden from your users and testers behind feature flags. Enable the flag in development to use the feature without the changes affecting anyone else. Once the feature is finished, you can remove the flags or use them to roll out to selected users and testers.

Code Standards

Accessibility

All features should attempt to conform to as many items on The A11Y Project's Web Accessibility Checklist as possible. If a checkbox can't be completed, the justification should be documented for future reference.

As part of our TypeScript linting process, we make use of react-a11y rules (surfaced via tslint-microsoft-contrib) to catch any common issues. react-a11y-role-has-required-aria-props is currently disabled for incorrect results.

Mobile First

Mobile devices are the most commonly used methods of browsing the web. When it comes to designing and developing your component, always build with mobile in mind first.

Need to modify the style at specific breakpoints? Scale your changes upwards; build for mobile by default and then add media queries for changes on larger sizes.

Want to use CSS Grid? Set your component to display: block; by default to stack items on mobile and other unsupported devices, then implement your grid at larger breakpoints.

Code Style

Code formatting is handled automatically via Prettier on pre-commit. However, you could install an IDE extension or run manually via yarn format <prettier-args>.

Linting will catch any further non-formatting issues:

Component Structure

File Structure

Separate concerns on a component basis, rather than the more traditional "style vs. function".

With Styled Components we can take advantage of keeping style, markup and logic tightly bound together as a single .tsx file. A component file should be defined in the following order:

  1. Imports
  2. External (e.g. node_modules)
  3. Internal (i.e. a different package from the design system)
  4. Component partials
  5. Styles
  6. Settings (e.g. const)
  7. Helper functions
  8. Markup / logic
  9. Exports

Documentation

Each component/consumable feature must have a README that follows the appropriate package's pre-defined .templates/:

This should be written in .mdx syntax, which will be included automatically in the Style Guide.

Directory Structure

For a basic component, the directory structure would look something like this:

+————————————+
│   Button   │
+————————————+


components
├── button
│   ├── README.mdx
│   └── index.js
└── …

For larger components, consider breaking down into smaller partials:

+——ComponentName——+
│                 │
│      Title      │
│                 │
+—————————————————+
│                 │
│     Caption     │
│                 │
+—————————————————+


components
├── button
├── component-name
│   ├── caption.tsx
│   ├── index.ts
│   ├── README.mdx
│   ├── settings.ts
│   ├── title.tsx
│   └── utils.ts
└── …

settings

Common constants/raw values that can be re-used across the different component partials.

utils

Styles that are unique to the component but need to be shared across the partials.

These styles should be flat/stateless and not bound by any form of functionality, making use of the CSSObject type from Styled Components for compatibility.

Naming

  • Components should be defined in PascalCase.

    For example: <ComponentName/>

    • Component partials should be prefixed by the component name:

      For example: <ComponentNameTitle/>

  • Flat re-usable styles should be defined in camelCase to differentiate.

    • For example: <div css={componentNameSizing}/>

Release Process

Thanks to Lerna and Commitizen, we can generate version bumps and CHANGELOGs for each package and release automatically.

  1. Assuming that all changes to be released have followed the Git Workflow outlined above, raise a pull request from develop into master.

  2. Ensure the pull request is up to date with master.

  3. Obtain at least 1 approval.

  4. Click the "Merge Pull Request" button to trigger an automatic release, monitoring progress in CircleCI.

    • If successful, a new tag will be visible, along with new package versions on NPM.
  5. Communicate the release to the team!

ES Modules


Rules

  1. All your files should be named after the actual component. So the component GroupIconCurrency is inside the file GroupIconCurrency.tsx.
  2. All your components should export a single default React component. This is only so we can enable tree shaking.
  3. All first level subfolders inside /src/ are considered public. People will use import { } from @heathmont/sportsbet-package-name/folder to import files from those folders directly.
  4. You are required to auto-generate an index file to for each subfolder which uses named exports to re-export all exports inside the folder + sub folders. This is required for tree shaking.
  5. You are required to auto-generate an index file to for your package which uses named exports to re-export all exports. This is required to allow lerna to import the project proeprly.

Build process

All packages are built in 2 separate formats, commonjs and es.

All code belongs in /src folder. When running yarn build, it will automatically generat a lib folder based on the code inside src.

First we transpile commonjs format modules into the lib folder directly. Second we transpile es format modules into the lib/es folder. Third we generated typescript definitions into the lib folder directly.

Release process

Before we release, we will:

  1. Copy all files from lib folder into the root folder.
  2. Update the files, main, module and typings fields in package.json

After we release, we will:

  1. Remove all the files we copied over from lib.
  2. Undo the changes to files, main, module and typings fields in package.json