Skip to content

Latest commit

 

History

History
278 lines (179 loc) · 11.9 KB

CONTRIBUTING.md

File metadata and controls

278 lines (179 loc) · 11.9 KB

Contributing

Contents

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

When does a component go in the design system?

Does It Belong in the System?

Release Process

Thanks to changeset, we can generate version bumps automatically.

  1. Ensure that develop branch is up to date with master. Run these commands on develop branch
  2. Run pnpm changeset in the root of the repository and follow CLI instructions to generate a new changeset.
  3. Run pnpm changeset version command. This will bump the versions of the packages previously specified with pnpm changeset (and any dependents of those) and update the changelog files.
  4. Run pnpm install. This will update the lockfile and rebuild packages.
  5. Commit the changes. (e.g git add . and git commit -m "chore: bump version X.X.X")
  6. Push your changes.
  7. Raise a pull request from develop into master.
  8. Obtain at least 1 approval.
  9. Click the "Merge Pull Request" button to trigger an automatic release, monitoring progress in CircleCI.
  10. Tag a version and push your tag (git tag vX.X.X and git push && git push --tags)
  11. Communicate the release to the team!

Prerelease Process

You might want to release a version of your packages before you do an actual release, Changesets lets you do this but there are some caveats because of the complexity that monorepos add that are important to understand.

When you want to do a prerelease, you need to enter prerelease mode. You can do that with the pre enter . The tag that you need to pass is used in versions(e.g. 1.0.0-beta.0) and for the npm dist tag.

A prerelease workflow might look something like this:

pnpm changeset pre enter alpha
pnpm changeset
pnpm changeset version
pnpm install

git checkout -b "feat/prerelease"
git add .
git commit -m "Enter prerelease mode and version packages"

pnpm changeset publish
git push --follow-tags

pnpm changeset pre exit

Icons

Designing

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

Each icon must:

  • have it's own 32×32 artboard.
    • in other words, a viewBox that is at least 32 on one axis:
      • good: viewBox="0 0 32 18", viewBox="0 0 32 32".
      • 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 moon-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:

pnpn run 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

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

Directory Structure

Before contributing new component in design system need to determine should it be put to core package or should be created new package for this component. For this you need follow the rule: if the components has complicated logic or some external dependencies - for it should be created new package.

Please stick to a directory style to make things visually easier to track new component:

  • the new component should be placed in separate folder and be given corresponding name (more details about the naming below);
  • styled component shoud be placed in styles folder. But only the ones used for this folder component. If any component down the tree needs styled stuff, they should have their own folder for it;
  • all component's logic better to moove to the hook and create a folder or file with the hook name;
  • all the nested components should be placed in folder private;
  • from the main file should be exported outside, only one component and it's interface;

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

+————————————+
│   Badge    │
+————————————+


components
├── badge
│   ├── styles
│       ├── Container.ts
│   └── Badge.tsx
└── …

For larger components, consider breaking down into smaller partials:


components
├── singleSelect
│   ├── private
│       ├── styles
│           ├── SearchWrapper.ts
│       ├── Options.tsx
│       ├── SingleSelectWithContext.tsx
│   ├── styles
│       ├── Container.ts
│       ├── SelectLabel.ts
│   └── SingleSelect.tsx
└── …

!! Any styled components created should be .ts and not .tsx. The same goes for custom hooks, if you need to make them .tsx, it means they are not just styled components anymore.

!! All what was placed in private and styled folders exlude from export outside, baced on barrelsby config.

Naming

  • Components should be defined in PascalCase.

    For example: <ComponentName/>

    • Component partials should be prefixed by the component name:

      For example: <ComponentNameTitle/>

Documentation

Each component feature must have a corresponding description page in next-docs/pages/components with code exepmples of all possible states.

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/moon-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.

ES 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