Skip to content

Latest commit

 

History

History
229 lines (154 loc) · 11.9 KB

CONTRIBUTING.md

File metadata and controls

229 lines (154 loc) · 11.9 KB

Contributing

Please read before contributing to UI Kit as we settled on some informal processes to keep components in UI Kit of a high standard with coherent APIs.

Criteria for components in UI Kit

These are general and loose rules components in UI Kit should strive to fulfill.

  • General purpose and a core building block (of an application)
  • Isolated behaviour agnostic to its environment (not easy to reach into internals)
  • Agreed and signed off by the design team (collaboration and sharing during development)
  • Easy to compose (components should be combinable)
  • Visual representation (a storybook serves as shared visual of different states)
  • Documentation of prop-types and usage patterns
  • Sensible defaults for props which are not a hard requirement

Folder Structure

This repository is managed as a monorepo, meaning it contains multiple packages located in the packages directory. Each component or shared utility function is set up as its own package. This should help applications to reduce their bundle size by importing only the needed packages, as well as to help with treeshaking. Some of the packages are used as "presets" and live in the presets folder. Those simply group other packages together to avoid importing each single one of them, for example inputs, buttons, etc.

Development

Testing

We split our testing into three parts: functionality testing, visual testing and bundle testing. We use separate tools for each of these, and we try to avoid overlap.

Functionality testing (*.spec.js)

The more your tests resemble the way your software is used, the more confidence they can give you..

  • write tests from a user perspective, not from a dev perspective
  • we test using @testing-library/react
    • we offer test-utils as a thin wrapper which sets up the context of tested components
    • we avoid beforeEach as it leads to test coupling
    • an it can describe the flow of a user
    • it is okay to have many expect statements in an it
    • we use code comments to help explain the expects better
  • avoid testing the visuals (classnames or DOM structure)
    • the user does not care about the DOM structure or the classnames themselves
    • use visual testing instead (see below)
  • try to use mocks at the same interface that a user would use (DOM, network, local-storage, cookies) instead of mocking implementation parts of the app
  • try to keep mocking minimal. The less we mock, and the further down the stack we mock, the more our tests will cover and the more confidence we gain that our components work

Visual testing (*.visualroute.js, *.visualspec.js)

These tests are used to prevent visuals regressions in our components exported from the build produced by rollup. It is necessary to build the bundle before running these tests.

  • we use a library called jest-puppeteer to run our visual tests
  • we use puppeteer to navigate to routes generated by our *.visualroute.js files, and then we use a tool called Percy to take snapshots of that route.
  • we can interact with our components before taking snapshots.
  • we take one snapshot per *.visualroute.js file, if we need to take multiple snapshots for a component, we create multiple *.visualroute.js files.
  • we test the components from the produced bundle
    • this gives us confidence that the bundling process works
    • this tests components under conditions closer to how consumers would use them
    • this helps us to avoid accidentally not exposing implemented components from the main index.js file
  • we test components in multiple states in one snapshot
    • it is nice to see all states in one snapshot
    • it uses less snapshots (we have a monthly budget)
    • we use custom components called Suite and Spec to surround our component-under-test, which makes the review easier
    • we set a min-height for every Spec to ensure that changes in height of a component's state don't break the visual diff of states following below that

Bundle testing (*.bundlespec.js)

These tests are used to ensure the bundle produced by rollup. It is necessary to build the bundle before running these tests. We use these tests to further ensure that our bundling process works.

Adding changesets

commercetools ui-kit uses changesets to do versioning and creating changelogs.

As a contributor you need to add a changeset by running yarn changeset. The command will prompt to select the packages that should be bumped, their associated semver bump types and some markdown which will be inserted into the changelogs.

When opening a Pull Request, a changeset-bot checks that the Pull Request contains a changeset. A changeset is NOT required, as things like documentation or other changes in the repository itself generally don't need a changeset.

Releasing packages

By default, all releases go to the next distribution channel and should be considered prereleases. This gives us a chance to test out a release before marking it stable in the latest distribution channel.

commercetools ui-kit uses changesets to do versioning and publishing a release.

A Changesets release GitHub Action opens a Version Packages Pull Request whenever there are some changesets that have not been released yet.

When the Version Packages Pull Request gets merged, the Changesets release GitHub Action will automatically trigger the release.

Moving the latest dist-tag to a release:

After testing the next release on a production project, if the version is stable it can be finally moved to the latest distribution channel.

$ yarn release:from-next-to-latest

The command will promote the version published on next to the latest npm dist-tag, for each package.

Canary releases

On master branch, we automatically publish canary releases from CI to the canary distribution channel, after the build runs successfully.

Canary releases are useful to test early changes that should not be released yet to next or latest. They are automatically triggered and released after a Pull Request is merged to master, unless the commit message contains [skip publish].

Note that canary releases will not create git tags and version bump commits.

Publishing documentation website

The documentation is currently built with Storybook and is hosted on Netlify.

By default, only Deploy Previews (Pull Requests) are deployed to Netlify. The Production website is deployed from the branch master.

Translations (i18n)

The UI Kit uses react-intl. The core messages are written down in messages.js files.

The translations for the supported languages exist in the /i18n folder. We do not use any automated translation software.

Adding new messages

In case you are working on a component and you want to add a completely new message, you should add it to (or create a) messages.js file. See the other messages.js files as a reference.

After adding the message(s), you need to run yarn i18n:build. This will modify the language files in /i18n by adding empty translations for the message keys.

Editing translations

If you want to modify an existing translation, you will need to manually edit the related files in /i18n.

How to add a component to UI Kit.

These are informal steps we suggest you to follow when adding a new component.

  1. Create a new task to add the component to the UI Kit.

    • Create task.
    • Add task to the MCD project.
    • Add task to the [UI Kit Kanban Board].
  2. Sync with the UI Kit leads

    • Notify @lufego or @dferber90 of the task.
  3. Create documentation for the component UNDECIDED

    • Create copy of [UI Kit Component Documentation Template].
    • Add copy to the [UI Kit Component Documentation List] page.
    • Designer & Dev go through the copy and update it for the new component.
  4. Align design with style guide

    • Designer checks the style guide restrictions and makes sure no elements are being duplicated.
  5. Create design for the component (if it hasn't been done already).

    • Designer creates the design for the component.
  6. Review new design

    • Designer & Dev review the component's design.
  7. Sync with the UI Kit leads

    • Notify @lufego or @dferber90 of the new design.
  8. Open a Github issue with the API proposal for the new component optional

    When the implementation of a component takes a lot of effort, or when multiple APIs are possible, it might be a good idea to open an issue first to discuss the API or to avoid doing unnecessary work.

    • i. Dev opens a Github issue on the MC Frontend repo describing the API proposal for the new component.
    • Use PropTypes to describe the component's props.
    • Show example usage of the component.
  9. Develop the component and open a PR to add the component to the UI Kit.

    • Open a PR to add the component to the UI Kit.
    • PR is approved by either Luis or Dominic or both.
  10. UX Review

    • Designer conducts the UX review on the component.
  11. Component is merged

    • Designer adds component to UI Kit Sketch file.
  12. Migrate component to MC.

    • Component is used only where needed for the user story.
    • Update component status on the UI Kit Kanban board.

When and how to change an existing component in UI Kit

  • Changing an existing component should be done with a certain degree of care. Please assume that the current API has been wrestled over.
  • If you want to add some functionality, consider if it should really be a concern of the component you want to enhance. For this:
    • The functionality should be applicable for a wide range of current and future requested features. What is in UI Kit should be basic building blocks that in theory can be used in a wide range of applications, even outside of commercetools.
    • When in doubt take inspiration from functionalities of the original HTML-tags than towards anything more complex.
  • Always remove unneeded functionality as soon as you spot it
    • This helps us to get components simple, consistent and easy to use
  • Avoid breaking changes to the API of the component. If you need to create breaking changes follow these steps
    • Make sure you have checked all usages of the component you change for potential problems
    • Inform all developers about the plan in the chats as pull requests might be open and other features already planned
    • Start with creating a deprecation notice on the component's functionality using the warning package (examples exist)
    • Ensuring that no consumer still uses the deprecated API after some time
    • Remove the deprecated feature
  • Before you implement your changes, create a Github issue stating your need for the required functionality, describe your proposed changes and also give an indication of the scope and implications of that change.
  • Make sure you also ping the design team about your changes to get their feedback
  • Implement your changes and put them up for code review
  • Update Storybook, all documentation and usage examples
  • Migrate all code that will immediately be affected by your changes

Resources