Skip to content

Contributing

Micah Godbolt edited this page Nov 9, 2022 · 13 revisions

Contributing to Fluent UI React

Please use the following steps to contribute a new component or a bug fix to the Fluent UI project.

Looking for a way to contribute? Check out the Good First Issues tag.

If you want to build a new component, read this first.

Getting set up

First, set up your development environment, including:

  • Install appropriate software (Git, Node, Yarn, VS Code or other editor)
  • Create a fork of the repo
  • Clone the fork and set your upstream remote

Building

Very short version (assumes fluentui is the name of your repo root folder):

cd fluentui
yarn
yarn start

Choose the appropriate package name (usually @fluentui/react or @fluentui/react-northstar) and a demo app will open. As you make changes to component code and save files, the demo app should update to reflect your changes.

For more details:

Folder structure

The repo has a few important top-level folders:

/scripts/ - Contains shared build tools /packages/ - Contains all shared packages /packages/fluentui/ - Currently contains packages specific to @fluentui/react-northstar /apps/ - Contains app projects which aren't intended to be published packages (website, test apps, etc)

Note that in the future, we'll be doing housecleaning under /packages/ to separate frameworks (React, web components) and make things easier to find.

For more details, see the Repo structure page.

Let's make a fix

See the Development Workflow page for a detailed walkthrough of:

  • Getting ramped up with your build environment
  • Making a change
  • Review process
  • Looking at build errors and getting a passing build
  • How to get help

What contracts do we adhere to and consider

We follow semantic versioning:

  • patches - Changes which are backwards/forwards compatible.
  • minors - New features
  • majors - Breaking changes (removal of features) - avoid this without coordinating a major release.

We make sure that we follow these things:

  • Accessibility standards. If there is a standard to follow, we follow it.
  • High contrast OS support. We currently add high contrast media query overrides in styling to fall back to system colors in HC OS mode. (Firefox high contrast mode uses a different approach and is not as well-supported.)
  • Focus rectangles are always hidden unless the user interacts with keyboard. (useFocusRects hook helps.)
  • Recently we introduced isConformant test abstraction to validate general expectations for React components in tests.

What affects the contract:

  • API surface
  • DOM shape
  • CSS rules
  • Behaviors
  • Performance or load-order characteristics
  • Top level import file names and paths

What's not part of the contract:

  • File names and paths
  • File name casing

What's a good fix vs bad?

Good fixes

  • Don't break contracts without the right semantic versioning.
  • Have little performance implications.
  • Have thorough tests (functional, snapshot, perf, visual regression as appropriate.)
  • Have great documentation.
  • Improvements that are backwards compatible
  • Changes that with low overhead that make the feature more complete

Bad fixes

  • Anything which breaks the contract without following semantic versioning
  • Things which benefit a specific scenario but penalize others
  • Things which someone couldn't look at and explain
    • Hacky prop additions like enableRootElementFocusFixOverride
    • Inconsistent prop additions onChange(value, value2) instead of onChange(ev, value).
  • Introduction of un-vetted 3rd-party dependencies that will affect downstream partners without any guidance on how they should deal with it.
  • Undocumented features

A few details

If you're modifying a public API, be sure to build the project and check in any updates to *.api.md files. These are generated by API Extractor and help ensure API changes are reviewed before merging.

If you're changing the DOM shape or styling, your build may fail if there are snapshot tests validating this (there almost always are). To update snapshots, you must build up to the corresponding project and run yarn update-snapshots. More details here.

If you're adjusting project dependencies, you may need to run yarn at the root to update the yarn lockfile. PLEASE be careful not to introduce unwanted dependencies here, and in particular, do not add untrusted 3rd-party dependencies without consulting owners/leads.

Before submitting, check these

  • It builds
  • Tests pass
  • Lint passes
  • You have adequate test coverage

Submitting a fix

  1. Create your branch on your fork
  2. Push changes to it
  3. Important: Run yarn change to create a change file. This command will detect which packages changed and ask you if it's a patch/minor/major and what your release notes are. You answer these, it creates a json file which you will need to push to your branch.
  • Note you may need to add yarn change -b upstream/master if you're on a Mac so that the tool compares your changes against the right branch.
  • The comments you include in the change file will show up in the release notes for the package. Please write meaningful things such as:

MyComponent: added foo property to allow customers to apply foo styling.

  1. Go to your fork and to the PRs section to submit a PR
  2. Please fill out the title and description to be meaningful and include screenshots as needed.

Bad:

Good:

  1. Know who is responsible for reviewing your change and reach out to them. Check the owners. Check assignments. Make sure they know you're waiting by talking with them over Teams chat; it will ensure your changes make sense and get and merged. Communicating is really important here, as things can be dismissed/ignored when we don't understand each others' needs.

Things you might find after you submit

Performance regressed

Bundle size regressed

Adding large amounts of code, or even a few imports that seem innocent, to a component can regress bundle for everyone. The build may complain about this. There are ways to compensate for this.

Can the feature be separated from the component? This might require the component to have more configurability, but sometimes separating out a hook or component, or adding a prop to inject the override can avoid penalizing everyone.

Can you reduce bundle elsewhere? Sometimes repeat code can contribute to bloat. Can you find ways to reduce repeat code?

What about breaking changes?

First, try not to break. It creates disruption for everyone. Can you deprecate old, and support old and new? (Search for warnDeprecations usage.)

If you need to break things, stage a /next folder. Duplicate code in there. You can opt into the breaking change in your product by referring to the path import.

When the major changes have been vetted and are final, we will coordinate a major release. Please work with leads to coordinate the release of the /next updates.

Packaging and versioning within the repo

Historically we have released "suite" packages only. We are moving to a sub-package model over time, where individual components live within their own package and use their own versioning. (This is still a work in progress as of version 8.) Once this is fully implemented, it means that major releases of one component won't require a major release of another unrelated one.

Suite packages will still export a set of sub packages and will not take major re-exported dependency changes without major releasing themselves. This is done on a less frequent cadence to avoid too much required churn on partners.

See releases

Changes are typically published around 5 AM Pacific time Monday through Friday. (Note that this means changes checked in on Friday typically won't be published until Monday morning.) New releases for each package will show up on its npm page, or you can see releases for all packages on our GitHub releases page.

Getting help

Bugs

If you encounter a problem which seems like a bug in Fluent UI React itself (or a problem with the website or documentation), please search for an existing issue and if you can't find one, file a new issue. Issues will be triaged each weekday by our shield team.

Before filing a bug, it's preferred that you have an isolated public repro (the issue template has some tips for making a repro). If the repro is inside a Microsoft product and you're having trouble making an isolated repro, please contact the team internally as described under "Questions" before filing an issue.

Feature requests

For feature requests, you can either file an issue or contact the team internally as described under "Questions."

Questions

Anyone can ask questions on Stack Overflow.

Microsoft employees can join Fluent Community on Teams. This is a good place to ask usage questions or get help isolating an issue repro.

There are also a few other ways Microsoft employees can get help:

  1. Use the Microsoft 1ES extension to help map GitHub usernames to internal aliases
  2. Be familiar with the CODEOWNERS list
  3. Use Teams chat to:
  • Ping the assigned owner for the issue/PR for help
  • Ping codeowners directly for help (please ask the community first unless urgent)
  1. Not getting traction? Ask leads for help:
  • React - Justin Slone (EM), Paul Gildea (PM)
  • Web components - Chris Holt (EM)

What's new

Planning

Process

Usage

Reporting issues

Contributing

Component creation and convergence

Testing

Coding guidelines

Best practices

References

Useful tools

Clone this wiki locally