NOTE: This document currently only applies to the packages located under packages/fluentui
, such as @fluentui/react-northstar
. For other packages, see this wiki page instead!
If you would like to contribute to packages besides the ones under packages/fluentui
, see this wiki page instead!
To contribute to packages in this folder, follow these setup instructions.
This list contains the most useful commands. You should run
yarn run
to see all scripts.
From repo root:
yarn start # start doc site: choose `@fluentui/docs`
yarn test # run all packages' tests once
yarn build # build all packages
yarn build:fluentui:docs # build docs
gulp deploy:docs # deploy gh-pages doc site
yarn lint # lint all packages
yarn prettier # run prettier on changed files
From an individual under packages/fluentui
, such as packages/fluentui/react-northstar
:
yarn test # test once
yarn test:watch # test on file change
yarn build # build all files in package
yarn lint # lint once
yarn lint:fix # lint and attempt to fix
These guides will walk your through various activities for contributing:
@fluentui/react-northstar
implements accessibility using accessibility behaviors. The behaviors add attributes to the DOM elements (mainly role and aria-* properties) as well as handle keyboard interaction and focus. Every accessible component has a default behavior, which can be overridden using the accessibility
prop. You can choose a behavior from the ones provided by Fluent UI or you can implement a new behavior.
Behaviors apply properties, focus handling and keyboard handlers to the component slots. When developing a component, the properties and keyboard handlers need to be spread to the corresponding slots.
ARIA roles and attributes provide necessary semantics for assistive technologies that allow persons with disabilities to navigate in the page/application.
In addition to behaviors, ARIA landmarks and naming props need to be added to the components/elements to form the page structure and provide textual information.
For example, to make an icon-only Button accessible, aria-label
prop needs to be used:
<button icon="star" iconOnly aria-label="Favorites" primary />
An application should always have an element with focus when in use. The user can change the focused element by:
- pressing tab/shift+tab keys to navigate through the components
- pressing arrow keys to navigate through children (for example menu items in menu)
- using the screen reader with or without virtual cursor
@fluentui/react-northstar
uses the FocusZone component for basic tab and arrow key focus handling. To use the focus zone, you can use the focusZone
configuration in the behavior (for example see MenuItemBehavior).
Focused component needs to be clearly visible. This is handled in @fluentui/react-northstar
by focus indicator functionality. Focus indicator will be displayed only if the application is in keyboard mode. Application switches to keyboard mode when a key relevant to navigation is pressed. It disables keyboard mode on mouse click events.
To style the focused component, you can use the isFromKeyboard
utility and prop. See Button component and Button style for reference.
In addition to basic focus handling, specific keyboard handlers can be added to the behaviors. These keyboard handlers call actions defined in the components, when corresponding keys are pressed by the user. For reference, see keyActions
in MenuItemBehavior and actionHandlers
in MenuItem component.
We are using Lerna to manage our packages and Yarn Workspaces to link them.
For now, you must copy the structure and boilerplate files of an existing package under packages/fluentui
when adding a new package. packages/fluentui/accessibility
is a good basic example.
- choose a name and update the
name
field (keep the@fluentui
scope)- it can be prefixed with the library name if the implementation is not framework-agnostic.
- the directory name should match the unscoped part of the package name
- please provide a meaningful description to a package in the matched field
- use
https://github.com/microsoft/fluentui/tree/master/packages/fluentui/__DIRECTORY_NAME__
ashomepage
- our packages are currently published with MIT license, please follow it until you will have specific legal requirements
Organise a new package.json
according to a conventional format, where fields appear in a predictable order and nested fields are ordered alphabetically.
yarn syncpack format
Please always use lerna add
to manage all dependencies including internal packages. The command below will add @fluentui/react-proptypes
as a production dependency to the @fluentui/react-northstar
package.
lerna add @fluentui/react-proptypes packages/fluentui/react-northstar
I (@rymeskar) have been part of the FluentUI framework team for the past two months. During these months, I have tried to collect ideas, rules, guidelines and best practices that are not otherwise captured. Generally, the recommendation is that code and conformant test is the best way to learn up-to-date FluentUI idioms.
- Changelog has a special format.
- Always try to find the most relevant and similar component to get inspired by.
- Try to extract pure functions outside of component's body; possibly into special files.
- Don't name boolean flags with 'is' prefix.
Yarn build
is not necessary when working with FluentUI. You should just callyarn
(resolve packages) and thenyarn start
(start application).- For benchmarking JavaScript, one can use the https://jsperf.com .
- The
useAutoControlled
hook description:defaultValue
comes from an outer scope and be defined by user, i.e.defaultChecked
.initialValue
is internal and will be used if there is nodefaultValue
orvalue
.value
should come from outer space and always wins.
- Testing
- For majority of components, visual test in combination with
isConformant
test is enough. - Visual tests are based off examples. You can extend the examples by also providing 'steps' action tests.
- For majority of components, visual test in combination with
- Props
- Props should be a flattened object.
- Props should take advantage of optional properties in combination with defaultValues.
- Event Handlers
- Going forward, we should use
onChange?: (e: React.SOME_EVENT<EL_TYPE>, data: DatepickerProps & { value: IDay }>)
. The currently used ComponentEventHandler uses React.SyntheticEvent and is able to reason about the proper type then. - We use lodash's
_.invoke()
, the function ensures that the prop actually exists. - We should work carefully with
event.preventDefault()
. Only invoke in necessary cases. In Datepicker, we wish to navigate grid cell navigation only explicitly within our code.
- Going forward, we should use
- Styling
- When developing with different kind of themes, one should add the style to default theme and add partial classes to dark or high-contrast.
- Behavior
- When developing behaviors, one must add proper specification strings. The format of these strings is defined in regexpes in the following file.
- Focus and navigation should be handled by focusZone section of behaviors. The actual types and definitions are defined here.
- For sustainable keyboard keys handling, one needs to map actions to key presses. Then within component code, one needs to define handling of these actions.