Development

Set up your laptop

Set up your Gestalt repository

  • Clone the repo: Fork the Gestalt repo and work off your forked repo, not the pinterest/gestalt repo.
  • Once forked, clone to your local machine using the SSH option
git clone git@github.com:<YOUR_USERNAME>/gestalt.git
  • Use the correct Node.js version to setup the environment locally
cd gestalt && nvm use
If the node version isn't available, you will need to install
; Opens a new tab
it.
  • Install project dependencies. Do not run npm install because it will create a package-lock.json file (and also takes considerably longer).
yarn
  • Add pinterest/gestalt as a remote upstream (you'll only need to do this once).
git remote add upstream git@github.com:pinterest/gestalt.git
  • Check your remote configuration
git remote -v
// origin    git@github.com:<YOUR_USERNAME>/gestalt.git (fetch)
// origin    git@github.com:<YOUR_USERNAME>/gestalt.git (push)
// upstream    git@github.com:pinterest/gestalt.git (fetch)
// upstream    git@github.com:pinterest/gestalt.git (push)

Set up Visual Studio Code

  • Open the new /gestalt folder with VS Code.
  • Install the suggested VS Code extensions including vs code-stylelint
    ; Opens a new tab
    to lint CSS files.
  • If you want to automatically launch the docs when you open VS Code:
    • In VS Code type CMD+Shift+p
    • Search and select Tasks: "Manage Automatic Tasks in Folder"
    • Select Allow "Automatic Tasks in Folder"
    • Relaunch VS Code

Run the Gestalt documentation server

Whenever you make changes to Gestalt, please test them out locally before making a PR.

To start the documentation server, run yarn start. In your favorite browser, navigate to http://localhost:8888.

Create a pull request

  • Rebase your local master branch
git fetch upstream
git rebase upstream/master
  • Create an checkout a branch. Replace the text <feature-branch> with your branch name
git checkout -b <feature-branch> upstream/master
  • Time to make changes to Gestalt! If you are introducing a new component, run the scaffolding command to generate the necessary files. Replace ‘ComponentName‘ with the name of your component.
yarn generate ComponentName
  • The script will generate the following files:
    • Component development
      • packages/gestalt/src/NewComponent.js: JS file for component development
      • packages/gestalt/src/NewComponent.css: CSS file for component development
      • packages/gestalt/src/NewComponent.css.flow: Autogenerated Flow types for the CSS file
      • packages/gestalt/src/NewComponent.flowtest.js: Tests for Flow types
      • packages/gestalt/src/NewComponent.test.js: Test file for the component. It can also be replaced or complemented with an additional packages/gestalt/src/NewComponent.jsdom.test.js
    • Component documentation
      • docs/pages/web/newcomponent.js: This file builds the documentation page for the component
      • docs/examples/newcomponent/main.js: This file builds the main example used in the component documentation page. To add more examples to the docs, duplicate this file as a template.
      • packages/gestalt/src/NewComponent.svg: SVG file used for the component overview page
      • docs/pages/visual-test/NewComponent-light.js: This file builds a component visual example in light mode. The component snapshot shows in VSCode when hovering over the component name
      • docs/pages/visual-test/NewComponent-dark.js: This file builds a component visual example in dark mode. The component snapshot shows in VSCode when hovering over the component name
    • Component testing
      • playwright/accessibility/NewComponent.spec.mjs: This file runs accessibility Playwright tests on the new component documentation page
      • playwright/visual-test/NewComponent.spec.mjs: This file creates visual snapshot tests on the new component in light mode
      • playwright/visual-test/NewComponent-dark.spec.mjs: This file creates visual snapshot tests on the new component in dark mode
    • packages/gestalt/src/README_DELETE_componentName.md: This file provides guidance on the remaining steps to set up your component. It must be deleted once the steps are done.
    • The script will also update packages/gestalt/src/index.js adding the new component to the index list.
  • While developing your new component or updating existing ones, your playground to test your work and changes is your component documentation page. Consider the following while developing:

    • Use your docs/examples/newcomponent/main.js example to iterate on your implementation
    • Our documentation currently uses two live coding environments: Sandpack
      ; Opens a new tab
      and React Live
      ; Opens a new tab
      . While Sandpack provides a better final experience, it has not been configured yet to support local development efficiently. On the other hand, React Live works well with local development; however, it has the following limitations to consider when building examples:
      • External imports are not supported
      • All constants must be within the exported function, not outside
      • Sandpack examples are contained within its own contained viewport, while React Live isn't contained and uses the Gestalt documentation page as viewport. For components that are shown by default in Sandpack, for example Modal or OverlayPanel, we shouldn't display them by default within React Live as they would automatically be visible in your page. Use the following useState const [showComponent, setShowComponent] = useState(true); to control the visibility of your component. Under the hood, we replace the boolean so the components are shown by default in Sandpack but stayed closed by default on React Live.
    • To enable React Live during development and within build testing URLs (https://deploy-preview-XXXX--gestalt.netlify.app
      ; Opens a new tab
      ), you can toggle between development mode view in the Settings menu in the site header.
  • Any subsequent component changes might require the following actions.

    • Run unit tests
    yarn jest -u
    
    yarn playwright:test accessibility/
    
    # Stop Docs build
    # Update all Gestalt packages builds running rollup. Make sure to run after every change in component/snapshot test
    yarn build:prod
    
    # Update a specific visual test snapshots with the latest builds
    yarn playwright:update-visual-test playwright/visual-test/<filename>  --update-snapshots
    
    • Update CSS flow types
    yarn run flow-generate:css
    
    • If you are introducing breaking changes, create a codemod to help users migrate between versions.
  • Commit the changes to your branch. Follow naming conventions for the PR

<Component>: <Commit Change Description (including platform if relevant)>

  • When you are done, push your branch up.
git add .
git commit -am "Component: Commit Change Description"
git push -f origin HEAD
  • Go to https://github.com/pinterest/gestalt

    . A new banner will be displayed, click on 'Compare & Create Pull Request'.

  • Add useful summary and screenshots. We provide a template for the summary to make sure you include all necessary information.

  • Click on Create Draft Pull Request to create your PR. Once you are done committing changes to it, and all the CI tests have passed, click the "Ready for Review" button.

Keeping the PR as a draft until it is ready for review reduces the number of unneeded notifications for maintainers
If you are a Pinterest employee, please let us know on Slack (#gestalt-eng-web) that your PR is ready for review.
  • Ensure checks pass on your Pull Request - having the "Require Semver / Test (pull_request)" check fail is expected, because a Gestalt maintainer needs to add a correct semver label. Read our release and versioning guidelines.

  • After a Gestalt maintainer adds a correct semver label and approves a Pull Request, the PR will be ready to merge. Coordinate with the reviewer to determine when the PR should be merged.

  • Check the status of your PR https://github.com/pinterest/gestalt/pull/XXXX

    and access the deploy preview using the built site URL https://deploy-preview-XXXX--gestalt.netlify.app
    ; Opens a new tab
    from Netlify.

  • When sharing preview urls, you may have to remind viewers to toggle on development mode from the header menu. This is necessary to see unpublished changes in the code examples. To simplify sharing, you can add a ?devexample=true parameter to the url to enable the examples by default.

Create a new package

When should you create a new gestalt- package instead of adding a new component to the existing gestalt?

Gestalt is a lightweight package with only 2 dependencies: "classnames" and "prop-types". By using the minimal amount of dependencies, we can maintain the size of the bundle small. If a new component requires external packages, it's worth isolating it in a single package so that importing Gestalt in our codebase keeps a small bundle.

When adding a new package, follow the steps in this PR: https://github.com/pinterest/gestalt/pull/3143

My pull request fails on "Semver / Require Label (pull_request)", how do I fix it?

Nothing you can do to fix it.

A Gestalt Core maintainer will add a semver label (patch release / minor release / major release) when reviewing a PR.

Guidelines

Scope of work

When pushing new changes to GitHub, your PR title should be aligned with the scope of your work. If your goal was to change the default color of a component, keep the scope of changes to that specific task and word the title to exactly reflect those changes.

Changes not allowed

Do not use the following CSS style properties:

  • line-height: Property in CSS that controls the space between lines of text. Not defining a line-height allows the browser to determine line-height based on language which prevents localization issues.

  • height/width: Height & width are CSS properties that can be used for determining the size of static assets such as an icon size. However, components that contain text data should not fix the height & width of the component to prevent incorrect styling under different cases such as localization, longer texts, etc. Consider other alternatives such as padding to define different component sizes.

Avoid:

  • Boolean props: For example, instead of isRTL: boolean or isStart: boolean or isEnd: boolean, use more declarative props such as layoutDirection: rtl | ltr or role: startInput | endInput.

Technical Design Documents

Before starting coding a new component, you must first detail the component specifications in Technical Design Documents (TDD). You can find the TDD template here

.

RFCs

Find the RFCs (request for comments) process and repository here

.