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.
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
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.
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.
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 anit
- we use code comments to help explain the
expect
s better
- we offer
- 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
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
andSpec
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
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.
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.
By default, all releases go to thenext
distribution channel and should be considered prereleases. This gives us a chance to test out a release before marking it stable in thelatest
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.
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.
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.
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
.
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.
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.
If you want to modify an existing translation, you will need to manually edit the related files in /i18n
.
These are informal steps we suggest you to follow when adding a new component.
-
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].
-
Sync with the UI Kit leads
- Notify @lufego or @dferber90 of the task.
-
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.
-
Align design with style guide
-
Designer
checks the style guide restrictions and makes sure no elements are being duplicated.
-
-
Create design for the component (if it hasn't been done already).
-
Designer
creates the design for the component.
-
-
Review new design
-
Designer
&Dev
review the component's design.
-
-
Sync with the UI Kit leads
- Notify @lufego or @dferber90 of the new design.
-
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.
- i.
-
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.
-
UX Review
-
Designer
conducts the UX review on the component.
-
-
Component is merged
-
Designer
adds component to UI Kit Sketch file.
-
-
Migrate component to MC.
- Component is used only where needed for the user story.
- Update component status on the UI Kit Kanban board.
- 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